diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 8fdf1407..e66d96dc 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.9.3","generation_timestamp":"2023-09-25T20:20:03","documenter_version":"1.0.1"}} \ No newline at end of file +{"documenter":{"julia_version":"1.9.3","generation_timestamp":"2023-11-07T07:46:11","documenter_version":"1.1.2"}} \ No newline at end of file diff --git a/dev/assets/documenter.js b/dev/assets/documenter.js index 7002e251..f5311607 100644 --- a/dev/assets/documenter.js +++ b/dev/assets/documenter.js @@ -75,61 +75,76 @@ $(document).ready(function() { //////////////////////////////////////////////////////////////////////////////// require(['jquery'], function($) { +let timer = 0; var isExpanded = true; $(document).on("click", ".docstring header", function () { let articleToggleTitle = "Expand docstring"; - if ($(this).siblings("section").is(":visible")) { - $(this) - .find(".docstring-article-toggle-button") - .removeClass("fa-chevron-down") - .addClass("fa-chevron-right"); - } else { - $(this) - .find(".docstring-article-toggle-button") - .removeClass("fa-chevron-right") - .addClass("fa-chevron-down"); + debounce(() => { + if ($(this).siblings("section").is(":visible")) { + $(this) + .find(".docstring-article-toggle-button") + .removeClass("fa-chevron-down") + .addClass("fa-chevron-right"); + } else { + $(this) + .find(".docstring-article-toggle-button") + .removeClass("fa-chevron-right") + .addClass("fa-chevron-down"); - articleToggleTitle = "Collapse docstring"; - } + articleToggleTitle = "Collapse docstring"; + } - $(this) - .find(".docstring-article-toggle-button") - .prop("title", articleToggleTitle); - $(this).siblings("section").slideToggle(); + $(this) + .find(".docstring-article-toggle-button") + .prop("title", articleToggleTitle); + $(this).siblings("section").slideToggle(); + }); }); $(document).on("click", ".docs-article-toggle-button", function () { let articleToggleTitle = "Expand docstring"; let navArticleToggleTitle = "Expand all docstrings"; - if (isExpanded) { - $(this).removeClass("fa-chevron-up").addClass("fa-chevron-down"); - $(".docstring-article-toggle-button") - .removeClass("fa-chevron-down") - .addClass("fa-chevron-right"); + debounce(() => { + if (isExpanded) { + $(this).removeClass("fa-chevron-up").addClass("fa-chevron-down"); + $(".docstring-article-toggle-button") + .removeClass("fa-chevron-down") + .addClass("fa-chevron-right"); - isExpanded = false; + isExpanded = false; - $(".docstring section").slideUp(); - } else { - $(this).removeClass("fa-chevron-down").addClass("fa-chevron-up"); - $(".docstring-article-toggle-button") - .removeClass("fa-chevron-right") - .addClass("fa-chevron-down"); + $(".docstring section").slideUp(); + } else { + $(this).removeClass("fa-chevron-down").addClass("fa-chevron-up"); + $(".docstring-article-toggle-button") + .removeClass("fa-chevron-right") + .addClass("fa-chevron-down"); - isExpanded = true; - articleToggleTitle = "Collapse docstring"; - navArticleToggleTitle = "Collapse all docstrings"; + isExpanded = true; + articleToggleTitle = "Collapse docstring"; + navArticleToggleTitle = "Collapse all docstrings"; - $(".docstring section").slideDown(); - } + $(".docstring section").slideDown(); + } - $(this).prop("title", navArticleToggleTitle); - $(".docstring-article-toggle-button").prop("title", articleToggleTitle); + $(this).prop("title", navArticleToggleTitle); + $(".docstring-article-toggle-button").prop("title", articleToggleTitle); + }); }); +function debounce(callback, timeout = 300) { + if (Date.now() - timer > timeout) { + callback(); + } + + clearTimeout(timer); + + timer = Date.now(); +} + }) //////////////////////////////////////////////////////////////////////////////// require([], function() { diff --git a/dev/assets/themes/documenter-dark.css b/dev/assets/themes/documenter-dark.css index 691b83ab..ec054ecc 100644 --- a/dev/assets/themes/documenter-dark.css +++ b/dev/assets/themes/documenter-dark.css @@ -4,4 +4,4 @@ Maintainer: @ericwbailey Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css -*/}html.theme--documenter-dark html{background-color:#1f2424;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--documenter-dark article,html.theme--documenter-dark aside,html.theme--documenter-dark figure,html.theme--documenter-dark footer,html.theme--documenter-dark header,html.theme--documenter-dark hgroup,html.theme--documenter-dark section{display:block}html.theme--documenter-dark body,html.theme--documenter-dark button,html.theme--documenter-dark input,html.theme--documenter-dark optgroup,html.theme--documenter-dark select,html.theme--documenter-dark textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}html.theme--documenter-dark code,html.theme--documenter-dark pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--documenter-dark body{color:#fff;font-size:1em;font-weight:400;line-height:1.5}html.theme--documenter-dark a{color:#1abc9c;cursor:pointer;text-decoration:none}html.theme--documenter-dark a strong{color:currentColor}html.theme--documenter-dark a:hover{color:#1dd2af}html.theme--documenter-dark code{background-color:rgba(255,255,255,0.05);color:#ececec;font-size:.875em;font-weight:normal;padding:.1em}html.theme--documenter-dark hr{background-color:#282f2f;border:none;display:block;height:2px;margin:1.5rem 0}html.theme--documenter-dark img{height:auto;max-width:100%}html.theme--documenter-dark input[type="checkbox"],html.theme--documenter-dark input[type="radio"]{vertical-align:baseline}html.theme--documenter-dark small{font-size:.875em}html.theme--documenter-dark span{font-style:inherit;font-weight:inherit}html.theme--documenter-dark strong{color:#f2f2f2;font-weight:700}html.theme--documenter-dark fieldset{border:none}html.theme--documenter-dark pre{-webkit-overflow-scrolling:touch;background-color:#282f2f;color:#fff;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}html.theme--documenter-dark pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}html.theme--documenter-dark table td,html.theme--documenter-dark table th{vertical-align:top}html.theme--documenter-dark table td:not([align]),html.theme--documenter-dark table th:not([align]){text-align:inherit}html.theme--documenter-dark table th{color:#f2f2f2}html.theme--documenter-dark .box{background-color:#343c3d;border-radius:8px;box-shadow:none;color:#fff;display:block;padding:1.25rem}html.theme--documenter-dark a.box:hover,html.theme--documenter-dark a.box:focus{box-shadow:0 0.5em 1em -0.125em rgba(10,10,10,0.1),0 0 0 1px #1abc9c}html.theme--documenter-dark a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #1abc9c}html.theme--documenter-dark .button{background-color:#282f2f;border-color:#4c5759;border-width:1px;color:#375a7f;cursor:pointer;justify-content:center;padding-bottom:calc(0.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(0.5em - 1px);text-align:center;white-space:nowrap}html.theme--documenter-dark .button strong{color:inherit}html.theme--documenter-dark .button .icon,html.theme--documenter-dark .button .icon.is-small,html.theme--documenter-dark .button #documenter .docs-sidebar form.docs-search>input.icon,html.theme--documenter-dark #documenter .docs-sidebar .button form.docs-search>input.icon,html.theme--documenter-dark .button .icon.is-medium,html.theme--documenter-dark .button .icon.is-large{height:1.5em;width:1.5em}html.theme--documenter-dark .button .icon:first-child:not(:last-child){margin-left:calc(-0.5em - 1px);margin-right:.25em}html.theme--documenter-dark .button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}html.theme--documenter-dark .button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 1px)}html.theme--documenter-dark .button:hover,html.theme--documenter-dark .button.is-hovered{border-color:#8c9b9d;color:#f2f2f2}html.theme--documenter-dark .button:focus,html.theme--documenter-dark .button.is-focused{border-color:#8c9b9d;color:#17a689}html.theme--documenter-dark .button:focus:not(:active),html.theme--documenter-dark .button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .button:active,html.theme--documenter-dark .button.is-active{border-color:#343c3d;color:#f2f2f2}html.theme--documenter-dark .button.is-text{background-color:transparent;border-color:transparent;color:#fff;text-decoration:underline}html.theme--documenter-dark .button.is-text:hover,html.theme--documenter-dark .button.is-text.is-hovered,html.theme--documenter-dark .button.is-text:focus,html.theme--documenter-dark .button.is-text.is-focused{background-color:#282f2f;color:#f2f2f2}html.theme--documenter-dark .button.is-text:active,html.theme--documenter-dark .button.is-text.is-active{background-color:#1d2122;color:#f2f2f2}html.theme--documenter-dark .button.is-text[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}html.theme--documenter-dark .button.is-ghost{background:none;border-color:rgba(0,0,0,0);color:#1abc9c;text-decoration:none}html.theme--documenter-dark .button.is-ghost:hover,html.theme--documenter-dark .button.is-ghost.is-hovered{color:#1abc9c;text-decoration:underline}html.theme--documenter-dark .button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white:hover,html.theme--documenter-dark .button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white:focus,html.theme--documenter-dark .button.is-white.is-focused{border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white:focus:not(:active),html.theme--documenter-dark .button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--documenter-dark .button.is-white:active,html.theme--documenter-dark .button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}html.theme--documenter-dark .button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .button.is-white.is-inverted:hover,html.theme--documenter-dark .button.is-white.is-inverted.is-hovered{background-color:#000}html.theme--documenter-dark .button.is-white.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-white.is-outlined:hover,html.theme--documenter-dark .button.is-white.is-outlined.is-hovered,html.theme--documenter-dark .button.is-white.is-outlined:focus,html.theme--documenter-dark .button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--documenter-dark .button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-white.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-white.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-white.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-white.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--documenter-dark .button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black:hover,html.theme--documenter-dark .button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black:focus,html.theme--documenter-dark .button.is-black.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black:focus:not(:active),html.theme--documenter-dark .button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--documenter-dark .button.is-black:active,html.theme--documenter-dark .button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}html.theme--documenter-dark .button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-inverted:hover,html.theme--documenter-dark .button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-black.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-outlined:hover,html.theme--documenter-dark .button.is-black.is-outlined.is-hovered,html.theme--documenter-dark .button.is-black.is-outlined:focus,html.theme--documenter-dark .button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--documenter-dark .button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-black.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-black.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-black.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-black.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-light{background-color:#ecf0f1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light:hover,html.theme--documenter-dark .button.is-light.is-hovered{background-color:#e5eaec;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light:focus,html.theme--documenter-dark .button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light:focus:not(:active),html.theme--documenter-dark .button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(236,240,241,0.25)}html.theme--documenter-dark .button.is-light:active,html.theme--documenter-dark .button.is-light.is-active{background-color:#dde4e6;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light{background-color:#ecf0f1;border-color:#ecf0f1;box-shadow:none}html.theme--documenter-dark .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-inverted:hover,html.theme--documenter-dark .button.is-light.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--documenter-dark .button.is-light.is-outlined{background-color:transparent;border-color:#ecf0f1;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-outlined:hover,html.theme--documenter-dark .button.is-light.is-outlined.is-hovered,html.theme--documenter-dark .button.is-light.is-outlined:focus,html.theme--documenter-dark .button.is-light.is-outlined.is-focused{background-color:#ecf0f1;border-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #ecf0f1 #ecf0f1 !important}html.theme--documenter-dark .button.is-light.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-light.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-light.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-light.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--documenter-dark .button.is-light.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light.is-outlined{background-color:transparent;border-color:#ecf0f1;box-shadow:none;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ecf0f1 #ecf0f1 !important}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-dark,html.theme--documenter-dark .content kbd.button{background-color:#282f2f;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-dark:hover,html.theme--documenter-dark .content kbd.button:hover,html.theme--documenter-dark .button.is-dark.is-hovered,html.theme--documenter-dark .content kbd.button.is-hovered{background-color:#232829;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-dark:focus,html.theme--documenter-dark .content kbd.button:focus,html.theme--documenter-dark .button.is-dark.is-focused,html.theme--documenter-dark .content kbd.button.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-dark:focus:not(:active),html.theme--documenter-dark .content kbd.button:focus:not(:active),html.theme--documenter-dark .button.is-dark.is-focused:not(:active),html.theme--documenter-dark .content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(40,47,47,0.25)}html.theme--documenter-dark .button.is-dark:active,html.theme--documenter-dark .content kbd.button:active,html.theme--documenter-dark .button.is-dark.is-active,html.theme--documenter-dark .content kbd.button.is-active{background-color:#1d2122;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-dark[disabled],html.theme--documenter-dark .content kbd.button[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark,fieldset[disabled] html.theme--documenter-dark .content kbd.button{background-color:#282f2f;border-color:#282f2f;box-shadow:none}html.theme--documenter-dark .button.is-dark.is-inverted,html.theme--documenter-dark .content kbd.button.is-inverted{background-color:#fff;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-inverted:hover,html.theme--documenter-dark .content kbd.button.is-inverted:hover,html.theme--documenter-dark .button.is-dark.is-inverted.is-hovered,html.theme--documenter-dark .content kbd.button.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-dark.is-inverted[disabled],html.theme--documenter-dark .content kbd.button.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark.is-inverted,fieldset[disabled] html.theme--documenter-dark .content kbd.button.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-loading::after,html.theme--documenter-dark .content kbd.button.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-dark.is-outlined,html.theme--documenter-dark .content kbd.button.is-outlined{background-color:transparent;border-color:#282f2f;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-outlined:hover,html.theme--documenter-dark .content kbd.button.is-outlined:hover,html.theme--documenter-dark .button.is-dark.is-outlined.is-hovered,html.theme--documenter-dark .content kbd.button.is-outlined.is-hovered,html.theme--documenter-dark .button.is-dark.is-outlined:focus,html.theme--documenter-dark .content kbd.button.is-outlined:focus,html.theme--documenter-dark .button.is-dark.is-outlined.is-focused,html.theme--documenter-dark .content kbd.button.is-outlined.is-focused{background-color:#282f2f;border-color:#282f2f;color:#fff}html.theme--documenter-dark .button.is-dark.is-outlined.is-loading::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #282f2f #282f2f !important}html.theme--documenter-dark .button.is-dark.is-outlined.is-loading:hover::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-dark.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-dark.is-outlined.is-loading:focus::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-dark.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-dark.is-outlined[disabled],html.theme--documenter-dark .content kbd.button.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark.is-outlined,fieldset[disabled] html.theme--documenter-dark .content kbd.button.is-outlined{background-color:transparent;border-color:#282f2f;box-shadow:none;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined:hover,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined:focus,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-focused,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-focused{background-color:#fff;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #282f2f #282f2f !important}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined[disabled],html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined,fieldset[disabled] html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-primary,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink{background-color:#375a7f;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary:hover,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#335476;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary:focus,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:focus,html.theme--documenter-dark .button.is-primary.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary:focus:not(:active),html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:focus:not(:active),html.theme--documenter-dark .button.is-primary.is-focused:not(:active),html.theme--documenter-dark .docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(55,90,127,0.25)}html.theme--documenter-dark .button.is-primary:active,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:active,html.theme--documenter-dark .button.is-primary.is-active,html.theme--documenter-dark .docstring>section>a.button.is-active.docs-sourcelink{background-color:#2f4d6d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary[disabled],html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink{background-color:#375a7f;border-color:#375a7f;box-shadow:none}html.theme--documenter-dark .button.is-primary.is-inverted,html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-inverted:hover,html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-inverted.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}html.theme--documenter-dark .button.is-primary.is-inverted[disabled],html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary.is-inverted,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-loading::after,html.theme--documenter-dark .docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-primary.is-outlined,html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#375a7f;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-outlined:hover,html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-outlined.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,html.theme--documenter-dark .button.is-primary.is-outlined:focus,html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink:focus,html.theme--documenter-dark .button.is-primary.is-outlined.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#375a7f;border-color:#375a7f;color:#fff}html.theme--documenter-dark .button.is-primary.is-outlined.is-loading::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #375a7f #375a7f !important}html.theme--documenter-dark .button.is-primary.is-outlined.is-loading:hover::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--documenter-dark .button.is-primary.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--documenter-dark .button.is-primary.is-outlined.is-loading:focus::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--documenter-dark .button.is-primary.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-primary.is-outlined[disabled],html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary.is-outlined,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#375a7f;box-shadow:none;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined:hover,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined:focus,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #375a7f #375a7f !important}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined[disabled],html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-primary.is-light,html.theme--documenter-dark .docstring>section>a.button.is-light.docs-sourcelink{background-color:#f1f5f9;color:#4d7eb2}html.theme--documenter-dark .button.is-primary.is-light:hover,html.theme--documenter-dark .docstring>section>a.button.is-light.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-light.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#e8eef5;border-color:transparent;color:#4d7eb2}html.theme--documenter-dark .button.is-primary.is-light:active,html.theme--documenter-dark .docstring>section>a.button.is-light.docs-sourcelink:active,html.theme--documenter-dark .button.is-primary.is-light.is-active,html.theme--documenter-dark .docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#dfe8f1;border-color:transparent;color:#4d7eb2}html.theme--documenter-dark .button.is-link{background-color:#1abc9c;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link:hover,html.theme--documenter-dark .button.is-link.is-hovered{background-color:#18b193;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link:focus,html.theme--documenter-dark .button.is-link.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link:focus:not(:active),html.theme--documenter-dark .button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .button.is-link:active,html.theme--documenter-dark .button.is-link.is-active{background-color:#17a689;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link{background-color:#1abc9c;border-color:#1abc9c;box-shadow:none}html.theme--documenter-dark .button.is-link.is-inverted{background-color:#fff;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-inverted:hover,html.theme--documenter-dark .button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-link.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-link.is-outlined{background-color:transparent;border-color:#1abc9c;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-outlined:hover,html.theme--documenter-dark .button.is-link.is-outlined.is-hovered,html.theme--documenter-dark .button.is-link.is-outlined:focus,html.theme--documenter-dark .button.is-link.is-outlined.is-focused{background-color:#1abc9c;border-color:#1abc9c;color:#fff}html.theme--documenter-dark .button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #1abc9c #1abc9c !important}html.theme--documenter-dark .button.is-link.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-link.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-link.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-link.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link.is-outlined{background-color:transparent;border-color:#1abc9c;box-shadow:none;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #1abc9c #1abc9c !important}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-link.is-light{background-color:#edfdf9;color:#15987e}html.theme--documenter-dark .button.is-link.is-light:hover,html.theme--documenter-dark .button.is-link.is-light.is-hovered{background-color:#e2fbf6;border-color:transparent;color:#15987e}html.theme--documenter-dark .button.is-link.is-light:active,html.theme--documenter-dark .button.is-link.is-light.is-active{background-color:#d7f9f3;border-color:transparent;color:#15987e}html.theme--documenter-dark .button.is-info{background-color:#024c7d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:hover,html.theme--documenter-dark .button.is-info.is-hovered{background-color:#024470;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:focus,html.theme--documenter-dark .button.is-info.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:focus:not(:active),html.theme--documenter-dark .button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(2,76,125,0.25)}html.theme--documenter-dark .button.is-info:active,html.theme--documenter-dark .button.is-info.is-active{background-color:#023d64;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info{background-color:#024c7d;border-color:#024c7d;box-shadow:none}html.theme--documenter-dark .button.is-info.is-inverted{background-color:#fff;color:#024c7d}html.theme--documenter-dark .button.is-info.is-inverted:hover,html.theme--documenter-dark .button.is-info.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-info.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#024c7d}html.theme--documenter-dark .button.is-info.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-info.is-outlined{background-color:transparent;border-color:#024c7d;color:#024c7d}html.theme--documenter-dark .button.is-info.is-outlined:hover,html.theme--documenter-dark .button.is-info.is-outlined.is-hovered,html.theme--documenter-dark .button.is-info.is-outlined:focus,html.theme--documenter-dark .button.is-info.is-outlined.is-focused{background-color:#024c7d;border-color:#024c7d;color:#fff}html.theme--documenter-dark .button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #024c7d #024c7d !important}html.theme--documenter-dark .button.is-info.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-info.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-info.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-info.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info.is-outlined{background-color:transparent;border-color:#024c7d;box-shadow:none;color:#024c7d}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-focused{background-color:#fff;color:#024c7d}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #024c7d #024c7d !important}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-info.is-light{background-color:#ebf7ff;color:#0e9dfb}html.theme--documenter-dark .button.is-info.is-light:hover,html.theme--documenter-dark .button.is-info.is-light.is-hovered{background-color:#def2fe;border-color:transparent;color:#0e9dfb}html.theme--documenter-dark .button.is-info.is-light:active,html.theme--documenter-dark .button.is-info.is-light.is-active{background-color:#d2edfe;border-color:transparent;color:#0e9dfb}html.theme--documenter-dark .button.is-success{background-color:#008438;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:hover,html.theme--documenter-dark .button.is-success.is-hovered{background-color:#073;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:focus,html.theme--documenter-dark .button.is-success.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:focus:not(:active),html.theme--documenter-dark .button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(0,132,56,0.25)}html.theme--documenter-dark .button.is-success:active,html.theme--documenter-dark .button.is-success.is-active{background-color:#006b2d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success{background-color:#008438;border-color:#008438;box-shadow:none}html.theme--documenter-dark .button.is-success.is-inverted{background-color:#fff;color:#008438}html.theme--documenter-dark .button.is-success.is-inverted:hover,html.theme--documenter-dark .button.is-success.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-success.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#008438}html.theme--documenter-dark .button.is-success.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-success.is-outlined{background-color:transparent;border-color:#008438;color:#008438}html.theme--documenter-dark .button.is-success.is-outlined:hover,html.theme--documenter-dark .button.is-success.is-outlined.is-hovered,html.theme--documenter-dark .button.is-success.is-outlined:focus,html.theme--documenter-dark .button.is-success.is-outlined.is-focused{background-color:#008438;border-color:#008438;color:#fff}html.theme--documenter-dark .button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #008438 #008438 !important}html.theme--documenter-dark .button.is-success.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-success.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-success.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-success.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success.is-outlined{background-color:transparent;border-color:#008438;box-shadow:none;color:#008438}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-focused{background-color:#fff;color:#008438}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #008438 #008438 !important}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-success.is-light{background-color:#ebfff3;color:#00eb64}html.theme--documenter-dark .button.is-success.is-light:hover,html.theme--documenter-dark .button.is-success.is-light.is-hovered{background-color:#deffec;border-color:transparent;color:#00eb64}html.theme--documenter-dark .button.is-success.is-light:active,html.theme--documenter-dark .button.is-success.is-light.is-active{background-color:#d1ffe5;border-color:transparent;color:#00eb64}html.theme--documenter-dark .button.is-warning{background-color:#ad8100;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning:hover,html.theme--documenter-dark .button.is-warning.is-hovered{background-color:#a07700;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning:focus,html.theme--documenter-dark .button.is-warning.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning:focus:not(:active),html.theme--documenter-dark .button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(173,129,0,0.25)}html.theme--documenter-dark .button.is-warning:active,html.theme--documenter-dark .button.is-warning.is-active{background-color:#946e00;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning{background-color:#ad8100;border-color:#ad8100;box-shadow:none}html.theme--documenter-dark .button.is-warning.is-inverted{background-color:#fff;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-inverted:hover,html.theme--documenter-dark .button.is-warning.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-warning.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-warning.is-outlined{background-color:transparent;border-color:#ad8100;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-outlined:hover,html.theme--documenter-dark .button.is-warning.is-outlined.is-hovered,html.theme--documenter-dark .button.is-warning.is-outlined:focus,html.theme--documenter-dark .button.is-warning.is-outlined.is-focused{background-color:#ad8100;border-color:#ad8100;color:#fff}html.theme--documenter-dark .button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #ad8100 #ad8100 !important}html.theme--documenter-dark .button.is-warning.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-warning.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-warning.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-warning.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-warning.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-outlined{background-color:transparent;border-color:#ad8100;box-shadow:none;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-focused{background-color:#fff;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ad8100 #ad8100 !important}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-warning.is-light{background-color:#fffaeb;color:#d19c00}html.theme--documenter-dark .button.is-warning.is-light:hover,html.theme--documenter-dark .button.is-warning.is-light.is-hovered{background-color:#fff7de;border-color:transparent;color:#d19c00}html.theme--documenter-dark .button.is-warning.is-light:active,html.theme--documenter-dark .button.is-warning.is-light.is-active{background-color:#fff3d1;border-color:transparent;color:#d19c00}html.theme--documenter-dark .button.is-danger{background-color:#9e1b0d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:hover,html.theme--documenter-dark .button.is-danger.is-hovered{background-color:#92190c;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:focus,html.theme--documenter-dark .button.is-danger.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:focus:not(:active),html.theme--documenter-dark .button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(158,27,13,0.25)}html.theme--documenter-dark .button.is-danger:active,html.theme--documenter-dark .button.is-danger.is-active{background-color:#86170b;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger{background-color:#9e1b0d;border-color:#9e1b0d;box-shadow:none}html.theme--documenter-dark .button.is-danger.is-inverted{background-color:#fff;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-inverted:hover,html.theme--documenter-dark .button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-danger.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-danger.is-outlined{background-color:transparent;border-color:#9e1b0d;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-outlined:hover,html.theme--documenter-dark .button.is-danger.is-outlined.is-hovered,html.theme--documenter-dark .button.is-danger.is-outlined:focus,html.theme--documenter-dark .button.is-danger.is-outlined.is-focused{background-color:#9e1b0d;border-color:#9e1b0d;color:#fff}html.theme--documenter-dark .button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #9e1b0d #9e1b0d !important}html.theme--documenter-dark .button.is-danger.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-danger.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-danger.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-danger.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger.is-outlined{background-color:transparent;border-color:#9e1b0d;box-shadow:none;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #9e1b0d #9e1b0d !important}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-danger.is-light{background-color:#fdeeec;color:#ec311d}html.theme--documenter-dark .button.is-danger.is-light:hover,html.theme--documenter-dark .button.is-danger.is-light.is-hovered{background-color:#fce3e0;border-color:transparent;color:#ec311d}html.theme--documenter-dark .button.is-danger.is-light:active,html.theme--documenter-dark .button.is-danger.is-light.is-active{background-color:#fcd8d5;border-color:transparent;color:#ec311d}html.theme--documenter-dark .button.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}html.theme--documenter-dark .button.is-small:not(.is-rounded),html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:3px}html.theme--documenter-dark .button.is-normal{font-size:1rem}html.theme--documenter-dark .button.is-medium{font-size:1.25rem}html.theme--documenter-dark .button.is-large{font-size:1.5rem}html.theme--documenter-dark .button[disabled],fieldset[disabled] html.theme--documenter-dark .button{background-color:#8c9b9d;border-color:#5e6d6f;box-shadow:none;opacity:.5}html.theme--documenter-dark .button.is-fullwidth{display:flex;width:100%}html.theme--documenter-dark .button.is-loading{color:transparent !important;pointer-events:none}html.theme--documenter-dark .button.is-loading::after{position:absolute;left:calc(50% - (1em * 0.5));top:calc(50% - (1em * 0.5));position:absolute !important}html.theme--documenter-dark .button.is-static{background-color:#282f2f;border-color:#5e6d6f;color:#dbdee0;box-shadow:none;pointer-events:none}html.theme--documenter-dark .button.is-rounded,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.button{border-radius:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}html.theme--documenter-dark .buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--documenter-dark .buttons .button{margin-bottom:0.5rem}html.theme--documenter-dark .buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}html.theme--documenter-dark .buttons:last-child{margin-bottom:-0.5rem}html.theme--documenter-dark .buttons:not(:last-child){margin-bottom:1rem}html.theme--documenter-dark .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}html.theme--documenter-dark .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:3px}html.theme--documenter-dark .buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}html.theme--documenter-dark .buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}html.theme--documenter-dark .buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}html.theme--documenter-dark .buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}html.theme--documenter-dark .buttons.has-addons .button:last-child{margin-right:0}html.theme--documenter-dark .buttons.has-addons .button:hover,html.theme--documenter-dark .buttons.has-addons .button.is-hovered{z-index:2}html.theme--documenter-dark .buttons.has-addons .button:focus,html.theme--documenter-dark .buttons.has-addons .button.is-focused,html.theme--documenter-dark .buttons.has-addons .button:active,html.theme--documenter-dark .buttons.has-addons .button.is-active,html.theme--documenter-dark .buttons.has-addons .button.is-selected{z-index:3}html.theme--documenter-dark .buttons.has-addons .button:focus:hover,html.theme--documenter-dark .buttons.has-addons .button.is-focused:hover,html.theme--documenter-dark .buttons.has-addons .button:active:hover,html.theme--documenter-dark .buttons.has-addons .button.is-active:hover,html.theme--documenter-dark .buttons.has-addons .button.is-selected:hover{z-index:4}html.theme--documenter-dark .buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .buttons.is-centered{justify-content:center}html.theme--documenter-dark .buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}html.theme--documenter-dark .buttons.is-right{justify-content:flex-end}html.theme--documenter-dark .buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}@media screen and (max-width: 768px){html.theme--documenter-dark .button.is-responsive.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}html.theme--documenter-dark .button.is-responsive,html.theme--documenter-dark .button.is-responsive.is-normal{font-size:.65625rem}html.theme--documenter-dark .button.is-responsive.is-medium{font-size:.75rem}html.theme--documenter-dark .button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .button.is-responsive.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}html.theme--documenter-dark .button.is-responsive,html.theme--documenter-dark .button.is-responsive.is-normal{font-size:.75rem}html.theme--documenter-dark .button.is-responsive.is-medium{font-size:1rem}html.theme--documenter-dark .button.is-responsive.is-large{font-size:1.25rem}}html.theme--documenter-dark .container{flex-grow:1;margin:0 auto;position:relative;width:auto}html.theme--documenter-dark .container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){html.theme--documenter-dark .container{max-width:992px}}@media screen and (max-width: 1215px){html.theme--documenter-dark .container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){html.theme--documenter-dark .container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){html.theme--documenter-dark .container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){html.theme--documenter-dark .container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}html.theme--documenter-dark .content li+li{margin-top:0.25em}html.theme--documenter-dark .content p:not(:last-child),html.theme--documenter-dark .content dl:not(:last-child),html.theme--documenter-dark .content ol:not(:last-child),html.theme--documenter-dark .content ul:not(:last-child),html.theme--documenter-dark .content blockquote:not(:last-child),html.theme--documenter-dark .content pre:not(:last-child),html.theme--documenter-dark .content table:not(:last-child){margin-bottom:1em}html.theme--documenter-dark .content h1,html.theme--documenter-dark .content h2,html.theme--documenter-dark .content h3,html.theme--documenter-dark .content h4,html.theme--documenter-dark .content h5,html.theme--documenter-dark .content h6{color:#f2f2f2;font-weight:600;line-height:1.125}html.theme--documenter-dark .content h1{font-size:2em;margin-bottom:0.5em}html.theme--documenter-dark .content h1:not(:first-child){margin-top:1em}html.theme--documenter-dark .content h2{font-size:1.75em;margin-bottom:0.5714em}html.theme--documenter-dark .content h2:not(:first-child){margin-top:1.1428em}html.theme--documenter-dark .content h3{font-size:1.5em;margin-bottom:0.6666em}html.theme--documenter-dark .content h3:not(:first-child){margin-top:1.3333em}html.theme--documenter-dark .content h4{font-size:1.25em;margin-bottom:0.8em}html.theme--documenter-dark .content h5{font-size:1.125em;margin-bottom:0.8888em}html.theme--documenter-dark .content h6{font-size:1em;margin-bottom:1em}html.theme--documenter-dark .content blockquote{background-color:#282f2f;border-left:5px solid #5e6d6f;padding:1.25em 1.5em}html.theme--documenter-dark .content ol{list-style-position:outside;margin-left:2em;margin-top:1em}html.theme--documenter-dark .content ol:not([type]){list-style-type:decimal}html.theme--documenter-dark .content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}html.theme--documenter-dark .content ol.is-lower-roman:not([type]){list-style-type:lower-roman}html.theme--documenter-dark .content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}html.theme--documenter-dark .content ol.is-upper-roman:not([type]){list-style-type:upper-roman}html.theme--documenter-dark .content ul{list-style:disc outside;margin-left:2em;margin-top:1em}html.theme--documenter-dark .content ul ul{list-style-type:circle;margin-top:0.5em}html.theme--documenter-dark .content ul ul ul{list-style-type:square}html.theme--documenter-dark .content dd{margin-left:2em}html.theme--documenter-dark .content figure{margin-left:2em;margin-right:2em;text-align:center}html.theme--documenter-dark .content figure:not(:first-child){margin-top:2em}html.theme--documenter-dark .content figure:not(:last-child){margin-bottom:2em}html.theme--documenter-dark .content figure img{display:inline-block}html.theme--documenter-dark .content figure figcaption{font-style:italic}html.theme--documenter-dark .content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}html.theme--documenter-dark .content sup,html.theme--documenter-dark .content sub{font-size:75%}html.theme--documenter-dark .content table{width:100%}html.theme--documenter-dark .content table td,html.theme--documenter-dark .content table th{border:1px solid #5e6d6f;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--documenter-dark .content table th{color:#f2f2f2}html.theme--documenter-dark .content table th:not([align]){text-align:inherit}html.theme--documenter-dark .content table thead td,html.theme--documenter-dark .content table thead th{border-width:0 0 2px;color:#f2f2f2}html.theme--documenter-dark .content table tfoot td,html.theme--documenter-dark .content table tfoot th{border-width:2px 0 0;color:#f2f2f2}html.theme--documenter-dark .content table tbody tr:last-child td,html.theme--documenter-dark .content table tbody tr:last-child th{border-bottom-width:0}html.theme--documenter-dark .content .tabs li+li{margin-top:0}html.theme--documenter-dark .content.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.content{font-size:.75rem}html.theme--documenter-dark .content.is-normal{font-size:1rem}html.theme--documenter-dark .content.is-medium{font-size:1.25rem}html.theme--documenter-dark .content.is-large{font-size:1.5rem}html.theme--documenter-dark .icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}html.theme--documenter-dark .icon.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}html.theme--documenter-dark .icon.is-medium{height:2rem;width:2rem}html.theme--documenter-dark .icon.is-large{height:3rem;width:3rem}html.theme--documenter-dark .icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}html.theme--documenter-dark .icon-text .icon{flex-grow:0;flex-shrink:0}html.theme--documenter-dark .icon-text .icon:not(:last-child){margin-right:.25em}html.theme--documenter-dark .icon-text .icon:not(:first-child){margin-left:.25em}html.theme--documenter-dark div.icon-text{display:flex}html.theme--documenter-dark .image,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img{display:block;position:relative}html.theme--documenter-dark .image img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}html.theme--documenter-dark .image img.is-rounded,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:9999px}html.theme--documenter-dark .image.is-fullwidth,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}html.theme--documenter-dark .image.is-square img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--documenter-dark .image.is-square .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--documenter-dark .image.is-1by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--documenter-dark .image.is-1by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--documenter-dark .image.is-5by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--documenter-dark .image.is-5by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--documenter-dark .image.is-4by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--documenter-dark .image.is-4by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--documenter-dark .image.is-3by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--documenter-dark .image.is-3by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--documenter-dark .image.is-5by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--documenter-dark .image.is-5by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--documenter-dark .image.is-16by9 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--documenter-dark .image.is-16by9 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--documenter-dark .image.is-2by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--documenter-dark .image.is-2by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--documenter-dark .image.is-3by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--documenter-dark .image.is-3by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--documenter-dark .image.is-4by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--documenter-dark .image.is-4by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--documenter-dark .image.is-3by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--documenter-dark .image.is-3by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--documenter-dark .image.is-2by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--documenter-dark .image.is-2by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--documenter-dark .image.is-3by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--documenter-dark .image.is-3by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--documenter-dark .image.is-9by16 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--documenter-dark .image.is-9by16 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--documenter-dark .image.is-1by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--documenter-dark .image.is-1by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--documenter-dark .image.is-1by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--documenter-dark .image.is-1by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}html.theme--documenter-dark .image.is-square,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square,html.theme--documenter-dark .image.is-1by1,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}html.theme--documenter-dark .image.is-5by4,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}html.theme--documenter-dark .image.is-4by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}html.theme--documenter-dark .image.is-3by2,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}html.theme--documenter-dark .image.is-5by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}html.theme--documenter-dark .image.is-16by9,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}html.theme--documenter-dark .image.is-2by1,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}html.theme--documenter-dark .image.is-3by1,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}html.theme--documenter-dark .image.is-4by5,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}html.theme--documenter-dark .image.is-3by4,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}html.theme--documenter-dark .image.is-2by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}html.theme--documenter-dark .image.is-3by5,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}html.theme--documenter-dark .image.is-9by16,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}html.theme--documenter-dark .image.is-1by2,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}html.theme--documenter-dark .image.is-1by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}html.theme--documenter-dark .image.is-16x16,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}html.theme--documenter-dark .image.is-24x24,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}html.theme--documenter-dark .image.is-32x32,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}html.theme--documenter-dark .image.is-48x48,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}html.theme--documenter-dark .image.is-64x64,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}html.theme--documenter-dark .image.is-96x96,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}html.theme--documenter-dark .image.is-128x128,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}html.theme--documenter-dark .notification{background-color:#282f2f;border-radius:.4em;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}html.theme--documenter-dark .notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--documenter-dark .notification strong{color:currentColor}html.theme--documenter-dark .notification code,html.theme--documenter-dark .notification pre{background:#fff}html.theme--documenter-dark .notification pre code{background:transparent}html.theme--documenter-dark .notification>.delete{right:.5rem;position:absolute;top:0.5rem}html.theme--documenter-dark .notification .title,html.theme--documenter-dark .notification .subtitle,html.theme--documenter-dark .notification .content{color:currentColor}html.theme--documenter-dark .notification.is-white{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .notification.is-black{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .notification.is-light{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .notification.is-dark,html.theme--documenter-dark .content kbd.notification{background-color:#282f2f;color:#fff}html.theme--documenter-dark .notification.is-primary,html.theme--documenter-dark .docstring>section>a.notification.docs-sourcelink{background-color:#375a7f;color:#fff}html.theme--documenter-dark .notification.is-primary.is-light,html.theme--documenter-dark .docstring>section>a.notification.is-light.docs-sourcelink{background-color:#f1f5f9;color:#4d7eb2}html.theme--documenter-dark .notification.is-link{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .notification.is-link.is-light{background-color:#edfdf9;color:#15987e}html.theme--documenter-dark .notification.is-info{background-color:#024c7d;color:#fff}html.theme--documenter-dark .notification.is-info.is-light{background-color:#ebf7ff;color:#0e9dfb}html.theme--documenter-dark .notification.is-success{background-color:#008438;color:#fff}html.theme--documenter-dark .notification.is-success.is-light{background-color:#ebfff3;color:#00eb64}html.theme--documenter-dark .notification.is-warning{background-color:#ad8100;color:#fff}html.theme--documenter-dark .notification.is-warning.is-light{background-color:#fffaeb;color:#d19c00}html.theme--documenter-dark .notification.is-danger{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .notification.is-danger.is-light{background-color:#fdeeec;color:#ec311d}html.theme--documenter-dark .progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}html.theme--documenter-dark .progress::-webkit-progress-bar{background-color:#343c3d}html.theme--documenter-dark .progress::-webkit-progress-value{background-color:#dbdee0}html.theme--documenter-dark .progress::-moz-progress-bar{background-color:#dbdee0}html.theme--documenter-dark .progress::-ms-fill{background-color:#dbdee0;border:none}html.theme--documenter-dark .progress.is-white::-webkit-progress-value{background-color:#fff}html.theme--documenter-dark .progress.is-white::-moz-progress-bar{background-color:#fff}html.theme--documenter-dark .progress.is-white::-ms-fill{background-color:#fff}html.theme--documenter-dark .progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-black::-webkit-progress-value{background-color:#0a0a0a}html.theme--documenter-dark .progress.is-black::-moz-progress-bar{background-color:#0a0a0a}html.theme--documenter-dark .progress.is-black::-ms-fill{background-color:#0a0a0a}html.theme--documenter-dark .progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-light::-webkit-progress-value{background-color:#ecf0f1}html.theme--documenter-dark .progress.is-light::-moz-progress-bar{background-color:#ecf0f1}html.theme--documenter-dark .progress.is-light::-ms-fill{background-color:#ecf0f1}html.theme--documenter-dark .progress.is-light:indeterminate{background-image:linear-gradient(to right, #ecf0f1 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-dark::-webkit-progress-value,html.theme--documenter-dark .content kbd.progress::-webkit-progress-value{background-color:#282f2f}html.theme--documenter-dark .progress.is-dark::-moz-progress-bar,html.theme--documenter-dark .content kbd.progress::-moz-progress-bar{background-color:#282f2f}html.theme--documenter-dark .progress.is-dark::-ms-fill,html.theme--documenter-dark .content kbd.progress::-ms-fill{background-color:#282f2f}html.theme--documenter-dark .progress.is-dark:indeterminate,html.theme--documenter-dark .content kbd.progress:indeterminate{background-image:linear-gradient(to right, #282f2f 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-primary::-webkit-progress-value,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#375a7f}html.theme--documenter-dark .progress.is-primary::-moz-progress-bar,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#375a7f}html.theme--documenter-dark .progress.is-primary::-ms-fill,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#375a7f}html.theme--documenter-dark .progress.is-primary:indeterminate,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #375a7f 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-link::-webkit-progress-value{background-color:#1abc9c}html.theme--documenter-dark .progress.is-link::-moz-progress-bar{background-color:#1abc9c}html.theme--documenter-dark .progress.is-link::-ms-fill{background-color:#1abc9c}html.theme--documenter-dark .progress.is-link:indeterminate{background-image:linear-gradient(to right, #1abc9c 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-info::-webkit-progress-value{background-color:#024c7d}html.theme--documenter-dark .progress.is-info::-moz-progress-bar{background-color:#024c7d}html.theme--documenter-dark .progress.is-info::-ms-fill{background-color:#024c7d}html.theme--documenter-dark .progress.is-info:indeterminate{background-image:linear-gradient(to right, #024c7d 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-success::-webkit-progress-value{background-color:#008438}html.theme--documenter-dark .progress.is-success::-moz-progress-bar{background-color:#008438}html.theme--documenter-dark .progress.is-success::-ms-fill{background-color:#008438}html.theme--documenter-dark .progress.is-success:indeterminate{background-image:linear-gradient(to right, #008438 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-warning::-webkit-progress-value{background-color:#ad8100}html.theme--documenter-dark .progress.is-warning::-moz-progress-bar{background-color:#ad8100}html.theme--documenter-dark .progress.is-warning::-ms-fill{background-color:#ad8100}html.theme--documenter-dark .progress.is-warning:indeterminate{background-image:linear-gradient(to right, #ad8100 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-danger::-webkit-progress-value{background-color:#9e1b0d}html.theme--documenter-dark .progress.is-danger::-moz-progress-bar{background-color:#9e1b0d}html.theme--documenter-dark .progress.is-danger::-ms-fill{background-color:#9e1b0d}html.theme--documenter-dark .progress.is-danger:indeterminate{background-image:linear-gradient(to right, #9e1b0d 30%, #343c3d 30%)}html.theme--documenter-dark .progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#343c3d;background-image:linear-gradient(to right, #fff 30%, #343c3d 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}html.theme--documenter-dark .progress:indeterminate::-webkit-progress-bar{background-color:transparent}html.theme--documenter-dark .progress:indeterminate::-moz-progress-bar{background-color:transparent}html.theme--documenter-dark .progress:indeterminate::-ms-fill{animation-name:none}html.theme--documenter-dark .progress.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}html.theme--documenter-dark .progress.is-medium{height:1.25rem}html.theme--documenter-dark .progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}html.theme--documenter-dark .table{background-color:#343c3d;color:#fff}html.theme--documenter-dark .table td,html.theme--documenter-dark .table th{border:1px solid #5e6d6f;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--documenter-dark .table td.is-white,html.theme--documenter-dark .table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--documenter-dark .table td.is-black,html.theme--documenter-dark .table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--documenter-dark .table td.is-light,html.theme--documenter-dark .table th.is-light{background-color:#ecf0f1;border-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .table td.is-dark,html.theme--documenter-dark .table th.is-dark{background-color:#282f2f;border-color:#282f2f;color:#fff}html.theme--documenter-dark .table td.is-primary,html.theme--documenter-dark .table th.is-primary{background-color:#375a7f;border-color:#375a7f;color:#fff}html.theme--documenter-dark .table td.is-link,html.theme--documenter-dark .table th.is-link{background-color:#1abc9c;border-color:#1abc9c;color:#fff}html.theme--documenter-dark .table td.is-info,html.theme--documenter-dark .table th.is-info{background-color:#024c7d;border-color:#024c7d;color:#fff}html.theme--documenter-dark .table td.is-success,html.theme--documenter-dark .table th.is-success{background-color:#008438;border-color:#008438;color:#fff}html.theme--documenter-dark .table td.is-warning,html.theme--documenter-dark .table th.is-warning{background-color:#ad8100;border-color:#ad8100;color:#fff}html.theme--documenter-dark .table td.is-danger,html.theme--documenter-dark .table th.is-danger{background-color:#9e1b0d;border-color:#9e1b0d;color:#fff}html.theme--documenter-dark .table td.is-narrow,html.theme--documenter-dark .table th.is-narrow{white-space:nowrap;width:1%}html.theme--documenter-dark .table td.is-selected,html.theme--documenter-dark .table th.is-selected{background-color:#375a7f;color:#fff}html.theme--documenter-dark .table td.is-selected a,html.theme--documenter-dark .table td.is-selected strong,html.theme--documenter-dark .table th.is-selected a,html.theme--documenter-dark .table th.is-selected strong{color:currentColor}html.theme--documenter-dark .table td.is-vcentered,html.theme--documenter-dark .table th.is-vcentered{vertical-align:middle}html.theme--documenter-dark .table th{color:#f2f2f2}html.theme--documenter-dark .table th:not([align]){text-align:left}html.theme--documenter-dark .table tr.is-selected{background-color:#375a7f;color:#fff}html.theme--documenter-dark .table tr.is-selected a,html.theme--documenter-dark .table tr.is-selected strong{color:currentColor}html.theme--documenter-dark .table tr.is-selected td,html.theme--documenter-dark .table tr.is-selected th{border-color:#fff;color:currentColor}html.theme--documenter-dark .table thead{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .table thead td,html.theme--documenter-dark .table thead th{border-width:0 0 2px;color:#f2f2f2}html.theme--documenter-dark .table tfoot{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .table tfoot td,html.theme--documenter-dark .table tfoot th{border-width:2px 0 0;color:#f2f2f2}html.theme--documenter-dark .table tbody{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .table tbody tr:last-child td,html.theme--documenter-dark .table tbody tr:last-child th{border-bottom-width:0}html.theme--documenter-dark .table.is-bordered td,html.theme--documenter-dark .table.is-bordered th{border-width:1px}html.theme--documenter-dark .table.is-bordered tr:last-child td,html.theme--documenter-dark .table.is-bordered tr:last-child th{border-bottom-width:1px}html.theme--documenter-dark .table.is-fullwidth{width:100%}html.theme--documenter-dark .table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#282f2f}html.theme--documenter-dark .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#282f2f}html.theme--documenter-dark .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#2d3435}html.theme--documenter-dark .table.is-narrow td,html.theme--documenter-dark .table.is-narrow th{padding:0.25em 0.5em}html.theme--documenter-dark .table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#282f2f}html.theme--documenter-dark .table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}html.theme--documenter-dark .tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--documenter-dark .tags .tag,html.theme--documenter-dark .tags .content kbd,html.theme--documenter-dark .content .tags kbd,html.theme--documenter-dark .tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}html.theme--documenter-dark .tags .tag:not(:last-child),html.theme--documenter-dark .tags .content kbd:not(:last-child),html.theme--documenter-dark .content .tags kbd:not(:last-child),html.theme--documenter-dark .tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:.5rem}html.theme--documenter-dark .tags:last-child{margin-bottom:-0.5rem}html.theme--documenter-dark .tags:not(:last-child){margin-bottom:1rem}html.theme--documenter-dark .tags.are-medium .tag:not(.is-normal):not(.is-large),html.theme--documenter-dark .tags.are-medium .content kbd:not(.is-normal):not(.is-large),html.theme--documenter-dark .content .tags.are-medium kbd:not(.is-normal):not(.is-large),html.theme--documenter-dark .tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:1rem}html.theme--documenter-dark .tags.are-large .tag:not(.is-normal):not(.is-medium),html.theme--documenter-dark .tags.are-large .content kbd:not(.is-normal):not(.is-medium),html.theme--documenter-dark .content .tags.are-large kbd:not(.is-normal):not(.is-medium),html.theme--documenter-dark .tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}html.theme--documenter-dark .tags.is-centered{justify-content:center}html.theme--documenter-dark .tags.is-centered .tag,html.theme--documenter-dark .tags.is-centered .content kbd,html.theme--documenter-dark .content .tags.is-centered kbd,html.theme--documenter-dark .tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}html.theme--documenter-dark .tags.is-right{justify-content:flex-end}html.theme--documenter-dark .tags.is-right .tag:not(:first-child),html.theme--documenter-dark .tags.is-right .content kbd:not(:first-child),html.theme--documenter-dark .content .tags.is-right kbd:not(:first-child),html.theme--documenter-dark .tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}html.theme--documenter-dark .tags.is-right .tag:not(:last-child),html.theme--documenter-dark .tags.is-right .content kbd:not(:last-child),html.theme--documenter-dark .content .tags.is-right kbd:not(:last-child),html.theme--documenter-dark .tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}html.theme--documenter-dark .tags.has-addons .tag,html.theme--documenter-dark .tags.has-addons .content kbd,html.theme--documenter-dark .content .tags.has-addons kbd,html.theme--documenter-dark .tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}html.theme--documenter-dark .tags.has-addons .tag:not(:first-child),html.theme--documenter-dark .tags.has-addons .content kbd:not(:first-child),html.theme--documenter-dark .content .tags.has-addons kbd:not(:first-child),html.theme--documenter-dark .tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}html.theme--documenter-dark .tags.has-addons .tag:not(:last-child),html.theme--documenter-dark .tags.has-addons .content kbd:not(:last-child),html.theme--documenter-dark .content .tags.has-addons kbd:not(:last-child),html.theme--documenter-dark .tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}html.theme--documenter-dark .tag:not(body),html.theme--documenter-dark .content kbd:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#282f2f;border-radius:.4em;color:#fff;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:0.75em;padding-right:0.75em;white-space:nowrap}html.theme--documenter-dark .tag:not(body) .delete,html.theme--documenter-dark .content kbd:not(body) .delete,html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}html.theme--documenter-dark .tag.is-white:not(body),html.theme--documenter-dark .content kbd.is-white:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .tag.is-black:not(body),html.theme--documenter-dark .content kbd.is-black:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .tag.is-light:not(body),html.theme--documenter-dark .content kbd.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .tag.is-dark:not(body),html.theme--documenter-dark .content kbd:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-dark:not(body),html.theme--documenter-dark .content .docstring>section>kbd:not(body){background-color:#282f2f;color:#fff}html.theme--documenter-dark .tag.is-primary:not(body),html.theme--documenter-dark .content kbd.is-primary:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body){background-color:#375a7f;color:#fff}html.theme--documenter-dark .tag.is-primary.is-light:not(body),html.theme--documenter-dark .content kbd.is-primary.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f1f5f9;color:#4d7eb2}html.theme--documenter-dark .tag.is-link:not(body),html.theme--documenter-dark .content kbd.is-link:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#1abc9c;color:#fff}html.theme--documenter-dark .tag.is-link.is-light:not(body),html.theme--documenter-dark .content kbd.is-link.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#edfdf9;color:#15987e}html.theme--documenter-dark .tag.is-info:not(body),html.theme--documenter-dark .content kbd.is-info:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#024c7d;color:#fff}html.theme--documenter-dark .tag.is-info.is-light:not(body),html.theme--documenter-dark .content kbd.is-info.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#ebf7ff;color:#0e9dfb}html.theme--documenter-dark .tag.is-success:not(body),html.theme--documenter-dark .content kbd.is-success:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#008438;color:#fff}html.theme--documenter-dark .tag.is-success.is-light:not(body),html.theme--documenter-dark .content kbd.is-success.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#ebfff3;color:#00eb64}html.theme--documenter-dark .tag.is-warning:not(body),html.theme--documenter-dark .content kbd.is-warning:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#ad8100;color:#fff}html.theme--documenter-dark .tag.is-warning.is-light:not(body),html.theme--documenter-dark .content kbd.is-warning.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fffaeb;color:#d19c00}html.theme--documenter-dark .tag.is-danger:not(body),html.theme--documenter-dark .content kbd.is-danger:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .tag.is-danger.is-light:not(body),html.theme--documenter-dark .content kbd.is-danger.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#fdeeec;color:#ec311d}html.theme--documenter-dark .tag.is-normal:not(body),html.theme--documenter-dark .content kbd.is-normal:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.75rem}html.theme--documenter-dark .tag.is-medium:not(body),html.theme--documenter-dark .content kbd.is-medium:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:1rem}html.theme--documenter-dark .tag.is-large:not(body),html.theme--documenter-dark .content kbd.is-large:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}html.theme--documenter-dark .tag:not(body) .icon:first-child:not(:last-child),html.theme--documenter-dark .content kbd:not(body) .icon:first-child:not(:last-child),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}html.theme--documenter-dark .tag:not(body) .icon:last-child:not(:first-child),html.theme--documenter-dark .content kbd:not(body) .icon:last-child:not(:first-child),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}html.theme--documenter-dark .tag:not(body) .icon:first-child:last-child,html.theme--documenter-dark .content kbd:not(body) .icon:first-child:last-child,html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}html.theme--documenter-dark .tag.is-delete:not(body),html.theme--documenter-dark .content kbd.is-delete:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}html.theme--documenter-dark .tag.is-delete:not(body)::before,html.theme--documenter-dark .content kbd.is-delete:not(body)::before,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::before,html.theme--documenter-dark .tag.is-delete:not(body)::after,html.theme--documenter-dark .content kbd.is-delete:not(body)::after,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--documenter-dark .tag.is-delete:not(body)::before,html.theme--documenter-dark .content kbd.is-delete:not(body)::before,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}html.theme--documenter-dark .tag.is-delete:not(body)::after,html.theme--documenter-dark .content kbd.is-delete:not(body)::after,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}html.theme--documenter-dark .tag.is-delete:not(body):hover,html.theme--documenter-dark .content kbd.is-delete:not(body):hover,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body):hover,html.theme--documenter-dark .tag.is-delete:not(body):focus,html.theme--documenter-dark .content kbd.is-delete:not(body):focus,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#1d2122}html.theme--documenter-dark .tag.is-delete:not(body):active,html.theme--documenter-dark .content kbd.is-delete:not(body):active,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#111414}html.theme--documenter-dark .tag.is-rounded:not(body),html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:not(body),html.theme--documenter-dark .content kbd.is-rounded:not(body),html.theme--documenter-dark #documenter .docs-sidebar .content form.docs-search>input:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:9999px}html.theme--documenter-dark a.tag:hover,html.theme--documenter-dark .docstring>section>a.docs-sourcelink:hover{text-decoration:underline}html.theme--documenter-dark .title,html.theme--documenter-dark .subtitle{word-break:break-word}html.theme--documenter-dark .title em,html.theme--documenter-dark .title span,html.theme--documenter-dark .subtitle em,html.theme--documenter-dark .subtitle span{font-weight:inherit}html.theme--documenter-dark .title sub,html.theme--documenter-dark .subtitle sub{font-size:.75em}html.theme--documenter-dark .title sup,html.theme--documenter-dark .subtitle sup{font-size:.75em}html.theme--documenter-dark .title .tag,html.theme--documenter-dark .title .content kbd,html.theme--documenter-dark .content .title kbd,html.theme--documenter-dark .title .docstring>section>a.docs-sourcelink,html.theme--documenter-dark .subtitle .tag,html.theme--documenter-dark .subtitle .content kbd,html.theme--documenter-dark .content .subtitle kbd,html.theme--documenter-dark .subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}html.theme--documenter-dark .title{color:#fff;font-size:2rem;font-weight:500;line-height:1.125}html.theme--documenter-dark .title strong{color:inherit;font-weight:inherit}html.theme--documenter-dark .title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}html.theme--documenter-dark .title.is-1{font-size:3rem}html.theme--documenter-dark .title.is-2{font-size:2.5rem}html.theme--documenter-dark .title.is-3{font-size:2rem}html.theme--documenter-dark .title.is-4{font-size:1.5rem}html.theme--documenter-dark .title.is-5{font-size:1.25rem}html.theme--documenter-dark .title.is-6{font-size:1rem}html.theme--documenter-dark .title.is-7{font-size:.75rem}html.theme--documenter-dark .subtitle{color:#8c9b9d;font-size:1.25rem;font-weight:400;line-height:1.25}html.theme--documenter-dark .subtitle strong{color:#8c9b9d;font-weight:600}html.theme--documenter-dark .subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}html.theme--documenter-dark .subtitle.is-1{font-size:3rem}html.theme--documenter-dark .subtitle.is-2{font-size:2.5rem}html.theme--documenter-dark .subtitle.is-3{font-size:2rem}html.theme--documenter-dark .subtitle.is-4{font-size:1.5rem}html.theme--documenter-dark .subtitle.is-5{font-size:1.25rem}html.theme--documenter-dark .subtitle.is-6{font-size:1rem}html.theme--documenter-dark .subtitle.is-7{font-size:.75rem}html.theme--documenter-dark .heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}html.theme--documenter-dark .number{align-items:center;background-color:#282f2f;border-radius:9999px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:0.25rem 0.5rem;text-align:center;vertical-align:top}html.theme--documenter-dark .select select,html.theme--documenter-dark .textarea,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{background-color:#1f2424;border-color:#5e6d6f;border-radius:.4em;color:#dbdee0}html.theme--documenter-dark .select select::-moz-placeholder,html.theme--documenter-dark .textarea::-moz-placeholder,html.theme--documenter-dark .input::-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:#868c98}html.theme--documenter-dark .select select::-webkit-input-placeholder,html.theme--documenter-dark .textarea::-webkit-input-placeholder,html.theme--documenter-dark .input::-webkit-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:#868c98}html.theme--documenter-dark .select select:-moz-placeholder,html.theme--documenter-dark .textarea:-moz-placeholder,html.theme--documenter-dark .input:-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:#868c98}html.theme--documenter-dark .select select:-ms-input-placeholder,html.theme--documenter-dark .textarea:-ms-input-placeholder,html.theme--documenter-dark .input:-ms-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:#868c98}html.theme--documenter-dark .select select:hover,html.theme--documenter-dark .textarea:hover,html.theme--documenter-dark .input:hover,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:hover,html.theme--documenter-dark .select select.is-hovered,html.theme--documenter-dark .is-hovered.textarea,html.theme--documenter-dark .is-hovered.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#8c9b9d}html.theme--documenter-dark .select select:focus,html.theme--documenter-dark .textarea:focus,html.theme--documenter-dark .input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:focus,html.theme--documenter-dark .select select.is-focused,html.theme--documenter-dark .is-focused.textarea,html.theme--documenter-dark .is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .select select:active,html.theme--documenter-dark .textarea:active,html.theme--documenter-dark .input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:active,html.theme--documenter-dark .select select.is-active,html.theme--documenter-dark .is-active.textarea,html.theme--documenter-dark .is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{border-color:#1abc9c;box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .select select[disabled],html.theme--documenter-dark .textarea[disabled],html.theme--documenter-dark .input[disabled],html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] html.theme--documenter-dark .select select,fieldset[disabled] html.theme--documenter-dark .textarea,fieldset[disabled] html.theme--documenter-dark .input,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{background-color:#8c9b9d;border-color:#282f2f;box-shadow:none;color:#fff}html.theme--documenter-dark .select select[disabled]::-moz-placeholder,html.theme--documenter-dark .textarea[disabled]::-moz-placeholder,html.theme--documenter-dark .input[disabled]::-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .select select::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .input::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .select select[disabled]::-webkit-input-placeholder,html.theme--documenter-dark .textarea[disabled]::-webkit-input-placeholder,html.theme--documenter-dark .input[disabled]::-webkit-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark .select select::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark .input::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .select select[disabled]:-moz-placeholder,html.theme--documenter-dark .textarea[disabled]:-moz-placeholder,html.theme--documenter-dark .input[disabled]:-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .select select:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .input:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .select select[disabled]:-ms-input-placeholder,html.theme--documenter-dark .textarea[disabled]:-ms-input-placeholder,html.theme--documenter-dark .input[disabled]:-ms-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark .select select:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark .input:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .textarea,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{box-shadow:inset 0 0.0625em 0.125em rgba(10,10,10,0.05);max-width:100%;width:100%}html.theme--documenter-dark .textarea[readonly],html.theme--documenter-dark .input[readonly],html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}html.theme--documenter-dark .is-white.textarea,html.theme--documenter-dark .is-white.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}html.theme--documenter-dark .is-white.textarea:focus,html.theme--documenter-dark .is-white.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-white:focus,html.theme--documenter-dark .is-white.is-focused.textarea,html.theme--documenter-dark .is-white.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-white.textarea:active,html.theme--documenter-dark .is-white.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-white:active,html.theme--documenter-dark .is-white.is-active.textarea,html.theme--documenter-dark .is-white.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--documenter-dark .is-black.textarea,html.theme--documenter-dark .is-black.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}html.theme--documenter-dark .is-black.textarea:focus,html.theme--documenter-dark .is-black.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-black:focus,html.theme--documenter-dark .is-black.is-focused.textarea,html.theme--documenter-dark .is-black.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-black.textarea:active,html.theme--documenter-dark .is-black.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-black:active,html.theme--documenter-dark .is-black.is-active.textarea,html.theme--documenter-dark .is-black.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--documenter-dark .is-light.textarea,html.theme--documenter-dark .is-light.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-light{border-color:#ecf0f1}html.theme--documenter-dark .is-light.textarea:focus,html.theme--documenter-dark .is-light.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-light:focus,html.theme--documenter-dark .is-light.is-focused.textarea,html.theme--documenter-dark .is-light.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-light.textarea:active,html.theme--documenter-dark .is-light.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-light:active,html.theme--documenter-dark .is-light.is-active.textarea,html.theme--documenter-dark .is-light.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(236,240,241,0.25)}html.theme--documenter-dark .is-dark.textarea,html.theme--documenter-dark .content kbd.textarea,html.theme--documenter-dark .is-dark.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-dark,html.theme--documenter-dark .content kbd.input{border-color:#282f2f}html.theme--documenter-dark .is-dark.textarea:focus,html.theme--documenter-dark .content kbd.textarea:focus,html.theme--documenter-dark .is-dark.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-dark:focus,html.theme--documenter-dark .content kbd.input:focus,html.theme--documenter-dark .is-dark.is-focused.textarea,html.theme--documenter-dark .content kbd.is-focused.textarea,html.theme--documenter-dark .is-dark.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .content kbd.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar .content form.docs-search>input.is-focused,html.theme--documenter-dark .is-dark.textarea:active,html.theme--documenter-dark .content kbd.textarea:active,html.theme--documenter-dark .is-dark.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-dark:active,html.theme--documenter-dark .content kbd.input:active,html.theme--documenter-dark .is-dark.is-active.textarea,html.theme--documenter-dark .content kbd.is-active.textarea,html.theme--documenter-dark .is-dark.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--documenter-dark .content kbd.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(40,47,47,0.25)}html.theme--documenter-dark .is-primary.textarea,html.theme--documenter-dark .docstring>section>a.textarea.docs-sourcelink,html.theme--documenter-dark .is-primary.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-primary,html.theme--documenter-dark .docstring>section>a.input.docs-sourcelink{border-color:#375a7f}html.theme--documenter-dark .is-primary.textarea:focus,html.theme--documenter-dark .docstring>section>a.textarea.docs-sourcelink:focus,html.theme--documenter-dark .is-primary.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-primary:focus,html.theme--documenter-dark .docstring>section>a.input.docs-sourcelink:focus,html.theme--documenter-dark .is-primary.is-focused.textarea,html.theme--documenter-dark .docstring>section>a.is-focused.textarea.docs-sourcelink,html.theme--documenter-dark .is-primary.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .docstring>section>a.is-focused.input.docs-sourcelink,html.theme--documenter-dark .is-primary.textarea:active,html.theme--documenter-dark .docstring>section>a.textarea.docs-sourcelink:active,html.theme--documenter-dark .is-primary.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-primary:active,html.theme--documenter-dark .docstring>section>a.input.docs-sourcelink:active,html.theme--documenter-dark .is-primary.is-active.textarea,html.theme--documenter-dark .docstring>section>a.is-active.textarea.docs-sourcelink,html.theme--documenter-dark .is-primary.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--documenter-dark .docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(55,90,127,0.25)}html.theme--documenter-dark .is-link.textarea,html.theme--documenter-dark .is-link.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-link{border-color:#1abc9c}html.theme--documenter-dark .is-link.textarea:focus,html.theme--documenter-dark .is-link.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-link:focus,html.theme--documenter-dark .is-link.is-focused.textarea,html.theme--documenter-dark .is-link.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-link.textarea:active,html.theme--documenter-dark .is-link.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-link:active,html.theme--documenter-dark .is-link.is-active.textarea,html.theme--documenter-dark .is-link.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .is-info.textarea,html.theme--documenter-dark .is-info.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-info{border-color:#024c7d}html.theme--documenter-dark .is-info.textarea:focus,html.theme--documenter-dark .is-info.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-info:focus,html.theme--documenter-dark .is-info.is-focused.textarea,html.theme--documenter-dark .is-info.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-info.textarea:active,html.theme--documenter-dark .is-info.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-info:active,html.theme--documenter-dark .is-info.is-active.textarea,html.theme--documenter-dark .is-info.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(2,76,125,0.25)}html.theme--documenter-dark .is-success.textarea,html.theme--documenter-dark .is-success.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-success{border-color:#008438}html.theme--documenter-dark .is-success.textarea:focus,html.theme--documenter-dark .is-success.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-success:focus,html.theme--documenter-dark .is-success.is-focused.textarea,html.theme--documenter-dark .is-success.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-success.textarea:active,html.theme--documenter-dark .is-success.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-success:active,html.theme--documenter-dark .is-success.is-active.textarea,html.theme--documenter-dark .is-success.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(0,132,56,0.25)}html.theme--documenter-dark .is-warning.textarea,html.theme--documenter-dark .is-warning.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#ad8100}html.theme--documenter-dark .is-warning.textarea:focus,html.theme--documenter-dark .is-warning.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-warning:focus,html.theme--documenter-dark .is-warning.is-focused.textarea,html.theme--documenter-dark .is-warning.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-warning.textarea:active,html.theme--documenter-dark .is-warning.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-warning:active,html.theme--documenter-dark .is-warning.is-active.textarea,html.theme--documenter-dark .is-warning.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(173,129,0,0.25)}html.theme--documenter-dark .is-danger.textarea,html.theme--documenter-dark .is-danger.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#9e1b0d}html.theme--documenter-dark .is-danger.textarea:focus,html.theme--documenter-dark .is-danger.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-danger:focus,html.theme--documenter-dark .is-danger.is-focused.textarea,html.theme--documenter-dark .is-danger.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-danger.textarea:active,html.theme--documenter-dark .is-danger.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-danger:active,html.theme--documenter-dark .is-danger.is-active.textarea,html.theme--documenter-dark .is-danger.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(158,27,13,0.25)}html.theme--documenter-dark .is-small.textarea,html.theme--documenter-dark .is-small.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{border-radius:3px;font-size:.75rem}html.theme--documenter-dark .is-medium.textarea,html.theme--documenter-dark .is-medium.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}html.theme--documenter-dark .is-large.textarea,html.theme--documenter-dark .is-large.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}html.theme--documenter-dark .is-fullwidth.textarea,html.theme--documenter-dark .is-fullwidth.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}html.theme--documenter-dark .is-inline.textarea,html.theme--documenter-dark .is-inline.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}html.theme--documenter-dark .input.is-rounded,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{border-radius:9999px;padding-left:calc(calc(0.75em - 1px) + 0.375em);padding-right:calc(calc(0.75em - 1px) + 0.375em)}html.theme--documenter-dark .input.is-static,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}html.theme--documenter-dark .textarea{display:block;max-width:100%;min-width:100%;padding:calc(0.75em - 1px);resize:vertical}html.theme--documenter-dark .textarea:not([rows]){max-height:40em;min-height:8em}html.theme--documenter-dark .textarea[rows]{height:initial}html.theme--documenter-dark .textarea.has-fixed-size{resize:none}html.theme--documenter-dark .radio,html.theme--documenter-dark .checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}html.theme--documenter-dark .radio input,html.theme--documenter-dark .checkbox input{cursor:pointer}html.theme--documenter-dark .radio:hover,html.theme--documenter-dark .checkbox:hover{color:#8c9b9d}html.theme--documenter-dark .radio[disabled],html.theme--documenter-dark .checkbox[disabled],fieldset[disabled] html.theme--documenter-dark .radio,fieldset[disabled] html.theme--documenter-dark .checkbox,html.theme--documenter-dark .radio input[disabled],html.theme--documenter-dark .checkbox input[disabled]{color:#fff;cursor:not-allowed}html.theme--documenter-dark .radio+.radio{margin-left:.5em}html.theme--documenter-dark .select{display:inline-block;max-width:100%;position:relative;vertical-align:top}html.theme--documenter-dark .select:not(.is-multiple){height:2.5em}html.theme--documenter-dark .select:not(.is-multiple):not(.is-loading)::after{border-color:#1abc9c;right:1.125em;z-index:4}html.theme--documenter-dark .select.is-rounded select,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.select select{border-radius:9999px;padding-left:1em}html.theme--documenter-dark .select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}html.theme--documenter-dark .select select::-ms-expand{display:none}html.theme--documenter-dark .select select[disabled]:hover,fieldset[disabled] html.theme--documenter-dark .select select:hover{border-color:#282f2f}html.theme--documenter-dark .select select:not([multiple]){padding-right:2.5em}html.theme--documenter-dark .select select[multiple]{height:auto;padding:0}html.theme--documenter-dark .select select[multiple] option{padding:0.5em 1em}html.theme--documenter-dark .select:not(.is-multiple):not(.is-loading):hover::after{border-color:#8c9b9d}html.theme--documenter-dark .select.is-white:not(:hover)::after{border-color:#fff}html.theme--documenter-dark .select.is-white select{border-color:#fff}html.theme--documenter-dark .select.is-white select:hover,html.theme--documenter-dark .select.is-white select.is-hovered{border-color:#f2f2f2}html.theme--documenter-dark .select.is-white select:focus,html.theme--documenter-dark .select.is-white select.is-focused,html.theme--documenter-dark .select.is-white select:active,html.theme--documenter-dark .select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--documenter-dark .select.is-black:not(:hover)::after{border-color:#0a0a0a}html.theme--documenter-dark .select.is-black select{border-color:#0a0a0a}html.theme--documenter-dark .select.is-black select:hover,html.theme--documenter-dark .select.is-black select.is-hovered{border-color:#000}html.theme--documenter-dark .select.is-black select:focus,html.theme--documenter-dark .select.is-black select.is-focused,html.theme--documenter-dark .select.is-black select:active,html.theme--documenter-dark .select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--documenter-dark .select.is-light:not(:hover)::after{border-color:#ecf0f1}html.theme--documenter-dark .select.is-light select{border-color:#ecf0f1}html.theme--documenter-dark .select.is-light select:hover,html.theme--documenter-dark .select.is-light select.is-hovered{border-color:#dde4e6}html.theme--documenter-dark .select.is-light select:focus,html.theme--documenter-dark .select.is-light select.is-focused,html.theme--documenter-dark .select.is-light select:active,html.theme--documenter-dark .select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(236,240,241,0.25)}html.theme--documenter-dark .select.is-dark:not(:hover)::after,html.theme--documenter-dark .content kbd.select:not(:hover)::after{border-color:#282f2f}html.theme--documenter-dark .select.is-dark select,html.theme--documenter-dark .content kbd.select select{border-color:#282f2f}html.theme--documenter-dark .select.is-dark select:hover,html.theme--documenter-dark .content kbd.select select:hover,html.theme--documenter-dark .select.is-dark select.is-hovered,html.theme--documenter-dark .content kbd.select select.is-hovered{border-color:#1d2122}html.theme--documenter-dark .select.is-dark select:focus,html.theme--documenter-dark .content kbd.select select:focus,html.theme--documenter-dark .select.is-dark select.is-focused,html.theme--documenter-dark .content kbd.select select.is-focused,html.theme--documenter-dark .select.is-dark select:active,html.theme--documenter-dark .content kbd.select select:active,html.theme--documenter-dark .select.is-dark select.is-active,html.theme--documenter-dark .content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(40,47,47,0.25)}html.theme--documenter-dark .select.is-primary:not(:hover)::after,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#375a7f}html.theme--documenter-dark .select.is-primary select,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select{border-color:#375a7f}html.theme--documenter-dark .select.is-primary select:hover,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select:hover,html.theme--documenter-dark .select.is-primary select.is-hovered,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#2f4d6d}html.theme--documenter-dark .select.is-primary select:focus,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select:focus,html.theme--documenter-dark .select.is-primary select.is-focused,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select.is-focused,html.theme--documenter-dark .select.is-primary select:active,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select:active,html.theme--documenter-dark .select.is-primary select.is-active,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(55,90,127,0.25)}html.theme--documenter-dark .select.is-link:not(:hover)::after{border-color:#1abc9c}html.theme--documenter-dark .select.is-link select{border-color:#1abc9c}html.theme--documenter-dark .select.is-link select:hover,html.theme--documenter-dark .select.is-link select.is-hovered{border-color:#17a689}html.theme--documenter-dark .select.is-link select:focus,html.theme--documenter-dark .select.is-link select.is-focused,html.theme--documenter-dark .select.is-link select:active,html.theme--documenter-dark .select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .select.is-info:not(:hover)::after{border-color:#024c7d}html.theme--documenter-dark .select.is-info select{border-color:#024c7d}html.theme--documenter-dark .select.is-info select:hover,html.theme--documenter-dark .select.is-info select.is-hovered{border-color:#023d64}html.theme--documenter-dark .select.is-info select:focus,html.theme--documenter-dark .select.is-info select.is-focused,html.theme--documenter-dark .select.is-info select:active,html.theme--documenter-dark .select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(2,76,125,0.25)}html.theme--documenter-dark .select.is-success:not(:hover)::after{border-color:#008438}html.theme--documenter-dark .select.is-success select{border-color:#008438}html.theme--documenter-dark .select.is-success select:hover,html.theme--documenter-dark .select.is-success select.is-hovered{border-color:#006b2d}html.theme--documenter-dark .select.is-success select:focus,html.theme--documenter-dark .select.is-success select.is-focused,html.theme--documenter-dark .select.is-success select:active,html.theme--documenter-dark .select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(0,132,56,0.25)}html.theme--documenter-dark .select.is-warning:not(:hover)::after{border-color:#ad8100}html.theme--documenter-dark .select.is-warning select{border-color:#ad8100}html.theme--documenter-dark .select.is-warning select:hover,html.theme--documenter-dark .select.is-warning select.is-hovered{border-color:#946e00}html.theme--documenter-dark .select.is-warning select:focus,html.theme--documenter-dark .select.is-warning select.is-focused,html.theme--documenter-dark .select.is-warning select:active,html.theme--documenter-dark .select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(173,129,0,0.25)}html.theme--documenter-dark .select.is-danger:not(:hover)::after{border-color:#9e1b0d}html.theme--documenter-dark .select.is-danger select{border-color:#9e1b0d}html.theme--documenter-dark .select.is-danger select:hover,html.theme--documenter-dark .select.is-danger select.is-hovered{border-color:#86170b}html.theme--documenter-dark .select.is-danger select:focus,html.theme--documenter-dark .select.is-danger select.is-focused,html.theme--documenter-dark .select.is-danger select:active,html.theme--documenter-dark .select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(158,27,13,0.25)}html.theme--documenter-dark .select.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.select{border-radius:3px;font-size:.75rem}html.theme--documenter-dark .select.is-medium{font-size:1.25rem}html.theme--documenter-dark .select.is-large{font-size:1.5rem}html.theme--documenter-dark .select.is-disabled::after{border-color:#fff !important;opacity:0.5}html.theme--documenter-dark .select.is-fullwidth{width:100%}html.theme--documenter-dark .select.is-fullwidth select{width:100%}html.theme--documenter-dark .select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:0.625em;transform:none}html.theme--documenter-dark .select.is-loading.is-small:after,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--documenter-dark .select.is-loading.is-medium:after{font-size:1.25rem}html.theme--documenter-dark .select.is-loading.is-large:after{font-size:1.5rem}html.theme--documenter-dark .file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}html.theme--documenter-dark .file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .file.is-white:hover .file-cta,html.theme--documenter-dark .file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .file.is-white:focus .file-cta,html.theme--documenter-dark .file.is-white.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,255,255,0.25);color:#0a0a0a}html.theme--documenter-dark .file.is-white:active .file-cta,html.theme--documenter-dark .file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-black:hover .file-cta,html.theme--documenter-dark .file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-black:focus .file-cta,html.theme--documenter-dark .file.is-black.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(10,10,10,0.25);color:#fff}html.theme--documenter-dark .file.is-black:active .file-cta,html.theme--documenter-dark .file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-light .file-cta{background-color:#ecf0f1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-light:hover .file-cta,html.theme--documenter-dark .file.is-light.is-hovered .file-cta{background-color:#e5eaec;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-light:focus .file-cta,html.theme--documenter-dark .file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(236,240,241,0.25);color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-light:active .file-cta,html.theme--documenter-dark .file.is-light.is-active .file-cta{background-color:#dde4e6;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-dark .file-cta,html.theme--documenter-dark .content kbd.file .file-cta{background-color:#282f2f;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-dark:hover .file-cta,html.theme--documenter-dark .content kbd.file:hover .file-cta,html.theme--documenter-dark .file.is-dark.is-hovered .file-cta,html.theme--documenter-dark .content kbd.file.is-hovered .file-cta{background-color:#232829;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-dark:focus .file-cta,html.theme--documenter-dark .content kbd.file:focus .file-cta,html.theme--documenter-dark .file.is-dark.is-focused .file-cta,html.theme--documenter-dark .content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(40,47,47,0.25);color:#fff}html.theme--documenter-dark .file.is-dark:active .file-cta,html.theme--documenter-dark .content kbd.file:active .file-cta,html.theme--documenter-dark .file.is-dark.is-active .file-cta,html.theme--documenter-dark .content kbd.file.is-active .file-cta{background-color:#1d2122;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-primary .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink .file-cta{background-color:#375a7f;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-primary:hover .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink:hover .file-cta,html.theme--documenter-dark .file.is-primary.is-hovered .file-cta,html.theme--documenter-dark .docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#335476;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-primary:focus .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink:focus .file-cta,html.theme--documenter-dark .file.is-primary.is-focused .file-cta,html.theme--documenter-dark .docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(55,90,127,0.25);color:#fff}html.theme--documenter-dark .file.is-primary:active .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink:active .file-cta,html.theme--documenter-dark .file.is-primary.is-active .file-cta,html.theme--documenter-dark .docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#2f4d6d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-link .file-cta{background-color:#1abc9c;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-link:hover .file-cta,html.theme--documenter-dark .file.is-link.is-hovered .file-cta{background-color:#18b193;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-link:focus .file-cta,html.theme--documenter-dark .file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(26,188,156,0.25);color:#fff}html.theme--documenter-dark .file.is-link:active .file-cta,html.theme--documenter-dark .file.is-link.is-active .file-cta{background-color:#17a689;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-info .file-cta{background-color:#024c7d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-info:hover .file-cta,html.theme--documenter-dark .file.is-info.is-hovered .file-cta{background-color:#024470;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-info:focus .file-cta,html.theme--documenter-dark .file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(2,76,125,0.25);color:#fff}html.theme--documenter-dark .file.is-info:active .file-cta,html.theme--documenter-dark .file.is-info.is-active .file-cta{background-color:#023d64;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success .file-cta{background-color:#008438;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success:hover .file-cta,html.theme--documenter-dark .file.is-success.is-hovered .file-cta{background-color:#073;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success:focus .file-cta,html.theme--documenter-dark .file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(0,132,56,0.25);color:#fff}html.theme--documenter-dark .file.is-success:active .file-cta,html.theme--documenter-dark .file.is-success.is-active .file-cta{background-color:#006b2d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-warning .file-cta{background-color:#ad8100;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-warning:hover .file-cta,html.theme--documenter-dark .file.is-warning.is-hovered .file-cta{background-color:#a07700;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-warning:focus .file-cta,html.theme--documenter-dark .file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(173,129,0,0.25);color:#fff}html.theme--documenter-dark .file.is-warning:active .file-cta,html.theme--documenter-dark .file.is-warning.is-active .file-cta{background-color:#946e00;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-danger .file-cta{background-color:#9e1b0d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-danger:hover .file-cta,html.theme--documenter-dark .file.is-danger.is-hovered .file-cta{background-color:#92190c;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-danger:focus .file-cta,html.theme--documenter-dark .file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(158,27,13,0.25);color:#fff}html.theme--documenter-dark .file.is-danger:active .file-cta,html.theme--documenter-dark .file.is-danger.is-active .file-cta{background-color:#86170b;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}html.theme--documenter-dark .file.is-normal{font-size:1rem}html.theme--documenter-dark .file.is-medium{font-size:1.25rem}html.theme--documenter-dark .file.is-medium .file-icon .fa{font-size:21px}html.theme--documenter-dark .file.is-large{font-size:1.5rem}html.theme--documenter-dark .file.is-large .file-icon .fa{font-size:28px}html.theme--documenter-dark .file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--documenter-dark .file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--documenter-dark .file.has-name.is-empty .file-cta{border-radius:.4em}html.theme--documenter-dark .file.has-name.is-empty .file-name{display:none}html.theme--documenter-dark .file.is-boxed .file-label{flex-direction:column}html.theme--documenter-dark .file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}html.theme--documenter-dark .file.is-boxed .file-name{border-width:0 1px 1px}html.theme--documenter-dark .file.is-boxed .file-icon{height:1.5em;width:1.5em}html.theme--documenter-dark .file.is-boxed .file-icon .fa{font-size:21px}html.theme--documenter-dark .file.is-boxed.is-small .file-icon .fa,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}html.theme--documenter-dark .file.is-boxed.is-medium .file-icon .fa{font-size:28px}html.theme--documenter-dark .file.is-boxed.is-large .file-icon .fa{font-size:35px}html.theme--documenter-dark .file.is-boxed.has-name .file-cta{border-radius:.4em .4em 0 0}html.theme--documenter-dark .file.is-boxed.has-name .file-name{border-radius:0 0 .4em .4em;border-width:0 1px 1px}html.theme--documenter-dark .file.is-centered{justify-content:center}html.theme--documenter-dark .file.is-fullwidth .file-label{width:100%}html.theme--documenter-dark .file.is-fullwidth .file-name{flex-grow:1;max-width:none}html.theme--documenter-dark .file.is-right{justify-content:flex-end}html.theme--documenter-dark .file.is-right .file-cta{border-radius:0 .4em .4em 0}html.theme--documenter-dark .file.is-right .file-name{border-radius:.4em 0 0 .4em;border-width:1px 0 1px 1px;order:-1}html.theme--documenter-dark .file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}html.theme--documenter-dark .file-label:hover .file-cta{background-color:#232829;color:#f2f2f2}html.theme--documenter-dark .file-label:hover .file-name{border-color:#596668}html.theme--documenter-dark .file-label:active .file-cta{background-color:#1d2122;color:#f2f2f2}html.theme--documenter-dark .file-label:active .file-name{border-color:#535f61}html.theme--documenter-dark .file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}html.theme--documenter-dark .file-cta,html.theme--documenter-dark .file-name{border-color:#5e6d6f;border-radius:.4em;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}html.theme--documenter-dark .file-cta{background-color:#282f2f;color:#fff}html.theme--documenter-dark .file-name{border-color:#5e6d6f;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}html.theme--documenter-dark .file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}html.theme--documenter-dark .file-icon .fa{font-size:14px}html.theme--documenter-dark .label{color:#f2f2f2;display:block;font-size:1rem;font-weight:700}html.theme--documenter-dark .label:not(:last-child){margin-bottom:0.5em}html.theme--documenter-dark .label.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.label{font-size:.75rem}html.theme--documenter-dark .label.is-medium{font-size:1.25rem}html.theme--documenter-dark .label.is-large{font-size:1.5rem}html.theme--documenter-dark .help{display:block;font-size:.75rem;margin-top:0.25rem}html.theme--documenter-dark .help.is-white{color:#fff}html.theme--documenter-dark .help.is-black{color:#0a0a0a}html.theme--documenter-dark .help.is-light{color:#ecf0f1}html.theme--documenter-dark .help.is-dark,html.theme--documenter-dark .content kbd.help{color:#282f2f}html.theme--documenter-dark .help.is-primary,html.theme--documenter-dark .docstring>section>a.help.docs-sourcelink{color:#375a7f}html.theme--documenter-dark .help.is-link{color:#1abc9c}html.theme--documenter-dark .help.is-info{color:#024c7d}html.theme--documenter-dark .help.is-success{color:#008438}html.theme--documenter-dark .help.is-warning{color:#ad8100}html.theme--documenter-dark .help.is-danger{color:#9e1b0d}html.theme--documenter-dark .field:not(:last-child){margin-bottom:0.75rem}html.theme--documenter-dark .field.has-addons{display:flex;justify-content:flex-start}html.theme--documenter-dark .field.has-addons .control:not(:last-child){margin-right:-1px}html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) .button,html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) .input,html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) .button,html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) .input,html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) .button,html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) .input,html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .button.is-hovered:not([disabled]),html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .input.is-hovered:not([disabled]),html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control .button.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control .button.is-active:not([disabled]),html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control .input.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control .input.is-active:not([disabled]),html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control .select select.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control .select select.is-active:not([disabled]){z-index:3}html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control .button.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control .button.is-active:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control .input.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control .input.is-active:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control .select select.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}html.theme--documenter-dark .field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .field.has-addons.has-addons-centered{justify-content:center}html.theme--documenter-dark .field.has-addons.has-addons-right{justify-content:flex-end}html.theme--documenter-dark .field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}html.theme--documenter-dark .field.is-grouped{display:flex;justify-content:flex-start}html.theme--documenter-dark .field.is-grouped>.control{flex-shrink:0}html.theme--documenter-dark .field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--documenter-dark .field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .field.is-grouped.is-grouped-centered{justify-content:center}html.theme--documenter-dark .field.is-grouped.is-grouped-right{justify-content:flex-end}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline{flex-wrap:wrap}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline>.control:last-child,html.theme--documenter-dark .field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--documenter-dark .field.is-horizontal{display:flex}}html.theme--documenter-dark .field-label .label{font-size:inherit}@media screen and (max-width: 768px){html.theme--documenter-dark .field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}html.theme--documenter-dark .field-label.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.field-label{font-size:.75rem;padding-top:0.375em}html.theme--documenter-dark .field-label.is-normal{padding-top:0.375em}html.theme--documenter-dark .field-label.is-medium{font-size:1.25rem;padding-top:0.375em}html.theme--documenter-dark .field-label.is-large{font-size:1.5rem;padding-top:0.375em}}html.theme--documenter-dark .field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--documenter-dark .field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}html.theme--documenter-dark .field-body .field{margin-bottom:0}html.theme--documenter-dark .field-body>.field{flex-shrink:1}html.theme--documenter-dark .field-body>.field:not(.is-narrow){flex-grow:1}html.theme--documenter-dark .field-body>.field:not(:last-child){margin-right:.75rem}}html.theme--documenter-dark .control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}html.theme--documenter-dark .control.has-icons-left .input:focus~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,html.theme--documenter-dark .control.has-icons-left .select:focus~.icon,html.theme--documenter-dark .control.has-icons-right .input:focus~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,html.theme--documenter-dark .control.has-icons-right .select:focus~.icon{color:#282f2f}html.theme--documenter-dark .control.has-icons-left .input.is-small~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,html.theme--documenter-dark .control.has-icons-left .select.is-small~.icon,html.theme--documenter-dark .control.has-icons-right .input.is-small~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,html.theme--documenter-dark .control.has-icons-right .select.is-small~.icon{font-size:.75rem}html.theme--documenter-dark .control.has-icons-left .input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-left .select.is-medium~.icon,html.theme--documenter-dark .control.has-icons-right .input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}html.theme--documenter-dark .control.has-icons-left .input.is-large~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,html.theme--documenter-dark .control.has-icons-left .select.is-large~.icon,html.theme--documenter-dark .control.has-icons-right .input.is-large~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,html.theme--documenter-dark .control.has-icons-right .select.is-large~.icon{font-size:1.5rem}html.theme--documenter-dark .control.has-icons-left .icon,html.theme--documenter-dark .control.has-icons-right .icon{color:#5e6d6f;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}html.theme--documenter-dark .control.has-icons-left .input,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input,html.theme--documenter-dark .control.has-icons-left .select select{padding-left:2.5em}html.theme--documenter-dark .control.has-icons-left .icon.is-left{left:0}html.theme--documenter-dark .control.has-icons-right .input,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input,html.theme--documenter-dark .control.has-icons-right .select select{padding-right:2.5em}html.theme--documenter-dark .control.has-icons-right .icon.is-right{right:0}html.theme--documenter-dark .control.is-loading::after{position:absolute !important;right:.625em;top:0.625em;z-index:4}html.theme--documenter-dark .control.is-loading.is-small:after,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--documenter-dark .control.is-loading.is-medium:after{font-size:1.25rem}html.theme--documenter-dark .control.is-loading.is-large:after{font-size:1.5rem}html.theme--documenter-dark .breadcrumb{font-size:1rem;white-space:nowrap}html.theme--documenter-dark .breadcrumb a{align-items:center;color:#1abc9c;display:flex;justify-content:center;padding:0 .75em}html.theme--documenter-dark .breadcrumb a:hover{color:#1dd2af}html.theme--documenter-dark .breadcrumb li{align-items:center;display:flex}html.theme--documenter-dark .breadcrumb li:first-child a{padding-left:0}html.theme--documenter-dark .breadcrumb li.is-active a{color:#f2f2f2;cursor:default;pointer-events:none}html.theme--documenter-dark .breadcrumb li+li::before{color:#8c9b9d;content:"\0002f"}html.theme--documenter-dark .breadcrumb ul,html.theme--documenter-dark .breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--documenter-dark .breadcrumb .icon:first-child{margin-right:.5em}html.theme--documenter-dark .breadcrumb .icon:last-child{margin-left:.5em}html.theme--documenter-dark .breadcrumb.is-centered ol,html.theme--documenter-dark .breadcrumb.is-centered ul{justify-content:center}html.theme--documenter-dark .breadcrumb.is-right ol,html.theme--documenter-dark .breadcrumb.is-right ul{justify-content:flex-end}html.theme--documenter-dark .breadcrumb.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.75rem}html.theme--documenter-dark .breadcrumb.is-medium{font-size:1.25rem}html.theme--documenter-dark .breadcrumb.is-large{font-size:1.5rem}html.theme--documenter-dark .breadcrumb.has-arrow-separator li+li::before{content:"\02192"}html.theme--documenter-dark .breadcrumb.has-bullet-separator li+li::before{content:"\02022"}html.theme--documenter-dark .breadcrumb.has-dot-separator li+li::before{content:"\000b7"}html.theme--documenter-dark .breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}html.theme--documenter-dark .card{background-color:#fff;border-radius:.25rem;box-shadow:#171717;color:#fff;max-width:100%;position:relative}html.theme--documenter-dark .card-footer:first-child,html.theme--documenter-dark .card-content:first-child,html.theme--documenter-dark .card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--documenter-dark .card-footer:last-child,html.theme--documenter-dark .card-content:last-child,html.theme--documenter-dark .card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--documenter-dark .card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);display:flex}html.theme--documenter-dark .card-header-title{align-items:center;color:#f2f2f2;display:flex;flex-grow:1;font-weight:700;padding:0.75rem 1rem}html.theme--documenter-dark .card-header-title.is-centered{justify-content:center}html.theme--documenter-dark .card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:0.75rem 1rem}html.theme--documenter-dark .card-image{display:block;position:relative}html.theme--documenter-dark .card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--documenter-dark .card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--documenter-dark .card-content{background-color:rgba(0,0,0,0);padding:1.5rem}html.theme--documenter-dark .card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #ededed;align-items:stretch;display:flex}html.theme--documenter-dark .card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}html.theme--documenter-dark .card-footer-item:not(:last-child){border-right:1px solid #ededed}html.theme--documenter-dark .card .media:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .dropdown{display:inline-flex;position:relative;vertical-align:top}html.theme--documenter-dark .dropdown.is-active .dropdown-menu,html.theme--documenter-dark .dropdown.is-hoverable:hover .dropdown-menu{display:block}html.theme--documenter-dark .dropdown.is-right .dropdown-menu{left:auto;right:0}html.theme--documenter-dark .dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}html.theme--documenter-dark .dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}html.theme--documenter-dark .dropdown-content{background-color:#282f2f;border-radius:.4em;box-shadow:#171717;padding-bottom:.5rem;padding-top:.5rem}html.theme--documenter-dark .dropdown-item{color:#fff;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}html.theme--documenter-dark a.dropdown-item,html.theme--documenter-dark button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}html.theme--documenter-dark a.dropdown-item:hover,html.theme--documenter-dark button.dropdown-item:hover{background-color:#282f2f;color:#0a0a0a}html.theme--documenter-dark a.dropdown-item.is-active,html.theme--documenter-dark button.dropdown-item.is-active{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:0.5rem 0}html.theme--documenter-dark .level{align-items:center;justify-content:space-between}html.theme--documenter-dark .level code{border-radius:.4em}html.theme--documenter-dark .level img{display:inline-block;vertical-align:top}html.theme--documenter-dark .level.is-mobile{display:flex}html.theme--documenter-dark .level.is-mobile .level-left,html.theme--documenter-dark .level.is-mobile .level-right{display:flex}html.theme--documenter-dark .level.is-mobile .level-left+.level-right{margin-top:0}html.theme--documenter-dark .level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--documenter-dark .level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level{display:flex}html.theme--documenter-dark .level>.level-item:not(.is-narrow){flex-grow:1}}html.theme--documenter-dark .level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}html.theme--documenter-dark .level-item .title,html.theme--documenter-dark .level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){html.theme--documenter-dark .level-item:not(:last-child){margin-bottom:.75rem}}html.theme--documenter-dark .level-left,html.theme--documenter-dark .level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--documenter-dark .level-left .level-item.is-flexible,html.theme--documenter-dark .level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level-left .level-item:not(:last-child),html.theme--documenter-dark .level-right .level-item:not(:last-child){margin-right:.75rem}}html.theme--documenter-dark .level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){html.theme--documenter-dark .level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level-left{display:flex}}html.theme--documenter-dark .level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level-right{display:flex}}html.theme--documenter-dark .media{align-items:flex-start;display:flex;text-align:inherit}html.theme--documenter-dark .media .content:not(:last-child){margin-bottom:.75rem}html.theme--documenter-dark .media .media{border-top:1px solid rgba(94,109,111,0.5);display:flex;padding-top:.75rem}html.theme--documenter-dark .media .media .content:not(:last-child),html.theme--documenter-dark .media .media .control:not(:last-child){margin-bottom:.5rem}html.theme--documenter-dark .media .media .media{padding-top:.5rem}html.theme--documenter-dark .media .media .media+.media{margin-top:.5rem}html.theme--documenter-dark .media+.media{border-top:1px solid rgba(94,109,111,0.5);margin-top:1rem;padding-top:1rem}html.theme--documenter-dark .media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}html.theme--documenter-dark .media-left,html.theme--documenter-dark .media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--documenter-dark .media-left{margin-right:1rem}html.theme--documenter-dark .media-right{margin-left:1rem}html.theme--documenter-dark .media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width: 768px){html.theme--documenter-dark .media-content{overflow-x:auto}}html.theme--documenter-dark .menu{font-size:1rem}html.theme--documenter-dark .menu.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}html.theme--documenter-dark .menu.is-medium{font-size:1.25rem}html.theme--documenter-dark .menu.is-large{font-size:1.5rem}html.theme--documenter-dark .menu-list{line-height:1.25}html.theme--documenter-dark .menu-list a{border-radius:3px;color:#fff;display:block;padding:0.5em 0.75em}html.theme--documenter-dark .menu-list a:hover{background-color:#282f2f;color:#f2f2f2}html.theme--documenter-dark .menu-list a.is-active{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .menu-list li ul{border-left:1px solid #5e6d6f;margin:.75em;padding-left:.75em}html.theme--documenter-dark .menu-label{color:#fff;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}html.theme--documenter-dark .menu-label:not(:first-child){margin-top:1em}html.theme--documenter-dark .menu-label:not(:last-child){margin-bottom:1em}html.theme--documenter-dark .message{background-color:#282f2f;border-radius:.4em;font-size:1rem}html.theme--documenter-dark .message strong{color:currentColor}html.theme--documenter-dark .message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--documenter-dark .message.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.message{font-size:.75rem}html.theme--documenter-dark .message.is-medium{font-size:1.25rem}html.theme--documenter-dark .message.is-large{font-size:1.5rem}html.theme--documenter-dark .message.is-white{background-color:#fff}html.theme--documenter-dark .message.is-white .message-header{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .message.is-white .message-body{border-color:#fff}html.theme--documenter-dark .message.is-black{background-color:#fafafa}html.theme--documenter-dark .message.is-black .message-header{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .message.is-black .message-body{border-color:#0a0a0a}html.theme--documenter-dark .message.is-light{background-color:#f9fafb}html.theme--documenter-dark .message.is-light .message-header{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .message.is-light .message-body{border-color:#ecf0f1}html.theme--documenter-dark .message.is-dark,html.theme--documenter-dark .content kbd.message{background-color:#f9fafa}html.theme--documenter-dark .message.is-dark .message-header,html.theme--documenter-dark .content kbd.message .message-header{background-color:#282f2f;color:#fff}html.theme--documenter-dark .message.is-dark .message-body,html.theme--documenter-dark .content kbd.message .message-body{border-color:#282f2f}html.theme--documenter-dark .message.is-primary,html.theme--documenter-dark .docstring>section>a.message.docs-sourcelink{background-color:#f1f5f9}html.theme--documenter-dark .message.is-primary .message-header,html.theme--documenter-dark .docstring>section>a.message.docs-sourcelink .message-header{background-color:#375a7f;color:#fff}html.theme--documenter-dark .message.is-primary .message-body,html.theme--documenter-dark .docstring>section>a.message.docs-sourcelink .message-body{border-color:#375a7f;color:#4d7eb2}html.theme--documenter-dark .message.is-link{background-color:#edfdf9}html.theme--documenter-dark .message.is-link .message-header{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .message.is-link .message-body{border-color:#1abc9c;color:#15987e}html.theme--documenter-dark .message.is-info{background-color:#ebf7ff}html.theme--documenter-dark .message.is-info .message-header{background-color:#024c7d;color:#fff}html.theme--documenter-dark .message.is-info .message-body{border-color:#024c7d;color:#0e9dfb}html.theme--documenter-dark .message.is-success{background-color:#ebfff3}html.theme--documenter-dark .message.is-success .message-header{background-color:#008438;color:#fff}html.theme--documenter-dark .message.is-success .message-body{border-color:#008438;color:#00eb64}html.theme--documenter-dark .message.is-warning{background-color:#fffaeb}html.theme--documenter-dark .message.is-warning .message-header{background-color:#ad8100;color:#fff}html.theme--documenter-dark .message.is-warning .message-body{border-color:#ad8100;color:#d19c00}html.theme--documenter-dark .message.is-danger{background-color:#fdeeec}html.theme--documenter-dark .message.is-danger .message-header{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .message.is-danger .message-body{border-color:#9e1b0d;color:#ec311d}html.theme--documenter-dark .message-header{align-items:center;background-color:#fff;border-radius:.4em .4em 0 0;color:rgba(0,0,0,0.7);display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.75em 1em;position:relative}html.theme--documenter-dark .message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}html.theme--documenter-dark .message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}html.theme--documenter-dark .message-body{border-color:#5e6d6f;border-radius:.4em;border-style:solid;border-width:0 0 0 4px;color:#fff;padding:1.25em 1.5em}html.theme--documenter-dark .message-body code,html.theme--documenter-dark .message-body pre{background-color:#fff}html.theme--documenter-dark .message-body pre code{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}html.theme--documenter-dark .modal.is-active{display:flex}html.theme--documenter-dark .modal-background{background-color:rgba(10,10,10,0.86)}html.theme--documenter-dark .modal-content,html.theme--documenter-dark .modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px){html.theme--documenter-dark .modal-content,html.theme--documenter-dark .modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}html.theme--documenter-dark .modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}html.theme--documenter-dark .modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}html.theme--documenter-dark .modal-card-head,html.theme--documenter-dark .modal-card-foot{align-items:center;background-color:#282f2f;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}html.theme--documenter-dark .modal-card-head{border-bottom:1px solid #5e6d6f;border-top-left-radius:8px;border-top-right-radius:8px}html.theme--documenter-dark .modal-card-title{color:#f2f2f2;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}html.theme--documenter-dark .modal-card-foot{border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid #5e6d6f}html.theme--documenter-dark .modal-card-foot .button:not(:last-child){margin-right:.5em}html.theme--documenter-dark .modal-card-body{-webkit-overflow-scrolling:touch;background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}html.theme--documenter-dark .navbar{background-color:#375a7f;min-height:4rem;position:relative;z-index:30}html.theme--documenter-dark .navbar.is-white{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-white .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-white .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-white .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-white .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-white .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-white .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-white .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-white .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-white .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}html.theme--documenter-dark .navbar.is-black{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-black .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-black .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-black .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-black .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-black .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-black .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-black .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-black .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-black .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}html.theme--documenter-dark .navbar.is-light{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-light .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-light .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#dde4e6;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-light .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-light .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-light .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-light .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-light .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-light .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-light .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link.is-active{background-color:#dde4e6;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#dde4e6;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}}html.theme--documenter-dark .navbar.is-dark,html.theme--documenter-dark .content kbd.navbar{background-color:#282f2f;color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-brand>.navbar-item,html.theme--documenter-dark .content kbd.navbar .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .content kbd.navbar .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-dark .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .content kbd.navbar .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-dark .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link:focus,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link:hover,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#1d2122;color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link::after,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-burger,html.theme--documenter-dark .content kbd.navbar .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-dark .navbar-start>.navbar-item,html.theme--documenter-dark .content kbd.navbar .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-dark .navbar-end>.navbar-item,html.theme--documenter-dark .content kbd.navbar .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .content kbd.navbar .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-dark .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .content kbd.navbar .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-dark .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link:focus,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link:hover,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .content kbd.navbar .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-dark .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .content kbd.navbar .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-dark .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link:focus,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link:hover,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#1d2122;color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link::after,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link::after,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#1d2122;color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-dropdown a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#282f2f;color:#fff}}html.theme--documenter-dark .navbar.is-primary,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink{background-color:#375a7f;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-brand>.navbar-item,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-primary .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-primary .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link::after,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-burger,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-primary .navbar-start>.navbar-item,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-primary .navbar-end>.navbar-item,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-primary .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-primary .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-primary .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-primary .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link::after,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link::after,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#375a7f;color:#fff}}html.theme--documenter-dark .navbar.is-link{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-link .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-link .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#17a689;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-link .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-link .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-link .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-link .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-link .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-link .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-link .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link.is-active{background-color:#17a689;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#17a689;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#1abc9c;color:#fff}}html.theme--documenter-dark .navbar.is-info{background-color:#024c7d;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-info .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-info .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#023d64;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-info .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-info .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-info .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-info .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-info .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-info .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-info .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link.is-active{background-color:#023d64;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#023d64;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#024c7d;color:#fff}}html.theme--documenter-dark .navbar.is-success{background-color:#008438;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-success .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-success .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#006b2d;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-success .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-success .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-success .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-success .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-success .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-success .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-success .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link.is-active{background-color:#006b2d;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#006b2d;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#008438;color:#fff}}html.theme--documenter-dark .navbar.is-warning{background-color:#ad8100;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-warning .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-warning .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#946e00;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-warning .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-warning .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-warning .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-warning .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-warning .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-warning .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#946e00;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#946e00;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#ad8100;color:#fff}}html.theme--documenter-dark .navbar.is-danger{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-danger .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-danger .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#86170b;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-danger .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-danger .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-danger .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-danger .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-danger .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-danger .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#86170b;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#86170b;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#9e1b0d;color:#fff}}html.theme--documenter-dark .navbar>.container{align-items:stretch;display:flex;min-height:4rem;width:100%}html.theme--documenter-dark .navbar.has-shadow{box-shadow:0 2px 0 0 #282f2f}html.theme--documenter-dark .navbar.is-fixed-bottom,html.theme--documenter-dark .navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}html.theme--documenter-dark .navbar.is-fixed-bottom{bottom:0}html.theme--documenter-dark .navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #282f2f}html.theme--documenter-dark .navbar.is-fixed-top{top:0}html.theme--documenter-dark html.has-navbar-fixed-top,html.theme--documenter-dark body.has-navbar-fixed-top{padding-top:4rem}html.theme--documenter-dark html.has-navbar-fixed-bottom,html.theme--documenter-dark body.has-navbar-fixed-bottom{padding-bottom:4rem}html.theme--documenter-dark .navbar-brand,html.theme--documenter-dark .navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:4rem}html.theme--documenter-dark .navbar-brand a.navbar-item:focus,html.theme--documenter-dark .navbar-brand a.navbar-item:hover{background-color:transparent}html.theme--documenter-dark .navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}html.theme--documenter-dark .navbar-burger{color:#fff;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:block;height:4rem;position:relative;width:4rem;margin-left:auto}html.theme--documenter-dark .navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;transform-origin:center;transition-duration:86ms;transition-property:background-color, opacity, transform;transition-timing-function:ease-out;width:16px}html.theme--documenter-dark .navbar-burger span:nth-child(1){top:calc(50% - 6px)}html.theme--documenter-dark .navbar-burger span:nth-child(2){top:calc(50% - 1px)}html.theme--documenter-dark .navbar-burger span:nth-child(3){top:calc(50% + 4px)}html.theme--documenter-dark .navbar-burger:hover{background-color:rgba(0,0,0,0.05)}html.theme--documenter-dark .navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}html.theme--documenter-dark .navbar-burger.is-active span:nth-child(2){opacity:0}html.theme--documenter-dark .navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}html.theme--documenter-dark .navbar-menu{display:none}html.theme--documenter-dark .navbar-item,html.theme--documenter-dark .navbar-link{color:#fff;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}html.theme--documenter-dark .navbar-item .icon:only-child,html.theme--documenter-dark .navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}html.theme--documenter-dark a.navbar-item,html.theme--documenter-dark .navbar-link{cursor:pointer}html.theme--documenter-dark a.navbar-item:focus,html.theme--documenter-dark a.navbar-item:focus-within,html.theme--documenter-dark a.navbar-item:hover,html.theme--documenter-dark a.navbar-item.is-active,html.theme--documenter-dark .navbar-link:focus,html.theme--documenter-dark .navbar-link:focus-within,html.theme--documenter-dark .navbar-link:hover,html.theme--documenter-dark .navbar-link.is-active{background-color:rgba(0,0,0,0);color:#1abc9c}html.theme--documenter-dark .navbar-item{flex-grow:0;flex-shrink:0}html.theme--documenter-dark .navbar-item img{max-height:1.75rem}html.theme--documenter-dark .navbar-item.has-dropdown{padding:0}html.theme--documenter-dark .navbar-item.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .navbar-item.is-tab{border-bottom:1px solid transparent;min-height:4rem;padding-bottom:calc(0.5rem - 1px)}html.theme--documenter-dark .navbar-item.is-tab:focus,html.theme--documenter-dark .navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#1abc9c}html.theme--documenter-dark .navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#1abc9c;border-bottom-style:solid;border-bottom-width:3px;color:#1abc9c;padding-bottom:calc(0.5rem - 3px)}html.theme--documenter-dark .navbar-content{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .navbar-link:not(.is-arrowless){padding-right:2.5em}html.theme--documenter-dark .navbar-link:not(.is-arrowless)::after{border-color:#fff;margin-top:-0.375em;right:1.125em}html.theme--documenter-dark .navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}html.theme--documenter-dark .navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}html.theme--documenter-dark .navbar-divider{background-color:rgba(0,0,0,0.2);border:none;display:none;height:2px;margin:0.5rem 0}@media screen and (max-width: 1055px){html.theme--documenter-dark .navbar>.container{display:block}html.theme--documenter-dark .navbar-brand .navbar-item,html.theme--documenter-dark .navbar-tabs .navbar-item{align-items:center;display:flex}html.theme--documenter-dark .navbar-link::after{display:none}html.theme--documenter-dark .navbar-menu{background-color:#375a7f;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}html.theme--documenter-dark .navbar-menu.is-active{display:block}html.theme--documenter-dark .navbar.is-fixed-bottom-touch,html.theme--documenter-dark .navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}html.theme--documenter-dark .navbar.is-fixed-bottom-touch{bottom:0}html.theme--documenter-dark .navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--documenter-dark .navbar.is-fixed-top-touch{top:0}html.theme--documenter-dark .navbar.is-fixed-top .navbar-menu,html.theme--documenter-dark .navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 4rem);overflow:auto}html.theme--documenter-dark html.has-navbar-fixed-top-touch,html.theme--documenter-dark body.has-navbar-fixed-top-touch{padding-top:4rem}html.theme--documenter-dark html.has-navbar-fixed-bottom-touch,html.theme--documenter-dark body.has-navbar-fixed-bottom-touch{padding-bottom:4rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar,html.theme--documenter-dark .navbar-menu,html.theme--documenter-dark .navbar-start,html.theme--documenter-dark .navbar-end{align-items:stretch;display:flex}html.theme--documenter-dark .navbar{min-height:4rem}html.theme--documenter-dark .navbar.is-spaced{padding:1rem 2rem}html.theme--documenter-dark .navbar.is-spaced .navbar-start,html.theme--documenter-dark .navbar.is-spaced .navbar-end{align-items:center}html.theme--documenter-dark .navbar.is-spaced a.navbar-item,html.theme--documenter-dark .navbar.is-spaced .navbar-link{border-radius:.4em}html.theme--documenter-dark .navbar.is-transparent a.navbar-item:focus,html.theme--documenter-dark .navbar.is-transparent a.navbar-item:hover,html.theme--documenter-dark .navbar.is-transparent a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-transparent .navbar-link:focus,html.theme--documenter-dark .navbar.is-transparent .navbar-link:hover,html.theme--documenter-dark .navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}html.theme--documenter-dark .navbar.is-transparent .navbar-dropdown a.navbar-item:focus,html.theme--documenter-dark .navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#dbdee0}html.theme--documenter-dark .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#1abc9c}html.theme--documenter-dark .navbar-burger{display:none}html.theme--documenter-dark .navbar-item,html.theme--documenter-dark .navbar-link{align-items:center;display:flex}html.theme--documenter-dark .navbar-item.has-dropdown{align-items:stretch}html.theme--documenter-dark .navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}html.theme--documenter-dark .navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:1px solid rgba(0,0,0,0.2);border-radius:8px 8px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,0.1);top:auto}html.theme--documenter-dark .navbar-item.is-active .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-active .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-hoverable:hover .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}html.theme--documenter-dark .navbar-menu{flex-grow:1;flex-shrink:0}html.theme--documenter-dark .navbar-start{justify-content:flex-start;margin-right:auto}html.theme--documenter-dark .navbar-end{justify-content:flex-end;margin-left:auto}html.theme--documenter-dark .navbar-dropdown{background-color:#375a7f;border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid rgba(0,0,0,0.2);box-shadow:0 8px 8px rgba(10,10,10,0.1);display:none;font-size:0.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}html.theme--documenter-dark .navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}html.theme--documenter-dark .navbar-dropdown a.navbar-item{padding-right:3rem}html.theme--documenter-dark .navbar-dropdown a.navbar-item:focus,html.theme--documenter-dark .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#dbdee0}html.theme--documenter-dark .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#1abc9c}.navbar.is-spaced html.theme--documenter-dark .navbar-dropdown,html.theme--documenter-dark .navbar-dropdown.is-boxed{border-radius:8px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,0.1), 0 0 0 1px rgba(10,10,10,0.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));transform:translateY(-5px);transition-duration:86ms;transition-property:opacity, transform}html.theme--documenter-dark .navbar-dropdown.is-right{left:auto;right:0}html.theme--documenter-dark .navbar-divider{display:block}html.theme--documenter-dark .navbar>.container .navbar-brand,html.theme--documenter-dark .container>.navbar .navbar-brand{margin-left:-.75rem}html.theme--documenter-dark .navbar>.container .navbar-menu,html.theme--documenter-dark .container>.navbar .navbar-menu{margin-right:-.75rem}html.theme--documenter-dark .navbar.is-fixed-bottom-desktop,html.theme--documenter-dark .navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}html.theme--documenter-dark .navbar.is-fixed-bottom-desktop{bottom:0}html.theme--documenter-dark .navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--documenter-dark .navbar.is-fixed-top-desktop{top:0}html.theme--documenter-dark html.has-navbar-fixed-top-desktop,html.theme--documenter-dark body.has-navbar-fixed-top-desktop{padding-top:4rem}html.theme--documenter-dark html.has-navbar-fixed-bottom-desktop,html.theme--documenter-dark body.has-navbar-fixed-bottom-desktop{padding-bottom:4rem}html.theme--documenter-dark html.has-spaced-navbar-fixed-top,html.theme--documenter-dark body.has-spaced-navbar-fixed-top{padding-top:6rem}html.theme--documenter-dark html.has-spaced-navbar-fixed-bottom,html.theme--documenter-dark body.has-spaced-navbar-fixed-bottom{padding-bottom:6rem}html.theme--documenter-dark a.navbar-item.is-active,html.theme--documenter-dark .navbar-link.is-active{color:#1abc9c}html.theme--documenter-dark a.navbar-item.is-active:not(:focus):not(:hover),html.theme--documenter-dark .navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}html.theme--documenter-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar-item.has-dropdown.is-active .navbar-link{background-color:rgba(0,0,0,0)}}html.theme--documenter-dark .hero.is-fullheight-with-navbar{min-height:calc(100vh - 4rem)}html.theme--documenter-dark .pagination{font-size:1rem;margin:-.25rem}html.theme--documenter-dark .pagination.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}html.theme--documenter-dark .pagination.is-medium{font-size:1.25rem}html.theme--documenter-dark .pagination.is-large{font-size:1.5rem}html.theme--documenter-dark .pagination.is-rounded .pagination-previous,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,html.theme--documenter-dark .pagination.is-rounded .pagination-next,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:9999px}html.theme--documenter-dark .pagination.is-rounded .pagination-link,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:9999px}html.theme--documenter-dark .pagination,html.theme--documenter-dark .pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link{border-color:#5e6d6f;color:#1abc9c;min-width:2.5em}html.theme--documenter-dark .pagination-previous:hover,html.theme--documenter-dark .pagination-next:hover,html.theme--documenter-dark .pagination-link:hover{border-color:#8c9b9d;color:#1dd2af}html.theme--documenter-dark .pagination-previous:focus,html.theme--documenter-dark .pagination-next:focus,html.theme--documenter-dark .pagination-link:focus{border-color:#8c9b9d}html.theme--documenter-dark .pagination-previous:active,html.theme--documenter-dark .pagination-next:active,html.theme--documenter-dark .pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}html.theme--documenter-dark .pagination-previous[disabled],html.theme--documenter-dark .pagination-previous.is-disabled,html.theme--documenter-dark .pagination-next[disabled],html.theme--documenter-dark .pagination-next.is-disabled,html.theme--documenter-dark .pagination-link[disabled],html.theme--documenter-dark .pagination-link.is-disabled{background-color:#5e6d6f;border-color:#5e6d6f;box-shadow:none;color:#fff;opacity:0.5}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next{padding-left:.75em;padding-right:.75em;white-space:nowrap}html.theme--documenter-dark .pagination-link.is-current{background-color:#1abc9c;border-color:#1abc9c;color:#fff}html.theme--documenter-dark .pagination-ellipsis{color:#8c9b9d;pointer-events:none}html.theme--documenter-dark .pagination-list{flex-wrap:wrap}html.theme--documenter-dark .pagination-list li{list-style:none}@media screen and (max-width: 768px){html.theme--documenter-dark .pagination{flex-wrap:wrap}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis{margin-bottom:0;margin-top:0}html.theme--documenter-dark .pagination-previous{order:2}html.theme--documenter-dark .pagination-next{order:3}html.theme--documenter-dark .pagination{justify-content:space-between;margin-bottom:0;margin-top:0}html.theme--documenter-dark .pagination.is-centered .pagination-previous{order:1}html.theme--documenter-dark .pagination.is-centered .pagination-list{justify-content:center;order:2}html.theme--documenter-dark .pagination.is-centered .pagination-next{order:3}html.theme--documenter-dark .pagination.is-right .pagination-previous{order:1}html.theme--documenter-dark .pagination.is-right .pagination-next{order:2}html.theme--documenter-dark .pagination.is-right .pagination-list{justify-content:flex-end;order:3}}html.theme--documenter-dark .panel{border-radius:8px;box-shadow:#171717;font-size:1rem}html.theme--documenter-dark .panel:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}html.theme--documenter-dark .panel.is-white .panel-block.is-active .panel-icon{color:#fff}html.theme--documenter-dark .panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}html.theme--documenter-dark .panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}html.theme--documenter-dark .panel.is-light .panel-heading{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .panel.is-light .panel-tabs a.is-active{border-bottom-color:#ecf0f1}html.theme--documenter-dark .panel.is-light .panel-block.is-active .panel-icon{color:#ecf0f1}html.theme--documenter-dark .panel.is-dark .panel-heading,html.theme--documenter-dark .content kbd.panel .panel-heading{background-color:#282f2f;color:#fff}html.theme--documenter-dark .panel.is-dark .panel-tabs a.is-active,html.theme--documenter-dark .content kbd.panel .panel-tabs a.is-active{border-bottom-color:#282f2f}html.theme--documenter-dark .panel.is-dark .panel-block.is-active .panel-icon,html.theme--documenter-dark .content kbd.panel .panel-block.is-active .panel-icon{color:#282f2f}html.theme--documenter-dark .panel.is-primary .panel-heading,html.theme--documenter-dark .docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#375a7f;color:#fff}html.theme--documenter-dark .panel.is-primary .panel-tabs a.is-active,html.theme--documenter-dark .docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#375a7f}html.theme--documenter-dark .panel.is-primary .panel-block.is-active .panel-icon,html.theme--documenter-dark .docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#375a7f}html.theme--documenter-dark .panel.is-link .panel-heading{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .panel.is-link .panel-tabs a.is-active{border-bottom-color:#1abc9c}html.theme--documenter-dark .panel.is-link .panel-block.is-active .panel-icon{color:#1abc9c}html.theme--documenter-dark .panel.is-info .panel-heading{background-color:#024c7d;color:#fff}html.theme--documenter-dark .panel.is-info .panel-tabs a.is-active{border-bottom-color:#024c7d}html.theme--documenter-dark .panel.is-info .panel-block.is-active .panel-icon{color:#024c7d}html.theme--documenter-dark .panel.is-success .panel-heading{background-color:#008438;color:#fff}html.theme--documenter-dark .panel.is-success .panel-tabs a.is-active{border-bottom-color:#008438}html.theme--documenter-dark .panel.is-success .panel-block.is-active .panel-icon{color:#008438}html.theme--documenter-dark .panel.is-warning .panel-heading{background-color:#ad8100;color:#fff}html.theme--documenter-dark .panel.is-warning .panel-tabs a.is-active{border-bottom-color:#ad8100}html.theme--documenter-dark .panel.is-warning .panel-block.is-active .panel-icon{color:#ad8100}html.theme--documenter-dark .panel.is-danger .panel-heading{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .panel.is-danger .panel-tabs a.is-active{border-bottom-color:#9e1b0d}html.theme--documenter-dark .panel.is-danger .panel-block.is-active .panel-icon{color:#9e1b0d}html.theme--documenter-dark .panel-tabs:not(:last-child),html.theme--documenter-dark .panel-block:not(:last-child){border-bottom:1px solid #ededed}html.theme--documenter-dark .panel-heading{background-color:#343c3d;border-radius:8px 8px 0 0;color:#f2f2f2;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}html.theme--documenter-dark .panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}html.theme--documenter-dark .panel-tabs a{border-bottom:1px solid #5e6d6f;margin-bottom:-1px;padding:0.5em}html.theme--documenter-dark .panel-tabs a.is-active{border-bottom-color:#343c3d;color:#17a689}html.theme--documenter-dark .panel-list a{color:#fff}html.theme--documenter-dark .panel-list a:hover{color:#1abc9c}html.theme--documenter-dark .panel-block{align-items:center;color:#f2f2f2;display:flex;justify-content:flex-start;padding:0.5em 0.75em}html.theme--documenter-dark .panel-block input[type="checkbox"]{margin-right:.75em}html.theme--documenter-dark .panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}html.theme--documenter-dark .panel-block.is-wrapped{flex-wrap:wrap}html.theme--documenter-dark .panel-block.is-active{border-left-color:#1abc9c;color:#17a689}html.theme--documenter-dark .panel-block.is-active .panel-icon{color:#1abc9c}html.theme--documenter-dark .panel-block:last-child{border-bottom-left-radius:8px;border-bottom-right-radius:8px}html.theme--documenter-dark a.panel-block,html.theme--documenter-dark label.panel-block{cursor:pointer}html.theme--documenter-dark a.panel-block:hover,html.theme--documenter-dark label.panel-block:hover{background-color:#282f2f}html.theme--documenter-dark .panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#fff;margin-right:.75em}html.theme--documenter-dark .panel-icon .fa{font-size:inherit;line-height:inherit}html.theme--documenter-dark .tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:1rem;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}html.theme--documenter-dark .tabs a{align-items:center;border-bottom-color:#5e6d6f;border-bottom-style:solid;border-bottom-width:1px;color:#fff;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}html.theme--documenter-dark .tabs a:hover{border-bottom-color:#f2f2f2;color:#f2f2f2}html.theme--documenter-dark .tabs li{display:block}html.theme--documenter-dark .tabs li.is-active a{border-bottom-color:#1abc9c;color:#1abc9c}html.theme--documenter-dark .tabs ul{align-items:center;border-bottom-color:#5e6d6f;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}html.theme--documenter-dark .tabs ul.is-left{padding-right:0.75em}html.theme--documenter-dark .tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}html.theme--documenter-dark .tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}html.theme--documenter-dark .tabs .icon:first-child{margin-right:.5em}html.theme--documenter-dark .tabs .icon:last-child{margin-left:.5em}html.theme--documenter-dark .tabs.is-centered ul{justify-content:center}html.theme--documenter-dark .tabs.is-right ul{justify-content:flex-end}html.theme--documenter-dark .tabs.is-boxed a{border:1px solid transparent;border-radius:.4em .4em 0 0}html.theme--documenter-dark .tabs.is-boxed a:hover{background-color:#282f2f;border-bottom-color:#5e6d6f}html.theme--documenter-dark .tabs.is-boxed li.is-active a{background-color:#fff;border-color:#5e6d6f;border-bottom-color:rgba(0,0,0,0) !important}html.theme--documenter-dark .tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}html.theme--documenter-dark .tabs.is-toggle a{border-color:#5e6d6f;border-style:solid;border-width:1px;margin-bottom:0;position:relative}html.theme--documenter-dark .tabs.is-toggle a:hover{background-color:#282f2f;border-color:#8c9b9d;z-index:2}html.theme--documenter-dark .tabs.is-toggle li+li{margin-left:-1px}html.theme--documenter-dark .tabs.is-toggle li:first-child a{border-top-left-radius:.4em;border-bottom-left-radius:.4em}html.theme--documenter-dark .tabs.is-toggle li:last-child a{border-top-right-radius:.4em;border-bottom-right-radius:.4em}html.theme--documenter-dark .tabs.is-toggle li.is-active a{background-color:#1abc9c;border-color:#1abc9c;color:#fff;z-index:1}html.theme--documenter-dark .tabs.is-toggle ul{border-bottom:none}html.theme--documenter-dark .tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}html.theme--documenter-dark .tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}html.theme--documenter-dark .tabs.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.tabs{font-size:.75rem}html.theme--documenter-dark .tabs.is-medium{font-size:1.25rem}html.theme--documenter-dark .tabs.is-large{font-size:1.5rem}html.theme--documenter-dark .column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>html.theme--documenter-dark .column.is-narrow{flex:none;width:unset}.columns.is-mobile>html.theme--documenter-dark .column.is-full{flex:none;width:100%}.columns.is-mobile>html.theme--documenter-dark .column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>html.theme--documenter-dark .column.is-half{flex:none;width:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>html.theme--documenter-dark .column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>html.theme--documenter-dark .column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>html.theme--documenter-dark .column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>html.theme--documenter-dark .column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-half{margin-left:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>html.theme--documenter-dark .column.is-0{flex:none;width:0%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-0{margin-left:0%}.columns.is-mobile>html.theme--documenter-dark .column.is-1{flex:none;width:8.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-2{margin-left:16.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-3{flex:none;width:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-3{margin-left:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-4{flex:none;width:33.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-5{margin-left:41.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-6{flex:none;width:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-6{margin-left:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-7{flex:none;width:58.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-8{margin-left:66.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-9{flex:none;width:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-9{margin-left:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-10{flex:none;width:83.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-11{margin-left:91.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-12{flex:none;width:100%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){html.theme--documenter-dark .column.is-narrow-mobile{flex:none;width:unset}html.theme--documenter-dark .column.is-full-mobile{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-mobile{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-mobile{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-mobile{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-mobile{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-mobile{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-mobile{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-mobile{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-mobile{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-mobile{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-mobile{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-mobile{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-mobile{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-mobile{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-mobile{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-mobile{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-mobile{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-mobile{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-mobile{margin-left:80%}html.theme--documenter-dark .column.is-0-mobile{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-mobile{margin-left:0%}html.theme--documenter-dark .column.is-1-mobile{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-mobile{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-mobile{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-mobile{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-mobile{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-mobile{margin-left:25%}html.theme--documenter-dark .column.is-4-mobile{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-mobile{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-mobile{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-mobile{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-mobile{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-mobile{margin-left:50%}html.theme--documenter-dark .column.is-7-mobile{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-mobile{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-mobile{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-mobile{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-mobile{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-mobile{margin-left:75%}html.theme--documenter-dark .column.is-10-mobile{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-mobile{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-mobile{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-mobile{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-mobile{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .column.is-narrow,html.theme--documenter-dark .column.is-narrow-tablet{flex:none;width:unset}html.theme--documenter-dark .column.is-full,html.theme--documenter-dark .column.is-full-tablet{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters,html.theme--documenter-dark .column.is-three-quarters-tablet{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds,html.theme--documenter-dark .column.is-two-thirds-tablet{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half,html.theme--documenter-dark .column.is-half-tablet{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third,html.theme--documenter-dark .column.is-one-third-tablet{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter,html.theme--documenter-dark .column.is-one-quarter-tablet{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth,html.theme--documenter-dark .column.is-one-fifth-tablet{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths,html.theme--documenter-dark .column.is-two-fifths-tablet{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths,html.theme--documenter-dark .column.is-three-fifths-tablet{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths,html.theme--documenter-dark .column.is-four-fifths-tablet{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters,html.theme--documenter-dark .column.is-offset-three-quarters-tablet{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds,html.theme--documenter-dark .column.is-offset-two-thirds-tablet{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half,html.theme--documenter-dark .column.is-offset-half-tablet{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third,html.theme--documenter-dark .column.is-offset-one-third-tablet{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter,html.theme--documenter-dark .column.is-offset-one-quarter-tablet{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth,html.theme--documenter-dark .column.is-offset-one-fifth-tablet{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths,html.theme--documenter-dark .column.is-offset-two-fifths-tablet{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths,html.theme--documenter-dark .column.is-offset-three-fifths-tablet{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths,html.theme--documenter-dark .column.is-offset-four-fifths-tablet{margin-left:80%}html.theme--documenter-dark .column.is-0,html.theme--documenter-dark .column.is-0-tablet{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0,html.theme--documenter-dark .column.is-offset-0-tablet{margin-left:0%}html.theme--documenter-dark .column.is-1,html.theme--documenter-dark .column.is-1-tablet{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1,html.theme--documenter-dark .column.is-offset-1-tablet{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2,html.theme--documenter-dark .column.is-2-tablet{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2,html.theme--documenter-dark .column.is-offset-2-tablet{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3,html.theme--documenter-dark .column.is-3-tablet{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3,html.theme--documenter-dark .column.is-offset-3-tablet{margin-left:25%}html.theme--documenter-dark .column.is-4,html.theme--documenter-dark .column.is-4-tablet{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4,html.theme--documenter-dark .column.is-offset-4-tablet{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5,html.theme--documenter-dark .column.is-5-tablet{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5,html.theme--documenter-dark .column.is-offset-5-tablet{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6,html.theme--documenter-dark .column.is-6-tablet{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6,html.theme--documenter-dark .column.is-offset-6-tablet{margin-left:50%}html.theme--documenter-dark .column.is-7,html.theme--documenter-dark .column.is-7-tablet{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7,html.theme--documenter-dark .column.is-offset-7-tablet{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8,html.theme--documenter-dark .column.is-8-tablet{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8,html.theme--documenter-dark .column.is-offset-8-tablet{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9,html.theme--documenter-dark .column.is-9-tablet{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9,html.theme--documenter-dark .column.is-offset-9-tablet{margin-left:75%}html.theme--documenter-dark .column.is-10,html.theme--documenter-dark .column.is-10-tablet{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10,html.theme--documenter-dark .column.is-offset-10-tablet{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11,html.theme--documenter-dark .column.is-11-tablet{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11,html.theme--documenter-dark .column.is-offset-11-tablet{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12,html.theme--documenter-dark .column.is-12-tablet{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12,html.theme--documenter-dark .column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){html.theme--documenter-dark .column.is-narrow-touch{flex:none;width:unset}html.theme--documenter-dark .column.is-full-touch{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-touch{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-touch{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-touch{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-touch{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-touch{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-touch{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-touch{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-touch{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-touch{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-touch{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-touch{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-touch{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-touch{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-touch{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-touch{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-touch{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-touch{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-touch{margin-left:80%}html.theme--documenter-dark .column.is-0-touch{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-touch{margin-left:0%}html.theme--documenter-dark .column.is-1-touch{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-touch{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-touch{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-touch{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-touch{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-touch{margin-left:25%}html.theme--documenter-dark .column.is-4-touch{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-touch{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-touch{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-touch{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-touch{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-touch{margin-left:50%}html.theme--documenter-dark .column.is-7-touch{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-touch{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-touch{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-touch{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-touch{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-touch{margin-left:75%}html.theme--documenter-dark .column.is-10-touch{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-touch{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-touch{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-touch{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-touch{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){html.theme--documenter-dark .column.is-narrow-desktop{flex:none;width:unset}html.theme--documenter-dark .column.is-full-desktop{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-desktop{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-desktop{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-desktop{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-desktop{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-desktop{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-desktop{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-desktop{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-desktop{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-desktop{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-desktop{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-desktop{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-desktop{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-desktop{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-desktop{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-desktop{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-desktop{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-desktop{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-desktop{margin-left:80%}html.theme--documenter-dark .column.is-0-desktop{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-desktop{margin-left:0%}html.theme--documenter-dark .column.is-1-desktop{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-desktop{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-desktop{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-desktop{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-desktop{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-desktop{margin-left:25%}html.theme--documenter-dark .column.is-4-desktop{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-desktop{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-desktop{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-desktop{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-desktop{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-desktop{margin-left:50%}html.theme--documenter-dark .column.is-7-desktop{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-desktop{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-desktop{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-desktop{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-desktop{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-desktop{margin-left:75%}html.theme--documenter-dark .column.is-10-desktop{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-desktop{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-desktop{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-desktop{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-desktop{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){html.theme--documenter-dark .column.is-narrow-widescreen{flex:none;width:unset}html.theme--documenter-dark .column.is-full-widescreen{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-widescreen{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-widescreen{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-widescreen{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-widescreen{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-widescreen{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-widescreen{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-widescreen{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-widescreen{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-widescreen{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-widescreen{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-widescreen{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-widescreen{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-widescreen{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-widescreen{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-widescreen{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-widescreen{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-widescreen{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-widescreen{margin-left:80%}html.theme--documenter-dark .column.is-0-widescreen{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-widescreen{margin-left:0%}html.theme--documenter-dark .column.is-1-widescreen{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-widescreen{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-widescreen{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-widescreen{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-widescreen{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-widescreen{margin-left:25%}html.theme--documenter-dark .column.is-4-widescreen{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-widescreen{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-widescreen{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-widescreen{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-widescreen{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-widescreen{margin-left:50%}html.theme--documenter-dark .column.is-7-widescreen{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-widescreen{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-widescreen{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-widescreen{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-widescreen{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-widescreen{margin-left:75%}html.theme--documenter-dark .column.is-10-widescreen{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-widescreen{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-widescreen{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-widescreen{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-widescreen{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){html.theme--documenter-dark .column.is-narrow-fullhd{flex:none;width:unset}html.theme--documenter-dark .column.is-full-fullhd{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-fullhd{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-fullhd{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-fullhd{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-fullhd{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-fullhd{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-fullhd{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-fullhd{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-fullhd{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-fullhd{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-fullhd{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-fullhd{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-fullhd{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-fullhd{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-fullhd{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-fullhd{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-fullhd{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-fullhd{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-fullhd{margin-left:80%}html.theme--documenter-dark .column.is-0-fullhd{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-fullhd{margin-left:0%}html.theme--documenter-dark .column.is-1-fullhd{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-fullhd{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-fullhd{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-fullhd{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-fullhd{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-fullhd{margin-left:25%}html.theme--documenter-dark .column.is-4-fullhd{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-fullhd{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-fullhd{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-fullhd{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-fullhd{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-fullhd{margin-left:50%}html.theme--documenter-dark .column.is-7-fullhd{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-fullhd{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-fullhd{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-fullhd{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-fullhd{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-fullhd{margin-left:75%}html.theme--documenter-dark .column.is-10-fullhd{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-fullhd{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-fullhd{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-fullhd{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-fullhd{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-fullhd{margin-left:100%}}html.theme--documenter-dark .columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--documenter-dark .columns:last-child{margin-bottom:-.75rem}html.theme--documenter-dark .columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}html.theme--documenter-dark .columns.is-centered{justify-content:center}html.theme--documenter-dark .columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}html.theme--documenter-dark .columns.is-gapless>.column{margin:0;padding:0 !important}html.theme--documenter-dark .columns.is-gapless:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .columns.is-gapless:last-child{margin-bottom:0}html.theme--documenter-dark .columns.is-mobile{display:flex}html.theme--documenter-dark .columns.is-multiline{flex-wrap:wrap}html.theme--documenter-dark .columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-desktop{display:flex}}html.theme--documenter-dark .columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}html.theme--documenter-dark .columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}html.theme--documenter-dark .columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-0-fullhd{--columnGap: 0rem}}html.theme--documenter-dark .columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-1-fullhd{--columnGap: .25rem}}html.theme--documenter-dark .columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-2-fullhd{--columnGap: .5rem}}html.theme--documenter-dark .columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-3-fullhd{--columnGap: .75rem}}html.theme--documenter-dark .columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-4-fullhd{--columnGap: 1rem}}html.theme--documenter-dark .columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}html.theme--documenter-dark .columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}html.theme--documenter-dark .columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}html.theme--documenter-dark .columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-8-fullhd{--columnGap: 2rem}}html.theme--documenter-dark .tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}html.theme--documenter-dark .tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--documenter-dark .tile.is-ancestor:last-child{margin-bottom:-.75rem}html.theme--documenter-dark .tile.is-ancestor:not(:last-child){margin-bottom:.75rem}html.theme--documenter-dark .tile.is-child{margin:0 !important}html.theme--documenter-dark .tile.is-parent{padding:.75rem}html.theme--documenter-dark .tile.is-vertical{flex-direction:column}html.theme--documenter-dark .tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{html.theme--documenter-dark .tile:not(.is-child){display:flex}html.theme--documenter-dark .tile.is-1{flex:none;width:8.33333337%}html.theme--documenter-dark .tile.is-2{flex:none;width:16.66666674%}html.theme--documenter-dark .tile.is-3{flex:none;width:25%}html.theme--documenter-dark .tile.is-4{flex:none;width:33.33333337%}html.theme--documenter-dark .tile.is-5{flex:none;width:41.66666674%}html.theme--documenter-dark .tile.is-6{flex:none;width:50%}html.theme--documenter-dark .tile.is-7{flex:none;width:58.33333337%}html.theme--documenter-dark .tile.is-8{flex:none;width:66.66666674%}html.theme--documenter-dark .tile.is-9{flex:none;width:75%}html.theme--documenter-dark .tile.is-10{flex:none;width:83.33333337%}html.theme--documenter-dark .tile.is-11{flex:none;width:91.66666674%}html.theme--documenter-dark .tile.is-12{flex:none;width:100%}}html.theme--documenter-dark .hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}html.theme--documenter-dark .hero .navbar{background:none}html.theme--documenter-dark .hero .tabs ul{border-bottom:none}html.theme--documenter-dark .hero.is-white{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-white strong{color:inherit}html.theme--documenter-dark .hero.is-white .title{color:#0a0a0a}html.theme--documenter-dark .hero.is-white .subtitle{color:rgba(10,10,10,0.9)}html.theme--documenter-dark .hero.is-white .subtitle a:not(.button),html.theme--documenter-dark .hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-white .navbar-menu{background-color:#fff}}html.theme--documenter-dark .hero.is-white .navbar-item,html.theme--documenter-dark .hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}html.theme--documenter-dark .hero.is-white a.navbar-item:hover,html.theme--documenter-dark .hero.is-white a.navbar-item.is-active,html.theme--documenter-dark .hero.is-white .navbar-link:hover,html.theme--documenter-dark .hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}html.theme--documenter-dark .hero.is-white .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-white .tabs li.is-active a{color:#fff !important;opacity:1}html.theme--documenter-dark .hero.is-white .tabs.is-boxed a,html.theme--documenter-dark .hero.is-white .tabs.is-toggle a{color:#0a0a0a}html.theme--documenter-dark .hero.is-white .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-white .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-white .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-white .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--documenter-dark .hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}html.theme--documenter-dark .hero.is-black{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-black strong{color:inherit}html.theme--documenter-dark .hero.is-black .title{color:#fff}html.theme--documenter-dark .hero.is-black .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-black .subtitle a:not(.button),html.theme--documenter-dark .hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-black .navbar-menu{background-color:#0a0a0a}}html.theme--documenter-dark .hero.is-black .navbar-item,html.theme--documenter-dark .hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-black a.navbar-item:hover,html.theme--documenter-dark .hero.is-black a.navbar-item.is-active,html.theme--documenter-dark .hero.is-black .navbar-link:hover,html.theme--documenter-dark .hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}html.theme--documenter-dark .hero.is-black .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-black .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-black .tabs li.is-active a{color:#0a0a0a !important;opacity:1}html.theme--documenter-dark .hero.is-black .tabs.is-boxed a,html.theme--documenter-dark .hero.is-black .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-black .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-black .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-black .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-black .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--documenter-dark .hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}html.theme--documenter-dark .hero.is-light{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-light strong{color:inherit}html.theme--documenter-dark .hero.is-light .title{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light .subtitle{color:rgba(0,0,0,0.9)}html.theme--documenter-dark .hero.is-light .subtitle a:not(.button),html.theme--documenter-dark .hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-light .navbar-menu{background-color:#ecf0f1}}html.theme--documenter-dark .hero.is-light .navbar-item,html.theme--documenter-dark .hero.is-light .navbar-link{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light a.navbar-item:hover,html.theme--documenter-dark .hero.is-light a.navbar-item.is-active,html.theme--documenter-dark .hero.is-light .navbar-link:hover,html.theme--documenter-dark .hero.is-light .navbar-link.is-active{background-color:#dde4e6;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--documenter-dark .hero.is-light .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-light .tabs li.is-active a{color:#ecf0f1 !important;opacity:1}html.theme--documenter-dark .hero.is-light .tabs.is-boxed a,html.theme--documenter-dark .hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-light .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-light .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-light .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#ecf0f1}html.theme--documenter-dark .hero.is-light.is-bold{background-image:linear-gradient(141deg, #cadfe0 0%, #ecf0f1 71%, #fafbfc 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #cadfe0 0%, #ecf0f1 71%, #fafbfc 100%)}}html.theme--documenter-dark .hero.is-dark,html.theme--documenter-dark .content kbd.hero{background-color:#282f2f;color:#fff}html.theme--documenter-dark .hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-dark strong,html.theme--documenter-dark .content kbd.hero strong{color:inherit}html.theme--documenter-dark .hero.is-dark .title,html.theme--documenter-dark .content kbd.hero .title{color:#fff}html.theme--documenter-dark .hero.is-dark .subtitle,html.theme--documenter-dark .content kbd.hero .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-dark .subtitle a:not(.button),html.theme--documenter-dark .content kbd.hero .subtitle a:not(.button),html.theme--documenter-dark .hero.is-dark .subtitle strong,html.theme--documenter-dark .content kbd.hero .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-dark .navbar-menu,html.theme--documenter-dark .content kbd.hero .navbar-menu{background-color:#282f2f}}html.theme--documenter-dark .hero.is-dark .navbar-item,html.theme--documenter-dark .content kbd.hero .navbar-item,html.theme--documenter-dark .hero.is-dark .navbar-link,html.theme--documenter-dark .content kbd.hero .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-dark a.navbar-item:hover,html.theme--documenter-dark .content kbd.hero a.navbar-item:hover,html.theme--documenter-dark .hero.is-dark a.navbar-item.is-active,html.theme--documenter-dark .content kbd.hero a.navbar-item.is-active,html.theme--documenter-dark .hero.is-dark .navbar-link:hover,html.theme--documenter-dark .content kbd.hero .navbar-link:hover,html.theme--documenter-dark .hero.is-dark .navbar-link.is-active,html.theme--documenter-dark .content kbd.hero .navbar-link.is-active{background-color:#1d2122;color:#fff}html.theme--documenter-dark .hero.is-dark .tabs a,html.theme--documenter-dark .content kbd.hero .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-dark .tabs a:hover,html.theme--documenter-dark .content kbd.hero .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-dark .tabs li.is-active a,html.theme--documenter-dark .content kbd.hero .tabs li.is-active a{color:#282f2f !important;opacity:1}html.theme--documenter-dark .hero.is-dark .tabs.is-boxed a,html.theme--documenter-dark .content kbd.hero .tabs.is-boxed a,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle a,html.theme--documenter-dark .content kbd.hero .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-dark .tabs.is-boxed a:hover,html.theme--documenter-dark .content kbd.hero .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle a:hover,html.theme--documenter-dark .content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-dark .tabs.is-boxed li.is-active a,html.theme--documenter-dark .content kbd.hero .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-dark .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle li.is-active a,html.theme--documenter-dark .content kbd.hero .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#282f2f}html.theme--documenter-dark .hero.is-dark.is-bold,html.theme--documenter-dark .content kbd.hero.is-bold{background-image:linear-gradient(141deg, #0f1615 0%, #282f2f 71%, #313c40 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-dark.is-bold .navbar-menu,html.theme--documenter-dark .content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #0f1615 0%, #282f2f 71%, #313c40 100%)}}html.theme--documenter-dark .hero.is-primary,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink{background-color:#375a7f;color:#fff}html.theme--documenter-dark .hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-primary strong,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink strong{color:inherit}html.theme--documenter-dark .hero.is-primary .title,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .title{color:#fff}html.theme--documenter-dark .hero.is-primary .subtitle,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-primary .subtitle a:not(.button),html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),html.theme--documenter-dark .hero.is-primary .subtitle strong,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-primary .navbar-menu,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#375a7f}}html.theme--documenter-dark .hero.is-primary .navbar-item,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-item,html.theme--documenter-dark .hero.is-primary .navbar-link,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-primary a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,html.theme--documenter-dark .hero.is-primary a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,html.theme--documenter-dark .hero.is-primary .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-link:hover,html.theme--documenter-dark .hero.is-primary .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .hero.is-primary .tabs a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-primary .tabs a:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-primary .tabs li.is-active a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{color:#375a7f !important;opacity:1}html.theme--documenter-dark .hero.is-primary .tabs.is-boxed a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-primary .tabs.is-boxed a:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle a:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-primary .tabs.is-boxed li.is-active a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-primary .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle li.is-active a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#375a7f}html.theme--documenter-dark .hero.is-primary.is-bold,html.theme--documenter-dark .docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #214b62 0%, #375a7f 71%, #3a5796 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-primary.is-bold .navbar-menu,html.theme--documenter-dark .docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #214b62 0%, #375a7f 71%, #3a5796 100%)}}html.theme--documenter-dark .hero.is-link{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-link strong{color:inherit}html.theme--documenter-dark .hero.is-link .title{color:#fff}html.theme--documenter-dark .hero.is-link .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-link .subtitle a:not(.button),html.theme--documenter-dark .hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-link .navbar-menu{background-color:#1abc9c}}html.theme--documenter-dark .hero.is-link .navbar-item,html.theme--documenter-dark .hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-link a.navbar-item:hover,html.theme--documenter-dark .hero.is-link a.navbar-item.is-active,html.theme--documenter-dark .hero.is-link .navbar-link:hover,html.theme--documenter-dark .hero.is-link .navbar-link.is-active{background-color:#17a689;color:#fff}html.theme--documenter-dark .hero.is-link .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-link .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-link .tabs li.is-active a{color:#1abc9c !important;opacity:1}html.theme--documenter-dark .hero.is-link .tabs.is-boxed a,html.theme--documenter-dark .hero.is-link .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-link .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-link .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-link .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-link .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#1abc9c}html.theme--documenter-dark .hero.is-link.is-bold{background-image:linear-gradient(141deg, #0c9764 0%, #1abc9c 71%, #17d8d2 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #0c9764 0%, #1abc9c 71%, #17d8d2 100%)}}html.theme--documenter-dark .hero.is-info{background-color:#024c7d;color:#fff}html.theme--documenter-dark .hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-info strong{color:inherit}html.theme--documenter-dark .hero.is-info .title{color:#fff}html.theme--documenter-dark .hero.is-info .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-info .subtitle a:not(.button),html.theme--documenter-dark .hero.is-info .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-info .navbar-menu{background-color:#024c7d}}html.theme--documenter-dark .hero.is-info .navbar-item,html.theme--documenter-dark .hero.is-info .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-info a.navbar-item:hover,html.theme--documenter-dark .hero.is-info a.navbar-item.is-active,html.theme--documenter-dark .hero.is-info .navbar-link:hover,html.theme--documenter-dark .hero.is-info .navbar-link.is-active{background-color:#023d64;color:#fff}html.theme--documenter-dark .hero.is-info .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-info .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-info .tabs li.is-active a{color:#024c7d !important;opacity:1}html.theme--documenter-dark .hero.is-info .tabs.is-boxed a,html.theme--documenter-dark .hero.is-info .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-info .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-info .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-info .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-info .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#024c7d}html.theme--documenter-dark .hero.is-info.is-bold{background-image:linear-gradient(141deg, #003a4c 0%, #024c7d 71%, #004299 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #003a4c 0%, #024c7d 71%, #004299 100%)}}html.theme--documenter-dark .hero.is-success{background-color:#008438;color:#fff}html.theme--documenter-dark .hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-success strong{color:inherit}html.theme--documenter-dark .hero.is-success .title{color:#fff}html.theme--documenter-dark .hero.is-success .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-success .subtitle a:not(.button),html.theme--documenter-dark .hero.is-success .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-success .navbar-menu{background-color:#008438}}html.theme--documenter-dark .hero.is-success .navbar-item,html.theme--documenter-dark .hero.is-success .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-success a.navbar-item:hover,html.theme--documenter-dark .hero.is-success a.navbar-item.is-active,html.theme--documenter-dark .hero.is-success .navbar-link:hover,html.theme--documenter-dark .hero.is-success .navbar-link.is-active{background-color:#006b2d;color:#fff}html.theme--documenter-dark .hero.is-success .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-success .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-success .tabs li.is-active a{color:#008438 !important;opacity:1}html.theme--documenter-dark .hero.is-success .tabs.is-boxed a,html.theme--documenter-dark .hero.is-success .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-success .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-success .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-success .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-success .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#008438}html.theme--documenter-dark .hero.is-success.is-bold{background-image:linear-gradient(141deg, #005115 0%, #008438 71%, #009e5d 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #005115 0%, #008438 71%, #009e5d 100%)}}html.theme--documenter-dark .hero.is-warning{background-color:#ad8100;color:#fff}html.theme--documenter-dark .hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-warning strong{color:inherit}html.theme--documenter-dark .hero.is-warning .title{color:#fff}html.theme--documenter-dark .hero.is-warning .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-warning .subtitle a:not(.button),html.theme--documenter-dark .hero.is-warning .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-warning .navbar-menu{background-color:#ad8100}}html.theme--documenter-dark .hero.is-warning .navbar-item,html.theme--documenter-dark .hero.is-warning .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-warning a.navbar-item:hover,html.theme--documenter-dark .hero.is-warning a.navbar-item.is-active,html.theme--documenter-dark .hero.is-warning .navbar-link:hover,html.theme--documenter-dark .hero.is-warning .navbar-link.is-active{background-color:#946e00;color:#fff}html.theme--documenter-dark .hero.is-warning .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-warning .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-warning .tabs li.is-active a{color:#ad8100 !important;opacity:1}html.theme--documenter-dark .hero.is-warning .tabs.is-boxed a,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-warning .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-warning .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-warning .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#ad8100}html.theme--documenter-dark .hero.is-warning.is-bold{background-image:linear-gradient(141deg, #7a4700 0%, #ad8100 71%, #c7b500 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #7a4700 0%, #ad8100 71%, #c7b500 100%)}}html.theme--documenter-dark .hero.is-danger{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-danger strong{color:inherit}html.theme--documenter-dark .hero.is-danger .title{color:#fff}html.theme--documenter-dark .hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-danger .subtitle a:not(.button),html.theme--documenter-dark .hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-danger .navbar-menu{background-color:#9e1b0d}}html.theme--documenter-dark .hero.is-danger .navbar-item,html.theme--documenter-dark .hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-danger a.navbar-item:hover,html.theme--documenter-dark .hero.is-danger a.navbar-item.is-active,html.theme--documenter-dark .hero.is-danger .navbar-link:hover,html.theme--documenter-dark .hero.is-danger .navbar-link.is-active{background-color:#86170b;color:#fff}html.theme--documenter-dark .hero.is-danger .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-danger .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-danger .tabs li.is-active a{color:#9e1b0d !important;opacity:1}html.theme--documenter-dark .hero.is-danger .tabs.is-boxed a,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-danger .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-danger .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-danger .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#9e1b0d}html.theme--documenter-dark .hero.is-danger.is-bold{background-image:linear-gradient(141deg, #75030b 0%, #9e1b0d 71%, #ba380a 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #75030b 0%, #9e1b0d 71%, #ba380a 100%)}}html.theme--documenter-dark .hero.is-small .hero-body,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding:1.5rem}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero.is-large .hero-body{padding:18rem 6rem}}html.theme--documenter-dark .hero.is-halfheight .hero-body,html.theme--documenter-dark .hero.is-fullheight .hero-body,html.theme--documenter-dark .hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}html.theme--documenter-dark .hero.is-halfheight .hero-body>.container,html.theme--documenter-dark .hero.is-fullheight .hero-body>.container,html.theme--documenter-dark .hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .hero.is-halfheight{min-height:50vh}html.theme--documenter-dark .hero.is-fullheight{min-height:100vh}html.theme--documenter-dark .hero-video{overflow:hidden}html.theme--documenter-dark .hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}html.theme--documenter-dark .hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){html.theme--documenter-dark .hero-video{display:none}}html.theme--documenter-dark .hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){html.theme--documenter-dark .hero-buttons .button{display:flex}html.theme--documenter-dark .hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero-buttons{display:flex;justify-content:center}html.theme--documenter-dark .hero-buttons .button:not(:last-child){margin-right:1.5rem}}html.theme--documenter-dark .hero-head,html.theme--documenter-dark .hero-foot{flex-grow:0;flex-shrink:0}html.theme--documenter-dark .hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero-body{padding:3rem 3rem}}html.theme--documenter-dark .section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){html.theme--documenter-dark .section{padding:3rem 3rem}html.theme--documenter-dark .section.is-medium{padding:9rem 4.5rem}html.theme--documenter-dark .section.is-large{padding:18rem 6rem}}html.theme--documenter-dark .footer{background-color:#282f2f;padding:3rem 1.5rem 6rem}html.theme--documenter-dark hr{height:1px}html.theme--documenter-dark h6{text-transform:uppercase;letter-spacing:0.5px}html.theme--documenter-dark .hero{background-color:#343c3d}html.theme--documenter-dark a{transition:all 200ms ease}html.theme--documenter-dark .button{transition:all 200ms ease;border-width:1px;color:#fff}html.theme--documenter-dark .button.is-active,html.theme--documenter-dark .button.is-focused,html.theme--documenter-dark .button:active,html.theme--documenter-dark .button:focus{box-shadow:0 0 0 2px rgba(140,155,157,0.5)}html.theme--documenter-dark .button.is-white.is-hovered,html.theme--documenter-dark .button.is-white:hover{background-color:#fff}html.theme--documenter-dark .button.is-white.is-active,html.theme--documenter-dark .button.is-white.is-focused,html.theme--documenter-dark .button.is-white:active,html.theme--documenter-dark .button.is-white:focus{border-color:#fff;box-shadow:0 0 0 2px rgba(255,255,255,0.5)}html.theme--documenter-dark .button.is-black.is-hovered,html.theme--documenter-dark .button.is-black:hover{background-color:#1d1d1d}html.theme--documenter-dark .button.is-black.is-active,html.theme--documenter-dark .button.is-black.is-focused,html.theme--documenter-dark .button.is-black:active,html.theme--documenter-dark .button.is-black:focus{border-color:#0a0a0a;box-shadow:0 0 0 2px rgba(10,10,10,0.5)}html.theme--documenter-dark .button.is-light.is-hovered,html.theme--documenter-dark .button.is-light:hover{background-color:#fff}html.theme--documenter-dark .button.is-light.is-active,html.theme--documenter-dark .button.is-light.is-focused,html.theme--documenter-dark .button.is-light:active,html.theme--documenter-dark .button.is-light:focus{border-color:#ecf0f1;box-shadow:0 0 0 2px rgba(236,240,241,0.5)}html.theme--documenter-dark .button.is-dark.is-hovered,html.theme--documenter-dark .content kbd.button.is-hovered,html.theme--documenter-dark .button.is-dark:hover,html.theme--documenter-dark .content kbd.button:hover{background-color:#3a4344}html.theme--documenter-dark .button.is-dark.is-active,html.theme--documenter-dark .content kbd.button.is-active,html.theme--documenter-dark .button.is-dark.is-focused,html.theme--documenter-dark .content kbd.button.is-focused,html.theme--documenter-dark .button.is-dark:active,html.theme--documenter-dark .content kbd.button:active,html.theme--documenter-dark .button.is-dark:focus,html.theme--documenter-dark .content kbd.button:focus{border-color:#282f2f;box-shadow:0 0 0 2px rgba(40,47,47,0.5)}html.theme--documenter-dark .button.is-primary.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-hovered.docs-sourcelink,html.theme--documenter-dark .button.is-primary:hover,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:hover{background-color:#436d9a}html.theme--documenter-dark .button.is-primary.is-active,html.theme--documenter-dark .docstring>section>a.button.is-active.docs-sourcelink,html.theme--documenter-dark .button.is-primary.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-focused.docs-sourcelink,html.theme--documenter-dark .button.is-primary:active,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:active,html.theme--documenter-dark .button.is-primary:focus,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:focus{border-color:#375a7f;box-shadow:0 0 0 2px rgba(55,90,127,0.5)}html.theme--documenter-dark .button.is-link.is-hovered,html.theme--documenter-dark .button.is-link:hover{background-color:#1fdeb8}html.theme--documenter-dark .button.is-link.is-active,html.theme--documenter-dark .button.is-link.is-focused,html.theme--documenter-dark .button.is-link:active,html.theme--documenter-dark .button.is-link:focus{border-color:#1abc9c;box-shadow:0 0 0 2px rgba(26,188,156,0.5)}html.theme--documenter-dark .button.is-info.is-hovered,html.theme--documenter-dark .button.is-info:hover{background-color:#0363a3}html.theme--documenter-dark .button.is-info.is-active,html.theme--documenter-dark .button.is-info.is-focused,html.theme--documenter-dark .button.is-info:active,html.theme--documenter-dark .button.is-info:focus{border-color:#024c7d;box-shadow:0 0 0 2px rgba(2,76,125,0.5)}html.theme--documenter-dark .button.is-success.is-hovered,html.theme--documenter-dark .button.is-success:hover{background-color:#00aa48}html.theme--documenter-dark .button.is-success.is-active,html.theme--documenter-dark .button.is-success.is-focused,html.theme--documenter-dark .button.is-success:active,html.theme--documenter-dark .button.is-success:focus{border-color:#008438;box-shadow:0 0 0 2px rgba(0,132,56,0.5)}html.theme--documenter-dark .button.is-warning.is-hovered,html.theme--documenter-dark .button.is-warning:hover{background-color:#d39e00}html.theme--documenter-dark .button.is-warning.is-active,html.theme--documenter-dark .button.is-warning.is-focused,html.theme--documenter-dark .button.is-warning:active,html.theme--documenter-dark .button.is-warning:focus{border-color:#ad8100;box-shadow:0 0 0 2px rgba(173,129,0,0.5)}html.theme--documenter-dark .button.is-danger.is-hovered,html.theme--documenter-dark .button.is-danger:hover{background-color:#c12110}html.theme--documenter-dark .button.is-danger.is-active,html.theme--documenter-dark .button.is-danger.is-focused,html.theme--documenter-dark .button.is-danger:active,html.theme--documenter-dark .button.is-danger:focus{border-color:#9e1b0d;box-shadow:0 0 0 2px rgba(158,27,13,0.5)}html.theme--documenter-dark .label{color:#dbdee0}html.theme--documenter-dark .button,html.theme--documenter-dark .control.has-icons-left .icon,html.theme--documenter-dark .control.has-icons-right .icon,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .select,html.theme--documenter-dark .select select,html.theme--documenter-dark .textarea{height:2.5em}html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark .textarea{transition:all 200ms ease;box-shadow:none;border-width:1px;padding-left:1em;padding-right:1em}html.theme--documenter-dark .select:after,html.theme--documenter-dark .select select{border-width:1px}html.theme--documenter-dark .control.has-addons .button,html.theme--documenter-dark .control.has-addons .input,html.theme--documenter-dark .control.has-addons #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .control.has-addons form.docs-search>input,html.theme--documenter-dark .control.has-addons .select{margin-right:-1px}html.theme--documenter-dark .notification{background-color:#343c3d}html.theme--documenter-dark .card{box-shadow:none;border:1px solid #343c3d;background-color:#282f2f;border-radius:.4em}html.theme--documenter-dark .card .card-image img{border-radius:.4em .4em 0 0}html.theme--documenter-dark .card .card-header{box-shadow:none;background-color:rgba(18,18,18,0.2);border-radius:.4em .4em 0 0}html.theme--documenter-dark .card .card-footer{background-color:rgba(18,18,18,0.2)}html.theme--documenter-dark .card .card-footer,html.theme--documenter-dark .card .card-footer-item{border-width:1px;border-color:#343c3d}html.theme--documenter-dark .notification.is-white a:not(.button){color:#0a0a0a;text-decoration:underline}html.theme--documenter-dark .notification.is-black a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-light a:not(.button){color:rgba(0,0,0,0.7);text-decoration:underline}html.theme--documenter-dark .notification.is-dark a:not(.button),html.theme--documenter-dark .content kbd.notification a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-primary a:not(.button),html.theme--documenter-dark .docstring>section>a.notification.docs-sourcelink a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-link a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-info a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-success a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-warning a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-danger a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .tag,html.theme--documenter-dark .content kbd,html.theme--documenter-dark .docstring>section>a.docs-sourcelink{border-radius:.4em}html.theme--documenter-dark .menu-list a{transition:all 300ms ease}html.theme--documenter-dark .modal-card-body{background-color:#282f2f}html.theme--documenter-dark .modal-card-foot,html.theme--documenter-dark .modal-card-head{border-color:#343c3d}html.theme--documenter-dark .message-header{font-weight:700;background-color:#343c3d;color:#fff}html.theme--documenter-dark .message-body{border-width:1px;border-color:#343c3d}html.theme--documenter-dark .navbar{border-radius:.4em}html.theme--documenter-dark .navbar.is-transparent{background:none}html.theme--documenter-dark .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#1abc9c}@media screen and (max-width: 1055px){html.theme--documenter-dark .navbar .navbar-menu{background-color:#375a7f;border-radius:0 0 .4em .4em}}html.theme--documenter-dark .hero .navbar,html.theme--documenter-dark body>.navbar{border-radius:0}html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-previous{border-width:1px}html.theme--documenter-dark .panel-block,html.theme--documenter-dark .panel-heading,html.theme--documenter-dark .panel-tabs{border-width:1px}html.theme--documenter-dark .panel-block:first-child,html.theme--documenter-dark .panel-heading:first-child,html.theme--documenter-dark .panel-tabs:first-child{border-top-width:1px}html.theme--documenter-dark .panel-heading{font-weight:700}html.theme--documenter-dark .panel-tabs a{border-width:1px;margin-bottom:-1px}html.theme--documenter-dark .panel-tabs a.is-active{border-bottom-color:#17a689}html.theme--documenter-dark .panel-block:hover{color:#1dd2af}html.theme--documenter-dark .panel-block:hover .panel-icon{color:#1dd2af}html.theme--documenter-dark .panel-block.is-active .panel-icon{color:#17a689}html.theme--documenter-dark .tabs a{border-bottom-width:1px;margin-bottom:-1px}html.theme--documenter-dark .tabs ul{border-bottom-width:1px}html.theme--documenter-dark .tabs.is-boxed a{border-width:1px}html.theme--documenter-dark .tabs.is-boxed li.is-active a{background-color:#1f2424}html.theme--documenter-dark .tabs.is-toggle li a{border-width:1px;margin-bottom:0}html.theme--documenter-dark .tabs.is-toggle li+li{margin-left:-1px}html.theme--documenter-dark .hero.is-white .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-black .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-light .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-dark .navbar .navbar-dropdown .navbar-item:hover,html.theme--documenter-dark .content kbd.hero .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-primary .navbar .navbar-dropdown .navbar-item:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-link .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-info .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-success .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-warning .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-danger .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark h1 .docs-heading-anchor,html.theme--documenter-dark h1 .docs-heading-anchor:hover,html.theme--documenter-dark h1 .docs-heading-anchor:visited,html.theme--documenter-dark h2 .docs-heading-anchor,html.theme--documenter-dark h2 .docs-heading-anchor:hover,html.theme--documenter-dark h2 .docs-heading-anchor:visited,html.theme--documenter-dark h3 .docs-heading-anchor,html.theme--documenter-dark h3 .docs-heading-anchor:hover,html.theme--documenter-dark h3 .docs-heading-anchor:visited,html.theme--documenter-dark h4 .docs-heading-anchor,html.theme--documenter-dark h4 .docs-heading-anchor:hover,html.theme--documenter-dark h4 .docs-heading-anchor:visited,html.theme--documenter-dark h5 .docs-heading-anchor,html.theme--documenter-dark h5 .docs-heading-anchor:hover,html.theme--documenter-dark h5 .docs-heading-anchor:visited,html.theme--documenter-dark h6 .docs-heading-anchor,html.theme--documenter-dark h6 .docs-heading-anchor:hover,html.theme--documenter-dark h6 .docs-heading-anchor:visited{color:#f2f2f2}html.theme--documenter-dark h1 .docs-heading-anchor-permalink,html.theme--documenter-dark h2 .docs-heading-anchor-permalink,html.theme--documenter-dark h3 .docs-heading-anchor-permalink,html.theme--documenter-dark h4 .docs-heading-anchor-permalink,html.theme--documenter-dark h5 .docs-heading-anchor-permalink,html.theme--documenter-dark h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}html.theme--documenter-dark h1 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h2 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h3 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h4 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h5 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f0c1"}html.theme--documenter-dark h1:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h2:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h3:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h4:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h5:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h6:hover .docs-heading-anchor-permalink{visibility:visible}html.theme--documenter-dark .docs-light-only{display:none !important}html.theme--documenter-dark pre{position:relative;overflow:hidden}html.theme--documenter-dark pre code,html.theme--documenter-dark pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}html.theme--documenter-dark pre code:first-of-type,html.theme--documenter-dark pre code.hljs:first-of-type{padding-top:0.5rem !important}html.theme--documenter-dark pre code:last-of-type,html.theme--documenter-dark pre code.hljs:last-of-type{padding-bottom:0.5rem !important}html.theme--documenter-dark pre .copy-button{opacity:0.2;transition:opacity 0.2s;position:absolute;right:0em;top:0em;padding:0.5em;width:2.5em;height:2.5em;background:transparent;border:none;font-family:"Font Awesome 6 Free";color:#fff;cursor:pointer;text-align:center}html.theme--documenter-dark pre .copy-button:focus,html.theme--documenter-dark pre .copy-button:hover{opacity:1;background:rgba(255,255,255,0.1);color:#1abc9c}html.theme--documenter-dark pre .copy-button.success{color:#259a12;opacity:1}html.theme--documenter-dark pre .copy-button.error{color:#cb3c33;opacity:1}html.theme--documenter-dark pre:hover .copy-button{opacity:1}html.theme--documenter-dark .admonition{background-color:#282f2f;border-style:solid;border-width:1px;border-color:#5e6d6f;border-radius:.4em;font-size:1rem}html.theme--documenter-dark .admonition strong{color:currentColor}html.theme--documenter-dark .admonition.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.admonition{font-size:.75rem}html.theme--documenter-dark .admonition.is-medium{font-size:1.25rem}html.theme--documenter-dark .admonition.is-large{font-size:1.5rem}html.theme--documenter-dark .admonition.is-default{background-color:#282f2f;border-color:#5e6d6f}html.theme--documenter-dark .admonition.is-default>.admonition-header{background-color:#5e6d6f;color:#fff}html.theme--documenter-dark .admonition.is-default>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-info{background-color:#282f2f;border-color:#024c7d}html.theme--documenter-dark .admonition.is-info>.admonition-header{background-color:#024c7d;color:#fff}html.theme--documenter-dark .admonition.is-info>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-success{background-color:#282f2f;border-color:#008438}html.theme--documenter-dark .admonition.is-success>.admonition-header{background-color:#008438;color:#fff}html.theme--documenter-dark .admonition.is-success>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-warning{background-color:#282f2f;border-color:#ad8100}html.theme--documenter-dark .admonition.is-warning>.admonition-header{background-color:#ad8100;color:#fff}html.theme--documenter-dark .admonition.is-warning>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-danger{background-color:#282f2f;border-color:#9e1b0d}html.theme--documenter-dark .admonition.is-danger>.admonition-header{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .admonition.is-danger>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-compat{background-color:#282f2f;border-color:#137886}html.theme--documenter-dark .admonition.is-compat>.admonition-header{background-color:#137886;color:#fff}html.theme--documenter-dark .admonition.is-compat>.admonition-body{color:#fff}html.theme--documenter-dark .admonition-header{color:#fff;background-color:#5e6d6f;align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}html.theme--documenter-dark .admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}html.theme--documenter-dark details.admonition.is-details>.admonition-header{list-style:none}html.theme--documenter-dark details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}html.theme--documenter-dark details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}html.theme--documenter-dark .admonition-body{color:#fff;padding:0.5rem .75rem}html.theme--documenter-dark .admonition-body pre{background-color:#282f2f}html.theme--documenter-dark .admonition-body code{background-color:rgba(255,255,255,0.05)}html.theme--documenter-dark .docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:1px solid #5e6d6f;box-shadow:none;max-width:100%}html.theme--documenter-dark .docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#282f2f;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #5e6d6f}html.theme--documenter-dark .docstring>header code{background-color:transparent}html.theme--documenter-dark .docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}html.theme--documenter-dark .docstring>header .docstring-binding{margin-right:0.3em}html.theme--documenter-dark .docstring>header .docstring-category{margin-left:0.3em}html.theme--documenter-dark .docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #5e6d6f}html.theme--documenter-dark .docstring>section:last-child{border-bottom:none}html.theme--documenter-dark .docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}html.theme--documenter-dark .docstring>section>a.docs-sourcelink:focus{opacity:1 !important}html.theme--documenter-dark .docstring:hover>section>a.docs-sourcelink{opacity:0.2}html.theme--documenter-dark .docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}html.theme--documenter-dark .docstring>section:hover a.docs-sourcelink{opacity:1}html.theme--documenter-dark .documenter-example-output{background-color:#1f2424}html.theme--documenter-dark .outdated-warning-overlay{position:fixed;top:0;left:0;right:0;box-shadow:0 0 10px rgba(0,0,0,0.3);z-index:999;background-color:#282f2f;color:#fff;border-bottom:3px solid #9e1b0d;padding:10px 35px;text-align:center;font-size:15px}html.theme--documenter-dark .outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}html.theme--documenter-dark .outdated-warning-overlay a{color:#1abc9c}html.theme--documenter-dark .outdated-warning-overlay a:hover{color:#1dd2af}html.theme--documenter-dark .content pre{border:1px solid #5e6d6f}html.theme--documenter-dark .content code{font-weight:inherit}html.theme--documenter-dark .content a code{color:#1abc9c}html.theme--documenter-dark .content h1 code,html.theme--documenter-dark .content h2 code,html.theme--documenter-dark .content h3 code,html.theme--documenter-dark .content h4 code,html.theme--documenter-dark .content h5 code,html.theme--documenter-dark .content h6 code{color:#f2f2f2}html.theme--documenter-dark .content table{display:block;width:initial;max-width:100%;overflow-x:auto}html.theme--documenter-dark .content blockquote>ul:first-child,html.theme--documenter-dark .content blockquote>ol:first-child,html.theme--documenter-dark .content .admonition-body>ul:first-child,html.theme--documenter-dark .content .admonition-body>ol:first-child{margin-top:0}html.theme--documenter-dark pre,html.theme--documenter-dark code{font-variant-ligatures:no-contextual}html.theme--documenter-dark .breadcrumb a.is-disabled{cursor:default;pointer-events:none}html.theme--documenter-dark .breadcrumb a.is-disabled,html.theme--documenter-dark .breadcrumb a.is-disabled:hover{color:#f2f2f2}html.theme--documenter-dark .hljs{background:initial !important}html.theme--documenter-dark .katex .katex-mathml{top:0;right:0}html.theme--documenter-dark .katex-display,html.theme--documenter-dark mjx-container,html.theme--documenter-dark .MathJax_Display{margin:0.5em 0 !important}html.theme--documenter-dark html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}html.theme--documenter-dark li.no-marker{list-style:none}html.theme--documenter-dark #documenter .docs-main>article{overflow-wrap:break-word}html.theme--documenter-dark #documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main{width:100%}html.theme--documenter-dark #documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}html.theme--documenter-dark #documenter .docs-main>header,html.theme--documenter-dark #documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}html.theme--documenter-dark #documenter .docs-main header.docs-navbar{background-color:#1f2424;border-bottom:1px solid #5e6d6f;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-icon,html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}html.theme--documenter-dark #documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main header.docs-navbar{position:sticky;top:0;padding:0 1rem;transition-property:top, box-shadow;-webkit-transition-property:top, box-shadow;transition-duration:0.3s;-webkit-transition-duration:0.3s}html.theme--documenter-dark #documenter .docs-main header.docs-navbar.headroom--not-top{box-shadow:.2rem 0rem .4rem #171717;transition-duration:0.7s;-webkit-transition-duration:0.7s}html.theme--documenter-dark #documenter .docs-main header.docs-navbar.headroom--unpinned.headroom--not-top.headroom--not-bottom{top:-4.5rem;transition-duration:0.7s;-webkit-transition-duration:0.7s}}html.theme--documenter-dark #documenter .docs-main section.footnotes{border-top:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-main section.footnotes li .tag:first-child,html.theme--documenter-dark #documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,html.theme--documenter-dark #documenter .docs-main section.footnotes li .content kbd:first-child,html.theme--documenter-dark .content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}html.theme--documenter-dark #documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #5e6d6f;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-nextpage,html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}html.theme--documenter-dark #documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}html.theme--documenter-dark #documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}html.theme--documenter-dark #documenter .docs-sidebar{display:flex;flex-direction:column;color:#fff;background-color:#282f2f;border-right:1px solid #5e6d6f;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}html.theme--documenter-dark #documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #171717}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar{left:0;top:0}}html.theme--documenter-dark #documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name{flex-shrink:0;font-size:1.5rem;font-weight:700;text-align:center;white-space:nowrap;overflow:hidden;padding:0.5rem 0}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name a,html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name a:hover{color:#fff}html.theme--documenter-dark #documenter .docs-sidebar .docs-version-selector{border-top:1px solid #5e6d6f;display:none;padding:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-version-selector.visible{display:flex}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #5e6d6f;padding-bottom:1.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1;font-size:.75rem;margin-left:1rem;margin-top:auto;margin-bottom:auto}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#fff;background:#282f2f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu a.tocitem:hover,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#fff;background-color:#32393a}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #5e6d6f;border-bottom:1px solid #5e6d6f;background-color:#1f2424}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#1f2424;color:#fff}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#32393a;color:#fff}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}html.theme--documenter-dark #documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{width:14.4rem}html.theme--documenter-dark #documenter .docs-sidebar #documenter-search-query{color:#868c98;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#3b4445}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#4e5a5c}}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#3b4445}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#4e5a5c}}html.theme--documenter-dark kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(245,245,245,0.6);box-shadow:0 2px 0 1px rgba(245,245,245,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}html.theme--documenter-dark .search-min-width-50{min-width:50%}html.theme--documenter-dark .search-min-height-100{min-height:100%}html.theme--documenter-dark .search-modal-card-body{max-height:calc(100vh - 15rem)}html.theme--documenter-dark .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--documenter-dark .search-result-link:hover,html.theme--documenter-dark .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--documenter-dark .search-result-link .property-search-result-badge,html.theme--documenter-dark .search-result-link .search-filter{transition:all 300ms}html.theme--documenter-dark .property-search-result-badge,html.theme--documenter-dark .search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}html.theme--documenter-dark .search-result-link:hover .property-search-result-badge,html.theme--documenter-dark .search-result-link:hover .search-filter,html.theme--documenter-dark .search-result-link:focus .property-search-result-badge,html.theme--documenter-dark .search-result-link:focus .search-filter{color:#333;background-color:#f1f5f9}html.theme--documenter-dark .search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}html.theme--documenter-dark .search-filter:hover,html.theme--documenter-dark .search-filter:focus{color:#333}html.theme--documenter-dark .search-filter-selected{color:#f5f5f5;background-color:rgba(139,0,139,0.5)}html.theme--documenter-dark .search-filter-selected:hover,html.theme--documenter-dark .search-filter-selected:focus{color:#f5f5f5}html.theme--documenter-dark .search-result-highlight{background-color:#ffdd57;color:black}html.theme--documenter-dark .search-divider{border-bottom:1px solid #5e6d6f}html.theme--documenter-dark .search-result-title{width:85%;color:#f5f5f5}html.theme--documenter-dark .search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar-thumb,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar-track,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}html.theme--documenter-dark .w-100{width:100%}html.theme--documenter-dark .gap-2{gap:0.5rem}html.theme--documenter-dark .gap-4{gap:1rem}html.theme--documenter-dark .gap-8{gap:2rem}html.theme--documenter-dark{background-color:#1f2424;font-size:16px;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--documenter-dark .ansi span.sgr1{font-weight:bolder}html.theme--documenter-dark .ansi span.sgr2{font-weight:lighter}html.theme--documenter-dark .ansi span.sgr3{font-style:italic}html.theme--documenter-dark .ansi span.sgr4{text-decoration:underline}html.theme--documenter-dark .ansi span.sgr7{color:#1f2424;background-color:#fff}html.theme--documenter-dark .ansi span.sgr8{color:transparent}html.theme--documenter-dark .ansi span.sgr8 span{color:transparent}html.theme--documenter-dark .ansi span.sgr9{text-decoration:line-through}html.theme--documenter-dark .ansi span.sgr30{color:#242424}html.theme--documenter-dark .ansi span.sgr31{color:#f6705f}html.theme--documenter-dark .ansi span.sgr32{color:#4fb43a}html.theme--documenter-dark .ansi span.sgr33{color:#f4c72f}html.theme--documenter-dark .ansi span.sgr34{color:#7587f0}html.theme--documenter-dark .ansi span.sgr35{color:#bc89d3}html.theme--documenter-dark .ansi span.sgr36{color:#49b6ca}html.theme--documenter-dark .ansi span.sgr37{color:#b3bdbe}html.theme--documenter-dark .ansi span.sgr40{background-color:#242424}html.theme--documenter-dark .ansi span.sgr41{background-color:#f6705f}html.theme--documenter-dark .ansi span.sgr42{background-color:#4fb43a}html.theme--documenter-dark .ansi span.sgr43{background-color:#f4c72f}html.theme--documenter-dark .ansi span.sgr44{background-color:#7587f0}html.theme--documenter-dark .ansi span.sgr45{background-color:#bc89d3}html.theme--documenter-dark .ansi span.sgr46{background-color:#49b6ca}html.theme--documenter-dark .ansi span.sgr47{background-color:#b3bdbe}html.theme--documenter-dark .ansi span.sgr90{color:#92a0a2}html.theme--documenter-dark .ansi span.sgr91{color:#ff8674}html.theme--documenter-dark .ansi span.sgr92{color:#79d462}html.theme--documenter-dark .ansi span.sgr93{color:#ffe76b}html.theme--documenter-dark .ansi span.sgr94{color:#8a98ff}html.theme--documenter-dark .ansi span.sgr95{color:#d2a4e6}html.theme--documenter-dark .ansi span.sgr96{color:#6bc8db}html.theme--documenter-dark .ansi span.sgr97{color:#ecf0f1}html.theme--documenter-dark .ansi span.sgr100{background-color:#92a0a2}html.theme--documenter-dark .ansi span.sgr101{background-color:#ff8674}html.theme--documenter-dark .ansi span.sgr102{background-color:#79d462}html.theme--documenter-dark .ansi span.sgr103{background-color:#ffe76b}html.theme--documenter-dark .ansi span.sgr104{background-color:#8a98ff}html.theme--documenter-dark .ansi span.sgr105{background-color:#d2a4e6}html.theme--documenter-dark .ansi span.sgr106{background-color:#6bc8db}html.theme--documenter-dark .ansi span.sgr107{background-color:#ecf0f1}html.theme--documenter-dark code.language-julia-repl>span.hljs-meta{color:#4fb43a;font-weight:bolder}html.theme--documenter-dark .hljs{background:#2b2b2b;color:#f8f8f2}html.theme--documenter-dark .hljs-comment,html.theme--documenter-dark .hljs-quote{color:#d4d0ab}html.theme--documenter-dark .hljs-variable,html.theme--documenter-dark .hljs-template-variable,html.theme--documenter-dark .hljs-tag,html.theme--documenter-dark .hljs-name,html.theme--documenter-dark .hljs-selector-id,html.theme--documenter-dark .hljs-selector-class,html.theme--documenter-dark .hljs-regexp,html.theme--documenter-dark .hljs-deletion{color:#ffa07a}html.theme--documenter-dark .hljs-number,html.theme--documenter-dark .hljs-built_in,html.theme--documenter-dark .hljs-literal,html.theme--documenter-dark .hljs-type,html.theme--documenter-dark .hljs-params,html.theme--documenter-dark .hljs-meta,html.theme--documenter-dark .hljs-link{color:#f5ab35}html.theme--documenter-dark .hljs-attribute{color:#ffd700}html.theme--documenter-dark .hljs-string,html.theme--documenter-dark .hljs-symbol,html.theme--documenter-dark .hljs-bullet,html.theme--documenter-dark .hljs-addition{color:#abe338}html.theme--documenter-dark .hljs-title,html.theme--documenter-dark .hljs-section{color:#00e0e0}html.theme--documenter-dark .hljs-keyword,html.theme--documenter-dark .hljs-selector-tag{color:#dcc6e0}html.theme--documenter-dark .hljs-emphasis{font-style:italic}html.theme--documenter-dark .hljs-strong{font-weight:bold}@media screen and (-ms-high-contrast: active){html.theme--documenter-dark .hljs-addition,html.theme--documenter-dark .hljs-attribute,html.theme--documenter-dark .hljs-built_in,html.theme--documenter-dark .hljs-bullet,html.theme--documenter-dark .hljs-comment,html.theme--documenter-dark .hljs-link,html.theme--documenter-dark .hljs-literal,html.theme--documenter-dark .hljs-meta,html.theme--documenter-dark .hljs-number,html.theme--documenter-dark .hljs-params,html.theme--documenter-dark .hljs-string,html.theme--documenter-dark .hljs-symbol,html.theme--documenter-dark .hljs-type,html.theme--documenter-dark .hljs-quote{color:highlight}html.theme--documenter-dark .hljs-keyword,html.theme--documenter-dark .hljs-selector-tag{font-weight:bold}}html.theme--documenter-dark .hljs-subst{color:#f8f8f2} +*/}html.theme--documenter-dark html{background-color:#1f2424;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--documenter-dark article,html.theme--documenter-dark aside,html.theme--documenter-dark figure,html.theme--documenter-dark footer,html.theme--documenter-dark header,html.theme--documenter-dark hgroup,html.theme--documenter-dark section{display:block}html.theme--documenter-dark body,html.theme--documenter-dark button,html.theme--documenter-dark input,html.theme--documenter-dark optgroup,html.theme--documenter-dark select,html.theme--documenter-dark textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}html.theme--documenter-dark code,html.theme--documenter-dark pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--documenter-dark body{color:#fff;font-size:1em;font-weight:400;line-height:1.5}html.theme--documenter-dark a{color:#1abc9c;cursor:pointer;text-decoration:none}html.theme--documenter-dark a strong{color:currentColor}html.theme--documenter-dark a:hover{color:#1dd2af}html.theme--documenter-dark code{background-color:rgba(255,255,255,0.05);color:#ececec;font-size:.875em;font-weight:normal;padding:.1em}html.theme--documenter-dark hr{background-color:#282f2f;border:none;display:block;height:2px;margin:1.5rem 0}html.theme--documenter-dark img{height:auto;max-width:100%}html.theme--documenter-dark input[type="checkbox"],html.theme--documenter-dark input[type="radio"]{vertical-align:baseline}html.theme--documenter-dark small{font-size:.875em}html.theme--documenter-dark span{font-style:inherit;font-weight:inherit}html.theme--documenter-dark strong{color:#f2f2f2;font-weight:700}html.theme--documenter-dark fieldset{border:none}html.theme--documenter-dark pre{-webkit-overflow-scrolling:touch;background-color:#282f2f;color:#fff;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}html.theme--documenter-dark pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}html.theme--documenter-dark table td,html.theme--documenter-dark table th{vertical-align:top}html.theme--documenter-dark table td:not([align]),html.theme--documenter-dark table th:not([align]){text-align:inherit}html.theme--documenter-dark table th{color:#f2f2f2}html.theme--documenter-dark .box{background-color:#343c3d;border-radius:8px;box-shadow:none;color:#fff;display:block;padding:1.25rem}html.theme--documenter-dark a.box:hover,html.theme--documenter-dark a.box:focus{box-shadow:0 0.5em 1em -0.125em rgba(10,10,10,0.1),0 0 0 1px #1abc9c}html.theme--documenter-dark a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #1abc9c}html.theme--documenter-dark .button{background-color:#282f2f;border-color:#4c5759;border-width:1px;color:#375a7f;cursor:pointer;justify-content:center;padding-bottom:calc(0.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(0.5em - 1px);text-align:center;white-space:nowrap}html.theme--documenter-dark .button strong{color:inherit}html.theme--documenter-dark .button .icon,html.theme--documenter-dark .button .icon.is-small,html.theme--documenter-dark .button #documenter .docs-sidebar form.docs-search>input.icon,html.theme--documenter-dark #documenter .docs-sidebar .button form.docs-search>input.icon,html.theme--documenter-dark .button .icon.is-medium,html.theme--documenter-dark .button .icon.is-large{height:1.5em;width:1.5em}html.theme--documenter-dark .button .icon:first-child:not(:last-child){margin-left:calc(-0.5em - 1px);margin-right:.25em}html.theme--documenter-dark .button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}html.theme--documenter-dark .button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 1px)}html.theme--documenter-dark .button:hover,html.theme--documenter-dark .button.is-hovered{border-color:#8c9b9d;color:#f2f2f2}html.theme--documenter-dark .button:focus,html.theme--documenter-dark .button.is-focused{border-color:#8c9b9d;color:#17a689}html.theme--documenter-dark .button:focus:not(:active),html.theme--documenter-dark .button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .button:active,html.theme--documenter-dark .button.is-active{border-color:#343c3d;color:#f2f2f2}html.theme--documenter-dark .button.is-text{background-color:transparent;border-color:transparent;color:#fff;text-decoration:underline}html.theme--documenter-dark .button.is-text:hover,html.theme--documenter-dark .button.is-text.is-hovered,html.theme--documenter-dark .button.is-text:focus,html.theme--documenter-dark .button.is-text.is-focused{background-color:#282f2f;color:#f2f2f2}html.theme--documenter-dark .button.is-text:active,html.theme--documenter-dark .button.is-text.is-active{background-color:#1d2122;color:#f2f2f2}html.theme--documenter-dark .button.is-text[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}html.theme--documenter-dark .button.is-ghost{background:none;border-color:rgba(0,0,0,0);color:#1abc9c;text-decoration:none}html.theme--documenter-dark .button.is-ghost:hover,html.theme--documenter-dark .button.is-ghost.is-hovered{color:#1abc9c;text-decoration:underline}html.theme--documenter-dark .button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white:hover,html.theme--documenter-dark .button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white:focus,html.theme--documenter-dark .button.is-white.is-focused{border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white:focus:not(:active),html.theme--documenter-dark .button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--documenter-dark .button.is-white:active,html.theme--documenter-dark .button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}html.theme--documenter-dark .button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .button.is-white.is-inverted:hover,html.theme--documenter-dark .button.is-white.is-inverted.is-hovered{background-color:#000}html.theme--documenter-dark .button.is-white.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-white.is-outlined:hover,html.theme--documenter-dark .button.is-white.is-outlined.is-hovered,html.theme--documenter-dark .button.is-white.is-outlined:focus,html.theme--documenter-dark .button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--documenter-dark .button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-white.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-white.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-white.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-white.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--documenter-dark .button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black:hover,html.theme--documenter-dark .button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black:focus,html.theme--documenter-dark .button.is-black.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black:focus:not(:active),html.theme--documenter-dark .button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--documenter-dark .button.is-black:active,html.theme--documenter-dark .button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}html.theme--documenter-dark .button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-inverted:hover,html.theme--documenter-dark .button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-black.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-outlined:hover,html.theme--documenter-dark .button.is-black.is-outlined.is-hovered,html.theme--documenter-dark .button.is-black.is-outlined:focus,html.theme--documenter-dark .button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--documenter-dark .button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-black.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-black.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-black.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-black.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-light{background-color:#ecf0f1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light:hover,html.theme--documenter-dark .button.is-light.is-hovered{background-color:#e5eaec;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light:focus,html.theme--documenter-dark .button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light:focus:not(:active),html.theme--documenter-dark .button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(236,240,241,0.25)}html.theme--documenter-dark .button.is-light:active,html.theme--documenter-dark .button.is-light.is-active{background-color:#dde4e6;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light{background-color:#ecf0f1;border-color:#ecf0f1;box-shadow:none}html.theme--documenter-dark .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-inverted:hover,html.theme--documenter-dark .button.is-light.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--documenter-dark .button.is-light.is-outlined{background-color:transparent;border-color:#ecf0f1;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-outlined:hover,html.theme--documenter-dark .button.is-light.is-outlined.is-hovered,html.theme--documenter-dark .button.is-light.is-outlined:focus,html.theme--documenter-dark .button.is-light.is-outlined.is-focused{background-color:#ecf0f1;border-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #ecf0f1 #ecf0f1 !important}html.theme--documenter-dark .button.is-light.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-light.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-light.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-light.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--documenter-dark .button.is-light.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light.is-outlined{background-color:transparent;border-color:#ecf0f1;box-shadow:none;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ecf0f1 #ecf0f1 !important}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-dark,html.theme--documenter-dark .content kbd.button{background-color:#282f2f;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-dark:hover,html.theme--documenter-dark .content kbd.button:hover,html.theme--documenter-dark .button.is-dark.is-hovered,html.theme--documenter-dark .content kbd.button.is-hovered{background-color:#232829;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-dark:focus,html.theme--documenter-dark .content kbd.button:focus,html.theme--documenter-dark .button.is-dark.is-focused,html.theme--documenter-dark .content kbd.button.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-dark:focus:not(:active),html.theme--documenter-dark .content kbd.button:focus:not(:active),html.theme--documenter-dark .button.is-dark.is-focused:not(:active),html.theme--documenter-dark .content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(40,47,47,0.25)}html.theme--documenter-dark .button.is-dark:active,html.theme--documenter-dark .content kbd.button:active,html.theme--documenter-dark .button.is-dark.is-active,html.theme--documenter-dark .content kbd.button.is-active{background-color:#1d2122;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-dark[disabled],html.theme--documenter-dark .content kbd.button[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark,fieldset[disabled] html.theme--documenter-dark .content kbd.button{background-color:#282f2f;border-color:#282f2f;box-shadow:none}html.theme--documenter-dark .button.is-dark.is-inverted,html.theme--documenter-dark .content kbd.button.is-inverted{background-color:#fff;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-inverted:hover,html.theme--documenter-dark .content kbd.button.is-inverted:hover,html.theme--documenter-dark .button.is-dark.is-inverted.is-hovered,html.theme--documenter-dark .content kbd.button.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-dark.is-inverted[disabled],html.theme--documenter-dark .content kbd.button.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark.is-inverted,fieldset[disabled] html.theme--documenter-dark .content kbd.button.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-loading::after,html.theme--documenter-dark .content kbd.button.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-dark.is-outlined,html.theme--documenter-dark .content kbd.button.is-outlined{background-color:transparent;border-color:#282f2f;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-outlined:hover,html.theme--documenter-dark .content kbd.button.is-outlined:hover,html.theme--documenter-dark .button.is-dark.is-outlined.is-hovered,html.theme--documenter-dark .content kbd.button.is-outlined.is-hovered,html.theme--documenter-dark .button.is-dark.is-outlined:focus,html.theme--documenter-dark .content kbd.button.is-outlined:focus,html.theme--documenter-dark .button.is-dark.is-outlined.is-focused,html.theme--documenter-dark .content kbd.button.is-outlined.is-focused{background-color:#282f2f;border-color:#282f2f;color:#fff}html.theme--documenter-dark .button.is-dark.is-outlined.is-loading::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #282f2f #282f2f !important}html.theme--documenter-dark .button.is-dark.is-outlined.is-loading:hover::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-dark.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-dark.is-outlined.is-loading:focus::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-dark.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-dark.is-outlined[disabled],html.theme--documenter-dark .content kbd.button.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark.is-outlined,fieldset[disabled] html.theme--documenter-dark .content kbd.button.is-outlined{background-color:transparent;border-color:#282f2f;box-shadow:none;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined:hover,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined:focus,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-focused,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-focused{background-color:#fff;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #282f2f #282f2f !important}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined[disabled],html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined,fieldset[disabled] html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-primary,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink{background-color:#375a7f;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary:hover,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#335476;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary:focus,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:focus,html.theme--documenter-dark .button.is-primary.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary:focus:not(:active),html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:focus:not(:active),html.theme--documenter-dark .button.is-primary.is-focused:not(:active),html.theme--documenter-dark .docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(55,90,127,0.25)}html.theme--documenter-dark .button.is-primary:active,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:active,html.theme--documenter-dark .button.is-primary.is-active,html.theme--documenter-dark .docstring>section>a.button.is-active.docs-sourcelink{background-color:#2f4d6d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary[disabled],html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink{background-color:#375a7f;border-color:#375a7f;box-shadow:none}html.theme--documenter-dark .button.is-primary.is-inverted,html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-inverted:hover,html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-inverted.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}html.theme--documenter-dark .button.is-primary.is-inverted[disabled],html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary.is-inverted,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-loading::after,html.theme--documenter-dark .docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-primary.is-outlined,html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#375a7f;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-outlined:hover,html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-outlined.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,html.theme--documenter-dark .button.is-primary.is-outlined:focus,html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink:focus,html.theme--documenter-dark .button.is-primary.is-outlined.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#375a7f;border-color:#375a7f;color:#fff}html.theme--documenter-dark .button.is-primary.is-outlined.is-loading::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #375a7f #375a7f !important}html.theme--documenter-dark .button.is-primary.is-outlined.is-loading:hover::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--documenter-dark .button.is-primary.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--documenter-dark .button.is-primary.is-outlined.is-loading:focus::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--documenter-dark .button.is-primary.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-primary.is-outlined[disabled],html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary.is-outlined,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#375a7f;box-shadow:none;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined:hover,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined:focus,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #375a7f #375a7f !important}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined[disabled],html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-primary.is-light,html.theme--documenter-dark .docstring>section>a.button.is-light.docs-sourcelink{background-color:#f1f5f9;color:#4d7eb2}html.theme--documenter-dark .button.is-primary.is-light:hover,html.theme--documenter-dark .docstring>section>a.button.is-light.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-light.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#e8eef5;border-color:transparent;color:#4d7eb2}html.theme--documenter-dark .button.is-primary.is-light:active,html.theme--documenter-dark .docstring>section>a.button.is-light.docs-sourcelink:active,html.theme--documenter-dark .button.is-primary.is-light.is-active,html.theme--documenter-dark .docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#dfe8f1;border-color:transparent;color:#4d7eb2}html.theme--documenter-dark .button.is-link{background-color:#1abc9c;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link:hover,html.theme--documenter-dark .button.is-link.is-hovered{background-color:#18b193;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link:focus,html.theme--documenter-dark .button.is-link.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link:focus:not(:active),html.theme--documenter-dark .button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .button.is-link:active,html.theme--documenter-dark .button.is-link.is-active{background-color:#17a689;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link{background-color:#1abc9c;border-color:#1abc9c;box-shadow:none}html.theme--documenter-dark .button.is-link.is-inverted{background-color:#fff;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-inverted:hover,html.theme--documenter-dark .button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-link.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-link.is-outlined{background-color:transparent;border-color:#1abc9c;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-outlined:hover,html.theme--documenter-dark .button.is-link.is-outlined.is-hovered,html.theme--documenter-dark .button.is-link.is-outlined:focus,html.theme--documenter-dark .button.is-link.is-outlined.is-focused{background-color:#1abc9c;border-color:#1abc9c;color:#fff}html.theme--documenter-dark .button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #1abc9c #1abc9c !important}html.theme--documenter-dark .button.is-link.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-link.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-link.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-link.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link.is-outlined{background-color:transparent;border-color:#1abc9c;box-shadow:none;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #1abc9c #1abc9c !important}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-link.is-light{background-color:#edfdf9;color:#15987e}html.theme--documenter-dark .button.is-link.is-light:hover,html.theme--documenter-dark .button.is-link.is-light.is-hovered{background-color:#e2fbf6;border-color:transparent;color:#15987e}html.theme--documenter-dark .button.is-link.is-light:active,html.theme--documenter-dark .button.is-link.is-light.is-active{background-color:#d7f9f3;border-color:transparent;color:#15987e}html.theme--documenter-dark .button.is-info{background-color:#024c7d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:hover,html.theme--documenter-dark .button.is-info.is-hovered{background-color:#024470;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:focus,html.theme--documenter-dark .button.is-info.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:focus:not(:active),html.theme--documenter-dark .button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(2,76,125,0.25)}html.theme--documenter-dark .button.is-info:active,html.theme--documenter-dark .button.is-info.is-active{background-color:#023d64;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info{background-color:#024c7d;border-color:#024c7d;box-shadow:none}html.theme--documenter-dark .button.is-info.is-inverted{background-color:#fff;color:#024c7d}html.theme--documenter-dark .button.is-info.is-inverted:hover,html.theme--documenter-dark .button.is-info.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-info.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#024c7d}html.theme--documenter-dark .button.is-info.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-info.is-outlined{background-color:transparent;border-color:#024c7d;color:#024c7d}html.theme--documenter-dark .button.is-info.is-outlined:hover,html.theme--documenter-dark .button.is-info.is-outlined.is-hovered,html.theme--documenter-dark .button.is-info.is-outlined:focus,html.theme--documenter-dark .button.is-info.is-outlined.is-focused{background-color:#024c7d;border-color:#024c7d;color:#fff}html.theme--documenter-dark .button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #024c7d #024c7d !important}html.theme--documenter-dark .button.is-info.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-info.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-info.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-info.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info.is-outlined{background-color:transparent;border-color:#024c7d;box-shadow:none;color:#024c7d}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-focused{background-color:#fff;color:#024c7d}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #024c7d #024c7d !important}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-info.is-light{background-color:#ebf7ff;color:#0e9dfb}html.theme--documenter-dark .button.is-info.is-light:hover,html.theme--documenter-dark .button.is-info.is-light.is-hovered{background-color:#def2fe;border-color:transparent;color:#0e9dfb}html.theme--documenter-dark .button.is-info.is-light:active,html.theme--documenter-dark .button.is-info.is-light.is-active{background-color:#d2edfe;border-color:transparent;color:#0e9dfb}html.theme--documenter-dark .button.is-success{background-color:#008438;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:hover,html.theme--documenter-dark .button.is-success.is-hovered{background-color:#073;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:focus,html.theme--documenter-dark .button.is-success.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:focus:not(:active),html.theme--documenter-dark .button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(0,132,56,0.25)}html.theme--documenter-dark .button.is-success:active,html.theme--documenter-dark .button.is-success.is-active{background-color:#006b2d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success{background-color:#008438;border-color:#008438;box-shadow:none}html.theme--documenter-dark .button.is-success.is-inverted{background-color:#fff;color:#008438}html.theme--documenter-dark .button.is-success.is-inverted:hover,html.theme--documenter-dark .button.is-success.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-success.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#008438}html.theme--documenter-dark .button.is-success.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-success.is-outlined{background-color:transparent;border-color:#008438;color:#008438}html.theme--documenter-dark .button.is-success.is-outlined:hover,html.theme--documenter-dark .button.is-success.is-outlined.is-hovered,html.theme--documenter-dark .button.is-success.is-outlined:focus,html.theme--documenter-dark .button.is-success.is-outlined.is-focused{background-color:#008438;border-color:#008438;color:#fff}html.theme--documenter-dark .button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #008438 #008438 !important}html.theme--documenter-dark .button.is-success.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-success.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-success.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-success.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success.is-outlined{background-color:transparent;border-color:#008438;box-shadow:none;color:#008438}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-focused{background-color:#fff;color:#008438}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #008438 #008438 !important}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-success.is-light{background-color:#ebfff3;color:#00eb64}html.theme--documenter-dark .button.is-success.is-light:hover,html.theme--documenter-dark .button.is-success.is-light.is-hovered{background-color:#deffec;border-color:transparent;color:#00eb64}html.theme--documenter-dark .button.is-success.is-light:active,html.theme--documenter-dark .button.is-success.is-light.is-active{background-color:#d1ffe5;border-color:transparent;color:#00eb64}html.theme--documenter-dark .button.is-warning{background-color:#ad8100;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning:hover,html.theme--documenter-dark .button.is-warning.is-hovered{background-color:#a07700;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning:focus,html.theme--documenter-dark .button.is-warning.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning:focus:not(:active),html.theme--documenter-dark .button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(173,129,0,0.25)}html.theme--documenter-dark .button.is-warning:active,html.theme--documenter-dark .button.is-warning.is-active{background-color:#946e00;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning{background-color:#ad8100;border-color:#ad8100;box-shadow:none}html.theme--documenter-dark .button.is-warning.is-inverted{background-color:#fff;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-inverted:hover,html.theme--documenter-dark .button.is-warning.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-warning.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-warning.is-outlined{background-color:transparent;border-color:#ad8100;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-outlined:hover,html.theme--documenter-dark .button.is-warning.is-outlined.is-hovered,html.theme--documenter-dark .button.is-warning.is-outlined:focus,html.theme--documenter-dark .button.is-warning.is-outlined.is-focused{background-color:#ad8100;border-color:#ad8100;color:#fff}html.theme--documenter-dark .button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #ad8100 #ad8100 !important}html.theme--documenter-dark .button.is-warning.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-warning.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-warning.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-warning.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-warning.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-outlined{background-color:transparent;border-color:#ad8100;box-shadow:none;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-focused{background-color:#fff;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ad8100 #ad8100 !important}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-warning.is-light{background-color:#fffaeb;color:#d19c00}html.theme--documenter-dark .button.is-warning.is-light:hover,html.theme--documenter-dark .button.is-warning.is-light.is-hovered{background-color:#fff7de;border-color:transparent;color:#d19c00}html.theme--documenter-dark .button.is-warning.is-light:active,html.theme--documenter-dark .button.is-warning.is-light.is-active{background-color:#fff3d1;border-color:transparent;color:#d19c00}html.theme--documenter-dark .button.is-danger{background-color:#9e1b0d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:hover,html.theme--documenter-dark .button.is-danger.is-hovered{background-color:#92190c;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:focus,html.theme--documenter-dark .button.is-danger.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:focus:not(:active),html.theme--documenter-dark .button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(158,27,13,0.25)}html.theme--documenter-dark .button.is-danger:active,html.theme--documenter-dark .button.is-danger.is-active{background-color:#86170b;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger{background-color:#9e1b0d;border-color:#9e1b0d;box-shadow:none}html.theme--documenter-dark .button.is-danger.is-inverted{background-color:#fff;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-inverted:hover,html.theme--documenter-dark .button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-danger.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-danger.is-outlined{background-color:transparent;border-color:#9e1b0d;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-outlined:hover,html.theme--documenter-dark .button.is-danger.is-outlined.is-hovered,html.theme--documenter-dark .button.is-danger.is-outlined:focus,html.theme--documenter-dark .button.is-danger.is-outlined.is-focused{background-color:#9e1b0d;border-color:#9e1b0d;color:#fff}html.theme--documenter-dark .button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #9e1b0d #9e1b0d !important}html.theme--documenter-dark .button.is-danger.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-danger.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-danger.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-danger.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger.is-outlined{background-color:transparent;border-color:#9e1b0d;box-shadow:none;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #9e1b0d #9e1b0d !important}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-danger.is-light{background-color:#fdeeec;color:#ec311d}html.theme--documenter-dark .button.is-danger.is-light:hover,html.theme--documenter-dark .button.is-danger.is-light.is-hovered{background-color:#fce3e0;border-color:transparent;color:#ec311d}html.theme--documenter-dark .button.is-danger.is-light:active,html.theme--documenter-dark .button.is-danger.is-light.is-active{background-color:#fcd8d5;border-color:transparent;color:#ec311d}html.theme--documenter-dark .button.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}html.theme--documenter-dark .button.is-small:not(.is-rounded),html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:3px}html.theme--documenter-dark .button.is-normal{font-size:1rem}html.theme--documenter-dark .button.is-medium{font-size:1.25rem}html.theme--documenter-dark .button.is-large{font-size:1.5rem}html.theme--documenter-dark .button[disabled],fieldset[disabled] html.theme--documenter-dark .button{background-color:#8c9b9d;border-color:#5e6d6f;box-shadow:none;opacity:.5}html.theme--documenter-dark .button.is-fullwidth{display:flex;width:100%}html.theme--documenter-dark .button.is-loading{color:transparent !important;pointer-events:none}html.theme--documenter-dark .button.is-loading::after{position:absolute;left:calc(50% - (1em * 0.5));top:calc(50% - (1em * 0.5));position:absolute !important}html.theme--documenter-dark .button.is-static{background-color:#282f2f;border-color:#5e6d6f;color:#dbdee0;box-shadow:none;pointer-events:none}html.theme--documenter-dark .button.is-rounded,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.button{border-radius:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}html.theme--documenter-dark .buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--documenter-dark .buttons .button{margin-bottom:0.5rem}html.theme--documenter-dark .buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}html.theme--documenter-dark .buttons:last-child{margin-bottom:-0.5rem}html.theme--documenter-dark .buttons:not(:last-child){margin-bottom:1rem}html.theme--documenter-dark .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}html.theme--documenter-dark .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:3px}html.theme--documenter-dark .buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}html.theme--documenter-dark .buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}html.theme--documenter-dark .buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}html.theme--documenter-dark .buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}html.theme--documenter-dark .buttons.has-addons .button:last-child{margin-right:0}html.theme--documenter-dark .buttons.has-addons .button:hover,html.theme--documenter-dark .buttons.has-addons .button.is-hovered{z-index:2}html.theme--documenter-dark .buttons.has-addons .button:focus,html.theme--documenter-dark .buttons.has-addons .button.is-focused,html.theme--documenter-dark .buttons.has-addons .button:active,html.theme--documenter-dark .buttons.has-addons .button.is-active,html.theme--documenter-dark .buttons.has-addons .button.is-selected{z-index:3}html.theme--documenter-dark .buttons.has-addons .button:focus:hover,html.theme--documenter-dark .buttons.has-addons .button.is-focused:hover,html.theme--documenter-dark .buttons.has-addons .button:active:hover,html.theme--documenter-dark .buttons.has-addons .button.is-active:hover,html.theme--documenter-dark .buttons.has-addons .button.is-selected:hover{z-index:4}html.theme--documenter-dark .buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .buttons.is-centered{justify-content:center}html.theme--documenter-dark .buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}html.theme--documenter-dark .buttons.is-right{justify-content:flex-end}html.theme--documenter-dark .buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}@media screen and (max-width: 768px){html.theme--documenter-dark .button.is-responsive.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}html.theme--documenter-dark .button.is-responsive,html.theme--documenter-dark .button.is-responsive.is-normal{font-size:.65625rem}html.theme--documenter-dark .button.is-responsive.is-medium{font-size:.75rem}html.theme--documenter-dark .button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .button.is-responsive.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}html.theme--documenter-dark .button.is-responsive,html.theme--documenter-dark .button.is-responsive.is-normal{font-size:.75rem}html.theme--documenter-dark .button.is-responsive.is-medium{font-size:1rem}html.theme--documenter-dark .button.is-responsive.is-large{font-size:1.25rem}}html.theme--documenter-dark .container{flex-grow:1;margin:0 auto;position:relative;width:auto}html.theme--documenter-dark .container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){html.theme--documenter-dark .container{max-width:992px}}@media screen and (max-width: 1215px){html.theme--documenter-dark .container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){html.theme--documenter-dark .container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){html.theme--documenter-dark .container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){html.theme--documenter-dark .container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}html.theme--documenter-dark .content li+li{margin-top:0.25em}html.theme--documenter-dark .content p:not(:last-child),html.theme--documenter-dark .content dl:not(:last-child),html.theme--documenter-dark .content ol:not(:last-child),html.theme--documenter-dark .content ul:not(:last-child),html.theme--documenter-dark .content blockquote:not(:last-child),html.theme--documenter-dark .content pre:not(:last-child),html.theme--documenter-dark .content table:not(:last-child){margin-bottom:1em}html.theme--documenter-dark .content h1,html.theme--documenter-dark .content h2,html.theme--documenter-dark .content h3,html.theme--documenter-dark .content h4,html.theme--documenter-dark .content h5,html.theme--documenter-dark .content h6{color:#f2f2f2;font-weight:600;line-height:1.125}html.theme--documenter-dark .content h1{font-size:2em;margin-bottom:0.5em}html.theme--documenter-dark .content h1:not(:first-child){margin-top:1em}html.theme--documenter-dark .content h2{font-size:1.75em;margin-bottom:0.5714em}html.theme--documenter-dark .content h2:not(:first-child){margin-top:1.1428em}html.theme--documenter-dark .content h3{font-size:1.5em;margin-bottom:0.6666em}html.theme--documenter-dark .content h3:not(:first-child){margin-top:1.3333em}html.theme--documenter-dark .content h4{font-size:1.25em;margin-bottom:0.8em}html.theme--documenter-dark .content h5{font-size:1.125em;margin-bottom:0.8888em}html.theme--documenter-dark .content h6{font-size:1em;margin-bottom:1em}html.theme--documenter-dark .content blockquote{background-color:#282f2f;border-left:5px solid #5e6d6f;padding:1.25em 1.5em}html.theme--documenter-dark .content ol{list-style-position:outside;margin-left:2em;margin-top:1em}html.theme--documenter-dark .content ol:not([type]){list-style-type:decimal}html.theme--documenter-dark .content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}html.theme--documenter-dark .content ol.is-lower-roman:not([type]){list-style-type:lower-roman}html.theme--documenter-dark .content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}html.theme--documenter-dark .content ol.is-upper-roman:not([type]){list-style-type:upper-roman}html.theme--documenter-dark .content ul{list-style:disc outside;margin-left:2em;margin-top:1em}html.theme--documenter-dark .content ul ul{list-style-type:circle;margin-top:0.5em}html.theme--documenter-dark .content ul ul ul{list-style-type:square}html.theme--documenter-dark .content dd{margin-left:2em}html.theme--documenter-dark .content figure{margin-left:2em;margin-right:2em;text-align:center}html.theme--documenter-dark .content figure:not(:first-child){margin-top:2em}html.theme--documenter-dark .content figure:not(:last-child){margin-bottom:2em}html.theme--documenter-dark .content figure img{display:inline-block}html.theme--documenter-dark .content figure figcaption{font-style:italic}html.theme--documenter-dark .content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}html.theme--documenter-dark .content sup,html.theme--documenter-dark .content sub{font-size:75%}html.theme--documenter-dark .content table{width:100%}html.theme--documenter-dark .content table td,html.theme--documenter-dark .content table th{border:1px solid #5e6d6f;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--documenter-dark .content table th{color:#f2f2f2}html.theme--documenter-dark .content table th:not([align]){text-align:inherit}html.theme--documenter-dark .content table thead td,html.theme--documenter-dark .content table thead th{border-width:0 0 2px;color:#f2f2f2}html.theme--documenter-dark .content table tfoot td,html.theme--documenter-dark .content table tfoot th{border-width:2px 0 0;color:#f2f2f2}html.theme--documenter-dark .content table tbody tr:last-child td,html.theme--documenter-dark .content table tbody tr:last-child th{border-bottom-width:0}html.theme--documenter-dark .content .tabs li+li{margin-top:0}html.theme--documenter-dark .content.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.content{font-size:.75rem}html.theme--documenter-dark .content.is-normal{font-size:1rem}html.theme--documenter-dark .content.is-medium{font-size:1.25rem}html.theme--documenter-dark .content.is-large{font-size:1.5rem}html.theme--documenter-dark .icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}html.theme--documenter-dark .icon.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}html.theme--documenter-dark .icon.is-medium{height:2rem;width:2rem}html.theme--documenter-dark .icon.is-large{height:3rem;width:3rem}html.theme--documenter-dark .icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}html.theme--documenter-dark .icon-text .icon{flex-grow:0;flex-shrink:0}html.theme--documenter-dark .icon-text .icon:not(:last-child){margin-right:.25em}html.theme--documenter-dark .icon-text .icon:not(:first-child){margin-left:.25em}html.theme--documenter-dark div.icon-text{display:flex}html.theme--documenter-dark .image,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img{display:block;position:relative}html.theme--documenter-dark .image img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}html.theme--documenter-dark .image img.is-rounded,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:9999px}html.theme--documenter-dark .image.is-fullwidth,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}html.theme--documenter-dark .image.is-square img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--documenter-dark .image.is-square .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--documenter-dark .image.is-1by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--documenter-dark .image.is-1by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--documenter-dark .image.is-5by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--documenter-dark .image.is-5by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--documenter-dark .image.is-4by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--documenter-dark .image.is-4by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--documenter-dark .image.is-3by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--documenter-dark .image.is-3by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--documenter-dark .image.is-5by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--documenter-dark .image.is-5by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--documenter-dark .image.is-16by9 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--documenter-dark .image.is-16by9 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--documenter-dark .image.is-2by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--documenter-dark .image.is-2by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--documenter-dark .image.is-3by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--documenter-dark .image.is-3by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--documenter-dark .image.is-4by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--documenter-dark .image.is-4by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--documenter-dark .image.is-3by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--documenter-dark .image.is-3by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--documenter-dark .image.is-2by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--documenter-dark .image.is-2by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--documenter-dark .image.is-3by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--documenter-dark .image.is-3by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--documenter-dark .image.is-9by16 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--documenter-dark .image.is-9by16 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--documenter-dark .image.is-1by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--documenter-dark .image.is-1by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--documenter-dark .image.is-1by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--documenter-dark .image.is-1by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}html.theme--documenter-dark .image.is-square,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square,html.theme--documenter-dark .image.is-1by1,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}html.theme--documenter-dark .image.is-5by4,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}html.theme--documenter-dark .image.is-4by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}html.theme--documenter-dark .image.is-3by2,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}html.theme--documenter-dark .image.is-5by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}html.theme--documenter-dark .image.is-16by9,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}html.theme--documenter-dark .image.is-2by1,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}html.theme--documenter-dark .image.is-3by1,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}html.theme--documenter-dark .image.is-4by5,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}html.theme--documenter-dark .image.is-3by4,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}html.theme--documenter-dark .image.is-2by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}html.theme--documenter-dark .image.is-3by5,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}html.theme--documenter-dark .image.is-9by16,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}html.theme--documenter-dark .image.is-1by2,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}html.theme--documenter-dark .image.is-1by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}html.theme--documenter-dark .image.is-16x16,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}html.theme--documenter-dark .image.is-24x24,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}html.theme--documenter-dark .image.is-32x32,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}html.theme--documenter-dark .image.is-48x48,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}html.theme--documenter-dark .image.is-64x64,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}html.theme--documenter-dark .image.is-96x96,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}html.theme--documenter-dark .image.is-128x128,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}html.theme--documenter-dark .notification{background-color:#282f2f;border-radius:.4em;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}html.theme--documenter-dark .notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--documenter-dark .notification strong{color:currentColor}html.theme--documenter-dark .notification code,html.theme--documenter-dark .notification pre{background:#fff}html.theme--documenter-dark .notification pre code{background:transparent}html.theme--documenter-dark .notification>.delete{right:.5rem;position:absolute;top:0.5rem}html.theme--documenter-dark .notification .title,html.theme--documenter-dark .notification .subtitle,html.theme--documenter-dark .notification .content{color:currentColor}html.theme--documenter-dark .notification.is-white{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .notification.is-black{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .notification.is-light{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .notification.is-dark,html.theme--documenter-dark .content kbd.notification{background-color:#282f2f;color:#fff}html.theme--documenter-dark .notification.is-primary,html.theme--documenter-dark .docstring>section>a.notification.docs-sourcelink{background-color:#375a7f;color:#fff}html.theme--documenter-dark .notification.is-primary.is-light,html.theme--documenter-dark .docstring>section>a.notification.is-light.docs-sourcelink{background-color:#f1f5f9;color:#4d7eb2}html.theme--documenter-dark .notification.is-link{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .notification.is-link.is-light{background-color:#edfdf9;color:#15987e}html.theme--documenter-dark .notification.is-info{background-color:#024c7d;color:#fff}html.theme--documenter-dark .notification.is-info.is-light{background-color:#ebf7ff;color:#0e9dfb}html.theme--documenter-dark .notification.is-success{background-color:#008438;color:#fff}html.theme--documenter-dark .notification.is-success.is-light{background-color:#ebfff3;color:#00eb64}html.theme--documenter-dark .notification.is-warning{background-color:#ad8100;color:#fff}html.theme--documenter-dark .notification.is-warning.is-light{background-color:#fffaeb;color:#d19c00}html.theme--documenter-dark .notification.is-danger{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .notification.is-danger.is-light{background-color:#fdeeec;color:#ec311d}html.theme--documenter-dark .progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}html.theme--documenter-dark .progress::-webkit-progress-bar{background-color:#343c3d}html.theme--documenter-dark .progress::-webkit-progress-value{background-color:#dbdee0}html.theme--documenter-dark .progress::-moz-progress-bar{background-color:#dbdee0}html.theme--documenter-dark .progress::-ms-fill{background-color:#dbdee0;border:none}html.theme--documenter-dark .progress.is-white::-webkit-progress-value{background-color:#fff}html.theme--documenter-dark .progress.is-white::-moz-progress-bar{background-color:#fff}html.theme--documenter-dark .progress.is-white::-ms-fill{background-color:#fff}html.theme--documenter-dark .progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-black::-webkit-progress-value{background-color:#0a0a0a}html.theme--documenter-dark .progress.is-black::-moz-progress-bar{background-color:#0a0a0a}html.theme--documenter-dark .progress.is-black::-ms-fill{background-color:#0a0a0a}html.theme--documenter-dark .progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-light::-webkit-progress-value{background-color:#ecf0f1}html.theme--documenter-dark .progress.is-light::-moz-progress-bar{background-color:#ecf0f1}html.theme--documenter-dark .progress.is-light::-ms-fill{background-color:#ecf0f1}html.theme--documenter-dark .progress.is-light:indeterminate{background-image:linear-gradient(to right, #ecf0f1 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-dark::-webkit-progress-value,html.theme--documenter-dark .content kbd.progress::-webkit-progress-value{background-color:#282f2f}html.theme--documenter-dark .progress.is-dark::-moz-progress-bar,html.theme--documenter-dark .content kbd.progress::-moz-progress-bar{background-color:#282f2f}html.theme--documenter-dark .progress.is-dark::-ms-fill,html.theme--documenter-dark .content kbd.progress::-ms-fill{background-color:#282f2f}html.theme--documenter-dark .progress.is-dark:indeterminate,html.theme--documenter-dark .content kbd.progress:indeterminate{background-image:linear-gradient(to right, #282f2f 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-primary::-webkit-progress-value,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#375a7f}html.theme--documenter-dark .progress.is-primary::-moz-progress-bar,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#375a7f}html.theme--documenter-dark .progress.is-primary::-ms-fill,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#375a7f}html.theme--documenter-dark .progress.is-primary:indeterminate,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #375a7f 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-link::-webkit-progress-value{background-color:#1abc9c}html.theme--documenter-dark .progress.is-link::-moz-progress-bar{background-color:#1abc9c}html.theme--documenter-dark .progress.is-link::-ms-fill{background-color:#1abc9c}html.theme--documenter-dark .progress.is-link:indeterminate{background-image:linear-gradient(to right, #1abc9c 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-info::-webkit-progress-value{background-color:#024c7d}html.theme--documenter-dark .progress.is-info::-moz-progress-bar{background-color:#024c7d}html.theme--documenter-dark .progress.is-info::-ms-fill{background-color:#024c7d}html.theme--documenter-dark .progress.is-info:indeterminate{background-image:linear-gradient(to right, #024c7d 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-success::-webkit-progress-value{background-color:#008438}html.theme--documenter-dark .progress.is-success::-moz-progress-bar{background-color:#008438}html.theme--documenter-dark .progress.is-success::-ms-fill{background-color:#008438}html.theme--documenter-dark .progress.is-success:indeterminate{background-image:linear-gradient(to right, #008438 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-warning::-webkit-progress-value{background-color:#ad8100}html.theme--documenter-dark .progress.is-warning::-moz-progress-bar{background-color:#ad8100}html.theme--documenter-dark .progress.is-warning::-ms-fill{background-color:#ad8100}html.theme--documenter-dark .progress.is-warning:indeterminate{background-image:linear-gradient(to right, #ad8100 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-danger::-webkit-progress-value{background-color:#9e1b0d}html.theme--documenter-dark .progress.is-danger::-moz-progress-bar{background-color:#9e1b0d}html.theme--documenter-dark .progress.is-danger::-ms-fill{background-color:#9e1b0d}html.theme--documenter-dark .progress.is-danger:indeterminate{background-image:linear-gradient(to right, #9e1b0d 30%, #343c3d 30%)}html.theme--documenter-dark .progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#343c3d;background-image:linear-gradient(to right, #fff 30%, #343c3d 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}html.theme--documenter-dark .progress:indeterminate::-webkit-progress-bar{background-color:transparent}html.theme--documenter-dark .progress:indeterminate::-moz-progress-bar{background-color:transparent}html.theme--documenter-dark .progress:indeterminate::-ms-fill{animation-name:none}html.theme--documenter-dark .progress.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}html.theme--documenter-dark .progress.is-medium{height:1.25rem}html.theme--documenter-dark .progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}html.theme--documenter-dark .table{background-color:#343c3d;color:#fff}html.theme--documenter-dark .table td,html.theme--documenter-dark .table th{border:1px solid #5e6d6f;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--documenter-dark .table td.is-white,html.theme--documenter-dark .table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--documenter-dark .table td.is-black,html.theme--documenter-dark .table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--documenter-dark .table td.is-light,html.theme--documenter-dark .table th.is-light{background-color:#ecf0f1;border-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .table td.is-dark,html.theme--documenter-dark .table th.is-dark{background-color:#282f2f;border-color:#282f2f;color:#fff}html.theme--documenter-dark .table td.is-primary,html.theme--documenter-dark .table th.is-primary{background-color:#375a7f;border-color:#375a7f;color:#fff}html.theme--documenter-dark .table td.is-link,html.theme--documenter-dark .table th.is-link{background-color:#1abc9c;border-color:#1abc9c;color:#fff}html.theme--documenter-dark .table td.is-info,html.theme--documenter-dark .table th.is-info{background-color:#024c7d;border-color:#024c7d;color:#fff}html.theme--documenter-dark .table td.is-success,html.theme--documenter-dark .table th.is-success{background-color:#008438;border-color:#008438;color:#fff}html.theme--documenter-dark .table td.is-warning,html.theme--documenter-dark .table th.is-warning{background-color:#ad8100;border-color:#ad8100;color:#fff}html.theme--documenter-dark .table td.is-danger,html.theme--documenter-dark .table th.is-danger{background-color:#9e1b0d;border-color:#9e1b0d;color:#fff}html.theme--documenter-dark .table td.is-narrow,html.theme--documenter-dark .table th.is-narrow{white-space:nowrap;width:1%}html.theme--documenter-dark .table td.is-selected,html.theme--documenter-dark .table th.is-selected{background-color:#375a7f;color:#fff}html.theme--documenter-dark .table td.is-selected a,html.theme--documenter-dark .table td.is-selected strong,html.theme--documenter-dark .table th.is-selected a,html.theme--documenter-dark .table th.is-selected strong{color:currentColor}html.theme--documenter-dark .table td.is-vcentered,html.theme--documenter-dark .table th.is-vcentered{vertical-align:middle}html.theme--documenter-dark .table th{color:#f2f2f2}html.theme--documenter-dark .table th:not([align]){text-align:left}html.theme--documenter-dark .table tr.is-selected{background-color:#375a7f;color:#fff}html.theme--documenter-dark .table tr.is-selected a,html.theme--documenter-dark .table tr.is-selected strong{color:currentColor}html.theme--documenter-dark .table tr.is-selected td,html.theme--documenter-dark .table tr.is-selected th{border-color:#fff;color:currentColor}html.theme--documenter-dark .table thead{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .table thead td,html.theme--documenter-dark .table thead th{border-width:0 0 2px;color:#f2f2f2}html.theme--documenter-dark .table tfoot{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .table tfoot td,html.theme--documenter-dark .table tfoot th{border-width:2px 0 0;color:#f2f2f2}html.theme--documenter-dark .table tbody{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .table tbody tr:last-child td,html.theme--documenter-dark .table tbody tr:last-child th{border-bottom-width:0}html.theme--documenter-dark .table.is-bordered td,html.theme--documenter-dark .table.is-bordered th{border-width:1px}html.theme--documenter-dark .table.is-bordered tr:last-child td,html.theme--documenter-dark .table.is-bordered tr:last-child th{border-bottom-width:1px}html.theme--documenter-dark .table.is-fullwidth{width:100%}html.theme--documenter-dark .table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#282f2f}html.theme--documenter-dark .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#282f2f}html.theme--documenter-dark .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#2d3435}html.theme--documenter-dark .table.is-narrow td,html.theme--documenter-dark .table.is-narrow th{padding:0.25em 0.5em}html.theme--documenter-dark .table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#282f2f}html.theme--documenter-dark .table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}html.theme--documenter-dark .tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--documenter-dark .tags .tag,html.theme--documenter-dark .tags .content kbd,html.theme--documenter-dark .content .tags kbd,html.theme--documenter-dark .tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}html.theme--documenter-dark .tags .tag:not(:last-child),html.theme--documenter-dark .tags .content kbd:not(:last-child),html.theme--documenter-dark .content .tags kbd:not(:last-child),html.theme--documenter-dark .tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:.5rem}html.theme--documenter-dark .tags:last-child{margin-bottom:-0.5rem}html.theme--documenter-dark .tags:not(:last-child){margin-bottom:1rem}html.theme--documenter-dark .tags.are-medium .tag:not(.is-normal):not(.is-large),html.theme--documenter-dark .tags.are-medium .content kbd:not(.is-normal):not(.is-large),html.theme--documenter-dark .content .tags.are-medium kbd:not(.is-normal):not(.is-large),html.theme--documenter-dark .tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:1rem}html.theme--documenter-dark .tags.are-large .tag:not(.is-normal):not(.is-medium),html.theme--documenter-dark .tags.are-large .content kbd:not(.is-normal):not(.is-medium),html.theme--documenter-dark .content .tags.are-large kbd:not(.is-normal):not(.is-medium),html.theme--documenter-dark .tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}html.theme--documenter-dark .tags.is-centered{justify-content:center}html.theme--documenter-dark .tags.is-centered .tag,html.theme--documenter-dark .tags.is-centered .content kbd,html.theme--documenter-dark .content .tags.is-centered kbd,html.theme--documenter-dark .tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}html.theme--documenter-dark .tags.is-right{justify-content:flex-end}html.theme--documenter-dark .tags.is-right .tag:not(:first-child),html.theme--documenter-dark .tags.is-right .content kbd:not(:first-child),html.theme--documenter-dark .content .tags.is-right kbd:not(:first-child),html.theme--documenter-dark .tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}html.theme--documenter-dark .tags.is-right .tag:not(:last-child),html.theme--documenter-dark .tags.is-right .content kbd:not(:last-child),html.theme--documenter-dark .content .tags.is-right kbd:not(:last-child),html.theme--documenter-dark .tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}html.theme--documenter-dark .tags.has-addons .tag,html.theme--documenter-dark .tags.has-addons .content kbd,html.theme--documenter-dark .content .tags.has-addons kbd,html.theme--documenter-dark .tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}html.theme--documenter-dark .tags.has-addons .tag:not(:first-child),html.theme--documenter-dark .tags.has-addons .content kbd:not(:first-child),html.theme--documenter-dark .content .tags.has-addons kbd:not(:first-child),html.theme--documenter-dark .tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}html.theme--documenter-dark .tags.has-addons .tag:not(:last-child),html.theme--documenter-dark .tags.has-addons .content kbd:not(:last-child),html.theme--documenter-dark .content .tags.has-addons kbd:not(:last-child),html.theme--documenter-dark .tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}html.theme--documenter-dark .tag:not(body),html.theme--documenter-dark .content kbd:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#282f2f;border-radius:.4em;color:#fff;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:0.75em;padding-right:0.75em;white-space:nowrap}html.theme--documenter-dark .tag:not(body) .delete,html.theme--documenter-dark .content kbd:not(body) .delete,html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}html.theme--documenter-dark .tag.is-white:not(body),html.theme--documenter-dark .content kbd.is-white:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .tag.is-black:not(body),html.theme--documenter-dark .content kbd.is-black:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .tag.is-light:not(body),html.theme--documenter-dark .content kbd.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .tag.is-dark:not(body),html.theme--documenter-dark .content kbd:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-dark:not(body),html.theme--documenter-dark .content .docstring>section>kbd:not(body){background-color:#282f2f;color:#fff}html.theme--documenter-dark .tag.is-primary:not(body),html.theme--documenter-dark .content kbd.is-primary:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body){background-color:#375a7f;color:#fff}html.theme--documenter-dark .tag.is-primary.is-light:not(body),html.theme--documenter-dark .content kbd.is-primary.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f1f5f9;color:#4d7eb2}html.theme--documenter-dark .tag.is-link:not(body),html.theme--documenter-dark .content kbd.is-link:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#1abc9c;color:#fff}html.theme--documenter-dark .tag.is-link.is-light:not(body),html.theme--documenter-dark .content kbd.is-link.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#edfdf9;color:#15987e}html.theme--documenter-dark .tag.is-info:not(body),html.theme--documenter-dark .content kbd.is-info:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#024c7d;color:#fff}html.theme--documenter-dark .tag.is-info.is-light:not(body),html.theme--documenter-dark .content kbd.is-info.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#ebf7ff;color:#0e9dfb}html.theme--documenter-dark .tag.is-success:not(body),html.theme--documenter-dark .content kbd.is-success:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#008438;color:#fff}html.theme--documenter-dark .tag.is-success.is-light:not(body),html.theme--documenter-dark .content kbd.is-success.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#ebfff3;color:#00eb64}html.theme--documenter-dark .tag.is-warning:not(body),html.theme--documenter-dark .content kbd.is-warning:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#ad8100;color:#fff}html.theme--documenter-dark .tag.is-warning.is-light:not(body),html.theme--documenter-dark .content kbd.is-warning.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fffaeb;color:#d19c00}html.theme--documenter-dark .tag.is-danger:not(body),html.theme--documenter-dark .content kbd.is-danger:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .tag.is-danger.is-light:not(body),html.theme--documenter-dark .content kbd.is-danger.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#fdeeec;color:#ec311d}html.theme--documenter-dark .tag.is-normal:not(body),html.theme--documenter-dark .content kbd.is-normal:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.75rem}html.theme--documenter-dark .tag.is-medium:not(body),html.theme--documenter-dark .content kbd.is-medium:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:1rem}html.theme--documenter-dark .tag.is-large:not(body),html.theme--documenter-dark .content kbd.is-large:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}html.theme--documenter-dark .tag:not(body) .icon:first-child:not(:last-child),html.theme--documenter-dark .content kbd:not(body) .icon:first-child:not(:last-child),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}html.theme--documenter-dark .tag:not(body) .icon:last-child:not(:first-child),html.theme--documenter-dark .content kbd:not(body) .icon:last-child:not(:first-child),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}html.theme--documenter-dark .tag:not(body) .icon:first-child:last-child,html.theme--documenter-dark .content kbd:not(body) .icon:first-child:last-child,html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}html.theme--documenter-dark .tag.is-delete:not(body),html.theme--documenter-dark .content kbd.is-delete:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}html.theme--documenter-dark .tag.is-delete:not(body)::before,html.theme--documenter-dark .content kbd.is-delete:not(body)::before,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::before,html.theme--documenter-dark .tag.is-delete:not(body)::after,html.theme--documenter-dark .content kbd.is-delete:not(body)::after,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--documenter-dark .tag.is-delete:not(body)::before,html.theme--documenter-dark .content kbd.is-delete:not(body)::before,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}html.theme--documenter-dark .tag.is-delete:not(body)::after,html.theme--documenter-dark .content kbd.is-delete:not(body)::after,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}html.theme--documenter-dark .tag.is-delete:not(body):hover,html.theme--documenter-dark .content kbd.is-delete:not(body):hover,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body):hover,html.theme--documenter-dark .tag.is-delete:not(body):focus,html.theme--documenter-dark .content kbd.is-delete:not(body):focus,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#1d2122}html.theme--documenter-dark .tag.is-delete:not(body):active,html.theme--documenter-dark .content kbd.is-delete:not(body):active,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#111414}html.theme--documenter-dark .tag.is-rounded:not(body),html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:not(body),html.theme--documenter-dark .content kbd.is-rounded:not(body),html.theme--documenter-dark #documenter .docs-sidebar .content form.docs-search>input:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:9999px}html.theme--documenter-dark a.tag:hover,html.theme--documenter-dark .docstring>section>a.docs-sourcelink:hover{text-decoration:underline}html.theme--documenter-dark .title,html.theme--documenter-dark .subtitle{word-break:break-word}html.theme--documenter-dark .title em,html.theme--documenter-dark .title span,html.theme--documenter-dark .subtitle em,html.theme--documenter-dark .subtitle span{font-weight:inherit}html.theme--documenter-dark .title sub,html.theme--documenter-dark .subtitle sub{font-size:.75em}html.theme--documenter-dark .title sup,html.theme--documenter-dark .subtitle sup{font-size:.75em}html.theme--documenter-dark .title .tag,html.theme--documenter-dark .title .content kbd,html.theme--documenter-dark .content .title kbd,html.theme--documenter-dark .title .docstring>section>a.docs-sourcelink,html.theme--documenter-dark .subtitle .tag,html.theme--documenter-dark .subtitle .content kbd,html.theme--documenter-dark .content .subtitle kbd,html.theme--documenter-dark .subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}html.theme--documenter-dark .title{color:#fff;font-size:2rem;font-weight:500;line-height:1.125}html.theme--documenter-dark .title strong{color:inherit;font-weight:inherit}html.theme--documenter-dark .title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}html.theme--documenter-dark .title.is-1{font-size:3rem}html.theme--documenter-dark .title.is-2{font-size:2.5rem}html.theme--documenter-dark .title.is-3{font-size:2rem}html.theme--documenter-dark .title.is-4{font-size:1.5rem}html.theme--documenter-dark .title.is-5{font-size:1.25rem}html.theme--documenter-dark .title.is-6{font-size:1rem}html.theme--documenter-dark .title.is-7{font-size:.75rem}html.theme--documenter-dark .subtitle{color:#8c9b9d;font-size:1.25rem;font-weight:400;line-height:1.25}html.theme--documenter-dark .subtitle strong{color:#8c9b9d;font-weight:600}html.theme--documenter-dark .subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}html.theme--documenter-dark .subtitle.is-1{font-size:3rem}html.theme--documenter-dark .subtitle.is-2{font-size:2.5rem}html.theme--documenter-dark .subtitle.is-3{font-size:2rem}html.theme--documenter-dark .subtitle.is-4{font-size:1.5rem}html.theme--documenter-dark .subtitle.is-5{font-size:1.25rem}html.theme--documenter-dark .subtitle.is-6{font-size:1rem}html.theme--documenter-dark .subtitle.is-7{font-size:.75rem}html.theme--documenter-dark .heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}html.theme--documenter-dark .number{align-items:center;background-color:#282f2f;border-radius:9999px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:0.25rem 0.5rem;text-align:center;vertical-align:top}html.theme--documenter-dark .select select,html.theme--documenter-dark .textarea,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{background-color:#1f2424;border-color:#5e6d6f;border-radius:.4em;color:#dbdee0}html.theme--documenter-dark .select select::-moz-placeholder,html.theme--documenter-dark .textarea::-moz-placeholder,html.theme--documenter-dark .input::-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:#868c98}html.theme--documenter-dark .select select::-webkit-input-placeholder,html.theme--documenter-dark .textarea::-webkit-input-placeholder,html.theme--documenter-dark .input::-webkit-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:#868c98}html.theme--documenter-dark .select select:-moz-placeholder,html.theme--documenter-dark .textarea:-moz-placeholder,html.theme--documenter-dark .input:-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:#868c98}html.theme--documenter-dark .select select:-ms-input-placeholder,html.theme--documenter-dark .textarea:-ms-input-placeholder,html.theme--documenter-dark .input:-ms-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:#868c98}html.theme--documenter-dark .select select:hover,html.theme--documenter-dark .textarea:hover,html.theme--documenter-dark .input:hover,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:hover,html.theme--documenter-dark .select select.is-hovered,html.theme--documenter-dark .is-hovered.textarea,html.theme--documenter-dark .is-hovered.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#8c9b9d}html.theme--documenter-dark .select select:focus,html.theme--documenter-dark .textarea:focus,html.theme--documenter-dark .input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:focus,html.theme--documenter-dark .select select.is-focused,html.theme--documenter-dark .is-focused.textarea,html.theme--documenter-dark .is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .select select:active,html.theme--documenter-dark .textarea:active,html.theme--documenter-dark .input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:active,html.theme--documenter-dark .select select.is-active,html.theme--documenter-dark .is-active.textarea,html.theme--documenter-dark .is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{border-color:#1abc9c;box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .select select[disabled],html.theme--documenter-dark .textarea[disabled],html.theme--documenter-dark .input[disabled],html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] html.theme--documenter-dark .select select,fieldset[disabled] html.theme--documenter-dark .textarea,fieldset[disabled] html.theme--documenter-dark .input,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{background-color:#8c9b9d;border-color:#282f2f;box-shadow:none;color:#fff}html.theme--documenter-dark .select select[disabled]::-moz-placeholder,html.theme--documenter-dark .textarea[disabled]::-moz-placeholder,html.theme--documenter-dark .input[disabled]::-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .select select::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .input::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .select select[disabled]::-webkit-input-placeholder,html.theme--documenter-dark .textarea[disabled]::-webkit-input-placeholder,html.theme--documenter-dark .input[disabled]::-webkit-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark .select select::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark .input::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .select select[disabled]:-moz-placeholder,html.theme--documenter-dark .textarea[disabled]:-moz-placeholder,html.theme--documenter-dark .input[disabled]:-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .select select:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .input:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .select select[disabled]:-ms-input-placeholder,html.theme--documenter-dark .textarea[disabled]:-ms-input-placeholder,html.theme--documenter-dark .input[disabled]:-ms-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark .select select:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark .input:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .textarea,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{box-shadow:inset 0 0.0625em 0.125em rgba(10,10,10,0.05);max-width:100%;width:100%}html.theme--documenter-dark .textarea[readonly],html.theme--documenter-dark .input[readonly],html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}html.theme--documenter-dark .is-white.textarea,html.theme--documenter-dark .is-white.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}html.theme--documenter-dark .is-white.textarea:focus,html.theme--documenter-dark .is-white.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-white:focus,html.theme--documenter-dark .is-white.is-focused.textarea,html.theme--documenter-dark .is-white.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-white.textarea:active,html.theme--documenter-dark .is-white.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-white:active,html.theme--documenter-dark .is-white.is-active.textarea,html.theme--documenter-dark .is-white.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--documenter-dark .is-black.textarea,html.theme--documenter-dark .is-black.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}html.theme--documenter-dark .is-black.textarea:focus,html.theme--documenter-dark .is-black.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-black:focus,html.theme--documenter-dark .is-black.is-focused.textarea,html.theme--documenter-dark .is-black.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-black.textarea:active,html.theme--documenter-dark .is-black.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-black:active,html.theme--documenter-dark .is-black.is-active.textarea,html.theme--documenter-dark .is-black.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--documenter-dark .is-light.textarea,html.theme--documenter-dark .is-light.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-light{border-color:#ecf0f1}html.theme--documenter-dark .is-light.textarea:focus,html.theme--documenter-dark .is-light.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-light:focus,html.theme--documenter-dark .is-light.is-focused.textarea,html.theme--documenter-dark .is-light.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-light.textarea:active,html.theme--documenter-dark .is-light.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-light:active,html.theme--documenter-dark .is-light.is-active.textarea,html.theme--documenter-dark .is-light.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(236,240,241,0.25)}html.theme--documenter-dark .is-dark.textarea,html.theme--documenter-dark .content kbd.textarea,html.theme--documenter-dark .is-dark.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-dark,html.theme--documenter-dark .content kbd.input{border-color:#282f2f}html.theme--documenter-dark .is-dark.textarea:focus,html.theme--documenter-dark .content kbd.textarea:focus,html.theme--documenter-dark .is-dark.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-dark:focus,html.theme--documenter-dark .content kbd.input:focus,html.theme--documenter-dark .is-dark.is-focused.textarea,html.theme--documenter-dark .content kbd.is-focused.textarea,html.theme--documenter-dark .is-dark.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .content kbd.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar .content form.docs-search>input.is-focused,html.theme--documenter-dark .is-dark.textarea:active,html.theme--documenter-dark .content kbd.textarea:active,html.theme--documenter-dark .is-dark.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-dark:active,html.theme--documenter-dark .content kbd.input:active,html.theme--documenter-dark .is-dark.is-active.textarea,html.theme--documenter-dark .content kbd.is-active.textarea,html.theme--documenter-dark .is-dark.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--documenter-dark .content kbd.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(40,47,47,0.25)}html.theme--documenter-dark .is-primary.textarea,html.theme--documenter-dark .docstring>section>a.textarea.docs-sourcelink,html.theme--documenter-dark .is-primary.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-primary,html.theme--documenter-dark .docstring>section>a.input.docs-sourcelink{border-color:#375a7f}html.theme--documenter-dark .is-primary.textarea:focus,html.theme--documenter-dark .docstring>section>a.textarea.docs-sourcelink:focus,html.theme--documenter-dark .is-primary.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-primary:focus,html.theme--documenter-dark .docstring>section>a.input.docs-sourcelink:focus,html.theme--documenter-dark .is-primary.is-focused.textarea,html.theme--documenter-dark .docstring>section>a.is-focused.textarea.docs-sourcelink,html.theme--documenter-dark .is-primary.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .docstring>section>a.is-focused.input.docs-sourcelink,html.theme--documenter-dark .is-primary.textarea:active,html.theme--documenter-dark .docstring>section>a.textarea.docs-sourcelink:active,html.theme--documenter-dark .is-primary.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-primary:active,html.theme--documenter-dark .docstring>section>a.input.docs-sourcelink:active,html.theme--documenter-dark .is-primary.is-active.textarea,html.theme--documenter-dark .docstring>section>a.is-active.textarea.docs-sourcelink,html.theme--documenter-dark .is-primary.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--documenter-dark .docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(55,90,127,0.25)}html.theme--documenter-dark .is-link.textarea,html.theme--documenter-dark .is-link.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-link{border-color:#1abc9c}html.theme--documenter-dark .is-link.textarea:focus,html.theme--documenter-dark .is-link.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-link:focus,html.theme--documenter-dark .is-link.is-focused.textarea,html.theme--documenter-dark .is-link.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-link.textarea:active,html.theme--documenter-dark .is-link.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-link:active,html.theme--documenter-dark .is-link.is-active.textarea,html.theme--documenter-dark .is-link.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .is-info.textarea,html.theme--documenter-dark .is-info.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-info{border-color:#024c7d}html.theme--documenter-dark .is-info.textarea:focus,html.theme--documenter-dark .is-info.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-info:focus,html.theme--documenter-dark .is-info.is-focused.textarea,html.theme--documenter-dark .is-info.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-info.textarea:active,html.theme--documenter-dark .is-info.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-info:active,html.theme--documenter-dark .is-info.is-active.textarea,html.theme--documenter-dark .is-info.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(2,76,125,0.25)}html.theme--documenter-dark .is-success.textarea,html.theme--documenter-dark .is-success.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-success{border-color:#008438}html.theme--documenter-dark .is-success.textarea:focus,html.theme--documenter-dark .is-success.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-success:focus,html.theme--documenter-dark .is-success.is-focused.textarea,html.theme--documenter-dark .is-success.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-success.textarea:active,html.theme--documenter-dark .is-success.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-success:active,html.theme--documenter-dark .is-success.is-active.textarea,html.theme--documenter-dark .is-success.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(0,132,56,0.25)}html.theme--documenter-dark .is-warning.textarea,html.theme--documenter-dark .is-warning.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#ad8100}html.theme--documenter-dark .is-warning.textarea:focus,html.theme--documenter-dark .is-warning.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-warning:focus,html.theme--documenter-dark .is-warning.is-focused.textarea,html.theme--documenter-dark .is-warning.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-warning.textarea:active,html.theme--documenter-dark .is-warning.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-warning:active,html.theme--documenter-dark .is-warning.is-active.textarea,html.theme--documenter-dark .is-warning.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(173,129,0,0.25)}html.theme--documenter-dark .is-danger.textarea,html.theme--documenter-dark .is-danger.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#9e1b0d}html.theme--documenter-dark .is-danger.textarea:focus,html.theme--documenter-dark .is-danger.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-danger:focus,html.theme--documenter-dark .is-danger.is-focused.textarea,html.theme--documenter-dark .is-danger.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-danger.textarea:active,html.theme--documenter-dark .is-danger.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-danger:active,html.theme--documenter-dark .is-danger.is-active.textarea,html.theme--documenter-dark .is-danger.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(158,27,13,0.25)}html.theme--documenter-dark .is-small.textarea,html.theme--documenter-dark .is-small.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{border-radius:3px;font-size:.75rem}html.theme--documenter-dark .is-medium.textarea,html.theme--documenter-dark .is-medium.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}html.theme--documenter-dark .is-large.textarea,html.theme--documenter-dark .is-large.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}html.theme--documenter-dark .is-fullwidth.textarea,html.theme--documenter-dark .is-fullwidth.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}html.theme--documenter-dark .is-inline.textarea,html.theme--documenter-dark .is-inline.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}html.theme--documenter-dark .input.is-rounded,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{border-radius:9999px;padding-left:calc(calc(0.75em - 1px) + 0.375em);padding-right:calc(calc(0.75em - 1px) + 0.375em)}html.theme--documenter-dark .input.is-static,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}html.theme--documenter-dark .textarea{display:block;max-width:100%;min-width:100%;padding:calc(0.75em - 1px);resize:vertical}html.theme--documenter-dark .textarea:not([rows]){max-height:40em;min-height:8em}html.theme--documenter-dark .textarea[rows]{height:initial}html.theme--documenter-dark .textarea.has-fixed-size{resize:none}html.theme--documenter-dark .radio,html.theme--documenter-dark .checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}html.theme--documenter-dark .radio input,html.theme--documenter-dark .checkbox input{cursor:pointer}html.theme--documenter-dark .radio:hover,html.theme--documenter-dark .checkbox:hover{color:#8c9b9d}html.theme--documenter-dark .radio[disabled],html.theme--documenter-dark .checkbox[disabled],fieldset[disabled] html.theme--documenter-dark .radio,fieldset[disabled] html.theme--documenter-dark .checkbox,html.theme--documenter-dark .radio input[disabled],html.theme--documenter-dark .checkbox input[disabled]{color:#fff;cursor:not-allowed}html.theme--documenter-dark .radio+.radio{margin-left:.5em}html.theme--documenter-dark .select{display:inline-block;max-width:100%;position:relative;vertical-align:top}html.theme--documenter-dark .select:not(.is-multiple){height:2.5em}html.theme--documenter-dark .select:not(.is-multiple):not(.is-loading)::after{border-color:#1abc9c;right:1.125em;z-index:4}html.theme--documenter-dark .select.is-rounded select,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.select select{border-radius:9999px;padding-left:1em}html.theme--documenter-dark .select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}html.theme--documenter-dark .select select::-ms-expand{display:none}html.theme--documenter-dark .select select[disabled]:hover,fieldset[disabled] html.theme--documenter-dark .select select:hover{border-color:#282f2f}html.theme--documenter-dark .select select:not([multiple]){padding-right:2.5em}html.theme--documenter-dark .select select[multiple]{height:auto;padding:0}html.theme--documenter-dark .select select[multiple] option{padding:0.5em 1em}html.theme--documenter-dark .select:not(.is-multiple):not(.is-loading):hover::after{border-color:#8c9b9d}html.theme--documenter-dark .select.is-white:not(:hover)::after{border-color:#fff}html.theme--documenter-dark .select.is-white select{border-color:#fff}html.theme--documenter-dark .select.is-white select:hover,html.theme--documenter-dark .select.is-white select.is-hovered{border-color:#f2f2f2}html.theme--documenter-dark .select.is-white select:focus,html.theme--documenter-dark .select.is-white select.is-focused,html.theme--documenter-dark .select.is-white select:active,html.theme--documenter-dark .select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--documenter-dark .select.is-black:not(:hover)::after{border-color:#0a0a0a}html.theme--documenter-dark .select.is-black select{border-color:#0a0a0a}html.theme--documenter-dark .select.is-black select:hover,html.theme--documenter-dark .select.is-black select.is-hovered{border-color:#000}html.theme--documenter-dark .select.is-black select:focus,html.theme--documenter-dark .select.is-black select.is-focused,html.theme--documenter-dark .select.is-black select:active,html.theme--documenter-dark .select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--documenter-dark .select.is-light:not(:hover)::after{border-color:#ecf0f1}html.theme--documenter-dark .select.is-light select{border-color:#ecf0f1}html.theme--documenter-dark .select.is-light select:hover,html.theme--documenter-dark .select.is-light select.is-hovered{border-color:#dde4e6}html.theme--documenter-dark .select.is-light select:focus,html.theme--documenter-dark .select.is-light select.is-focused,html.theme--documenter-dark .select.is-light select:active,html.theme--documenter-dark .select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(236,240,241,0.25)}html.theme--documenter-dark .select.is-dark:not(:hover)::after,html.theme--documenter-dark .content kbd.select:not(:hover)::after{border-color:#282f2f}html.theme--documenter-dark .select.is-dark select,html.theme--documenter-dark .content kbd.select select{border-color:#282f2f}html.theme--documenter-dark .select.is-dark select:hover,html.theme--documenter-dark .content kbd.select select:hover,html.theme--documenter-dark .select.is-dark select.is-hovered,html.theme--documenter-dark .content kbd.select select.is-hovered{border-color:#1d2122}html.theme--documenter-dark .select.is-dark select:focus,html.theme--documenter-dark .content kbd.select select:focus,html.theme--documenter-dark .select.is-dark select.is-focused,html.theme--documenter-dark .content kbd.select select.is-focused,html.theme--documenter-dark .select.is-dark select:active,html.theme--documenter-dark .content kbd.select select:active,html.theme--documenter-dark .select.is-dark select.is-active,html.theme--documenter-dark .content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(40,47,47,0.25)}html.theme--documenter-dark .select.is-primary:not(:hover)::after,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#375a7f}html.theme--documenter-dark .select.is-primary select,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select{border-color:#375a7f}html.theme--documenter-dark .select.is-primary select:hover,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select:hover,html.theme--documenter-dark .select.is-primary select.is-hovered,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#2f4d6d}html.theme--documenter-dark .select.is-primary select:focus,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select:focus,html.theme--documenter-dark .select.is-primary select.is-focused,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select.is-focused,html.theme--documenter-dark .select.is-primary select:active,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select:active,html.theme--documenter-dark .select.is-primary select.is-active,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(55,90,127,0.25)}html.theme--documenter-dark .select.is-link:not(:hover)::after{border-color:#1abc9c}html.theme--documenter-dark .select.is-link select{border-color:#1abc9c}html.theme--documenter-dark .select.is-link select:hover,html.theme--documenter-dark .select.is-link select.is-hovered{border-color:#17a689}html.theme--documenter-dark .select.is-link select:focus,html.theme--documenter-dark .select.is-link select.is-focused,html.theme--documenter-dark .select.is-link select:active,html.theme--documenter-dark .select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .select.is-info:not(:hover)::after{border-color:#024c7d}html.theme--documenter-dark .select.is-info select{border-color:#024c7d}html.theme--documenter-dark .select.is-info select:hover,html.theme--documenter-dark .select.is-info select.is-hovered{border-color:#023d64}html.theme--documenter-dark .select.is-info select:focus,html.theme--documenter-dark .select.is-info select.is-focused,html.theme--documenter-dark .select.is-info select:active,html.theme--documenter-dark .select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(2,76,125,0.25)}html.theme--documenter-dark .select.is-success:not(:hover)::after{border-color:#008438}html.theme--documenter-dark .select.is-success select{border-color:#008438}html.theme--documenter-dark .select.is-success select:hover,html.theme--documenter-dark .select.is-success select.is-hovered{border-color:#006b2d}html.theme--documenter-dark .select.is-success select:focus,html.theme--documenter-dark .select.is-success select.is-focused,html.theme--documenter-dark .select.is-success select:active,html.theme--documenter-dark .select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(0,132,56,0.25)}html.theme--documenter-dark .select.is-warning:not(:hover)::after{border-color:#ad8100}html.theme--documenter-dark .select.is-warning select{border-color:#ad8100}html.theme--documenter-dark .select.is-warning select:hover,html.theme--documenter-dark .select.is-warning select.is-hovered{border-color:#946e00}html.theme--documenter-dark .select.is-warning select:focus,html.theme--documenter-dark .select.is-warning select.is-focused,html.theme--documenter-dark .select.is-warning select:active,html.theme--documenter-dark .select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(173,129,0,0.25)}html.theme--documenter-dark .select.is-danger:not(:hover)::after{border-color:#9e1b0d}html.theme--documenter-dark .select.is-danger select{border-color:#9e1b0d}html.theme--documenter-dark .select.is-danger select:hover,html.theme--documenter-dark .select.is-danger select.is-hovered{border-color:#86170b}html.theme--documenter-dark .select.is-danger select:focus,html.theme--documenter-dark .select.is-danger select.is-focused,html.theme--documenter-dark .select.is-danger select:active,html.theme--documenter-dark .select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(158,27,13,0.25)}html.theme--documenter-dark .select.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.select{border-radius:3px;font-size:.75rem}html.theme--documenter-dark .select.is-medium{font-size:1.25rem}html.theme--documenter-dark .select.is-large{font-size:1.5rem}html.theme--documenter-dark .select.is-disabled::after{border-color:#fff !important;opacity:0.5}html.theme--documenter-dark .select.is-fullwidth{width:100%}html.theme--documenter-dark .select.is-fullwidth select{width:100%}html.theme--documenter-dark .select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:0.625em;transform:none}html.theme--documenter-dark .select.is-loading.is-small:after,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--documenter-dark .select.is-loading.is-medium:after{font-size:1.25rem}html.theme--documenter-dark .select.is-loading.is-large:after{font-size:1.5rem}html.theme--documenter-dark .file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}html.theme--documenter-dark .file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .file.is-white:hover .file-cta,html.theme--documenter-dark .file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .file.is-white:focus .file-cta,html.theme--documenter-dark .file.is-white.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,255,255,0.25);color:#0a0a0a}html.theme--documenter-dark .file.is-white:active .file-cta,html.theme--documenter-dark .file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-black:hover .file-cta,html.theme--documenter-dark .file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-black:focus .file-cta,html.theme--documenter-dark .file.is-black.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(10,10,10,0.25);color:#fff}html.theme--documenter-dark .file.is-black:active .file-cta,html.theme--documenter-dark .file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-light .file-cta{background-color:#ecf0f1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-light:hover .file-cta,html.theme--documenter-dark .file.is-light.is-hovered .file-cta{background-color:#e5eaec;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-light:focus .file-cta,html.theme--documenter-dark .file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(236,240,241,0.25);color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-light:active .file-cta,html.theme--documenter-dark .file.is-light.is-active .file-cta{background-color:#dde4e6;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-dark .file-cta,html.theme--documenter-dark .content kbd.file .file-cta{background-color:#282f2f;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-dark:hover .file-cta,html.theme--documenter-dark .content kbd.file:hover .file-cta,html.theme--documenter-dark .file.is-dark.is-hovered .file-cta,html.theme--documenter-dark .content kbd.file.is-hovered .file-cta{background-color:#232829;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-dark:focus .file-cta,html.theme--documenter-dark .content kbd.file:focus .file-cta,html.theme--documenter-dark .file.is-dark.is-focused .file-cta,html.theme--documenter-dark .content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(40,47,47,0.25);color:#fff}html.theme--documenter-dark .file.is-dark:active .file-cta,html.theme--documenter-dark .content kbd.file:active .file-cta,html.theme--documenter-dark .file.is-dark.is-active .file-cta,html.theme--documenter-dark .content kbd.file.is-active .file-cta{background-color:#1d2122;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-primary .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink .file-cta{background-color:#375a7f;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-primary:hover .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink:hover .file-cta,html.theme--documenter-dark .file.is-primary.is-hovered .file-cta,html.theme--documenter-dark .docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#335476;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-primary:focus .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink:focus .file-cta,html.theme--documenter-dark .file.is-primary.is-focused .file-cta,html.theme--documenter-dark .docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(55,90,127,0.25);color:#fff}html.theme--documenter-dark .file.is-primary:active .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink:active .file-cta,html.theme--documenter-dark .file.is-primary.is-active .file-cta,html.theme--documenter-dark .docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#2f4d6d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-link .file-cta{background-color:#1abc9c;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-link:hover .file-cta,html.theme--documenter-dark .file.is-link.is-hovered .file-cta{background-color:#18b193;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-link:focus .file-cta,html.theme--documenter-dark .file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(26,188,156,0.25);color:#fff}html.theme--documenter-dark .file.is-link:active .file-cta,html.theme--documenter-dark .file.is-link.is-active .file-cta{background-color:#17a689;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-info .file-cta{background-color:#024c7d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-info:hover .file-cta,html.theme--documenter-dark .file.is-info.is-hovered .file-cta{background-color:#024470;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-info:focus .file-cta,html.theme--documenter-dark .file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(2,76,125,0.25);color:#fff}html.theme--documenter-dark .file.is-info:active .file-cta,html.theme--documenter-dark .file.is-info.is-active .file-cta{background-color:#023d64;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success .file-cta{background-color:#008438;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success:hover .file-cta,html.theme--documenter-dark .file.is-success.is-hovered .file-cta{background-color:#073;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success:focus .file-cta,html.theme--documenter-dark .file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(0,132,56,0.25);color:#fff}html.theme--documenter-dark .file.is-success:active .file-cta,html.theme--documenter-dark .file.is-success.is-active .file-cta{background-color:#006b2d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-warning .file-cta{background-color:#ad8100;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-warning:hover .file-cta,html.theme--documenter-dark .file.is-warning.is-hovered .file-cta{background-color:#a07700;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-warning:focus .file-cta,html.theme--documenter-dark .file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(173,129,0,0.25);color:#fff}html.theme--documenter-dark .file.is-warning:active .file-cta,html.theme--documenter-dark .file.is-warning.is-active .file-cta{background-color:#946e00;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-danger .file-cta{background-color:#9e1b0d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-danger:hover .file-cta,html.theme--documenter-dark .file.is-danger.is-hovered .file-cta{background-color:#92190c;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-danger:focus .file-cta,html.theme--documenter-dark .file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(158,27,13,0.25);color:#fff}html.theme--documenter-dark .file.is-danger:active .file-cta,html.theme--documenter-dark .file.is-danger.is-active .file-cta{background-color:#86170b;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}html.theme--documenter-dark .file.is-normal{font-size:1rem}html.theme--documenter-dark .file.is-medium{font-size:1.25rem}html.theme--documenter-dark .file.is-medium .file-icon .fa{font-size:21px}html.theme--documenter-dark .file.is-large{font-size:1.5rem}html.theme--documenter-dark .file.is-large .file-icon .fa{font-size:28px}html.theme--documenter-dark .file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--documenter-dark .file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--documenter-dark .file.has-name.is-empty .file-cta{border-radius:.4em}html.theme--documenter-dark .file.has-name.is-empty .file-name{display:none}html.theme--documenter-dark .file.is-boxed .file-label{flex-direction:column}html.theme--documenter-dark .file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}html.theme--documenter-dark .file.is-boxed .file-name{border-width:0 1px 1px}html.theme--documenter-dark .file.is-boxed .file-icon{height:1.5em;width:1.5em}html.theme--documenter-dark .file.is-boxed .file-icon .fa{font-size:21px}html.theme--documenter-dark .file.is-boxed.is-small .file-icon .fa,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}html.theme--documenter-dark .file.is-boxed.is-medium .file-icon .fa{font-size:28px}html.theme--documenter-dark .file.is-boxed.is-large .file-icon .fa{font-size:35px}html.theme--documenter-dark .file.is-boxed.has-name .file-cta{border-radius:.4em .4em 0 0}html.theme--documenter-dark .file.is-boxed.has-name .file-name{border-radius:0 0 .4em .4em;border-width:0 1px 1px}html.theme--documenter-dark .file.is-centered{justify-content:center}html.theme--documenter-dark .file.is-fullwidth .file-label{width:100%}html.theme--documenter-dark .file.is-fullwidth .file-name{flex-grow:1;max-width:none}html.theme--documenter-dark .file.is-right{justify-content:flex-end}html.theme--documenter-dark .file.is-right .file-cta{border-radius:0 .4em .4em 0}html.theme--documenter-dark .file.is-right .file-name{border-radius:.4em 0 0 .4em;border-width:1px 0 1px 1px;order:-1}html.theme--documenter-dark .file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}html.theme--documenter-dark .file-label:hover .file-cta{background-color:#232829;color:#f2f2f2}html.theme--documenter-dark .file-label:hover .file-name{border-color:#596668}html.theme--documenter-dark .file-label:active .file-cta{background-color:#1d2122;color:#f2f2f2}html.theme--documenter-dark .file-label:active .file-name{border-color:#535f61}html.theme--documenter-dark .file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}html.theme--documenter-dark .file-cta,html.theme--documenter-dark .file-name{border-color:#5e6d6f;border-radius:.4em;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}html.theme--documenter-dark .file-cta{background-color:#282f2f;color:#fff}html.theme--documenter-dark .file-name{border-color:#5e6d6f;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}html.theme--documenter-dark .file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}html.theme--documenter-dark .file-icon .fa{font-size:14px}html.theme--documenter-dark .label{color:#f2f2f2;display:block;font-size:1rem;font-weight:700}html.theme--documenter-dark .label:not(:last-child){margin-bottom:0.5em}html.theme--documenter-dark .label.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.label{font-size:.75rem}html.theme--documenter-dark .label.is-medium{font-size:1.25rem}html.theme--documenter-dark .label.is-large{font-size:1.5rem}html.theme--documenter-dark .help{display:block;font-size:.75rem;margin-top:0.25rem}html.theme--documenter-dark .help.is-white{color:#fff}html.theme--documenter-dark .help.is-black{color:#0a0a0a}html.theme--documenter-dark .help.is-light{color:#ecf0f1}html.theme--documenter-dark .help.is-dark,html.theme--documenter-dark .content kbd.help{color:#282f2f}html.theme--documenter-dark .help.is-primary,html.theme--documenter-dark .docstring>section>a.help.docs-sourcelink{color:#375a7f}html.theme--documenter-dark .help.is-link{color:#1abc9c}html.theme--documenter-dark .help.is-info{color:#024c7d}html.theme--documenter-dark .help.is-success{color:#008438}html.theme--documenter-dark .help.is-warning{color:#ad8100}html.theme--documenter-dark .help.is-danger{color:#9e1b0d}html.theme--documenter-dark .field:not(:last-child){margin-bottom:0.75rem}html.theme--documenter-dark .field.has-addons{display:flex;justify-content:flex-start}html.theme--documenter-dark .field.has-addons .control:not(:last-child){margin-right:-1px}html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) .button,html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) .input,html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) .button,html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) .input,html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) .button,html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) .input,html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .button.is-hovered:not([disabled]),html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .input.is-hovered:not([disabled]),html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control .button.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control .button.is-active:not([disabled]),html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control .input.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control .input.is-active:not([disabled]),html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control .select select.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control .select select.is-active:not([disabled]){z-index:3}html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control .button.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control .button.is-active:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control .input.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control .input.is-active:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control .select select.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}html.theme--documenter-dark .field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .field.has-addons.has-addons-centered{justify-content:center}html.theme--documenter-dark .field.has-addons.has-addons-right{justify-content:flex-end}html.theme--documenter-dark .field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}html.theme--documenter-dark .field.is-grouped{display:flex;justify-content:flex-start}html.theme--documenter-dark .field.is-grouped>.control{flex-shrink:0}html.theme--documenter-dark .field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--documenter-dark .field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .field.is-grouped.is-grouped-centered{justify-content:center}html.theme--documenter-dark .field.is-grouped.is-grouped-right{justify-content:flex-end}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline{flex-wrap:wrap}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline>.control:last-child,html.theme--documenter-dark .field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--documenter-dark .field.is-horizontal{display:flex}}html.theme--documenter-dark .field-label .label{font-size:inherit}@media screen and (max-width: 768px){html.theme--documenter-dark .field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}html.theme--documenter-dark .field-label.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.field-label{font-size:.75rem;padding-top:0.375em}html.theme--documenter-dark .field-label.is-normal{padding-top:0.375em}html.theme--documenter-dark .field-label.is-medium{font-size:1.25rem;padding-top:0.375em}html.theme--documenter-dark .field-label.is-large{font-size:1.5rem;padding-top:0.375em}}html.theme--documenter-dark .field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--documenter-dark .field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}html.theme--documenter-dark .field-body .field{margin-bottom:0}html.theme--documenter-dark .field-body>.field{flex-shrink:1}html.theme--documenter-dark .field-body>.field:not(.is-narrow){flex-grow:1}html.theme--documenter-dark .field-body>.field:not(:last-child){margin-right:.75rem}}html.theme--documenter-dark .control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}html.theme--documenter-dark .control.has-icons-left .input:focus~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,html.theme--documenter-dark .control.has-icons-left .select:focus~.icon,html.theme--documenter-dark .control.has-icons-right .input:focus~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,html.theme--documenter-dark .control.has-icons-right .select:focus~.icon{color:#282f2f}html.theme--documenter-dark .control.has-icons-left .input.is-small~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,html.theme--documenter-dark .control.has-icons-left .select.is-small~.icon,html.theme--documenter-dark .control.has-icons-right .input.is-small~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,html.theme--documenter-dark .control.has-icons-right .select.is-small~.icon{font-size:.75rem}html.theme--documenter-dark .control.has-icons-left .input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-left .select.is-medium~.icon,html.theme--documenter-dark .control.has-icons-right .input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}html.theme--documenter-dark .control.has-icons-left .input.is-large~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,html.theme--documenter-dark .control.has-icons-left .select.is-large~.icon,html.theme--documenter-dark .control.has-icons-right .input.is-large~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,html.theme--documenter-dark .control.has-icons-right .select.is-large~.icon{font-size:1.5rem}html.theme--documenter-dark .control.has-icons-left .icon,html.theme--documenter-dark .control.has-icons-right .icon{color:#5e6d6f;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}html.theme--documenter-dark .control.has-icons-left .input,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input,html.theme--documenter-dark .control.has-icons-left .select select{padding-left:2.5em}html.theme--documenter-dark .control.has-icons-left .icon.is-left{left:0}html.theme--documenter-dark .control.has-icons-right .input,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input,html.theme--documenter-dark .control.has-icons-right .select select{padding-right:2.5em}html.theme--documenter-dark .control.has-icons-right .icon.is-right{right:0}html.theme--documenter-dark .control.is-loading::after{position:absolute !important;right:.625em;top:0.625em;z-index:4}html.theme--documenter-dark .control.is-loading.is-small:after,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--documenter-dark .control.is-loading.is-medium:after{font-size:1.25rem}html.theme--documenter-dark .control.is-loading.is-large:after{font-size:1.5rem}html.theme--documenter-dark .breadcrumb{font-size:1rem;white-space:nowrap}html.theme--documenter-dark .breadcrumb a{align-items:center;color:#1abc9c;display:flex;justify-content:center;padding:0 .75em}html.theme--documenter-dark .breadcrumb a:hover{color:#1dd2af}html.theme--documenter-dark .breadcrumb li{align-items:center;display:flex}html.theme--documenter-dark .breadcrumb li:first-child a{padding-left:0}html.theme--documenter-dark .breadcrumb li.is-active a{color:#f2f2f2;cursor:default;pointer-events:none}html.theme--documenter-dark .breadcrumb li+li::before{color:#8c9b9d;content:"\0002f"}html.theme--documenter-dark .breadcrumb ul,html.theme--documenter-dark .breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--documenter-dark .breadcrumb .icon:first-child{margin-right:.5em}html.theme--documenter-dark .breadcrumb .icon:last-child{margin-left:.5em}html.theme--documenter-dark .breadcrumb.is-centered ol,html.theme--documenter-dark .breadcrumb.is-centered ul{justify-content:center}html.theme--documenter-dark .breadcrumb.is-right ol,html.theme--documenter-dark .breadcrumb.is-right ul{justify-content:flex-end}html.theme--documenter-dark .breadcrumb.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.75rem}html.theme--documenter-dark .breadcrumb.is-medium{font-size:1.25rem}html.theme--documenter-dark .breadcrumb.is-large{font-size:1.5rem}html.theme--documenter-dark .breadcrumb.has-arrow-separator li+li::before{content:"\02192"}html.theme--documenter-dark .breadcrumb.has-bullet-separator li+li::before{content:"\02022"}html.theme--documenter-dark .breadcrumb.has-dot-separator li+li::before{content:"\000b7"}html.theme--documenter-dark .breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}html.theme--documenter-dark .card{background-color:#fff;border-radius:.25rem;box-shadow:#171717;color:#fff;max-width:100%;position:relative}html.theme--documenter-dark .card-footer:first-child,html.theme--documenter-dark .card-content:first-child,html.theme--documenter-dark .card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--documenter-dark .card-footer:last-child,html.theme--documenter-dark .card-content:last-child,html.theme--documenter-dark .card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--documenter-dark .card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);display:flex}html.theme--documenter-dark .card-header-title{align-items:center;color:#f2f2f2;display:flex;flex-grow:1;font-weight:700;padding:0.75rem 1rem}html.theme--documenter-dark .card-header-title.is-centered{justify-content:center}html.theme--documenter-dark .card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:0.75rem 1rem}html.theme--documenter-dark .card-image{display:block;position:relative}html.theme--documenter-dark .card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--documenter-dark .card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--documenter-dark .card-content{background-color:rgba(0,0,0,0);padding:1.5rem}html.theme--documenter-dark .card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #ededed;align-items:stretch;display:flex}html.theme--documenter-dark .card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}html.theme--documenter-dark .card-footer-item:not(:last-child){border-right:1px solid #ededed}html.theme--documenter-dark .card .media:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .dropdown{display:inline-flex;position:relative;vertical-align:top}html.theme--documenter-dark .dropdown.is-active .dropdown-menu,html.theme--documenter-dark .dropdown.is-hoverable:hover .dropdown-menu{display:block}html.theme--documenter-dark .dropdown.is-right .dropdown-menu{left:auto;right:0}html.theme--documenter-dark .dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}html.theme--documenter-dark .dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}html.theme--documenter-dark .dropdown-content{background-color:#282f2f;border-radius:.4em;box-shadow:#171717;padding-bottom:.5rem;padding-top:.5rem}html.theme--documenter-dark .dropdown-item{color:#fff;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}html.theme--documenter-dark a.dropdown-item,html.theme--documenter-dark button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}html.theme--documenter-dark a.dropdown-item:hover,html.theme--documenter-dark button.dropdown-item:hover{background-color:#282f2f;color:#0a0a0a}html.theme--documenter-dark a.dropdown-item.is-active,html.theme--documenter-dark button.dropdown-item.is-active{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:0.5rem 0}html.theme--documenter-dark .level{align-items:center;justify-content:space-between}html.theme--documenter-dark .level code{border-radius:.4em}html.theme--documenter-dark .level img{display:inline-block;vertical-align:top}html.theme--documenter-dark .level.is-mobile{display:flex}html.theme--documenter-dark .level.is-mobile .level-left,html.theme--documenter-dark .level.is-mobile .level-right{display:flex}html.theme--documenter-dark .level.is-mobile .level-left+.level-right{margin-top:0}html.theme--documenter-dark .level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--documenter-dark .level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level{display:flex}html.theme--documenter-dark .level>.level-item:not(.is-narrow){flex-grow:1}}html.theme--documenter-dark .level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}html.theme--documenter-dark .level-item .title,html.theme--documenter-dark .level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){html.theme--documenter-dark .level-item:not(:last-child){margin-bottom:.75rem}}html.theme--documenter-dark .level-left,html.theme--documenter-dark .level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--documenter-dark .level-left .level-item.is-flexible,html.theme--documenter-dark .level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level-left .level-item:not(:last-child),html.theme--documenter-dark .level-right .level-item:not(:last-child){margin-right:.75rem}}html.theme--documenter-dark .level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){html.theme--documenter-dark .level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level-left{display:flex}}html.theme--documenter-dark .level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level-right{display:flex}}html.theme--documenter-dark .media{align-items:flex-start;display:flex;text-align:inherit}html.theme--documenter-dark .media .content:not(:last-child){margin-bottom:.75rem}html.theme--documenter-dark .media .media{border-top:1px solid rgba(94,109,111,0.5);display:flex;padding-top:.75rem}html.theme--documenter-dark .media .media .content:not(:last-child),html.theme--documenter-dark .media .media .control:not(:last-child){margin-bottom:.5rem}html.theme--documenter-dark .media .media .media{padding-top:.5rem}html.theme--documenter-dark .media .media .media+.media{margin-top:.5rem}html.theme--documenter-dark .media+.media{border-top:1px solid rgba(94,109,111,0.5);margin-top:1rem;padding-top:1rem}html.theme--documenter-dark .media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}html.theme--documenter-dark .media-left,html.theme--documenter-dark .media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--documenter-dark .media-left{margin-right:1rem}html.theme--documenter-dark .media-right{margin-left:1rem}html.theme--documenter-dark .media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width: 768px){html.theme--documenter-dark .media-content{overflow-x:auto}}html.theme--documenter-dark .menu{font-size:1rem}html.theme--documenter-dark .menu.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}html.theme--documenter-dark .menu.is-medium{font-size:1.25rem}html.theme--documenter-dark .menu.is-large{font-size:1.5rem}html.theme--documenter-dark .menu-list{line-height:1.25}html.theme--documenter-dark .menu-list a{border-radius:3px;color:#fff;display:block;padding:0.5em 0.75em}html.theme--documenter-dark .menu-list a:hover{background-color:#282f2f;color:#f2f2f2}html.theme--documenter-dark .menu-list a.is-active{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .menu-list li ul{border-left:1px solid #5e6d6f;margin:.75em;padding-left:.75em}html.theme--documenter-dark .menu-label{color:#fff;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}html.theme--documenter-dark .menu-label:not(:first-child){margin-top:1em}html.theme--documenter-dark .menu-label:not(:last-child){margin-bottom:1em}html.theme--documenter-dark .message{background-color:#282f2f;border-radius:.4em;font-size:1rem}html.theme--documenter-dark .message strong{color:currentColor}html.theme--documenter-dark .message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--documenter-dark .message.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.message{font-size:.75rem}html.theme--documenter-dark .message.is-medium{font-size:1.25rem}html.theme--documenter-dark .message.is-large{font-size:1.5rem}html.theme--documenter-dark .message.is-white{background-color:#fff}html.theme--documenter-dark .message.is-white .message-header{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .message.is-white .message-body{border-color:#fff}html.theme--documenter-dark .message.is-black{background-color:#fafafa}html.theme--documenter-dark .message.is-black .message-header{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .message.is-black .message-body{border-color:#0a0a0a}html.theme--documenter-dark .message.is-light{background-color:#f9fafb}html.theme--documenter-dark .message.is-light .message-header{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .message.is-light .message-body{border-color:#ecf0f1}html.theme--documenter-dark .message.is-dark,html.theme--documenter-dark .content kbd.message{background-color:#f9fafa}html.theme--documenter-dark .message.is-dark .message-header,html.theme--documenter-dark .content kbd.message .message-header{background-color:#282f2f;color:#fff}html.theme--documenter-dark .message.is-dark .message-body,html.theme--documenter-dark .content kbd.message .message-body{border-color:#282f2f}html.theme--documenter-dark .message.is-primary,html.theme--documenter-dark .docstring>section>a.message.docs-sourcelink{background-color:#f1f5f9}html.theme--documenter-dark .message.is-primary .message-header,html.theme--documenter-dark .docstring>section>a.message.docs-sourcelink .message-header{background-color:#375a7f;color:#fff}html.theme--documenter-dark .message.is-primary .message-body,html.theme--documenter-dark .docstring>section>a.message.docs-sourcelink .message-body{border-color:#375a7f;color:#4d7eb2}html.theme--documenter-dark .message.is-link{background-color:#edfdf9}html.theme--documenter-dark .message.is-link .message-header{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .message.is-link .message-body{border-color:#1abc9c;color:#15987e}html.theme--documenter-dark .message.is-info{background-color:#ebf7ff}html.theme--documenter-dark .message.is-info .message-header{background-color:#024c7d;color:#fff}html.theme--documenter-dark .message.is-info .message-body{border-color:#024c7d;color:#0e9dfb}html.theme--documenter-dark .message.is-success{background-color:#ebfff3}html.theme--documenter-dark .message.is-success .message-header{background-color:#008438;color:#fff}html.theme--documenter-dark .message.is-success .message-body{border-color:#008438;color:#00eb64}html.theme--documenter-dark .message.is-warning{background-color:#fffaeb}html.theme--documenter-dark .message.is-warning .message-header{background-color:#ad8100;color:#fff}html.theme--documenter-dark .message.is-warning .message-body{border-color:#ad8100;color:#d19c00}html.theme--documenter-dark .message.is-danger{background-color:#fdeeec}html.theme--documenter-dark .message.is-danger .message-header{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .message.is-danger .message-body{border-color:#9e1b0d;color:#ec311d}html.theme--documenter-dark .message-header{align-items:center;background-color:#fff;border-radius:.4em .4em 0 0;color:rgba(0,0,0,0.7);display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.75em 1em;position:relative}html.theme--documenter-dark .message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}html.theme--documenter-dark .message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}html.theme--documenter-dark .message-body{border-color:#5e6d6f;border-radius:.4em;border-style:solid;border-width:0 0 0 4px;color:#fff;padding:1.25em 1.5em}html.theme--documenter-dark .message-body code,html.theme--documenter-dark .message-body pre{background-color:#fff}html.theme--documenter-dark .message-body pre code{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}html.theme--documenter-dark .modal.is-active{display:flex}html.theme--documenter-dark .modal-background{background-color:rgba(10,10,10,0.86)}html.theme--documenter-dark .modal-content,html.theme--documenter-dark .modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px){html.theme--documenter-dark .modal-content,html.theme--documenter-dark .modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}html.theme--documenter-dark .modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}html.theme--documenter-dark .modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}html.theme--documenter-dark .modal-card-head,html.theme--documenter-dark .modal-card-foot{align-items:center;background-color:#282f2f;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}html.theme--documenter-dark .modal-card-head{border-bottom:1px solid #5e6d6f;border-top-left-radius:8px;border-top-right-radius:8px}html.theme--documenter-dark .modal-card-title{color:#f2f2f2;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}html.theme--documenter-dark .modal-card-foot{border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid #5e6d6f}html.theme--documenter-dark .modal-card-foot .button:not(:last-child){margin-right:.5em}html.theme--documenter-dark .modal-card-body{-webkit-overflow-scrolling:touch;background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}html.theme--documenter-dark .navbar{background-color:#375a7f;min-height:4rem;position:relative;z-index:30}html.theme--documenter-dark .navbar.is-white{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-white .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-white .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-white .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-white .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-white .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-white .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-white .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-white .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-white .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}html.theme--documenter-dark .navbar.is-black{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-black .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-black .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-black .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-black .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-black .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-black .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-black .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-black .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-black .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}html.theme--documenter-dark .navbar.is-light{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-light .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-light .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#dde4e6;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-light .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-light .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-light .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-light .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-light .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-light .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-light .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link.is-active{background-color:#dde4e6;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#dde4e6;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}}html.theme--documenter-dark .navbar.is-dark,html.theme--documenter-dark .content kbd.navbar{background-color:#282f2f;color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-brand>.navbar-item,html.theme--documenter-dark .content kbd.navbar .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .content kbd.navbar .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-dark .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .content kbd.navbar .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-dark .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link:focus,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link:hover,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#1d2122;color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link::after,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-burger,html.theme--documenter-dark .content kbd.navbar .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-dark .navbar-start>.navbar-item,html.theme--documenter-dark .content kbd.navbar .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-dark .navbar-end>.navbar-item,html.theme--documenter-dark .content kbd.navbar .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .content kbd.navbar .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-dark .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .content kbd.navbar .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-dark .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link:focus,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link:hover,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .content kbd.navbar .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-dark .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .content kbd.navbar .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-dark .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link:focus,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link:hover,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#1d2122;color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link::after,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link::after,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#1d2122;color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-dropdown a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#282f2f;color:#fff}}html.theme--documenter-dark .navbar.is-primary,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink{background-color:#375a7f;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-brand>.navbar-item,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-primary .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-primary .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link::after,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-burger,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-primary .navbar-start>.navbar-item,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-primary .navbar-end>.navbar-item,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-primary .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-primary .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-primary .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-primary .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link::after,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link::after,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#375a7f;color:#fff}}html.theme--documenter-dark .navbar.is-link{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-link .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-link .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#17a689;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-link .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-link .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-link .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-link .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-link .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-link .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-link .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link.is-active{background-color:#17a689;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#17a689;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#1abc9c;color:#fff}}html.theme--documenter-dark .navbar.is-info{background-color:#024c7d;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-info .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-info .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#023d64;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-info .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-info .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-info .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-info .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-info .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-info .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-info .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link.is-active{background-color:#023d64;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#023d64;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#024c7d;color:#fff}}html.theme--documenter-dark .navbar.is-success{background-color:#008438;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-success .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-success .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#006b2d;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-success .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-success .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-success .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-success .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-success .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-success .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-success .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link.is-active{background-color:#006b2d;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#006b2d;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#008438;color:#fff}}html.theme--documenter-dark .navbar.is-warning{background-color:#ad8100;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-warning .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-warning .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#946e00;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-warning .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-warning .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-warning .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-warning .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-warning .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-warning .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#946e00;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#946e00;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#ad8100;color:#fff}}html.theme--documenter-dark .navbar.is-danger{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-danger .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-danger .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#86170b;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-danger .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-danger .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-danger .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-danger .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-danger .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-danger .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#86170b;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#86170b;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#9e1b0d;color:#fff}}html.theme--documenter-dark .navbar>.container{align-items:stretch;display:flex;min-height:4rem;width:100%}html.theme--documenter-dark .navbar.has-shadow{box-shadow:0 2px 0 0 #282f2f}html.theme--documenter-dark .navbar.is-fixed-bottom,html.theme--documenter-dark .navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}html.theme--documenter-dark .navbar.is-fixed-bottom{bottom:0}html.theme--documenter-dark .navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #282f2f}html.theme--documenter-dark .navbar.is-fixed-top{top:0}html.theme--documenter-dark html.has-navbar-fixed-top,html.theme--documenter-dark body.has-navbar-fixed-top{padding-top:4rem}html.theme--documenter-dark html.has-navbar-fixed-bottom,html.theme--documenter-dark body.has-navbar-fixed-bottom{padding-bottom:4rem}html.theme--documenter-dark .navbar-brand,html.theme--documenter-dark .navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:4rem}html.theme--documenter-dark .navbar-brand a.navbar-item:focus,html.theme--documenter-dark .navbar-brand a.navbar-item:hover{background-color:transparent}html.theme--documenter-dark .navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}html.theme--documenter-dark .navbar-burger{color:#fff;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:block;height:4rem;position:relative;width:4rem;margin-left:auto}html.theme--documenter-dark .navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;transform-origin:center;transition-duration:86ms;transition-property:background-color, opacity, transform;transition-timing-function:ease-out;width:16px}html.theme--documenter-dark .navbar-burger span:nth-child(1){top:calc(50% - 6px)}html.theme--documenter-dark .navbar-burger span:nth-child(2){top:calc(50% - 1px)}html.theme--documenter-dark .navbar-burger span:nth-child(3){top:calc(50% + 4px)}html.theme--documenter-dark .navbar-burger:hover{background-color:rgba(0,0,0,0.05)}html.theme--documenter-dark .navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}html.theme--documenter-dark .navbar-burger.is-active span:nth-child(2){opacity:0}html.theme--documenter-dark .navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}html.theme--documenter-dark .navbar-menu{display:none}html.theme--documenter-dark .navbar-item,html.theme--documenter-dark .navbar-link{color:#fff;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}html.theme--documenter-dark .navbar-item .icon:only-child,html.theme--documenter-dark .navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}html.theme--documenter-dark a.navbar-item,html.theme--documenter-dark .navbar-link{cursor:pointer}html.theme--documenter-dark a.navbar-item:focus,html.theme--documenter-dark a.navbar-item:focus-within,html.theme--documenter-dark a.navbar-item:hover,html.theme--documenter-dark a.navbar-item.is-active,html.theme--documenter-dark .navbar-link:focus,html.theme--documenter-dark .navbar-link:focus-within,html.theme--documenter-dark .navbar-link:hover,html.theme--documenter-dark .navbar-link.is-active{background-color:rgba(0,0,0,0);color:#1abc9c}html.theme--documenter-dark .navbar-item{flex-grow:0;flex-shrink:0}html.theme--documenter-dark .navbar-item img{max-height:1.75rem}html.theme--documenter-dark .navbar-item.has-dropdown{padding:0}html.theme--documenter-dark .navbar-item.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .navbar-item.is-tab{border-bottom:1px solid transparent;min-height:4rem;padding-bottom:calc(0.5rem - 1px)}html.theme--documenter-dark .navbar-item.is-tab:focus,html.theme--documenter-dark .navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#1abc9c}html.theme--documenter-dark .navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#1abc9c;border-bottom-style:solid;border-bottom-width:3px;color:#1abc9c;padding-bottom:calc(0.5rem - 3px)}html.theme--documenter-dark .navbar-content{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .navbar-link:not(.is-arrowless){padding-right:2.5em}html.theme--documenter-dark .navbar-link:not(.is-arrowless)::after{border-color:#fff;margin-top:-0.375em;right:1.125em}html.theme--documenter-dark .navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}html.theme--documenter-dark .navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}html.theme--documenter-dark .navbar-divider{background-color:rgba(0,0,0,0.2);border:none;display:none;height:2px;margin:0.5rem 0}@media screen and (max-width: 1055px){html.theme--documenter-dark .navbar>.container{display:block}html.theme--documenter-dark .navbar-brand .navbar-item,html.theme--documenter-dark .navbar-tabs .navbar-item{align-items:center;display:flex}html.theme--documenter-dark .navbar-link::after{display:none}html.theme--documenter-dark .navbar-menu{background-color:#375a7f;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}html.theme--documenter-dark .navbar-menu.is-active{display:block}html.theme--documenter-dark .navbar.is-fixed-bottom-touch,html.theme--documenter-dark .navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}html.theme--documenter-dark .navbar.is-fixed-bottom-touch{bottom:0}html.theme--documenter-dark .navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--documenter-dark .navbar.is-fixed-top-touch{top:0}html.theme--documenter-dark .navbar.is-fixed-top .navbar-menu,html.theme--documenter-dark .navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 4rem);overflow:auto}html.theme--documenter-dark html.has-navbar-fixed-top-touch,html.theme--documenter-dark body.has-navbar-fixed-top-touch{padding-top:4rem}html.theme--documenter-dark html.has-navbar-fixed-bottom-touch,html.theme--documenter-dark body.has-navbar-fixed-bottom-touch{padding-bottom:4rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar,html.theme--documenter-dark .navbar-menu,html.theme--documenter-dark .navbar-start,html.theme--documenter-dark .navbar-end{align-items:stretch;display:flex}html.theme--documenter-dark .navbar{min-height:4rem}html.theme--documenter-dark .navbar.is-spaced{padding:1rem 2rem}html.theme--documenter-dark .navbar.is-spaced .navbar-start,html.theme--documenter-dark .navbar.is-spaced .navbar-end{align-items:center}html.theme--documenter-dark .navbar.is-spaced a.navbar-item,html.theme--documenter-dark .navbar.is-spaced .navbar-link{border-radius:.4em}html.theme--documenter-dark .navbar.is-transparent a.navbar-item:focus,html.theme--documenter-dark .navbar.is-transparent a.navbar-item:hover,html.theme--documenter-dark .navbar.is-transparent a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-transparent .navbar-link:focus,html.theme--documenter-dark .navbar.is-transparent .navbar-link:hover,html.theme--documenter-dark .navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}html.theme--documenter-dark .navbar.is-transparent .navbar-dropdown a.navbar-item:focus,html.theme--documenter-dark .navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#dbdee0}html.theme--documenter-dark .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#1abc9c}html.theme--documenter-dark .navbar-burger{display:none}html.theme--documenter-dark .navbar-item,html.theme--documenter-dark .navbar-link{align-items:center;display:flex}html.theme--documenter-dark .navbar-item.has-dropdown{align-items:stretch}html.theme--documenter-dark .navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}html.theme--documenter-dark .navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:1px solid rgba(0,0,0,0.2);border-radius:8px 8px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,0.1);top:auto}html.theme--documenter-dark .navbar-item.is-active .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-active .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-hoverable:hover .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}html.theme--documenter-dark .navbar-menu{flex-grow:1;flex-shrink:0}html.theme--documenter-dark .navbar-start{justify-content:flex-start;margin-right:auto}html.theme--documenter-dark .navbar-end{justify-content:flex-end;margin-left:auto}html.theme--documenter-dark .navbar-dropdown{background-color:#375a7f;border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid rgba(0,0,0,0.2);box-shadow:0 8px 8px rgba(10,10,10,0.1);display:none;font-size:0.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}html.theme--documenter-dark .navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}html.theme--documenter-dark .navbar-dropdown a.navbar-item{padding-right:3rem}html.theme--documenter-dark .navbar-dropdown a.navbar-item:focus,html.theme--documenter-dark .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#dbdee0}html.theme--documenter-dark .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#1abc9c}.navbar.is-spaced html.theme--documenter-dark .navbar-dropdown,html.theme--documenter-dark .navbar-dropdown.is-boxed{border-radius:8px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,0.1), 0 0 0 1px rgba(10,10,10,0.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));transform:translateY(-5px);transition-duration:86ms;transition-property:opacity, transform}html.theme--documenter-dark .navbar-dropdown.is-right{left:auto;right:0}html.theme--documenter-dark .navbar-divider{display:block}html.theme--documenter-dark .navbar>.container .navbar-brand,html.theme--documenter-dark .container>.navbar .navbar-brand{margin-left:-.75rem}html.theme--documenter-dark .navbar>.container .navbar-menu,html.theme--documenter-dark .container>.navbar .navbar-menu{margin-right:-.75rem}html.theme--documenter-dark .navbar.is-fixed-bottom-desktop,html.theme--documenter-dark .navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}html.theme--documenter-dark .navbar.is-fixed-bottom-desktop{bottom:0}html.theme--documenter-dark .navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--documenter-dark .navbar.is-fixed-top-desktop{top:0}html.theme--documenter-dark html.has-navbar-fixed-top-desktop,html.theme--documenter-dark body.has-navbar-fixed-top-desktop{padding-top:4rem}html.theme--documenter-dark html.has-navbar-fixed-bottom-desktop,html.theme--documenter-dark body.has-navbar-fixed-bottom-desktop{padding-bottom:4rem}html.theme--documenter-dark html.has-spaced-navbar-fixed-top,html.theme--documenter-dark body.has-spaced-navbar-fixed-top{padding-top:6rem}html.theme--documenter-dark html.has-spaced-navbar-fixed-bottom,html.theme--documenter-dark body.has-spaced-navbar-fixed-bottom{padding-bottom:6rem}html.theme--documenter-dark a.navbar-item.is-active,html.theme--documenter-dark .navbar-link.is-active{color:#1abc9c}html.theme--documenter-dark a.navbar-item.is-active:not(:focus):not(:hover),html.theme--documenter-dark .navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}html.theme--documenter-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar-item.has-dropdown.is-active .navbar-link{background-color:rgba(0,0,0,0)}}html.theme--documenter-dark .hero.is-fullheight-with-navbar{min-height:calc(100vh - 4rem)}html.theme--documenter-dark .pagination{font-size:1rem;margin:-.25rem}html.theme--documenter-dark .pagination.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}html.theme--documenter-dark .pagination.is-medium{font-size:1.25rem}html.theme--documenter-dark .pagination.is-large{font-size:1.5rem}html.theme--documenter-dark .pagination.is-rounded .pagination-previous,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,html.theme--documenter-dark .pagination.is-rounded .pagination-next,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:9999px}html.theme--documenter-dark .pagination.is-rounded .pagination-link,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:9999px}html.theme--documenter-dark .pagination,html.theme--documenter-dark .pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link{border-color:#5e6d6f;color:#1abc9c;min-width:2.5em}html.theme--documenter-dark .pagination-previous:hover,html.theme--documenter-dark .pagination-next:hover,html.theme--documenter-dark .pagination-link:hover{border-color:#8c9b9d;color:#1dd2af}html.theme--documenter-dark .pagination-previous:focus,html.theme--documenter-dark .pagination-next:focus,html.theme--documenter-dark .pagination-link:focus{border-color:#8c9b9d}html.theme--documenter-dark .pagination-previous:active,html.theme--documenter-dark .pagination-next:active,html.theme--documenter-dark .pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}html.theme--documenter-dark .pagination-previous[disabled],html.theme--documenter-dark .pagination-previous.is-disabled,html.theme--documenter-dark .pagination-next[disabled],html.theme--documenter-dark .pagination-next.is-disabled,html.theme--documenter-dark .pagination-link[disabled],html.theme--documenter-dark .pagination-link.is-disabled{background-color:#5e6d6f;border-color:#5e6d6f;box-shadow:none;color:#fff;opacity:0.5}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next{padding-left:.75em;padding-right:.75em;white-space:nowrap}html.theme--documenter-dark .pagination-link.is-current{background-color:#1abc9c;border-color:#1abc9c;color:#fff}html.theme--documenter-dark .pagination-ellipsis{color:#8c9b9d;pointer-events:none}html.theme--documenter-dark .pagination-list{flex-wrap:wrap}html.theme--documenter-dark .pagination-list li{list-style:none}@media screen and (max-width: 768px){html.theme--documenter-dark .pagination{flex-wrap:wrap}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis{margin-bottom:0;margin-top:0}html.theme--documenter-dark .pagination-previous{order:2}html.theme--documenter-dark .pagination-next{order:3}html.theme--documenter-dark .pagination{justify-content:space-between;margin-bottom:0;margin-top:0}html.theme--documenter-dark .pagination.is-centered .pagination-previous{order:1}html.theme--documenter-dark .pagination.is-centered .pagination-list{justify-content:center;order:2}html.theme--documenter-dark .pagination.is-centered .pagination-next{order:3}html.theme--documenter-dark .pagination.is-right .pagination-previous{order:1}html.theme--documenter-dark .pagination.is-right .pagination-next{order:2}html.theme--documenter-dark .pagination.is-right .pagination-list{justify-content:flex-end;order:3}}html.theme--documenter-dark .panel{border-radius:8px;box-shadow:#171717;font-size:1rem}html.theme--documenter-dark .panel:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}html.theme--documenter-dark .panel.is-white .panel-block.is-active .panel-icon{color:#fff}html.theme--documenter-dark .panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}html.theme--documenter-dark .panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}html.theme--documenter-dark .panel.is-light .panel-heading{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .panel.is-light .panel-tabs a.is-active{border-bottom-color:#ecf0f1}html.theme--documenter-dark .panel.is-light .panel-block.is-active .panel-icon{color:#ecf0f1}html.theme--documenter-dark .panel.is-dark .panel-heading,html.theme--documenter-dark .content kbd.panel .panel-heading{background-color:#282f2f;color:#fff}html.theme--documenter-dark .panel.is-dark .panel-tabs a.is-active,html.theme--documenter-dark .content kbd.panel .panel-tabs a.is-active{border-bottom-color:#282f2f}html.theme--documenter-dark .panel.is-dark .panel-block.is-active .panel-icon,html.theme--documenter-dark .content kbd.panel .panel-block.is-active .panel-icon{color:#282f2f}html.theme--documenter-dark .panel.is-primary .panel-heading,html.theme--documenter-dark .docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#375a7f;color:#fff}html.theme--documenter-dark .panel.is-primary .panel-tabs a.is-active,html.theme--documenter-dark .docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#375a7f}html.theme--documenter-dark .panel.is-primary .panel-block.is-active .panel-icon,html.theme--documenter-dark .docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#375a7f}html.theme--documenter-dark .panel.is-link .panel-heading{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .panel.is-link .panel-tabs a.is-active{border-bottom-color:#1abc9c}html.theme--documenter-dark .panel.is-link .panel-block.is-active .panel-icon{color:#1abc9c}html.theme--documenter-dark .panel.is-info .panel-heading{background-color:#024c7d;color:#fff}html.theme--documenter-dark .panel.is-info .panel-tabs a.is-active{border-bottom-color:#024c7d}html.theme--documenter-dark .panel.is-info .panel-block.is-active .panel-icon{color:#024c7d}html.theme--documenter-dark .panel.is-success .panel-heading{background-color:#008438;color:#fff}html.theme--documenter-dark .panel.is-success .panel-tabs a.is-active{border-bottom-color:#008438}html.theme--documenter-dark .panel.is-success .panel-block.is-active .panel-icon{color:#008438}html.theme--documenter-dark .panel.is-warning .panel-heading{background-color:#ad8100;color:#fff}html.theme--documenter-dark .panel.is-warning .panel-tabs a.is-active{border-bottom-color:#ad8100}html.theme--documenter-dark .panel.is-warning .panel-block.is-active .panel-icon{color:#ad8100}html.theme--documenter-dark .panel.is-danger .panel-heading{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .panel.is-danger .panel-tabs a.is-active{border-bottom-color:#9e1b0d}html.theme--documenter-dark .panel.is-danger .panel-block.is-active .panel-icon{color:#9e1b0d}html.theme--documenter-dark .panel-tabs:not(:last-child),html.theme--documenter-dark .panel-block:not(:last-child){border-bottom:1px solid #ededed}html.theme--documenter-dark .panel-heading{background-color:#343c3d;border-radius:8px 8px 0 0;color:#f2f2f2;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}html.theme--documenter-dark .panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}html.theme--documenter-dark .panel-tabs a{border-bottom:1px solid #5e6d6f;margin-bottom:-1px;padding:0.5em}html.theme--documenter-dark .panel-tabs a.is-active{border-bottom-color:#343c3d;color:#17a689}html.theme--documenter-dark .panel-list a{color:#fff}html.theme--documenter-dark .panel-list a:hover{color:#1abc9c}html.theme--documenter-dark .panel-block{align-items:center;color:#f2f2f2;display:flex;justify-content:flex-start;padding:0.5em 0.75em}html.theme--documenter-dark .panel-block input[type="checkbox"]{margin-right:.75em}html.theme--documenter-dark .panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}html.theme--documenter-dark .panel-block.is-wrapped{flex-wrap:wrap}html.theme--documenter-dark .panel-block.is-active{border-left-color:#1abc9c;color:#17a689}html.theme--documenter-dark .panel-block.is-active .panel-icon{color:#1abc9c}html.theme--documenter-dark .panel-block:last-child{border-bottom-left-radius:8px;border-bottom-right-radius:8px}html.theme--documenter-dark a.panel-block,html.theme--documenter-dark label.panel-block{cursor:pointer}html.theme--documenter-dark a.panel-block:hover,html.theme--documenter-dark label.panel-block:hover{background-color:#282f2f}html.theme--documenter-dark .panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#fff;margin-right:.75em}html.theme--documenter-dark .panel-icon .fa{font-size:inherit;line-height:inherit}html.theme--documenter-dark .tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:1rem;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}html.theme--documenter-dark .tabs a{align-items:center;border-bottom-color:#5e6d6f;border-bottom-style:solid;border-bottom-width:1px;color:#fff;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}html.theme--documenter-dark .tabs a:hover{border-bottom-color:#f2f2f2;color:#f2f2f2}html.theme--documenter-dark .tabs li{display:block}html.theme--documenter-dark .tabs li.is-active a{border-bottom-color:#1abc9c;color:#1abc9c}html.theme--documenter-dark .tabs ul{align-items:center;border-bottom-color:#5e6d6f;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}html.theme--documenter-dark .tabs ul.is-left{padding-right:0.75em}html.theme--documenter-dark .tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}html.theme--documenter-dark .tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}html.theme--documenter-dark .tabs .icon:first-child{margin-right:.5em}html.theme--documenter-dark .tabs .icon:last-child{margin-left:.5em}html.theme--documenter-dark .tabs.is-centered ul{justify-content:center}html.theme--documenter-dark .tabs.is-right ul{justify-content:flex-end}html.theme--documenter-dark .tabs.is-boxed a{border:1px solid transparent;border-radius:.4em .4em 0 0}html.theme--documenter-dark .tabs.is-boxed a:hover{background-color:#282f2f;border-bottom-color:#5e6d6f}html.theme--documenter-dark .tabs.is-boxed li.is-active a{background-color:#fff;border-color:#5e6d6f;border-bottom-color:rgba(0,0,0,0) !important}html.theme--documenter-dark .tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}html.theme--documenter-dark .tabs.is-toggle a{border-color:#5e6d6f;border-style:solid;border-width:1px;margin-bottom:0;position:relative}html.theme--documenter-dark .tabs.is-toggle a:hover{background-color:#282f2f;border-color:#8c9b9d;z-index:2}html.theme--documenter-dark .tabs.is-toggle li+li{margin-left:-1px}html.theme--documenter-dark .tabs.is-toggle li:first-child a{border-top-left-radius:.4em;border-bottom-left-radius:.4em}html.theme--documenter-dark .tabs.is-toggle li:last-child a{border-top-right-radius:.4em;border-bottom-right-radius:.4em}html.theme--documenter-dark .tabs.is-toggle li.is-active a{background-color:#1abc9c;border-color:#1abc9c;color:#fff;z-index:1}html.theme--documenter-dark .tabs.is-toggle ul{border-bottom:none}html.theme--documenter-dark .tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}html.theme--documenter-dark .tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}html.theme--documenter-dark .tabs.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.tabs{font-size:.75rem}html.theme--documenter-dark .tabs.is-medium{font-size:1.25rem}html.theme--documenter-dark .tabs.is-large{font-size:1.5rem}html.theme--documenter-dark .column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>html.theme--documenter-dark .column.is-narrow{flex:none;width:unset}.columns.is-mobile>html.theme--documenter-dark .column.is-full{flex:none;width:100%}.columns.is-mobile>html.theme--documenter-dark .column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>html.theme--documenter-dark .column.is-half{flex:none;width:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>html.theme--documenter-dark .column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>html.theme--documenter-dark .column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>html.theme--documenter-dark .column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>html.theme--documenter-dark .column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-half{margin-left:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>html.theme--documenter-dark .column.is-0{flex:none;width:0%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-0{margin-left:0%}.columns.is-mobile>html.theme--documenter-dark .column.is-1{flex:none;width:8.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-2{margin-left:16.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-3{flex:none;width:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-3{margin-left:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-4{flex:none;width:33.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-5{margin-left:41.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-6{flex:none;width:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-6{margin-left:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-7{flex:none;width:58.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-8{margin-left:66.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-9{flex:none;width:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-9{margin-left:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-10{flex:none;width:83.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-11{margin-left:91.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-12{flex:none;width:100%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){html.theme--documenter-dark .column.is-narrow-mobile{flex:none;width:unset}html.theme--documenter-dark .column.is-full-mobile{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-mobile{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-mobile{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-mobile{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-mobile{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-mobile{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-mobile{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-mobile{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-mobile{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-mobile{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-mobile{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-mobile{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-mobile{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-mobile{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-mobile{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-mobile{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-mobile{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-mobile{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-mobile{margin-left:80%}html.theme--documenter-dark .column.is-0-mobile{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-mobile{margin-left:0%}html.theme--documenter-dark .column.is-1-mobile{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-mobile{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-mobile{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-mobile{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-mobile{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-mobile{margin-left:25%}html.theme--documenter-dark .column.is-4-mobile{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-mobile{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-mobile{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-mobile{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-mobile{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-mobile{margin-left:50%}html.theme--documenter-dark .column.is-7-mobile{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-mobile{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-mobile{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-mobile{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-mobile{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-mobile{margin-left:75%}html.theme--documenter-dark .column.is-10-mobile{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-mobile{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-mobile{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-mobile{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-mobile{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .column.is-narrow,html.theme--documenter-dark .column.is-narrow-tablet{flex:none;width:unset}html.theme--documenter-dark .column.is-full,html.theme--documenter-dark .column.is-full-tablet{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters,html.theme--documenter-dark .column.is-three-quarters-tablet{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds,html.theme--documenter-dark .column.is-two-thirds-tablet{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half,html.theme--documenter-dark .column.is-half-tablet{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third,html.theme--documenter-dark .column.is-one-third-tablet{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter,html.theme--documenter-dark .column.is-one-quarter-tablet{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth,html.theme--documenter-dark .column.is-one-fifth-tablet{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths,html.theme--documenter-dark .column.is-two-fifths-tablet{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths,html.theme--documenter-dark .column.is-three-fifths-tablet{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths,html.theme--documenter-dark .column.is-four-fifths-tablet{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters,html.theme--documenter-dark .column.is-offset-three-quarters-tablet{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds,html.theme--documenter-dark .column.is-offset-two-thirds-tablet{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half,html.theme--documenter-dark .column.is-offset-half-tablet{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third,html.theme--documenter-dark .column.is-offset-one-third-tablet{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter,html.theme--documenter-dark .column.is-offset-one-quarter-tablet{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth,html.theme--documenter-dark .column.is-offset-one-fifth-tablet{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths,html.theme--documenter-dark .column.is-offset-two-fifths-tablet{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths,html.theme--documenter-dark .column.is-offset-three-fifths-tablet{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths,html.theme--documenter-dark .column.is-offset-four-fifths-tablet{margin-left:80%}html.theme--documenter-dark .column.is-0,html.theme--documenter-dark .column.is-0-tablet{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0,html.theme--documenter-dark .column.is-offset-0-tablet{margin-left:0%}html.theme--documenter-dark .column.is-1,html.theme--documenter-dark .column.is-1-tablet{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1,html.theme--documenter-dark .column.is-offset-1-tablet{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2,html.theme--documenter-dark .column.is-2-tablet{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2,html.theme--documenter-dark .column.is-offset-2-tablet{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3,html.theme--documenter-dark .column.is-3-tablet{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3,html.theme--documenter-dark .column.is-offset-3-tablet{margin-left:25%}html.theme--documenter-dark .column.is-4,html.theme--documenter-dark .column.is-4-tablet{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4,html.theme--documenter-dark .column.is-offset-4-tablet{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5,html.theme--documenter-dark .column.is-5-tablet{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5,html.theme--documenter-dark .column.is-offset-5-tablet{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6,html.theme--documenter-dark .column.is-6-tablet{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6,html.theme--documenter-dark .column.is-offset-6-tablet{margin-left:50%}html.theme--documenter-dark .column.is-7,html.theme--documenter-dark .column.is-7-tablet{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7,html.theme--documenter-dark .column.is-offset-7-tablet{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8,html.theme--documenter-dark .column.is-8-tablet{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8,html.theme--documenter-dark .column.is-offset-8-tablet{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9,html.theme--documenter-dark .column.is-9-tablet{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9,html.theme--documenter-dark .column.is-offset-9-tablet{margin-left:75%}html.theme--documenter-dark .column.is-10,html.theme--documenter-dark .column.is-10-tablet{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10,html.theme--documenter-dark .column.is-offset-10-tablet{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11,html.theme--documenter-dark .column.is-11-tablet{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11,html.theme--documenter-dark .column.is-offset-11-tablet{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12,html.theme--documenter-dark .column.is-12-tablet{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12,html.theme--documenter-dark .column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){html.theme--documenter-dark .column.is-narrow-touch{flex:none;width:unset}html.theme--documenter-dark .column.is-full-touch{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-touch{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-touch{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-touch{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-touch{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-touch{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-touch{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-touch{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-touch{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-touch{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-touch{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-touch{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-touch{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-touch{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-touch{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-touch{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-touch{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-touch{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-touch{margin-left:80%}html.theme--documenter-dark .column.is-0-touch{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-touch{margin-left:0%}html.theme--documenter-dark .column.is-1-touch{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-touch{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-touch{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-touch{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-touch{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-touch{margin-left:25%}html.theme--documenter-dark .column.is-4-touch{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-touch{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-touch{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-touch{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-touch{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-touch{margin-left:50%}html.theme--documenter-dark .column.is-7-touch{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-touch{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-touch{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-touch{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-touch{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-touch{margin-left:75%}html.theme--documenter-dark .column.is-10-touch{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-touch{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-touch{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-touch{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-touch{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){html.theme--documenter-dark .column.is-narrow-desktop{flex:none;width:unset}html.theme--documenter-dark .column.is-full-desktop{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-desktop{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-desktop{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-desktop{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-desktop{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-desktop{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-desktop{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-desktop{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-desktop{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-desktop{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-desktop{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-desktop{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-desktop{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-desktop{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-desktop{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-desktop{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-desktop{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-desktop{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-desktop{margin-left:80%}html.theme--documenter-dark .column.is-0-desktop{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-desktop{margin-left:0%}html.theme--documenter-dark .column.is-1-desktop{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-desktop{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-desktop{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-desktop{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-desktop{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-desktop{margin-left:25%}html.theme--documenter-dark .column.is-4-desktop{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-desktop{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-desktop{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-desktop{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-desktop{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-desktop{margin-left:50%}html.theme--documenter-dark .column.is-7-desktop{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-desktop{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-desktop{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-desktop{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-desktop{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-desktop{margin-left:75%}html.theme--documenter-dark .column.is-10-desktop{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-desktop{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-desktop{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-desktop{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-desktop{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){html.theme--documenter-dark .column.is-narrow-widescreen{flex:none;width:unset}html.theme--documenter-dark .column.is-full-widescreen{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-widescreen{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-widescreen{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-widescreen{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-widescreen{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-widescreen{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-widescreen{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-widescreen{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-widescreen{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-widescreen{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-widescreen{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-widescreen{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-widescreen{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-widescreen{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-widescreen{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-widescreen{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-widescreen{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-widescreen{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-widescreen{margin-left:80%}html.theme--documenter-dark .column.is-0-widescreen{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-widescreen{margin-left:0%}html.theme--documenter-dark .column.is-1-widescreen{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-widescreen{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-widescreen{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-widescreen{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-widescreen{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-widescreen{margin-left:25%}html.theme--documenter-dark .column.is-4-widescreen{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-widescreen{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-widescreen{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-widescreen{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-widescreen{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-widescreen{margin-left:50%}html.theme--documenter-dark .column.is-7-widescreen{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-widescreen{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-widescreen{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-widescreen{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-widescreen{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-widescreen{margin-left:75%}html.theme--documenter-dark .column.is-10-widescreen{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-widescreen{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-widescreen{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-widescreen{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-widescreen{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){html.theme--documenter-dark .column.is-narrow-fullhd{flex:none;width:unset}html.theme--documenter-dark .column.is-full-fullhd{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-fullhd{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-fullhd{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-fullhd{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-fullhd{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-fullhd{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-fullhd{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-fullhd{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-fullhd{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-fullhd{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-fullhd{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-fullhd{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-fullhd{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-fullhd{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-fullhd{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-fullhd{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-fullhd{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-fullhd{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-fullhd{margin-left:80%}html.theme--documenter-dark .column.is-0-fullhd{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-fullhd{margin-left:0%}html.theme--documenter-dark .column.is-1-fullhd{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-fullhd{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-fullhd{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-fullhd{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-fullhd{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-fullhd{margin-left:25%}html.theme--documenter-dark .column.is-4-fullhd{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-fullhd{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-fullhd{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-fullhd{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-fullhd{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-fullhd{margin-left:50%}html.theme--documenter-dark .column.is-7-fullhd{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-fullhd{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-fullhd{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-fullhd{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-fullhd{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-fullhd{margin-left:75%}html.theme--documenter-dark .column.is-10-fullhd{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-fullhd{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-fullhd{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-fullhd{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-fullhd{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-fullhd{margin-left:100%}}html.theme--documenter-dark .columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--documenter-dark .columns:last-child{margin-bottom:-.75rem}html.theme--documenter-dark .columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}html.theme--documenter-dark .columns.is-centered{justify-content:center}html.theme--documenter-dark .columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}html.theme--documenter-dark .columns.is-gapless>.column{margin:0;padding:0 !important}html.theme--documenter-dark .columns.is-gapless:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .columns.is-gapless:last-child{margin-bottom:0}html.theme--documenter-dark .columns.is-mobile{display:flex}html.theme--documenter-dark .columns.is-multiline{flex-wrap:wrap}html.theme--documenter-dark .columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-desktop{display:flex}}html.theme--documenter-dark .columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}html.theme--documenter-dark .columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}html.theme--documenter-dark .columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-0-fullhd{--columnGap: 0rem}}html.theme--documenter-dark .columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-1-fullhd{--columnGap: .25rem}}html.theme--documenter-dark .columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-2-fullhd{--columnGap: .5rem}}html.theme--documenter-dark .columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-3-fullhd{--columnGap: .75rem}}html.theme--documenter-dark .columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-4-fullhd{--columnGap: 1rem}}html.theme--documenter-dark .columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}html.theme--documenter-dark .columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}html.theme--documenter-dark .columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}html.theme--documenter-dark .columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-8-fullhd{--columnGap: 2rem}}html.theme--documenter-dark .tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}html.theme--documenter-dark .tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--documenter-dark .tile.is-ancestor:last-child{margin-bottom:-.75rem}html.theme--documenter-dark .tile.is-ancestor:not(:last-child){margin-bottom:.75rem}html.theme--documenter-dark .tile.is-child{margin:0 !important}html.theme--documenter-dark .tile.is-parent{padding:.75rem}html.theme--documenter-dark .tile.is-vertical{flex-direction:column}html.theme--documenter-dark .tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{html.theme--documenter-dark .tile:not(.is-child){display:flex}html.theme--documenter-dark .tile.is-1{flex:none;width:8.33333337%}html.theme--documenter-dark .tile.is-2{flex:none;width:16.66666674%}html.theme--documenter-dark .tile.is-3{flex:none;width:25%}html.theme--documenter-dark .tile.is-4{flex:none;width:33.33333337%}html.theme--documenter-dark .tile.is-5{flex:none;width:41.66666674%}html.theme--documenter-dark .tile.is-6{flex:none;width:50%}html.theme--documenter-dark .tile.is-7{flex:none;width:58.33333337%}html.theme--documenter-dark .tile.is-8{flex:none;width:66.66666674%}html.theme--documenter-dark .tile.is-9{flex:none;width:75%}html.theme--documenter-dark .tile.is-10{flex:none;width:83.33333337%}html.theme--documenter-dark .tile.is-11{flex:none;width:91.66666674%}html.theme--documenter-dark .tile.is-12{flex:none;width:100%}}html.theme--documenter-dark .hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}html.theme--documenter-dark .hero .navbar{background:none}html.theme--documenter-dark .hero .tabs ul{border-bottom:none}html.theme--documenter-dark .hero.is-white{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-white strong{color:inherit}html.theme--documenter-dark .hero.is-white .title{color:#0a0a0a}html.theme--documenter-dark .hero.is-white .subtitle{color:rgba(10,10,10,0.9)}html.theme--documenter-dark .hero.is-white .subtitle a:not(.button),html.theme--documenter-dark .hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-white .navbar-menu{background-color:#fff}}html.theme--documenter-dark .hero.is-white .navbar-item,html.theme--documenter-dark .hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}html.theme--documenter-dark .hero.is-white a.navbar-item:hover,html.theme--documenter-dark .hero.is-white a.navbar-item.is-active,html.theme--documenter-dark .hero.is-white .navbar-link:hover,html.theme--documenter-dark .hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}html.theme--documenter-dark .hero.is-white .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-white .tabs li.is-active a{color:#fff !important;opacity:1}html.theme--documenter-dark .hero.is-white .tabs.is-boxed a,html.theme--documenter-dark .hero.is-white .tabs.is-toggle a{color:#0a0a0a}html.theme--documenter-dark .hero.is-white .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-white .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-white .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-white .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--documenter-dark .hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}html.theme--documenter-dark .hero.is-black{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-black strong{color:inherit}html.theme--documenter-dark .hero.is-black .title{color:#fff}html.theme--documenter-dark .hero.is-black .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-black .subtitle a:not(.button),html.theme--documenter-dark .hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-black .navbar-menu{background-color:#0a0a0a}}html.theme--documenter-dark .hero.is-black .navbar-item,html.theme--documenter-dark .hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-black a.navbar-item:hover,html.theme--documenter-dark .hero.is-black a.navbar-item.is-active,html.theme--documenter-dark .hero.is-black .navbar-link:hover,html.theme--documenter-dark .hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}html.theme--documenter-dark .hero.is-black .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-black .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-black .tabs li.is-active a{color:#0a0a0a !important;opacity:1}html.theme--documenter-dark .hero.is-black .tabs.is-boxed a,html.theme--documenter-dark .hero.is-black .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-black .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-black .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-black .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-black .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--documenter-dark .hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}html.theme--documenter-dark .hero.is-light{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-light strong{color:inherit}html.theme--documenter-dark .hero.is-light .title{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light .subtitle{color:rgba(0,0,0,0.9)}html.theme--documenter-dark .hero.is-light .subtitle a:not(.button),html.theme--documenter-dark .hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-light .navbar-menu{background-color:#ecf0f1}}html.theme--documenter-dark .hero.is-light .navbar-item,html.theme--documenter-dark .hero.is-light .navbar-link{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light a.navbar-item:hover,html.theme--documenter-dark .hero.is-light a.navbar-item.is-active,html.theme--documenter-dark .hero.is-light .navbar-link:hover,html.theme--documenter-dark .hero.is-light .navbar-link.is-active{background-color:#dde4e6;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--documenter-dark .hero.is-light .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-light .tabs li.is-active a{color:#ecf0f1 !important;opacity:1}html.theme--documenter-dark .hero.is-light .tabs.is-boxed a,html.theme--documenter-dark .hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-light .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-light .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-light .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#ecf0f1}html.theme--documenter-dark .hero.is-light.is-bold{background-image:linear-gradient(141deg, #cadfe0 0%, #ecf0f1 71%, #fafbfc 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #cadfe0 0%, #ecf0f1 71%, #fafbfc 100%)}}html.theme--documenter-dark .hero.is-dark,html.theme--documenter-dark .content kbd.hero{background-color:#282f2f;color:#fff}html.theme--documenter-dark .hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-dark strong,html.theme--documenter-dark .content kbd.hero strong{color:inherit}html.theme--documenter-dark .hero.is-dark .title,html.theme--documenter-dark .content kbd.hero .title{color:#fff}html.theme--documenter-dark .hero.is-dark .subtitle,html.theme--documenter-dark .content kbd.hero .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-dark .subtitle a:not(.button),html.theme--documenter-dark .content kbd.hero .subtitle a:not(.button),html.theme--documenter-dark .hero.is-dark .subtitle strong,html.theme--documenter-dark .content kbd.hero .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-dark .navbar-menu,html.theme--documenter-dark .content kbd.hero .navbar-menu{background-color:#282f2f}}html.theme--documenter-dark .hero.is-dark .navbar-item,html.theme--documenter-dark .content kbd.hero .navbar-item,html.theme--documenter-dark .hero.is-dark .navbar-link,html.theme--documenter-dark .content kbd.hero .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-dark a.navbar-item:hover,html.theme--documenter-dark .content kbd.hero a.navbar-item:hover,html.theme--documenter-dark .hero.is-dark a.navbar-item.is-active,html.theme--documenter-dark .content kbd.hero a.navbar-item.is-active,html.theme--documenter-dark .hero.is-dark .navbar-link:hover,html.theme--documenter-dark .content kbd.hero .navbar-link:hover,html.theme--documenter-dark .hero.is-dark .navbar-link.is-active,html.theme--documenter-dark .content kbd.hero .navbar-link.is-active{background-color:#1d2122;color:#fff}html.theme--documenter-dark .hero.is-dark .tabs a,html.theme--documenter-dark .content kbd.hero .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-dark .tabs a:hover,html.theme--documenter-dark .content kbd.hero .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-dark .tabs li.is-active a,html.theme--documenter-dark .content kbd.hero .tabs li.is-active a{color:#282f2f !important;opacity:1}html.theme--documenter-dark .hero.is-dark .tabs.is-boxed a,html.theme--documenter-dark .content kbd.hero .tabs.is-boxed a,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle a,html.theme--documenter-dark .content kbd.hero .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-dark .tabs.is-boxed a:hover,html.theme--documenter-dark .content kbd.hero .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle a:hover,html.theme--documenter-dark .content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-dark .tabs.is-boxed li.is-active a,html.theme--documenter-dark .content kbd.hero .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-dark .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle li.is-active a,html.theme--documenter-dark .content kbd.hero .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#282f2f}html.theme--documenter-dark .hero.is-dark.is-bold,html.theme--documenter-dark .content kbd.hero.is-bold{background-image:linear-gradient(141deg, #0f1615 0%, #282f2f 71%, #313c40 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-dark.is-bold .navbar-menu,html.theme--documenter-dark .content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #0f1615 0%, #282f2f 71%, #313c40 100%)}}html.theme--documenter-dark .hero.is-primary,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink{background-color:#375a7f;color:#fff}html.theme--documenter-dark .hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-primary strong,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink strong{color:inherit}html.theme--documenter-dark .hero.is-primary .title,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .title{color:#fff}html.theme--documenter-dark .hero.is-primary .subtitle,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-primary .subtitle a:not(.button),html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),html.theme--documenter-dark .hero.is-primary .subtitle strong,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-primary .navbar-menu,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#375a7f}}html.theme--documenter-dark .hero.is-primary .navbar-item,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-item,html.theme--documenter-dark .hero.is-primary .navbar-link,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-primary a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,html.theme--documenter-dark .hero.is-primary a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,html.theme--documenter-dark .hero.is-primary .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-link:hover,html.theme--documenter-dark .hero.is-primary .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .hero.is-primary .tabs a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-primary .tabs a:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-primary .tabs li.is-active a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{color:#375a7f !important;opacity:1}html.theme--documenter-dark .hero.is-primary .tabs.is-boxed a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-primary .tabs.is-boxed a:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle a:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-primary .tabs.is-boxed li.is-active a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-primary .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle li.is-active a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#375a7f}html.theme--documenter-dark .hero.is-primary.is-bold,html.theme--documenter-dark .docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #214b62 0%, #375a7f 71%, #3a5796 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-primary.is-bold .navbar-menu,html.theme--documenter-dark .docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #214b62 0%, #375a7f 71%, #3a5796 100%)}}html.theme--documenter-dark .hero.is-link{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-link strong{color:inherit}html.theme--documenter-dark .hero.is-link .title{color:#fff}html.theme--documenter-dark .hero.is-link .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-link .subtitle a:not(.button),html.theme--documenter-dark .hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-link .navbar-menu{background-color:#1abc9c}}html.theme--documenter-dark .hero.is-link .navbar-item,html.theme--documenter-dark .hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-link a.navbar-item:hover,html.theme--documenter-dark .hero.is-link a.navbar-item.is-active,html.theme--documenter-dark .hero.is-link .navbar-link:hover,html.theme--documenter-dark .hero.is-link .navbar-link.is-active{background-color:#17a689;color:#fff}html.theme--documenter-dark .hero.is-link .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-link .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-link .tabs li.is-active a{color:#1abc9c !important;opacity:1}html.theme--documenter-dark .hero.is-link .tabs.is-boxed a,html.theme--documenter-dark .hero.is-link .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-link .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-link .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-link .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-link .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#1abc9c}html.theme--documenter-dark .hero.is-link.is-bold{background-image:linear-gradient(141deg, #0c9764 0%, #1abc9c 71%, #17d8d2 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #0c9764 0%, #1abc9c 71%, #17d8d2 100%)}}html.theme--documenter-dark .hero.is-info{background-color:#024c7d;color:#fff}html.theme--documenter-dark .hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-info strong{color:inherit}html.theme--documenter-dark .hero.is-info .title{color:#fff}html.theme--documenter-dark .hero.is-info .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-info .subtitle a:not(.button),html.theme--documenter-dark .hero.is-info .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-info .navbar-menu{background-color:#024c7d}}html.theme--documenter-dark .hero.is-info .navbar-item,html.theme--documenter-dark .hero.is-info .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-info a.navbar-item:hover,html.theme--documenter-dark .hero.is-info a.navbar-item.is-active,html.theme--documenter-dark .hero.is-info .navbar-link:hover,html.theme--documenter-dark .hero.is-info .navbar-link.is-active{background-color:#023d64;color:#fff}html.theme--documenter-dark .hero.is-info .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-info .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-info .tabs li.is-active a{color:#024c7d !important;opacity:1}html.theme--documenter-dark .hero.is-info .tabs.is-boxed a,html.theme--documenter-dark .hero.is-info .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-info .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-info .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-info .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-info .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#024c7d}html.theme--documenter-dark .hero.is-info.is-bold{background-image:linear-gradient(141deg, #003a4c 0%, #024c7d 71%, #004299 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #003a4c 0%, #024c7d 71%, #004299 100%)}}html.theme--documenter-dark .hero.is-success{background-color:#008438;color:#fff}html.theme--documenter-dark .hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-success strong{color:inherit}html.theme--documenter-dark .hero.is-success .title{color:#fff}html.theme--documenter-dark .hero.is-success .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-success .subtitle a:not(.button),html.theme--documenter-dark .hero.is-success .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-success .navbar-menu{background-color:#008438}}html.theme--documenter-dark .hero.is-success .navbar-item,html.theme--documenter-dark .hero.is-success .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-success a.navbar-item:hover,html.theme--documenter-dark .hero.is-success a.navbar-item.is-active,html.theme--documenter-dark .hero.is-success .navbar-link:hover,html.theme--documenter-dark .hero.is-success .navbar-link.is-active{background-color:#006b2d;color:#fff}html.theme--documenter-dark .hero.is-success .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-success .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-success .tabs li.is-active a{color:#008438 !important;opacity:1}html.theme--documenter-dark .hero.is-success .tabs.is-boxed a,html.theme--documenter-dark .hero.is-success .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-success .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-success .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-success .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-success .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#008438}html.theme--documenter-dark .hero.is-success.is-bold{background-image:linear-gradient(141deg, #005115 0%, #008438 71%, #009e5d 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #005115 0%, #008438 71%, #009e5d 100%)}}html.theme--documenter-dark .hero.is-warning{background-color:#ad8100;color:#fff}html.theme--documenter-dark .hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-warning strong{color:inherit}html.theme--documenter-dark .hero.is-warning .title{color:#fff}html.theme--documenter-dark .hero.is-warning .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-warning .subtitle a:not(.button),html.theme--documenter-dark .hero.is-warning .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-warning .navbar-menu{background-color:#ad8100}}html.theme--documenter-dark .hero.is-warning .navbar-item,html.theme--documenter-dark .hero.is-warning .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-warning a.navbar-item:hover,html.theme--documenter-dark .hero.is-warning a.navbar-item.is-active,html.theme--documenter-dark .hero.is-warning .navbar-link:hover,html.theme--documenter-dark .hero.is-warning .navbar-link.is-active{background-color:#946e00;color:#fff}html.theme--documenter-dark .hero.is-warning .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-warning .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-warning .tabs li.is-active a{color:#ad8100 !important;opacity:1}html.theme--documenter-dark .hero.is-warning .tabs.is-boxed a,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-warning .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-warning .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-warning .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#ad8100}html.theme--documenter-dark .hero.is-warning.is-bold{background-image:linear-gradient(141deg, #7a4700 0%, #ad8100 71%, #c7b500 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #7a4700 0%, #ad8100 71%, #c7b500 100%)}}html.theme--documenter-dark .hero.is-danger{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-danger strong{color:inherit}html.theme--documenter-dark .hero.is-danger .title{color:#fff}html.theme--documenter-dark .hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-danger .subtitle a:not(.button),html.theme--documenter-dark .hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-danger .navbar-menu{background-color:#9e1b0d}}html.theme--documenter-dark .hero.is-danger .navbar-item,html.theme--documenter-dark .hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-danger a.navbar-item:hover,html.theme--documenter-dark .hero.is-danger a.navbar-item.is-active,html.theme--documenter-dark .hero.is-danger .navbar-link:hover,html.theme--documenter-dark .hero.is-danger .navbar-link.is-active{background-color:#86170b;color:#fff}html.theme--documenter-dark .hero.is-danger .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-danger .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-danger .tabs li.is-active a{color:#9e1b0d !important;opacity:1}html.theme--documenter-dark .hero.is-danger .tabs.is-boxed a,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-danger .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-danger .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-danger .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#9e1b0d}html.theme--documenter-dark .hero.is-danger.is-bold{background-image:linear-gradient(141deg, #75030b 0%, #9e1b0d 71%, #ba380a 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #75030b 0%, #9e1b0d 71%, #ba380a 100%)}}html.theme--documenter-dark .hero.is-small .hero-body,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding:1.5rem}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero.is-large .hero-body{padding:18rem 6rem}}html.theme--documenter-dark .hero.is-halfheight .hero-body,html.theme--documenter-dark .hero.is-fullheight .hero-body,html.theme--documenter-dark .hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}html.theme--documenter-dark .hero.is-halfheight .hero-body>.container,html.theme--documenter-dark .hero.is-fullheight .hero-body>.container,html.theme--documenter-dark .hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .hero.is-halfheight{min-height:50vh}html.theme--documenter-dark .hero.is-fullheight{min-height:100vh}html.theme--documenter-dark .hero-video{overflow:hidden}html.theme--documenter-dark .hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}html.theme--documenter-dark .hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){html.theme--documenter-dark .hero-video{display:none}}html.theme--documenter-dark .hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){html.theme--documenter-dark .hero-buttons .button{display:flex}html.theme--documenter-dark .hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero-buttons{display:flex;justify-content:center}html.theme--documenter-dark .hero-buttons .button:not(:last-child){margin-right:1.5rem}}html.theme--documenter-dark .hero-head,html.theme--documenter-dark .hero-foot{flex-grow:0;flex-shrink:0}html.theme--documenter-dark .hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero-body{padding:3rem 3rem}}html.theme--documenter-dark .section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){html.theme--documenter-dark .section{padding:3rem 3rem}html.theme--documenter-dark .section.is-medium{padding:9rem 4.5rem}html.theme--documenter-dark .section.is-large{padding:18rem 6rem}}html.theme--documenter-dark .footer{background-color:#282f2f;padding:3rem 1.5rem 6rem}html.theme--documenter-dark hr{height:1px}html.theme--documenter-dark h6{text-transform:uppercase;letter-spacing:0.5px}html.theme--documenter-dark .hero{background-color:#343c3d}html.theme--documenter-dark a{transition:all 200ms ease}html.theme--documenter-dark .button{transition:all 200ms ease;border-width:1px;color:#fff}html.theme--documenter-dark .button.is-active,html.theme--documenter-dark .button.is-focused,html.theme--documenter-dark .button:active,html.theme--documenter-dark .button:focus{box-shadow:0 0 0 2px rgba(140,155,157,0.5)}html.theme--documenter-dark .button.is-white.is-hovered,html.theme--documenter-dark .button.is-white:hover{background-color:#fff}html.theme--documenter-dark .button.is-white.is-active,html.theme--documenter-dark .button.is-white.is-focused,html.theme--documenter-dark .button.is-white:active,html.theme--documenter-dark .button.is-white:focus{border-color:#fff;box-shadow:0 0 0 2px rgba(255,255,255,0.5)}html.theme--documenter-dark .button.is-black.is-hovered,html.theme--documenter-dark .button.is-black:hover{background-color:#1d1d1d}html.theme--documenter-dark .button.is-black.is-active,html.theme--documenter-dark .button.is-black.is-focused,html.theme--documenter-dark .button.is-black:active,html.theme--documenter-dark .button.is-black:focus{border-color:#0a0a0a;box-shadow:0 0 0 2px rgba(10,10,10,0.5)}html.theme--documenter-dark .button.is-light.is-hovered,html.theme--documenter-dark .button.is-light:hover{background-color:#fff}html.theme--documenter-dark .button.is-light.is-active,html.theme--documenter-dark .button.is-light.is-focused,html.theme--documenter-dark .button.is-light:active,html.theme--documenter-dark .button.is-light:focus{border-color:#ecf0f1;box-shadow:0 0 0 2px rgba(236,240,241,0.5)}html.theme--documenter-dark .button.is-dark.is-hovered,html.theme--documenter-dark .content kbd.button.is-hovered,html.theme--documenter-dark .button.is-dark:hover,html.theme--documenter-dark .content kbd.button:hover{background-color:#3a4344}html.theme--documenter-dark .button.is-dark.is-active,html.theme--documenter-dark .content kbd.button.is-active,html.theme--documenter-dark .button.is-dark.is-focused,html.theme--documenter-dark .content kbd.button.is-focused,html.theme--documenter-dark .button.is-dark:active,html.theme--documenter-dark .content kbd.button:active,html.theme--documenter-dark .button.is-dark:focus,html.theme--documenter-dark .content kbd.button:focus{border-color:#282f2f;box-shadow:0 0 0 2px rgba(40,47,47,0.5)}html.theme--documenter-dark .button.is-primary.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-hovered.docs-sourcelink,html.theme--documenter-dark .button.is-primary:hover,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:hover{background-color:#436d9a}html.theme--documenter-dark .button.is-primary.is-active,html.theme--documenter-dark .docstring>section>a.button.is-active.docs-sourcelink,html.theme--documenter-dark .button.is-primary.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-focused.docs-sourcelink,html.theme--documenter-dark .button.is-primary:active,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:active,html.theme--documenter-dark .button.is-primary:focus,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:focus{border-color:#375a7f;box-shadow:0 0 0 2px rgba(55,90,127,0.5)}html.theme--documenter-dark .button.is-link.is-hovered,html.theme--documenter-dark .button.is-link:hover{background-color:#1fdeb8}html.theme--documenter-dark .button.is-link.is-active,html.theme--documenter-dark .button.is-link.is-focused,html.theme--documenter-dark .button.is-link:active,html.theme--documenter-dark .button.is-link:focus{border-color:#1abc9c;box-shadow:0 0 0 2px rgba(26,188,156,0.5)}html.theme--documenter-dark .button.is-info.is-hovered,html.theme--documenter-dark .button.is-info:hover{background-color:#0363a3}html.theme--documenter-dark .button.is-info.is-active,html.theme--documenter-dark .button.is-info.is-focused,html.theme--documenter-dark .button.is-info:active,html.theme--documenter-dark .button.is-info:focus{border-color:#024c7d;box-shadow:0 0 0 2px rgba(2,76,125,0.5)}html.theme--documenter-dark .button.is-success.is-hovered,html.theme--documenter-dark .button.is-success:hover{background-color:#00aa48}html.theme--documenter-dark .button.is-success.is-active,html.theme--documenter-dark .button.is-success.is-focused,html.theme--documenter-dark .button.is-success:active,html.theme--documenter-dark .button.is-success:focus{border-color:#008438;box-shadow:0 0 0 2px rgba(0,132,56,0.5)}html.theme--documenter-dark .button.is-warning.is-hovered,html.theme--documenter-dark .button.is-warning:hover{background-color:#d39e00}html.theme--documenter-dark .button.is-warning.is-active,html.theme--documenter-dark .button.is-warning.is-focused,html.theme--documenter-dark .button.is-warning:active,html.theme--documenter-dark .button.is-warning:focus{border-color:#ad8100;box-shadow:0 0 0 2px rgba(173,129,0,0.5)}html.theme--documenter-dark .button.is-danger.is-hovered,html.theme--documenter-dark .button.is-danger:hover{background-color:#c12110}html.theme--documenter-dark .button.is-danger.is-active,html.theme--documenter-dark .button.is-danger.is-focused,html.theme--documenter-dark .button.is-danger:active,html.theme--documenter-dark .button.is-danger:focus{border-color:#9e1b0d;box-shadow:0 0 0 2px rgba(158,27,13,0.5)}html.theme--documenter-dark .label{color:#dbdee0}html.theme--documenter-dark .button,html.theme--documenter-dark .control.has-icons-left .icon,html.theme--documenter-dark .control.has-icons-right .icon,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .select,html.theme--documenter-dark .select select,html.theme--documenter-dark .textarea{height:2.5em}html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark .textarea{transition:all 200ms ease;box-shadow:none;border-width:1px;padding-left:1em;padding-right:1em}html.theme--documenter-dark .select:after,html.theme--documenter-dark .select select{border-width:1px}html.theme--documenter-dark .control.has-addons .button,html.theme--documenter-dark .control.has-addons .input,html.theme--documenter-dark .control.has-addons #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .control.has-addons form.docs-search>input,html.theme--documenter-dark .control.has-addons .select{margin-right:-1px}html.theme--documenter-dark .notification{background-color:#343c3d}html.theme--documenter-dark .card{box-shadow:none;border:1px solid #343c3d;background-color:#282f2f;border-radius:.4em}html.theme--documenter-dark .card .card-image img{border-radius:.4em .4em 0 0}html.theme--documenter-dark .card .card-header{box-shadow:none;background-color:rgba(18,18,18,0.2);border-radius:.4em .4em 0 0}html.theme--documenter-dark .card .card-footer{background-color:rgba(18,18,18,0.2)}html.theme--documenter-dark .card .card-footer,html.theme--documenter-dark .card .card-footer-item{border-width:1px;border-color:#343c3d}html.theme--documenter-dark .notification.is-white a:not(.button){color:#0a0a0a;text-decoration:underline}html.theme--documenter-dark .notification.is-black a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-light a:not(.button){color:rgba(0,0,0,0.7);text-decoration:underline}html.theme--documenter-dark .notification.is-dark a:not(.button),html.theme--documenter-dark .content kbd.notification a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-primary a:not(.button),html.theme--documenter-dark .docstring>section>a.notification.docs-sourcelink a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-link a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-info a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-success a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-warning a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-danger a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .tag,html.theme--documenter-dark .content kbd,html.theme--documenter-dark .docstring>section>a.docs-sourcelink{border-radius:.4em}html.theme--documenter-dark .menu-list a{transition:all 300ms ease}html.theme--documenter-dark .modal-card-body{background-color:#282f2f}html.theme--documenter-dark .modal-card-foot,html.theme--documenter-dark .modal-card-head{border-color:#343c3d}html.theme--documenter-dark .message-header{font-weight:700;background-color:#343c3d;color:#fff}html.theme--documenter-dark .message-body{border-width:1px;border-color:#343c3d}html.theme--documenter-dark .navbar{border-radius:.4em}html.theme--documenter-dark .navbar.is-transparent{background:none}html.theme--documenter-dark .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#1abc9c}@media screen and (max-width: 1055px){html.theme--documenter-dark .navbar .navbar-menu{background-color:#375a7f;border-radius:0 0 .4em .4em}}html.theme--documenter-dark .hero .navbar,html.theme--documenter-dark body>.navbar{border-radius:0}html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-previous{border-width:1px}html.theme--documenter-dark .panel-block,html.theme--documenter-dark .panel-heading,html.theme--documenter-dark .panel-tabs{border-width:1px}html.theme--documenter-dark .panel-block:first-child,html.theme--documenter-dark .panel-heading:first-child,html.theme--documenter-dark .panel-tabs:first-child{border-top-width:1px}html.theme--documenter-dark .panel-heading{font-weight:700}html.theme--documenter-dark .panel-tabs a{border-width:1px;margin-bottom:-1px}html.theme--documenter-dark .panel-tabs a.is-active{border-bottom-color:#17a689}html.theme--documenter-dark .panel-block:hover{color:#1dd2af}html.theme--documenter-dark .panel-block:hover .panel-icon{color:#1dd2af}html.theme--documenter-dark .panel-block.is-active .panel-icon{color:#17a689}html.theme--documenter-dark .tabs a{border-bottom-width:1px;margin-bottom:-1px}html.theme--documenter-dark .tabs ul{border-bottom-width:1px}html.theme--documenter-dark .tabs.is-boxed a{border-width:1px}html.theme--documenter-dark .tabs.is-boxed li.is-active a{background-color:#1f2424}html.theme--documenter-dark .tabs.is-toggle li a{border-width:1px;margin-bottom:0}html.theme--documenter-dark .tabs.is-toggle li+li{margin-left:-1px}html.theme--documenter-dark .hero.is-white .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-black .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-light .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-dark .navbar .navbar-dropdown .navbar-item:hover,html.theme--documenter-dark .content kbd.hero .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-primary .navbar .navbar-dropdown .navbar-item:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-link .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-info .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-success .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-warning .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-danger .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark h1 .docs-heading-anchor,html.theme--documenter-dark h1 .docs-heading-anchor:hover,html.theme--documenter-dark h1 .docs-heading-anchor:visited,html.theme--documenter-dark h2 .docs-heading-anchor,html.theme--documenter-dark h2 .docs-heading-anchor:hover,html.theme--documenter-dark h2 .docs-heading-anchor:visited,html.theme--documenter-dark h3 .docs-heading-anchor,html.theme--documenter-dark h3 .docs-heading-anchor:hover,html.theme--documenter-dark h3 .docs-heading-anchor:visited,html.theme--documenter-dark h4 .docs-heading-anchor,html.theme--documenter-dark h4 .docs-heading-anchor:hover,html.theme--documenter-dark h4 .docs-heading-anchor:visited,html.theme--documenter-dark h5 .docs-heading-anchor,html.theme--documenter-dark h5 .docs-heading-anchor:hover,html.theme--documenter-dark h5 .docs-heading-anchor:visited,html.theme--documenter-dark h6 .docs-heading-anchor,html.theme--documenter-dark h6 .docs-heading-anchor:hover,html.theme--documenter-dark h6 .docs-heading-anchor:visited{color:#f2f2f2}html.theme--documenter-dark h1 .docs-heading-anchor-permalink,html.theme--documenter-dark h2 .docs-heading-anchor-permalink,html.theme--documenter-dark h3 .docs-heading-anchor-permalink,html.theme--documenter-dark h4 .docs-heading-anchor-permalink,html.theme--documenter-dark h5 .docs-heading-anchor-permalink,html.theme--documenter-dark h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}html.theme--documenter-dark h1 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h2 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h3 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h4 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h5 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f0c1"}html.theme--documenter-dark h1:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h2:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h3:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h4:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h5:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h6:hover .docs-heading-anchor-permalink{visibility:visible}html.theme--documenter-dark .docs-light-only{display:none !important}html.theme--documenter-dark pre{position:relative;overflow:hidden}html.theme--documenter-dark pre code,html.theme--documenter-dark pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}html.theme--documenter-dark pre code:first-of-type,html.theme--documenter-dark pre code.hljs:first-of-type{padding-top:0.5rem !important}html.theme--documenter-dark pre code:last-of-type,html.theme--documenter-dark pre code.hljs:last-of-type{padding-bottom:0.5rem !important}html.theme--documenter-dark pre .copy-button{opacity:0.2;transition:opacity 0.2s;position:absolute;right:0em;top:0em;padding:0.5em;width:2.5em;height:2.5em;background:transparent;border:none;font-family:"Font Awesome 6 Free";color:#fff;cursor:pointer;text-align:center}html.theme--documenter-dark pre .copy-button:focus,html.theme--documenter-dark pre .copy-button:hover{opacity:1;background:rgba(255,255,255,0.1);color:#1abc9c}html.theme--documenter-dark pre .copy-button.success{color:#259a12;opacity:1}html.theme--documenter-dark pre .copy-button.error{color:#cb3c33;opacity:1}html.theme--documenter-dark pre:hover .copy-button{opacity:1}html.theme--documenter-dark .admonition{background-color:#282f2f;border-style:solid;border-width:1px;border-color:#5e6d6f;border-radius:.4em;font-size:1rem}html.theme--documenter-dark .admonition strong{color:currentColor}html.theme--documenter-dark .admonition.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.admonition{font-size:.75rem}html.theme--documenter-dark .admonition.is-medium{font-size:1.25rem}html.theme--documenter-dark .admonition.is-large{font-size:1.5rem}html.theme--documenter-dark .admonition.is-default{background-color:#282f2f;border-color:#5e6d6f}html.theme--documenter-dark .admonition.is-default>.admonition-header{background-color:#5e6d6f;color:#fff}html.theme--documenter-dark .admonition.is-default>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-info{background-color:#282f2f;border-color:#024c7d}html.theme--documenter-dark .admonition.is-info>.admonition-header{background-color:#024c7d;color:#fff}html.theme--documenter-dark .admonition.is-info>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-success{background-color:#282f2f;border-color:#008438}html.theme--documenter-dark .admonition.is-success>.admonition-header{background-color:#008438;color:#fff}html.theme--documenter-dark .admonition.is-success>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-warning{background-color:#282f2f;border-color:#ad8100}html.theme--documenter-dark .admonition.is-warning>.admonition-header{background-color:#ad8100;color:#fff}html.theme--documenter-dark .admonition.is-warning>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-danger{background-color:#282f2f;border-color:#9e1b0d}html.theme--documenter-dark .admonition.is-danger>.admonition-header{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .admonition.is-danger>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-compat{background-color:#282f2f;border-color:#137886}html.theme--documenter-dark .admonition.is-compat>.admonition-header{background-color:#137886;color:#fff}html.theme--documenter-dark .admonition.is-compat>.admonition-body{color:#fff}html.theme--documenter-dark .admonition-header{color:#fff;background-color:#5e6d6f;align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}html.theme--documenter-dark .admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}html.theme--documenter-dark details.admonition.is-details>.admonition-header{list-style:none}html.theme--documenter-dark details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}html.theme--documenter-dark details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}html.theme--documenter-dark .admonition-body{color:#fff;padding:0.5rem .75rem}html.theme--documenter-dark .admonition-body pre{background-color:#282f2f}html.theme--documenter-dark .admonition-body code{background-color:rgba(255,255,255,0.05)}html.theme--documenter-dark .docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:1px solid #5e6d6f;box-shadow:none;max-width:100%}html.theme--documenter-dark .docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#282f2f;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #5e6d6f}html.theme--documenter-dark .docstring>header code{background-color:transparent}html.theme--documenter-dark .docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}html.theme--documenter-dark .docstring>header .docstring-binding{margin-right:0.3em}html.theme--documenter-dark .docstring>header .docstring-category{margin-left:0.3em}html.theme--documenter-dark .docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #5e6d6f}html.theme--documenter-dark .docstring>section:last-child{border-bottom:none}html.theme--documenter-dark .docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}html.theme--documenter-dark .docstring>section>a.docs-sourcelink:focus{opacity:1 !important}html.theme--documenter-dark .docstring:hover>section>a.docs-sourcelink{opacity:0.2}html.theme--documenter-dark .docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}html.theme--documenter-dark .docstring>section:hover a.docs-sourcelink{opacity:1}html.theme--documenter-dark .documenter-example-output{background-color:#1f2424}html.theme--documenter-dark .outdated-warning-overlay{position:fixed;top:0;left:0;right:0;box-shadow:0 0 10px rgba(0,0,0,0.3);z-index:999;background-color:#282f2f;color:#fff;border-bottom:3px solid #9e1b0d;padding:10px 35px;text-align:center;font-size:15px}html.theme--documenter-dark .outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}html.theme--documenter-dark .outdated-warning-overlay a{color:#1abc9c}html.theme--documenter-dark .outdated-warning-overlay a:hover{color:#1dd2af}html.theme--documenter-dark .content pre{border:1px solid #5e6d6f}html.theme--documenter-dark .content code{font-weight:inherit}html.theme--documenter-dark .content a code{color:#1abc9c}html.theme--documenter-dark .content h1 code,html.theme--documenter-dark .content h2 code,html.theme--documenter-dark .content h3 code,html.theme--documenter-dark .content h4 code,html.theme--documenter-dark .content h5 code,html.theme--documenter-dark .content h6 code{color:#f2f2f2}html.theme--documenter-dark .content table{display:block;width:initial;max-width:100%;overflow-x:auto}html.theme--documenter-dark .content blockquote>ul:first-child,html.theme--documenter-dark .content blockquote>ol:first-child,html.theme--documenter-dark .content .admonition-body>ul:first-child,html.theme--documenter-dark .content .admonition-body>ol:first-child{margin-top:0}html.theme--documenter-dark pre,html.theme--documenter-dark code{font-variant-ligatures:no-contextual}html.theme--documenter-dark .breadcrumb a.is-disabled{cursor:default;pointer-events:none}html.theme--documenter-dark .breadcrumb a.is-disabled,html.theme--documenter-dark .breadcrumb a.is-disabled:hover{color:#f2f2f2}html.theme--documenter-dark .hljs{background:initial !important}html.theme--documenter-dark .katex .katex-mathml{top:0;right:0}html.theme--documenter-dark .katex-display,html.theme--documenter-dark mjx-container,html.theme--documenter-dark .MathJax_Display{margin:0.5em 0 !important}html.theme--documenter-dark html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}html.theme--documenter-dark li.no-marker{list-style:none}html.theme--documenter-dark #documenter .docs-main>article{overflow-wrap:break-word}html.theme--documenter-dark #documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main{width:100%}html.theme--documenter-dark #documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}html.theme--documenter-dark #documenter .docs-main>header,html.theme--documenter-dark #documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}html.theme--documenter-dark #documenter .docs-main header.docs-navbar{background-color:#1f2424;border-bottom:1px solid #5e6d6f;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-icon,html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}html.theme--documenter-dark #documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main header.docs-navbar{position:sticky;top:0;padding:0 1rem;transition-property:top, box-shadow;-webkit-transition-property:top, box-shadow;transition-duration:0.3s;-webkit-transition-duration:0.3s}html.theme--documenter-dark #documenter .docs-main header.docs-navbar.headroom--not-top{box-shadow:.2rem 0rem .4rem #171717;transition-duration:0.7s;-webkit-transition-duration:0.7s}html.theme--documenter-dark #documenter .docs-main header.docs-navbar.headroom--unpinned.headroom--not-top.headroom--not-bottom{top:-4.5rem;transition-duration:0.7s;-webkit-transition-duration:0.7s}}html.theme--documenter-dark #documenter .docs-main section.footnotes{border-top:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-main section.footnotes li .tag:first-child,html.theme--documenter-dark #documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,html.theme--documenter-dark #documenter .docs-main section.footnotes li .content kbd:first-child,html.theme--documenter-dark .content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}html.theme--documenter-dark #documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #5e6d6f;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-nextpage,html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}html.theme--documenter-dark #documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}html.theme--documenter-dark #documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}html.theme--documenter-dark #documenter .docs-sidebar{display:flex;flex-direction:column;color:#fff;background-color:#282f2f;border-right:1px solid #5e6d6f;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}html.theme--documenter-dark #documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #171717}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar{left:0;top:0}}html.theme--documenter-dark #documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name{flex-shrink:0;font-size:1.5rem;font-weight:700;text-align:center;white-space:nowrap;overflow:hidden;padding:0.5rem 0}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name a,html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name a:hover{color:#fff}html.theme--documenter-dark #documenter .docs-sidebar .docs-version-selector{border-top:1px solid #5e6d6f;display:none;padding:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-version-selector.visible{display:flex}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #5e6d6f;padding-bottom:1.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1;font-size:.75rem;margin-left:1rem;margin-top:auto;margin-bottom:auto}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#fff;background:#282f2f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu a.tocitem:hover,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#fff;background-color:#32393a}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #5e6d6f;border-bottom:1px solid #5e6d6f;background-color:#1f2424}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#1f2424;color:#fff}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#32393a;color:#fff}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}html.theme--documenter-dark #documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{width:14.4rem}html.theme--documenter-dark #documenter .docs-sidebar #documenter-search-query{color:#868c98;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#3b4445}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#4e5a5c}}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#3b4445}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#4e5a5c}}html.theme--documenter-dark kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(245,245,245,0.6);box-shadow:0 2px 0 1px rgba(245,245,245,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}html.theme--documenter-dark .search-min-width-50{min-width:50%}html.theme--documenter-dark .search-min-height-100{min-height:100%}html.theme--documenter-dark .search-modal-card-body{max-height:calc(100vh - 15rem)}html.theme--documenter-dark .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--documenter-dark .search-result-link:hover,html.theme--documenter-dark .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--documenter-dark .search-result-link .property-search-result-badge,html.theme--documenter-dark .search-result-link .search-filter{transition:all 300ms}html.theme--documenter-dark .property-search-result-badge,html.theme--documenter-dark .search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}html.theme--documenter-dark .search-result-link:hover .property-search-result-badge,html.theme--documenter-dark .search-result-link:hover .search-filter,html.theme--documenter-dark .search-result-link:focus .property-search-result-badge,html.theme--documenter-dark .search-result-link:focus .search-filter{color:#333;background-color:#f1f5f9}html.theme--documenter-dark .search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}html.theme--documenter-dark .search-filter:hover,html.theme--documenter-dark .search-filter:focus{color:#333}html.theme--documenter-dark .search-filter-selected{color:#f5f5f5;background-color:rgba(139,0,139,0.5)}html.theme--documenter-dark .search-filter-selected:hover,html.theme--documenter-dark .search-filter-selected:focus{color:#f5f5f5}html.theme--documenter-dark .search-result-highlight{background-color:#ffdd57;color:black}html.theme--documenter-dark .search-divider{border-bottom:1px solid #5e6d6f}html.theme--documenter-dark .search-result-title{width:85%;color:#f5f5f5}html.theme--documenter-dark .search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar-thumb,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar-track,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}html.theme--documenter-dark .w-100{width:100%}html.theme--documenter-dark .gap-2{gap:0.5rem}html.theme--documenter-dark .gap-4{gap:1rem}html.theme--documenter-dark .gap-8{gap:2rem}html.theme--documenter-dark{background-color:#1f2424;font-size:16px;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--documenter-dark .ansi span.sgr1{font-weight:bolder}html.theme--documenter-dark .ansi span.sgr2{font-weight:lighter}html.theme--documenter-dark .ansi span.sgr3{font-style:italic}html.theme--documenter-dark .ansi span.sgr4{text-decoration:underline}html.theme--documenter-dark .ansi span.sgr7{color:#1f2424;background-color:#fff}html.theme--documenter-dark .ansi span.sgr8{color:transparent}html.theme--documenter-dark .ansi span.sgr8 span{color:transparent}html.theme--documenter-dark .ansi span.sgr9{text-decoration:line-through}html.theme--documenter-dark .ansi span.sgr30{color:#242424}html.theme--documenter-dark .ansi span.sgr31{color:#f6705f}html.theme--documenter-dark .ansi span.sgr32{color:#4fb43a}html.theme--documenter-dark .ansi span.sgr33{color:#f4c72f}html.theme--documenter-dark .ansi span.sgr34{color:#7587f0}html.theme--documenter-dark .ansi span.sgr35{color:#bc89d3}html.theme--documenter-dark .ansi span.sgr36{color:#49b6ca}html.theme--documenter-dark .ansi span.sgr37{color:#b3bdbe}html.theme--documenter-dark .ansi span.sgr40{background-color:#242424}html.theme--documenter-dark .ansi span.sgr41{background-color:#f6705f}html.theme--documenter-dark .ansi span.sgr42{background-color:#4fb43a}html.theme--documenter-dark .ansi span.sgr43{background-color:#f4c72f}html.theme--documenter-dark .ansi span.sgr44{background-color:#7587f0}html.theme--documenter-dark .ansi span.sgr45{background-color:#bc89d3}html.theme--documenter-dark .ansi span.sgr46{background-color:#49b6ca}html.theme--documenter-dark .ansi span.sgr47{background-color:#b3bdbe}html.theme--documenter-dark .ansi span.sgr90{color:#92a0a2}html.theme--documenter-dark .ansi span.sgr91{color:#ff8674}html.theme--documenter-dark .ansi span.sgr92{color:#79d462}html.theme--documenter-dark .ansi span.sgr93{color:#ffe76b}html.theme--documenter-dark .ansi span.sgr94{color:#8a98ff}html.theme--documenter-dark .ansi span.sgr95{color:#d2a4e6}html.theme--documenter-dark .ansi span.sgr96{color:#6bc8db}html.theme--documenter-dark .ansi span.sgr97{color:#ecf0f1}html.theme--documenter-dark .ansi span.sgr100{background-color:#92a0a2}html.theme--documenter-dark .ansi span.sgr101{background-color:#ff8674}html.theme--documenter-dark .ansi span.sgr102{background-color:#79d462}html.theme--documenter-dark .ansi span.sgr103{background-color:#ffe76b}html.theme--documenter-dark .ansi span.sgr104{background-color:#8a98ff}html.theme--documenter-dark .ansi span.sgr105{background-color:#d2a4e6}html.theme--documenter-dark .ansi span.sgr106{background-color:#6bc8db}html.theme--documenter-dark .ansi span.sgr107{background-color:#ecf0f1}html.theme--documenter-dark code.language-julia-repl>span.hljs-meta{color:#4fb43a;font-weight:bolder}html.theme--documenter-dark .hljs{background:#2b2b2b;color:#f8f8f2}html.theme--documenter-dark .hljs-comment,html.theme--documenter-dark .hljs-quote{color:#d4d0ab}html.theme--documenter-dark .hljs-variable,html.theme--documenter-dark .hljs-template-variable,html.theme--documenter-dark .hljs-tag,html.theme--documenter-dark .hljs-name,html.theme--documenter-dark .hljs-selector-id,html.theme--documenter-dark .hljs-selector-class,html.theme--documenter-dark .hljs-regexp,html.theme--documenter-dark .hljs-deletion{color:#ffa07a}html.theme--documenter-dark .hljs-number,html.theme--documenter-dark .hljs-built_in,html.theme--documenter-dark .hljs-literal,html.theme--documenter-dark .hljs-type,html.theme--documenter-dark .hljs-params,html.theme--documenter-dark .hljs-meta,html.theme--documenter-dark .hljs-link{color:#f5ab35}html.theme--documenter-dark .hljs-attribute{color:#ffd700}html.theme--documenter-dark .hljs-string,html.theme--documenter-dark .hljs-symbol,html.theme--documenter-dark .hljs-bullet,html.theme--documenter-dark .hljs-addition{color:#abe338}html.theme--documenter-dark .hljs-title,html.theme--documenter-dark .hljs-section{color:#00e0e0}html.theme--documenter-dark .hljs-keyword,html.theme--documenter-dark .hljs-selector-tag{color:#dcc6e0}html.theme--documenter-dark .hljs-emphasis{font-style:italic}html.theme--documenter-dark .hljs-strong{font-weight:bold}@media screen and (-ms-high-contrast: active){html.theme--documenter-dark .hljs-addition,html.theme--documenter-dark .hljs-attribute,html.theme--documenter-dark .hljs-built_in,html.theme--documenter-dark .hljs-bullet,html.theme--documenter-dark .hljs-comment,html.theme--documenter-dark .hljs-link,html.theme--documenter-dark .hljs-literal,html.theme--documenter-dark .hljs-meta,html.theme--documenter-dark .hljs-number,html.theme--documenter-dark .hljs-params,html.theme--documenter-dark .hljs-string,html.theme--documenter-dark .hljs-symbol,html.theme--documenter-dark .hljs-type,html.theme--documenter-dark .hljs-quote{color:highlight}html.theme--documenter-dark .hljs-keyword,html.theme--documenter-dark .hljs-selector-tag{font-weight:bold}}html.theme--documenter-dark .hljs-subst{color:#f8f8f2}html.theme--documenter-dark .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--documenter-dark .search-result-link:hover,html.theme--documenter-dark .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--documenter-dark .search-result-link .property-search-result-badge,html.theme--documenter-dark .search-result-link .search-filter{transition:all 300ms}html.theme--documenter-dark .search-result-link:hover .property-search-result-badge,html.theme--documenter-dark .search-result-link:hover .search-filter,html.theme--documenter-dark .search-result-link:focus .property-search-result-badge,html.theme--documenter-dark .search-result-link:focus .search-filter{color:#333 !important;background-color:#f1f5f9 !important}html.theme--documenter-dark .property-search-result-badge,html.theme--documenter-dark .search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:whitesmoke;background-color:#33415580;border-radius:0.6rem}html.theme--documenter-dark .search-result-title{color:whitesmoke}html.theme--documenter-dark .search-result-highlight{background-color:greenyellow;color:black}html.theme--documenter-dark .search-divider{border-bottom:1px solid #5e6d6f50}html.theme--documenter-dark .w-100{width:100%}html.theme--documenter-dark .gap-2{gap:0.5rem}html.theme--documenter-dark .gap-4{gap:1rem} diff --git a/dev/assets/themes/documenter-light.css b/dev/assets/themes/documenter-light.css index 60a317a4..1262ec50 100644 --- a/dev/assets/themes/documenter-light.css +++ b/dev/assets/themes/documenter-light.css @@ -6,4 +6,4 @@ Website: https://highlightjs.org/ License: see project LICENSE Touched: 2021 -*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#F3F3F3;color:#444}.hljs-comment{color:#697070}.hljs-tag,.hljs-punctuation{color:#444a}.hljs-tag .hljs-name,.hljs-tag .hljs-attr{color:#444}.hljs-keyword,.hljs-attribute,.hljs-selector-tag,.hljs-meta .hljs-keyword,.hljs-doctag,.hljs-name{font-weight:bold}.hljs-type,.hljs-string,.hljs-number,.hljs-selector-id,.hljs-selector-class,.hljs-quote,.hljs-template-tag,.hljs-deletion{color:#880000}.hljs-title,.hljs-section{color:#880000;font-weight:bold}.hljs-regexp,.hljs-symbol,.hljs-variable,.hljs-template-variable,.hljs-link,.hljs-selector-attr,.hljs-operator,.hljs-selector-pseudo{color:#ab5656}.hljs-literal{color:#695}.hljs-built_in,.hljs-bullet,.hljs-code,.hljs-addition{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#38a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold} +*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#F3F3F3;color:#444}.hljs-comment{color:#697070}.hljs-tag,.hljs-punctuation{color:#444a}.hljs-tag .hljs-name,.hljs-tag .hljs-attr{color:#444}.hljs-keyword,.hljs-attribute,.hljs-selector-tag,.hljs-meta .hljs-keyword,.hljs-doctag,.hljs-name{font-weight:bold}.hljs-type,.hljs-string,.hljs-number,.hljs-selector-id,.hljs-selector-class,.hljs-quote,.hljs-template-tag,.hljs-deletion{color:#880000}.hljs-title,.hljs-section{color:#880000;font-weight:bold}.hljs-regexp,.hljs-symbol,.hljs-variable,.hljs-template-variable,.hljs-link,.hljs-selector-attr,.hljs-operator,.hljs-selector-pseudo{color:#ab5656}.hljs-literal{color:#695}.hljs-built_in,.hljs-bullet,.hljs-code,.hljs-addition{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#38a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}.gap-4{gap:1rem} diff --git a/dev/generated/Coloring/48ce2746.svg b/dev/generated/Coloring/48ce2746.svg new file mode 100644 index 00000000..a719b5eb --- /dev/null +++ b/dev/generated/Coloring/48ce2746.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/generated/Coloring/562ae81f.svg b/dev/generated/Coloring/562ae81f.svg deleted file mode 100644 index 322090fa..00000000 --- a/dev/generated/Coloring/562ae81f.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/Coloring/beec6420.svg b/dev/generated/Coloring/beec6420.svg deleted file mode 100644 index 1d20316b..00000000 --- a/dev/generated/Coloring/beec6420.svg +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/Coloring/c2dd93f2.svg b/dev/generated/Coloring/c2dd93f2.svg deleted file mode 100644 index 06136c5f..00000000 --- a/dev/generated/Coloring/c2dd93f2.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/Coloring/index.html b/dev/generated/Coloring/index.html index 6fb3f464..b4ad0310 100644 --- a/dev/generated/Coloring/index.html +++ b/dev/generated/Coloring/index.html @@ -5,7 +5,38 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...] -show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We construct the tensor network for the 3-coloring problem as

problem = Coloring{3}(graph);

Theory (can skip)

Type Coloring can be used for constructing the tensor network with optimized contraction order for a coloring problem. Let us use 3-coloring problem defined on vertices as an example. For a vertex $v$, we define the degrees of freedom $c_v\in\{1,2,3\}$ and a vertex tensor labelled by it as

\[W(v) = \left(\begin{matrix} +show_graph(graph; locs=locations, format=:svg)

Generic tensor network representation

We construct the tensor network for the 3-coloring problem as

problem = Coloring{3}(graph);

Theory (can skip)

Type Coloring can be used for constructing the tensor network with optimized contraction order for a coloring problem. Let us use 3-coloring problem defined on vertices as an example. For a vertex $v$, we define the degrees of freedom $c_v\in\{1,2,3\}$ and a vertex tensor labelled by it as

\[W(v) = \left(\begin{matrix} 1\\ 1\\ 1 @@ -20,9 +51,40 @@ vertex_color_map = Dict(0=>"red", 1=>"green", 2=>"blue") show_graph(graph; locs=locations, format=:svg, vertex_colors=[vertex_color_map[Int(c)] - for c in single_solution.c.data])Example block output

Let us try to solve the same issue on its line graph, a graph that generated by mapping an edge to a vertex and two edges sharing a common vertex will be connected.

linegraph = line_graph(graph)
+     for c in single_solution.c.data])

Let us try to solve the same issue on its line graph, a graph that generated by mapping an edge to a vertex and two edges sharing a common vertex will be connected.

linegraph = line_graph(graph)
 
 show_graph(linegraph; locs=[0.5 .* (locations[e.src] .+ locations[e.dst])
-     for e in edges(graph)], format=:svg)
Example block output

Let us construct the tensor network and see if there are solutions.

lineproblem = Coloring{3}(linegraph);
+     for e in edges(graph)], format=:svg)
Example block output

Let us construct the tensor network and see if there are solutions.

lineproblem = Coloring{3}(linegraph);
 
-num_of_coloring = solve(lineproblem, CountingMax())[]
(28.0, 1800.0)ₜ

You will see the maximum size 28 is smaller than the number of edges in the linegraph, meaning no solution for the 3-coloring on edges of a Petersen graph.


This page was generated using Literate.jl.

+num_of_coloring = solve(lineproblem, CountingMax())[]
(28.0, 1800.0)ₜ

You will see the maximum size 28 is smaller than the number of edges in the linegraph, meaning no solution for the 3-coloring on edges of a Petersen graph.


This page was generated using Literate.jl.

diff --git a/dev/generated/DominatingSet/97999130.svg b/dev/generated/DominatingSet/97999130.svg deleted file mode 100644 index ee5ccce7..00000000 --- a/dev/generated/DominatingSet/97999130.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/MaximalIS/f9ff3e5a.svg b/dev/generated/DominatingSet/f9ffae21.svg similarity index 58% rename from dev/generated/MaximalIS/f9ff3e5a.svg rename to dev/generated/DominatingSet/f9ffae21.svg index b18bf5ba..33b59c1e 100644 --- a/dev/generated/MaximalIS/f9ff3e5a.svg +++ b/dev/generated/DominatingSet/f9ffae21.svg @@ -1,44 +1,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + @@ -55,46 +18,15 @@ - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - + - - - - - - - @@ -111,46 +43,15 @@ - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - + + + - - - - @@ -167,46 +68,15 @@ - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - + + + @@ -222,47 +92,16 @@ - - - - + - - - - - - - + - - - - - - - + - - - - - - - - - - + - - - - - - - @@ -279,46 +118,15 @@ - - - - - - - - - - - - - - + + - - - - - - - - - - + - - - - - - - - - - - + @@ -334,47 +142,16 @@ - - - - + - - - - - - - - - - - + + - - - - - - - + - - - - - - - - - - - - - @@ -390,47 +167,16 @@ - - - - + - - - - - - - - - - - - - + - - - - - - - + - - - - - - - + - - - - @@ -446,47 +192,16 @@ - - - - + - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - + @@ -503,46 +218,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -559,45 +243,14 @@ - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - + + diff --git a/dev/generated/DominatingSet/index.html b/dev/generated/DominatingSet/index.html index bcc33e0c..3b5488fa 100644 --- a/dev/generated/DominatingSet/index.html +++ b/dev/generated/DominatingSet/index.html @@ -5,7 +5,38 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...] -show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We can use DominatingSet to construct the tensor network for solving the dominating set problem as

problem = DominatingSet(graph; optimizer=TreeSA());

Theory (can skip)

Let $G=(V,E)$ be the target graph that we want to solve. The tensor network representation map a vertex $v\in V$ to a boolean degree of freedom $s_v\in\{0, 1\}$. We defined the restriction on a vertex and its neighboring vertices $N(v)$:

\[T(x_v)_{s_1,s_2,\ldots,s_{|N(v)|},s_v} = \begin{cases} +show_graph(graph; locs=locations, format=:svg)

Generic tensor network representation

We can use DominatingSet to construct the tensor network for solving the dominating set problem as

problem = DominatingSet(graph; optimizer=TreeSA());

Theory (can skip)

Let $G=(V,E)$ be the target graph that we want to solve. The tensor network representation map a vertex $v\in V$ to a boolean degree of freedom $s_v\in\{0, 1\}$. We defined the restriction on a vertex and its neighboring vertices $N(v)$:

\[T(x_v)_{s_1,s_2,\ldots,s_{|N(v)|},s_v} = \begin{cases} 0 & s_1=s_2=\ldots=s_{|N(v)|}=s_v=0,\\ 1 & s_v=0,\\ x_v^{w_v} & \text{otherwise}, @@ -13,4 +44,4 @@ Space complexity: 2^8.0 Read-write complexity: 2^11.129926933510392

Solving properties

Counting properties

Domination polynomial

The graph polynomial for the dominating set problem is known as the domination polynomial (see arXiv:0905.2251). It is defined as

\[D(G, x) = \sum_{k=0}^{\gamma(G)} d_k x^k,\]

where $d_k$ is the number of dominating sets of size $k$ in graph $G=(V, E)$.

domination_polynomial = solve(problem, GraphPolynomial())[]
10∙x3 + 75∙x4 + 192∙x5 + 200∙x6 + 120∙x7 + 45∙x8 + 10∙x9 + x10

The domination number $\gamma(G)$ can be computed with the SizeMin property:

domination_number = solve(problem, SizeMin())[]
3.0ₜ

Similarly, we have its counting CountingMin:

counting_min_dominating_set = solve(problem, CountingMin())[]
(3.0, 10.0)ₜ

Configuration properties

finding minimum dominating set

One can enumerate all minimum dominating sets with the ConfigsMin property in the program.

min_configs = solve(problem, ConfigsMin())[].c
 
-all(c->is_dominating_set(graph, c), min_configs)
true
show_gallery(graph, (2, 5); locs=locations, vertex_configs=min_configs, format=:svg)
Example block output

Similarly, if one is only interested in computing one of the minimum dominating sets, one can use the graph property SingleConfigMin.


This page was generated using Literate.jl.

+all(c->is_dominating_set(graph, c), min_configs)
true
show_gallery(graph, (2, 5); locs=locations, vertex_configs=min_configs, format=:svg)
Example block output

Similarly, if one is only interested in computing one of the minimum dominating sets, one can use the graph property SingleConfigMin.


This page was generated using Literate.jl.

diff --git a/dev/generated/HyperSpinGlass/index.html b/dev/generated/HyperSpinGlass/index.html index 82eb7418..a4c81e2f 100644 --- a/dev/generated/HyperSpinGlass/index.html +++ b/dev/generated/HyperSpinGlass/index.html @@ -19,4 +19,4 @@ \end{cases}\]

and the vertex tensor $W^{(v)}$ (used to carry labels) is defined as

\[W^{(v)} = \left(\begin{matrix}1_v\\ 1_v\end{matrix}\right)\]

Solving properties

Minimum and maximum energies

Its ground state energy is -8.

Emin = solve(problem, SizeMin())[]
-8.0ₜ

While the state correspond to the highest energy has the ferromagnetic order.

Emax = solve(problem, SizeMax())[]
8.0ₜ

In this example, the spin configurations can be chosen to make all hyperedges having even or odd spin parity.

Counting properties

partition function and graph polynomial

The graph polynomial defined for the hyper-spin-glass problem is a Laurent polynomial

\[Z(G, w, x) = \sum_{k=E_{\rm min}}^{E_{\rm max}} c_k x^k,\]

where $E_{\rm min}$ and $E_{\rm max}$ are minimum and maximum energies, $c_k$ is the number of spin configurations with energy $k$. Let the inverse temperature $\beta = 2$, the partition function is

β = 2.0
 Z = solve(problem, PartitionFunction(β))[]
1.315167258498167e9

The infinite temperature partition function is the counting of all feasible configurations

solve(problem, PartitionFunction(0.0))[]
32768.0

Let $x = e^\beta$, it corresponds to the partition function of a spin glass at temperature $\beta^{-1}$.

poly = solve(problem, GraphPolynomial())[]
128.0∙x⁻⁸ + 1024.0∙x⁻⁶ + 3584.0∙x⁻⁴ + 7168.0∙x⁻² + 8960.0 + 7168.0∙x² + 3584.0∙x⁴ + 1024.0∙x⁶ + 128.0∙x⁸

Configuration properties

finding a ground state
ground_state = solve(problem, SingleConfigMin())[].c.data
 
-Emin_verify = hyperspinglass_energy(hyperedges, ground_state; weights)
-8

You should see a consistent result as above Emin.


This page was generated using Literate.jl.

+Emin_verify = hyperspinglass_energy(hyperedges, ground_state; weights)
-8

You should see a consistent result as above Emin.


This page was generated using Literate.jl.

diff --git a/dev/generated/IndependentSet/863bb5fa.svg b/dev/generated/IndependentSet/863bb5fa.svg deleted file mode 100644 index 226250af..00000000 --- a/dev/generated/IndependentSet/863bb5fa.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/IndependentSet/c140c961.svg b/dev/generated/IndependentSet/c140c961.svg deleted file mode 100644 index 4731038c..00000000 --- a/dev/generated/IndependentSet/c140c961.svg +++ /dev/null @@ -1,323 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/IndependentSet/c7dd602c.svg b/dev/generated/IndependentSet/c7dd602c.svg deleted file mode 100644 index b44d4415..00000000 --- a/dev/generated/IndependentSet/c7dd602c.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/IndependentSet/ce135f66.svg b/dev/generated/IndependentSet/ce135f66.svg new file mode 100644 index 00000000..a3e764f1 --- /dev/null +++ b/dev/generated/IndependentSet/ce135f66.svg @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/generated/IndependentSet/index.html b/dev/generated/IndependentSet/index.html index 50c807db..c4a4c0be 100644 --- a/dev/generated/IndependentSet/index.html +++ b/dev/generated/IndependentSet/index.html @@ -6,7 +6,38 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...] -show_graph(graph; locs=locations, format=:svg)Example block output

The graphical display is available in the following editors

Generic tensor network representation

The generic tensor network representation of the independent set problem can be constructed with IndependentSet.

problem = IndependentSet(graph; optimizer=TreeSA());

Here, the key word argument optimizer specifies the tensor network contraction order optimizer as a local search based optimizer TreeSA. The resulting contraction order optimized tensor network is contained in the code field of problem.

Theory (can skip)

Let $G=(V, E)$ be a graph with each vertex $v\in V$ associated with a weight $w_v$. To reduce the independent set problem on it to a tensor network contraction, we first map a vertex $v\in V$ to a label $s_v \in \{0, 1\}$ of dimension $2$, where we use $0$ ($1$) to denote a vertex absent (present) in the set. For each vertex $v$, we defined a parameterized rank-one tensor indexed by $s_v$ as

\[W(x_v^{w_v}) = \left(\begin{matrix} +show_graph(graph; locs=locations, format=:svg)

The graphical display is available in the following editors

Generic tensor network representation

The generic tensor network representation of the independent set problem can be constructed with IndependentSet.

problem = IndependentSet(graph; optimizer=TreeSA());

Here, the key word argument optimizer specifies the tensor network contraction order optimizer as a local search based optimizer TreeSA. The resulting contraction order optimized tensor network is contained in the code field of problem.

Theory (can skip)

Let $G=(V, E)$ be a graph with each vertex $v\in V$ associated with a weight $w_v$. To reduce the independent set problem on it to a tensor network contraction, we first map a vertex $v\in V$ to a label $s_v \in \{0, 1\}$ of dimension $2$, where we use $0$ ($1$) to denote a vertex absent (present) in the set. For each vertex $v$, we defined a parameterized rank-one tensor indexed by $s_v$ as

\[W(x_v^{w_v}) = \left(\begin{matrix} 1 \\ x_v^{w_v} \end{matrix}\right)\]

where $x_v$ is a variable associated with $v$. Similarly, for each edge $(u, v) \in E$, we define a matrix $B$ indexed by $s_u$ and $s_v$ as

\[B = \left(\begin{matrix} @@ -19,81 +50,126 @@ 10 30 30 - 5

Configuration properties

Find one best solution

We can use the bounded or unbounded SingleConfigMax to find one of the solutions with largest size. The unbounded (default) version uses a joint type of CountingTropical and ConfigSampler in computation, where CountingTropical finds the maximum size and ConfigSampler samples one of the best solutions. The bounded version uses the binary gradient back-propagation (see our paper) to compute the gradients. It requires caching intermediate states, but is often faster (on CPU) because it can use TropicalGEMM (see Performance Tips).

max_config = solve(problem, SingleConfigMax(; bounded=false))[]
(4.0, ConfigSampler{10, 1, 1}(0010111000))ₜ

The return value has type CountingTropical with its counting field having ConfigSampler type. The data field of ConfigSampler is a bit string that corresponds to the solution

single_solution = max_config.c.data
0010111000

This bit string should be read from left to right, with the i-th bit being 1 (0) to indicate the i-th vertex is present (absent) in the set. We can visualize this MIS with the following function.

show_graph(graph; locs=locations, format=:svg, vertex_colors=
-    [iszero(single_solution[i]) ? "white" : "red" for i=1:nv(graph)])
Example block output
Enumerate all solutions and best several solutions

We can use bounded or unbounded ConfigsMax to find all solutions with largest-K set sizes. In most cases, the bounded (default) version is preferred because it can reduce the memory usage significantly.

all_max_configs = solve(problem, ConfigsMax(; bounded=true))[]
(4.0, {1001001100, 0100100110, 0101010001, 1010000011, 0010111000})ₜ

The return value has type CountingTropical, while its counting field having type ConfigEnumerator. The data field of a ConfigEnumerator instance contains a vector of bit strings.

all_max_configs.c.data
5-element Vector{StaticBitVector{10, 1}}:
- 1001001100
+  5

Configuration properties

Find one best solution

We can use the bounded or unbounded SingleConfigMax to find one of the solutions with largest size. The unbounded (default) version uses a joint type of CountingTropical and ConfigSampler in computation, where CountingTropical finds the maximum size and ConfigSampler samples one of the best solutions. The bounded version uses the binary gradient back-propagation (see our paper) to compute the gradients. It requires caching intermediate states, but is often faster (on CPU) because it can use TropicalGEMM (see Performance Tips).

max_config = solve(problem, SingleConfigMax(; bounded=false))[]
(4.0, ConfigSampler{10, 1, 1}(0101010001))ₜ

The return value has type CountingTropical with its counting field having ConfigSampler type. The data field of ConfigSampler is a bit string that corresponds to the solution

single_solution = max_config.c.data
0101010001

This bit string should be read from left to right, with the i-th bit being 1 (0) to indicate the i-th vertex is present (absent) in the set. We can visualize this MIS with the following function.

show_graph(graph; locs=locations, format=:svg, vertex_colors=
+    [iszero(single_solution[i]) ? "white" : "red" for i=1:nv(graph)])
Enumerate all solutions and best several solutions

We can use bounded or unbounded ConfigsMax to find all solutions with largest-K set sizes. In most cases, the bounded (default) version is preferred because it can reduce the memory usage significantly.

all_max_configs = solve(problem, ConfigsMax(; bounded=true))[]
(4.0, {0100100110, 1010000011, 0010111000, 0101010001, 1001001100})ₜ

The return value has type CountingTropical, while its counting field having type ConfigEnumerator. The data field of a ConfigEnumerator instance contains a vector of bit strings.

all_max_configs.c.data
5-element Vector{StaticBitVector{10, 1}}:
  0100100110
- 0101010001
  1010000011
- 0010111000

These solutions can be visualized with the show_gallery function.

show_gallery(graph, (1, length(all_max_configs.c)); locs=locations, vertex_configs=all_max_configs.c, format=:svg)
Example block output

We can use ConfigsAll to enumerate all sets satisfying the independence constraint.

all_independent_sets = solve(problem, ConfigsAll())[]
{0000000000, 0000000100, 0000010000, 0000100000, 0000100100, 0000110000, 0001000000, 0001000100, 0001010000, 0000000010, 0000000110, 0000100010, 0000100110, 0000000001, 0000010001, 0001000001, 0001010001, 0000000011, 1000000000, 1000000100, 1001000000, 1001000100, 1000000010, 1000000110, 1000000001, 1001000001, 1000000011, 0000001000, 0000001100, 0000011000, 0000101000, 0000101100, 0000111000, 0001001000, 0001001100, 0001011000, 1000001000, 1000001100, 1001001000, 1001001100, 0100000000, 0100000100, 0100010000, 0100100000, 0100100100, 0100110000, 0101000000, 0101000100, 0101010000, 0100000010, 0100000110, 0100100010, 0100100110, 0100000001, 0100010001, 0101000001, 0101010001, 0100000011, 0010000000, 0010010000, 0010100000, 0010110000, 0010000010, 0010100010, 0010000001, 0010010001, 0010000011, 1010000000, 1010000010, 1010000001, 1010000011, 0010001000, 0010011000, 0010101000, 0010111000, 1010001000}

The return value has type ConfigEnumerator.

Sample solutions

It is often difficult to store all configurations in a vector. A more clever way to store the data is using the sum product tree format.

all_independent_sets_tree = solve(problem, ConfigsAll(; tree_storage=true))[]
+ (count = 76.0)
+ 0010111000
+ 0101010001
+ 1001001100

These solutions can be visualized with the show_gallery function.

show_gallery(graph, (1, length(all_max_configs.c)); locs=locations, vertex_configs=all_max_configs.c, format=:svg)
Example block output

We can use ConfigsAll to enumerate all sets satisfying the independence constraint.

all_independent_sets = solve(problem, ConfigsAll())[]
{0000000000, 0100000000, 0000001000, 0000010000, 0100010000, 0000011000, 0000000100, 0100000100, 0000001100, 0000000001, 0100000001, 0000010001, 0100010001, 1000000000, 1000001000, 1000000100, 1000001100, 1000000001, 0000000010, 0100000010, 0000000110, 0100000110, 0000000011, 0100000011, 1000000010, 1000000110, 1000000011, 0000100000, 0100100000, 0000101000, 0000110000, 0100110000, 0000111000, 0000100100, 0100100100, 0000101100, 0000100010, 0100100010, 0000100110, 0100100110, 0010000000, 0010001000, 0010010000, 0010011000, 0010000001, 0010010001, 1010000000, 1010001000, 1010000001, 0010000010, 0010000011, 1010000010, 1010000011, 0010100000, 0010101000, 0010110000, 0010111000, 0010100010, 0001000000, 0101000000, 0001001000, 0001010000, 0101010000, 0001011000, 0001000100, 0101000100, 0001001100, 0001000001, 0101000001, 0001010001, 0101010001, 1001000000, 1001001000, 1001000100, 1001001100, 1001000001}

The return value has type ConfigEnumerator.

Sample solutions

It is often difficult to store all configurations in a vector. A more clever way to store the data is using the sum product tree format.

all_independent_sets_tree = solve(problem, ConfigsAll(; tree_storage=true))[]
+ (count = 76.0)
 ├─ + (count = 58.0)
 │  ├─ + (count = 40.0)
-│  │  ├─ + (count = 36.0)
-│  │  │  ├─ + (count = 27.0)
-│  │  │  │  ├─ + (count = 18.0)
+│  │  ├─ + (count = 27.0)
+│  │  │  ├─ + (count = 18.0)
+│  │  │  │  ├─ + (count = 17.0)
 │  │  │  │  │  ⋮
 │  │  │  │  │  
-│  │  │  │  └─ * (count = 9.0)
+│  │  │  │  └─ * (count = 1.0)
 │  │  │  │     ⋮
 │  │  │  │     
-│  │  │  └─ * (count = 9.0)
-│  │  │     ├─ OnehotVec{10, 2}(7, 1)
-│  │  │     └─ * (count = 9.0)
+│  │  │  └─ + (count = 9.0)
+│  │  │     ├─ + (count = 8.0)
+│  │  │     │  ⋮
+│  │  │     │  
+│  │  │     └─ * (count = 1.0)
 │  │  │        ⋮
 │  │  │        
-│  │  └─ * (count = 4.0)
-│  │     ├─ * (count = 1.0)
-│  │     │  ├─ OnehotVec{10, 2}(1, 1)
-│  │     │  └─ OnehotVec{10, 2}(7, 1)
-│  │     └─ * (count = 4.0)
-│  │        ├─ + (count = 2.0)
+│  │  └─ * (count = 13.0)
+│  │     ├─ OnehotVec{10, 2}(5, 1)
+│  │     └─ + (count = 13.0)
+│  │        ├─ * (count = 9.0)
 │  │        │  ⋮
 │  │        │  
-│  │        └─ + (count = 2.0)
+│  │        └─ * (count = 4.0)
 │  │           ⋮
 │  │           
-│  └─ * (count = 18.0)
-│     ├─ + (count = 18.0)
-│     │  ├─ + (count = 17.0)
-│     │  │  ├─ + (count = 13.0)
+│  └─ + (count = 18.0)
+│     ├─ + (count = 13.0)
+│     │  ├─ + (count = 9.0)
+│     │  │  ├─ + (count = 8.0)
 │     │  │  │  ⋮
 │     │  │  │  
-│     │  │  └─ * (count = 4.0)
+│     │  │  └─ * (count = 1.0)
 │     │  │     ⋮
 │     │  │     
-│     │  └─ * (count = 1.0)
-│     │     ├─ OnehotVec{10, 2}(10, 1)
-│     │     └─ OnehotVec{10, 2}(9, 1)
-│     └─ OnehotVec{10, 2}(2, 1)
+│     │  └─ + (count = 4.0)
+│     │     ├─ + (count = 3.0)
+│     │     │  ⋮
+│     │     │  
+│     │     └─ * (count = 1.0)
+│     │        ⋮
+│     │        
+│     └─ * (count = 5.0)
+│        ├─ OnehotVec{10, 2}(5, 1)
+│        └─ + (count = 5.0)
+│           ├─ * (count = 4.0)
+│           │  ⋮
+│           │  
+│           └─ * (count = 1.0)
+│              ⋮
+│              
 └─ * (count = 18.0)
-   ├─ OnehotVec{10, 2}(3, 1)
+   ├─ OnehotVec{10, 2}(4, 1)
    └─ + (count = 18.0)
       ├─ + (count = 17.0)
       │  ├─ + (count = 13.0)
-      │  │  ├─ + (count = 9.0)
+      │  │  ├─ * (count = 9.0)
       │  │  │  ⋮
       │  │  │  
       │  │  └─ * (count = 4.0)
       │  │     ⋮
       │  │     
       │  └─ * (count = 4.0)
-      │     ├─ OnehotVec{10, 2}(7, 1)
-      │     └─ * (count = 4.0)
+      │     ├─ + (count = 2.0)
+      │     │  ⋮
+      │     │  
+      │     └─ + (count = 2.0)
       │        ⋮
       │        
       └─ * (count = 1.0)
-         ├─ OnehotVec{10, 2}(1, 1)
-         └─ OnehotVec{10, 2}(7, 1)
+         ├─ OnehotVec{10, 2}(10, 1)
+         └─ OnehotVec{10, 2}(1, 1)
 

The return value has the SumProductTree type. Its length corresponds to the number of configurations.

length(all_independent_sets_tree)
76.0

We can use Base.collect function to create a ConfigEnumerator or use generate_samples to generate samples from it.

collect(all_independent_sets_tree)
 
 generate_samples(all_independent_sets_tree, 10)
10-element Vector{StaticBitVector{10, 1}}:
+ 1000001100
+ 0000000010
+ 0000000011
+ 0100000011
+ 1000000011
+ 0010011000
+ 0010000001
  0001000000
- 0000000100
- 0001000001
- 0001000001
- 1000000000
- 0000101000
- 0000011000
- 1001001100
- 0101010001
- 0010100000

This page was generated using Literate.jl.

+ 1001000001 + 1001000001

This page was generated using Literate.jl.

diff --git a/dev/generated/Matching/7c793104.svg b/dev/generated/Matching/7c793104.svg deleted file mode 100644 index b9529924..00000000 --- a/dev/generated/Matching/7c793104.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/Matching/c9a3dba2.svg b/dev/generated/Matching/c9a3dba2.svg deleted file mode 100644 index bb1bded5..00000000 --- a/dev/generated/Matching/c9a3dba2.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/Matching/index.html b/dev/generated/Matching/index.html index 8a63032a..d269da2a 100644 --- a/dev/generated/Matching/index.html +++ b/dev/generated/Matching/index.html @@ -3,11 +3,73 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...] -show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We construct the tensor network for the matching problem by typing

problem = Matching(graph);

Theory (can skip)

Type Matching can be used for constructing the tensor network with optimized contraction order for a matching problem. We map an edge $(u, v) \in E$ to a label $\langle u, v\rangle \in \{0, 1\}$ in a tensor network, where 1 means two vertices of an edge are matched, 0 means otherwise. Then we define a tensor of rank $d(v) = |N(v)|$ on vertex $v$ such that,

\[W_{\langle v, n_1\rangle, \langle v, n_2 \rangle, \ldots, \langle v, n_{d(v)}\rangle} = \begin{cases} +show_graph(graph; locs=locations, format=:svg)

Generic tensor network representation

We construct the tensor network for the matching problem by typing

problem = Matching(graph);

Theory (can skip)

Type Matching can be used for constructing the tensor network with optimized contraction order for a matching problem. We map an edge $(u, v) \in E$ to a label $\langle u, v\rangle \in \{0, 1\}$ in a tensor network, where 1 means two vertices of an edge are matched, 0 means otherwise. Then we define a tensor of rank $d(v) = |N(v)|$ on vertex $v$ such that,

\[W_{\langle v, n_1\rangle, \langle v, n_2 \rangle, \ldots, \langle v, n_{d(v)}\rangle} = \begin{cases} 1, & \sum_{i=1}^{d(v)} \langle v, n_i \rangle \leq 1,\\ 0, & \text{otherwise}, \end{cases}\]

and a tensor of rank 1 on the bond

\[B_{\langle v, w\rangle} = \begin{cases} 1, & \langle v, w \rangle = 0 \\ x, & \langle v, w \rangle = 1, \end{cases}\]

where label $\langle v, w \rangle$ is equivalent to $\langle w,v\rangle$.

Solving properties

Maximum matching

Configuration properties

max_matching = solve(problem, SizeMax())[]
5.0ₜ

The largest number of matching is 5, which means we have a perfect matching (vertices are all paired).

matching polynomial

The graph polynomial defined for the matching problem is known as the matching polynomial. Here, we adopt the first definition in the wiki page.

\[M(G, x) = \sum\limits_{k=1}^{|V|/2} c_k x^k,\]

where $k$ is the number of matches, and coefficients $c_k$ are the corresponding counting.

matching_poly = solve(problem, GraphPolynomial())[]
1 + 15∙x + 75∙x2 + 145∙x3 + 90∙x4 + 6∙x5

Configuration properties

one of the perfect matches
match_config = solve(problem, SingleConfigMax())[]
(5.0, ConfigSampler{15, 1, 1}(010011000001001))ₜ

Let us show the result by coloring the matched edges to red

show_graph(graph; locs=locations, format=:svg, edge_colors=
-    [isone(match_config.c.data[i]) ? "red" : "black" for i=1:ne(graph)])
Example block output

where we use edges with red color to related pairs of matched vertices.


This page was generated using Literate.jl.

+ [isone(match_config.c.data[i]) ? "red" : "black" for i=1:ne(graph)])

where we use edges with red color to related pairs of matched vertices.


This page was generated using Literate.jl.

diff --git a/dev/generated/MaxCut/97eceb8a.svg b/dev/generated/MaxCut/97eceb8a.svg deleted file mode 100644 index 01739a34..00000000 --- a/dev/generated/MaxCut/97eceb8a.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/MaxCut/bfcbaa5b.svg b/dev/generated/MaxCut/bfcbaa5b.svg deleted file mode 100644 index 2971429a..00000000 --- a/dev/generated/MaxCut/bfcbaa5b.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/MaxCut/index.html b/dev/generated/MaxCut/index.html index 0feb481b..70407205 100644 --- a/dev/generated/MaxCut/index.html +++ b/dev/generated/MaxCut/index.html @@ -3,7 +3,38 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...] -show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We define the cutting problem as

problem = MaxCut(graph);

Theory (can skip)

We associated a vertex $v\in V$ with a boolean degree of freedom $s_v\in\{0, 1\}$. Then the maximum cutting problem can be encoded to tensor networks by mapping an edge $(i,j)\in E$ to an edge matrix labelled by $s_i$ and $s_j$

\[B(x_i, x_j, w_{ij}) = \left(\begin{matrix} +show_graph(graph; locs=locations, format=:svg)

Generic tensor network representation

We define the cutting problem as

problem = MaxCut(graph);

Theory (can skip)

We associated a vertex $v\in V$ with a boolean degree of freedom $s_v\in\{0, 1\}$. Then the maximum cutting problem can be encoded to tensor networks by mapping an edge $(i,j)\in E$ to an edge matrix labelled by $s_i$ and $s_j$

\[B(x_i, x_j, w_{ij}) = \left(\begin{matrix} 1 & x_{i}^{w_{ij}}\\ x_{j}^{w_{ij}} & 1 \end{matrix}\right),\]

where $w_{ij}$ is a real number associated with edge $(i, j)$ as the edge weight. If and only if the bipartition cuts on edge $(i, j)$, this tensor contributes a factor $x_{i}^{w_{ij}}$ or $x_{j}^{w_{ij}}$. Similarly, one can assign weights to vertices, which corresponds to the onsite energy terms in the spin glass. The vertex tensor is

\[W(x_i, w_i) = \left(\begin{matrix} @@ -12,4 +43,35 @@ \end{matrix}\right),\]

where $w_i$ is a real number associated with vertex $i$ as the vertex weight.

Its contraction time space complexity is $2^{{\rm tw}(G)}$, where ${\rm tw(G)}$ is the tree-width of $G$.

Solving properties

Maximum cut size $\gamma(G)$

max_cut_size = solve(problem, SizeMax())[]
12.0ₜ

Counting properties

graph polynomial

The graph polynomial defined for the cutting problem is

\[C(G, x) = \sum_{k=0}^{\gamma(G)} c_k x^k,\]

where $\gamma(G)$ is the maximum cut size, $c_k/2$ is the number of cuts of size $k$ in graph $G=(V,E)$. Since the variable $x$ is defined on edges, the coefficients of the polynomial is the number of configurations having different number of anti-parallel edges.

max_config = solve(problem, GraphPolynomial())[]
2 + 20∙x3 + 30∙x4 + 72∙x5 + 200∙x6 + 240∙x7 + 150∙x8 + 120∙x9 + 120∙x10 + 60∙x11 + 10∙x12

Configuration properties

finding one max cut solution
max_vertex_config = solve(problem, SingleConfigMax())[].c.data
 
 max_cut_size_verify = cut_size(graph, max_vertex_config)
0x000000000000000c

You should see a consistent result as above max_cut_size.

show_graph(graph; locs=locations, vertex_colors=[
-        iszero(max_vertex_config[i]) ? "white" : "red" for i=1:nv(graph)], format=:svg)
Example block output

where red vertices and white vertices are separated by the cut.


This page was generated using Literate.jl.

+ iszero(max_vertex_config[i]) ? "white" : "red" for i=1:nv(graph)], format=:svg)

where red vertices and white vertices are separated by the cut.


This page was generated using Literate.jl.

diff --git a/dev/generated/MaximalIS/678e44d9.svg b/dev/generated/MaximalIS/678e44d9.svg deleted file mode 100644 index 68685110..00000000 --- a/dev/generated/MaximalIS/678e44d9.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/MaximalIS/dded1bba.svg b/dev/generated/MaximalIS/6904a94b.svg similarity index 57% rename from dev/generated/MaximalIS/dded1bba.svg rename to dev/generated/MaximalIS/6904a94b.svg index c4c508f7..a06fd9a9 100644 --- a/dev/generated/MaximalIS/dded1bba.svg +++ b/dev/generated/MaximalIS/6904a94b.svg @@ -1,44 +1,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + @@ -55,46 +18,15 @@ - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - + - - - - - - - @@ -111,46 +43,15 @@ - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - + + + - - - - @@ -166,47 +67,16 @@ - - - - - - - - - - - - + + + - - - - - - - - - - - - - + - - - - - - - - - - - - + + @@ -223,46 +93,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - + - - - - @@ -279,46 +118,15 @@ - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - @@ -335,46 +143,15 @@ - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - + + + @@ -390,47 +167,16 @@ - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - + + - - - - - - - @@ -446,47 +192,16 @@ - - - - - - - - + + - - - - - - - - - - - + + - - - - - - - + - - - - - - - + - - - - @@ -503,46 +218,15 @@ - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - + + + + @@ -558,47 +242,16 @@ - - - - + - - - - - - - - - - - - - + - - - - - - - + - - - - - - - + - - - - @@ -615,46 +268,15 @@ - - - - - - - + - - - - - - - + - - - - - - - - - - - + + - - - - - - - - - - - - + + @@ -671,46 +293,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -726,47 +317,16 @@ - - - - - - - - - - - - - - - - + + + + - - - - - - - + - - - - - - - - - - + - - - - @@ -783,46 +343,15 @@ - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - + - - - - - - - - - - - + @@ -838,46 +367,15 @@ - - - - - - - - + + - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - + diff --git a/dev/generated/DominatingSet/a050b03b.svg b/dev/generated/MaximalIS/c466793e.svg similarity index 57% rename from dev/generated/DominatingSet/a050b03b.svg rename to dev/generated/MaximalIS/c466793e.svg index f8481350..328348ed 100644 --- a/dev/generated/DominatingSet/a050b03b.svg +++ b/dev/generated/MaximalIS/c466793e.svg @@ -1,44 +1,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + @@ -55,46 +18,15 @@ - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - + + @@ -111,46 +43,15 @@ - - - - - - - - - - - + + - - - - - - - - - - + - - - - - - - - - - + - - - - @@ -166,47 +67,16 @@ - - - - + - - - - - - - - - - - + + - - - - - - - + - - - - - - - - - - - - - @@ -222,47 +92,16 @@ - - - - + - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - + @@ -278,47 +117,16 @@ - - - - + - - - - - - - - - - - - - + - - - - - - - + - - - - - - - + - - - - @@ -334,47 +142,16 @@ - - - - - - - - + + - - - - - - - + - - - - - - - - - - - - - - - - + - - - - @@ -391,46 +168,15 @@ - - - - - - - + - - - - - - - - - - - + + - - - - - - - + - - - - - - - - - - @@ -447,46 +193,15 @@ - - - - - - - - - - - + + - - - - - - - - - - + - - - - - - - - - - + - - - - @@ -503,46 +218,15 @@ - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - + + @@ -559,45 +243,14 @@ - - - - - - - - - - - - - - + + - - - - - - - - - - + - - - - - - - - - - - + diff --git a/dev/generated/MaximalIS/index.html b/dev/generated/MaximalIS/index.html index 2198e11e..bda6eb56 100644 --- a/dev/generated/MaximalIS/index.html +++ b/dev/generated/MaximalIS/index.html @@ -5,14 +5,45 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...] -show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We can use MaximalIS to construct the tensor network for solving the maximal independent set problem as

problem = MaximalIS(graph; optimizer=TreeSA());

Theory (can skip)

Let $G=(V,E)$ be the target graph that we want to solve. The tensor network representation map a vertex $v\in V$ to a boolean degree of freedom $s_v\in\{0, 1\}$. We defined the restriction on its neighborhood $N(v)$:

\[T(x_v)_{s_1,s_2,\ldots,s_{|N(v)|},s_v} = \begin{cases} +show_graph(graph; locs=locations, format=:svg)

Generic tensor network representation

We can use MaximalIS to construct the tensor network for solving the maximal independent set problem as

problem = MaximalIS(graph; optimizer=TreeSA());

Theory (can skip)

Let $G=(V,E)$ be the target graph that we want to solve. The tensor network representation map a vertex $v\in V$ to a boolean degree of freedom $s_v\in\{0, 1\}$. We defined the restriction on its neighborhood $N(v)$:

\[T(x_v)_{s_1,s_2,\ldots,s_{|N(v)|},s_v} = \begin{cases} s_vx_v^{w_v} & s_1=s_2=\ldots=s_{|N(v)|}=0,\\ 1-s_v& \text{otherwise}. \end{cases}\]

The first case corresponds to all the neighborhood vertices of $v$ are not in $I_{m}$, then $v$ must be in $I_{m}$ and contribute a factor $x_{v}^{w_v}$, where $w_v$ is the weight of vertex $v$. Otherwise, if any of the neighboring vertices of $v$ is in $I_{m}$, $v$ must not be in $I_{m}$ by the independence requirement.

Its contraction time space complexity of a MaximalIS instance is no longer determined by the tree-width of the original graph $G$. It is often harder to contract this tensor network than to contract the one for regular independent set problem.

contraction_complexity(problem)
Time complexity: 2^11.011227255423254
 Space complexity: 2^8.0
 Read-write complexity: 2^11.129926933510392

Solving properties

Counting properties

maximal independence polynomial

The graph polynomial defined for the maximal independent set problem is

\[I_{\rm max}(G, x) = \sum_{k=0}^{\alpha(G)} b_k x^k,\]

where $b_k$ is the number of maximal independent sets of size $k$ in graph $G=(V, E)$.

maximal_indenpendence_polynomial = solve(problem, GraphPolynomial())[]
10∙x3 + 5∙x4

One can see the first several coefficients are 0, because it only counts the maximal independent sets, The minimum maximal independent set size is also known as the independent domination number. It can be computed with the SizeMin property:

independent_domination_number = solve(problem, SizeMin())[]
3.0ₜ

Similarly, we have its counting CountingMin:

counting_min_maximal_independent_set = solve(problem, CountingMin())[]
(3.0, 10.0)ₜ

Configuration properties

finding all maximal independent set
maximal_configs = solve(problem, ConfigsAll())[]
 
-all(c->is_maximal_independent_set(graph, c), maximal_configs)
true
show_gallery(graph, (3, 5); locs=locations, vertex_configs=maximal_configs, format=:svg)
Example block output

This result should be consistent with that given by the Bron Kerbosch algorithm on the complement of Petersen graph.

cliques = maximal_cliques(complement(graph))
15-element Vector{Vector{Int64}}:
+all(c->is_maximal_independent_set(graph, c), maximal_configs)
true
show_gallery(graph, (3, 5); locs=locations, vertex_configs=maximal_configs, format=:svg)
Example block output

This result should be consistent with that given by the Bron Kerbosch algorithm on the complement of Petersen graph.

cliques = maximal_cliques(complement(graph))
15-element Vector{Vector{Int64}}:
  [5, 6, 7, 3]
  [5, 6, 2]
  [5, 9, 2, 8]
@@ -29,4 +60,4 @@
  [1, 9, 8]
  [1, 3, 7]

For sparse graphs, the generic tensor network approach is usually much faster and memory efficient than the Bron Kerbosch algorithm.

finding minimum maximal independent set

It is the ConfigsMin property in the program.

minimum_maximal_configs = solve(problem, ConfigsMin())[].c
 
-show_gallery(graph, (2, 5); locs=locations, vertex_configs=minimum_maximal_configs, format=:svg)
Example block output

Similarly, if one is only interested in computing one of the minimum sets, one can use the graph property SingleConfigMin.


This page was generated using Literate.jl.

+show_gallery(graph, (2, 5); locs=locations, vertex_configs=minimum_maximal_configs, format=:svg)Example block output

Similarly, if one is only interested in computing one of the minimum sets, one can use the graph property SingleConfigMin.


This page was generated using Literate.jl.

diff --git a/dev/generated/PaintShop/3be843ef.svg b/dev/generated/PaintShop/ccf06b52.svg similarity index 92% rename from dev/generated/PaintShop/3be843ef.svg rename to dev/generated/PaintShop/ccf06b52.svg index 0e5cbc57..b1c3798b 100644 --- a/dev/generated/PaintShop/3be843ef.svg +++ b/dev/generated/PaintShop/ccf06b52.svg @@ -2,34 +2,34 @@ - + - + - + - + - + - + - + - + - + - + @@ -62,76 +62,76 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/dev/generated/PaintShop/fe3874dd.svg b/dev/generated/PaintShop/e63a2fee.svg similarity index 95% rename from dev/generated/PaintShop/fe3874dd.svg rename to dev/generated/PaintShop/e63a2fee.svg index a800afae..ee581a58 100644 --- a/dev/generated/PaintShop/fe3874dd.svg +++ b/dev/generated/PaintShop/e63a2fee.svg @@ -2,34 +2,34 @@ - + - + - + - + - + - + - + - + - + - + @@ -63,75 +63,75 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/dev/generated/PaintShop/index.html b/dev/generated/PaintShop/index.html index 7b089c14..928db5a5 100644 --- a/dev/generated/PaintShop/index.html +++ b/dev/generated/PaintShop/index.html @@ -30,7 +30,7 @@ end show_graph(graph; locs=locations, texts=string.(sequence), format=:svg, edge_colors= - [sequence[e.src] == sequence[e.dst] ? "blue" : "black" for e in edges(graph)])Example block output

Vertices connected by blue edges must have different colors, and the goal becomes a min-cut problem defined on black edges.

Generic tensor network representation

Let us construct the problem instance as bellow.

problem = PaintShop(sequence);

Theory (can skip)

Type PaintShop can be used for constructing the tensor network with optimized contraction order for solving a binary paint shop problem. To obtain its tensor network representation, we associating car $c_i$ (the $i$-th character in our example) with a degree of freedom $s_{c_i} \in \{0, 1\}$, where we use $0$ to denote the first appearance of a car is colored red and $1$ to denote the first appearance of a car is colored blue. For each black edges $(i, i+1)$, we define an edge tensor labeled by $(s_{c_i}, s_{c_{i+1}})$ as follows: If both cars on this edge are their first or second appearance

\[B^{\rm parallel} = \left(\begin{matrix} + [sequence[e.src] == sequence[e.dst] ? "blue" : "black" for e in edges(graph)])Example block output

Vertices connected by blue edges must have different colors, and the goal becomes a min-cut problem defined on black edges.

Generic tensor network representation

Let us construct the problem instance as bellow.

problem = PaintShop(sequence);

Theory (can skip)

Type PaintShop can be used for constructing the tensor network with optimized contraction order for solving a binary paint shop problem. To obtain its tensor network representation, we associating car $c_i$ (the $i$-th character in our example) with a degree of freedom $s_{c_i} \in \{0, 1\}$, where we use $0$ to denote the first appearance of a car is colored red and $1$ to denote the first appearance of a car is colored blue. For each black edges $(i, i+1)$, we define an edge tensor labeled by $(s_{c_i}, s_{c_{i+1}})$ as follows: If both cars on this edge are their first or second appearance

\[B^{\rm parallel} = \left(\begin{matrix} x & 1 \\ 1 & x \\ \end{matrix}\right),\]

otherwise,

\[B^{\rm anti-parallel} = \left(\begin{matrix} @@ -40,4 +40,4 @@ show_graph(graph; locs=locations, format=:svg, texts=string.(sequence), edge_colors=[sequence[e.src] == sequence[e.dst] ? "blue" : "black" for e in edges(graph)], - vertex_colors=[isone(c) ? "red" : "black" for c in painting1], vertex_text_color="white")Example block output

Since we have different choices of initial color, the number of best solution is 2.

The following function will check the solution and return you the number of color switches

num_paint_shop_color_switch(sequence, painting1)
4

This page was generated using Literate.jl.

+ vertex_colors=[isone(c) ? "red" : "black" for c in painting1], vertex_text_color="white")Example block output

Since we have different choices of initial color, the number of best solution is 2.

The following function will check the solution and return you the number of color switches

num_paint_shop_color_switch(sequence, painting1)
4

This page was generated using Literate.jl.

diff --git a/dev/generated/Satisfiability/index.html b/dev/generated/Satisfiability/index.html index f719905a..b426f209 100644 --- a/dev/generated/Satisfiability/index.html +++ b/dev/generated/Satisfiability/index.html @@ -14,4 +14,4 @@ x & x \\ 1 & x \end{matrix}\right) -\end{matrix}\right).\]

There is only one entry $(s_x, s_y, s_z) = (1, 0, 1)$ that makes this clause unsatisfied.

Solving properties

Satisfiability and its counting

The size of a satisfiability problem is defined by the number of satisfiable clauses.

num_satisfiable = solve(problem, SizeMax())[]
4.0ₜ

The GraphPolynomial of a satisfiability problem counts the number of solutions that k clauses satisfied.

num_satisfiable_count = solve(problem, GraphPolynomial())[]
12∙x2 + 56∙x3 + 60∙x4

Find one of the solutions

single_config = solve(problem, SingleConfigMax())[].c.data
0111111

One will see a bit vector printed. One can create an assignment and check the validity with the following statement:

satisfiable(cnf, Dict(zip(labels(problem), single_config)))
true

This page was generated using Literate.jl.

+\end{matrix}\right).\]

There is only one entry $(s_x, s_y, s_z) = (1, 0, 1)$ that makes this clause unsatisfied.

Solving properties

Satisfiability and its counting

The size of a satisfiability problem is defined by the number of satisfiable clauses.

num_satisfiable = solve(problem, SizeMax())[]
4.0ₜ

The GraphPolynomial of a satisfiability problem counts the number of solutions that k clauses satisfied.

num_satisfiable_count = solve(problem, GraphPolynomial())[]
12∙x2 + 56∙x3 + 60∙x4

Find one of the solutions

single_config = solve(problem, SingleConfigMax())[].c.data
1011011

One will see a bit vector printed. One can create an assignment and check the validity with the following statement:

satisfiable(cnf, Dict(zip(labels(problem), single_config)))
true

This page was generated using Literate.jl.

diff --git a/dev/generated/SetCovering/index.html b/dev/generated/SetCovering/index.html index 73d45af5..f1d1557d 100644 --- a/dev/generated/SetCovering/index.html +++ b/dev/generated/SetCovering/index.html @@ -17,4 +17,4 @@ 1 & \text{otherwise}. \end{cases}\]

This tensor means if none of the sets containing element $a$ are included, then this configuration is forbidden, One can check the contraction time space complexity of a SetCovering instance by typing:

contraction_complexity(problem)
Time complexity: 2^8.820178962415188
 Space complexity: 2^4.0
-Read-write complexity: 2^10.109830654278793

Solving properties

Counting properties

The "graph" polynomial

The graph polynomial for the set covering problem is defined as

\[P(S, x) = \sum_{k=0}^{|S|} c_k x^k,\]

where $c_k$ is the number of configurations having $k$ sets.

covering_polynomial = solve(problem, GraphPolynomial())[]
2∙x4 + 11∙x5 + 13∙x6 + 6∙x7 + x8

The minimum number of sets that covering the set of elements can be computed with the SizeMin property:

min_cover_size = solve(problem, SizeMin())[]
4.0ₜ

Similarly, we have its counting CountingMin:

counting_minimum_setcovering = solve(problem, CountingMin())[]
(4.0, 2.0)ₜ

Configuration properties

Finding minimum set covering

One can enumerate all minimum set covering with the ConfigsMin property in the program.

min_configs = solve(problem, ConfigsMin())[].c
{10101100, 01111000}

Hence the two optimal solutions are $\{z_1, z_3, z_5, z_6\}$ and $\{z_2, z_3, z_4, z_5\}$. The correctness of this result can be checked with the is_set_covering function.

all(c->is_set_covering(sets, c), min_configs)
true

Similarly, if one is only interested in computing one of the minimum set coverings, one can use the graph property SingleConfigMin.


This page was generated using Literate.jl.

+Read-write complexity: 2^10.109830654278793

Solving properties

Counting properties

The "graph" polynomial

The graph polynomial for the set covering problem is defined as

\[P(S, x) = \sum_{k=0}^{|S|} c_k x^k,\]

where $c_k$ is the number of configurations having $k$ sets.

covering_polynomial = solve(problem, GraphPolynomial())[]
2∙x4 + 11∙x5 + 13∙x6 + 6∙x7 + x8

The minimum number of sets that covering the set of elements can be computed with the SizeMin property:

min_cover_size = solve(problem, SizeMin())[]
4.0ₜ

Similarly, we have its counting CountingMin:

counting_minimum_setcovering = solve(problem, CountingMin())[]
(4.0, 2.0)ₜ

Configuration properties

Finding minimum set covering

One can enumerate all minimum set covering with the ConfigsMin property in the program.

min_configs = solve(problem, ConfigsMin())[].c
{01111000, 10101100}

Hence the two optimal solutions are $\{z_1, z_3, z_5, z_6\}$ and $\{z_2, z_3, z_4, z_5\}$. The correctness of this result can be checked with the is_set_covering function.

all(c->is_set_covering(sets, c), min_configs)
true

Similarly, if one is only interested in computing one of the minimum set coverings, one can use the graph property SingleConfigMin.


This page was generated using Literate.jl.

diff --git a/dev/generated/SetPacking/index.html b/dev/generated/SetPacking/index.html index 83cbe8cb..88f3b819 100644 --- a/dev/generated/SetPacking/index.html +++ b/dev/generated/SetPacking/index.html @@ -15,6 +15,6 @@ \end{matrix}\right)\]

where $x_s$ is a variable associated with $s$. For each unique element $a$, we defined the constraint over all sets containing it $N(a) = \{s | s \in S \land a\in s\}$:

\[B_{s_1,s_2,\ldots,s_{|N(a)|}} = \begin{cases} 0 & s_1+s_2+\ldots+s_{|N(a)|} > 1,\\ 1 & \text{otherwise}. -\end{cases}\]

This tensor means if in a configuration, two sets contain the element $a$, then this configuration is forbidden, One can check the contraction time space complexity of a SetPacking instance by typing:

contraction_complexity(problem)
Time complexity: 2^8.169925001442312
+\end{cases}\]

This tensor means if in a configuration, two sets contain the element $a$, then this configuration is forbidden, One can check the contraction time space complexity of a SetPacking instance by typing:

contraction_complexity(problem)
Time complexity: 2^8.247927513443585
 Space complexity: 2^4.0
-Read-write complexity: 2^9.047123912114026

Solving properties

Counting properties

The "graph" polynomial

The graph polynomial for the set packing problem is defined as

\[P(S, x) = \sum_{k=0}^{\alpha(S)} c_k x^k,\]

where $c_k$ is the number of configurations having $k$ sets, and $\alpha(S)$ is the maximum size of the packing.

packing_polynomial = solve(problem, GraphPolynomial())[]
1 + 8∙x + 8∙x2 + x3

The maximum number of sets that packing the set of elements can be computed with the SizeMax property:

max_packing_size = solve(problem, SizeMax())[]
3.0ₜ

Similarly, we have its counting CountingMax:

counting_maximum_set_packing = solve(problem, CountingMax())[]
(3.0, 1.0)ₜ

Configuration properties

Finding maximum set packing

One can enumerate all maximum set packing with the ConfigsMax property in the program.

max_configs = solve(problem, ConfigsMax())[].c
{10100100}

Hence the only optimal solution is $\{z_1, z_3, z_6\}$ that has size 3. The correctness of this result can be checked with the is_set_packing function.

all(c->is_set_packing(sets, c), max_configs)
true

Similarly, if one is only interested in computing one of the maximum set packing, one can use the graph property SingleConfigMax.


This page was generated using Literate.jl.

+Read-write complexity: 2^9.131856960608793

Solving properties

Counting properties

The "graph" polynomial

The graph polynomial for the set packing problem is defined as

\[P(S, x) = \sum_{k=0}^{\alpha(S)} c_k x^k,\]

where $c_k$ is the number of configurations having $k$ sets, and $\alpha(S)$ is the maximum size of the packing.

packing_polynomial = solve(problem, GraphPolynomial())[]
1 + 8∙x + 8∙x2 + x3

The maximum number of sets that packing the set of elements can be computed with the SizeMax property:

max_packing_size = solve(problem, SizeMax())[]
3.0ₜ

Similarly, we have its counting CountingMax:

counting_maximum_set_packing = solve(problem, CountingMax())[]
(3.0, 1.0)ₜ

Configuration properties

Finding maximum set packing

One can enumerate all maximum set packing with the ConfigsMax property in the program.

max_configs = solve(problem, ConfigsMax())[].c
{10100100}

Hence the only optimal solution is $\{z_1, z_3, z_6\}$ that has size 3. The correctness of this result can be checked with the is_set_packing function.

all(c->is_set_packing(sets, c), max_configs)
true

Similarly, if one is only interested in computing one of the maximum set packing, one can use the graph property SingleConfigMax.


This page was generated using Literate.jl.

diff --git a/dev/generated/SpinGlass/726b1976.svg b/dev/generated/SpinGlass/726b1976.svg deleted file mode 100644 index c92cd514..00000000 --- a/dev/generated/SpinGlass/726b1976.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/SpinGlass/dc38b2b2.svg b/dev/generated/SpinGlass/dc38b2b2.svg deleted file mode 100644 index 671a32ba..00000000 --- a/dev/generated/SpinGlass/dc38b2b2.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/SpinGlass/index.html b/dev/generated/SpinGlass/index.html index d34a193e..1addc6d6 100644 --- a/dev/generated/SpinGlass/index.html +++ b/dev/generated/SpinGlass/index.html @@ -3,7 +3,69 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...] -show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We define an anti-ferromagnetic spin glass problem as

problem = SpinGlass(graph; J=fill(-1, ne(graph)));

Theory (can skip)

The spin glass problem is reduced to the Cutting problem for solving. Let $G=(V,E)$ be a graph, the cutting problem can also be described by the following energy model

\[H^c = \sum_{ij \in E} C_{ij} ((1 - n_i) n_j + (1 - n_j) n_i) + \sum_{i \in V} w_i n_i,\]

where $n_i$ is the same as the partition index in the cutting problem, $C_{ij} = 2J_{ij}$ are edge weights and $w_i = -2h_i$ are vertex weights. The total energy is shifted by $-\sum_{ij\in E}J_{ij} + \sum_{i \in V} h_i$.

Solving properties

Minimum and maximum energies

Its ground state energy is -9.

Emin = solve(problem, SizeMin())[]
-9.0ₜ

While the state correspond to the highest energy has the ferromagnetic order.

Emax = solve(problem, SizeMax())[]
15.0ₜ

Counting properties

graph polynomial

The graph polynomial defined for the spin glass problem is a Laurent polynomial

\[Z(G, J, h, x) = \sum_{k=E_{\rm min}}^{E_{\rm max}} c_k x^k,\]

where $E_{\rm min}$ and $E_{\rm max}$ are minimum and maximum energies, $c_k$ is the number of spin configurations with energy $k$. Let $x = e^\beta$, it corresponds to the partition function of a spin glass at temperature $\beta^{-1}$.

partition_function = solve(problem, GraphPolynomial())[]
10∙x⁻⁹ + 60∙x⁻⁷ + 120∙x⁻⁵ + 120∙x⁻³ + 150∙x⁻¹ + 240∙x + 200∙x³ + 72∙x⁵ + 30∙x⁷ + 20∙x⁹ + 2∙x¹⁵

Configuration properties

finding a ground state
ground_state = solve(problem, SingleConfigMin())[].c.data
+show_graph(graph; locs=locations, format=:svg)

Generic tensor network representation

We define an anti-ferromagnetic spin glass problem as

problem = SpinGlass(graph; J=fill(-1, ne(graph)));

Theory (can skip)

The spin glass problem is reduced to the Cutting problem for solving. Let $G=(V,E)$ be a graph, the cutting problem can also be described by the following energy model

\[H^c = \sum_{ij \in E} C_{ij} ((1 - n_i) n_j + (1 - n_j) n_i) + \sum_{i \in V} w_i n_i,\]

where $n_i$ is the same as the partition index in the cutting problem, $C_{ij} = 2J_{ij}$ are edge weights and $w_i = -2h_i$ are vertex weights. The total energy is shifted by $-\sum_{ij\in E}J_{ij} + \sum_{i \in V} h_i$.

Solving properties

Minimum and maximum energies

Its ground state energy is -9.

Emin = solve(problem, SizeMin())[]
-9.0ₜ

While the state correspond to the highest energy has the ferromagnetic order.

Emax = solve(problem, SizeMax())[]
15.0ₜ

Counting properties

graph polynomial

The graph polynomial defined for the spin glass problem is a Laurent polynomial

\[Z(G, J, h, x) = \sum_{k=E_{\rm min}}^{E_{\rm max}} c_k x^k,\]

where $E_{\rm min}$ and $E_{\rm max}$ are minimum and maximum energies, $c_k$ is the number of spin configurations with energy $k$. Let $x = e^\beta$, it corresponds to the partition function of a spin glass at temperature $\beta^{-1}$.

partition_function = solve(problem, GraphPolynomial())[]
10∙x⁻⁹ + 60∙x⁻⁷ + 120∙x⁻⁵ + 120∙x⁻³ + 150∙x⁻¹ + 240∙x + 200∙x³ + 72∙x⁵ + 30∙x⁷ + 20∙x⁹ + 2∙x¹⁵

Configuration properties

finding a ground state
ground_state = solve(problem, SingleConfigMin())[].c.data
 
 Emin_verify = spinglass_energy(graph, ground_state)
9

You should see a consistent result as above Emin.

show_graph(graph; locs=locations, vertex_colors=[
-        iszero(ground_state[i]) ? "white" : "red" for i=1:nv(graph)], format=:svg)
Example block output

where a red vertex and a white vertex correspond to a spin having value 1 and 0 respectively.


This page was generated using Literate.jl.

+ iszero(ground_state[i]) ? "white" : "red" for i=1:nv(graph)], format=:svg)

where a red vertex and a white vertex correspond to a spin having value 1 and 0 respectively.


This page was generated using Literate.jl.

diff --git a/dev/generated/open/index.html b/dev/generated/open/index.html index 0e913680..3e1eca6b 100644 --- a/dev/generated/open/index.html +++ b/dev/generated/open/index.html @@ -26,4 +26,4 @@ [:, :, 2] = 4.0ₜ -Infₜ - 4.0ₜ -Infₜ

One can easily check this one also gets the correct marginal on vertices 1, 2 and 3. As a reminder, their computational hardness can be different, because the contraction order optimization program can optimize over open degrees of freedom.


This page was generated using Literate.jl.

+ 4.0ₜ -Infₜ

One can easily check this one also gets the correct marginal on vertices 1, 2 and 3. As a reminder, their computational hardness can be different, because the contraction order optimization program can optimize over open degrees of freedom.


This page was generated using Literate.jl.

diff --git a/dev/generated/saveload/index.html b/dev/generated/saveload/index.html index ad4cec73..3385f7ea 100644 --- a/dev/generated/saveload/index.html +++ b/dev/generated/saveload/index.html @@ -3,49 +3,71 @@ problem = IndependentSet(Graphs.smallgraph(:petersen)) -all_independent_sets = solve(problem, ConfigsAll())[]
{0000000000, 0100000000, 0010000000, 0000100000, 0100100000, 0010100000, 0000000001, 0100000001, 0010000001, 0000010000, 0100010000, 0010010000, 0000110000, 0100110000, 0010110000, 0000010001, 0100010001, 0010010001, 0000000010, 0100000010, 0010000010, 0000100010, 0100100010, 0010100010, 0000000011, 0100000011, 0010000011, 1000000000, 1010000000, 1000000001, 1010000001, 1000000010, 1010000010, 1000000011, 1010000011, 0000001000, 0010001000, 0000101000, 0010101000, 0000011000, 0010011000, 0000111000, 0010111000, 1000001000, 1010001000, 0001000000, 0101000000, 0001000001, 0101000001, 0001010000, 0101010000, 0001010001, 0101010001, 1001000000, 1001000001, 0001001000, 0001011000, 1001001000, 0000000100, 0100000100, 0000100100, 0100100100, 0000000110, 0100000110, 0000100110, 0100100110, 1000000100, 1000000110, 0000001100, 0000101100, 1000001100, 0001000100, 0101000100, 1001000100, 0001001100, 1001001100}

The return value has type ConfigEnumerator. We can use save_configs and load_configs to save and read a ConfigEnumerator instance to the disk.

filename = tempname()
+all_independent_sets = solve(problem, ConfigsAll())[]
{0000000000, 0010000000, 0100000000, 0000000001, 0010000001, 0100000001, 0000100000, 0010100000, 0100100000, 0000000010, 0010000010, 0100000010, 0000000011, 0010000011, 0100000011, 0000100010, 0010100010, 0100100010, 0001000000, 0101000000, 0001000001, 0101000001, 0000001000, 0010001000, 0000101000, 0010101000, 0001001000, 1000000000, 1010000000, 1000000001, 1010000001, 1000000010, 1010000010, 1000000011, 1010000011, 1001000000, 1001000001, 1000001000, 1010001000, 1001001000, 0000000100, 0100000100, 0000100100, 0100100100, 0000000110, 0100000110, 0000100110, 0100100110, 0001000100, 0101000100, 0000001100, 0000101100, 0001001100, 1000000100, 1000000110, 1001000100, 1000001100, 1001001100, 0000010000, 0010010000, 0100010000, 0000010001, 0010010001, 0100010001, 0000110000, 0010110000, 0100110000, 0001010000, 0101010000, 0001010001, 0101010001, 0000011000, 0010011000, 0000111000, 0010111000, 0001011000}

The return value has type ConfigEnumerator. We can use save_configs and load_configs to save and read a ConfigEnumerator instance to the disk.

filename = tempname()
 
 save_configs(filename, all_independent_sets; format=:binary)
 
-loaded_sets = load_configs(filename; format=:binary, bitlength=10)
{0000000000, 0100000000, 0010000000, 0000100000, 0100100000, 0010100000, 0000000001, 0100000001, 0010000001, 0000010000, 0100010000, 0010010000, 0000110000, 0100110000, 0010110000, 0000010001, 0100010001, 0010010001, 0000000010, 0100000010, 0010000010, 0000100010, 0100100010, 0010100010, 0000000011, 0100000011, 0010000011, 1000000000, 1010000000, 1000000001, 1010000001, 1000000010, 1010000010, 1000000011, 1010000011, 0000001000, 0010001000, 0000101000, 0010101000, 0000011000, 0010011000, 0000111000, 0010111000, 1000001000, 1010001000, 0001000000, 0101000000, 0001000001, 0101000001, 0001010000, 0101010000, 0001010001, 0101010001, 1001000000, 1001000001, 0001001000, 0001011000, 1001001000, 0000000100, 0100000100, 0000100100, 0100100100, 0000000110, 0100000110, 0000100110, 0100100110, 1000000100, 1000000110, 0000001100, 0000101100, 1000001100, 0001000100, 0101000100, 1001000100, 0001001100, 1001001100}
Note

When loading the data in the binary format, bit string length information bitlength is required.

For the SumProductTree type output, we can use save_sumproduct and load_sumproduct to save and load serialized data.

all_independent_sets_tree = solve(problem, ConfigsAll(; tree_storage=true))[]
+loaded_sets = load_configs(filename; format=:binary, bitlength=10)
{0000000000, 0010000000, 0100000000, 0000000001, 0010000001, 0100000001, 0000100000, 0010100000, 0100100000, 0000000010, 0010000010, 0100000010, 0000000011, 0010000011, 0100000011, 0000100010, 0010100010, 0100100010, 0001000000, 0101000000, 0001000001, 0101000001, 0000001000, 0010001000, 0000101000, 0010101000, 0001001000, 1000000000, 1010000000, 1000000001, 1010000001, 1000000010, 1010000010, 1000000011, 1010000011, 1001000000, 1001000001, 1000001000, 1010001000, 1001001000, 0000000100, 0100000100, 0000100100, 0100100100, 0000000110, 0100000110, 0000100110, 0100100110, 0001000100, 0101000100, 0000001100, 0000101100, 0001001100, 1000000100, 1000000110, 1001000100, 1000001100, 1001001100, 0000010000, 0010010000, 0100010000, 0000010001, 0010010001, 0100010001, 0000110000, 0010110000, 0100110000, 0001010000, 0101010000, 0001010001, 0101010001, 0000011000, 0010011000, 0000111000, 0010111000, 0001011000}
Note

When loading the data in the binary format, bit string length information bitlength is required.

For the SumProductTree type output, we can use save_sumproduct and load_sumproduct to save and load serialized data.

all_independent_sets_tree = solve(problem, ConfigsAll(; tree_storage=true))[]
 
 save_sumproduct(filename, all_independent_sets_tree)
 
 loaded_sets_tree = load_sumproduct(filename)
+ (count = 76.0)
-├─ + (count = 75.0)
-│  ├─ + (count = 74.0)
-│  │  ├─ + (count = 73.0)
-│  │  │  ├─ + (count = 71.0)
-│  │  │  │  ├─ + (count = 70.0)
+├─ + (count = 58.0)
+│  ├─ + (count = 53.0)
+│  │  ├─ + (count = 40.0)
+│  │  │  ├─ + (count = 27.0)
+│  │  │  │  ├─ + (count = 26.0)
 │  │  │  │  │  ⋮
 │  │  │  │  │  
 │  │  │  │  └─ * (count = 1.0)
 │  │  │  │     ⋮
 │  │  │  │     
-│  │  │  └─ * (count = 2.0)
-│  │  │     ├─ + (count = 2.0)
-│  │  │     │  ⋮
-│  │  │     │  
-│  │  │     └─ * (count = 1.0)
+│  │  │  └─ * (count = 13.0)
+│  │  │     ├─ OnehotVec{10, 2}(1, 1)
+│  │  │     └─ + (count = 13.0)
 │  │  │        ⋮
 │  │  │        
-│  │  └─ * (count = 1.0)
-│  │     ├─ OnehotVec{10, 2}(1, 1)
-│  │     └─ * (count = 1.0)
-│  │        ├─ OnehotVec{10, 2}(4, 1)
-│  │        └─ OnehotVec{10, 2}(8, 1)
-│  └─ * (count = 1.0)
-│     ├─ OnehotVec{10, 2}(4, 1)
-│     └─ * (count = 1.0)
-│        ├─ OnehotVec{10, 2}(7, 1)
-│        └─ OnehotVec{10, 2}(8, 1)
-└─ * (count = 1.0)
-   ├─ OnehotVec{10, 2}(1, 1)
-   └─ * (count = 1.0)
-      ├─ OnehotVec{10, 2}(4, 1)
+│  │  └─ * (count = 13.0)
+│  │     ├─ OnehotVec{10, 2}(8, 1)
+│  │     └─ + (count = 13.0)
+│  │        ├─ + (count = 12.0)
+│  │        │  ⋮
+│  │        │  
+│  │        └─ * (count = 1.0)
+│  │           ⋮
+│  │           
+│  └─ * (count = 5.0)
+│     ├─ * (count = 1.0)
+│     │  ├─ OnehotVec{10, 2}(1, 1)
+│     │  └─ OnehotVec{10, 2}(8, 1)
+│     └─ + (count = 5.0)
+│        ├─ + (count = 4.0)
+│        │  ├─ + (count = 3.0)
+│        │  │  ⋮
+│        │  │  
+│        │  └─ OnehotVec{10, 2}(7, 1)
+│        └─ * (count = 1.0)
+│           ├─ OnehotVec{10, 2}(4, 1)
+│           └─ OnehotVec{10, 2}(7, 1)
+└─ * (count = 18.0)
+   ├─ OnehotVec{10, 2}(6, 1)
+   └─ + (count = 18.0)
+      ├─ + (count = 17.0)
+      │  ├─ + (count = 13.0)
+      │  │  ├─ * (count = 9.0)
+      │  │  │  ⋮
+      │  │  │  
+      │  │  └─ * (count = 4.0)
+      │  │     ⋮
+      │  │     
+      │  └─ * (count = 4.0)
+      │     ├─ * (count = 4.0)
+      │     │  ⋮
+      │     │  
+      │     └─ OnehotVec{10, 2}(7, 1)
       └─ * (count = 1.0)
-         ├─ OnehotVec{10, 2}(7, 1)
-         └─ OnehotVec{10, 2}(8, 1)
+         ├─ OnehotVec{10, 2}(4, 1)
+         └─ OnehotVec{10, 2}(7, 1)
 

Loading solutions to python

The following python script loads and unpacks the solutions as a numpy array from a :binary format file.

import numpy as np
 
 def loadfile(filename:str, bitlength:int):
@@ -57,4 +79,4 @@
     print("number of solutions = %d"%(len(res)))
     return res  # in big endian format
 
-res = loadfile(filename, 10)
Note

Check section Maximal independent set problem for solution space properties related the maximal independent sets. That example also contains using cases of finding solution space properties related to minimum sizes:


This page was generated using Literate.jl.

+res = loadfile(filename, 10)
Note

Check section Maximal independent set problem for solution space properties related the maximal independent sets. That example also contains using cases of finding solution space properties related to minimum sizes:


This page was generated using Literate.jl.

diff --git a/dev/generated/weighted/b95f3e0a.svg b/dev/generated/weighted/b95f3e0a.svg deleted file mode 100644 index 7f9973c8..00000000 --- a/dev/generated/weighted/b95f3e0a.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/weighted/273e3eea.svg b/dev/generated/weighted/e47c6a53.svg similarity index 54% rename from dev/generated/weighted/273e3eea.svg rename to dev/generated/weighted/e47c6a53.svg index 5a75e727..c0549d6d 100644 --- a/dev/generated/weighted/273e3eea.svg +++ b/dev/generated/weighted/e47c6a53.svg @@ -1,44 +1,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + @@ -55,46 +18,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -111,46 +43,15 @@ - - - - - - - - - - + - - - - - - - + - - - - - - - - - - + - - - - - - - - + @@ -167,46 +68,15 @@ - - - - - - - - - - + - - - - - - - + - - - - - - - - - - + - - - - - - - - + @@ -223,46 +93,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -279,45 +118,14 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/weighted/index.html b/dev/generated/weighted/index.html index fa8bd850..6bffb90d 100644 --- a/dev/generated/weighted/index.html +++ b/dev/generated/weighted/index.html @@ -6,7 +6,38 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...] show_graph(graph; locs=locations, format=:svg, vertex_colors= - [iszero(max_config_weighted.c.data[i]) ? "white" : "red" for i=1:nv(graph)])Example block output

The only solution space property that can not be defined for general real-weighted (not including integer-weighted) graphs is the GraphPolynomial.

For the weighted MIS problem, a useful solution space property is the "energy spectrum", i.e. the largest several configurations and their weights. We can use the solution space property is SizeMax(10) to compute the largest 10 weights.

spectrum = solve(problem, SizeMax(10))[]
ExtendedTropical{10, Tropical{Float64}}(Tropical{Float64}[20.0ₜ, 20.0ₜ, 20.0ₜ, 21.0ₜ, 21.0ₜ, 22.0ₜ, 22.0ₜ, 22.0ₜ, 23.0ₜ, 24.0ₜ])

The return value has type ExtendedTropical, which contains one field orders.

spectrum.orders
10-element Vector{Tropical{Float64}}:
+          [iszero(max_config_weighted.c.data[i]) ? "white" : "red" for i=1:nv(graph)])

The only solution space property that can not be defined for general real-weighted (not including integer-weighted) graphs is the GraphPolynomial.

For the weighted MIS problem, a useful solution space property is the "energy spectrum", i.e. the largest several configurations and their weights. We can use the solution space property is SizeMax(10) to compute the largest 10 weights.

spectrum = solve(problem, SizeMax(10))[]
ExtendedTropical{10, Tropical{Float64}}(Tropical{Float64}[20.0ₜ, 20.0ₜ, 20.0ₜ, 21.0ₜ, 21.0ₜ, 22.0ₜ, 22.0ₜ, 22.0ₜ, 23.0ₜ, 24.0ₜ])

The return value has type ExtendedTropical, which contains one field orders.

spectrum.orders
10-element Vector{Tropical{Float64}}:
  20.0ₜ
  20.0ₜ
  20.0ₜ
@@ -16,9 +47,9 @@
  22.0ₜ
  22.0ₜ
  23.0ₜ
- 24.0ₜ

We can see the order is a vector of Tropical numbers. Similarly, we can get weighted independent sets with maximum 5 sizes as follows.

max5_configs = solve(problem, SingleConfigMax(5))[]
ExtendedTropical{5, CountingTropical{Float64, ConfigSampler{10, 1, 1}}}(CountingTropical{Float64, ConfigSampler{10, 1, 1}}[(22.0, ConfigSampler{10, 1, 1}(0101010001))ₜ, (22.0, ConfigSampler{10, 1, 1}(0000100110))ₜ, (22.0, ConfigSampler{10, 1, 1}(0010000011))ₜ, (23.0, ConfigSampler{10, 1, 1}(1010000011))ₜ, (24.0, ConfigSampler{10, 1, 1}(0100100110))ₜ])

The return value also has type ExtendedTropical, but this time the element type of orders has been changed to CountingTropical{Float64,ConfigSampler}.

max5_configs.orders
5-element Vector{CountingTropical{Float64, ConfigSampler{10, 1, 1}}}:
+ 24.0ₜ

We can see the order is a vector of Tropical numbers. Similarly, we can get weighted independent sets with maximum 5 sizes as follows.

max5_configs = solve(problem, SingleConfigMax(5))[]
ExtendedTropical{5, CountingTropical{Float64, ConfigSampler{10, 1, 1}}}(CountingTropical{Float64, ConfigSampler{10, 1, 1}}[(22.0, ConfigSampler{10, 1, 1}(0101010001))ₜ, (22.0, ConfigSampler{10, 1, 1}(0010000011))ₜ, (22.0, ConfigSampler{10, 1, 1}(0000100110))ₜ, (23.0, ConfigSampler{10, 1, 1}(1010000011))ₜ, (24.0, ConfigSampler{10, 1, 1}(0100100110))ₜ])

The return value also has type ExtendedTropical, but this time the element type of orders has been changed to CountingTropical{Float64,ConfigSampler}.

max5_configs.orders
5-element Vector{CountingTropical{Float64, ConfigSampler{10, 1, 1}}}:
  (22.0, ConfigSampler{10, 1, 1}(0101010001))ₜ
- (22.0, ConfigSampler{10, 1, 1}(0000100110))ₜ
  (22.0, ConfigSampler{10, 1, 1}(0010000011))ₜ
+ (22.0, ConfigSampler{10, 1, 1}(0000100110))ₜ
  (23.0, ConfigSampler{10, 1, 1}(1010000011))ₜ
- (24.0, ConfigSampler{10, 1, 1}(0100100110))ₜ

Let us visually check these configurations

show_gallery(graph, (1, 5); locs=locations, format=:svg, vertex_configs=[max5_configs.orders[k].c.data for k=1:5])
Example block output

This page was generated using Literate.jl.

+ (24.0, ConfigSampler{10, 1, 1}(0100100110))ₜ

Let us visually check these configurations

show_gallery(graph, (1, 5); locs=locations, format=:svg, vertex_configs=[max5_configs.orders[k].c.data for k=1:5])
Example block output

This page was generated using Literate.jl.

diff --git a/dev/gist/index.html b/dev/gist/index.html index 9cd9b7d1..34732ff9 100644 --- a/dev/gist/index.html +++ b/dev/gist/index.html @@ -112,4 +112,4 @@ println("one of the optimal configurations is $(mis_config(optimized_code; all=false)[].c.data)") # direct enumeration of configurations can be very slow; please check the bounding version in our Github repo. -println("all optimal configurations are $(mis_config(optimized_code; all=true)[].c)") +println("all optimal configurations are $(mis_config(optimized_code; all=true)[].c)") diff --git a/dev/index.html b/dev/index.html index 0bbc5269..45d1d08d 100644 --- a/dev/index.html +++ b/dev/index.html @@ -17,4 +17,4 @@ 0-dimensional Array{Polynomial{BigInt, :x}, 0}: Polynomial(1 + 20*x + 160*x^2 + 659*x^3 + 1500*x^4 + 1883*x^5 + 1223*x^6 + 347*x^7 + 25*x^8)

Here the main function solve takes three input arguments, the problem instance of type IndependentSet, the property instance of type GraphPolynomial and an optional key word argument usecuda to decide use GPU or not. If one wants to use GPU to accelerate the computation, the using CUDA statement must uncommented.

The problem instance takes four arguments to initialize, the only positional argument is the graph instance that one wants to solve, the key word argument optimizer is for specifying the tensor network optimization algorithm, the key word argument weights is for specifying the weights of vertices as either a vector or NoWeight(). The keyword argument openvertices is a tuple of labels for specifying the degrees of freedom not summed over, and fixedvertices is a label-value dictionary for specifying the fixed values of the degree of freedoms. Here, we use TreeSA method as the tensor network optimizer, and leave weights and openvertices the default values. The TreeSA method finds the best contraction order in most of our applications, while the default GreedyMethod runs the fastest.

The first execution of this function will be a bit slow due to Julia's just in time compiling. The subsequent runs will be fast. The following diagram lists possible combinations of input arguments, where functions in the Graph are mainly defined in the package Graphs, and the rest can be found in this package.

-

⠀ You can find many examples in this documentation, a good one to start with is Independent set problem.

+

⠀ You can find many examples in this documentation, a good one to start with is Independent set problem.

diff --git a/dev/performancetips/index.html b/dev/performancetips/index.html index 9485fab0..f19973cf 100644 --- a/dev/performancetips/index.html +++ b/dev/performancetips/index.html @@ -80,4 +80,4 @@ julia> solve(problem, SizeMax(), usecuda=true) 0-dimensional CuArray{TropicalF64, 0, CUDA.Mem.DeviceBuffer}: -53.0ₜ

Solution space properties computable on GPU includes

Benchmarks

We run a single thread benchmark on central processing units (CPU) Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz, and its CUDA version on a GPU Tesla V100-SXM2 16G. The results are summarized in the following plot. The benchmark code can be found in our paper repository.

benchmark-independent-set This benchmark results is for computing different solution space properties of independent sets of random three-regular graphs with different tensor element types. The time in these plots only includes tensor network contraction, without taking into account the contraction order finding and just-in-time compilation time. Legends are properties, algebra, and devices that we used in the computation; one can find the corresponding computed solution space property in Table 1 in the paper.

The graphs in all benchmarks are random three-regular graphs, which have treewidth that is asymptotically smaller than $|V|/6$. In this benchmark, we do not include traditional algorithms for finding the MIS sizes such as branching or dynamic programming. To the best of our knowledge, these algorithms are not suitable for computing most of the solution space properties mentioned in this paper. The main goal of this section is to show the relative computation time for calculating different solution space properties.

Panel (a) shows the time and space complexity of tensor network contraction for different graph sizes. The contraction order is obtained using the TreeSA algorithm that implemented in OMEinsumContractionOrders. If we assume our contraction-order finding program has found the optimal treewidth, which is very likely to be true, the space complexity is the same as the treewidth of the problem graph. Slicing technique has been used for graphs with space complexity greater than $2^{27}$ (above the yellow dashed line) to fit the computation into a 16GB memory. One can see that all the computation times in panels (b), (c), and (d) have a strong correlation with the predicted time and space complexity. While in panel (d), the computation time of configuration enumeration also strongly correlates with other factors such as the configuration space size. Among these benchmarks, computational tasks with data types real numbers, complex numbers, or Tropical numbers (CPU only) can utilize fast basic linear algebra subprograms (BLAS) functions. These tasks usually compute much faster than ones with other element types in the same category. Immutable data types with no reference to other values can be compiled to GPU devices that run much faster than CPUs in all cases when the problem scale is big enough. These data types do not include those defined in Polynomial, ConfigEnumerator, ExtendedTropical and SumProductTree or a data type containing them as a part. In panel (c), one can see the Fourier transformation-based method is the fastest in computing the independence polynomial, but it may suffer from round-off errors. The finite field (GF(p)) approach is the only method that does not have round-off errors and can be run on a GPU. In panel (d), one can see the technique to bound the enumeration space (see paper) improves the performance for more than one order of magnitude in enumerating the MISs. The bounding technique can also reduce the memory usage significantly, without which the largest computable graph size is only $\sim150$ on a device with 32GB main memory.

We show the benchmark of computing the maximal independent set properties on 3-regular graphs in the following plot, including a comparison to the Bron-Kerbosch algorithm from Julia package Graphs

benchmark-maximal-independent-set

In this plot, benchmarks of computing different solution space properties of the maximal independent sets (ISs) problem on random three regular graphs at different sizes.

Panel (a) shows the space and time complexities of tensor contraction, which are typically larger than those for the independent set problem. In panel (b), one can see counting maximal independent sets are much more efficient than enumerating them, while our generic tensor network approach runs slightly faster than the Bron-Kerbosch approach in enumerating all maximal independent sets.

+53.0ₜ

Solution space properties computable on GPU includes

Benchmarks

We run a single thread benchmark on central processing units (CPU) Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz, and its CUDA version on a GPU Tesla V100-SXM2 16G. The results are summarized in the following plot. The benchmark code can be found in our paper repository.

benchmark-independent-set This benchmark results is for computing different solution space properties of independent sets of random three-regular graphs with different tensor element types. The time in these plots only includes tensor network contraction, without taking into account the contraction order finding and just-in-time compilation time. Legends are properties, algebra, and devices that we used in the computation; one can find the corresponding computed solution space property in Table 1 in the paper.

The graphs in all benchmarks are random three-regular graphs, which have treewidth that is asymptotically smaller than $|V|/6$. In this benchmark, we do not include traditional algorithms for finding the MIS sizes such as branching or dynamic programming. To the best of our knowledge, these algorithms are not suitable for computing most of the solution space properties mentioned in this paper. The main goal of this section is to show the relative computation time for calculating different solution space properties.

Panel (a) shows the time and space complexity of tensor network contraction for different graph sizes. The contraction order is obtained using the TreeSA algorithm that implemented in OMEinsumContractionOrders. If we assume our contraction-order finding program has found the optimal treewidth, which is very likely to be true, the space complexity is the same as the treewidth of the problem graph. Slicing technique has been used for graphs with space complexity greater than $2^{27}$ (above the yellow dashed line) to fit the computation into a 16GB memory. One can see that all the computation times in panels (b), (c), and (d) have a strong correlation with the predicted time and space complexity. While in panel (d), the computation time of configuration enumeration also strongly correlates with other factors such as the configuration space size. Among these benchmarks, computational tasks with data types real numbers, complex numbers, or Tropical numbers (CPU only) can utilize fast basic linear algebra subprograms (BLAS) functions. These tasks usually compute much faster than ones with other element types in the same category. Immutable data types with no reference to other values can be compiled to GPU devices that run much faster than CPUs in all cases when the problem scale is big enough. These data types do not include those defined in Polynomial, ConfigEnumerator, ExtendedTropical and SumProductTree or a data type containing them as a part. In panel (c), one can see the Fourier transformation-based method is the fastest in computing the independence polynomial, but it may suffer from round-off errors. The finite field (GF(p)) approach is the only method that does not have round-off errors and can be run on a GPU. In panel (d), one can see the technique to bound the enumeration space (see paper) improves the performance for more than one order of magnitude in enumerating the MISs. The bounding technique can also reduce the memory usage significantly, without which the largest computable graph size is only $\sim150$ on a device with 32GB main memory.

We show the benchmark of computing the maximal independent set properties on 3-regular graphs in the following plot, including a comparison to the Bron-Kerbosch algorithm from Julia package Graphs

benchmark-maximal-independent-set

In this plot, benchmarks of computing different solution space properties of the maximal independent sets (ISs) problem on random three regular graphs at different sizes.

Panel (a) shows the space and time complexities of tensor contraction, which are typically larger than those for the independent set problem. In panel (b), one can see counting maximal independent sets are much more efficient than enumerating them, while our generic tensor network approach runs slightly faster than the Bron-Kerbosch approach in enumerating all maximal independent sets.

diff --git a/dev/ref/index.html b/dev/ref/index.html index e5e3c6f6..79f4fa0d 100644 --- a/dev/ref/index.html +++ b/dev/ref/index.html @@ -1,5 +1,5 @@ -References · GenericTensorNetworks.jl

References

Graph problems

GenericTensorNetworks.solveFunction
solve(problem, property; usecuda=false, T=Float64)

Solving a certain property of a graph problem.

Positional Arguments

  • problem is the graph problem with tensor network information,

  • property is string specifying the task. Using the maximum independent set problem as an example, it can be one of

    • PartitionFunction() for computing the partition function,

    • SizeMax(k=Single) for finding maximum-$k$ set sizes,

    • SizeMin(k=Single) for finding minimum-$k$ set sizes,

    • CountingMax(k=Single) for counting configurations with maximum-$k$ sizes,

    • CountingMin(k=Single) for counting configurations with minimum-$k$ sizes,

    • CountingAll() for counting all configurations,

    • PartitionFunction() for counting all configurations,

    • GraphPolynomial(; method=:finitefield, kwargs...) for evaluating the graph polynomial,

    • SingleConfigMax(k=Single; bounded=false) for finding one maximum-$k$ configuration for each size,

    • SingleConfigMin(k=Single; bounded=false) for finding one minimum-$k$ configuration for each size,

    • ConfigsMax(k=Single; bounded=true, tree_storage=false) for enumerating configurations with maximum-$k$ sizes,

    • ConfigsMin(k=Single; bounded=true, tree_storage=false) for enumerating configurations with minimum-$k$ sizes,

    • ConfigsAll(; tree_storage=false) for enumerating all configurations,

Keyword arguments

  • usecuda is a switch to use CUDA (if possible), user need to call statement using CUDA before turning on this switch.
  • T is the "base" element type, sometimes can be used to reduce the memory cost.
source
GenericTensorNetworks.IndependentSetType
IndependentSet{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
+References · GenericTensorNetworks.jl

References

Graph problems

GenericTensorNetworks.solveFunction
solve(problem, property; usecuda=false, T=Float64)

Solving a certain property of a graph problem.

Positional Arguments

  • problem is the graph problem with tensor network information,

  • property is string specifying the task. Using the maximum independent set problem as an example, it can be one of

    • PartitionFunction() for computing the partition function,

    • SizeMax(k=Single) for finding maximum-$k$ set sizes,

    • SizeMin(k=Single) for finding minimum-$k$ set sizes,

    • CountingMax(k=Single) for counting configurations with maximum-$k$ sizes,

    • CountingMin(k=Single) for counting configurations with minimum-$k$ sizes,

    • CountingAll() for counting all configurations,

    • PartitionFunction() for counting all configurations,

    • GraphPolynomial(; method=:finitefield, kwargs...) for evaluating the graph polynomial,

    • SingleConfigMax(k=Single; bounded=false) for finding one maximum-$k$ configuration for each size,

    • SingleConfigMin(k=Single; bounded=false) for finding one minimum-$k$ configuration for each size,

    • ConfigsMax(k=Single; bounded=true, tree_storage=false) for enumerating configurations with maximum-$k$ sizes,

    • ConfigsMin(k=Single; bounded=true, tree_storage=false) for enumerating configurations with minimum-$k$ sizes,

    • ConfigsAll(; tree_storage=false) for enumerating all configurations,

Keyword arguments

  • usecuda is a switch to use CUDA (if possible), user need to call statement using CUDA before turning on this switch.
  • T is the "base" element type, sometimes can be used to reduce the memory cost.
source
GenericTensorNetworks.IndependentSetType
IndependentSet{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
 IndependentSet(graph; weights=NoWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
@@ -9,32 +9,32 @@
 
 julia> solve(problem, ConfigsMax())
 0-dimensional Array{CountingTropical{Float64, ConfigEnumerator{10, 1, 1}}, 0}:
-(4.0, {0101010001, 1010000011, 0100100110, 0010111000, 1001001100})ₜ
source
GenericTensorNetworks.MaximalISType
MaximalIS{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
+(4.0, {0101010001, 1010000011, 0100100110, 0010111000, 1001001100})ₜ
source
GenericTensorNetworks.MaximalISType
MaximalIS{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
 MaximalIS(graph; weights=NoWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
-    )

The maximal independent set problem. In the constructor, weights are the weights of vertices.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • weights are associated with the vertices of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (absent in the set) or 1 (present in the set).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.MatchingType
Matching{CT<:AbstractEinsum, WT<:Union{NoWeight,Vector}} <: GraphProblem
+    )

The maximal independent set problem. In the constructor, weights are the weights of vertices.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • weights are associated with the vertices of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (absent in the set) or 1 (present in the set).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.MatchingType
Matching{CT<:AbstractEinsum, WT<:Union{NoWeight,Vector}} <: GraphProblem
 Matching(graph; weights=NoWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
-    )

The Vertex matching problem.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • weights are associated with the edges of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms on edges, where a value can be 0 (not matched) or 1 (mathced).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.ColoringType
Coloring{K,CT<:AbstractEinsum, WT<:Union{NoWeight, Vector}} <: GraphProblem
+    )

The Vertex matching problem.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • weights are associated with the edges of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms on edges, where a value can be 0 (not matched) or 1 (mathced).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.ColoringType
Coloring{K,CT<:AbstractEinsum, WT<:Union{NoWeight, Vector}} <: GraphProblem
 Coloring{K}(graph; weights=NoWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
-    )

The Vertex Coloring problem.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • weights are associated with the edges of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms on vertices, where a value can be in $0,...,K-1$ (different colors).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.DominatingSetType
DominatingSet{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
+    )

The Vertex Coloring problem.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • weights are associated with the edges of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms on vertices, where a value can be in $0,...,K-1$ (different colors).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.DominatingSetType
DominatingSet{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
 DominatingSet(graph; weights=NoWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
-    )

The dominating set problem.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • weights are associated with the vertices of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms on vertices, where a value can be 0 (absent in the set) or 1 (present in the set).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.SpinGlassType
SpinGlass{TT<:MaxCut,WT1<:Union{NoWeight, Vector},WT2<:Union{ZeroWeight, Vector}} <: ReducedProblem
+    )

The dominating set problem.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • weights are associated with the vertices of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms on vertices, where a value can be 0 (absent in the set) or 1 (present in the set).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.SpinGlassType
SpinGlass{TT<:MaxCut,WT1<:Union{NoWeight, Vector},WT2<:Union{ZeroWeight, Vector}} <: ReducedProblem
 SpinGlass(graph; J=NoWeight(), h=ZeroWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
     )
-SpinGlass(M::AbstractMatrix, h::AbstractVector; kwargs...)

The spin glass problem (or cutting problem). In the output, the spin ↑ is mapped to configuration 0, while spin ↓ is mapped to configuration 1.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • M is a symmetric matrix of the coupling strengths.
  • J is a vector of coupling strengths associated with the edges of the graph.
  • h is a vector of onsite energy terms associated with the vertices of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.HyperSpinGlassType
struct HyperSpinGlass{CT<:OMEinsum.AbstractEinsum, WT<:Union{NoWeight, Vector}} <: GraphProblem

The hyper-spin-glass problem is a generalization of the spin-glass problem to hypergraphs.

Positional arguments

  • n is the number of spins.
  • cliques is a vector of cliques, each being a vector of vertices (integers).

Keyword arguments

  • weights are associated with the cliques.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.MaxCutType
MaxCut{CT<:AbstractEinsum,WT1<:Union{NoWeight, Vector},WT2<:Union{ZeroWeight, Vector}} <: GraphProblem
+SpinGlass(M::AbstractMatrix, h::AbstractVector; kwargs...)

The spin glass problem (or cutting problem). In the output, the spin ↑ is mapped to configuration 0, while spin ↓ is mapped to configuration 1.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • M is a symmetric matrix of the coupling strengths.
  • J is a vector of coupling strengths associated with the edges of the graph.
  • h is a vector of onsite energy terms associated with the vertices of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.HyperSpinGlassType
struct HyperSpinGlass{CT<:OMEinsum.AbstractEinsum, WT<:Union{NoWeight, Vector}} <: GraphProblem

The hyper-spin-glass problem is a generalization of the spin-glass problem to hypergraphs.

Positional arguments

  • n is the number of spins.
  • cliques is a vector of cliques, each being a vector of vertices (integers).

Keyword arguments

  • weights are associated with the cliques.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.MaxCutType
MaxCut{CT<:AbstractEinsum,WT1<:Union{NoWeight, Vector},WT2<:Union{ZeroWeight, Vector}} <: GraphProblem
 MaxCut(graph; edge_weights=NoWeight(), vertex_weights=ZeroWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
-    )

The cutting problem.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • edge_weights are associated with the edges of the graph.
  • vertex_weights are associated with the vertices of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.PaintShopType
PaintShop{CT<:AbstractEinsum} <: GraphProblem
+    )

The cutting problem.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • edge_weights are associated with the edges of the graph.
  • vertex_weights are associated with the vertices of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.PaintShopType
PaintShop{CT<:AbstractEinsum} <: GraphProblem
 PaintShop(sequence::AbstractVector; openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
@@ -48,7 +48,7 @@
 julia> solve(pb, ConfigsMin())[].c.data
 2-element Vector{StaticBitVector{3, 1}}:
  100
- 011

In our definition, we find the maximum number of unchanged color in this sequence, i.e. (n-1) - (minimum number of color changes) In the output of maximum configurations, the two configurations are defined on 5 bonds i.e. pairs of (i, i+1), 0 means color changed, while 1 means color not changed. If we denote two "colors" as r and b, then the optimal painting is rbbbrr or brrrbb, both change the colors twice.

source
GenericTensorNetworks.SatisfiabilityType
Satisfiability{CT<:AbstractEinsum,T,WT<:Union{NoWeight, Vector}} <: GraphProblem
+ 011

In our definition, we find the maximum number of unchanged color in this sequence, i.e. (n-1) - (minimum number of color changes) In the output of maximum configurations, the two configurations are defined on 5 bonds i.e. pairs of (i, i+1), 0 means color changed, while 1 means color not changed. If we denote two "colors" as r and b, then the optimal painting is rbbbrr or brrrbb, both change the colors twice.

source
GenericTensorNetworks.SatisfiabilityType
Satisfiability{CT<:AbstractEinsum,T,WT<:Union{NoWeight, Vector}} <: GraphProblem
 Satisfiability(cnf::CNF; weights=NoWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
@@ -72,7 +72,7 @@
 julia> gp = Satisfiability(cnf);
 
 julia> solve(gp, SizeMax())[]
-4.0ₜ
source
GenericTensorNetworks.SetCoveringType
SetCovering{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
 SetCovering(sets; weights=NoWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
@@ -81,7 +81,7 @@
 julia> gp = SetCovering(sets);
 
 julia> res = solve(gp, ConfigsMin())[]
-(3.0, {10110, 10101})ₜ
source
GenericTensorNetworks.SetPackingType
SetPacking{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
 SetPacking(sets; weights=NoWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
@@ -90,7 +90,7 @@
 julia> gp = SetPacking(sets);
 
 julia> res = solve(gp, ConfigsMax())[]
-(2.0, {00110, 10010, 01100})ₜ
source
GenericTensorNetworks.OpenPitMiningType
OpenPitMining{ET, CT<:AbstractEinsum} <: GraphProblem
 OpenPitMining(rewards; openvertices=(),
              optimizer=GreedyMethod(), simplifier=nothing,
              fixedvertices=Dict())

The open pit mining problem. This problem can be solved in polynomial time with the pseudoflow algorithm.

Positional arguments

  • rewards is a matrix of rewards.

Keyword arguments

  • openvertices specifies labels of the output tensor.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of labels, where a value can be 0 (not mined) or 1 (mined)
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.

Example

julia> rewards =  [-4  -7  -7  -17  -7  -26;
@@ -114,7 +114,7 @@
       ◼       ◼       1       8       ◼       ◼ 
       ◼       ◼       ◼       ◼       ◼       ◼ 
       ◼       ◼       ◼       ◼       ◼       ◼ 
-      ◼       ◼       ◼       ◼       ◼       ◼

You will the the mining is printed as green in an colored REPL.

source

Graph Problem Interfaces

To subtype GraphProblem, a new type must contain a code field to represent the (optimized) tensor network. Interfaces GenericTensorNetworks.generate_tensors, labels, flavors and get_weights are required. nflavor is optional.

GenericTensorNetworks.generate_tensorsFunction
generate_tensors(func, problem::GraphProblem)

Generate a vector of tensors as the inputs of the tensor network contraction code problem.code. func is a function to customize the tensors. func(symbol) returns a vector of elements, the length of which is same as the number of flavors.

Example

The following code gives your the maximum independent set size

julia> using Graphs, GenericTensorNetworks
+      ◼       ◼       ◼       ◼       ◼       ◼

You will the the mining is printed as green in an colored REPL.

source

Graph Problem Interfaces

To subtype GraphProblem, a new type must contain a code field to represent the (optimized) tensor network. Interfaces GenericTensorNetworks.generate_tensors, labels, flavors and get_weights are required. nflavor is optional.

GenericTensorNetworks.generate_tensorsFunction
generate_tensors(func, problem::GraphProblem)

Generate a vector of tensors as the inputs of the tensor network contraction code problem.code. func is a function to customize the tensors. func(symbol) returns a vector of elements, the length of which is same as the number of flavors.

Example

The following code gives your the maximum independent set size

julia> using Graphs, GenericTensorNetworks
 
 julia> gp = IndependentSet(smallgraph(:petersen));
 
@@ -143,10 +143,10 @@
 
 julia> gp.code(GenericTensorNetworks.generate_tensors(Tropical(1.0), gp)...)
 0-dimensional Array{Tropical{Float64}, 0}:
-4.0ₜ
source
GenericTensorNetworks.labelsFunction
labels(problem::GraphProblem) -> Vector

The labels of a graph problem is defined as the degrees of freedoms in the graph problem. e.g. for the maximum independent set problems, they are the indices of vertices: 1, 2, 3..., while for the max cut problem, they are the edges.

source
GenericTensorNetworks.termsFunction
terms(problem::GraphProblem) -> Vector

The terms of a graph problem is defined as the tensor labels that defining local energies (or weights) in the graph problem. e.g. for the maximum independent set problems, they are the vertex-tensor labels: [1], [2], [3]... The weight of a term is same as the exponents in the graph polynomial.

source
GenericTensorNetworks.flavorsFunction
flavors(::Type{<:GraphProblem}) -> Vector

It returns a vector of integers as the flavors of a degree of freedom. Its size is the same as the degree of freedom on a single vertex/edge.

source
GenericTensorNetworks.get_weightsFunction
get_weights(problem::GraphProblem, i::Int) -> Vector
-get_weights(problem::GraphProblem) -> Vector

The weights for the problem or the weights for the degree of freedom specified by the i-th term if a second argument is provided. Weights are associated with terms in the graph problem. In graph polynomial, integer weights can be the exponents.

source
GenericTensorNetworks.chweightsFunction
chweights(problem::GraphProblem, weights) -> GraphProblem

Change the weights for the problem and return a new problem instance. Weights are associated with terms in the graph problem. In graph polynomial, integer weights can be the exponents.

source
GenericTensorNetworks.fixedverticesFunction
fixedvertices(problem::GraphProblem) -> Dict

Fix degree of freedoms in a graph problem to a certain value using a dict, where the key is a label, and the value should be in, e.g. [0, 1] in the indepenent set problem. When a degree of freedom is fixed, its size is 1. The optimal tensor network contraction order is then different from the default case.

source
GenericTensorNetworks.extract_resultFunction
extract_result(p::ReducedProblem, output)
-extract_result(p::ReducedProblem)

Post process the output of the target problem to get an output to the source problem. If the output is not provided, it will return a function instead. The result extraction rule is determined by the output type. e.g. If the output type is Tropical, it will be interpreted as the energy. If the output is a Vector, it will be interpreted as a configuration.

source

Graph Problem Utilities

GenericTensorNetworks.is_vertex_coloringFunction
is_vertex_coloring(graph::SimpleGraph, config)

Returns true if the coloring specified by config is a valid one, i.e. does not violate the contraints of vertices of an edges having different colors.

source
GenericTensorNetworks.is_matchingFunction
is_matching(graph::SimpleGraph, config)

Returns true if config is a valid matching on graph, and false if a vertex is double matched. config is a vector of boolean variables, which has one to one correspondence with edges(graph).

source
GenericTensorNetworks.cut_sizeFunction
cut_size(g::SimpleGraph, config; edge_weights=NoWeight(), vertex_weights=ZeroWeight())

Compute the cut size for the vertex configuration config (an iterator).

source
GenericTensorNetworks.spinglass_energyFunction
spinglass_energy(g::SimpleGraph, config; J=NoWeight(), h=ZeroWeight())

Compute the spin glass state energy for the vertex configuration config. In the configuration, the spin ↑ is mapped to configuration 0, while spin ↓ is mapped to configuration 1. Let $G=(V,E)$ be the input graph, the hamiltonian is

\[H = - \sum_{ij \in E} J_{ij} s_i s_j + \sum_{i \in V} h_i s_i,\]

where $s_i \in \{-1, 1\}$ stands for spin ↓ and spin ↑.

source
GenericTensorNetworks.paint_shop_coloring_from_configFunction
paint_shop_coloring_from_config(p::PaintShop, config)

Returns a valid painting from the paint shop configuration (given by the configuration solvers). The config is a sequence of 0 and 1, where 0 means painting the first appearence of a car in blue, 1 otherwise.

source
GenericTensorNetworks.mis_compactify!Function
mis_compactify!(tropicaltensor)

Compactify tropical tensor for maximum independent set problem. It will eliminate some entries by setting them to zero, by the criteria that removing these entry does not change the MIS size of its parent graph (reference to be added).

source
GenericTensorNetworks.labelsFunction
labels(problem::GraphProblem) -> Vector

The labels of a graph problem is defined as the degrees of freedoms in the graph problem. e.g. for the maximum independent set problems, they are the indices of vertices: 1, 2, 3..., while for the max cut problem, they are the edges.

source
GenericTensorNetworks.termsFunction
terms(problem::GraphProblem) -> Vector

The terms of a graph problem is defined as the tensor labels that defining local energies (or weights) in the graph problem. e.g. for the maximum independent set problems, they are the vertex-tensor labels: [1], [2], [3]... The weight of a term is same as the exponents in the graph polynomial.

source
GenericTensorNetworks.flavorsFunction
flavors(::Type{<:GraphProblem}) -> Vector

It returns a vector of integers as the flavors of a degree of freedom. Its size is the same as the degree of freedom on a single vertex/edge.

source
GenericTensorNetworks.get_weightsFunction
get_weights(problem::GraphProblem, i::Int) -> Vector
+get_weights(problem::GraphProblem) -> Vector

The weights for the problem or the weights for the degree of freedom specified by the i-th term if a second argument is provided. Weights are associated with terms in the graph problem. In graph polynomial, integer weights can be the exponents.

source
GenericTensorNetworks.chweightsFunction
chweights(problem::GraphProblem, weights) -> GraphProblem

Change the weights for the problem and return a new problem instance. Weights are associated with terms in the graph problem. In graph polynomial, integer weights can be the exponents.

source
GenericTensorNetworks.fixedverticesFunction
fixedvertices(problem::GraphProblem) -> Dict

Fix degree of freedoms in a graph problem to a certain value using a dict, where the key is a label, and the value should be in, e.g. [0, 1] in the indepenent set problem. When a degree of freedom is fixed, its size is 1. The optimal tensor network contraction order is then different from the default case.

source
GenericTensorNetworks.extract_resultFunction
extract_result(p::ReducedProblem, output)
+extract_result(p::ReducedProblem)

Post process the output of the target problem to get an output to the source problem. If the output is not provided, it will return a function instead. The result extraction rule is determined by the output type. e.g. If the output type is Tropical, it will be interpreted as the energy. If the output is a Vector, it will be interpreted as a configuration.

source

Graph Problem Utilities

GenericTensorNetworks.is_vertex_coloringFunction
is_vertex_coloring(graph::SimpleGraph, config)

Returns true if the coloring specified by config is a valid one, i.e. does not violate the contraints of vertices of an edges having different colors.

source
GenericTensorNetworks.is_matchingFunction
is_matching(graph::SimpleGraph, config)

Returns true if config is a valid matching on graph, and false if a vertex is double matched. config is a vector of boolean variables, which has one to one correspondence with edges(graph).

source
GenericTensorNetworks.cut_sizeFunction
cut_size(g::SimpleGraph, config; edge_weights=NoWeight(), vertex_weights=ZeroWeight())

Compute the cut size for the vertex configuration config (an iterator).

source
GenericTensorNetworks.spinglass_energyFunction
spinglass_energy(g::SimpleGraph, config; J=NoWeight(), h=ZeroWeight())

Compute the spin glass state energy for the vertex configuration config. In the configuration, the spin ↑ is mapped to configuration 0, while spin ↓ is mapped to configuration 1. Let $G=(V,E)$ be the input graph, the hamiltonian is

\[H = - \sum_{ij \in E} J_{ij} s_i s_j + \sum_{i \in V} h_i s_i,\]

where $s_i \in \{-1, 1\}$ stands for spin ↓ and spin ↑.

source
GenericTensorNetworks.paint_shop_coloring_from_configFunction
paint_shop_coloring_from_config(p::PaintShop, config)

Returns a valid painting from the paint shop configuration (given by the configuration solvers). The config is a sequence of 0 and 1, where 0 means painting the first appearence of a car in blue, 1 otherwise.

source
GenericTensorNetworks.mis_compactify!Function
mis_compactify!(tropicaltensor)

Compactify tropical tensor for maximum independent set problem. It will eliminate some entries by setting them to zero, by the criteria that removing these entry does not change the MIS size of its parent graph (reference to be added).

source
GenericTensorNetworks.CNFType
CNF{T}
 CNF(clauses)

Boolean expression in conjunctive normal form. clauses is a vector of CNFClause, if and only if all clauses are satisfied, this CNF is satisfied.

Example

julia> @bools x y z
 
 julia> cnf = (x ∨ y) ∧ (¬y ∨ z)
@@ -156,23 +156,23 @@
 true
 
 julia> satisfiable(cnf, Dict([:x=>false, :y=>false, :z=>true]))
-false
source
GenericTensorNetworks.@boolsMacro
@bools(syms::Symbol...)

Create some boolean variables of type BoolVar in current scope that can be used in create a CNF.

Example

julia> @bools x y z
 
 julia> (x ∨ y) ∧ (¬y ∨ z)
-(x ∨ y) ∧ (¬y ∨ z)
source

Properties

GenericTensorNetworks.SizeMaxType
SizeMax{K} <: AbstractProperty
-SizeMax(k::Int)

The maximum-K set sizes. e.g. the largest size of the IndependentSet problem is also know as the independence number.

  • The corresponding tensor element type are max-plus tropical number Tropical if K is Single and ExtendedTropical if K is an integer.
  • It is compatible with weighted graph problems.
  • BLAS (on CPU) and GPU are supported only if K is Single,
source
GenericTensorNetworks.SizeMinType
SizeMin{K} <: AbstractProperty
-SizeMin(k::Int)

The minimum-K set sizes. e.g. the smallest size ofthe MaximalIS problem is also known as the independent domination number.

  • The corresponding tensor element type are inverted max-plus tropical number Tropical if K is Single and inverted ExtendedTropical K is an integer.

The inverted Tropical number emulates the min-plus tropical number.

  • It is compatible with weighted graph problems.
  • BLAS (on CPU) and GPU are supported only if K is Single,
source
GenericTensorNetworks.CountingAllType
CountingAll <: AbstractProperty
-CountingAll()

Counting the total number of sets. e.g. for the IndependentSet problem, it counts the independent sets.

  • The corresponding tensor element type is Base.Real.
  • The weights on graph does not have effect.
  • BLAS (GPU and CPU) and GPU are supported,
source
GenericTensorNetworks.CountingMaxType
CountingMax{K} <: AbstractProperty
-CountingMax(K=Single)

Counting the number of sets with largest-K size. e.g. for IndependentSet problem, it counts independent sets of size $\alpha(G), \alpha(G)-1, \ldots, \alpha(G)-K+1$.

  • The corresponding tensor element type is CountingTropical if K is Single, and TruncatedPoly{K} if K is an integer.
  • Weighted graph problems is only supported if K is Single.
  • GPU is supported,
source
GenericTensorNetworks.CountingMinType
CountingMin{K} <: AbstractProperty
-CountingMin(K=Single)

Counting the number of sets with smallest-K size.

  • The corresponding tensor element type is inverted CountingTropical if K is Single, and TruncatedPoly{K} if K is an integer.
  • Weighted graph problems is only supported if K is Single.
  • GPU is supported,
source
GenericTensorNetworks.GraphPolynomialType
GraphPolynomial{METHOD} <: AbstractProperty
-GraphPolynomial(; method=:finitefield, kwargs...)

Compute the graph polynomial, e.g. for IndependentSet problem, it is the independence polynomial. The METHOD type parameter can be one of the following symbols

Method Argument

  • :finitefield, uses finite field algebra to fit the polynomial.
    • The corresponding tensor element type is Mods.Mod,
    • It does not have round-off error,
    • GPU is supported,
    • It accepts keyword arguments maxorder (optional, e.g. the MIS size in the IndependentSet problem).
  • :polynomial and :laurent, use (Laurent) polynomial numbers to solve the polynomial directly.
    • The corresponding tensor element types are Polynomial and LaurentPolynomial.
    • It might have small round-off error depending on the data type for storing the counting.
    • It has memory overhead that linear to the graph size.
  • :fft, use fast fourier transformation to fit the polynomial.
    • The corresponding tensor element type is Base.Complex.
    • It has (controllable) round-off error.
    • BLAS and GPU are supported.
    • It accepts keyword arguments maxorder (optional) and r, if r > 1, one has better precision for coefficients of large order, if r < 1, one has better precision for coefficients of small order.
  • :fitting, fit the polynomial directly.
    • The corresponding tensor element type is floating point numbers like Base.Float64.
    • It has round-off error.
    • BLAS and GPU are supported, it is the fastest among all methods.

Graph polynomials are not defined for weighted graph problems.

source
GenericTensorNetworks.SingleConfigMaxType
SingleConfigMax{K, BOUNDED} <: AbstractProperty
-SingleConfigMax(k::Int; bounded=false)

Finding single solution for largest-K sizes, e.g. for IndependentSet problem, it is one of the maximum independent sets.

Keyword Arguments

  • bounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.
source
GenericTensorNetworks.SingleConfigMinType
SingleConfigMin{K, BOUNDED} <: AbstractProperty
-SingleConfigMin(k::Int; bounded=false)

Finding single solution with smallest-K size.

Keyword Arguments

  • bounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.
source
GenericTensorNetworks.ConfigsAllType
ConfigsAll{TREESTORAGE} <:AbstractProperty
-ConfigsAll(; tree_storage=false)

Find all valid configurations, e.g. for IndependentSet problem, it is finding all independent sets.

Keyword Arguments

  • tree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.
source
GenericTensorNetworks.ConfigsMaxType
ConfigsMax{K, BOUNDED, TREESTORAGE} <:AbstractProperty
-ConfigsMax(K=Single; bounded=true, tree_storage=true)

Find configurations with largest-K sizes, e.g. for IndependentSet problem, it is finding all independent sets of sizes $\alpha(G), \alpha(G)-1, \ldots, \alpha(G)-K+1$.

  • The corresponding data type is CountingTropical{Float64,<:ConfigEnumerator} if K is Single and TruncatedPoly{K,<:ConfigEnumerator} if K is an integer.
  • Weighted graph problems is only supported if K is Single.

Keyword Arguments

  • bounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.
  • tree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.
source
GenericTensorNetworks.ConfigsMinType
ConfigsMin{K, BOUNDED, TREESTORAGE} <:AbstractProperty
-ConfigsMin(K=Single; bounded=true, tree_storage=false)

Find configurations with smallest-K sizes.

  • The corresponding data type is inverted CountingTropical{Float64,<:ConfigEnumerator} if K is Single and inverted TruncatedPoly{K,<:ConfigEnumerator} if K is an integer.
  • Weighted graph problems is only supported if K is Single.

Keyword Arguments

  • bounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.
  • tree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.
source

Element Algebras

GenericTensorNetworks.is_commutative_semiringFunction
is_commutative_semiring(a::T, b::T, c::T) where T

Check if elements a, b and c satisfied the commutative semiring requirements.

\[\begin{align*} +(x ∨ y) ∧ (¬y ∨ z)

source

Properties

GenericTensorNetworks.SizeMaxType
SizeMax{K} <: AbstractProperty
+SizeMax(k::Int)

The maximum-K set sizes. e.g. the largest size of the IndependentSet problem is also know as the independence number.

  • The corresponding tensor element type are max-plus tropical number Tropical if K is Single and ExtendedTropical if K is an integer.
  • It is compatible with weighted graph problems.
  • BLAS (on CPU) and GPU are supported only if K is Single,
source
GenericTensorNetworks.SizeMinType
SizeMin{K} <: AbstractProperty
+SizeMin(k::Int)

The minimum-K set sizes. e.g. the smallest size ofthe MaximalIS problem is also known as the independent domination number.

  • The corresponding tensor element type are inverted max-plus tropical number Tropical if K is Single and inverted ExtendedTropical K is an integer.

The inverted Tropical number emulates the min-plus tropical number.

  • It is compatible with weighted graph problems.
  • BLAS (on CPU) and GPU are supported only if K is Single,
source
GenericTensorNetworks.CountingAllType
CountingAll <: AbstractProperty
+CountingAll()

Counting the total number of sets. e.g. for the IndependentSet problem, it counts the independent sets.

  • The corresponding tensor element type is Base.Real.
  • The weights on graph does not have effect.
  • BLAS (GPU and CPU) and GPU are supported,
source
GenericTensorNetworks.CountingMaxType
CountingMax{K} <: AbstractProperty
+CountingMax(K=Single)

Counting the number of sets with largest-K size. e.g. for IndependentSet problem, it counts independent sets of size $\alpha(G), \alpha(G)-1, \ldots, \alpha(G)-K+1$.

  • The corresponding tensor element type is CountingTropical if K is Single, and TruncatedPoly{K} if K is an integer.
  • Weighted graph problems is only supported if K is Single.
  • GPU is supported,
source
GenericTensorNetworks.CountingMinType
CountingMin{K} <: AbstractProperty
+CountingMin(K=Single)

Counting the number of sets with smallest-K size.

  • The corresponding tensor element type is inverted CountingTropical if K is Single, and TruncatedPoly{K} if K is an integer.
  • Weighted graph problems is only supported if K is Single.
  • GPU is supported,
source
GenericTensorNetworks.GraphPolynomialType
GraphPolynomial{METHOD} <: AbstractProperty
+GraphPolynomial(; method=:finitefield, kwargs...)

Compute the graph polynomial, e.g. for IndependentSet problem, it is the independence polynomial. The METHOD type parameter can be one of the following symbols

Method Argument

  • :finitefield, uses finite field algebra to fit the polynomial.
    • The corresponding tensor element type is Mods.Mod,
    • It does not have round-off error,
    • GPU is supported,
    • It accepts keyword arguments maxorder (optional, e.g. the MIS size in the IndependentSet problem).
  • :polynomial and :laurent, use (Laurent) polynomial numbers to solve the polynomial directly.
    • The corresponding tensor element types are Polynomial and LaurentPolynomial.
    • It might have small round-off error depending on the data type for storing the counting.
    • It has memory overhead that linear to the graph size.
  • :fft, use fast fourier transformation to fit the polynomial.
    • The corresponding tensor element type is Base.Complex.
    • It has (controllable) round-off error.
    • BLAS and GPU are supported.
    • It accepts keyword arguments maxorder (optional) and r, if r > 1, one has better precision for coefficients of large order, if r < 1, one has better precision for coefficients of small order.
  • :fitting, fit the polynomial directly.
    • The corresponding tensor element type is floating point numbers like Base.Float64.
    • It has round-off error.
    • BLAS and GPU are supported, it is the fastest among all methods.

Graph polynomials are not defined for weighted graph problems.

source
GenericTensorNetworks.SingleConfigMaxType
SingleConfigMax{K, BOUNDED} <: AbstractProperty
+SingleConfigMax(k::Int; bounded=false)

Finding single solution for largest-K sizes, e.g. for IndependentSet problem, it is one of the maximum independent sets.

Keyword Arguments

  • bounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.
source
GenericTensorNetworks.SingleConfigMinType
SingleConfigMin{K, BOUNDED} <: AbstractProperty
+SingleConfigMin(k::Int; bounded=false)

Finding single solution with smallest-K size.

Keyword Arguments

  • bounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.
source
GenericTensorNetworks.ConfigsAllType
ConfigsAll{TREESTORAGE} <:AbstractProperty
+ConfigsAll(; tree_storage=false)

Find all valid configurations, e.g. for IndependentSet problem, it is finding all independent sets.

Keyword Arguments

  • tree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.
source
GenericTensorNetworks.ConfigsMaxType
ConfigsMax{K, BOUNDED, TREESTORAGE} <:AbstractProperty
+ConfigsMax(K=Single; bounded=true, tree_storage=true)

Find configurations with largest-K sizes, e.g. for IndependentSet problem, it is finding all independent sets of sizes $\alpha(G), \alpha(G)-1, \ldots, \alpha(G)-K+1$.

  • The corresponding data type is CountingTropical{Float64,<:ConfigEnumerator} if K is Single and TruncatedPoly{K,<:ConfigEnumerator} if K is an integer.
  • Weighted graph problems is only supported if K is Single.

Keyword Arguments

  • bounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.
  • tree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.
source
GenericTensorNetworks.ConfigsMinType
ConfigsMin{K, BOUNDED, TREESTORAGE} <:AbstractProperty
+ConfigsMin(K=Single; bounded=true, tree_storage=false)

Find configurations with smallest-K sizes.

  • The corresponding data type is inverted CountingTropical{Float64,<:ConfigEnumerator} if K is Single and inverted TruncatedPoly{K,<:ConfigEnumerator} if K is an integer.
  • Weighted graph problems is only supported if K is Single.

Keyword Arguments

  • bounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.
  • tree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.
source

Element Algebras

GenericTensorNetworks.is_commutative_semiringFunction
is_commutative_semiring(a::T, b::T, c::T) where T

Check if elements a, b and c satisfied the commutative semiring requirements.

\[\begin{align*} (a \oplus b) \oplus c = a \oplus (b \oplus c) & \hspace{5em}\triangleright\text{commutative monoid $\oplus$ with identity $\mathbb{0}$}\\ a \oplus \mathbb{0} = \mathbb{0} \oplus a = a &\\ a \oplus b = b \oplus a &\\ @@ -185,7 +185,7 @@ (a\oplus b) \odot c = a\odot c \oplus b\odot c &\\ &\\ a \odot \mathbb{0} = \mathbb{0} \odot a = \mathbb{0} -\end{align*}\]

source
TropicalNumbers.TropicalType
TropicalMaxPlus{T} = Tropical{T} <: AbstractSemiring

TropicalMaxPlus is a semiring algebra, can be described by

  • Tropical (TropicalMaxPlus), (ℝ, max, +, -Inf, 0).

It maps

  • + to max in regular algebra,
  • * to + in regular algebra,
  • 1 to 0 in regular algebra,
  • 0 to -Inf in regular algebra (for integer content types, this is chosen as a small integer).

Example

julia> TropicalMaxPlus(1.0) + TropicalMaxPlus(3.0)
+\end{align*}\]

source
TropicalNumbers.TropicalType
TropicalMaxPlus{T} = Tropical{T} <: AbstractSemiring

TropicalMaxPlus is a semiring algebra, can be described by

  • Tropical (TropicalMaxPlus), (ℝ, max, +, -Inf, 0).

It maps

  • + to max in regular algebra,
  • * to + in regular algebra,
  • 1 to 0 in regular algebra,
  • 0 to -Inf in regular algebra (for integer content types, this is chosen as a small integer).

Example

julia> TropicalMaxPlus(1.0) + TropicalMaxPlus(3.0)
 3.0ₜ
 
 julia> TropicalMaxPlus(1.0) * TropicalMaxPlus(3.0)
@@ -195,7 +195,7 @@
 0.0ₜ
 
 julia> zero(TropicalMaxPlusF64)
--Infₜ
source
TropicalNumbers.CountingTropicalType
CountingTropical{T,CT} <: Number

Counting tropical number type is also a semiring algebra. It is tropical algebra with one extra field for counting, it is introduced in arXiv:2008.06888.

Example

julia> CountingTropical(1.0, 5.0) + CountingTropical(3.0, 2.0)
+-Infₜ
source
TropicalNumbers.CountingTropicalType
CountingTropical{T,CT} <: Number

Counting tropical number type is also a semiring algebra. It is tropical algebra with one extra field for counting, it is introduced in arXiv:2008.06888.

Example

julia> CountingTropical(1.0, 5.0) + CountingTropical(3.0, 2.0)
 (3.0, 2.0)ₜ
 
 julia> CountingTropical(1.0, 5.0) * CountingTropical(3.0, 2.0)
@@ -205,7 +205,7 @@
 (0.0, 1.0)ₜ
 
 julia> zero(CountingTropicalF64)
-(-Inf, 0.0)ₜ
source
GenericTensorNetworks.ExtendedTropicalType
ExtendedTropical{K,TO} <: Number
 ExtendedTropical{K}(orders)

Extended Tropical numbers with largest K orders keeped, or the TruncatedPoly without coefficients, TO is the element type of orders, usually Tropical numbers. This algebra maps

  • + to finding largest K values of union of two sets.
  • * to finding largest K values of sum combination of two sets.
  • 0 to set [-Inf, -Inf, ..., -Inf, -Inf]
  • 1 to set [-Inf, -Inf, ..., -Inf, 0]

Fields

Examples

julia> x = ExtendedTropical{3}(Tropical.([1.0, 2, 3]))
 ExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[1.0ₜ, 2.0ₜ, 3.0ₜ])
 
@@ -222,7 +222,7 @@
 ExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[-Infₜ, -Infₜ, 0.0ₜ])
 
 julia> zero(x)
-ExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[-Infₜ, -Infₜ, -Infₜ])
source
Mods.ModType

Mod{m}(v) creates a modular number in mod m with value mod(v,m).

source
Mods.ModType

Mod{m}(v) creates a modular number in mod m with value mod(v,m).

source
GenericTensorNetworks.TruncatedPolyType
TruncatedPoly{K,T,TO} <: Number
 TruncatedPoly(coeffs::Tuple, maxorder)

Polynomial truncated to largest K orders. T is the coefficients type and TO is the orders type.

Fields

  • coeffs is the largest-K coefficients of a polynomial. In GenericTensorNetworks, it can be the counting or enumeration of solutions.
  • maxorder is the order of a polynomial.

Examples

julia> TruncatedPoly((1,2,3), 6)
 x^4 + 2*x^5 + 3*x^6
 
@@ -230,8 +230,8 @@
 20*x^7 + 8*x^8 + 3*x^9
 
 julia> TruncatedPoly((1,2,3), 6) + TruncatedPoly((5,2,1), 3)
-x^4 + 2*x^5 + 3*x^6
source
GenericTensorNetworks.ConfigEnumeratorType
ConfigEnumerator{N,S,C} <: AbstractSetNumber

Set algebra for enumerating configurations, where N is the length of configurations, C is the size of storage in unit of UInt64, S is the bit width to store a single element in a configuration, i.e. log2(# of flavors), for bitstrings, it is 1`.

Fields

Examples

julia> a = ConfigEnumerator([StaticBitVector([1,1,1,0,0]), StaticBitVector([1,0,0,0,1])])
+x^4 + 2*x^5 + 3*x^6
source
GenericTensorNetworks.ConfigEnumeratorType
ConfigEnumerator{N,S,C} <: AbstractSetNumber

Set algebra for enumerating configurations, where N is the length of configurations, C is the size of storage in unit of UInt64, S is the bit width to store a single element in a configuration, i.e. log2(# of flavors), for bitstrings, it is 1`.

Fields

Examples

julia> a = ConfigEnumerator([StaticBitVector([1,1,1,0,0]), StaticBitVector([1,0,0,0,1])])
 {11100, 10001}
 
 julia> b = ConfigEnumerator([StaticBitVector([0,0,0,0,0]), StaticBitVector([1,0,1,0,1])])
@@ -244,7 +244,7 @@
 {00000}
 
 julia> zero(a)
-{}
source
GenericTensorNetworks.SumProductTreeType
SumProductTree{ET} <: AbstractSetNumber

Configuration enumerator encoded in a tree, it is the most natural representation given by a sum-product network and is often more memory efficient than putting the configurations in a vector. One can use generate_samples to sample configurations from this tree structure efficiently.

Fields

  • tag is one of ZERO, ONE, LEAF, SUM, PROD.
  • data is the element stored in a LEAF node.
  • left and right are two operands of a SUM or PROD node.

Examples

julia> s = SumProductTree(bv"00111")
+{}
source
GenericTensorNetworks.SumProductTreeType
SumProductTree{ET} <: AbstractSetNumber

Configuration enumerator encoded in a tree, it is the most natural representation given by a sum-product network and is often more memory efficient than putting the configurations in a vector. One can use generate_samples to sample configurations from this tree structure efficiently.

Fields

  • tag is one of ZERO, ONE, LEAF, SUM, PROD.
  • data is the element stored in a LEAF node.
  • left and right are two operands of a SUM or PROD node.

Examples

julia> s = SumProductTree(bv"00111")
 00111
 
 
@@ -283,7 +283,7 @@
 julia> one(s)
 00000
 
-
source
GenericTensorNetworks.ConfigSamplerType
ConfigSampler{N,S,C} <: AbstractSetNumber
 ConfigSampler(elements::StaticElementVector)

The algebra for sampling one configuration, where N is the length of configurations, C is the size of storage in unit of UInt64, S is the bit width to store a single element in a configuration, i.e. log2(# of flavors), for bitstrings, it is 1`.

Note

ConfigSampler is a probabilistic commutative semiring, adding two config samplers do not give you deterministic results.

Fields

Examples

julia> ConfigSampler(StaticBitVector([1,1,1,0,0]))
 ConfigSampler{5, 1, 1}(11100)
 
@@ -297,7 +297,7 @@
 ConfigSampler{5, 1, 1}(00000)
 
 julia> zero(ConfigSampler{5, 1, 1})
-ConfigSampler{5, 1, 1}(11111)
source

GenericTensorNetworks also exports the Polynomial and LaurentPolynomial types defined in package Polynomials.

GenericTensorNetworks also exports the Polynomial and LaurentPolynomial types defined in package Polynomials.

GenericTensorNetworks.StaticBitVectorType
StaticBitVector{N,C} = StaticElementVector{N,1,C}
 StaticBitVector(x::AbstractVector)

Examples

julia> sb = StaticBitVector([1,0,0,1,1])
 10011
 
@@ -310,7 +310,7 @@
  0
  0
  1
- 1
source
GenericTensorNetworks.StaticElementVectorType
StaticElementVector{N,S,C}
 StaticElementVector(nflavor::Int, x::AbstractVector)

N is the length of vector, C is the size of storage in unit of UInt64, S is the stride defined as the log2(# of flavors). When the number of flavors is 2, it is a StaticBitVector.

Fields

  • data is a tuple of UInt64 for storing the configuration of static elements.

Examples

julia> ev = StaticElementVector(3, [1,2,0,1,2])
 12012
 
@@ -323,9 +323,9 @@
  2
  0
  1
- 2
source
GenericTensorNetworks.load_configsFunction
load_configs(filename; format=:binary, bitlength=nothing, nflavors=2)

Load configurations from file filename. The format is :binary or :text. If the format is :binary, the bitstring length bitlength must be specified, nflavors specifies the degree of freedom.

source
GenericTensorNetworks.onehotvFunction
onehotv(::Type{<:StaticElementVector}, i, v)
-onehotv(::Type{<:StaticBitVector, i)

Returns a static element vector, with the value at location i being v (1 if not specified).

source
GenericTensorNetworks.load_configsFunction
load_configs(filename; format=:binary, bitlength=nothing, nflavors=2)

Load configurations from file filename. The format is :binary or :text. If the format is :binary, the bitstring length bitlength must be specified, nflavors specifies the degree of freedom.

source
GenericTensorNetworks.onehotvFunction
onehotv(::Type{<:StaticElementVector}, i, v)
+onehotv(::Type{<:StaticBitVector, i)

Returns a static element vector, with the value at location i being v (1 if not specified).

source
GenericTensorNetworks.generate_samplesFunction
generate_samples(t::SumProductTree, nsamples::Int)

Direct sampling configurations from a SumProductTree instance.

Examples

julia> using Graphs
 
 julia> g= smallgraph(:petersen)
 {10, 15} undirected simple Int64 graph
@@ -335,7 +335,7 @@
 julia> samples = generate_samples(t, 1000);
 
 julia> all(s->is_independent_set(g, s), samples)
-true
source
GenericTensorNetworks.hamming_distributionFunction
hamming_distribution(S, T)

Compute the distribution of pair-wise Hamming distances, which is defined as:

\[c(k) := \sum_{\sigma\in S, \tau\in T} \delta({\rm dist}(\sigma, \tau), k)\]

where $\delta$ is a function that returns 1 if two arguments are equivalent, 0 otherwise, ${\rm dist}$ is the Hamming distance function.

Returns the counting as a vector.

source

Tensor Network

OMEinsumContractionOrders.optimize_codeFunction
optimize_code(eincode, size_dict, optimizer = GreedyMethod(), simplifier=nothing, permute=true) -> optimized_eincode

Optimize the einsum contraction code and reduce the time/space complexity of tensor network contraction. Returns a NestedEinsum instance. Input arguments are

  • eincode is an einsum contraction code instance, one of DynamicEinCode, StaticEinCode or NestedEinsum.
  • size is a dictionary of "edge label=>edge size" that contains the size information, one can use uniformsize(eincode, 2) to create a uniform size.
  • optimizer is a CodeOptimizer instance, should be one of GreedyMethod, KaHyParBipartite, SABipartite or TreeSA. Check their docstrings for details.
  • simplifier is one of MergeVectors or MergeGreedy.
  • optimize the permutation if permute is true.

Examples

julia> using OMEinsum
+true
source
GenericTensorNetworks.hamming_distributionFunction
hamming_distribution(S, T)

Compute the distribution of pair-wise Hamming distances, which is defined as:

\[c(k) := \sum_{\sigma\in S, \tau\in T} \delta({\rm dist}(\sigma, \tau), k)\]

where $\delta$ is a function that returns 1 if two arguments are equivalent, 0 otherwise, ${\rm dist}$ is the Hamming distance function.

Returns the counting as a vector.

source

Tensor Network

OMEinsumContractionOrders.optimize_codeFunction
optimize_code(eincode, size_dict, optimizer = GreedyMethod(), simplifier=nothing, permute=true) -> optimized_eincode

Optimize the einsum contraction code and reduce the time/space complexity of tensor network contraction. Returns a NestedEinsum instance. Input arguments are

  • eincode is an einsum contraction code instance, one of DynamicEinCode, StaticEinCode or NestedEinsum.
  • size is a dictionary of "edge label=>edge size" that contains the size information, one can use uniformsize(eincode, 2) to create a uniform size.
  • optimizer is a CodeOptimizer instance, should be one of GreedyMethod, KaHyParBipartite, SABipartite or TreeSA. Check their docstrings for details.
  • simplifier is one of MergeVectors or MergeGreedy.
  • optimize the permutation if permute is true.

Examples

julia> using OMEinsum
 
 julia> code = ein"ij, jk, kl, il->"
 ij, jk, kl, il -> 
julia> optimize_code(code, uniformsize(code, 2), TreeSA())
@@ -357,7 +357,7 @@
     property::GenericTensorNetworks.AbstractProperty;
     T
 ) -> Any
-

Memory estimation in number of bytes to compute certain property of a problem. T is the base type.

source
OMEinsum.@ein_strMacro
ein"ij,jk -> ik"(A,B)

String macro interface which understands numpy.einsum's notation. Translates strings into StaticEinCode-structs that can be called to evaluate an einsum. To control evaluation order, use parentheses - instead of an EinCode, a NestedEinsum is returned which evaluates the expression according to parens. The valid character ranges for index-labels are a-z and α-ω.

example

julia> a, b, c = rand(10,10), rand(10,10), rand(10,1);
+

Memory estimation in number of bytes to compute certain property of a problem. T is the base type.

source
OMEinsum.@ein_strMacro
ein"ij,jk -> ik"(A,B)

String macro interface which understands numpy.einsum's notation. Translates strings into StaticEinCode-structs that can be called to evaluate an einsum. To control evaluation order, use parentheses - instead of an EinCode, a NestedEinsum is returned which evaluates the expression according to parens. The valid character ranges for index-labels are a-z and α-ω.

example

julia> a, b, c = rand(10,10), rand(10,10), rand(10,1);
 
 julia> ein"ij,jk,kl -> il"(a,b,c) ≈ ein"(ij,jk),kl -> il"(a,b,c) ≈ a * b * c
 true
source
OMEinsumContractionOrders.GreedyMethodType
GreedyMethod{MT}
@@ -380,13 +380,12 @@
     vertex_stroke_colors=nothing,
     vertex_text_colors=nothing,
     edge_colors=nothing,
-    edge_line_widths=nothing,
     texts = nothing,
-    format=DEFAULT_FORMAT[],
+    format=GraphDisplayConfig.format[],
     filename=nothing,
-    kwargs...)

Show a graph in VSCode, Pluto or Jupyter notebook, or save it to a file.

Positional arguments

  • f is a function that returns extra Luxor plotting statements.
  • graph is a graph instance.

Keyword arguments

  • locs is a vector of tuples for specifying the vertex locations.

  • layout is one of [:auto, :spring, :stress], the default value is :spring if locs is nothing.

  • optimal_distance is a optimal distance parameter for spring optimizer.

  • spring_mask specfies which location is optimizable for spring optimizer.

  • vertex_colors is a vector of color strings for specifying vertex fill colors.

  • vertex_sizes is a vector of real numbers for specifying vertex sizes.

  • vertex_shapes is a vector of strings for specifying vertex shapes, the string should be "circle" or "box".

  • vertex_stroke_colors is a vector of color strings for specifying vertex stroke colors.

  • vertex_text_colors is a vector of color strings for specifying vertex text colors.

  • edge_colors is a vector of color strings for specifying edge colors.

  • edge_line_widths is a vector of real numbers for specifying edge line widths.

  • texts is a vector of strings for labeling vertices.

  • format is the output format, which can be :svg, :png or :pdf.

  • filename is a string as the output filename.

Extra keyword arguments

  • general
    • xpad::Float64 = 1.0, the padding space in x direction
    • ypad::Float64 = 1.0, the padding space in y direction
    • xpad_right::Float64 = 1.0, the padding space in x direction (right side)
    • ypad_bottom::Float64 = 1.0, the padding space in y direction (bottom side)
    • background_color = DEFAULT_BACKGROUND_COLOR[], the background color
    • unit::Float64 = DEFAULT_UNIT[], the unit distance as the number of pixels
    • fontsize::Float64 = DEFAULT_FONTSIZE[], the font size
    • fontface::String = "", the font face, leave empty to follow system
  • vertex
    • vertex_text_color = DEFAULT_VERTEX_TEXT_COLOR[], the default text color
    • vertex_stroke_color = DEFAULT_VERTEX_STROKE_COLOR[], the default stroke color for vertices
    • vertex_fill_color = DEFAULT_VERTEX_FILL_COLOR[], the default default fill color for vertices
    • vertex_size::Float64 = DEFAULT_VERTEX_SIZE[], the default vertex size
    • vertex_shape::String = "circle", the default vertex shape, which can be "circle" or "box"
    • vertex_line_width::Float64 = 1, the default vertex stroke line width
    • vertex_line_style::String = "solid", the line style of vertex stroke, which can be one of ["solid", "dotted", "dot", "dotdashed", "longdashed", "shortdashed", "dash", "dashed", "dotdotdashed", "dotdotdotdashed"]
  • edge
    • edge_color = DEFAULT_EDGE_COLOR[], the default edge color
    • edge_line_width::Float64 = 1, the default line width
    • edge_style::String = "solid", the line style of edges, which can be one of ["solid", "dotted", "dot", "dotdashed", "longdashed", "shortdashed", "dash", "dashed", "dotdotdashed", "dotdotdotdashed"]

Example

julia> using Graphs
+    kwargs...)

Show a graph in VSCode, Pluto or Jupyter notebook, or save it to a file.

Positional arguments

  • f is a function that returns extra Luxor plotting statements.
  • graph is a graph instance.

Keyword arguments

  • locs is a vector of tuples for specifying the vertex locations.

  • layout is one of [:auto, :spring, :stress], the default value is :spring if locs is nothing.

  • optimal_distance is a optimal distance parameter for spring optimizer.

  • spring_mask specfies which location is optimizable for spring optimizer.

  • vertex_colors is a vector of color strings for specifying vertex fill colors.

  • vertex_sizes is a vector of real numbers for specifying vertex sizes.

  • vertex_shapes is a vector of strings for specifying vertex shapes, the string should be "circle" or "box".

  • vertex_stroke_colors is a vector of color strings for specifying vertex stroke colors.

  • vertex_text_colors is a vector of color strings for specifying vertex text colors.

  • edge_colors is a vector of color strings for specifying edge colors.

  • texts is a vector of strings for labeling vertices.

  • format is the output format, which can be :svg, :png or :pdf.

  • filename is a string as the output filename.

Extra keyword arguments

  • general
    • xpad::Float64 = 1.0, the padding space in x direction
    • ypad::Float64 = 1.0, the padding space in y direction
    • xpad_right::Float64 = 1.0, the padding space in x direction (right side)
    • ypad_bottom::Float64 = 1.0, the padding space in y direction (bottom side)
    • background_color = DEFAULT_BACKGROUND_COLOR[], the background color
    • unit::Float64 = DEFAULT_UNIT[], the unit distance as the number of pixels
    • fontsize::Float64 = DEFAULT_FONTSIZE[], the font size
    • fontface::String = "", the font face, leave empty to follow system
  • vertex
    • vertex_text_color = DEFAULT_VERTEX_TEXT_COLOR[], the default text color
    • vertex_stroke_color = DEFAULT_VERTEX_STROKE_COLOR[], the default stroke color for vertices
    • vertex_color = DEFAULT_VERTEX_FILL_COLOR[], the default default fill color for vertices
    • vertex_size::Float64 = DEFAULT_VERTEX_SIZE[], the default vertex size
    • vertex_shape::String = "circle", the default vertex shape, which can be "circle" or "box"
    • vertex_line_width::Float64 = 1, the default vertex stroke line width
    • vertex_line_style::String = "solid", the line style of vertex stroke, which can be one of ["solid", "dotted", "dot", "dotdashed", "longdashed", "shortdashed", "dash", "dashed", "dotdotdashed", "dotdotdotdashed"]
  • edge
    • edge_color = DEFAULT_EDGE_COLOR[], the default edge color
    • edge_line_width::Float64 = 1, the default line width
    • edge_style::String = "solid", the line style of edges, which can be one of ["solid", "dotted", "dot", "dotdashed", "longdashed", "shortdashed", "dash", "dashed", "dotdotdashed", "dotdotdotdashed"]

Example

julia> using Graphs
 
-julia> show_graph(smallgraph(:petersen); format=:png, vertex_colors=rand(["blue", "red"], 10));
source
LuxorGraphPlot.show_galleryFunction
show_gallery([f, ]graph::SimpleGraph, grid::Tuple{Int,Int};
+julia> show_graph(smallgraph(:petersen); format=:png, vertex_colors=rand(["blue", "red"], 10));
source
LuxorGraphPlot.show_galleryFunction
show_gallery([f, ]graph::SimpleGraph, grid::Tuple{Int,Int};
     locs=nothing,
     layout=:auto,
     optimal_distance=1.0,
@@ -396,7 +395,6 @@
     edge_configs=nothing,
     vertex_color=nothing,
     edge_color=nothing,
-    edge_line_widths=nothing,
 
     vertex_sizes=nothing,
     vertex_shapes=nothing,
@@ -405,11 +403,11 @@
     texts=nothing,
     xpad=1.0,
     ypad=1.0,
-    format=DEFAULT_FORMAT[],
+    format=GraphDisplayConfig.format[],
     filename=nothing,
-    kwargs...)

Show a gallery of graphs for multiple vertex configurations or edge configurations in VSCode, Pluto or Jupyter notebook, or save it to a file.

Positional arguments

  • f is a function that returns extra Luxor plotting statements.
  • graph is a graph instance.
  • grid is the grid layout of the gallery, e.g. input value (2, 3) means a grid layout with 2 rows and 3 columns.

Keyword arguments

  • locs is a vector of tuples for specifying the vertex locations.

  • layout is one of [:auto, :spring, :stress], the default value is :spring if locs is nothing.

  • optimal_distance is a optimal distance parameter for spring optimizer.

  • spring_mask specfies which location is optimizable for spring optimizer.

  • vertex_configs is an iterator of bit strings for specifying vertex configurations. It will be rendered as vertex colors.

  • edge_configs is an iterator of bit strings for specifying edge configurations. It will be rendered as edge colors.

  • edge_color is a dictionary that specifies the edge configuration - color map.

  • edge_line_widths is a vector of real numbers for specifying edge line widths.

  • vertex_color is a dictionary that specifies the vertex configuration - color map.

  • vertex_sizes is a vector of real numbers for specifying vertex sizes.

  • vertex_shapes is a vector of strings for specifying vertex shapes, the string should be "circle" or "box".

  • vertex_stroke_colors is a vector of color strings for specifying vertex stroke colors.

  • vertex_text_colors is a vector of color strings for specifying vertex text colors.

  • texts is a vector of strings for labeling vertices.

  • xpad is the space between two adjacent plots in x direction.

  • ypad is the space between two adjacent plots in y direction.

  • format is the output format, which can be :svg, :png or :pdf.

  • filename is a string as the output filename.

Extra keyword arguments

  • general
    • xpad::Float64 = 1.0, the padding space in x direction
    • ypad::Float64 = 1.0, the padding space in y direction
    • xpad_right::Float64 = 1.0, the padding space in x direction (right side)
    • ypad_bottom::Float64 = 1.0, the padding space in y direction (bottom side)
    • background_color = DEFAULT_BACKGROUND_COLOR[], the background color
    • unit::Float64 = DEFAULT_UNIT[], the unit distance as the number of pixels
    • fontsize::Float64 = DEFAULT_FONTSIZE[], the font size
    • fontface::String = "", the font face, leave empty to follow system
  • vertex
    • vertex_text_color = DEFAULT_VERTEX_TEXT_COLOR[], the default text color
    • vertex_stroke_color = DEFAULT_VERTEX_STROKE_COLOR[], the default stroke color for vertices
    • vertex_fill_color = DEFAULT_VERTEX_FILL_COLOR[], the default default fill color for vertices
    • vertex_size::Float64 = DEFAULT_VERTEX_SIZE[], the default vertex size
    • vertex_shape::String = "circle", the default vertex shape, which can be "circle" or "box"
    • vertex_line_width::Float64 = 1, the default vertex stroke line width
    • vertex_line_style::String = "solid", the line style of vertex stroke, which can be one of ["solid", "dotted", "dot", "dotdashed", "longdashed", "shortdashed", "dash", "dashed", "dotdotdashed", "dotdotdotdashed"]
  • edge
    • edge_color = DEFAULT_EDGE_COLOR[], the default edge color
    • edge_line_width::Float64 = 1, the default line width
    • edge_style::String = "solid", the line style of edges, which can be one of ["solid", "dotted", "dot", "dotdashed", "longdashed", "shortdashed", "dash", "dashed", "dotdotdashed", "dotdotdotdashed"]

Example

julia> using Graphs
+    kwargs...)

Show a gallery of graphs for multiple vertex configurations or edge configurations in VSCode, Pluto or Jupyter notebook, or save it to a file.

Positional arguments

  • f is a function that returns extra Luxor plotting statements.
  • graph is a graph instance.
  • grid is the grid layout of the gallery, e.g. input value (2, 3) means a grid layout with 2 rows and 3 columns.

Keyword arguments

  • locs is a vector of tuples for specifying the vertex locations.

  • layout is one of [:auto, :spring, :stress], the default value is :spring if locs is nothing.

  • optimal_distance is a optimal distance parameter for spring optimizer.

  • spring_mask specfies which location is optimizable for spring optimizer.

  • vertex_configs is an iterator of bit strings for specifying vertex configurations. It will be rendered as vertex colors.

  • edge_configs is an iterator of bit strings for specifying edge configurations. It will be rendered as edge colors.

  • edge_color is a dictionary that specifies the edge configuration - color map.

  • vertex_color is a dictionary that specifies the vertex configuration - color map.

  • vertex_sizes is a vector of real numbers for specifying vertex sizes.

  • vertex_shapes is a vector of strings for specifying vertex shapes, the string should be "circle" or "box".

  • vertex_stroke_colors is a vector of color strings for specifying vertex stroke colors.

  • vertex_text_colors is a vector of color strings for specifying vertex text colors.

  • texts is a vector of strings for labeling vertices.

  • xpad is the space between two adjacent plots in x direction.

  • ypad is the space between two adjacent plots in y direction.

  • format is the output format, which can be :svg, :png or :pdf.

  • filename is a string as the output filename.

Extra keyword arguments

  • general
    • xpad::Float64 = 1.0, the padding space in x direction
    • ypad::Float64 = 1.0, the padding space in y direction
    • xpad_right::Float64 = 1.0, the padding space in x direction (right side)
    • ypad_bottom::Float64 = 1.0, the padding space in y direction (bottom side)
    • background_color = DEFAULT_BACKGROUND_COLOR[], the background color
    • unit::Float64 = DEFAULT_UNIT[], the unit distance as the number of pixels
    • fontsize::Float64 = DEFAULT_FONTSIZE[], the font size
    • fontface::String = "", the font face, leave empty to follow system
  • vertex
    • vertex_text_color = DEFAULT_VERTEX_TEXT_COLOR[], the default text color
    • vertex_stroke_color = DEFAULT_VERTEX_STROKE_COLOR[], the default stroke color for vertices
    • vertex_color = DEFAULT_VERTEX_FILL_COLOR[], the default default fill color for vertices
    • vertex_size::Float64 = DEFAULT_VERTEX_SIZE[], the default vertex size
    • vertex_shape::String = "circle", the default vertex shape, which can be "circle" or "box"
    • vertex_line_width::Float64 = 1, the default vertex stroke line width
    • vertex_line_style::String = "solid", the line style of vertex stroke, which can be one of ["solid", "dotted", "dot", "dotdashed", "longdashed", "shortdashed", "dash", "dashed", "dotdotdashed", "dotdotdotdashed"]
  • edge
    • edge_color = DEFAULT_EDGE_COLOR[], the default edge color
    • edge_line_width::Float64 = 1, the default line width
    • edge_style::String = "solid", the line style of edges, which can be one of ["solid", "dotted", "dot", "dotdashed", "longdashed", "shortdashed", "dash", "dashed", "dotdotdashed", "dotdotdotdashed"]

Example

julia> using Graphs
 
-julia> show_gallery(smallgraph(:petersen), (2, 3); format=:png, vertex_configs=[rand(Bool, 10) for k=1:6]);
source
GenericTensorNetworks.show_einsumFunction
show_einsum(ein::AbstractEinsum;
     tensor_locs=nothing,
     label_locs=nothing,  # dict
     spring::Bool=true,
@@ -425,7 +423,7 @@
     open_label_color="red",
     annotate_labels=true,
     kwargs...
-    )

Positional arguments

  • ein is an Einsum contraction code (provided by package OMEinsum).

Keyword arguments

  • tensor_locs is a vector of tuples for specifying the vertex locations.

  • label_locs is a vector of tuples for specifying the vertex locations.

  • spring is switch to use spring method to optimize the location.

  • optimal_distance is a optimal distance parameter for spring optimizer.

  • tensor_color is a string to specify the color of tensor nodes.

  • tensor_size is a real number to specify the size of tensor nodes.

  • tensor_text_color is a color strings to specify tensor text color.

  • annotate_tensors is a boolean switch for annotate different tensors by integers.

  • label_size is a real number to specify label text node size.

  • label_color is a color strings to specify label text color.

  • open_label_color is a color strings to specify open label text color.

  • annotate_labels is a boolean switch for annotate different labels.

  • format is the output format, which can be :svg, :png or :pdf.

  • filename is a string as the output filename.

Extra keyword arguments

  • general
    • xpad::Float64 = 1.0, the padding space in x direction
    • ypad::Float64 = 1.0, the padding space in y direction
    • xpad_right::Float64 = 1.0, the padding space in x direction (right side)
    • ypad_bottom::Float64 = 1.0, the padding space in y direction (bottom side)
    • background_color = DEFAULT_BACKGROUND_COLOR[], the background color
    • unit::Float64 = DEFAULT_UNIT[], the unit distance as the number of pixels
    • fontsize::Float64 = DEFAULT_FONTSIZE[], the font size
    • fontface::String = "", the font face, leave empty to follow system
  • vertex
    • vertex_text_color = DEFAULT_VERTEX_TEXT_COLOR[], the default text color
    • vertex_stroke_color = DEFAULT_VERTEX_STROKE_COLOR[], the default stroke color for vertices
    • vertex_fill_color = DEFAULT_VERTEX_FILL_COLOR[], the default default fill color for vertices
    • vertex_size::Float64 = DEFAULT_VERTEX_SIZE[], the default vertex size
    • vertex_shape::String = "circle", the default vertex shape, which can be "circle" or "box"
    • vertex_line_width::Float64 = 1, the default vertex stroke line width
    • vertex_line_style::String = "solid", the line style of vertex stroke, which can be one of ["solid", "dotted", "dot", "dotdashed", "longdashed", "shortdashed", "dash", "dashed", "dotdotdashed", "dotdotdotdashed"]
  • edge
    • edge_color = DEFAULT_EDGE_COLOR[], the default edge color
    • edge_line_width::Float64 = 1, the default line width
    • edge_style::String = "solid", the line style of edges, which can be one of ["solid", "dotted", "dot", "dotdashed", "longdashed", "shortdashed", "dash", "dashed", "dotdotdashed", "dotdotdotdashed"]
source
GenericTensorNetworks.line_graphFunction
line_graph(g::SimpleGraph)

Returns the line graph of g. The line graph is generated by mapping an edge to a vertex and two edges sharing a common vertex will be connected.

source

One can also use random_regular_graph and smallgraph in Graphs to build special graphs.

Multiprocessing

GenericTensorNetworks.SimpleMultiprocessing.multiprocess_runFunction
multiprocess_run(func, inputs::AbstractVector)

Execute function func on inputs with multiple processing.

Example

Suppose we have a file run.jl with the following contents

using GenericTensorNetworks.SimpleMultiprocessing
+    )

Positional arguments

  • ein is an Einsum contraction code (provided by package OMEinsum).

Keyword arguments

  • tensor_locs is a vector of tuples for specifying the vertex locations.

  • label_locs is a vector of tuples for specifying the vertex locations.

  • spring is switch to use spring method to optimize the location.

  • optimal_distance is a optimal distance parameter for spring optimizer.

  • tensor_color is a string to specify the color of tensor nodes.

  • tensor_size is a real number to specify the size of tensor nodes.

  • tensor_text_color is a color strings to specify tensor text color.

  • annotate_tensors is a boolean switch for annotate different tensors by integers.

  • label_size is a real number to specify label text node size.

  • label_color is a color strings to specify label text color.

  • open_label_color is a color strings to specify open label text color.

  • annotate_labels is a boolean switch for annotate different labels.

  • format is the output format, which can be :svg, :png or :pdf.

  • filename is a string as the output filename.

Extra keyword arguments

  • general
    • xpad::Float64 = 1.0, the padding space in x direction
    • ypad::Float64 = 1.0, the padding space in y direction
    • xpad_right::Float64 = 1.0, the padding space in x direction (right side)
    • ypad_bottom::Float64 = 1.0, the padding space in y direction (bottom side)
    • background_color = DEFAULT_BACKGROUND_COLOR[], the background color
    • unit::Float64 = DEFAULT_UNIT[], the unit distance as the number of pixels
    • fontsize::Float64 = DEFAULT_FONTSIZE[], the font size
    • fontface::String = "", the font face, leave empty to follow system
  • vertex
    • vertex_text_color = DEFAULT_VERTEX_TEXT_COLOR[], the default text color
    • vertex_stroke_color = DEFAULT_VERTEX_STROKE_COLOR[], the default stroke color for vertices
    • vertex_color = DEFAULT_VERTEX_FILL_COLOR[], the default default fill color for vertices
    • vertex_size::Float64 = DEFAULT_VERTEX_SIZE[], the default vertex size
    • vertex_shape::String = "circle", the default vertex shape, which can be "circle" or "box"
    • vertex_line_width::Float64 = 1, the default vertex stroke line width
    • vertex_line_style::String = "solid", the line style of vertex stroke, which can be one of ["solid", "dotted", "dot", "dotdashed", "longdashed", "shortdashed", "dash", "dashed", "dotdotdashed", "dotdotdotdashed"]
  • edge
    • edge_color = DEFAULT_EDGE_COLOR[], the default edge color
    • edge_line_width::Float64 = 1, the default line width
    • edge_style::String = "solid", the line style of edges, which can be one of ["solid", "dotted", "dot", "dotdashed", "longdashed", "shortdashed", "dash", "dashed", "dotdotdashed", "dotdotdotdashed"]
source
GenericTensorNetworks.line_graphFunction
line_graph(g::SimpleGraph)

Returns the line graph of g. The line graph is generated by mapping an edge to a vertex and two edges sharing a common vertex will be connected.

source

One can also use random_regular_graph and smallgraph in Graphs to build special graphs.

Multiprocessing

GenericTensorNetworks.SimpleMultiprocessing.multiprocess_runFunction
multiprocess_run(func, inputs::AbstractVector)

Execute function func on inputs with multiple processing.

Example

Suppose we have a file run.jl with the following contents

using GenericTensorNetworks.SimpleMultiprocessing
 
 results = multiprocess_run(x->x^2, randn(8))

In an terminal, you may run the script with 4 processes by typing

$ julia -p4 run.jl
       From worker 2:	[ Info: running argument -0.17544008350172655 on device 2
@@ -435,4 +433,4 @@
       From worker 2:	[ Info: running argument 0.013132180639054629 on device 2
       From worker 3:	[ Info: running argument 0.9960101782201602 on device 3
       From worker 4:	[ Info: running argument -0.5613942832743966 on device 4
-      From worker 5:	[ Info: running argument 0.39460402723831134 on device 5
source
+ From worker 5: [ Info: running argument 0.39460402723831134 on device 5source diff --git a/dev/search_index.js b/dev/search_index.js index ce11971c..f332a38b 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"EditURL = \"../../../examples/IndependentSet.jl\"","category":"page"},{"location":"generated/IndependentSet/#Independent-set-problem","page":"Independent set problem","title":"Independent set problem","text":"","category":"section"},{"location":"generated/IndependentSet/#Problem-definition","page":"Independent set problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"In graph theory, an independent set is a set of vertices in a graph, no two of which are adjacent.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"In the following, we are going to solve the solution space properties of the independent set problem on the Petersen graph. To start, let us define a Petersen graph instance.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"using GenericTensorNetworks, Graphs\n\ngraph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can visualize this graph using the show_graph function","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"# set the vertex locations manually instead of using the default spring layout\nrot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a\n\nlocations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]\n\nshow_graph(graph; locs=locations, format=:svg)","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The graphical display is available in the following editors","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"a VSCode editor,\na Jupyter notebook,\nor a Pluto notebook,","category":"page"},{"location":"generated/IndependentSet/#Generic-tensor-network-representation","page":"Independent set problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The generic tensor network representation of the independent set problem can be constructed with IndependentSet.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"problem = IndependentSet(graph; optimizer=TreeSA());\nnothing #hide","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"Here, the key word argument optimizer specifies the tensor network contraction order optimizer as a local search based optimizer TreeSA. The resulting contraction order optimized tensor network is contained in the code field of problem.","category":"page"},{"location":"generated/IndependentSet/#Theory-(can-skip)","page":"Independent set problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"Let G=(V E) be a graph with each vertex vin V associated with a weight w_v. To reduce the independent set problem on it to a tensor network contraction, we first map a vertex vin V to a label s_v in 0 1 of dimension 2, where we use 0 (1) to denote a vertex absent (present) in the set. For each vertex v, we defined a parameterized rank-one tensor indexed by s_v as","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"W(x_v^w_v) = left(beginmatrix\n 1 \n x_v^w_v\n endmatrixright)","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"where x_v is a variable associated with v. Similarly, for each edge (u v) in E, we define a matrix B indexed by s_u and s_v as","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"B = left(beginmatrix\n1 1\n1 0\nendmatrixright)","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"Ideally, an optimal contraction order has a space complexity 2^rm tw(G), where rm tw(G) is the tree-width of G (or graph in the code). We can check the time, space and read-write complexities by typing","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"contraction_complexity(problem)","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"For more information about how to improve the contraction order, please check the Performance Tips.","category":"page"},{"location":"generated/IndependentSet/#Solution-space-properties","page":"Independent set problem","title":"Solution space properties","text":"","category":"section"},{"location":"generated/IndependentSet/#Maximum-independent-set-size-\\alpha(G)","page":"Independent set problem","title":"Maximum independent set size alpha(G)","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can compute solution space properties with the solve function, which takes two positional arguments, the problem instance and the wanted property.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"maximum_independent_set_size = solve(problem, SizeMax())[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"Here SizeMax means finding the solution with maximum set size. The return value has Tropical type. We can get its content by typing","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"maximum_independent_set_size.n","category":"page"},{"location":"generated/IndependentSet/#Counting-properties","page":"Independent set problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/IndependentSet/#Count-all-solutions-and-best-several-solutions","page":"Independent set problem","title":"Count all solutions and best several solutions","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can count all independent sets with the CountingAll property.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"count_all_independent_sets = solve(problem, CountingAll())[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The return value has type Float64. The counting of all independent sets is equivalent to the infinite temperature partition function","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"solve(problem, PartitionFunction(0.0))[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can count the maximum independent sets with CountingMax.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"count_maximum_independent_sets = solve(problem, CountingMax())[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The return value has type CountingTropical, which contains two fields. They are n being the maximum independent set size and c being the number of the maximum independent sets.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"count_maximum_independent_sets.c","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"Similarly, we can count independent sets of sizes alpha(G) and alpha(G)-1 by feeding an integer positional argument to CountingMax.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"count_max2_independent_sets = solve(problem, CountingMax(2))[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The return value has type TruncatedPoly, which contains two fields. They are maxorder being the maximum independent set size and coeffs being the number of independent sets having sizes alpha(G)-1 and alpha(G).","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"count_max2_independent_sets.coeffs","category":"page"},{"location":"generated/IndependentSet/#Find-the-graph-polynomial","page":"Independent set problem","title":"Find the graph polynomial","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can count the number of independent sets at any size, which is equivalent to finding the coefficients of an independence polynomial that defined as","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"I(G x) = sum_k=0^alpha(G) a_k x^k","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"where alpha(G) is the maximum independent set size, a_k is the number of independent sets of size k. The total number of independent sets is thus equal to I(G 1). There are 3 methods to compute a graph polynomial, :finitefield, :fft and :polynomial. These methods are introduced in the docstring of GraphPolynomial.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"independence_polynomial = solve(problem, GraphPolynomial(; method=:finitefield))[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The return type is Polynomial.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"independence_polynomial.coeffs","category":"page"},{"location":"generated/IndependentSet/#Configuration-properties","page":"Independent set problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/IndependentSet/#Find-one-best-solution","page":"Independent set problem","title":"Find one best solution","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can use the bounded or unbounded SingleConfigMax to find one of the solutions with largest size. The unbounded (default) version uses a joint type of CountingTropical and ConfigSampler in computation, where CountingTropical finds the maximum size and ConfigSampler samples one of the best solutions. The bounded version uses the binary gradient back-propagation (see our paper) to compute the gradients. It requires caching intermediate states, but is often faster (on CPU) because it can use TropicalGEMM (see Performance Tips).","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"max_config = solve(problem, SingleConfigMax(; bounded=false))[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The return value has type CountingTropical with its counting field having ConfigSampler type. The data field of ConfigSampler is a bit string that corresponds to the solution","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"single_solution = max_config.c.data","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"This bit string should be read from left to right, with the i-th bit being 1 (0) to indicate the i-th vertex is present (absent) in the set. We can visualize this MIS with the following function.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"show_graph(graph; locs=locations, format=:svg, vertex_colors=\n [iszero(single_solution[i]) ? \"white\" : \"red\" for i=1:nv(graph)])","category":"page"},{"location":"generated/IndependentSet/#Enumerate-all-solutions-and-best-several-solutions","page":"Independent set problem","title":"Enumerate all solutions and best several solutions","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can use bounded or unbounded ConfigsMax to find all solutions with largest-K set sizes. In most cases, the bounded (default) version is preferred because it can reduce the memory usage significantly.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"all_max_configs = solve(problem, ConfigsMax(; bounded=true))[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The return value has type CountingTropical, while its counting field having type ConfigEnumerator. The data field of a ConfigEnumerator instance contains a vector of bit strings.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"all_max_configs.c.data","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"These solutions can be visualized with the show_gallery function.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"show_gallery(graph, (1, length(all_max_configs.c)); locs=locations, vertex_configs=all_max_configs.c, format=:svg)","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can use ConfigsAll to enumerate all sets satisfying the independence constraint.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"all_independent_sets = solve(problem, ConfigsAll())[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The return value has type ConfigEnumerator.","category":"page"},{"location":"generated/IndependentSet/#Sample-solutions","page":"Independent set problem","title":"Sample solutions","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"It is often difficult to store all configurations in a vector. A more clever way to store the data is using the sum product tree format.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"all_independent_sets_tree = solve(problem, ConfigsAll(; tree_storage=true))[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The return value has the SumProductTree type. Its length corresponds to the number of configurations.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"length(all_independent_sets_tree)","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can use Base.collect function to create a ConfigEnumerator or use generate_samples to generate samples from it.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"collect(all_independent_sets_tree)\n\ngenerate_samples(all_independent_sets_tree, 10)","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"EditURL = \"../../../examples/PaintShop.jl\"","category":"page"},{"location":"generated/PaintShop/#Binary-paint-shop-problem","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"","category":"section"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/PaintShop/#Problem-Definition","page":"Binary paint shop problem","title":"Problem Definition","text":"","category":"section"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"The binary paint shop problem is defined as follows: we are given a 2m length sequence containing m cars, where each car appears twice. Each car need to be colored red in one occurrence, and blue in the other. We need to choose which occurrence for each car to color with which color — the goal is to minimize the number of times we need to change the current color.","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"In the following, we use a character to represent a car, and defined a binary paint shop problem as a string that each character appear exactly twice.","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"using GenericTensorNetworks, Graphs\n\nsequence = collect(\"iadgbeadfcchghebif\")","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"We can visualize this paint shop problem as a graph","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"rot(a, b, θ) = cos(θ)*a + sin(θ)*b, cos(θ)*b - sin(θ)*a\n\nlocations = [rot(0.0, 2.0, -0.25π - 1.5*π*(i-0.5)/length(sequence)) for i=1:length(sequence)]\n\ngraph = path_graph(length(sequence))\nfor i=1:length(sequence)\n j = findlast(==(sequence[i]), sequence)\n i != j && add_edge!(graph, i, j)\nend\n\nshow_graph(graph; locs=locations, texts=string.(sequence), format=:svg, edge_colors=\n [sequence[e.src] == sequence[e.dst] ? \"blue\" : \"black\" for e in edges(graph)])","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"Vertices connected by blue edges must have different colors, and the goal becomes a min-cut problem defined on black edges.","category":"page"},{"location":"generated/PaintShop/#Generic-tensor-network-representation","page":"Binary paint shop problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"Let us construct the problem instance as bellow.","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"problem = PaintShop(sequence);\nnothing #hide","category":"page"},{"location":"generated/PaintShop/#Theory-(can-skip)","page":"Binary paint shop problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"Type PaintShop can be used for constructing the tensor network with optimized contraction order for solving a binary paint shop problem. To obtain its tensor network representation, we associating car c_i (the i-th character in our example) with a degree of freedom s_c_i in 0 1, where we use 0 to denote the first appearance of a car is colored red and 1 to denote the first appearance of a car is colored blue. For each black edges (i i+1), we define an edge tensor labeled by (s_c_i s_c_i+1) as follows: If both cars on this edge are their first or second appearance","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"B^rm parallel = left(beginmatrix\nx 1 \n1 x \nendmatrixright)","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"otherwise,","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"B^rm anti-parallel = left(beginmatrix\n1 x \nx 1 \nendmatrixright)","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"It can be understood as, when both cars are their first appearance, they tend to have the same configuration so that the color is not changed. Otherwise, they tend to have different configuration to keep the color unchanged.","category":"page"},{"location":"generated/PaintShop/#Counting-properties","page":"Binary paint shop problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/PaintShop/#graph-polynomial","page":"Binary paint shop problem","title":"graph polynomial","text":"","category":"section"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"The graph polynomial defined for the maximal independent set problem is","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"I_rm max(G x) = sum_k=0^alpha(G) b_k x^k","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"where b_k is the number of maximal independent sets of size k in graph G=(V E).","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"max_config = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"Since it only counts the maximal independent sets, the first several coefficients are 0.","category":"page"},{"location":"generated/PaintShop/#Counting-properties-2","page":"Binary paint shop problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/PaintShop/#graph-polynomial-2","page":"Binary paint shop problem","title":"graph polynomial","text":"","category":"section"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"The graph polynomial of the binary paint shop problem in our convention is defined as","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"P(G x) = sum_k=0^delta(G) p_k x^k","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"where p_k is the number of possible coloring with number of color changes 2m-1-k.","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"paint_polynomial = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/PaintShop/#Configuration-properties","page":"Binary paint shop problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/PaintShop/#finding-best-solutions","page":"Binary paint shop problem","title":"finding best solutions","text":"","category":"section"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"best_configs = solve(problem, ConfigsMin())[]","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"One can see to identical bitstrings corresponding two different vertex configurations, they are related to bit-flip symmetry.","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"painting1 = paint_shop_coloring_from_config(problem, best_configs.c.data[1])\n\nshow_graph(graph; locs=locations, format=:svg, texts=string.(sequence),\n edge_colors=[sequence[e.src] == sequence[e.dst] ? \"blue\" : \"black\" for e in edges(graph)],\n vertex_colors=[isone(c) ? \"red\" : \"black\" for c in painting1], vertex_text_color=\"white\")","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"Since we have different choices of initial color, the number of best solution is 2.","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"The following function will check the solution and return you the number of color switches","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"num_paint_shop_color_switch(sequence, painting1)","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"sumproduct/#Sum-product-representation-for-configurations","page":"Sum product tree representation","title":"Sum product representation for configurations","text":"","category":"section"},{"location":"sumproduct/","page":"Sum product tree representation","title":"Sum product tree representation","text":"SumProductTree can use polynomial memory to store exponential number of configurations. It is a sum-product expression tree to store ConfigEnumerator in a lazy style, where configurations can be extracted by depth first searching the tree with the Base.collect method. Although it is space efficient, it is in general not easy to extract information from it due to the exponential large configuration space. Directed sampling is one of its most important operations, with which one can get some statistic properties from it with an intermediate effort. For example, if we want to check some property of an intermediate scale graph, one can type","category":"page"},{"location":"sumproduct/","page":"Sum product tree representation","title":"Sum product tree representation","text":"julia> graph = random_regular_graph(70, 3)\n\njulia> problem = IndependentSet(graph; optimizer=TreeSA());\n\njulia> tree = solve(problem, ConfigsAll(; tree_storage=true))[];\n16633909006371","category":"page"},{"location":"sumproduct/","page":"Sum product tree representation","title":"Sum product tree representation","text":"If one wants to store these configurations, he will need a hard disk of size 256 TB! However, this sum-product binary tree structure supports efficient and unbiased direct sampling.","category":"page"},{"location":"sumproduct/","page":"Sum product tree representation","title":"Sum product tree representation","text":"samples = generate_samples(tree, 1000);","category":"page"},{"location":"sumproduct/","page":"Sum product tree representation","title":"Sum product tree representation","text":"With these samples, one can already compute useful properties like Hamming distance (see hamming_distribution) distribution.","category":"page"},{"location":"sumproduct/","page":"Sum product tree representation","title":"Sum product tree representation","text":"julia> using UnicodePlots\n\njulia> lineplot(hamming_distribution(samples, samples))\n ┌────────────────────────────────────────┐ \n 100000 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠹⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡎⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡇⠀⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠸⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠃⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡞⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠁⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⡼⠀⠀⠀⠀⠀⠀⠈⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⢠⠇⠀⠀⠀⠀⠀⠀⠀⢳⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n 0 │⢀⣀⣀⣀⣀⣀⣀⣀⠎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠓⢄⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⠀⠀⠀⠀│ \n └────────────────────────────────────────┘ \n ⠀0⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀80⠀ ","category":"page"},{"location":"sumproduct/","page":"Sum product tree representation","title":"Sum product tree representation","text":"Here, the x-axis is the Hamming distance and the y-axis is the counting of pair-wise Hamming distances.","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"EditURL = \"../../../examples/Coloring.jl\"","category":"page"},{"location":"generated/Coloring/#Coloring-problem","page":"Coloring problem","title":"Coloring problem","text":"","category":"section"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/Coloring/#Problem-definition","page":"Coloring problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"A vertex coloring is an assignment of labels or colors to each vertex of a graph such that no edge connects two identically colored vertices. In the following, we are going to defined a 3-coloring problem for the Petersen graph.","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"using GenericTensorNetworks, Graphs\n\ngraph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"We can visualize this graph using the following function","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a\n\nlocations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]\n\nshow_graph(graph; locs=locations, format=:svg)","category":"page"},{"location":"generated/Coloring/#Generic-tensor-network-representation","page":"Coloring problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"We construct the tensor network for the 3-coloring problem as","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"problem = Coloring{3}(graph);\nnothing #hide","category":"page"},{"location":"generated/Coloring/#Theory-(can-skip)","page":"Coloring problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"Type Coloring can be used for constructing the tensor network with optimized contraction order for a coloring problem. Let us use 3-coloring problem defined on vertices as an example. For a vertex v, we define the degrees of freedom c_vin123 and a vertex tensor labelled by it as","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"W(v) = left(beginmatrix\n 1\n 1\n 1\nendmatrixright)","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"For an edge (u v), we define an edge tensor as a matrix labelled by (c_u c_v) to specify the constraint","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"B = left(beginmatrix\n 1 x x\n x 1 x\n x x 1\nendmatrixright)","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"The number of possible coloring can be obtained by contracting this tensor network by setting vertex tensor elements r_v g_v and b_v to 1.","category":"page"},{"location":"generated/Coloring/#Solving-properties","page":"Coloring problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/Coloring/#counting-all-possible-coloring","page":"Coloring problem","title":"counting all possible coloring","text":"","category":"section"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"num_of_coloring = solve(problem, CountingMax())[]","category":"page"},{"location":"generated/Coloring/#finding-one-best-coloring","page":"Coloring problem","title":"finding one best coloring","text":"","category":"section"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"single_solution = solve(problem, SingleConfigMax())[]\n\nis_vertex_coloring(graph, single_solution.c.data)\n\nvertex_color_map = Dict(0=>\"red\", 1=>\"green\", 2=>\"blue\")\n\nshow_graph(graph; locs=locations, format=:svg, vertex_colors=[vertex_color_map[Int(c)]\n for c in single_solution.c.data])","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"Let us try to solve the same issue on its line graph, a graph that generated by mapping an edge to a vertex and two edges sharing a common vertex will be connected.","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"linegraph = line_graph(graph)\n\nshow_graph(linegraph; locs=[0.5 .* (locations[e.src] .+ locations[e.dst])\n for e in edges(graph)], format=:svg)","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"Let us construct the tensor network and see if there are solutions.","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"lineproblem = Coloring{3}(linegraph);\n\nnum_of_coloring = solve(lineproblem, CountingMax())[]","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"You will see the maximum size 28 is smaller than the number of edges in the linegraph, meaning no solution for the 3-coloring on edges of a Petersen graph.","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"EditURL = \"../../../examples/SetPacking.jl\"","category":"page"},{"location":"generated/SetPacking/#Set-packing-problem","page":"Set packing problem","title":"Set packing problem","text":"","category":"section"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/SetPacking/#Problem-definition","page":"Set packing problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"The set packing problem is generalization of the IndependentSet problem from the simple graph to the multigraph. Suppose one has a finite set S and a list of subsets of S. Then, the set packing problem asks if some k subsets in the list are pairwise disjoint. In the following, we will find the solution space properties for the set in the Set covering problem.","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"using GenericTensorNetworks, Graphs","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"The packing stadium areas of cameras are represented as the following sets.","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"sets = [[1,3,4,6,7], [4,7,8,12], [2,5,9,11,13],\n [1,2,14,15], [3,6,10,12,14], [8,14,15],\n [1,2,6,11], [1,2,4,6,8,12]]","category":"page"},{"location":"generated/SetPacking/#Generic-tensor-network-representation","page":"Set packing problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"We create a [SetPacking] instance that contains a generic tensor network as its code field.","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"problem = SetPacking(sets);\nnothing #hide","category":"page"},{"location":"generated/SetPacking/#Theory-(can-skip)","page":"Set packing problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"Let S be the target set packing problem that we want to solve. For each set s in S, we associate it with a weight w_s to it. The tensor network representation map a set sin S to a boolean degree of freedom v_sin0 1. For each set s, we defined a parameterized rank-one tensor indexed by v_s as","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"W(x_s^w_s) = left(beginmatrix\n 1 \n x_s^w_s\n endmatrixright)","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"where x_s is a variable associated with s. For each unique element a, we defined the constraint over all sets containing it N(a) = s s in S land ain s:","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"B_s_1s_2ldotss_N(a) = begincases\n 0 s_1+s_2+ldots+s_N(a) 1\n 1 textotherwise\nendcases","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"This tensor means if in a configuration, two sets contain the element a, then this configuration is forbidden, One can check the contraction time space complexity of a SetPacking instance by typing:","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"contraction_complexity(problem)","category":"page"},{"location":"generated/SetPacking/#Solving-properties","page":"Set packing problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/SetPacking/#Counting-properties","page":"Set packing problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/SetPacking/#The-\"graph\"-polynomial","page":"Set packing problem","title":"The \"graph\" polynomial","text":"","category":"section"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"The graph polynomial for the set packing problem is defined as","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"P(S x) = sum_k=0^alpha(S) c_k x^k","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"where c_k is the number of configurations having k sets, and alpha(S) is the maximum size of the packing.","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"packing_polynomial = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"The maximum number of sets that packing the set of elements can be computed with the SizeMax property:","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"max_packing_size = solve(problem, SizeMax())[]","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"Similarly, we have its counting CountingMax:","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"counting_maximum_set_packing = solve(problem, CountingMax())[]","category":"page"},{"location":"generated/SetPacking/#Configuration-properties","page":"Set packing problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/SetPacking/#Finding-maximum-set-packing","page":"Set packing problem","title":"Finding maximum set packing","text":"","category":"section"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"One can enumerate all maximum set packing with the ConfigsMax property in the program.","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"max_configs = solve(problem, ConfigsMax())[].c","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"Hence the only optimal solution is z_1 z_3 z_6 that has size 3. The correctness of this result can be checked with the is_set_packing function.","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"all(c->is_set_packing(sets, c), max_configs)","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"Similarly, if one is only interested in computing one of the maximum set packing, one can use the graph property SingleConfigMax.","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"EditURL = \"../../../examples/open.jl\"","category":"page"},{"location":"generated/open/#Open-and-fixed-degrees-of-freedom","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"","category":"section"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"Open degrees of freedom is useful when one want to get the marginal about certain degrees of freedom. When one specifies the openvertices keyword argument in solve function as a tuple of vertices, the output will be a tensor that can be indexed by these degrees of freedom. Let us use the maximum independent set problem on Petersen graph as an example.","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"using GenericTensorNetworks, Graphs\n\ngraph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"The following code computes the MIS tropical tensor (reference to be added) with open vertices 1, 2 and 3.","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"problem = IndependentSet(graph; openvertices=[1,2,3]);\n\nmarginal = solve(problem, SizeMax())","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"The return value is a rank-3 tensor, with its elements being the MIS sizes under different configuration of open vertices. For the maximum independent set problem, this tensor is also called the MIS tropical tensor, which can be useful in the MIS tropical tensor analysis (reference to be added).","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"One can also specify the fixed degrees of freedom by providing the fixedvertices keyword argument as a Dict, which can be used to get conditioned probability. For example, we can use the following code to do the same calculation as using openvertices.","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"problem = IndependentSet(graph; fixedvertices=Dict(1=>0, 2=>0, 3=>0));\n\noutput = zeros(TropicalF64,2,2,2);\n\nmarginal_alternative = map(CartesianIndices((2,2,2))) do ci\n problem.fixedvertices[1] = ci.I[1]-1\n problem.fixedvertices[2] = ci.I[2]-1\n problem.fixedvertices[3] = ci.I[3]-1\n output[ci] = solve(problem, SizeMax())[]\nend","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"One can easily check this one also gets the correct marginal on vertices 1, 2 and 3. As a reminder, their computational hardness can be different, because the contraction order optimization program can optimize over open degrees of freedom.","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"EditURL = \"../../../examples/HyperSpinGlass.jl\"","category":"page"},{"location":"generated/HyperSpinGlass/#Hyper-Spin-glass-problem","page":"Hyper Spin glass problem","title":"Hyper-Spin-glass problem","text":"","category":"section"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/HyperSpinGlass/#Problem-definition","page":"Hyper Spin glass problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"The hyper-spin-glass problem is a natural generalization of the spin-glass problem from simple graph to hypergraph. A hyper-spin-glass problem of hypergraph H = (V E) can be characterized by the following energy function","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"E = sum_c in E w_c prod_vin c S_v","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"where S_v in -1 1, w_c is coupling strength associated with hyperedge c. In the program, we use boolean variable s_v = frac1-S_v2 to represent a spin configuration.","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"using GenericTensorNetworks","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"In the following, we are going to defined an spin glass problem for the following hypergraph.","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"num_vertices = 15\n\nhyperedges = [[1,3,4,6,7], [4,7,8,12], [2,5,9,11,13],\n [1,2,14,15], [3,6,10,12,14], [8,14,15],\n [1,2,6,11], [1,2,4,6,8,12]]\n\nweights = [-1, 1, -1, 1, -1, 1, -1, 1];\nnothing #hide","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"The energy function is","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"beginalign*\nE = -S_1S_3S_4S_6S_7 + S_4S_7S_8S_12 - S_2S_5S_9S_11S_13 +\n S_1S_2S_14S_15 - S_3S_6S_10S_12S_14 + S_8S_14S_15 +\n S_1S_2S_6S_11 - S_1s_2S_4S_6S_8S_12\nendalign*","category":"page"},{"location":"generated/HyperSpinGlass/#Generic-tensor-network-representation","page":"Hyper Spin glass problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"We define an anti-ferromagnetic spin glass problem as","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"problem = HyperSpinGlass(num_vertices, hyperedges; weights);\nnothing #hide","category":"page"},{"location":"generated/HyperSpinGlass/#Theory-(can-skip)","page":"Hyper Spin glass problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"Let H = (V E) be a hypergraph. The tensor network for the partition function of the energy model for H can be defined as the following triple of (alphabet of labels, input tensors, output labels).","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"begincases\nLambda = s_v mid v in V\nmathcalT = B^(c)_s_N(c 1)N(c 2)ldotsN(c d(c)) mid c in E cup W^(v)_s_v mid v in V\nsigma_o = varepsilon\nendcases","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"where s_v in 0 1 is the boolean degreen associated to vertex v, N(c k) is the kth vertex of hyperedge c, and d(c) is the degree of c. The edge tensor B^(c) is defined as","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"B^(c) = begincases\nx^w_c (sum_vin c s_v) is even \nx^-w_c otherwise\nendcases","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"and the vertex tensor W^(v) (used to carry labels) is defined as","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"W^(v) = left(beginmatrix1_v 1_vendmatrixright)","category":"page"},{"location":"generated/HyperSpinGlass/#Solving-properties","page":"Hyper Spin glass problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/HyperSpinGlass/#Minimum-and-maximum-energies","page":"Hyper Spin glass problem","title":"Minimum and maximum energies","text":"","category":"section"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"Its ground state energy is -8.","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"Emin = solve(problem, SizeMin())[]","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"While the state correspond to the highest energy has the ferromagnetic order.","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"Emax = solve(problem, SizeMax())[]","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"In this example, the spin configurations can be chosen to make all hyperedges having even or odd spin parity.","category":"page"},{"location":"generated/HyperSpinGlass/#Counting-properties","page":"Hyper Spin glass problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/HyperSpinGlass/#partition-function-and-graph-polynomial","page":"Hyper Spin glass problem","title":"partition function and graph polynomial","text":"","category":"section"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"The graph polynomial defined for the hyper-spin-glass problem is a Laurent polynomial","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"Z(G w x) = sum_k=E_rm min^E_rm max c_k x^k","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"where E_rm min and E_rm max are minimum and maximum energies, c_k is the number of spin configurations with energy k. Let the inverse temperature beta = 2, the partition function is","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"β = 2.0\nZ = solve(problem, PartitionFunction(β))[]","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"The infinite temperature partition function is the counting of all feasible configurations","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"solve(problem, PartitionFunction(0.0))[]","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"Let x = e^beta, it corresponds to the partition function of a spin glass at temperature beta^-1.","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"poly = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/HyperSpinGlass/#Configuration-properties","page":"Hyper Spin glass problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/HyperSpinGlass/#finding-a-ground-state","page":"Hyper Spin glass problem","title":"finding a ground state","text":"","category":"section"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"ground_state = solve(problem, SingleConfigMin())[].c.data\n\nEmin_verify = hyperspinglass_energy(hyperedges, ground_state; weights)","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"You should see a consistent result as above Emin.","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"EditURL = \"../../../examples/Matching.jl\"","category":"page"},{"location":"generated/Matching/#Vertex-matching-problem","page":"Vertex matching problem","title":"Vertex matching problem","text":"","category":"section"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/Matching/#Problem-definition","page":"Vertex matching problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"A k-matching in a graph G is a set of k edges, no two of which have a vertex in common.","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"using GenericTensorNetworks, Graphs","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"In the following, we are going to defined a matching problem for the Petersen graph.","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"graph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"We can visualize this graph using the following function","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a\n\nlocations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]\n\nshow_graph(graph; locs=locations, format=:svg)","category":"page"},{"location":"generated/Matching/#Generic-tensor-network-representation","page":"Vertex matching problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"We construct the tensor network for the matching problem by typing","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"problem = Matching(graph);\nnothing #hide","category":"page"},{"location":"generated/Matching/#Theory-(can-skip)","page":"Vertex matching problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"Type Matching can be used for constructing the tensor network with optimized contraction order for a matching problem. We map an edge (u v) in E to a label langle u vrangle in 0 1 in a tensor network, where 1 means two vertices of an edge are matched, 0 means otherwise. Then we define a tensor of rank d(v) = N(v) on vertex v such that,","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"W_langle v n_1rangle langle v n_2 rangle ldots langle v n_d(v)rangle = begincases\n 1 sum_i=1^d(v) langle v n_i rangle leq 1\n 0 textotherwise\nendcases","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"and a tensor of rank 1 on the bond","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"B_langle v wrangle = begincases\n1 langle v w rangle = 0 \nx langle v w rangle = 1\nendcases","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"where label langle v w rangle is equivalent to langle wvrangle.","category":"page"},{"location":"generated/Matching/#Solving-properties","page":"Vertex matching problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/Matching/#Maximum-matching","page":"Vertex matching problem","title":"Maximum matching","text":"","category":"section"},{"location":"generated/Matching/#Configuration-properties","page":"Vertex matching problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"max_matching = solve(problem, SizeMax())[]","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"The largest number of matching is 5, which means we have a perfect matching (vertices are all paired).","category":"page"},{"location":"generated/Matching/#matching-polynomial","page":"Vertex matching problem","title":"matching polynomial","text":"","category":"section"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"The graph polynomial defined for the matching problem is known as the matching polynomial. Here, we adopt the first definition in the wiki page.","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"M(G x) = sumlimits_k=1^V2 c_k x^k","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"where k is the number of matches, and coefficients c_k are the corresponding counting.","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"matching_poly = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/Matching/#Configuration-properties-2","page":"Vertex matching problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/Matching/#one-of-the-perfect-matches","page":"Vertex matching problem","title":"one of the perfect matches","text":"","category":"section"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"match_config = solve(problem, SingleConfigMax())[]","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"Let us show the result by coloring the matched edges to red","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"show_graph(graph; locs=locations, format=:svg, edge_colors=\n [isone(match_config.c.data[i]) ? \"red\" : \"black\" for i=1:ne(graph)])","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"where we use edges with red color to related pairs of matched vertices.","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"EditURL = \"../../../examples/Satisfiability.jl\"","category":"page"},{"location":"generated/Satisfiability/#Satisfiability-problem","page":"Satisfiability problem","title":"Satisfiability problem","text":"","category":"section"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/Satisfiability/#Problem-definition","page":"Satisfiability problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"In logic and computer science, the boolean satisfiability problem is the problem of determining if there exists an interpretation that satisfies a given boolean formula. One can specify a satisfiable problem in the conjunctive normal form. In boolean logic, a formula is in conjunctive normal form (CNF) if it is a conjunction (∧) of one or more clauses, where a clause is a disjunction (∨) of literals.","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"using GenericTensorNetworks\n\n@bools a b c d e f g\n\ncnf = ∧(∨(a, b, ¬d, ¬e), ∨(¬a, d, e, ¬f), ∨(f, g), ∨(¬b, c))","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"To goal is to find an assignment to satisfy the above CNF. For a satisfiability problem at this size, we can find the following assignment to satisfy this assignment manually.","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"assignment = Dict([:a=>true, :b=>false, :c=>false, :d=>true, :e=>false, :f=>false, :g=>true])\n\nsatisfiable(cnf, assignment)","category":"page"},{"location":"generated/Satisfiability/#Generic-tensor-network-representation","page":"Satisfiability problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"If we contract this tensor network, we will get a multiplicative factor x whenever there is a clause satisfied.","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"problem = Satisfiability(cnf);\nnothing #hide","category":"page"},{"location":"generated/Satisfiability/#Theory-(can-skip)","page":"Satisfiability problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"We can construct a Satisfiability problem to solve the above problem. To generate a tensor network, we map a boolean variable x and its negation neg x to a degree of freedom (label) s_x in 0 1, where 0 stands for variable x having value false while 1 stands for having value true. Then we map a clause to a tensor. For example, a clause x y z can be mapped to a tensor labeled by (s_x s_y s_z).","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"C = left(beginmatrix\nleft(beginmatrix\nx x \nx x\nendmatrixright) \nleft(beginmatrix\nx x \n1 x\nendmatrixright)\nendmatrixright)","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"There is only one entry (s_x s_y s_z) = (1 0 1) that makes this clause unsatisfied.","category":"page"},{"location":"generated/Satisfiability/#Solving-properties","page":"Satisfiability problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/Satisfiability/#Satisfiability-and-its-counting","page":"Satisfiability problem","title":"Satisfiability and its counting","text":"","category":"section"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"The size of a satisfiability problem is defined by the number of satisfiable clauses.","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"num_satisfiable = solve(problem, SizeMax())[]","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"The GraphPolynomial of a satisfiability problem counts the number of solutions that k clauses satisfied.","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"num_satisfiable_count = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/Satisfiability/#Find-one-of-the-solutions","page":"Satisfiability problem","title":"Find one of the solutions","text":"","category":"section"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"single_config = solve(problem, SingleConfigMax())[].c.data","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"One will see a bit vector printed. One can create an assignment and check the validity with the following statement:","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"satisfiable(cnf, Dict(zip(labels(problem), single_config)))","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"EditURL = \"../../../examples/SpinGlass.jl\"","category":"page"},{"location":"generated/SpinGlass/#Spin-glass-problem","page":"Spin glass problem","title":"Spin-glass problem","text":"","category":"section"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/SpinGlass/#Problem-definition","page":"Spin glass problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"Let G=(V E) be a graph, the spin-glass problem in physics is characterized by the following energy function","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"H = -sum_ij in E J_ij s_i s_j + sum_i in V h_i s_i","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"where h_i is an onsite energy term associated with spin s_i in -1 1, and J_ij is the coupling strength between spins s_i and s_j. In the program, we use boolean variable n_i = frac1-s_i2 to represent a spin configuration.","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"using GenericTensorNetworks, Graphs","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"In the following, we are going to defined an spin glass problem for the Petersen graph.","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"graph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"We can visualize this graph using the following function","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a\n\nlocations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]\n\nshow_graph(graph; locs=locations, format=:svg)","category":"page"},{"location":"generated/SpinGlass/#Generic-tensor-network-representation","page":"Spin glass problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"We define an anti-ferromagnetic spin glass problem as","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"problem = SpinGlass(graph; J=fill(-1, ne(graph)));\nnothing #hide","category":"page"},{"location":"generated/SpinGlass/#Theory-(can-skip)","page":"Spin glass problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"The spin glass problem is reduced to the Cutting problem for solving. Let G=(VE) be a graph, the cutting problem can also be described by the following energy model","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"H^c = sum_ij in E C_ij ((1 - n_i) n_j + (1 - n_j) n_i) + sum_i in V w_i n_i","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"where n_i is the same as the partition index in the cutting problem, C_ij = 2J_ij are edge weights and w_i = -2h_i are vertex weights. The total energy is shifted by -sum_ijin EJ_ij + sum_i in V h_i.","category":"page"},{"location":"generated/SpinGlass/#Solving-properties","page":"Spin glass problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/SpinGlass/#Minimum-and-maximum-energies","page":"Spin glass problem","title":"Minimum and maximum energies","text":"","category":"section"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"Its ground state energy is -9.","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"Emin = solve(problem, SizeMin())[]","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"While the state correspond to the highest energy has the ferromagnetic order.","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"Emax = solve(problem, SizeMax())[]","category":"page"},{"location":"generated/SpinGlass/#Counting-properties","page":"Spin glass problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/SpinGlass/#graph-polynomial","page":"Spin glass problem","title":"graph polynomial","text":"","category":"section"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"The graph polynomial defined for the spin glass problem is a Laurent polynomial","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"Z(G J h x) = sum_k=E_rm min^E_rm max c_k x^k","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"where E_rm min and E_rm max are minimum and maximum energies, c_k is the number of spin configurations with energy k. Let x = e^beta, it corresponds to the partition function of a spin glass at temperature beta^-1.","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"partition_function = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/SpinGlass/#Configuration-properties","page":"Spin glass problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/SpinGlass/#finding-a-ground-state","page":"Spin glass problem","title":"finding a ground state","text":"","category":"section"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"ground_state = solve(problem, SingleConfigMin())[].c.data\n\nEmin_verify = spinglass_energy(graph, ground_state)","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"You should see a consistent result as above Emin.","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"show_graph(graph; locs=locations, vertex_colors=[\n iszero(ground_state[i]) ? \"white\" : \"red\" for i=1:nv(graph)], format=:svg)","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"where a red vertex and a white vertex correspond to a spin having value 1 and 0 respectively.","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"performancetips/#Performance-Tips","page":"Performance Tips","title":"Performance Tips","text":"","category":"section"},{"location":"performancetips/#Optimize-contraction-orders","page":"Performance Tips","title":"Optimize contraction orders","text":"","category":"section"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"Let us use the independent set problem on 3-regular graphs as an example.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"julia> using GenericTensorNetworks, Graphs, Random\n\njulia> graph = random_regular_graph(120, 3)\n{120, 180} undirected simple Int64 graph\n\njulia> problem = IndependentSet(graph; optimizer=TreeSA(\n sc_target=20, sc_weight=1.0, rw_weight=3.0, ntrials=10, βs=0.01:0.1:15.0, niters=20), simplifier=MergeGreedy());","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"The IndependentSet constructor maps an independent set problem to a tensor network with optimized contraction order. The key word argument optimizer specifies the contraction order optimizer of the tensor network. Here, we choose the local search based TreeSA algorithm, which often finds the smallest time/space complexity and supports slicing. One can type ?TreeSA in a Julia REPL for more information about how to configure the hyper-parameters of the TreeSA method, while the detailed algorithm explanation is in arXiv: 2108.05665. Alternative tensor network contraction order optimizers include","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"GreedyMethod (default, fastest in searching speed but worst in contraction complexity)\nKaHyParBipartite\nSABipartite","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"The keyword argument simplifier specifies the preprocessor to improve the searching speed of the contraction order finding. For example, the MergeGreedy() here \"contracts\" tensors greedily whenever the contraction result has a smaller space complexity. It can remove all vertex tensors (vectors) before entering the contraction order optimization algorithm.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"The returned object problem contains a field code that specifies the tensor network with optimized contraction order. For an independent set problem, the optimal contraction time/space complexity is sim 2^rm tw(G), where rm tw(G) is the tree-width of G. One can check the time, space and read-write complexity with the contraction_complexity function.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"julia> contraction_complexity(problem)\nTime complexity (number of element-wise multiplications) = 2^20.568850503058382\nSpace complexity (number of elements in the largest intermediate tensor) = 2^16.0\nRead-write complexity (number of element-wise read and write) = 2^18.70474460304404","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"The return values are log2 values of the number of multiplications, the number elements in the largest tensor during contraction and the number of read-write operations to tensor elements. In this example, the number * operations is sim 2^219, the number of read-write operations are sim 2^20, and the largest tensor size is 2^17. One can check the element size by typing","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"julia> sizeof(TropicalF64)\n8\n\njulia> sizeof(TropicalF32)\n4\n\njulia> sizeof(StaticBitVector{200,4})\n32\n\njulia> sizeof(TruncatedPoly{5,Float64,Float64})\n48","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"One can use estimate_memory to get a good estimation of peak memory in bytes. For example, to compute the graph polynomial, the peak memory can be estimated as follows.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"julia> estimate_memory(problem, GraphPolynomial(; method=:finitefield))\n297616\n\njulia> estimate_memory(problem, GraphPolynomial(; method=:polynomial))\n71427840","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"The finite field approach only requires 298 KB memory, while using the Polynomial number type requires 71 MB memory.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"note: Note\nThe actual run time memory can be several times larger than the size of the maximum tensor, so the estimate_memory is more accurate in estimating the peak memory.\nFor mutable element types like ConfigEnumerator, none of memory estimation functions measure the actual memory usage correctly.","category":"page"},{"location":"performancetips/#Slicing-technique","page":"Performance Tips","title":"Slicing technique","text":"","category":"section"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"For large scale applications, it is also possible to slice over certain degrees of freedom to reduce the space complexity, i.e. loop and accumulate over certain degrees of freedom so that one can have a smaller tensor network inside the loop due to the removal of these degrees of freedom. In the TreeSA optimizer, one can set nslices to a value larger than zero to turn on this feature.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"julia> using GenericTensorNetworks, Graphs, Random\n\njulia> graph = random_regular_graph(120, 3)\n{120, 180} undirected simple Int64 graph\n\njulia> problem = IndependentSet(graph; optimizer=TreeSA(βs=0.01:0.1:25.0, ntrials=10, niters=10));\n\njulia> contraction_complexity(problem)\nTime complexity (number of element-wise multiplications) = 2^20.53277253647484\nSpace complexity (number of elements in the largest intermediate tensor) = 2^16.0\nRead-write complexity (number of element-wise read and write) = 2^19.34699193791874\n\njulia> problem = IndependentSet(graph; optimizer=TreeSA(βs=0.01:0.1:25.0, ntrials=10, niters=10, nslices=5));\n\njulia> contraction_complexity(problem)\nTime complexity (number of element-wise multiplications) = 2^21.117277836449578\nSpace complexity (number of elements in the largest intermediate tensor) = 2^11.0\nRead-write complexity (number of element-wise read and write) = 2^19.854965754099602","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"In the second IndependentSet constructor, we slice over 5 degrees of freedom, which can reduce the space complexity by at most 5. In this application, the slicing achieves the largest possible space complexity reduction 5, while the time and read-write complexity are only increased by less than 1, i.e. the peak memory usage is reduced by a factor 32, while the (theoretical) computing time is increased by at a factor 2.","category":"page"},{"location":"performancetips/#GEMM-for-Tropical-numbers","page":"Performance Tips","title":"GEMM for Tropical numbers","text":"","category":"section"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"One can speed up the Tropical number matrix multiplication when computing the solution space property SizeMax() by using the Tropical GEMM routines implemented in package TropicalGEMM.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"julia> using BenchmarkTools\n\njulia> @btime solve(problem, SizeMax())\n 91.630 ms (19203 allocations: 23.72 MiB)\n0-dimensional Array{TropicalF64, 0}:\n53.0ₜ\n\njulia> using TropicalGEMM\n\njulia> @btime solve(problem, SizeMax())\n 8.960 ms (18532 allocations: 17.01 MiB)\n0-dimensional Array{TropicalF64, 0}:\n53.0ₜ","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"The TropicalGEMM package pirates the LinearAlgebra.mul! interface, hence it takes effect upon using. The above example shows more than 10x speed up on a single thread CPU, which can be even faster if the Julia multi-threading if turned on. The benchmark in the TropicalGEMM repo shows this performance is close to the theoretical optimal value.","category":"page"},{"location":"performancetips/#Multiprocessing","page":"Performance Tips","title":"Multiprocessing","text":"","category":"section"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"Submodule GenericTensorNetworks.SimpleMutiprocessing provides one function GenericTensorNetworks.SimpleMultiprocessing.multiprocess_run function for simple multi-processing jobs. It is not directly related to GenericTensorNetworks, but is very convenient to have one. Suppose we want to find the independence polynomial for multiple graphs with 4 processes. We can create a file, e.g. named run.jl with the following content","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"using Distributed, GenericTensorNetworks.SimpleMultiprocessing\nusing Random, GenericTensorNetworks # to avoid multi-precompilation\n@everywhere using Random, GenericTensorNetworks\n\nresults = multiprocess_run(collect(1:10)) do seed\n Random.seed!(seed)\n n = 10\n @info \"Graph size $n x $n, seed= $seed\"\n g = random_diagonal_coupled_graph(n, n, 0.8)\n gp = Independence(g; optimizer=TreeSA(), simplifier=MergeGreedy())\n res = solve(gp, GraphPolynomial())[]\n return res\nend\n\nprintln(results)","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"One can run this script file with the following command","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"$ julia -p4 run.jl\n From worker 3:\t[ Info: running argument 4 on device 3\n From worker 4:\t[ Info: running argument 2 on device 4\n From worker 5:\t[ Info: running argument 3 on device 5\n From worker 2:\t[ Info: running argument 1 on device 2\n From worker 3:\t[ Info: Graph size 10 x 10, seed= 4\n From worker 4:\t[ Info: Graph size 10 x 10, seed= 2\n From worker 5:\t[ Info: Graph size 10 x 10, seed= 3\n From worker 2:\t[ Info: Graph size 10 x 10, seed= 1\n From worker 4:\t[ Info: running argument 5 on device\n ...","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"You will see a vector of polynomials printed out.","category":"page"},{"location":"performancetips/#Make-use-of-GPUs","page":"Performance Tips","title":"Make use of GPUs","text":"","category":"section"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"To upload the computation to GPU, you just add using CUDA before calling the solve function, and set the keyword argument usecuda to true.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"julia> using CUDA\n[ Info: OMEinsum loaded the CUDA module successfully\n\njulia> solve(problem, SizeMax(), usecuda=true)\n0-dimensional CuArray{TropicalF64, 0, CUDA.Mem.DeviceBuffer}:\n53.0ₜ","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"Solution space properties computable on GPU includes","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"SizeMax and SizeMin\nCountingAll\nCountingMax and CountingMin\nGraphPolynomial\nSingleConfigMax and SingleConfigMin","category":"page"},{"location":"performancetips/#Benchmarks","page":"Performance Tips","title":"Benchmarks","text":"","category":"section"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"We run a single thread benchmark on central processing units (CPU) Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz, and its CUDA version on a GPU Tesla V100-SXM2 16G. The results are summarized in the following plot. The benchmark code can be found in our paper repository.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"(Image: benchmark-independent-set) This benchmark results is for computing different solution space properties of independent sets of random three-regular graphs with different tensor element types. The time in these plots only includes tensor network contraction, without taking into account the contraction order finding and just-in-time compilation time. Legends are properties, algebra, and devices that we used in the computation; one can find the corresponding computed solution space property in Table 1 in the paper.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"(a) time and space complexity versus the number of vertices for the benchmarked graphs.\n(b) The computation time for calculating the MIS size and for counting the number of all independent sets (ISs), the number of MISs, the number of independent sets having size alpha(G) and alpha(G)-1, and finding 100 largest set sizes.\n(c) The computation time for calculating the independence polynomials with different approaches.\n(d) The computation time for configuration enumeration, including single MIS configuration, the enumeration of all independent set configurations, all MIS configurations, all independent sets, and all independent set configurations having size alpha(G) and alpha(G)-1.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"The graphs in all benchmarks are random three-regular graphs, which have treewidth that is asymptotically smaller than V6. In this benchmark, we do not include traditional algorithms for finding the MIS sizes such as branching or dynamic programming. To the best of our knowledge, these algorithms are not suitable for computing most of the solution space properties mentioned in this paper. The main goal of this section is to show the relative computation time for calculating different solution space properties.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"Panel (a) shows the time and space complexity of tensor network contraction for different graph sizes. The contraction order is obtained using the TreeSA algorithm that implemented in OMEinsumContractionOrders. If we assume our contraction-order finding program has found the optimal treewidth, which is very likely to be true, the space complexity is the same as the treewidth of the problem graph. Slicing technique has been used for graphs with space complexity greater than 2^27 (above the yellow dashed line) to fit the computation into a 16GB memory. One can see that all the computation times in panels (b), (c), and (d) have a strong correlation with the predicted time and space complexity. While in panel (d), the computation time of configuration enumeration also strongly correlates with other factors such as the configuration space size. Among these benchmarks, computational tasks with data types real numbers, complex numbers, or Tropical numbers (CPU only) can utilize fast basic linear algebra subprograms (BLAS) functions. These tasks usually compute much faster than ones with other element types in the same category. Immutable data types with no reference to other values can be compiled to GPU devices that run much faster than CPUs in all cases when the problem scale is big enough. These data types do not include those defined in Polynomial, ConfigEnumerator, ExtendedTropical and SumProductTree or a data type containing them as a part. In panel (c), one can see the Fourier transformation-based method is the fastest in computing the independence polynomial, but it may suffer from round-off errors. The finite field (GF(p)) approach is the only method that does not have round-off errors and can be run on a GPU. In panel (d), one can see the technique to bound the enumeration space (see paper) improves the performance for more than one order of magnitude in enumerating the MISs. The bounding technique can also reduce the memory usage significantly, without which the largest computable graph size is only sim150 on a device with 32GB main memory.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"We show the benchmark of computing the maximal independent set properties on 3-regular graphs in the following plot, including a comparison to the Bron-Kerbosch algorithm from Julia package Graphs","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"(Image: benchmark-maximal-independent-set)","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"In this plot, benchmarks of computing different solution space properties of the maximal independent sets (ISs) problem on random three regular graphs at different sizes.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"(a) time and space complexity of tensor network contraction.\n(b) The wall clock time for counting and enumeration of maximal ISs.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"Panel (a) shows the space and time complexities of tensor contraction, which are typically larger than those for the independent set problem. In panel (b), one can see counting maximal independent sets are much more efficient than enumerating them, while our generic tensor network approach runs slightly faster than the Bron-Kerbosch approach in enumerating all maximal independent sets.","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"EditURL = \"../../../examples/MaximalIS.jl\"","category":"page"},{"location":"generated/MaximalIS/#Maximal-independent-set-problem","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"","category":"section"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/MaximalIS/#Problem-definition","page":"Maximal independent set problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"In graph theory, a maximal independent set is an independent set that is not a subset of any other independent set. It is different from maximum independent set because it does not require the set to have the max size. In the following, we are going to solve the maximal independent set problem on the Petersen graph.","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"using GenericTensorNetworks, Graphs\n\ngraph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"We can visualize this graph using the following function","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a\n\nlocations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]\n\nshow_graph(graph; locs=locations, format=:svg)","category":"page"},{"location":"generated/MaximalIS/#Generic-tensor-network-representation","page":"Maximal independent set problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"We can use MaximalIS to construct the tensor network for solving the maximal independent set problem as","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"problem = MaximalIS(graph; optimizer=TreeSA());\nnothing #hide","category":"page"},{"location":"generated/MaximalIS/#Theory-(can-skip)","page":"Maximal independent set problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"Let G=(VE) be the target graph that we want to solve. The tensor network representation map a vertex vin V to a boolean degree of freedom s_vin0 1. We defined the restriction on its neighborhood N(v):","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"T(x_v)_s_1s_2ldotss_N(v)s_v = begincases\n s_vx_v^w_v s_1=s_2=ldots=s_N(v)=0\n 1-s_v textotherwise\nendcases","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"The first case corresponds to all the neighborhood vertices of v are not in I_m, then v must be in I_m and contribute a factor x_v^w_v, where w_v is the weight of vertex v. Otherwise, if any of the neighboring vertices of v is in I_m, v must not be in I_m by the independence requirement.","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"Its contraction time space complexity of a MaximalIS instance is no longer determined by the tree-width of the original graph G. It is often harder to contract this tensor network than to contract the one for regular independent set problem.","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"contraction_complexity(problem)","category":"page"},{"location":"generated/MaximalIS/#Solving-properties","page":"Maximal independent set problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/MaximalIS/#Counting-properties","page":"Maximal independent set problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/MaximalIS/#maximal-independence-polynomial","page":"Maximal independent set problem","title":"maximal independence polynomial","text":"","category":"section"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"The graph polynomial defined for the maximal independent set problem is","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"I_rm max(G x) = sum_k=0^alpha(G) b_k x^k","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"where b_k is the number of maximal independent sets of size k in graph G=(V E).","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"maximal_indenpendence_polynomial = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"One can see the first several coefficients are 0, because it only counts the maximal independent sets, The minimum maximal independent set size is also known as the independent domination number. It can be computed with the SizeMin property:","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"independent_domination_number = solve(problem, SizeMin())[]","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"Similarly, we have its counting CountingMin:","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"counting_min_maximal_independent_set = solve(problem, CountingMin())[]","category":"page"},{"location":"generated/MaximalIS/#Configuration-properties","page":"Maximal independent set problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/MaximalIS/#finding-all-maximal-independent-set","page":"Maximal independent set problem","title":"finding all maximal independent set","text":"","category":"section"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"maximal_configs = solve(problem, ConfigsAll())[]\n\nall(c->is_maximal_independent_set(graph, c), maximal_configs)","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"show_gallery(graph, (3, 5); locs=locations, vertex_configs=maximal_configs, format=:svg)","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"This result should be consistent with that given by the Bron Kerbosch algorithm on the complement of Petersen graph.","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"cliques = maximal_cliques(complement(graph))","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"For sparse graphs, the generic tensor network approach is usually much faster and memory efficient than the Bron Kerbosch algorithm.","category":"page"},{"location":"generated/MaximalIS/#finding-minimum-maximal-independent-set","page":"Maximal independent set problem","title":"finding minimum maximal independent set","text":"","category":"section"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"It is the ConfigsMin property in the program.","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"minimum_maximal_configs = solve(problem, ConfigsMin())[].c\n\nshow_gallery(graph, (2, 5); locs=locations, vertex_configs=minimum_maximal_configs, format=:svg)","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"Similarly, if one is only interested in computing one of the minimum sets, one can use the graph property SingleConfigMin.","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"EditURL = \"../../../examples/MaxCut.jl\"","category":"page"},{"location":"generated/MaxCut/#Cutting-problem","page":"Cutting problem","title":"Cutting problem","text":"","category":"section"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/MaxCut/#Problem-definition","page":"Cutting problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"In graph theory, a cut is a partition of the vertices of a graph into two disjoint subsets. It is closely related to the Spin-glass problem in physics. Finding the maximum cut is NP-Hard, where a maximum cut is a cut whose size is at least the size of any other cut, where the size of a cut is the number of edges (or the sum of weights on edges) crossing the cut.","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"using GenericTensorNetworks, Graphs","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"In the following, we are going to defined an cutting problem for the Petersen graph.","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"graph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"We can visualize this graph using the following function","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a\n\nlocations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]\n\nshow_graph(graph; locs=locations, format=:svg)","category":"page"},{"location":"generated/MaxCut/#Generic-tensor-network-representation","page":"Cutting problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"We define the cutting problem as","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"problem = MaxCut(graph);\nnothing #hide","category":"page"},{"location":"generated/MaxCut/#Theory-(can-skip)","page":"Cutting problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"We associated a vertex vin V with a boolean degree of freedom s_vin0 1. Then the maximum cutting problem can be encoded to tensor networks by mapping an edge (ij)in E to an edge matrix labelled by s_i and s_j","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"B(x_i x_j w_ij) = left(beginmatrix\n 1 x_i^w_ij\n x_j^w_ij 1\nendmatrixright)","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"where w_ij is a real number associated with edge (i j) as the edge weight. If and only if the bipartition cuts on edge (i j), this tensor contributes a factor x_i^w_ij or x_j^w_ij. Similarly, one can assign weights to vertices, which corresponds to the onsite energy terms in the spin glass. The vertex tensor is","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"W(x_i w_i) = left(beginmatrix\n 1\n x_i^w_i\nendmatrixright)","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"where w_i is a real number associated with vertex i as the vertex weight.","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"Its contraction time space complexity is 2^rm tw(G), where rm tw(G) is the tree-width of G.","category":"page"},{"location":"generated/MaxCut/#Solving-properties","page":"Cutting problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/MaxCut/#Maximum-cut-size-\\gamma(G)","page":"Cutting problem","title":"Maximum cut size gamma(G)","text":"","category":"section"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"max_cut_size = solve(problem, SizeMax())[]","category":"page"},{"location":"generated/MaxCut/#Counting-properties","page":"Cutting problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/MaxCut/#graph-polynomial","page":"Cutting problem","title":"graph polynomial","text":"","category":"section"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"The graph polynomial defined for the cutting problem is","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"C(G x) = sum_k=0^gamma(G) c_k x^k","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"where gamma(G) is the maximum cut size, c_k2 is the number of cuts of size k in graph G=(VE). Since the variable x is defined on edges, the coefficients of the polynomial is the number of configurations having different number of anti-parallel edges.","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"max_config = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/MaxCut/#Configuration-properties","page":"Cutting problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/MaxCut/#finding-one-max-cut-solution","page":"Cutting problem","title":"finding one max cut solution","text":"","category":"section"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"max_vertex_config = solve(problem, SingleConfigMax())[].c.data\n\nmax_cut_size_verify = cut_size(graph, max_vertex_config)","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"You should see a consistent result as above max_cut_size.","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"show_graph(graph; locs=locations, vertex_colors=[\n iszero(max_vertex_config[i]) ? \"white\" : \"red\" for i=1:nv(graph)], format=:svg)","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"where red vertices and white vertices are separated by the cut.","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"EditURL = \"../../../examples/saveload.jl\"","category":"page"},{"location":"generated/saveload/#Save-and-load-solutions","page":"Save and load solutions","title":"Save and load solutions","text":"","category":"section"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"Let us use the maximum independent set problem on Petersen graph as an example. The following code enumerates all independent sets.","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"using GenericTensorNetworks, Graphs\n\nproblem = IndependentSet(Graphs.smallgraph(:petersen))\n\nall_independent_sets = solve(problem, ConfigsAll())[]","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"The return value has type ConfigEnumerator. We can use save_configs and load_configs to save and read a ConfigEnumerator instance to the disk.","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"filename = tempname()\n\nsave_configs(filename, all_independent_sets; format=:binary)\n\nloaded_sets = load_configs(filename; format=:binary, bitlength=10)","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"note: Note\nWhen loading the data in the binary format, bit string length information bitlength is required.","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"For the SumProductTree type output, we can use save_sumproduct and load_sumproduct to save and load serialized data.","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"all_independent_sets_tree = solve(problem, ConfigsAll(; tree_storage=true))[]\n\nsave_sumproduct(filename, all_independent_sets_tree)\n\nloaded_sets_tree = load_sumproduct(filename)","category":"page"},{"location":"generated/saveload/#Loading-solutions-to-python","page":"Save and load solutions","title":"Loading solutions to python","text":"","category":"section"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"The following python script loads and unpacks the solutions as a numpy array from a :binary format file.","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"import numpy as np\n\ndef loadfile(filename:str, bitlength:int):\n C = int(np.ceil(bitlength / 64))\n arr = np.fromfile(filename, dtype=\"uint8\")\n # Some axes should be transformed from big endian to little endian\n res = np.unpackbits(arr).reshape(-1, C, 8, 8)[:,::-1,::-1,:]\n res = res.reshape(-1, C*64)[:, :(64*C-bitlength)-1:-1]\n print(\"number of solutions = %d\"%(len(res)))\n return res # in big endian format\n\nres = loadfile(filename, 10)","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"note: Note\nCheck section Maximal independent set problem for solution space properties related the maximal independent sets. That example also contains using cases of finding solution space properties related to minimum sizes:SizeMin for finding minimum several set sizes,\nCountingMin for counting minimum several set sizes,\nSingleConfigMin for finding one solution with minimum several sizes,\nConfigsMin for enumerating solutions with minimum several sizes,","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"EditURL = \"../../../examples/SetCovering.jl\"","category":"page"},{"location":"generated/SetCovering/#Set-covering-problem","page":"Set covering problem","title":"Set covering problem","text":"","category":"section"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/SetCovering/#Problem-definition","page":"Set covering problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"The set covering problem is a significant NP-hard problem in combinatorial optimization. Given a collection of elements, the set covering problem aims to find the minimum number of sets that incorporate (cover) all of these elements. In the following, we will find the solution space properties for the camera location and stadium area example in the Cornell University Computational Optimization Open Textbook.","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"using GenericTensorNetworks, Graphs","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"The covering stadium areas of cameras are represented as the following sets.","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"sets = [[1,3,4,6,7], [4,7,8,12], [2,5,9,11,13],\n [1,2,14,15], [3,6,10,12,14], [8,14,15],\n [1,2,6,11], [1,2,4,6,8,12]]","category":"page"},{"location":"generated/SetCovering/#Generic-tensor-network-representation","page":"Set covering problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"We create a [SetCovering] instance that contains a generic tensor network as its code field.","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"problem = SetCovering(sets);\nnothing #hide","category":"page"},{"location":"generated/SetCovering/#Theory-(can-skip)","page":"Set covering problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"Let S be the target set covering problem that we want to solve. For each set s in S, we associate it with a weight w_s to it. The tensor network representation map a set sin S to a boolean degree of freedom v_sin0 1. For each set s, we defined a parameterized rank-one tensor indexed by v_s as","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"W(x_s^w_s) = left(beginmatrix\n 1 \n x_s^w_s\n endmatrixright)","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"where x_s is a variable associated with s. For each unique element a, we defined the constraint over all sets containing it N(a) = s s in S land ain s:","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"B_s_1s_2ldotss_N(a) = begincases\n 0 s_1=s_2=ldots=s_N(a)=0\n 1 textotherwise\nendcases","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"This tensor means if none of the sets containing element a are included, then this configuration is forbidden, One can check the contraction time space complexity of a SetCovering instance by typing:","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"contraction_complexity(problem)","category":"page"},{"location":"generated/SetCovering/#Solving-properties","page":"Set covering problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/SetCovering/#Counting-properties","page":"Set covering problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/SetCovering/#The-\"graph\"-polynomial","page":"Set covering problem","title":"The \"graph\" polynomial","text":"","category":"section"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"The graph polynomial for the set covering problem is defined as","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"P(S x) = sum_k=0^S c_k x^k","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"where c_k is the number of configurations having k sets.","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"covering_polynomial = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"The minimum number of sets that covering the set of elements can be computed with the SizeMin property:","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"min_cover_size = solve(problem, SizeMin())[]","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"Similarly, we have its counting CountingMin:","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"counting_minimum_setcovering = solve(problem, CountingMin())[]","category":"page"},{"location":"generated/SetCovering/#Configuration-properties","page":"Set covering problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/SetCovering/#Finding-minimum-set-covering","page":"Set covering problem","title":"Finding minimum set covering","text":"","category":"section"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"One can enumerate all minimum set covering with the ConfigsMin property in the program.","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"min_configs = solve(problem, ConfigsMin())[].c","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"Hence the two optimal solutions are z_1 z_3 z_5 z_6 and z_2 z_3 z_4 z_5. The correctness of this result can be checked with the is_set_covering function.","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"all(c->is_set_covering(sets, c), min_configs)","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"Similarly, if one is only interested in computing one of the minimum set coverings, one can use the graph property SingleConfigMin.","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"gist/#Gist-of-implementation","page":"Gist","title":"Gist of implementation","text":"","category":"section"},{"location":"gist/","page":"Gist","title":"Gist","text":"The code we will show below is a gist of how this package is implemented for pedagogical purpose, which covers many functionalities of the main repo without caring much about performance. This project depends on multiple open source packages in the Julia ecosystem:","category":"page"},{"location":"gist/","page":"Gist","title":"Gist","text":"OMEinsum and OMEinsumContractionOrders are packages providing the support for Einstein's (or tensor network) notation and state-of-the-art algorithms for contraction order optimization, which includes multiple state of the art algorithms.\nTropicalNumbers and TropicalGEMM are packages providing tropical number and efficient tropical matrix multiplication.\nGraphs is a foundational package for graph manipulation in the Julia community.\nPolynomials is a package providing polynomial algebra and polynomial fitting.\nMods and the Primes package providing finite field algebra and prime number manipulation.","category":"page"},{"location":"gist/","page":"Gist","title":"Gist","text":"They can be installed in a similar way to GenericTensorNetworks. After installing the required packages, one can open a Julia REPL, and copy-paste the following code snippet into it.","category":"page"},{"location":"gist/","page":"Gist","title":"Gist","text":"using OMEinsum\nusing Graphs\nusing Random\n\n# generate a random regular graph of size 50, degree 3\ngraph = (Random.seed!(2); Graphs.random_regular_graph(50, 3))\n\n# generate einsum code, i.e. the labels of tensors\ncode = EinCode(([minmax(e.src,e.dst) for e in Graphs.edges(graph)]..., # labels for edge tensors\n [(i,) for i in Graphs.vertices(graph)]...), ()) # labels for vertex tensors\n\n# an einsum contraction without a contraction order specified is called `EinCode`,\n# an einsum contraction having a contraction order (specified as a tree structure) is called `NestedEinsum`.\n# assign each label a dimension-2, it will be used in the contraction order optimization\n# `uniquelabels` function extracts the tensor labels into a vector.\nsize_dict = Dict([s=>2 for s in uniquelabels(code)])\n# optimize the contraction order using the `TreeSA` method; the target space complexity is 2^17\noptimized_code = optimize_code(code, size_dict, TreeSA())\nprintln(\"time/space complexity is $(OMEinsum.timespace_complexity(optimized_code, size_dict))\")\n\n# a function for computing the independence polynomial\nfunction independence_polynomial(x::T, code) where {T}\n\txs = map(getixsv(code)) do ix\n # if the tensor rank is 1, create a vertex tensor.\n # otherwise the tensor rank must be 2, create a bond tensor.\n length(ix)==1 ? [one(T), x] : [one(T) one(T); one(T) zero(T)]\n end\n # both `EinCode` and `NestedEinsum` are callable, inputs are tensors.\n\tcode(xs...)\nend\n\n########## COMPUTING THE MAXIMUM INDEPENDENT SET SIZE AND ITS COUNTING/DEGENERACY ###########\n\n# using Tropical numbers to compute the MIS size and the MIS degeneracy.\nusing TropicalNumbers\nmis_size(code) = independence_polynomial(TropicalF64(1.0), code)[]\nprintln(\"the maximum independent set size is $(mis_size(optimized_code).n)\")\n\n# A `CountingTropical` object has two fields, tropical field `n` and counting field `c`.\nmis_count(code) = independence_polynomial(CountingTropical{Float64,Float64}(1.0, 1.0), code)[]\nprintln(\"the degeneracy of maximum independent sets is $(mis_count(optimized_code).c)\")\n\n########## COMPUTING THE INDEPENDENCE POLYNOMIAL ###########\n\n# using Polynomial numbers to compute the polynomial directly\nusing Polynomials\nprintln(\"the independence polynomial is $(independence_polynomial(Polynomial([0.0, 1.0]), optimized_code)[])\")\n\n########## FINDING MIS CONFIGURATIONS ###########\n\n# define the set algebra\nstruct ConfigEnumerator{N}\n # NOTE: BitVector is dynamic and it can be very slow; check our repo for the static version\n data::Vector{BitVector}\nend\nfunction Base.:+(x::ConfigEnumerator{N}, y::ConfigEnumerator{N}) where {N}\n res = ConfigEnumerator{N}(vcat(x.data, y.data))\n return res\nend\nfunction Base.:*(x::ConfigEnumerator{L}, y::ConfigEnumerator{L}) where {L}\n M, N = length(x.data), length(y.data)\n z = Vector{BitVector}(undef, M*N)\n for j=1:N, i=1:M\n z[(j-1)*M+i] = x.data[i] .| y.data[j]\n end\n return ConfigEnumerator{L}(z)\nend\nBase.zero(::Type{ConfigEnumerator{N}}) where {N} = ConfigEnumerator{N}(BitVector[])\nBase.one(::Type{ConfigEnumerator{N}}) where {N} = ConfigEnumerator{N}([falses(N)])\n\n# the algebra sampling one of the configurations\nstruct ConfigSampler{N}\n data::BitVector\nend\n\nfunction Base.:+(x::ConfigSampler{N}, y::ConfigSampler{N}) where {N} # biased sampling: return `x`\n return x # randomly pick one\nend\nfunction Base.:*(x::ConfigSampler{L}, y::ConfigSampler{L}) where {L}\n ConfigSampler{L}(x.data .| y.data)\nend\n\nBase.zero(::Type{ConfigSampler{N}}) where {N} = ConfigSampler{N}(trues(N))\nBase.one(::Type{ConfigSampler{N}}) where {N} = ConfigSampler{N}(falses(N))\n\n# enumerate all configurations if `all` is true; compute one otherwise.\n# a configuration is stored in the data type of `StaticBitVector`; it uses integers to represent bit strings.\n# `ConfigTropical` is defined in `TropicalNumbers`. It has two fields: tropical number `n` and optimal configuration `config`.\n# `CountingTropical{T,<:ConfigEnumerator}` stores configurations instead of simple counting.\nfunction mis_config(code; all=false)\n # map a vertex label to an integer\n vertex_index = Dict([s=>i for (i, s) in enumerate(uniquelabels(code))])\n N = length(vertex_index) # number of vertices\n xs = map(getixsv(code)) do ix\n T = all ? CountingTropical{Float64, ConfigEnumerator{N}} : CountingTropical{Float64, ConfigSampler{N}}\n if length(ix) == 2\n return [one(T) one(T); one(T) zero(T)]\n else\n s = falses(N)\n s[vertex_index[ix[1]]] = true # one hot vector\n if all\n [one(T), T(1.0, ConfigEnumerator{N}([s]))]\n else\n [one(T), T(1.0, ConfigSampler{N}(s))]\n end\n end\n end\n\treturn code(xs...)\nend\n\nprintln(\"one of the optimal configurations is $(mis_config(optimized_code; all=false)[].c.data)\")\n\n# direct enumeration of configurations can be very slow; please check the bounding version in our Github repo.\nprintln(\"all optimal configurations are $(mis_config(optimized_code; all=true)[].c)\")","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"EditURL = \"../../../examples/DominatingSet.jl\"","category":"page"},{"location":"generated/DominatingSet/#Dominating-set-problem","page":"Dominating set problem","title":"Dominating set problem","text":"","category":"section"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/DominatingSet/#Problem-definition","page":"Dominating set problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"In graph theory, a dominating set for a graph G = (V E) is a subset D of V such that every vertex not in D is adjacent to at least one member of D. The domination number gamma(G) is the number of vertices in a smallest dominating set for G. The decision version of finding the minimum dominating set is an NP-complete. In the following, we are going to solve the dominating set problem on the Petersen graph.","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"using GenericTensorNetworks, Graphs\n\ngraph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"We can visualize this graph using the following function","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a\n\nlocations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]\n\nshow_graph(graph; locs=locations, format=:svg)","category":"page"},{"location":"generated/DominatingSet/#Generic-tensor-network-representation","page":"Dominating set problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"We can use DominatingSet to construct the tensor network for solving the dominating set problem as","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"problem = DominatingSet(graph; optimizer=TreeSA());\nnothing #hide","category":"page"},{"location":"generated/DominatingSet/#Theory-(can-skip)","page":"Dominating set problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"Let G=(VE) be the target graph that we want to solve. The tensor network representation map a vertex vin V to a boolean degree of freedom s_vin0 1. We defined the restriction on a vertex and its neighboring vertices N(v):","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"T(x_v)_s_1s_2ldotss_N(v)s_v = begincases\n 0 s_1=s_2=ldots=s_N(v)=s_v=0\n 1 s_v=0\n x_v^w_v textotherwise\nendcases","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"where w_v is the weight of vertex v. This tensor means if both v and its neighboring vertices are not in D, i.e., s_1=s_2=ldots=s_N(v)=s_v=0, this configuration is forbidden because v is not adjacent to any member in the set. otherwise, if v is in D, it has a contribution x_v^w_v to the final result. One can check the contraction time space complexity of a DominatingSet instance by typing:","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"contraction_complexity(problem)","category":"page"},{"location":"generated/DominatingSet/#Solving-properties","page":"Dominating set problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/DominatingSet/#Counting-properties","page":"Dominating set problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/DominatingSet/#Domination-polynomial","page":"Dominating set problem","title":"Domination polynomial","text":"","category":"section"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"The graph polynomial for the dominating set problem is known as the domination polynomial (see arXiv:0905.2251). It is defined as","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"D(G x) = sum_k=0^gamma(G) d_k x^k","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"where d_k is the number of dominating sets of size k in graph G=(V E).","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"domination_polynomial = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"The domination number gamma(G) can be computed with the SizeMin property:","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"domination_number = solve(problem, SizeMin())[]","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"Similarly, we have its counting CountingMin:","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"counting_min_dominating_set = solve(problem, CountingMin())[]","category":"page"},{"location":"generated/DominatingSet/#Configuration-properties","page":"Dominating set problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/DominatingSet/#finding-minimum-dominating-set","page":"Dominating set problem","title":"finding minimum dominating set","text":"","category":"section"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"One can enumerate all minimum dominating sets with the ConfigsMin property in the program.","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"min_configs = solve(problem, ConfigsMin())[].c\n\nall(c->is_dominating_set(graph, c), min_configs)","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"show_gallery(graph, (2, 5); locs=locations, vertex_configs=min_configs, format=:svg)","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"Similarly, if one is only interested in computing one of the minimum dominating sets, one can use the graph property SingleConfigMin.","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"EditURL = \"../../../examples/weighted.jl\"","category":"page"},{"location":"generated/weighted/#Weighted-problems","page":"Weighted problems","title":"Weighted problems","text":"","category":"section"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"Let us use the maximum independent set problem on Petersen graph as an example.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"using GenericTensorNetworks, Graphs\n\ngraph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"The following code constructs a weighted MIS problem instance.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"problem = IndependentSet(graph; weights=collect(1:10));\nnothing #hide","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"Here, the weights keyword argument can be a vector for weighted graphs or NoWeight() for unweighted graphs. Most solution space properties work for unweighted graphs also work for the weighted graphs. For example, the maximum independent set can be found as follows.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"max_config_weighted = solve(problem, SingleConfigMax())[]","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"Let us visualize the solution.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a\n\nlocations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]\n\nshow_graph(graph; locs=locations, format=:svg, vertex_colors=\n [iszero(max_config_weighted.c.data[i]) ? \"white\" : \"red\" for i=1:nv(graph)])","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"The only solution space property that can not be defined for general real-weighted (not including integer-weighted) graphs is the GraphPolynomial.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"For the weighted MIS problem, a useful solution space property is the \"energy spectrum\", i.e. the largest several configurations and their weights. We can use the solution space property is SizeMax(10) to compute the largest 10 weights.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"spectrum = solve(problem, SizeMax(10))[]","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"The return value has type ExtendedTropical, which contains one field orders.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"spectrum.orders","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"We can see the order is a vector of Tropical numbers. Similarly, we can get weighted independent sets with maximum 5 sizes as follows.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"max5_configs = solve(problem, SingleConfigMax(5))[]","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"The return value also has type ExtendedTropical, but this time the element type of orders has been changed to CountingTropical{Float64,ConfigSampler}.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"max5_configs.orders","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"Let us visually check these configurations","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"show_gallery(graph, (1, 5); locs=locations, format=:svg, vertex_configs=[max5_configs.orders[k].c.data for k=1:5])","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"This page was generated using Literate.jl.","category":"page"},{"location":"ref/#References","page":"References","title":"References","text":"","category":"section"},{"location":"ref/#Graph-problems","page":"References","title":"Graph problems","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"solve\nGraphProblem\nIndependentSet\nMaximalIS\nMatching\nColoring\nDominatingSet\nSpinGlass\nHyperSpinGlass\nMaxCut\nPaintShop\nSatisfiability\nSetCovering\nSetPacking\nOpenPitMining","category":"page"},{"location":"ref/#GenericTensorNetworks.solve","page":"References","title":"GenericTensorNetworks.solve","text":"solve(problem, property; usecuda=false, T=Float64)\n\nSolving a certain property of a graph problem.\n\nPositional Arguments\n\nproblem is the graph problem with tensor network information,\nproperty is string specifying the task. Using the maximum independent set problem as an example, it can be one of\nPartitionFunction() for computing the partition function,\nSizeMax(k=Single) for finding maximum-k set sizes,\nSizeMin(k=Single) for finding minimum-k set sizes,\nCountingMax(k=Single) for counting configurations with maximum-k sizes,\nCountingMin(k=Single) for counting configurations with minimum-k sizes,\nCountingAll() for counting all configurations,\nPartitionFunction() for counting all configurations,\nGraphPolynomial(; method=:finitefield, kwargs...) for evaluating the graph polynomial,\nSingleConfigMax(k=Single; bounded=false) for finding one maximum-k configuration for each size,\nSingleConfigMin(k=Single; bounded=false) for finding one minimum-k configuration for each size,\nConfigsMax(k=Single; bounded=true, tree_storage=false) for enumerating configurations with maximum-k sizes,\nConfigsMin(k=Single; bounded=true, tree_storage=false) for enumerating configurations with minimum-k sizes,\nConfigsAll(; tree_storage=false) for enumerating all configurations,\n\nKeyword arguments\n\nusecuda is a switch to use CUDA (if possible), user need to call statement using CUDA before turning on this switch.\nT is the \"base\" element type, sometimes can be used to reduce the memory cost.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.GraphProblem","page":"References","title":"GenericTensorNetworks.GraphProblem","text":"GraphProblem\n\nThe abstract base type of graph problems.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.IndependentSet","page":"References","title":"GenericTensorNetworks.IndependentSet","text":"IndependentSet{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem\nIndependentSet(graph; weights=NoWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe independent set problem in graph theory.\n\nPositional arguments\n\ngraph is the problem graph.\n\nKeyword arguments\n\nweights are associated with the vertices of the graph.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms on vertices, where a value can be 0 (absent in the set) or 1 (present in the set).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\nExamples\n\njulia> using GenericTensorNetworks, Graphs\n\njulia> problem = IndependentSet(smallgraph(:petersen));\n\njulia> solve(problem, ConfigsMax())\n0-dimensional Array{CountingTropical{Float64, ConfigEnumerator{10, 1, 1}}, 0}:\n(4.0, {0101010001, 1010000011, 0100100110, 0010111000, 1001001100})ₜ\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.MaximalIS","page":"References","title":"GenericTensorNetworks.MaximalIS","text":"MaximalIS{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem\nMaximalIS(graph; weights=NoWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe maximal independent set problem. In the constructor, weights are the weights of vertices.\n\nPositional arguments\n\ngraph is the problem graph.\n\nKeyword arguments\n\nweights are associated with the vertices of the graph.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (absent in the set) or 1 (present in the set).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.Matching","page":"References","title":"GenericTensorNetworks.Matching","text":"Matching{CT<:AbstractEinsum, WT<:Union{NoWeight,Vector}} <: GraphProblem\nMatching(graph; weights=NoWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe Vertex matching problem.\n\nPositional arguments\n\ngraph is the problem graph.\n\nKeyword arguments\n\nweights are associated with the edges of the graph.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms on edges, where a value can be 0 (not matched) or 1 (mathced).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.Coloring","page":"References","title":"GenericTensorNetworks.Coloring","text":"Coloring{K,CT<:AbstractEinsum, WT<:Union{NoWeight, Vector}} <: GraphProblem\nColoring{K}(graph; weights=NoWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe Vertex Coloring problem.\n\nPositional arguments\n\ngraph is the problem graph.\n\nKeyword arguments\n\nweights are associated with the edges of the graph.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms on vertices, where a value can be in 0K-1 (different colors).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.DominatingSet","page":"References","title":"GenericTensorNetworks.DominatingSet","text":"DominatingSet{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem\nDominatingSet(graph; weights=NoWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe dominating set problem.\n\nPositional arguments\n\ngraph is the problem graph.\n\nKeyword arguments\n\nweights are associated with the vertices of the graph.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms on vertices, where a value can be 0 (absent in the set) or 1 (present in the set).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.SpinGlass","page":"References","title":"GenericTensorNetworks.SpinGlass","text":"SpinGlass{TT<:MaxCut,WT1<:Union{NoWeight, Vector},WT2<:Union{ZeroWeight, Vector}} <: ReducedProblem\nSpinGlass(graph; J=NoWeight(), h=ZeroWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\nSpinGlass(M::AbstractMatrix, h::AbstractVector; kwargs...)\n\nThe spin glass problem (or cutting problem). In the output, the spin ↑ is mapped to configuration 0, while spin ↓ is mapped to configuration 1.\n\nPositional arguments\n\ngraph is the problem graph.\n\nKeyword arguments\n\nM is a symmetric matrix of the coupling strengths.\nJ is a vector of coupling strengths associated with the edges of the graph.\nh is a vector of onsite energy terms associated with the vertices of the graph.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.HyperSpinGlass","page":"References","title":"GenericTensorNetworks.HyperSpinGlass","text":"struct HyperSpinGlass{CT<:OMEinsum.AbstractEinsum, WT<:Union{NoWeight, Vector}} <: GraphProblem\n\nThe hyper-spin-glass problem is a generalization of the spin-glass problem to hypergraphs.\n\nPositional arguments\n\nn is the number of spins.\ncliques is a vector of cliques, each being a vector of vertices (integers).\n\nKeyword arguments\n\nweights are associated with the cliques.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.MaxCut","page":"References","title":"GenericTensorNetworks.MaxCut","text":"MaxCut{CT<:AbstractEinsum,WT1<:Union{NoWeight, Vector},WT2<:Union{ZeroWeight, Vector}} <: GraphProblem\nMaxCut(graph; edge_weights=NoWeight(), vertex_weights=ZeroWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe cutting problem.\n\nPositional arguments\n\ngraph is the problem graph.\n\nKeyword arguments\n\nedge_weights are associated with the edges of the graph.\nvertex_weights are associated with the vertices of the graph.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.PaintShop","page":"References","title":"GenericTensorNetworks.PaintShop","text":"PaintShop{CT<:AbstractEinsum} <: GraphProblem\nPaintShop(sequence::AbstractVector; openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe binary paint shop problem.\n\nPositional arguments\n\nKeyword arguments\n\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (the first appearence in blue) or 1 (the first appearence in red).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\nExamples\n\nOne can encode the paint shop problem abaccb as the following\n\njulia> syms = collect(\"abaccb\");\n\njulia> pb = PaintShop(syms);\n\njulia> solve(pb, SizeMin())[]\n2.0ₜ\n\njulia> solve(pb, ConfigsMin())[].c.data\n2-element Vector{StaticBitVector{3, 1}}:\n 100\n 011\n\nIn our definition, we find the maximum number of unchanged color in this sequence, i.e. (n-1) - (minimum number of color changes) In the output of maximum configurations, the two configurations are defined on 5 bonds i.e. pairs of (i, i+1), 0 means color changed, while 1 means color not changed. If we denote two \"colors\" as r and b, then the optimal painting is rbbbrr or brrrbb, both change the colors twice.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.Satisfiability","page":"References","title":"GenericTensorNetworks.Satisfiability","text":"Satisfiability{CT<:AbstractEinsum,T,WT<:Union{NoWeight, Vector}} <: GraphProblem\nSatisfiability(cnf::CNF; weights=NoWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe satisfiability problem.\n\nPositional arguments\n\ncnf is a conjunctive normal form (CNF) for specifying the satisfiability problems.\n\nKeyword arguments\n\nweights are associated with clauses.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of boolean variables, where a value can be 0 or 1.\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\nExamples\n\njulia> @bools x y z a b c\n\njulia> c1 = x ∨ ¬y\nx ∨ ¬y\n\njulia> c2 = c ∨ (¬a ∨ b)\nc ∨ ¬a ∨ b\n\njulia> c3 = (z ∨ ¬a) ∨ y\nz ∨ ¬a ∨ y\n\njulia> c4 = (c ∨ z) ∨ ¬b\nc ∨ z ∨ ¬b\n\njulia> cnf = (c1 ∧ c4) ∧ (c2 ∧ c3)\n(x ∨ ¬y) ∧ (c ∨ z ∨ ¬b) ∧ (c ∨ ¬a ∨ b) ∧ (z ∨ ¬a ∨ y)\n\njulia> gp = Satisfiability(cnf);\n\njulia> solve(gp, SizeMax())[]\n4.0ₜ\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.SetCovering","page":"References","title":"GenericTensorNetworks.SetCovering","text":"SetCovering{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem\nSetCovering(sets; weights=NoWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe set covering problem.\n\nPositional arguments\n\nsets is a vector of vectors, each set is associated with a weight specified in weights.\n\nKeyword arguments\n\nweights are associated with sets.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (absent in the set) or 1 (present in the set).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\nExamples\n\njulia> sets = [[1, 2, 5], [1, 3], [2, 4], [3, 6], [2, 3, 6]]; # each set is a vertex\n\njulia> gp = SetCovering(sets);\n\njulia> res = solve(gp, ConfigsMin())[]\n(3.0, {10110, 10101})ₜ\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.SetPacking","page":"References","title":"GenericTensorNetworks.SetPacking","text":"SetPacking{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem\nSetPacking(sets; weights=NoWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe set packing problem, a generalization of independent set problem to hypergraphs.\n\nPositional arguments\n\nsets is a vector of vectors, each set is associated with a weight specified in weights.\n\nKeyword arguments\n\nweights are associated with sets.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (absent in the set) or 1 (present in the set).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\nExamples\n\njulia> sets = [[1, 2, 5], [1, 3], [2, 4], [3, 6], [2, 3, 6]]; # each set is a vertex\n\njulia> gp = SetPacking(sets);\n\njulia> res = solve(gp, ConfigsMax())[]\n(2.0, {00110, 10010, 01100})ₜ\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.OpenPitMining","page":"References","title":"GenericTensorNetworks.OpenPitMining","text":"OpenPitMining{ET, CT<:AbstractEinsum} <: GraphProblem\nOpenPitMining(rewards; openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict())\n\nThe open pit mining problem. This problem can be solved in polynomial time with the pseudoflow algorithm.\n\nPositional arguments\n\nrewards is a matrix of rewards.\n\nKeyword arguments\n\nopenvertices specifies labels of the output tensor.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of labels, where a value can be 0 (not mined) or 1 (mined)\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\nExample\n\njulia> rewards = [-4 -7 -7 -17 -7 -26;\n 0 39 -7 -7 -4 0;\n 0 0 1 8 0 0;\n 0 0 0 0 0 0;\n 0 0 0 0 0 0;\n 0 0 0 0 0 0];\n\njulia> gp = OpenPitMining(rewards);\n\njulia> res = solve(gp, SingleConfigMax())[]\n(21.0, ConfigSampler{12, 1, 1}(111000100000))ₜ\n\njulia> is_valid_mining(rewards, res.c.data)\ntrue\n\njulia> print_mining(rewards, res.c.data)\n -4 -7 -7 -17 -7 -26 \n ◼ 39 -7 -7 -4 ◼ \n ◼ ◼ 1 8 ◼ ◼ \n ◼ ◼ ◼ ◼ ◼ ◼ \n ◼ ◼ ◼ ◼ ◼ ◼ \n ◼ ◼ ◼ ◼ ◼ ◼\n\nYou will the the mining is printed as green in an colored REPL.\n\n\n\n\n\n","category":"type"},{"location":"ref/#Graph-Problem-Interfaces","page":"References","title":"Graph Problem Interfaces","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"To subtype GraphProblem, a new type must contain a code field to represent the (optimized) tensor network. Interfaces GenericTensorNetworks.generate_tensors, labels, flavors and get_weights are required. nflavor is optional.","category":"page"},{"location":"ref/","page":"References","title":"References","text":"GenericTensorNetworks.generate_tensors\nlabels\nterms\nflavors\nget_weights\nchweights\nnflavor\nfixedvertices\n\nextract_result","category":"page"},{"location":"ref/#GenericTensorNetworks.generate_tensors","page":"References","title":"GenericTensorNetworks.generate_tensors","text":"generate_tensors(func, problem::GraphProblem)\n\nGenerate a vector of tensors as the inputs of the tensor network contraction code problem.code. func is a function to customize the tensors. func(symbol) returns a vector of elements, the length of which is same as the number of flavors.\n\nExample\n\nThe following code gives your the maximum independent set size\n\njulia> using Graphs, GenericTensorNetworks\n\njulia> gp = IndependentSet(smallgraph(:petersen));\n\njulia> getixsv(gp.code)\n25-element Vector{Vector{Int64}}:\n [1]\n [2]\n [3]\n [4]\n [5]\n [6]\n [7]\n [8]\n [9]\n [10]\n ⋮\n [3, 8]\n [4, 5]\n [4, 9]\n [5, 10]\n [6, 8]\n [6, 9]\n [7, 9]\n [7, 10]\n [8, 10]\n\njulia> gp.code(GenericTensorNetworks.generate_tensors(Tropical(1.0), gp)...)\n0-dimensional Array{Tropical{Float64}, 0}:\n4.0ₜ\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.labels","page":"References","title":"GenericTensorNetworks.labels","text":"labels(problem::GraphProblem) -> Vector\n\nThe labels of a graph problem is defined as the degrees of freedoms in the graph problem. e.g. for the maximum independent set problems, they are the indices of vertices: 1, 2, 3..., while for the max cut problem, they are the edges.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.terms","page":"References","title":"GenericTensorNetworks.terms","text":"terms(problem::GraphProblem) -> Vector\n\nThe terms of a graph problem is defined as the tensor labels that defining local energies (or weights) in the graph problem. e.g. for the maximum independent set problems, they are the vertex-tensor labels: [1], [2], [3]... The weight of a term is same as the exponents in the graph polynomial.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.flavors","page":"References","title":"GenericTensorNetworks.flavors","text":"flavors(::Type{<:GraphProblem}) -> Vector\n\nIt returns a vector of integers as the flavors of a degree of freedom. Its size is the same as the degree of freedom on a single vertex/edge.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.get_weights","page":"References","title":"GenericTensorNetworks.get_weights","text":"get_weights(problem::GraphProblem, i::Int) -> Vector\nget_weights(problem::GraphProblem) -> Vector\n\nThe weights for the problem or the weights for the degree of freedom specified by the i-th term if a second argument is provided. Weights are associated with terms in the graph problem. In graph polynomial, integer weights can be the exponents.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.chweights","page":"References","title":"GenericTensorNetworks.chweights","text":"chweights(problem::GraphProblem, weights) -> GraphProblem\n\nChange the weights for the problem and return a new problem instance. Weights are associated with terms in the graph problem. In graph polynomial, integer weights can be the exponents.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.nflavor","page":"References","title":"GenericTensorNetworks.nflavor","text":"nflavor(::Type{<:GraphProblem}) -> Int\n\nBond size is equal to the number of flavors.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.fixedvertices","page":"References","title":"GenericTensorNetworks.fixedvertices","text":"fixedvertices(problem::GraphProblem) -> Dict\n\nFix degree of freedoms in a graph problem to a certain value using a dict, where the key is a label, and the value should be in, e.g. [0, 1] in the indepenent set problem. When a degree of freedom is fixed, its size is 1. The optimal tensor network contraction order is then different from the default case.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.extract_result","page":"References","title":"GenericTensorNetworks.extract_result","text":"extract_result(p::ReducedProblem, output)\nextract_result(p::ReducedProblem)\n\nPost process the output of the target problem to get an output to the source problem. If the output is not provided, it will return a function instead. The result extraction rule is determined by the output type. e.g. If the output type is Tropical, it will be interpreted as the energy. If the output is a Vector, it will be interpreted as a configuration.\n\n\n\n\n\n","category":"function"},{"location":"ref/#Graph-Problem-Utilities","page":"References","title":"Graph Problem Utilities","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"is_independent_set\nis_maximal_independent_set\nis_dominating_set\nis_vertex_coloring\nis_matching\nis_set_covering\nis_set_packing\n\ncut_size\nspinglass_energy\nhyperspinglass_energy\nnum_paint_shop_color_switch\npaint_shop_coloring_from_config\nmis_compactify!\n\nCNF\nCNFClause\nBoolVar\nsatisfiable\n@bools\n∨\n¬\n∧\n\nis_valid_mining\nprint_mining","category":"page"},{"location":"ref/#GenericTensorNetworks.is_independent_set","page":"References","title":"GenericTensorNetworks.is_independent_set","text":"is_independent_set(g::SimpleGraph, config)\n\nReturn true if config (a vector of boolean numbers as the mask of vertices) is an independent set of graph g.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.is_maximal_independent_set","page":"References","title":"GenericTensorNetworks.is_maximal_independent_set","text":"is_maximal_independent_set(g::SimpleGraph, config)\n\nReturn true if config (a vector of boolean numbers as the mask of vertices) is a maximal independent set of graph g.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.is_dominating_set","page":"References","title":"GenericTensorNetworks.is_dominating_set","text":"is_dominating_set(g::SimpleGraph, config)\n\nReturn true if config (a vector of boolean numbers as the mask of vertices) is a dominating set of graph g.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.is_vertex_coloring","page":"References","title":"GenericTensorNetworks.is_vertex_coloring","text":"is_vertex_coloring(graph::SimpleGraph, config)\n\nReturns true if the coloring specified by config is a valid one, i.e. does not violate the contraints of vertices of an edges having different colors.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.is_matching","page":"References","title":"GenericTensorNetworks.is_matching","text":"is_matching(graph::SimpleGraph, config)\n\nReturns true if config is a valid matching on graph, and false if a vertex is double matched. config is a vector of boolean variables, which has one to one correspondence with edges(graph).\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.is_set_covering","page":"References","title":"GenericTensorNetworks.is_set_covering","text":"is_set_covering(sets::AbstractVector, config)\n\nReturn true if config (a vector of boolean numbers as the mask of sets) is a set covering of sets.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.is_set_packing","page":"References","title":"GenericTensorNetworks.is_set_packing","text":"is_set_packing(sets::AbstractVector, config)\n\nReturn true if config (a vector of boolean numbers as the mask of sets) is a set packing of sets.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.cut_size","page":"References","title":"GenericTensorNetworks.cut_size","text":"cut_size(g::SimpleGraph, config; edge_weights=NoWeight(), vertex_weights=ZeroWeight())\n\nCompute the cut size for the vertex configuration config (an iterator).\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.spinglass_energy","page":"References","title":"GenericTensorNetworks.spinglass_energy","text":"spinglass_energy(g::SimpleGraph, config; J=NoWeight(), h=ZeroWeight())\n\nCompute the spin glass state energy for the vertex configuration config. In the configuration, the spin ↑ is mapped to configuration 0, while spin ↓ is mapped to configuration 1. Let G=(VE) be the input graph, the hamiltonian is\n\nH = - sum_ij in E J_ij s_i s_j + sum_i in V h_i s_i\n\nwhere s_i in -1 1 stands for spin ↓ and spin ↑.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.hyperspinglass_energy","page":"References","title":"GenericTensorNetworks.hyperspinglass_energy","text":"hyperspinglass_energy(cliques, config; weights) -> Real\n\n\nCompute the energy for spin configuration config (an iterator).\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.num_paint_shop_color_switch","page":"References","title":"GenericTensorNetworks.num_paint_shop_color_switch","text":"num_paint_shop_color_switch(sequence::AbstractVector, coloring)\n\nReturns the number of color switches.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.paint_shop_coloring_from_config","page":"References","title":"GenericTensorNetworks.paint_shop_coloring_from_config","text":"paint_shop_coloring_from_config(p::PaintShop, config)\n\nReturns a valid painting from the paint shop configuration (given by the configuration solvers). The config is a sequence of 0 and 1, where 0 means painting the first appearence of a car in blue, 1 otherwise.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.mis_compactify!","page":"References","title":"GenericTensorNetworks.mis_compactify!","text":"mis_compactify!(tropicaltensor)\n\nCompactify tropical tensor for maximum independent set problem. It will eliminate some entries by setting them to zero, by the criteria that removing these entry does not change the MIS size of its parent graph (reference to be added).\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.CNF","page":"References","title":"GenericTensorNetworks.CNF","text":"CNF{T}\nCNF(clauses)\n\nBoolean expression in conjunctive normal form. clauses is a vector of CNFClause, if and only if all clauses are satisfied, this CNF is satisfied.\n\nExample\n\njulia> @bools x y z\n\njulia> cnf = (x ∨ y) ∧ (¬y ∨ z)\n(x ∨ y) ∧ (¬y ∨ z)\n\njulia> satisfiable(cnf, Dict([:x=>true, :y=>false, :z=>true]))\ntrue\n\njulia> satisfiable(cnf, Dict([:x=>false, :y=>false, :z=>true]))\nfalse\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.CNFClause","page":"References","title":"GenericTensorNetworks.CNFClause","text":"CNFClause{T}\nCNFClause(vars)\n\nA clause in CNF, its value is the logical or of vars, where vars is a vector of BoolVar.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.BoolVar","page":"References","title":"GenericTensorNetworks.BoolVar","text":"BoolVar{T}\nBoolVar(name, neg)\n\nBoolean variable for constructing CNF clauses.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.satisfiable","page":"References","title":"GenericTensorNetworks.satisfiable","text":"satisfiable(cnf::CNF, config::AbstractDict)\n\nReturns true if an assignment of variables satisfies a CNF.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.@bools","page":"References","title":"GenericTensorNetworks.@bools","text":"@bools(syms::Symbol...)\n\nCreate some boolean variables of type BoolVar in current scope that can be used in create a CNF.\n\nExample\n\njulia> @bools x y z\n\njulia> (x ∨ y) ∧ (¬y ∨ z)\n(x ∨ y) ∧ (¬y ∨ z)\n\n\n\n\n\n","category":"macro"},{"location":"ref/#GenericTensorNetworks.:∨","page":"References","title":"GenericTensorNetworks.:∨","text":"∨(vars...)\n\nLogical or applied on BoolVar and CNFClause. Returns a CNFClause.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.:¬","page":"References","title":"GenericTensorNetworks.:¬","text":"¬(var::BoolVar)\n\nNegation of a boolean variables of type BoolVar.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.:∧","page":"References","title":"GenericTensorNetworks.:∧","text":"∧(vars...)\n\nLogical and applied on CNFClause and CNF. Returns a new CNF.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.is_valid_mining","page":"References","title":"GenericTensorNetworks.is_valid_mining","text":"is_valid_mining(rewards::AbstractMatrix, config)\n\nReturn true if config (a boolean mask for the feasible region) is a valid mining of rewards.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.print_mining","page":"References","title":"GenericTensorNetworks.print_mining","text":"print_mining(rewards::AbstractMatrix, config)\n\nPrinting the mining solution in a colored REPL.\n\n\n\n\n\n","category":"function"},{"location":"ref/#Properties","page":"References","title":"Properties","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"PartitionFunction\nSizeMax\nSizeMin\nCountingAll\nCountingMax\nCountingMin\nGraphPolynomial\nSingleConfigMax\nSingleConfigMin\nConfigsAll\nConfigsMax\nConfigsMin","category":"page"},{"location":"ref/#GenericTensorNetworks.PartitionFunction","page":"References","title":"GenericTensorNetworks.PartitionFunction","text":"struct PartitionFunction{T} <: GenericTensorNetworks.AbstractProperty\n\nbeta\n\nCompute the partition function for the target problem.\n\nThe corresponding tensor element type is T.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.SizeMax","page":"References","title":"GenericTensorNetworks.SizeMax","text":"SizeMax{K} <: AbstractProperty\nSizeMax(k::Int)\n\nThe maximum-K set sizes. e.g. the largest size of the IndependentSet problem is also know as the independence number.\n\nThe corresponding tensor element type are max-plus tropical number Tropical if K is Single and ExtendedTropical if K is an integer.\nIt is compatible with weighted graph problems.\nBLAS (on CPU) and GPU are supported only if K is Single,\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.SizeMin","page":"References","title":"GenericTensorNetworks.SizeMin","text":"SizeMin{K} <: AbstractProperty\nSizeMin(k::Int)\n\nThe minimum-K set sizes. e.g. the smallest size ofthe MaximalIS problem is also known as the independent domination number.\n\nThe corresponding tensor element type are inverted max-plus tropical number Tropical if K is Single and inverted ExtendedTropical K is an integer.\n\nThe inverted Tropical number emulates the min-plus tropical number.\n\nIt is compatible with weighted graph problems.\nBLAS (on CPU) and GPU are supported only if K is Single,\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.CountingAll","page":"References","title":"GenericTensorNetworks.CountingAll","text":"CountingAll <: AbstractProperty\nCountingAll()\n\nCounting the total number of sets. e.g. for the IndependentSet problem, it counts the independent sets.\n\nThe corresponding tensor element type is Base.Real.\nThe weights on graph does not have effect.\nBLAS (GPU and CPU) and GPU are supported,\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.CountingMax","page":"References","title":"GenericTensorNetworks.CountingMax","text":"CountingMax{K} <: AbstractProperty\nCountingMax(K=Single)\n\nCounting the number of sets with largest-K size. e.g. for IndependentSet problem, it counts independent sets of size alpha(G) alpha(G)-1 ldots alpha(G)-K+1.\n\nThe corresponding tensor element type is CountingTropical if K is Single, and TruncatedPoly{K} if K is an integer.\nWeighted graph problems is only supported if K is Single.\nGPU is supported,\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.CountingMin","page":"References","title":"GenericTensorNetworks.CountingMin","text":"CountingMin{K} <: AbstractProperty\nCountingMin(K=Single)\n\nCounting the number of sets with smallest-K size.\n\nThe corresponding tensor element type is inverted CountingTropical if K is Single, and TruncatedPoly{K} if K is an integer.\nWeighted graph problems is only supported if K is Single.\nGPU is supported,\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.GraphPolynomial","page":"References","title":"GenericTensorNetworks.GraphPolynomial","text":"GraphPolynomial{METHOD} <: AbstractProperty\nGraphPolynomial(; method=:finitefield, kwargs...)\n\nCompute the graph polynomial, e.g. for IndependentSet problem, it is the independence polynomial. The METHOD type parameter can be one of the following symbols\n\nMethod Argument\n\n:finitefield, uses finite field algebra to fit the polynomial.\nThe corresponding tensor element type is Mods.Mod,\nIt does not have round-off error,\nGPU is supported,\nIt accepts keyword arguments maxorder (optional, e.g. the MIS size in the IndependentSet problem).\n:polynomial and :laurent, use (Laurent) polynomial numbers to solve the polynomial directly.\nThe corresponding tensor element types are Polynomial and LaurentPolynomial.\nIt might have small round-off error depending on the data type for storing the counting.\nIt has memory overhead that linear to the graph size.\n:fft, use fast fourier transformation to fit the polynomial.\nThe corresponding tensor element type is Base.Complex.\nIt has (controllable) round-off error.\nBLAS and GPU are supported.\nIt accepts keyword arguments maxorder (optional) and r, if r > 1, one has better precision for coefficients of large order, if r < 1, one has better precision for coefficients of small order.\n:fitting, fit the polynomial directly.\nThe corresponding tensor element type is floating point numbers like Base.Float64.\nIt has round-off error.\nBLAS and GPU are supported, it is the fastest among all methods.\n\nGraph polynomials are not defined for weighted graph problems.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.SingleConfigMax","page":"References","title":"GenericTensorNetworks.SingleConfigMax","text":"SingleConfigMax{K, BOUNDED} <: AbstractProperty\nSingleConfigMax(k::Int; bounded=false)\n\nFinding single solution for largest-K sizes, e.g. for IndependentSet problem, it is one of the maximum independent sets.\n\nThe corresponding data type is CountingTropical{Float64,<:ConfigSampler} if BOUNDED is false, Tropical otherwise.\nWeighted graph problems is supported.\nGPU is supported,\n\nKeyword Arguments\n\nbounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.SingleConfigMin","page":"References","title":"GenericTensorNetworks.SingleConfigMin","text":"SingleConfigMin{K, BOUNDED} <: AbstractProperty\nSingleConfigMin(k::Int; bounded=false)\n\nFinding single solution with smallest-K size.\n\nThe corresponding data type is inverted CountingTropical{Float64,<:ConfigSampler} if BOUNDED is false, inverted Tropical otherwise.\nWeighted graph problems is supported.\nGPU is supported,\n\nKeyword Arguments\n\nbounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.ConfigsAll","page":"References","title":"GenericTensorNetworks.ConfigsAll","text":"ConfigsAll{TREESTORAGE} <:AbstractProperty\nConfigsAll(; tree_storage=false)\n\nFind all valid configurations, e.g. for IndependentSet problem, it is finding all independent sets.\n\nThe corresponding data type is ConfigEnumerator.\nWeights do not take effect.\n\nKeyword Arguments\n\ntree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.ConfigsMax","page":"References","title":"GenericTensorNetworks.ConfigsMax","text":"ConfigsMax{K, BOUNDED, TREESTORAGE} <:AbstractProperty\nConfigsMax(K=Single; bounded=true, tree_storage=true)\n\nFind configurations with largest-K sizes, e.g. for IndependentSet problem, it is finding all independent sets of sizes alpha(G) alpha(G)-1 ldots alpha(G)-K+1.\n\nThe corresponding data type is CountingTropical{Float64,<:ConfigEnumerator} if K is Single and TruncatedPoly{K,<:ConfigEnumerator} if K is an integer.\nWeighted graph problems is only supported if K is Single.\n\nKeyword Arguments\n\nbounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.\ntree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.ConfigsMin","page":"References","title":"GenericTensorNetworks.ConfigsMin","text":"ConfigsMin{K, BOUNDED, TREESTORAGE} <:AbstractProperty\nConfigsMin(K=Single; bounded=true, tree_storage=false)\n\nFind configurations with smallest-K sizes.\n\nThe corresponding data type is inverted CountingTropical{Float64,<:ConfigEnumerator} if K is Single and inverted TruncatedPoly{K,<:ConfigEnumerator} if K is an integer.\nWeighted graph problems is only supported if K is Single.\n\nKeyword Arguments\n\nbounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.\ntree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.\n\n\n\n\n\n","category":"type"},{"location":"ref/#Element-Algebras","page":"References","title":"Element Algebras","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"is_commutative_semiring","category":"page"},{"location":"ref/#GenericTensorNetworks.is_commutative_semiring","page":"References","title":"GenericTensorNetworks.is_commutative_semiring","text":"is_commutative_semiring(a::T, b::T, c::T) where T\n\nCheck if elements a, b and c satisfied the commutative semiring requirements.\n\nbeginalign*\n(a oplus b) oplus c = a oplus (b oplus c) hspace5emtrianglerighttextcommutative monoid oplus with identity mathbb0\na oplus mathbb0 = mathbb0 oplus a = a \na oplus b = b oplus a \n\n(a odot b) odot c = a odot (b odot c) hspace5emtriangleright textcommutative monoid odot with identity mathbb1\na odot mathbb1 = mathbb1 odot a = a \na odot b = b odot a \n\na odot (boplus c) = aodot b oplus aodot c hspace5emtriangleright textleft and right distributive\n(aoplus b) odot c = aodot c oplus bodot c \n\na odot mathbb0 = mathbb0 odot a = mathbb0\nendalign*\n\n\n\n\n\n","category":"function"},{"location":"ref/","page":"References","title":"References","text":"TropicalNumbers.Tropical\nTropicalNumbers.CountingTropical\nExtendedTropical\nMods.Mod\nTruncatedPoly\nMax2Poly\nConfigEnumerator\nSumProductTree\nConfigSampler","category":"page"},{"location":"ref/#TropicalNumbers.Tropical","page":"References","title":"TropicalNumbers.Tropical","text":"TropicalMaxPlus{T} = Tropical{T} <: AbstractSemiring\n\nTropicalMaxPlus is a semiring algebra, can be described by\n\nTropical (TropicalMaxPlus), (ℝ, max, +, -Inf, 0).\n\nIt maps\n\n+ to max in regular algebra,\n* to + in regular algebra,\n1 to 0 in regular algebra,\n0 to -Inf in regular algebra (for integer content types, this is chosen as a small integer).\n\nExample\n\njulia> TropicalMaxPlus(1.0) + TropicalMaxPlus(3.0)\n3.0ₜ\n\njulia> TropicalMaxPlus(1.0) * TropicalMaxPlus(3.0)\n4.0ₜ\n\njulia> one(TropicalMaxPlusF64)\n0.0ₜ\n\njulia> zero(TropicalMaxPlusF64)\n-Infₜ\n\n\n\n\n\n","category":"type"},{"location":"ref/#TropicalNumbers.CountingTropical","page":"References","title":"TropicalNumbers.CountingTropical","text":"CountingTropical{T,CT} <: Number\n\nCounting tropical number type is also a semiring algebra. It is tropical algebra with one extra field for counting, it is introduced in arXiv:2008.06888.\n\nExample\n\njulia> CountingTropical(1.0, 5.0) + CountingTropical(3.0, 2.0)\n(3.0, 2.0)ₜ\n\njulia> CountingTropical(1.0, 5.0) * CountingTropical(3.0, 2.0)\n(4.0, 10.0)ₜ\n\njulia> one(CountingTropicalF64)\n(0.0, 1.0)ₜ\n\njulia> zero(CountingTropicalF64)\n(-Inf, 0.0)ₜ\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.ExtendedTropical","page":"References","title":"GenericTensorNetworks.ExtendedTropical","text":"ExtendedTropical{K,TO} <: Number\nExtendedTropical{K}(orders)\n\nExtended Tropical numbers with largest K orders keeped, or the TruncatedPoly without coefficients, TO is the element type of orders, usually Tropical numbers. This algebra maps\n\n+ to finding largest K values of union of two sets.\n* to finding largest K values of sum combination of two sets.\n0 to set [-Inf, -Inf, ..., -Inf, -Inf]\n1 to set [-Inf, -Inf, ..., -Inf, 0]\n\nFields\n\norders is a vector of Tropical (CountingTropical) numbers as the largest-K solution sizes (solutions).\n\nExamples\n\njulia> x = ExtendedTropical{3}(Tropical.([1.0, 2, 3]))\nExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[1.0ₜ, 2.0ₜ, 3.0ₜ])\n\njulia> y = ExtendedTropical{3}(Tropical.([-Inf, 2, 5]))\nExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[-Infₜ, 2.0ₜ, 5.0ₜ])\n\njulia> x * y\nExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[6.0ₜ, 7.0ₜ, 8.0ₜ])\n\njulia> x + y\nExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[2.0ₜ, 3.0ₜ, 5.0ₜ])\n\njulia> one(x)\nExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[-Infₜ, -Infₜ, 0.0ₜ])\n\njulia> zero(x)\nExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[-Infₜ, -Infₜ, -Infₜ])\n\n\n\n\n\n","category":"type"},{"location":"ref/#Mods.Mod","page":"References","title":"Mods.Mod","text":"Mod{m}(v) creates a modular number in mod m with value mod(v,m).\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.TruncatedPoly","page":"References","title":"GenericTensorNetworks.TruncatedPoly","text":"TruncatedPoly{K,T,TO} <: Number\nTruncatedPoly(coeffs::Tuple, maxorder)\n\nPolynomial truncated to largest K orders. T is the coefficients type and TO is the orders type.\n\nFields\n\ncoeffs is the largest-K coefficients of a polynomial. In GenericTensorNetworks, it can be the counting or enumeration of solutions.\nmaxorder is the order of a polynomial.\n\nExamples\n\njulia> TruncatedPoly((1,2,3), 6)\nx^4 + 2*x^5 + 3*x^6\n\njulia> TruncatedPoly((1,2,3), 6) * TruncatedPoly((5,2,1), 3)\n20*x^7 + 8*x^8 + 3*x^9\n\njulia> TruncatedPoly((1,2,3), 6) + TruncatedPoly((5,2,1), 3)\nx^4 + 2*x^5 + 3*x^6\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.Max2Poly","page":"References","title":"GenericTensorNetworks.Max2Poly","text":"Max2Poly{T,TO} = TruncatedPoly{2,T,TO}\nMax2Poly(a, b, maxorder)\n\nA shorthand of TruncatedPoly{2}.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.ConfigEnumerator","page":"References","title":"GenericTensorNetworks.ConfigEnumerator","text":"ConfigEnumerator{N,S,C} <: AbstractSetNumber\n\nSet algebra for enumerating configurations, where N is the length of configurations, C is the size of storage in unit of UInt64, S is the bit width to store a single element in a configuration, i.e. log2(# of flavors), for bitstrings, it is 1`.\n\nFields\n\ndata is a vector of StaticElementVector as the solution set.\n\nExamples\n\njulia> a = ConfigEnumerator([StaticBitVector([1,1,1,0,0]), StaticBitVector([1,0,0,0,1])])\n{11100, 10001}\n\njulia> b = ConfigEnumerator([StaticBitVector([0,0,0,0,0]), StaticBitVector([1,0,1,0,1])])\n{00000, 10101}\n\njulia> a + b\n{11100, 10001, 00000, 10101}\n\njulia> one(a)\n{00000}\n\njulia> zero(a)\n{}\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.SumProductTree","page":"References","title":"GenericTensorNetworks.SumProductTree","text":"SumProductTree{ET} <: AbstractSetNumber\n\nConfiguration enumerator encoded in a tree, it is the most natural representation given by a sum-product network and is often more memory efficient than putting the configurations in a vector. One can use generate_samples to sample configurations from this tree structure efficiently.\n\nFields\n\ntag is one of ZERO, ONE, LEAF, SUM, PROD.\ndata is the element stored in a LEAF node.\nleft and right are two operands of a SUM or PROD node.\n\nExamples\n\njulia> s = SumProductTree(bv\"00111\")\n00111\n\n\njulia> q = SumProductTree(bv\"10000\")\n10000\n\n\njulia> x = s + q\n+ (count = 2.0)\n├─ 00111\n└─ 10000\n\n\njulia> y = x * x\n* (count = 4.0)\n├─ + (count = 2.0)\n│ ├─ 00111\n│ └─ 10000\n└─ + (count = 2.0)\n ├─ 00111\n └─ 10000\n\n\njulia> collect(y)\n4-element Vector{StaticBitVector{5, 1}}:\n 00111\n 10111\n 10111\n 10000\n\njulia> zero(s)\n∅\n\n\n\njulia> one(s)\n00000\n\n\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.ConfigSampler","page":"References","title":"GenericTensorNetworks.ConfigSampler","text":"ConfigSampler{N,S,C} <: AbstractSetNumber\nConfigSampler(elements::StaticElementVector)\n\nThe algebra for sampling one configuration, where N is the length of configurations, C is the size of storage in unit of UInt64, S is the bit width to store a single element in a configuration, i.e. log2(# of flavors), for bitstrings, it is 1`.\n\nnote: Note\nConfigSampler is a probabilistic commutative semiring, adding two config samplers do not give you deterministic results.\n\nFields\n\ndata is a StaticElementVector as the sampled solution.\n\nExamples\n\njulia> ConfigSampler(StaticBitVector([1,1,1,0,0]))\nConfigSampler{5, 1, 1}(11100)\n\njulia> ConfigSampler(StaticBitVector([1,1,1,0,0])) + ConfigSampler(StaticBitVector([1,0,1,0,0]))\nConfigSampler{5, 1, 1}(10100)\n\njulia> ConfigSampler(StaticBitVector([1,1,1,0,0])) * ConfigSampler(StaticBitVector([0,0,0,0,1]))\nConfigSampler{5, 1, 1}(11101)\n\njulia> one(ConfigSampler{5, 1, 1})\nConfigSampler{5, 1, 1}(00000)\n\njulia> zero(ConfigSampler{5, 1, 1})\nConfigSampler{5, 1, 1}(11111)\n\n\n\n\n\n","category":"type"},{"location":"ref/","page":"References","title":"References","text":"GenericTensorNetworks also exports the Polynomial and LaurentPolynomial types defined in package Polynomials.","category":"page"},{"location":"ref/","page":"References","title":"References","text":"StaticBitVector\nStaticElementVector\nOnehotVec\nsave_configs\nload_configs\nsave_sumproduct\nload_sumproduct\n@bv_str\nonehotv\n\ngenerate_samples\nhamming_distribution","category":"page"},{"location":"ref/#GenericTensorNetworks.StaticBitVector","page":"References","title":"GenericTensorNetworks.StaticBitVector","text":"StaticBitVector{N,C} = StaticElementVector{N,1,C}\nStaticBitVector(x::AbstractVector)\n\nExamples\n\njulia> sb = StaticBitVector([1,0,0,1,1])\n10011\n\njulia> sb[3]\n0x0000000000000000\n\njulia> collect(Int, sb)\n5-element Vector{Int64}:\n 1\n 0\n 0\n 1\n 1\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.StaticElementVector","page":"References","title":"GenericTensorNetworks.StaticElementVector","text":"StaticElementVector{N,S,C}\nStaticElementVector(nflavor::Int, x::AbstractVector)\n\nN is the length of vector, C is the size of storage in unit of UInt64, S is the stride defined as the log2(# of flavors). When the number of flavors is 2, it is a StaticBitVector.\n\nFields\n\ndata is a tuple of UInt64 for storing the configuration of static elements.\n\nExamples\n\njulia> ev = StaticElementVector(3, [1,2,0,1,2])\n12012\n\njulia> ev[2]\n0x0000000000000002\n\njulia> collect(Int, ev)\n5-element Vector{Int64}:\n 1\n 2\n 0\n 1\n 2\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.OnehotVec","page":"References","title":"GenericTensorNetworks.OnehotVec","text":"OnehotVec{N,NF}\nOnehotVec{N,NF}(loc, val)\n\nOnehot vector type, N is the number of vector length, NF is the number of flavors.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.save_configs","page":"References","title":"GenericTensorNetworks.save_configs","text":"save_configs(filename, data::ConfigEnumerator; format=:binary)\n\nSave configurations data to file filename. The format is :binary or :text.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.load_configs","page":"References","title":"GenericTensorNetworks.load_configs","text":"load_configs(filename; format=:binary, bitlength=nothing, nflavors=2)\n\nLoad configurations from file filename. The format is :binary or :text. If the format is :binary, the bitstring length bitlength must be specified, nflavors specifies the degree of freedom.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.save_sumproduct","page":"References","title":"GenericTensorNetworks.save_sumproduct","text":"save_sumproduct(filename, t::SumProductTree)\n\nSerialize a sum-product tree into a file.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.load_sumproduct","page":"References","title":"GenericTensorNetworks.load_sumproduct","text":"load_sumproduct(filename)\n\nDeserialize a sum-product tree from a file.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.@bv_str","page":"References","title":"GenericTensorNetworks.@bv_str","text":"Constructing a static bit vector.\n\n\n\n\n\n","category":"macro"},{"location":"ref/#GenericTensorNetworks.onehotv","page":"References","title":"GenericTensorNetworks.onehotv","text":"onehotv(::Type{<:StaticElementVector}, i, v)\nonehotv(::Type{<:StaticBitVector, i)\n\nReturns a static element vector, with the value at location i being v (1 if not specified).\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.generate_samples","page":"References","title":"GenericTensorNetworks.generate_samples","text":"generate_samples(t::SumProductTree, nsamples::Int)\n\nDirect sampling configurations from a SumProductTree instance.\n\nExamples\n\njulia> using Graphs\n\njulia> g= smallgraph(:petersen)\n{10, 15} undirected simple Int64 graph\n\njulia> t = solve(IndependentSet(g), ConfigsAll(; tree_storage=true))[];\n\njulia> samples = generate_samples(t, 1000);\n\njulia> all(s->is_independent_set(g, s), samples)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.hamming_distribution","page":"References","title":"GenericTensorNetworks.hamming_distribution","text":"hamming_distribution(S, T)\n\nCompute the distribution of pair-wise Hamming distances, which is defined as:\n\nc(k) = sum_sigmain S tauin T delta(rm dist(sigma tau) k)\n\nwhere delta is a function that returns 1 if two arguments are equivalent, 0 otherwise, rm dist is the Hamming distance function.\n\nReturns the counting as a vector.\n\n\n\n\n\n","category":"function"},{"location":"ref/#Tensor-Network","page":"References","title":"Tensor Network","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"optimize_code\ngetixsv\ngetiyv\ncontraction_complexity\nestimate_memory\n@ein_str\nGreedyMethod\nTreeSA\nSABipartite\nKaHyParBipartite\nMergeVectors\nMergeGreedy","category":"page"},{"location":"ref/#OMEinsumContractionOrders.optimize_code","page":"References","title":"OMEinsumContractionOrders.optimize_code","text":"optimize_code(eincode, size_dict, optimizer = GreedyMethod(), simplifier=nothing, permute=true) -> optimized_eincode\n\nOptimize the einsum contraction code and reduce the time/space complexity of tensor network contraction. Returns a NestedEinsum instance. Input arguments are\n\neincode is an einsum contraction code instance, one of DynamicEinCode, StaticEinCode or NestedEinsum.\nsize is a dictionary of \"edge label=>edge size\" that contains the size information, one can use uniformsize(eincode, 2) to create a uniform size.\noptimizer is a CodeOptimizer instance, should be one of GreedyMethod, KaHyParBipartite, SABipartite or TreeSA. Check their docstrings for details.\nsimplifier is one of MergeVectors or MergeGreedy.\noptimize the permutation if permute is true.\n\nExamples\n\njulia> using OMEinsum\n\njulia> code = ein\"ij, jk, kl, il->\"\nij, jk, kl, il -> \n\njulia> optimize_code(code, uniformsize(code, 2), TreeSA())\nSlicedEinsum{Char, NestedEinsum{DynamicEinCode{Char}}}(Char[], ki, ki -> \n├─ jk, ij -> ki\n│ ├─ jk\n│ └─ ij\n└─ kl, il -> ki\n ├─ kl\n └─ il\n)\n\n\n\n\n\n","category":"function"},{"location":"ref/#OMEinsum.getixsv","page":"References","title":"OMEinsum.getixsv","text":"getixsv(code)\n\nGet labels of input tensors for EinCode, NestedEinsum and some other einsum like objects. Returns a vector of vectors.\n\njulia> getixsv(ein\"(ij,jk),k->i\")\n3-element Vector{Vector{Char}}:\n ['i', 'j']\n ['j', 'k']\n ['k']\n\n\n\n\n\n","category":"function"},{"location":"ref/#OMEinsum.getiyv","page":"References","title":"OMEinsum.getiyv","text":"getiy(code)\n\nGet labels of the output tensor for EinCode, NestedEinsum and some other einsum like objects. Returns a vector.\n\njulia> getiyv(ein\"(ij,jk),k->i\")\n1-element Vector{Char}:\n 'i': ASCII/Unicode U+0069 (category Ll: Letter, lowercase)\n\n\n\n\n\n","category":"function"},{"location":"ref/#OMEinsumContractionOrders.contraction_complexity","page":"References","title":"OMEinsumContractionOrders.contraction_complexity","text":"contraction_complexity(eincode, size_dict) -> ContractionComplexity\n\nReturns the time, space and read-write complexity of the einsum contraction. The returned object contains 3 fields:\n\ntime complexity tc defined as log2(number of element-wise multiplications).\nspace complexity sc defined as log2(size of the maximum intermediate tensor).\nread-write complexity rwc defined as log2(the number of read-write operations).\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.estimate_memory","page":"References","title":"GenericTensorNetworks.estimate_memory","text":"estimate_memory(\n problem::GraphProblem,\n property::GenericTensorNetworks.AbstractProperty;\n T\n) -> Any\n\n\nMemory estimation in number of bytes to compute certain property of a problem. T is the base type.\n\n\n\n\n\n","category":"function"},{"location":"ref/#OMEinsum.@ein_str","page":"References","title":"OMEinsum.@ein_str","text":"ein\"ij,jk -> ik\"(A,B)\n\nString macro interface which understands numpy.einsum's notation. Translates strings into StaticEinCode-structs that can be called to evaluate an einsum. To control evaluation order, use parentheses - instead of an EinCode, a NestedEinsum is returned which evaluates the expression according to parens. The valid character ranges for index-labels are a-z and α-ω.\n\nexample\n\njulia> a, b, c = rand(10,10), rand(10,10), rand(10,1);\n\njulia> ein\"ij,jk,kl -> il\"(a,b,c) ≈ ein\"(ij,jk),kl -> il\"(a,b,c) ≈ a * b * c\ntrue\n\n\n\n\n\n","category":"macro"},{"location":"ref/#OMEinsumContractionOrders.GreedyMethod","page":"References","title":"OMEinsumContractionOrders.GreedyMethod","text":"GreedyMethod{MT}\nGreedyMethod(; method=MinSpaceOut(), nrepeat=10)\n\nThe fast but poor greedy optimizer. Input arguments are\n\nmethod is MinSpaceDiff() or MinSpaceOut.\nMinSpaceOut choose one of the contraction that produces a minimum output tensor size,\nMinSpaceDiff choose one of the contraction that decrease the space most.\nnrepeat is the number of repeatition, returns the best contraction order.\n\n\n\n\n\n","category":"type"},{"location":"ref/#OMEinsumContractionOrders.TreeSA","page":"References","title":"OMEinsumContractionOrders.TreeSA","text":"TreeSA{RT,IT,GM}\nTreeSA(; sc_target=20, βs=collect(0.01:0.05:15), ntrials=10, niters=50,\n sc_weight=1.0, rw_weight=0.2, initializer=:greedy, greedy_config=GreedyMethod(; nrepeat=1))\n\nOptimize the einsum contraction pattern using the simulated annealing on tensor expression tree.\n\nsc_target is the target space complexity,\nntrials, βs and niters are annealing parameters, doing ntrials indepedent annealings, each has inverse tempteratures specified by βs, in each temperature, do niters updates of the tree.\nsc_weight is the relative importance factor of space complexity in the loss compared with the time complexity.\nrw_weight is the relative importance factor of memory read and write in the loss compared with the time complexity.\ninitializer specifies how to determine the initial configuration, it can be :greedy or :random. If it is using :greedy method to generate the initial configuration, it also uses two extra arguments greedy_method and greedy_nrepeat.\nnslices is the number of sliced legs, default is 0.\nfixed_slices is a vector of sliced legs, default is [].\n\nReferences\n\nRecursive Multi-Tensor Contraction for XEB Verification of Quantum Circuits\n\n\n\n\n\n","category":"type"},{"location":"ref/#OMEinsumContractionOrders.SABipartite","page":"References","title":"OMEinsumContractionOrders.SABipartite","text":"SABipartite{RT,BT}\nSABipartite(; sc_target=25, ntrials=50, βs=0.1:0.2:15.0, niters=1000\n max_group_size=40, greedy_config=GreedyMethod(), initializer=:random)\n\nOptimize the einsum code contraction order using the Simulated Annealing bipartition + Greedy approach. This program first recursively cuts the tensors into several groups using simulated annealing, with maximum group size specifed by max_group_size and maximum space complexity specified by sc_target, Then finds the contraction order inside each group with the greedy search algorithm. Other arguments are\n\nsize_dict, a dictionary that specifies leg dimensions,\nsc_target is the target space complexity, defined as log2(number of elements in the largest tensor),\nmax_group_size is the maximum size that allowed to used greedy search,\nβs is a list of inverse temperature 1/T,\nniters is the number of iteration in each temperature,\nntrials is the number of repetition (with different random seeds),\ngreedy_config configures the greedy method,\ninitializer, the partition configuration initializer, one can choose :random or :greedy (slow but better).\n\nReferences\n\nHyper-optimized tensor network contraction\n\n\n\n\n\n","category":"type"},{"location":"ref/#OMEinsumContractionOrders.KaHyParBipartite","page":"References","title":"OMEinsumContractionOrders.KaHyParBipartite","text":"KaHyParBipartite{RT,IT,GM}\nKaHyParBipartite(; sc_target, imbalances=collect(0.0:0.005:0.8),\n max_group_size=40, greedy_config=GreedyMethod())\n\nOptimize the einsum code contraction order using the KaHyPar + Greedy approach. This program first recursively cuts the tensors into several groups using KaHyPar, with maximum group size specifed by max_group_size and maximum space complexity specified by sc_target, Then finds the contraction order inside each group with the greedy search algorithm. Other arguments are\n\nsc_target is the target space complexity, defined as log2(number of elements in the largest tensor),\nimbalances is a KaHyPar parameter that controls the group sizes in hierarchical bipartition,\nmax_group_size is the maximum size that allowed to used greedy search,\ngreedy_config is a greedy optimizer.\n\nReferences\n\nHyper-optimized tensor network contraction\nSimulating the Sycamore quantum supremacy circuits\n\n\n\n\n\n","category":"type"},{"location":"ref/#OMEinsumContractionOrders.MergeVectors","page":"References","title":"OMEinsumContractionOrders.MergeVectors","text":"MergeVectors <: CodeSimplifier\nMergeVectors()\n\nContraction code simplifier (in order to reduce the time of calling optimizers) that merges vectors to closest tensors.\n\n\n\n\n\n","category":"type"},{"location":"ref/#OMEinsumContractionOrders.MergeGreedy","page":"References","title":"OMEinsumContractionOrders.MergeGreedy","text":"MergeGreedy <: CodeSimplifier\nMergeGreedy(; threshhold=-1e-12)\n\nContraction code simplifier (in order to reduce the time of calling optimizers) that merges tensors greedily if the space complexity of merged tensors is reduced (difference smaller than the threshhold).\n\n\n\n\n\n","category":"type"},{"location":"ref/#Others","page":"References","title":"Others","text":"","category":"section"},{"location":"ref/#Graph","page":"References","title":"Graph","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"show_graph\nshow_gallery\nshow_einsum\n\ndiagonal_coupled_graph\nsquare_lattice_graph\nunit_disk_graph\nline_graph\n\nrandom_diagonal_coupled_graph\nrandom_square_lattice_graph","category":"page"},{"location":"ref/#LuxorGraphPlot.show_graph","page":"References","title":"LuxorGraphPlot.show_graph","text":"show_graph([f, ]graph::SimpleGraph;\n locs=nothing,\n layout=:auto,\n optimal_distance=1.0,\n spring_mask=trues(nv(graph)),\n\n vertex_colors=nothing,\n vertex_sizes=nothing,\n vertex_stroke_colors=nothing,\n vertex_text_colors=nothing,\n edge_colors=nothing,\n edge_line_widths=nothing,\n texts = nothing,\n format=DEFAULT_FORMAT[],\n filename=nothing,\n kwargs...)\n\nShow a graph in VSCode, Pluto or Jupyter notebook, or save it to a file.\n\nPositional arguments\n\nf is a function that returns extra Luxor plotting statements.\ngraph is a graph instance.\n\nKeyword arguments\n\nlocs is a vector of tuples for specifying the vertex locations.\nlayout is one of [:auto, :spring, :stress], the default value is :spring if locs is nothing.\noptimal_distance is a optimal distance parameter for spring optimizer.\nspring_mask specfies which location is optimizable for spring optimizer.\nvertex_colors is a vector of color strings for specifying vertex fill colors.\nvertex_sizes is a vector of real numbers for specifying vertex sizes.\nvertex_shapes is a vector of strings for specifying vertex shapes, the string should be \"circle\" or \"box\".\nvertex_stroke_colors is a vector of color strings for specifying vertex stroke colors.\nvertex_text_colors is a vector of color strings for specifying vertex text colors.\nedge_colors is a vector of color strings for specifying edge colors.\nedge_line_widths is a vector of real numbers for specifying edge line widths.\ntexts is a vector of strings for labeling vertices.\nformat is the output format, which can be :svg, :png or :pdf.\nfilename is a string as the output filename.\n\nExtra keyword arguments\n\ngeneral\nxpad::Float64 = 1.0, the padding space in x direction\nypad::Float64 = 1.0, the padding space in y direction\nxpad_right::Float64 = 1.0, the padding space in x direction (right side)\nypad_bottom::Float64 = 1.0, the padding space in y direction (bottom side)\nbackground_color = DEFAULT_BACKGROUND_COLOR[], the background color\nunit::Float64 = DEFAULT_UNIT[], the unit distance as the number of pixels\nfontsize::Float64 = DEFAULT_FONTSIZE[], the font size\nfontface::String = \"\", the font face, leave empty to follow system\nvertex\nvertex_text_color = DEFAULT_VERTEX_TEXT_COLOR[], the default text color\nvertex_stroke_color = DEFAULT_VERTEX_STROKE_COLOR[], the default stroke color for vertices\nvertex_fill_color = DEFAULT_VERTEX_FILL_COLOR[], the default default fill color for vertices\nvertex_size::Float64 = DEFAULT_VERTEX_SIZE[], the default vertex size\nvertex_shape::String = \"circle\", the default vertex shape, which can be \"circle\" or \"box\"\nvertex_line_width::Float64 = 1, the default vertex stroke line width\nvertex_line_style::String = \"solid\", the line style of vertex stroke, which can be one of [\"solid\", \"dotted\", \"dot\", \"dotdashed\", \"longdashed\", \"shortdashed\", \"dash\", \"dashed\", \"dotdotdashed\", \"dotdotdotdashed\"]\nedge\nedge_color = DEFAULT_EDGE_COLOR[], the default edge color\nedge_line_width::Float64 = 1, the default line width\nedge_style::String = \"solid\", the line style of edges, which can be one of [\"solid\", \"dotted\", \"dot\", \"dotdashed\", \"longdashed\", \"shortdashed\", \"dash\", \"dashed\", \"dotdotdashed\", \"dotdotdotdashed\"]\n\nExample\n\njulia> using Graphs\n\njulia> show_graph(smallgraph(:petersen); format=:png, vertex_colors=rand([\"blue\", \"red\"], 10));\n\n\n\n\n\n","category":"function"},{"location":"ref/#LuxorGraphPlot.show_gallery","page":"References","title":"LuxorGraphPlot.show_gallery","text":"show_gallery([f, ]graph::SimpleGraph, grid::Tuple{Int,Int};\n locs=nothing,\n layout=:auto,\n optimal_distance=1.0,\n spring_mask=trues(nv(graph)),\n\n vertex_configs=nothing,\n edge_configs=nothing,\n vertex_color=nothing,\n edge_color=nothing,\n edge_line_widths=nothing,\n\n vertex_sizes=nothing,\n vertex_shapes=nothing,\n vertex_stroke_colors=nothing,\n vertex_text_colors=nothing,\n texts=nothing,\n xpad=1.0,\n ypad=1.0,\n format=DEFAULT_FORMAT[],\n filename=nothing,\n kwargs...)\n\nShow a gallery of graphs for multiple vertex configurations or edge configurations in VSCode, Pluto or Jupyter notebook, or save it to a file.\n\nPositional arguments\n\nf is a function that returns extra Luxor plotting statements.\ngraph is a graph instance.\ngrid is the grid layout of the gallery, e.g. input value (2, 3) means a grid layout with 2 rows and 3 columns.\n\nKeyword arguments\n\nlocs is a vector of tuples for specifying the vertex locations.\nlayout is one of [:auto, :spring, :stress], the default value is :spring if locs is nothing.\noptimal_distance is a optimal distance parameter for spring optimizer.\nspring_mask specfies which location is optimizable for spring optimizer.\nvertex_configs is an iterator of bit strings for specifying vertex configurations. It will be rendered as vertex colors.\nedge_configs is an iterator of bit strings for specifying edge configurations. It will be rendered as edge colors.\nedge_color is a dictionary that specifies the edge configuration - color map.\nedge_line_widths is a vector of real numbers for specifying edge line widths.\nvertex_color is a dictionary that specifies the vertex configuration - color map.\nvertex_sizes is a vector of real numbers for specifying vertex sizes.\nvertex_shapes is a vector of strings for specifying vertex shapes, the string should be \"circle\" or \"box\".\nvertex_stroke_colors is a vector of color strings for specifying vertex stroke colors.\nvertex_text_colors is a vector of color strings for specifying vertex text colors.\ntexts is a vector of strings for labeling vertices.\nxpad is the space between two adjacent plots in x direction.\nypad is the space between two adjacent plots in y direction.\nformat is the output format, which can be :svg, :png or :pdf.\nfilename is a string as the output filename.\n\nExtra keyword arguments\n\ngeneral\nxpad::Float64 = 1.0, the padding space in x direction\nypad::Float64 = 1.0, the padding space in y direction\nxpad_right::Float64 = 1.0, the padding space in x direction (right side)\nypad_bottom::Float64 = 1.0, the padding space in y direction (bottom side)\nbackground_color = DEFAULT_BACKGROUND_COLOR[], the background color\nunit::Float64 = DEFAULT_UNIT[], the unit distance as the number of pixels\nfontsize::Float64 = DEFAULT_FONTSIZE[], the font size\nfontface::String = \"\", the font face, leave empty to follow system\nvertex\nvertex_text_color = DEFAULT_VERTEX_TEXT_COLOR[], the default text color\nvertex_stroke_color = DEFAULT_VERTEX_STROKE_COLOR[], the default stroke color for vertices\nvertex_fill_color = DEFAULT_VERTEX_FILL_COLOR[], the default default fill color for vertices\nvertex_size::Float64 = DEFAULT_VERTEX_SIZE[], the default vertex size\nvertex_shape::String = \"circle\", the default vertex shape, which can be \"circle\" or \"box\"\nvertex_line_width::Float64 = 1, the default vertex stroke line width\nvertex_line_style::String = \"solid\", the line style of vertex stroke, which can be one of [\"solid\", \"dotted\", \"dot\", \"dotdashed\", \"longdashed\", \"shortdashed\", \"dash\", \"dashed\", \"dotdotdashed\", \"dotdotdotdashed\"]\nedge\nedge_color = DEFAULT_EDGE_COLOR[], the default edge color\nedge_line_width::Float64 = 1, the default line width\nedge_style::String = \"solid\", the line style of edges, which can be one of [\"solid\", \"dotted\", \"dot\", \"dotdashed\", \"longdashed\", \"shortdashed\", \"dash\", \"dashed\", \"dotdotdashed\", \"dotdotdotdashed\"]\n\nExample\n\njulia> using Graphs\n\njulia> show_gallery(smallgraph(:petersen), (2, 3); format=:png, vertex_configs=[rand(Bool, 10) for k=1:6]);\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.show_einsum","page":"References","title":"GenericTensorNetworks.show_einsum","text":"show_einsum(ein::AbstractEinsum;\n tensor_locs=nothing,\n label_locs=nothing, # dict\n spring::Bool=true,\n optimal_distance=1.0,\n\n tensor_size=0.3,\n tensor_color=\"black\",\n tensor_text_color=\"white\",\n annotate_tensors=false,\n\n label_size=0.15,\n label_color=\"black\",\n open_label_color=\"red\",\n annotate_labels=true,\n kwargs...\n )\n\nPositional arguments\n\nein is an Einsum contraction code (provided by package OMEinsum).\n\nKeyword arguments\n\ntensor_locs is a vector of tuples for specifying the vertex locations.\nlabel_locs is a vector of tuples for specifying the vertex locations.\nspring is switch to use spring method to optimize the location.\noptimal_distance is a optimal distance parameter for spring optimizer.\ntensor_color is a string to specify the color of tensor nodes.\ntensor_size is a real number to specify the size of tensor nodes.\ntensor_text_color is a color strings to specify tensor text color.\nannotate_tensors is a boolean switch for annotate different tensors by integers.\nlabel_size is a real number to specify label text node size.\nlabel_color is a color strings to specify label text color.\nopen_label_color is a color strings to specify open label text color.\nannotate_labels is a boolean switch for annotate different labels.\nformat is the output format, which can be :svg, :png or :pdf.\nfilename is a string as the output filename.\n\nExtra keyword arguments\n\ngeneral\nxpad::Float64 = 1.0, the padding space in x direction\nypad::Float64 = 1.0, the padding space in y direction\nxpad_right::Float64 = 1.0, the padding space in x direction (right side)\nypad_bottom::Float64 = 1.0, the padding space in y direction (bottom side)\nbackground_color = DEFAULT_BACKGROUND_COLOR[], the background color\nunit::Float64 = DEFAULT_UNIT[], the unit distance as the number of pixels\nfontsize::Float64 = DEFAULT_FONTSIZE[], the font size\nfontface::String = \"\", the font face, leave empty to follow system\nvertex\nvertex_text_color = DEFAULT_VERTEX_TEXT_COLOR[], the default text color\nvertex_stroke_color = DEFAULT_VERTEX_STROKE_COLOR[], the default stroke color for vertices\nvertex_fill_color = DEFAULT_VERTEX_FILL_COLOR[], the default default fill color for vertices\nvertex_size::Float64 = DEFAULT_VERTEX_SIZE[], the default vertex size\nvertex_shape::String = \"circle\", the default vertex shape, which can be \"circle\" or \"box\"\nvertex_line_width::Float64 = 1, the default vertex stroke line width\nvertex_line_style::String = \"solid\", the line style of vertex stroke, which can be one of [\"solid\", \"dotted\", \"dot\", \"dotdashed\", \"longdashed\", \"shortdashed\", \"dash\", \"dashed\", \"dotdotdashed\", \"dotdotdotdashed\"]\nedge\nedge_color = DEFAULT_EDGE_COLOR[], the default edge color\nedge_line_width::Float64 = 1, the default line width\nedge_style::String = \"solid\", the line style of edges, which can be one of [\"solid\", \"dotted\", \"dot\", \"dotdashed\", \"longdashed\", \"shortdashed\", \"dash\", \"dashed\", \"dotdotdashed\", \"dotdotdotdashed\"]\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.diagonal_coupled_graph","page":"References","title":"GenericTensorNetworks.diagonal_coupled_graph","text":"diagonal_coupled_graph(mask::AbstractMatrix{Bool})\n\nCreate a masked diagonal coupled square lattice graph from a specified mask.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.square_lattice_graph","page":"References","title":"GenericTensorNetworks.square_lattice_graph","text":"square_lattice_graph(mask::AbstractMatrix{Bool})\n\nCreate a masked square lattice graph.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.unit_disk_graph","page":"References","title":"GenericTensorNetworks.unit_disk_graph","text":"unit_disk_graph(locs::AbstractVector, unit::Real)\n\nCreate a unit disk graph with locations specified by locs and unit distance unit.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.line_graph","page":"References","title":"GenericTensorNetworks.line_graph","text":"line_graph(g::SimpleGraph)\n\nReturns the line graph of g. The line graph is generated by mapping an edge to a vertex and two edges sharing a common vertex will be connected.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.random_diagonal_coupled_graph","page":"References","title":"GenericTensorNetworks.random_diagonal_coupled_graph","text":"random_diagonal_coupled_graph(m::Int, n::Int, ρ::Real)\n\nCreate a mtimes n random masked diagonal coupled square lattice graph, with number of vertices equal to lfloor m times ntimes rho rceil.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.random_square_lattice_graph","page":"References","title":"GenericTensorNetworks.random_square_lattice_graph","text":"random_square_lattice_graph(m::Int, n::Int, ρ::Real)\n\nCreate a random masked square lattice graph, with number of vertices fixed to lfloor mnrho rceil.\n\n\n\n\n\n","category":"function"},{"location":"ref/","page":"References","title":"References","text":"One can also use random_regular_graph and smallgraph in Graphs to build special graphs.","category":"page"},{"location":"ref/#Multiprocessing","page":"References","title":"Multiprocessing","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"GenericTensorNetworks.SimpleMultiprocessing.multiprocess_run","category":"page"},{"location":"ref/#GenericTensorNetworks.SimpleMultiprocessing.multiprocess_run","page":"References","title":"GenericTensorNetworks.SimpleMultiprocessing.multiprocess_run","text":"multiprocess_run(func, inputs::AbstractVector)\n\nExecute function func on inputs with multiple processing.\n\nExample\n\nSuppose we have a file run.jl with the following contents\n\nusing GenericTensorNetworks.SimpleMultiprocessing\n\nresults = multiprocess_run(x->x^2, randn(8))\n\nIn an terminal, you may run the script with 4 processes by typing\n\n$ julia -p4 run.jl\n From worker 2:\t[ Info: running argument -0.17544008350172655 on device 2\n From worker 5:\t[ Info: running argument 0.34578117779452555 on device 5\n From worker 3:\t[ Info: running argument 2.0312551239727705 on device 3\n From worker 4:\t[ Info: running argument -0.7319353419291961 on device 4\n From worker 2:\t[ Info: running argument 0.013132180639054629 on device 2\n From worker 3:\t[ Info: running argument 0.9960101782201602 on device 3\n From worker 4:\t[ Info: running argument -0.5613942832743966 on device 4\n From worker 5:\t[ Info: running argument 0.39460402723831134 on device 5\n\n\n\n\n\n","category":"function"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = GenericTensorNetworks","category":"page"},{"location":"#GenericTensorNetworks","page":"Home","title":"GenericTensorNetworks","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"This package implements generic tensor networks to compute solution space properties of a class of hard combinatorial problems. The solution space properties include","category":"page"},{"location":"","page":"Home","title":"Home","text":"The maximum/minimum solution sizes,\nThe number of solutions at certain sizes,\nThe enumeration of solutions at certain sizes.\nThe direct sampling of solutions at certain sizes.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The solvable problems include Independent set problem, Maximal independent set problem, Spin-glass problem, Cutting problem, Vertex matching problem, Binary paint shop problem, Coloring problem, Dominating set problem, Satisfiability problem, Set packing problem and Set covering problem.","category":"page"},{"location":"#Background-knowledge","page":"Home","title":"Background knowledge","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Please check our paper \"Computing properties of independent sets by generic programming tensor networks\". If you find our paper or software useful in your work, we would be grateful if you could cite our work. The CITATION.bib file in the root of this repository lists the relevant papers.","category":"page"},{"location":"#Quick-start","page":"Home","title":"Quick start","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"You can find a set up guide in our README. To get started, open a Julia REPL and type the following code.","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> using GenericTensorNetworks, Graphs\n\njulia> # using CUDA\n\njulia> solve(\n IndependentSet(\n Graphs.random_regular_graph(20, 3);\n optimizer = TreeSA(),\n weights = NoWeight(), # default: uniform weight 1\n openvertices = (), # default: no open vertices\n fixedvertices = Dict() # default: no fixed vertices\n ),\n GraphPolynomial();\n usecuda=false # the default value\n )\n0-dimensional Array{Polynomial{BigInt, :x}, 0}:\nPolynomial(1 + 20*x + 160*x^2 + 659*x^3 + 1500*x^4 + 1883*x^5 + 1223*x^6 + 347*x^7 + 25*x^8)","category":"page"},{"location":"","page":"Home","title":"Home","text":"Here the main function solve takes three input arguments, the problem instance of type IndependentSet, the property instance of type GraphPolynomial and an optional key word argument usecuda to decide use GPU or not. If one wants to use GPU to accelerate the computation, the using CUDA statement must uncommented.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The problem instance takes four arguments to initialize, the only positional argument is the graph instance that one wants to solve, the key word argument optimizer is for specifying the tensor network optimization algorithm, the key word argument weights is for specifying the weights of vertices as either a vector or NoWeight(). The keyword argument openvertices is a tuple of labels for specifying the degrees of freedom not summed over, and fixedvertices is a label-value dictionary for specifying the fixed values of the degree of freedoms. Here, we use TreeSA method as the tensor network optimizer, and leave weights and openvertices the default values. The TreeSA method finds the best contraction order in most of our applications, while the default GreedyMethod runs the fastest.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The first execution of this function will be a bit slow due to Julia's just in time compiling. The subsequent runs will be fast. The following diagram lists possible combinations of input arguments, where functions in the Graph are mainly defined in the package Graphs, and the rest can be found in this package.","category":"page"},{"location":"","page":"Home","title":"Home","text":"
\n\n
","category":"page"},{"location":"","page":"Home","title":"Home","text":"⠀ You can find many examples in this documentation, a good one to start with is Independent set problem.","category":"page"}] +[{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"EditURL = \"../../../examples/IndependentSet.jl\"","category":"page"},{"location":"generated/IndependentSet/#Independent-set-problem","page":"Independent set problem","title":"Independent set problem","text":"","category":"section"},{"location":"generated/IndependentSet/#Problem-definition","page":"Independent set problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"In graph theory, an independent set is a set of vertices in a graph, no two of which are adjacent.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"In the following, we are going to solve the solution space properties of the independent set problem on the Petersen graph. To start, let us define a Petersen graph instance.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"using GenericTensorNetworks, Graphs\n\ngraph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can visualize this graph using the show_graph function","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"# set the vertex locations manually instead of using the default spring layout\nrot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a\n\nlocations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]\n\nshow_graph(graph; locs=locations, format=:svg)","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The graphical display is available in the following editors","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"a VSCode editor,\na Jupyter notebook,\nor a Pluto notebook,","category":"page"},{"location":"generated/IndependentSet/#Generic-tensor-network-representation","page":"Independent set problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The generic tensor network representation of the independent set problem can be constructed with IndependentSet.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"problem = IndependentSet(graph; optimizer=TreeSA());\nnothing #hide","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"Here, the key word argument optimizer specifies the tensor network contraction order optimizer as a local search based optimizer TreeSA. The resulting contraction order optimized tensor network is contained in the code field of problem.","category":"page"},{"location":"generated/IndependentSet/#Theory-(can-skip)","page":"Independent set problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"Let G=(V E) be a graph with each vertex vin V associated with a weight w_v. To reduce the independent set problem on it to a tensor network contraction, we first map a vertex vin V to a label s_v in 0 1 of dimension 2, where we use 0 (1) to denote a vertex absent (present) in the set. For each vertex v, we defined a parameterized rank-one tensor indexed by s_v as","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"W(x_v^w_v) = left(beginmatrix\n 1 \n x_v^w_v\n endmatrixright)","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"where x_v is a variable associated with v. Similarly, for each edge (u v) in E, we define a matrix B indexed by s_u and s_v as","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"B = left(beginmatrix\n1 1\n1 0\nendmatrixright)","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"Ideally, an optimal contraction order has a space complexity 2^rm tw(G), where rm tw(G) is the tree-width of G (or graph in the code). We can check the time, space and read-write complexities by typing","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"contraction_complexity(problem)","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"For more information about how to improve the contraction order, please check the Performance Tips.","category":"page"},{"location":"generated/IndependentSet/#Solution-space-properties","page":"Independent set problem","title":"Solution space properties","text":"","category":"section"},{"location":"generated/IndependentSet/#Maximum-independent-set-size-\\alpha(G)","page":"Independent set problem","title":"Maximum independent set size alpha(G)","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can compute solution space properties with the solve function, which takes two positional arguments, the problem instance and the wanted property.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"maximum_independent_set_size = solve(problem, SizeMax())[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"Here SizeMax means finding the solution with maximum set size. The return value has Tropical type. We can get its content by typing","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"maximum_independent_set_size.n","category":"page"},{"location":"generated/IndependentSet/#Counting-properties","page":"Independent set problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/IndependentSet/#Count-all-solutions-and-best-several-solutions","page":"Independent set problem","title":"Count all solutions and best several solutions","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can count all independent sets with the CountingAll property.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"count_all_independent_sets = solve(problem, CountingAll())[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The return value has type Float64. The counting of all independent sets is equivalent to the infinite temperature partition function","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"solve(problem, PartitionFunction(0.0))[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can count the maximum independent sets with CountingMax.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"count_maximum_independent_sets = solve(problem, CountingMax())[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The return value has type CountingTropical, which contains two fields. They are n being the maximum independent set size and c being the number of the maximum independent sets.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"count_maximum_independent_sets.c","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"Similarly, we can count independent sets of sizes alpha(G) and alpha(G)-1 by feeding an integer positional argument to CountingMax.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"count_max2_independent_sets = solve(problem, CountingMax(2))[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The return value has type TruncatedPoly, which contains two fields. They are maxorder being the maximum independent set size and coeffs being the number of independent sets having sizes alpha(G)-1 and alpha(G).","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"count_max2_independent_sets.coeffs","category":"page"},{"location":"generated/IndependentSet/#Find-the-graph-polynomial","page":"Independent set problem","title":"Find the graph polynomial","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can count the number of independent sets at any size, which is equivalent to finding the coefficients of an independence polynomial that defined as","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"I(G x) = sum_k=0^alpha(G) a_k x^k","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"where alpha(G) is the maximum independent set size, a_k is the number of independent sets of size k. The total number of independent sets is thus equal to I(G 1). There are 3 methods to compute a graph polynomial, :finitefield, :fft and :polynomial. These methods are introduced in the docstring of GraphPolynomial.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"independence_polynomial = solve(problem, GraphPolynomial(; method=:finitefield))[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The return type is Polynomial.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"independence_polynomial.coeffs","category":"page"},{"location":"generated/IndependentSet/#Configuration-properties","page":"Independent set problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/IndependentSet/#Find-one-best-solution","page":"Independent set problem","title":"Find one best solution","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can use the bounded or unbounded SingleConfigMax to find one of the solutions with largest size. The unbounded (default) version uses a joint type of CountingTropical and ConfigSampler in computation, where CountingTropical finds the maximum size and ConfigSampler samples one of the best solutions. The bounded version uses the binary gradient back-propagation (see our paper) to compute the gradients. It requires caching intermediate states, but is often faster (on CPU) because it can use TropicalGEMM (see Performance Tips).","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"max_config = solve(problem, SingleConfigMax(; bounded=false))[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The return value has type CountingTropical with its counting field having ConfigSampler type. The data field of ConfigSampler is a bit string that corresponds to the solution","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"single_solution = max_config.c.data","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"This bit string should be read from left to right, with the i-th bit being 1 (0) to indicate the i-th vertex is present (absent) in the set. We can visualize this MIS with the following function.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"show_graph(graph; locs=locations, format=:svg, vertex_colors=\n [iszero(single_solution[i]) ? \"white\" : \"red\" for i=1:nv(graph)])","category":"page"},{"location":"generated/IndependentSet/#Enumerate-all-solutions-and-best-several-solutions","page":"Independent set problem","title":"Enumerate all solutions and best several solutions","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can use bounded or unbounded ConfigsMax to find all solutions with largest-K set sizes. In most cases, the bounded (default) version is preferred because it can reduce the memory usage significantly.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"all_max_configs = solve(problem, ConfigsMax(; bounded=true))[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The return value has type CountingTropical, while its counting field having type ConfigEnumerator. The data field of a ConfigEnumerator instance contains a vector of bit strings.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"all_max_configs.c.data","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"These solutions can be visualized with the show_gallery function.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"show_gallery(graph, (1, length(all_max_configs.c)); locs=locations, vertex_configs=all_max_configs.c, format=:svg)","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can use ConfigsAll to enumerate all sets satisfying the independence constraint.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"all_independent_sets = solve(problem, ConfigsAll())[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The return value has type ConfigEnumerator.","category":"page"},{"location":"generated/IndependentSet/#Sample-solutions","page":"Independent set problem","title":"Sample solutions","text":"","category":"section"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"It is often difficult to store all configurations in a vector. A more clever way to store the data is using the sum product tree format.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"all_independent_sets_tree = solve(problem, ConfigsAll(; tree_storage=true))[]","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"The return value has the SumProductTree type. Its length corresponds to the number of configurations.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"length(all_independent_sets_tree)","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"We can use Base.collect function to create a ConfigEnumerator or use generate_samples to generate samples from it.","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"collect(all_independent_sets_tree)\n\ngenerate_samples(all_independent_sets_tree, 10)","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"","category":"page"},{"location":"generated/IndependentSet/","page":"Independent set problem","title":"Independent set problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"EditURL = \"../../../examples/PaintShop.jl\"","category":"page"},{"location":"generated/PaintShop/#Binary-paint-shop-problem","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"","category":"section"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/PaintShop/#Problem-Definition","page":"Binary paint shop problem","title":"Problem Definition","text":"","category":"section"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"The binary paint shop problem is defined as follows: we are given a 2m length sequence containing m cars, where each car appears twice. Each car need to be colored red in one occurrence, and blue in the other. We need to choose which occurrence for each car to color with which color — the goal is to minimize the number of times we need to change the current color.","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"In the following, we use a character to represent a car, and defined a binary paint shop problem as a string that each character appear exactly twice.","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"using GenericTensorNetworks, Graphs\n\nsequence = collect(\"iadgbeadfcchghebif\")","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"We can visualize this paint shop problem as a graph","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"rot(a, b, θ) = cos(θ)*a + sin(θ)*b, cos(θ)*b - sin(θ)*a\n\nlocations = [rot(0.0, 2.0, -0.25π - 1.5*π*(i-0.5)/length(sequence)) for i=1:length(sequence)]\n\ngraph = path_graph(length(sequence))\nfor i=1:length(sequence)\n j = findlast(==(sequence[i]), sequence)\n i != j && add_edge!(graph, i, j)\nend\n\nshow_graph(graph; locs=locations, texts=string.(sequence), format=:svg, edge_colors=\n [sequence[e.src] == sequence[e.dst] ? \"blue\" : \"black\" for e in edges(graph)])","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"Vertices connected by blue edges must have different colors, and the goal becomes a min-cut problem defined on black edges.","category":"page"},{"location":"generated/PaintShop/#Generic-tensor-network-representation","page":"Binary paint shop problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"Let us construct the problem instance as bellow.","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"problem = PaintShop(sequence);\nnothing #hide","category":"page"},{"location":"generated/PaintShop/#Theory-(can-skip)","page":"Binary paint shop problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"Type PaintShop can be used for constructing the tensor network with optimized contraction order for solving a binary paint shop problem. To obtain its tensor network representation, we associating car c_i (the i-th character in our example) with a degree of freedom s_c_i in 0 1, where we use 0 to denote the first appearance of a car is colored red and 1 to denote the first appearance of a car is colored blue. For each black edges (i i+1), we define an edge tensor labeled by (s_c_i s_c_i+1) as follows: If both cars on this edge are their first or second appearance","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"B^rm parallel = left(beginmatrix\nx 1 \n1 x \nendmatrixright)","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"otherwise,","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"B^rm anti-parallel = left(beginmatrix\n1 x \nx 1 \nendmatrixright)","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"It can be understood as, when both cars are their first appearance, they tend to have the same configuration so that the color is not changed. Otherwise, they tend to have different configuration to keep the color unchanged.","category":"page"},{"location":"generated/PaintShop/#Counting-properties","page":"Binary paint shop problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/PaintShop/#graph-polynomial","page":"Binary paint shop problem","title":"graph polynomial","text":"","category":"section"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"The graph polynomial defined for the maximal independent set problem is","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"I_rm max(G x) = sum_k=0^alpha(G) b_k x^k","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"where b_k is the number of maximal independent sets of size k in graph G=(V E).","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"max_config = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"Since it only counts the maximal independent sets, the first several coefficients are 0.","category":"page"},{"location":"generated/PaintShop/#Counting-properties-2","page":"Binary paint shop problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/PaintShop/#graph-polynomial-2","page":"Binary paint shop problem","title":"graph polynomial","text":"","category":"section"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"The graph polynomial of the binary paint shop problem in our convention is defined as","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"P(G x) = sum_k=0^delta(G) p_k x^k","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"where p_k is the number of possible coloring with number of color changes 2m-1-k.","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"paint_polynomial = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/PaintShop/#Configuration-properties","page":"Binary paint shop problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/PaintShop/#finding-best-solutions","page":"Binary paint shop problem","title":"finding best solutions","text":"","category":"section"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"best_configs = solve(problem, ConfigsMin())[]","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"One can see to identical bitstrings corresponding two different vertex configurations, they are related to bit-flip symmetry.","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"painting1 = paint_shop_coloring_from_config(problem, best_configs.c.data[1])\n\nshow_graph(graph; locs=locations, format=:svg, texts=string.(sequence),\n edge_colors=[sequence[e.src] == sequence[e.dst] ? \"blue\" : \"black\" for e in edges(graph)],\n vertex_colors=[isone(c) ? \"red\" : \"black\" for c in painting1], vertex_text_color=\"white\")","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"Since we have different choices of initial color, the number of best solution is 2.","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"The following function will check the solution and return you the number of color switches","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"num_paint_shop_color_switch(sequence, painting1)","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"","category":"page"},{"location":"generated/PaintShop/","page":"Binary paint shop problem","title":"Binary paint shop problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"sumproduct/#Sum-product-representation-for-configurations","page":"Sum product tree representation","title":"Sum product representation for configurations","text":"","category":"section"},{"location":"sumproduct/","page":"Sum product tree representation","title":"Sum product tree representation","text":"SumProductTree can use polynomial memory to store exponential number of configurations. It is a sum-product expression tree to store ConfigEnumerator in a lazy style, where configurations can be extracted by depth first searching the tree with the Base.collect method. Although it is space efficient, it is in general not easy to extract information from it due to the exponential large configuration space. Directed sampling is one of its most important operations, with which one can get some statistic properties from it with an intermediate effort. For example, if we want to check some property of an intermediate scale graph, one can type","category":"page"},{"location":"sumproduct/","page":"Sum product tree representation","title":"Sum product tree representation","text":"julia> graph = random_regular_graph(70, 3)\n\njulia> problem = IndependentSet(graph; optimizer=TreeSA());\n\njulia> tree = solve(problem, ConfigsAll(; tree_storage=true))[];\n16633909006371","category":"page"},{"location":"sumproduct/","page":"Sum product tree representation","title":"Sum product tree representation","text":"If one wants to store these configurations, he will need a hard disk of size 256 TB! However, this sum-product binary tree structure supports efficient and unbiased direct sampling.","category":"page"},{"location":"sumproduct/","page":"Sum product tree representation","title":"Sum product tree representation","text":"samples = generate_samples(tree, 1000);","category":"page"},{"location":"sumproduct/","page":"Sum product tree representation","title":"Sum product tree representation","text":"With these samples, one can already compute useful properties like Hamming distance (see hamming_distribution) distribution.","category":"page"},{"location":"sumproduct/","page":"Sum product tree representation","title":"Sum product tree representation","text":"julia> using UnicodePlots\n\njulia> lineplot(hamming_distribution(samples, samples))\n ┌────────────────────────────────────────┐ \n 100000 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠹⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡎⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡇⠀⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠸⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠃⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡞⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠁⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⡼⠀⠀⠀⠀⠀⠀⠈⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n │⠀⠀⠀⠀⠀⠀⠀⠀⢠⠇⠀⠀⠀⠀⠀⠀⠀⢳⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ \n 0 │⢀⣀⣀⣀⣀⣀⣀⣀⠎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠓⢄⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⠀⠀⠀⠀│ \n └────────────────────────────────────────┘ \n ⠀0⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀80⠀ ","category":"page"},{"location":"sumproduct/","page":"Sum product tree representation","title":"Sum product tree representation","text":"Here, the x-axis is the Hamming distance and the y-axis is the counting of pair-wise Hamming distances.","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"EditURL = \"../../../examples/Coloring.jl\"","category":"page"},{"location":"generated/Coloring/#Coloring-problem","page":"Coloring problem","title":"Coloring problem","text":"","category":"section"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/Coloring/#Problem-definition","page":"Coloring problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"A vertex coloring is an assignment of labels or colors to each vertex of a graph such that no edge connects two identically colored vertices. In the following, we are going to defined a 3-coloring problem for the Petersen graph.","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"using GenericTensorNetworks, Graphs\n\ngraph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"We can visualize this graph using the following function","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a\n\nlocations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]\n\nshow_graph(graph; locs=locations, format=:svg)","category":"page"},{"location":"generated/Coloring/#Generic-tensor-network-representation","page":"Coloring problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"We construct the tensor network for the 3-coloring problem as","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"problem = Coloring{3}(graph);\nnothing #hide","category":"page"},{"location":"generated/Coloring/#Theory-(can-skip)","page":"Coloring problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"Type Coloring can be used for constructing the tensor network with optimized contraction order for a coloring problem. Let us use 3-coloring problem defined on vertices as an example. For a vertex v, we define the degrees of freedom c_vin123 and a vertex tensor labelled by it as","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"W(v) = left(beginmatrix\n 1\n 1\n 1\nendmatrixright)","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"For an edge (u v), we define an edge tensor as a matrix labelled by (c_u c_v) to specify the constraint","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"B = left(beginmatrix\n 1 x x\n x 1 x\n x x 1\nendmatrixright)","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"The number of possible coloring can be obtained by contracting this tensor network by setting vertex tensor elements r_v g_v and b_v to 1.","category":"page"},{"location":"generated/Coloring/#Solving-properties","page":"Coloring problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/Coloring/#counting-all-possible-coloring","page":"Coloring problem","title":"counting all possible coloring","text":"","category":"section"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"num_of_coloring = solve(problem, CountingMax())[]","category":"page"},{"location":"generated/Coloring/#finding-one-best-coloring","page":"Coloring problem","title":"finding one best coloring","text":"","category":"section"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"single_solution = solve(problem, SingleConfigMax())[]\n\nis_vertex_coloring(graph, single_solution.c.data)\n\nvertex_color_map = Dict(0=>\"red\", 1=>\"green\", 2=>\"blue\")\n\nshow_graph(graph; locs=locations, format=:svg, vertex_colors=[vertex_color_map[Int(c)]\n for c in single_solution.c.data])","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"Let us try to solve the same issue on its line graph, a graph that generated by mapping an edge to a vertex and two edges sharing a common vertex will be connected.","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"linegraph = line_graph(graph)\n\nshow_graph(linegraph; locs=[0.5 .* (locations[e.src] .+ locations[e.dst])\n for e in edges(graph)], format=:svg)","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"Let us construct the tensor network and see if there are solutions.","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"lineproblem = Coloring{3}(linegraph);\n\nnum_of_coloring = solve(lineproblem, CountingMax())[]","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"You will see the maximum size 28 is smaller than the number of edges in the linegraph, meaning no solution for the 3-coloring on edges of a Petersen graph.","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"","category":"page"},{"location":"generated/Coloring/","page":"Coloring problem","title":"Coloring problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"EditURL = \"../../../examples/SetPacking.jl\"","category":"page"},{"location":"generated/SetPacking/#Set-packing-problem","page":"Set packing problem","title":"Set packing problem","text":"","category":"section"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/SetPacking/#Problem-definition","page":"Set packing problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"The set packing problem is generalization of the IndependentSet problem from the simple graph to the multigraph. Suppose one has a finite set S and a list of subsets of S. Then, the set packing problem asks if some k subsets in the list are pairwise disjoint. In the following, we will find the solution space properties for the set in the Set covering problem.","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"using GenericTensorNetworks, Graphs","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"The packing stadium areas of cameras are represented as the following sets.","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"sets = [[1,3,4,6,7], [4,7,8,12], [2,5,9,11,13],\n [1,2,14,15], [3,6,10,12,14], [8,14,15],\n [1,2,6,11], [1,2,4,6,8,12]]","category":"page"},{"location":"generated/SetPacking/#Generic-tensor-network-representation","page":"Set packing problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"We create a [SetPacking] instance that contains a generic tensor network as its code field.","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"problem = SetPacking(sets);\nnothing #hide","category":"page"},{"location":"generated/SetPacking/#Theory-(can-skip)","page":"Set packing problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"Let S be the target set packing problem that we want to solve. For each set s in S, we associate it with a weight w_s to it. The tensor network representation map a set sin S to a boolean degree of freedom v_sin0 1. For each set s, we defined a parameterized rank-one tensor indexed by v_s as","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"W(x_s^w_s) = left(beginmatrix\n 1 \n x_s^w_s\n endmatrixright)","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"where x_s is a variable associated with s. For each unique element a, we defined the constraint over all sets containing it N(a) = s s in S land ain s:","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"B_s_1s_2ldotss_N(a) = begincases\n 0 s_1+s_2+ldots+s_N(a) 1\n 1 textotherwise\nendcases","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"This tensor means if in a configuration, two sets contain the element a, then this configuration is forbidden, One can check the contraction time space complexity of a SetPacking instance by typing:","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"contraction_complexity(problem)","category":"page"},{"location":"generated/SetPacking/#Solving-properties","page":"Set packing problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/SetPacking/#Counting-properties","page":"Set packing problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/SetPacking/#The-\"graph\"-polynomial","page":"Set packing problem","title":"The \"graph\" polynomial","text":"","category":"section"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"The graph polynomial for the set packing problem is defined as","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"P(S x) = sum_k=0^alpha(S) c_k x^k","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"where c_k is the number of configurations having k sets, and alpha(S) is the maximum size of the packing.","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"packing_polynomial = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"The maximum number of sets that packing the set of elements can be computed with the SizeMax property:","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"max_packing_size = solve(problem, SizeMax())[]","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"Similarly, we have its counting CountingMax:","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"counting_maximum_set_packing = solve(problem, CountingMax())[]","category":"page"},{"location":"generated/SetPacking/#Configuration-properties","page":"Set packing problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/SetPacking/#Finding-maximum-set-packing","page":"Set packing problem","title":"Finding maximum set packing","text":"","category":"section"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"One can enumerate all maximum set packing with the ConfigsMax property in the program.","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"max_configs = solve(problem, ConfigsMax())[].c","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"Hence the only optimal solution is z_1 z_3 z_6 that has size 3. The correctness of this result can be checked with the is_set_packing function.","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"all(c->is_set_packing(sets, c), max_configs)","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"Similarly, if one is only interested in computing one of the maximum set packing, one can use the graph property SingleConfigMax.","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"","category":"page"},{"location":"generated/SetPacking/","page":"Set packing problem","title":"Set packing problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"EditURL = \"../../../examples/open.jl\"","category":"page"},{"location":"generated/open/#Open-and-fixed-degrees-of-freedom","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"","category":"section"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"Open degrees of freedom is useful when one want to get the marginal about certain degrees of freedom. When one specifies the openvertices keyword argument in solve function as a tuple of vertices, the output will be a tensor that can be indexed by these degrees of freedom. Let us use the maximum independent set problem on Petersen graph as an example.","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"using GenericTensorNetworks, Graphs\n\ngraph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"The following code computes the MIS tropical tensor (reference to be added) with open vertices 1, 2 and 3.","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"problem = IndependentSet(graph; openvertices=[1,2,3]);\n\nmarginal = solve(problem, SizeMax())","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"The return value is a rank-3 tensor, with its elements being the MIS sizes under different configuration of open vertices. For the maximum independent set problem, this tensor is also called the MIS tropical tensor, which can be useful in the MIS tropical tensor analysis (reference to be added).","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"One can also specify the fixed degrees of freedom by providing the fixedvertices keyword argument as a Dict, which can be used to get conditioned probability. For example, we can use the following code to do the same calculation as using openvertices.","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"problem = IndependentSet(graph; fixedvertices=Dict(1=>0, 2=>0, 3=>0));\n\noutput = zeros(TropicalF64,2,2,2);\n\nmarginal_alternative = map(CartesianIndices((2,2,2))) do ci\n problem.fixedvertices[1] = ci.I[1]-1\n problem.fixedvertices[2] = ci.I[2]-1\n problem.fixedvertices[3] = ci.I[3]-1\n output[ci] = solve(problem, SizeMax())[]\nend","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"One can easily check this one also gets the correct marginal on vertices 1, 2 and 3. As a reminder, their computational hardness can be different, because the contraction order optimization program can optimize over open degrees of freedom.","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"","category":"page"},{"location":"generated/open/","page":"Open and fixed degrees of freedom","title":"Open and fixed degrees of freedom","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"EditURL = \"../../../examples/HyperSpinGlass.jl\"","category":"page"},{"location":"generated/HyperSpinGlass/#Hyper-Spin-glass-problem","page":"Hyper Spin glass problem","title":"Hyper-Spin-glass problem","text":"","category":"section"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/HyperSpinGlass/#Problem-definition","page":"Hyper Spin glass problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"The hyper-spin-glass problem is a natural generalization of the spin-glass problem from simple graph to hypergraph. A hyper-spin-glass problem of hypergraph H = (V E) can be characterized by the following energy function","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"E = sum_c in E w_c prod_vin c S_v","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"where S_v in -1 1, w_c is coupling strength associated with hyperedge c. In the program, we use boolean variable s_v = frac1-S_v2 to represent a spin configuration.","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"using GenericTensorNetworks","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"In the following, we are going to defined an spin glass problem for the following hypergraph.","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"num_vertices = 15\n\nhyperedges = [[1,3,4,6,7], [4,7,8,12], [2,5,9,11,13],\n [1,2,14,15], [3,6,10,12,14], [8,14,15],\n [1,2,6,11], [1,2,4,6,8,12]]\n\nweights = [-1, 1, -1, 1, -1, 1, -1, 1];\nnothing #hide","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"The energy function is","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"beginalign*\nE = -S_1S_3S_4S_6S_7 + S_4S_7S_8S_12 - S_2S_5S_9S_11S_13 +\n S_1S_2S_14S_15 - S_3S_6S_10S_12S_14 + S_8S_14S_15 +\n S_1S_2S_6S_11 - S_1s_2S_4S_6S_8S_12\nendalign*","category":"page"},{"location":"generated/HyperSpinGlass/#Generic-tensor-network-representation","page":"Hyper Spin glass problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"We define an anti-ferromagnetic spin glass problem as","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"problem = HyperSpinGlass(num_vertices, hyperedges; weights);\nnothing #hide","category":"page"},{"location":"generated/HyperSpinGlass/#Theory-(can-skip)","page":"Hyper Spin glass problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"Let H = (V E) be a hypergraph. The tensor network for the partition function of the energy model for H can be defined as the following triple of (alphabet of labels, input tensors, output labels).","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"begincases\nLambda = s_v mid v in V\nmathcalT = B^(c)_s_N(c 1)N(c 2)ldotsN(c d(c)) mid c in E cup W^(v)_s_v mid v in V\nsigma_o = varepsilon\nendcases","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"where s_v in 0 1 is the boolean degreen associated to vertex v, N(c k) is the kth vertex of hyperedge c, and d(c) is the degree of c. The edge tensor B^(c) is defined as","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"B^(c) = begincases\nx^w_c (sum_vin c s_v) is even \nx^-w_c otherwise\nendcases","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"and the vertex tensor W^(v) (used to carry labels) is defined as","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"W^(v) = left(beginmatrix1_v 1_vendmatrixright)","category":"page"},{"location":"generated/HyperSpinGlass/#Solving-properties","page":"Hyper Spin glass problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/HyperSpinGlass/#Minimum-and-maximum-energies","page":"Hyper Spin glass problem","title":"Minimum and maximum energies","text":"","category":"section"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"Its ground state energy is -8.","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"Emin = solve(problem, SizeMin())[]","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"While the state correspond to the highest energy has the ferromagnetic order.","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"Emax = solve(problem, SizeMax())[]","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"In this example, the spin configurations can be chosen to make all hyperedges having even or odd spin parity.","category":"page"},{"location":"generated/HyperSpinGlass/#Counting-properties","page":"Hyper Spin glass problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/HyperSpinGlass/#partition-function-and-graph-polynomial","page":"Hyper Spin glass problem","title":"partition function and graph polynomial","text":"","category":"section"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"The graph polynomial defined for the hyper-spin-glass problem is a Laurent polynomial","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"Z(G w x) = sum_k=E_rm min^E_rm max c_k x^k","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"where E_rm min and E_rm max are minimum and maximum energies, c_k is the number of spin configurations with energy k. Let the inverse temperature beta = 2, the partition function is","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"β = 2.0\nZ = solve(problem, PartitionFunction(β))[]","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"The infinite temperature partition function is the counting of all feasible configurations","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"solve(problem, PartitionFunction(0.0))[]","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"Let x = e^beta, it corresponds to the partition function of a spin glass at temperature beta^-1.","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"poly = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/HyperSpinGlass/#Configuration-properties","page":"Hyper Spin glass problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/HyperSpinGlass/#finding-a-ground-state","page":"Hyper Spin glass problem","title":"finding a ground state","text":"","category":"section"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"ground_state = solve(problem, SingleConfigMin())[].c.data\n\nEmin_verify = hyperspinglass_energy(hyperedges, ground_state; weights)","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"You should see a consistent result as above Emin.","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"","category":"page"},{"location":"generated/HyperSpinGlass/","page":"Hyper Spin glass problem","title":"Hyper Spin glass problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"EditURL = \"../../../examples/Matching.jl\"","category":"page"},{"location":"generated/Matching/#Vertex-matching-problem","page":"Vertex matching problem","title":"Vertex matching problem","text":"","category":"section"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/Matching/#Problem-definition","page":"Vertex matching problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"A k-matching in a graph G is a set of k edges, no two of which have a vertex in common.","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"using GenericTensorNetworks, Graphs","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"In the following, we are going to defined a matching problem for the Petersen graph.","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"graph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"We can visualize this graph using the following function","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a\n\nlocations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]\n\nshow_graph(graph; locs=locations, format=:svg)","category":"page"},{"location":"generated/Matching/#Generic-tensor-network-representation","page":"Vertex matching problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"We construct the tensor network for the matching problem by typing","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"problem = Matching(graph);\nnothing #hide","category":"page"},{"location":"generated/Matching/#Theory-(can-skip)","page":"Vertex matching problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"Type Matching can be used for constructing the tensor network with optimized contraction order for a matching problem. We map an edge (u v) in E to a label langle u vrangle in 0 1 in a tensor network, where 1 means two vertices of an edge are matched, 0 means otherwise. Then we define a tensor of rank d(v) = N(v) on vertex v such that,","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"W_langle v n_1rangle langle v n_2 rangle ldots langle v n_d(v)rangle = begincases\n 1 sum_i=1^d(v) langle v n_i rangle leq 1\n 0 textotherwise\nendcases","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"and a tensor of rank 1 on the bond","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"B_langle v wrangle = begincases\n1 langle v w rangle = 0 \nx langle v w rangle = 1\nendcases","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"where label langle v w rangle is equivalent to langle wvrangle.","category":"page"},{"location":"generated/Matching/#Solving-properties","page":"Vertex matching problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/Matching/#Maximum-matching","page":"Vertex matching problem","title":"Maximum matching","text":"","category":"section"},{"location":"generated/Matching/#Configuration-properties","page":"Vertex matching problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"max_matching = solve(problem, SizeMax())[]","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"The largest number of matching is 5, which means we have a perfect matching (vertices are all paired).","category":"page"},{"location":"generated/Matching/#matching-polynomial","page":"Vertex matching problem","title":"matching polynomial","text":"","category":"section"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"The graph polynomial defined for the matching problem is known as the matching polynomial. Here, we adopt the first definition in the wiki page.","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"M(G x) = sumlimits_k=1^V2 c_k x^k","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"where k is the number of matches, and coefficients c_k are the corresponding counting.","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"matching_poly = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/Matching/#Configuration-properties-2","page":"Vertex matching problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/Matching/#one-of-the-perfect-matches","page":"Vertex matching problem","title":"one of the perfect matches","text":"","category":"section"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"match_config = solve(problem, SingleConfigMax())[]","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"Let us show the result by coloring the matched edges to red","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"show_graph(graph; locs=locations, format=:svg, edge_colors=\n [isone(match_config.c.data[i]) ? \"red\" : \"black\" for i=1:ne(graph)])","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"where we use edges with red color to related pairs of matched vertices.","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"","category":"page"},{"location":"generated/Matching/","page":"Vertex matching problem","title":"Vertex matching problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"EditURL = \"../../../examples/Satisfiability.jl\"","category":"page"},{"location":"generated/Satisfiability/#Satisfiability-problem","page":"Satisfiability problem","title":"Satisfiability problem","text":"","category":"section"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/Satisfiability/#Problem-definition","page":"Satisfiability problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"In logic and computer science, the boolean satisfiability problem is the problem of determining if there exists an interpretation that satisfies a given boolean formula. One can specify a satisfiable problem in the conjunctive normal form. In boolean logic, a formula is in conjunctive normal form (CNF) if it is a conjunction (∧) of one or more clauses, where a clause is a disjunction (∨) of literals.","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"using GenericTensorNetworks\n\n@bools a b c d e f g\n\ncnf = ∧(∨(a, b, ¬d, ¬e), ∨(¬a, d, e, ¬f), ∨(f, g), ∨(¬b, c))","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"To goal is to find an assignment to satisfy the above CNF. For a satisfiability problem at this size, we can find the following assignment to satisfy this assignment manually.","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"assignment = Dict([:a=>true, :b=>false, :c=>false, :d=>true, :e=>false, :f=>false, :g=>true])\n\nsatisfiable(cnf, assignment)","category":"page"},{"location":"generated/Satisfiability/#Generic-tensor-network-representation","page":"Satisfiability problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"If we contract this tensor network, we will get a multiplicative factor x whenever there is a clause satisfied.","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"problem = Satisfiability(cnf);\nnothing #hide","category":"page"},{"location":"generated/Satisfiability/#Theory-(can-skip)","page":"Satisfiability problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"We can construct a Satisfiability problem to solve the above problem. To generate a tensor network, we map a boolean variable x and its negation neg x to a degree of freedom (label) s_x in 0 1, where 0 stands for variable x having value false while 1 stands for having value true. Then we map a clause to a tensor. For example, a clause x y z can be mapped to a tensor labeled by (s_x s_y s_z).","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"C = left(beginmatrix\nleft(beginmatrix\nx x \nx x\nendmatrixright) \nleft(beginmatrix\nx x \n1 x\nendmatrixright)\nendmatrixright)","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"There is only one entry (s_x s_y s_z) = (1 0 1) that makes this clause unsatisfied.","category":"page"},{"location":"generated/Satisfiability/#Solving-properties","page":"Satisfiability problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/Satisfiability/#Satisfiability-and-its-counting","page":"Satisfiability problem","title":"Satisfiability and its counting","text":"","category":"section"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"The size of a satisfiability problem is defined by the number of satisfiable clauses.","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"num_satisfiable = solve(problem, SizeMax())[]","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"The GraphPolynomial of a satisfiability problem counts the number of solutions that k clauses satisfied.","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"num_satisfiable_count = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/Satisfiability/#Find-one-of-the-solutions","page":"Satisfiability problem","title":"Find one of the solutions","text":"","category":"section"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"single_config = solve(problem, SingleConfigMax())[].c.data","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"One will see a bit vector printed. One can create an assignment and check the validity with the following statement:","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"satisfiable(cnf, Dict(zip(labels(problem), single_config)))","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"","category":"page"},{"location":"generated/Satisfiability/","page":"Satisfiability problem","title":"Satisfiability problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"EditURL = \"../../../examples/SpinGlass.jl\"","category":"page"},{"location":"generated/SpinGlass/#Spin-glass-problem","page":"Spin glass problem","title":"Spin-glass problem","text":"","category":"section"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/SpinGlass/#Problem-definition","page":"Spin glass problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"Let G=(V E) be a graph, the spin-glass problem in physics is characterized by the following energy function","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"H = -sum_ij in E J_ij s_i s_j + sum_i in V h_i s_i","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"where h_i is an onsite energy term associated with spin s_i in -1 1, and J_ij is the coupling strength between spins s_i and s_j. In the program, we use boolean variable n_i = frac1-s_i2 to represent a spin configuration.","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"using GenericTensorNetworks, Graphs","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"In the following, we are going to defined an spin glass problem for the Petersen graph.","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"graph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"We can visualize this graph using the following function","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a\n\nlocations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]\n\nshow_graph(graph; locs=locations, format=:svg)","category":"page"},{"location":"generated/SpinGlass/#Generic-tensor-network-representation","page":"Spin glass problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"We define an anti-ferromagnetic spin glass problem as","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"problem = SpinGlass(graph; J=fill(-1, ne(graph)));\nnothing #hide","category":"page"},{"location":"generated/SpinGlass/#Theory-(can-skip)","page":"Spin glass problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"The spin glass problem is reduced to the Cutting problem for solving. Let G=(VE) be a graph, the cutting problem can also be described by the following energy model","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"H^c = sum_ij in E C_ij ((1 - n_i) n_j + (1 - n_j) n_i) + sum_i in V w_i n_i","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"where n_i is the same as the partition index in the cutting problem, C_ij = 2J_ij are edge weights and w_i = -2h_i are vertex weights. The total energy is shifted by -sum_ijin EJ_ij + sum_i in V h_i.","category":"page"},{"location":"generated/SpinGlass/#Solving-properties","page":"Spin glass problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/SpinGlass/#Minimum-and-maximum-energies","page":"Spin glass problem","title":"Minimum and maximum energies","text":"","category":"section"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"Its ground state energy is -9.","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"Emin = solve(problem, SizeMin())[]","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"While the state correspond to the highest energy has the ferromagnetic order.","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"Emax = solve(problem, SizeMax())[]","category":"page"},{"location":"generated/SpinGlass/#Counting-properties","page":"Spin glass problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/SpinGlass/#graph-polynomial","page":"Spin glass problem","title":"graph polynomial","text":"","category":"section"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"The graph polynomial defined for the spin glass problem is a Laurent polynomial","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"Z(G J h x) = sum_k=E_rm min^E_rm max c_k x^k","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"where E_rm min and E_rm max are minimum and maximum energies, c_k is the number of spin configurations with energy k. Let x = e^beta, it corresponds to the partition function of a spin glass at temperature beta^-1.","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"partition_function = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/SpinGlass/#Configuration-properties","page":"Spin glass problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/SpinGlass/#finding-a-ground-state","page":"Spin glass problem","title":"finding a ground state","text":"","category":"section"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"ground_state = solve(problem, SingleConfigMin())[].c.data\n\nEmin_verify = spinglass_energy(graph, ground_state)","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"You should see a consistent result as above Emin.","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"show_graph(graph; locs=locations, vertex_colors=[\n iszero(ground_state[i]) ? \"white\" : \"red\" for i=1:nv(graph)], format=:svg)","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"where a red vertex and a white vertex correspond to a spin having value 1 and 0 respectively.","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"","category":"page"},{"location":"generated/SpinGlass/","page":"Spin glass problem","title":"Spin glass problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"performancetips/#Performance-Tips","page":"Performance Tips","title":"Performance Tips","text":"","category":"section"},{"location":"performancetips/#Optimize-contraction-orders","page":"Performance Tips","title":"Optimize contraction orders","text":"","category":"section"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"Let us use the independent set problem on 3-regular graphs as an example.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"julia> using GenericTensorNetworks, Graphs, Random\n\njulia> graph = random_regular_graph(120, 3)\n{120, 180} undirected simple Int64 graph\n\njulia> problem = IndependentSet(graph; optimizer=TreeSA(\n sc_target=20, sc_weight=1.0, rw_weight=3.0, ntrials=10, βs=0.01:0.1:15.0, niters=20), simplifier=MergeGreedy());","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"The IndependentSet constructor maps an independent set problem to a tensor network with optimized contraction order. The key word argument optimizer specifies the contraction order optimizer of the tensor network. Here, we choose the local search based TreeSA algorithm, which often finds the smallest time/space complexity and supports slicing. One can type ?TreeSA in a Julia REPL for more information about how to configure the hyper-parameters of the TreeSA method, while the detailed algorithm explanation is in arXiv: 2108.05665. Alternative tensor network contraction order optimizers include","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"GreedyMethod (default, fastest in searching speed but worst in contraction complexity)\nKaHyParBipartite\nSABipartite","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"The keyword argument simplifier specifies the preprocessor to improve the searching speed of the contraction order finding. For example, the MergeGreedy() here \"contracts\" tensors greedily whenever the contraction result has a smaller space complexity. It can remove all vertex tensors (vectors) before entering the contraction order optimization algorithm.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"The returned object problem contains a field code that specifies the tensor network with optimized contraction order. For an independent set problem, the optimal contraction time/space complexity is sim 2^rm tw(G), where rm tw(G) is the tree-width of G. One can check the time, space and read-write complexity with the contraction_complexity function.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"julia> contraction_complexity(problem)\nTime complexity (number of element-wise multiplications) = 2^20.568850503058382\nSpace complexity (number of elements in the largest intermediate tensor) = 2^16.0\nRead-write complexity (number of element-wise read and write) = 2^18.70474460304404","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"The return values are log2 values of the number of multiplications, the number elements in the largest tensor during contraction and the number of read-write operations to tensor elements. In this example, the number * operations is sim 2^219, the number of read-write operations are sim 2^20, and the largest tensor size is 2^17. One can check the element size by typing","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"julia> sizeof(TropicalF64)\n8\n\njulia> sizeof(TropicalF32)\n4\n\njulia> sizeof(StaticBitVector{200,4})\n32\n\njulia> sizeof(TruncatedPoly{5,Float64,Float64})\n48","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"One can use estimate_memory to get a good estimation of peak memory in bytes. For example, to compute the graph polynomial, the peak memory can be estimated as follows.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"julia> estimate_memory(problem, GraphPolynomial(; method=:finitefield))\n297616\n\njulia> estimate_memory(problem, GraphPolynomial(; method=:polynomial))\n71427840","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"The finite field approach only requires 298 KB memory, while using the Polynomial number type requires 71 MB memory.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"note: Note\nThe actual run time memory can be several times larger than the size of the maximum tensor, so the estimate_memory is more accurate in estimating the peak memory.\nFor mutable element types like ConfigEnumerator, none of memory estimation functions measure the actual memory usage correctly.","category":"page"},{"location":"performancetips/#Slicing-technique","page":"Performance Tips","title":"Slicing technique","text":"","category":"section"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"For large scale applications, it is also possible to slice over certain degrees of freedom to reduce the space complexity, i.e. loop and accumulate over certain degrees of freedom so that one can have a smaller tensor network inside the loop due to the removal of these degrees of freedom. In the TreeSA optimizer, one can set nslices to a value larger than zero to turn on this feature.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"julia> using GenericTensorNetworks, Graphs, Random\n\njulia> graph = random_regular_graph(120, 3)\n{120, 180} undirected simple Int64 graph\n\njulia> problem = IndependentSet(graph; optimizer=TreeSA(βs=0.01:0.1:25.0, ntrials=10, niters=10));\n\njulia> contraction_complexity(problem)\nTime complexity (number of element-wise multiplications) = 2^20.53277253647484\nSpace complexity (number of elements in the largest intermediate tensor) = 2^16.0\nRead-write complexity (number of element-wise read and write) = 2^19.34699193791874\n\njulia> problem = IndependentSet(graph; optimizer=TreeSA(βs=0.01:0.1:25.0, ntrials=10, niters=10, nslices=5));\n\njulia> contraction_complexity(problem)\nTime complexity (number of element-wise multiplications) = 2^21.117277836449578\nSpace complexity (number of elements in the largest intermediate tensor) = 2^11.0\nRead-write complexity (number of element-wise read and write) = 2^19.854965754099602","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"In the second IndependentSet constructor, we slice over 5 degrees of freedom, which can reduce the space complexity by at most 5. In this application, the slicing achieves the largest possible space complexity reduction 5, while the time and read-write complexity are only increased by less than 1, i.e. the peak memory usage is reduced by a factor 32, while the (theoretical) computing time is increased by at a factor 2.","category":"page"},{"location":"performancetips/#GEMM-for-Tropical-numbers","page":"Performance Tips","title":"GEMM for Tropical numbers","text":"","category":"section"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"One can speed up the Tropical number matrix multiplication when computing the solution space property SizeMax() by using the Tropical GEMM routines implemented in package TropicalGEMM.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"julia> using BenchmarkTools\n\njulia> @btime solve(problem, SizeMax())\n 91.630 ms (19203 allocations: 23.72 MiB)\n0-dimensional Array{TropicalF64, 0}:\n53.0ₜ\n\njulia> using TropicalGEMM\n\njulia> @btime solve(problem, SizeMax())\n 8.960 ms (18532 allocations: 17.01 MiB)\n0-dimensional Array{TropicalF64, 0}:\n53.0ₜ","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"The TropicalGEMM package pirates the LinearAlgebra.mul! interface, hence it takes effect upon using. The above example shows more than 10x speed up on a single thread CPU, which can be even faster if the Julia multi-threading if turned on. The benchmark in the TropicalGEMM repo shows this performance is close to the theoretical optimal value.","category":"page"},{"location":"performancetips/#Multiprocessing","page":"Performance Tips","title":"Multiprocessing","text":"","category":"section"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"Submodule GenericTensorNetworks.SimpleMutiprocessing provides one function GenericTensorNetworks.SimpleMultiprocessing.multiprocess_run function for simple multi-processing jobs. It is not directly related to GenericTensorNetworks, but is very convenient to have one. Suppose we want to find the independence polynomial for multiple graphs with 4 processes. We can create a file, e.g. named run.jl with the following content","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"using Distributed, GenericTensorNetworks.SimpleMultiprocessing\nusing Random, GenericTensorNetworks # to avoid multi-precompilation\n@everywhere using Random, GenericTensorNetworks\n\nresults = multiprocess_run(collect(1:10)) do seed\n Random.seed!(seed)\n n = 10\n @info \"Graph size $n x $n, seed= $seed\"\n g = random_diagonal_coupled_graph(n, n, 0.8)\n gp = Independence(g; optimizer=TreeSA(), simplifier=MergeGreedy())\n res = solve(gp, GraphPolynomial())[]\n return res\nend\n\nprintln(results)","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"One can run this script file with the following command","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"$ julia -p4 run.jl\n From worker 3:\t[ Info: running argument 4 on device 3\n From worker 4:\t[ Info: running argument 2 on device 4\n From worker 5:\t[ Info: running argument 3 on device 5\n From worker 2:\t[ Info: running argument 1 on device 2\n From worker 3:\t[ Info: Graph size 10 x 10, seed= 4\n From worker 4:\t[ Info: Graph size 10 x 10, seed= 2\n From worker 5:\t[ Info: Graph size 10 x 10, seed= 3\n From worker 2:\t[ Info: Graph size 10 x 10, seed= 1\n From worker 4:\t[ Info: running argument 5 on device\n ...","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"You will see a vector of polynomials printed out.","category":"page"},{"location":"performancetips/#Make-use-of-GPUs","page":"Performance Tips","title":"Make use of GPUs","text":"","category":"section"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"To upload the computation to GPU, you just add using CUDA before calling the solve function, and set the keyword argument usecuda to true.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"julia> using CUDA\n[ Info: OMEinsum loaded the CUDA module successfully\n\njulia> solve(problem, SizeMax(), usecuda=true)\n0-dimensional CuArray{TropicalF64, 0, CUDA.Mem.DeviceBuffer}:\n53.0ₜ","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"Solution space properties computable on GPU includes","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"SizeMax and SizeMin\nCountingAll\nCountingMax and CountingMin\nGraphPolynomial\nSingleConfigMax and SingleConfigMin","category":"page"},{"location":"performancetips/#Benchmarks","page":"Performance Tips","title":"Benchmarks","text":"","category":"section"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"We run a single thread benchmark on central processing units (CPU) Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz, and its CUDA version on a GPU Tesla V100-SXM2 16G. The results are summarized in the following plot. The benchmark code can be found in our paper repository.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"(Image: benchmark-independent-set) This benchmark results is for computing different solution space properties of independent sets of random three-regular graphs with different tensor element types. The time in these plots only includes tensor network contraction, without taking into account the contraction order finding and just-in-time compilation time. Legends are properties, algebra, and devices that we used in the computation; one can find the corresponding computed solution space property in Table 1 in the paper.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"(a) time and space complexity versus the number of vertices for the benchmarked graphs.\n(b) The computation time for calculating the MIS size and for counting the number of all independent sets (ISs), the number of MISs, the number of independent sets having size alpha(G) and alpha(G)-1, and finding 100 largest set sizes.\n(c) The computation time for calculating the independence polynomials with different approaches.\n(d) The computation time for configuration enumeration, including single MIS configuration, the enumeration of all independent set configurations, all MIS configurations, all independent sets, and all independent set configurations having size alpha(G) and alpha(G)-1.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"The graphs in all benchmarks are random three-regular graphs, which have treewidth that is asymptotically smaller than V6. In this benchmark, we do not include traditional algorithms for finding the MIS sizes such as branching or dynamic programming. To the best of our knowledge, these algorithms are not suitable for computing most of the solution space properties mentioned in this paper. The main goal of this section is to show the relative computation time for calculating different solution space properties.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"Panel (a) shows the time and space complexity of tensor network contraction for different graph sizes. The contraction order is obtained using the TreeSA algorithm that implemented in OMEinsumContractionOrders. If we assume our contraction-order finding program has found the optimal treewidth, which is very likely to be true, the space complexity is the same as the treewidth of the problem graph. Slicing technique has been used for graphs with space complexity greater than 2^27 (above the yellow dashed line) to fit the computation into a 16GB memory. One can see that all the computation times in panels (b), (c), and (d) have a strong correlation with the predicted time and space complexity. While in panel (d), the computation time of configuration enumeration also strongly correlates with other factors such as the configuration space size. Among these benchmarks, computational tasks with data types real numbers, complex numbers, or Tropical numbers (CPU only) can utilize fast basic linear algebra subprograms (BLAS) functions. These tasks usually compute much faster than ones with other element types in the same category. Immutable data types with no reference to other values can be compiled to GPU devices that run much faster than CPUs in all cases when the problem scale is big enough. These data types do not include those defined in Polynomial, ConfigEnumerator, ExtendedTropical and SumProductTree or a data type containing them as a part. In panel (c), one can see the Fourier transformation-based method is the fastest in computing the independence polynomial, but it may suffer from round-off errors. The finite field (GF(p)) approach is the only method that does not have round-off errors and can be run on a GPU. In panel (d), one can see the technique to bound the enumeration space (see paper) improves the performance for more than one order of magnitude in enumerating the MISs. The bounding technique can also reduce the memory usage significantly, without which the largest computable graph size is only sim150 on a device with 32GB main memory.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"We show the benchmark of computing the maximal independent set properties on 3-regular graphs in the following plot, including a comparison to the Bron-Kerbosch algorithm from Julia package Graphs","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"(Image: benchmark-maximal-independent-set)","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"In this plot, benchmarks of computing different solution space properties of the maximal independent sets (ISs) problem on random three regular graphs at different sizes.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"(a) time and space complexity of tensor network contraction.\n(b) The wall clock time for counting and enumeration of maximal ISs.","category":"page"},{"location":"performancetips/","page":"Performance Tips","title":"Performance Tips","text":"Panel (a) shows the space and time complexities of tensor contraction, which are typically larger than those for the independent set problem. In panel (b), one can see counting maximal independent sets are much more efficient than enumerating them, while our generic tensor network approach runs slightly faster than the Bron-Kerbosch approach in enumerating all maximal independent sets.","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"EditURL = \"../../../examples/MaximalIS.jl\"","category":"page"},{"location":"generated/MaximalIS/#Maximal-independent-set-problem","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"","category":"section"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/MaximalIS/#Problem-definition","page":"Maximal independent set problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"In graph theory, a maximal independent set is an independent set that is not a subset of any other independent set. It is different from maximum independent set because it does not require the set to have the max size. In the following, we are going to solve the maximal independent set problem on the Petersen graph.","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"using GenericTensorNetworks, Graphs\n\ngraph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"We can visualize this graph using the following function","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a\n\nlocations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]\n\nshow_graph(graph; locs=locations, format=:svg)","category":"page"},{"location":"generated/MaximalIS/#Generic-tensor-network-representation","page":"Maximal independent set problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"We can use MaximalIS to construct the tensor network for solving the maximal independent set problem as","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"problem = MaximalIS(graph; optimizer=TreeSA());\nnothing #hide","category":"page"},{"location":"generated/MaximalIS/#Theory-(can-skip)","page":"Maximal independent set problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"Let G=(VE) be the target graph that we want to solve. The tensor network representation map a vertex vin V to a boolean degree of freedom s_vin0 1. We defined the restriction on its neighborhood N(v):","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"T(x_v)_s_1s_2ldotss_N(v)s_v = begincases\n s_vx_v^w_v s_1=s_2=ldots=s_N(v)=0\n 1-s_v textotherwise\nendcases","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"The first case corresponds to all the neighborhood vertices of v are not in I_m, then v must be in I_m and contribute a factor x_v^w_v, where w_v is the weight of vertex v. Otherwise, if any of the neighboring vertices of v is in I_m, v must not be in I_m by the independence requirement.","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"Its contraction time space complexity of a MaximalIS instance is no longer determined by the tree-width of the original graph G. It is often harder to contract this tensor network than to contract the one for regular independent set problem.","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"contraction_complexity(problem)","category":"page"},{"location":"generated/MaximalIS/#Solving-properties","page":"Maximal independent set problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/MaximalIS/#Counting-properties","page":"Maximal independent set problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/MaximalIS/#maximal-independence-polynomial","page":"Maximal independent set problem","title":"maximal independence polynomial","text":"","category":"section"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"The graph polynomial defined for the maximal independent set problem is","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"I_rm max(G x) = sum_k=0^alpha(G) b_k x^k","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"where b_k is the number of maximal independent sets of size k in graph G=(V E).","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"maximal_indenpendence_polynomial = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"One can see the first several coefficients are 0, because it only counts the maximal independent sets, The minimum maximal independent set size is also known as the independent domination number. It can be computed with the SizeMin property:","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"independent_domination_number = solve(problem, SizeMin())[]","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"Similarly, we have its counting CountingMin:","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"counting_min_maximal_independent_set = solve(problem, CountingMin())[]","category":"page"},{"location":"generated/MaximalIS/#Configuration-properties","page":"Maximal independent set problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/MaximalIS/#finding-all-maximal-independent-set","page":"Maximal independent set problem","title":"finding all maximal independent set","text":"","category":"section"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"maximal_configs = solve(problem, ConfigsAll())[]\n\nall(c->is_maximal_independent_set(graph, c), maximal_configs)","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"show_gallery(graph, (3, 5); locs=locations, vertex_configs=maximal_configs, format=:svg)","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"This result should be consistent with that given by the Bron Kerbosch algorithm on the complement of Petersen graph.","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"cliques = maximal_cliques(complement(graph))","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"For sparse graphs, the generic tensor network approach is usually much faster and memory efficient than the Bron Kerbosch algorithm.","category":"page"},{"location":"generated/MaximalIS/#finding-minimum-maximal-independent-set","page":"Maximal independent set problem","title":"finding minimum maximal independent set","text":"","category":"section"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"It is the ConfigsMin property in the program.","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"minimum_maximal_configs = solve(problem, ConfigsMin())[].c\n\nshow_gallery(graph, (2, 5); locs=locations, vertex_configs=minimum_maximal_configs, format=:svg)","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"Similarly, if one is only interested in computing one of the minimum sets, one can use the graph property SingleConfigMin.","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"","category":"page"},{"location":"generated/MaximalIS/","page":"Maximal independent set problem","title":"Maximal independent set problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"EditURL = \"../../../examples/MaxCut.jl\"","category":"page"},{"location":"generated/MaxCut/#Cutting-problem","page":"Cutting problem","title":"Cutting problem","text":"","category":"section"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/MaxCut/#Problem-definition","page":"Cutting problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"In graph theory, a cut is a partition of the vertices of a graph into two disjoint subsets. It is closely related to the Spin-glass problem in physics. Finding the maximum cut is NP-Hard, where a maximum cut is a cut whose size is at least the size of any other cut, where the size of a cut is the number of edges (or the sum of weights on edges) crossing the cut.","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"using GenericTensorNetworks, Graphs","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"In the following, we are going to defined an cutting problem for the Petersen graph.","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"graph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"We can visualize this graph using the following function","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a\n\nlocations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]\n\nshow_graph(graph; locs=locations, format=:svg)","category":"page"},{"location":"generated/MaxCut/#Generic-tensor-network-representation","page":"Cutting problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"We define the cutting problem as","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"problem = MaxCut(graph);\nnothing #hide","category":"page"},{"location":"generated/MaxCut/#Theory-(can-skip)","page":"Cutting problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"We associated a vertex vin V with a boolean degree of freedom s_vin0 1. Then the maximum cutting problem can be encoded to tensor networks by mapping an edge (ij)in E to an edge matrix labelled by s_i and s_j","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"B(x_i x_j w_ij) = left(beginmatrix\n 1 x_i^w_ij\n x_j^w_ij 1\nendmatrixright)","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"where w_ij is a real number associated with edge (i j) as the edge weight. If and only if the bipartition cuts on edge (i j), this tensor contributes a factor x_i^w_ij or x_j^w_ij. Similarly, one can assign weights to vertices, which corresponds to the onsite energy terms in the spin glass. The vertex tensor is","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"W(x_i w_i) = left(beginmatrix\n 1\n x_i^w_i\nendmatrixright)","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"where w_i is a real number associated with vertex i as the vertex weight.","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"Its contraction time space complexity is 2^rm tw(G), where rm tw(G) is the tree-width of G.","category":"page"},{"location":"generated/MaxCut/#Solving-properties","page":"Cutting problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/MaxCut/#Maximum-cut-size-\\gamma(G)","page":"Cutting problem","title":"Maximum cut size gamma(G)","text":"","category":"section"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"max_cut_size = solve(problem, SizeMax())[]","category":"page"},{"location":"generated/MaxCut/#Counting-properties","page":"Cutting problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/MaxCut/#graph-polynomial","page":"Cutting problem","title":"graph polynomial","text":"","category":"section"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"The graph polynomial defined for the cutting problem is","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"C(G x) = sum_k=0^gamma(G) c_k x^k","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"where gamma(G) is the maximum cut size, c_k2 is the number of cuts of size k in graph G=(VE). Since the variable x is defined on edges, the coefficients of the polynomial is the number of configurations having different number of anti-parallel edges.","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"max_config = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/MaxCut/#Configuration-properties","page":"Cutting problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/MaxCut/#finding-one-max-cut-solution","page":"Cutting problem","title":"finding one max cut solution","text":"","category":"section"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"max_vertex_config = solve(problem, SingleConfigMax())[].c.data\n\nmax_cut_size_verify = cut_size(graph, max_vertex_config)","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"You should see a consistent result as above max_cut_size.","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"show_graph(graph; locs=locations, vertex_colors=[\n iszero(max_vertex_config[i]) ? \"white\" : \"red\" for i=1:nv(graph)], format=:svg)","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"where red vertices and white vertices are separated by the cut.","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"","category":"page"},{"location":"generated/MaxCut/","page":"Cutting problem","title":"Cutting problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"EditURL = \"../../../examples/saveload.jl\"","category":"page"},{"location":"generated/saveload/#Save-and-load-solutions","page":"Save and load solutions","title":"Save and load solutions","text":"","category":"section"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"Let us use the maximum independent set problem on Petersen graph as an example. The following code enumerates all independent sets.","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"using GenericTensorNetworks, Graphs\n\nproblem = IndependentSet(Graphs.smallgraph(:petersen))\n\nall_independent_sets = solve(problem, ConfigsAll())[]","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"The return value has type ConfigEnumerator. We can use save_configs and load_configs to save and read a ConfigEnumerator instance to the disk.","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"filename = tempname()\n\nsave_configs(filename, all_independent_sets; format=:binary)\n\nloaded_sets = load_configs(filename; format=:binary, bitlength=10)","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"note: Note\nWhen loading the data in the binary format, bit string length information bitlength is required.","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"For the SumProductTree type output, we can use save_sumproduct and load_sumproduct to save and load serialized data.","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"all_independent_sets_tree = solve(problem, ConfigsAll(; tree_storage=true))[]\n\nsave_sumproduct(filename, all_independent_sets_tree)\n\nloaded_sets_tree = load_sumproduct(filename)","category":"page"},{"location":"generated/saveload/#Loading-solutions-to-python","page":"Save and load solutions","title":"Loading solutions to python","text":"","category":"section"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"The following python script loads and unpacks the solutions as a numpy array from a :binary format file.","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"import numpy as np\n\ndef loadfile(filename:str, bitlength:int):\n C = int(np.ceil(bitlength / 64))\n arr = np.fromfile(filename, dtype=\"uint8\")\n # Some axes should be transformed from big endian to little endian\n res = np.unpackbits(arr).reshape(-1, C, 8, 8)[:,::-1,::-1,:]\n res = res.reshape(-1, C*64)[:, :(64*C-bitlength)-1:-1]\n print(\"number of solutions = %d\"%(len(res)))\n return res # in big endian format\n\nres = loadfile(filename, 10)","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"note: Note\nCheck section Maximal independent set problem for solution space properties related the maximal independent sets. That example also contains using cases of finding solution space properties related to minimum sizes:SizeMin for finding minimum several set sizes,\nCountingMin for counting minimum several set sizes,\nSingleConfigMin for finding one solution with minimum several sizes,\nConfigsMin for enumerating solutions with minimum several sizes,","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"","category":"page"},{"location":"generated/saveload/","page":"Save and load solutions","title":"Save and load solutions","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"EditURL = \"../../../examples/SetCovering.jl\"","category":"page"},{"location":"generated/SetCovering/#Set-covering-problem","page":"Set covering problem","title":"Set covering problem","text":"","category":"section"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/SetCovering/#Problem-definition","page":"Set covering problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"The set covering problem is a significant NP-hard problem in combinatorial optimization. Given a collection of elements, the set covering problem aims to find the minimum number of sets that incorporate (cover) all of these elements. In the following, we will find the solution space properties for the camera location and stadium area example in the Cornell University Computational Optimization Open Textbook.","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"using GenericTensorNetworks, Graphs","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"The covering stadium areas of cameras are represented as the following sets.","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"sets = [[1,3,4,6,7], [4,7,8,12], [2,5,9,11,13],\n [1,2,14,15], [3,6,10,12,14], [8,14,15],\n [1,2,6,11], [1,2,4,6,8,12]]","category":"page"},{"location":"generated/SetCovering/#Generic-tensor-network-representation","page":"Set covering problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"We create a [SetCovering] instance that contains a generic tensor network as its code field.","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"problem = SetCovering(sets);\nnothing #hide","category":"page"},{"location":"generated/SetCovering/#Theory-(can-skip)","page":"Set covering problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"Let S be the target set covering problem that we want to solve. For each set s in S, we associate it with a weight w_s to it. The tensor network representation map a set sin S to a boolean degree of freedom v_sin0 1. For each set s, we defined a parameterized rank-one tensor indexed by v_s as","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"W(x_s^w_s) = left(beginmatrix\n 1 \n x_s^w_s\n endmatrixright)","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"where x_s is a variable associated with s. For each unique element a, we defined the constraint over all sets containing it N(a) = s s in S land ain s:","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"B_s_1s_2ldotss_N(a) = begincases\n 0 s_1=s_2=ldots=s_N(a)=0\n 1 textotherwise\nendcases","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"This tensor means if none of the sets containing element a are included, then this configuration is forbidden, One can check the contraction time space complexity of a SetCovering instance by typing:","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"contraction_complexity(problem)","category":"page"},{"location":"generated/SetCovering/#Solving-properties","page":"Set covering problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/SetCovering/#Counting-properties","page":"Set covering problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/SetCovering/#The-\"graph\"-polynomial","page":"Set covering problem","title":"The \"graph\" polynomial","text":"","category":"section"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"The graph polynomial for the set covering problem is defined as","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"P(S x) = sum_k=0^S c_k x^k","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"where c_k is the number of configurations having k sets.","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"covering_polynomial = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"The minimum number of sets that covering the set of elements can be computed with the SizeMin property:","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"min_cover_size = solve(problem, SizeMin())[]","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"Similarly, we have its counting CountingMin:","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"counting_minimum_setcovering = solve(problem, CountingMin())[]","category":"page"},{"location":"generated/SetCovering/#Configuration-properties","page":"Set covering problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/SetCovering/#Finding-minimum-set-covering","page":"Set covering problem","title":"Finding minimum set covering","text":"","category":"section"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"One can enumerate all minimum set covering with the ConfigsMin property in the program.","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"min_configs = solve(problem, ConfigsMin())[].c","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"Hence the two optimal solutions are z_1 z_3 z_5 z_6 and z_2 z_3 z_4 z_5. The correctness of this result can be checked with the is_set_covering function.","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"all(c->is_set_covering(sets, c), min_configs)","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"Similarly, if one is only interested in computing one of the minimum set coverings, one can use the graph property SingleConfigMin.","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"","category":"page"},{"location":"generated/SetCovering/","page":"Set covering problem","title":"Set covering problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"gist/#Gist-of-implementation","page":"Gist","title":"Gist of implementation","text":"","category":"section"},{"location":"gist/","page":"Gist","title":"Gist","text":"The code we will show below is a gist of how this package is implemented for pedagogical purpose, which covers many functionalities of the main repo without caring much about performance. This project depends on multiple open source packages in the Julia ecosystem:","category":"page"},{"location":"gist/","page":"Gist","title":"Gist","text":"OMEinsum and OMEinsumContractionOrders are packages providing the support for Einstein's (or tensor network) notation and state-of-the-art algorithms for contraction order optimization, which includes multiple state of the art algorithms.\nTropicalNumbers and TropicalGEMM are packages providing tropical number and efficient tropical matrix multiplication.\nGraphs is a foundational package for graph manipulation in the Julia community.\nPolynomials is a package providing polynomial algebra and polynomial fitting.\nMods and the Primes package providing finite field algebra and prime number manipulation.","category":"page"},{"location":"gist/","page":"Gist","title":"Gist","text":"They can be installed in a similar way to GenericTensorNetworks. After installing the required packages, one can open a Julia REPL, and copy-paste the following code snippet into it.","category":"page"},{"location":"gist/","page":"Gist","title":"Gist","text":"using OMEinsum\nusing Graphs\nusing Random\n\n# generate a random regular graph of size 50, degree 3\ngraph = (Random.seed!(2); Graphs.random_regular_graph(50, 3))\n\n# generate einsum code, i.e. the labels of tensors\ncode = EinCode(([minmax(e.src,e.dst) for e in Graphs.edges(graph)]..., # labels for edge tensors\n [(i,) for i in Graphs.vertices(graph)]...), ()) # labels for vertex tensors\n\n# an einsum contraction without a contraction order specified is called `EinCode`,\n# an einsum contraction having a contraction order (specified as a tree structure) is called `NestedEinsum`.\n# assign each label a dimension-2, it will be used in the contraction order optimization\n# `uniquelabels` function extracts the tensor labels into a vector.\nsize_dict = Dict([s=>2 for s in uniquelabels(code)])\n# optimize the contraction order using the `TreeSA` method; the target space complexity is 2^17\noptimized_code = optimize_code(code, size_dict, TreeSA())\nprintln(\"time/space complexity is $(OMEinsum.timespace_complexity(optimized_code, size_dict))\")\n\n# a function for computing the independence polynomial\nfunction independence_polynomial(x::T, code) where {T}\n\txs = map(getixsv(code)) do ix\n # if the tensor rank is 1, create a vertex tensor.\n # otherwise the tensor rank must be 2, create a bond tensor.\n length(ix)==1 ? [one(T), x] : [one(T) one(T); one(T) zero(T)]\n end\n # both `EinCode` and `NestedEinsum` are callable, inputs are tensors.\n\tcode(xs...)\nend\n\n########## COMPUTING THE MAXIMUM INDEPENDENT SET SIZE AND ITS COUNTING/DEGENERACY ###########\n\n# using Tropical numbers to compute the MIS size and the MIS degeneracy.\nusing TropicalNumbers\nmis_size(code) = independence_polynomial(TropicalF64(1.0), code)[]\nprintln(\"the maximum independent set size is $(mis_size(optimized_code).n)\")\n\n# A `CountingTropical` object has two fields, tropical field `n` and counting field `c`.\nmis_count(code) = independence_polynomial(CountingTropical{Float64,Float64}(1.0, 1.0), code)[]\nprintln(\"the degeneracy of maximum independent sets is $(mis_count(optimized_code).c)\")\n\n########## COMPUTING THE INDEPENDENCE POLYNOMIAL ###########\n\n# using Polynomial numbers to compute the polynomial directly\nusing Polynomials\nprintln(\"the independence polynomial is $(independence_polynomial(Polynomial([0.0, 1.0]), optimized_code)[])\")\n\n########## FINDING MIS CONFIGURATIONS ###########\n\n# define the set algebra\nstruct ConfigEnumerator{N}\n # NOTE: BitVector is dynamic and it can be very slow; check our repo for the static version\n data::Vector{BitVector}\nend\nfunction Base.:+(x::ConfigEnumerator{N}, y::ConfigEnumerator{N}) where {N}\n res = ConfigEnumerator{N}(vcat(x.data, y.data))\n return res\nend\nfunction Base.:*(x::ConfigEnumerator{L}, y::ConfigEnumerator{L}) where {L}\n M, N = length(x.data), length(y.data)\n z = Vector{BitVector}(undef, M*N)\n for j=1:N, i=1:M\n z[(j-1)*M+i] = x.data[i] .| y.data[j]\n end\n return ConfigEnumerator{L}(z)\nend\nBase.zero(::Type{ConfigEnumerator{N}}) where {N} = ConfigEnumerator{N}(BitVector[])\nBase.one(::Type{ConfigEnumerator{N}}) where {N} = ConfigEnumerator{N}([falses(N)])\n\n# the algebra sampling one of the configurations\nstruct ConfigSampler{N}\n data::BitVector\nend\n\nfunction Base.:+(x::ConfigSampler{N}, y::ConfigSampler{N}) where {N} # biased sampling: return `x`\n return x # randomly pick one\nend\nfunction Base.:*(x::ConfigSampler{L}, y::ConfigSampler{L}) where {L}\n ConfigSampler{L}(x.data .| y.data)\nend\n\nBase.zero(::Type{ConfigSampler{N}}) where {N} = ConfigSampler{N}(trues(N))\nBase.one(::Type{ConfigSampler{N}}) where {N} = ConfigSampler{N}(falses(N))\n\n# enumerate all configurations if `all` is true; compute one otherwise.\n# a configuration is stored in the data type of `StaticBitVector`; it uses integers to represent bit strings.\n# `ConfigTropical` is defined in `TropicalNumbers`. It has two fields: tropical number `n` and optimal configuration `config`.\n# `CountingTropical{T,<:ConfigEnumerator}` stores configurations instead of simple counting.\nfunction mis_config(code; all=false)\n # map a vertex label to an integer\n vertex_index = Dict([s=>i for (i, s) in enumerate(uniquelabels(code))])\n N = length(vertex_index) # number of vertices\n xs = map(getixsv(code)) do ix\n T = all ? CountingTropical{Float64, ConfigEnumerator{N}} : CountingTropical{Float64, ConfigSampler{N}}\n if length(ix) == 2\n return [one(T) one(T); one(T) zero(T)]\n else\n s = falses(N)\n s[vertex_index[ix[1]]] = true # one hot vector\n if all\n [one(T), T(1.0, ConfigEnumerator{N}([s]))]\n else\n [one(T), T(1.0, ConfigSampler{N}(s))]\n end\n end\n end\n\treturn code(xs...)\nend\n\nprintln(\"one of the optimal configurations is $(mis_config(optimized_code; all=false)[].c.data)\")\n\n# direct enumeration of configurations can be very slow; please check the bounding version in our Github repo.\nprintln(\"all optimal configurations are $(mis_config(optimized_code; all=true)[].c)\")","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"EditURL = \"../../../examples/DominatingSet.jl\"","category":"page"},{"location":"generated/DominatingSet/#Dominating-set-problem","page":"Dominating set problem","title":"Dominating set problem","text":"","category":"section"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"note: Note\nIt is highly recommended to read the Independent set problem chapter before reading this one.","category":"page"},{"location":"generated/DominatingSet/#Problem-definition","page":"Dominating set problem","title":"Problem definition","text":"","category":"section"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"In graph theory, a dominating set for a graph G = (V E) is a subset D of V such that every vertex not in D is adjacent to at least one member of D. The domination number gamma(G) is the number of vertices in a smallest dominating set for G. The decision version of finding the minimum dominating set is an NP-complete. In the following, we are going to solve the dominating set problem on the Petersen graph.","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"using GenericTensorNetworks, Graphs\n\ngraph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"We can visualize this graph using the following function","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a\n\nlocations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]\n\nshow_graph(graph; locs=locations, format=:svg)","category":"page"},{"location":"generated/DominatingSet/#Generic-tensor-network-representation","page":"Dominating set problem","title":"Generic tensor network representation","text":"","category":"section"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"We can use DominatingSet to construct the tensor network for solving the dominating set problem as","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"problem = DominatingSet(graph; optimizer=TreeSA());\nnothing #hide","category":"page"},{"location":"generated/DominatingSet/#Theory-(can-skip)","page":"Dominating set problem","title":"Theory (can skip)","text":"","category":"section"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"Let G=(VE) be the target graph that we want to solve. The tensor network representation map a vertex vin V to a boolean degree of freedom s_vin0 1. We defined the restriction on a vertex and its neighboring vertices N(v):","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"T(x_v)_s_1s_2ldotss_N(v)s_v = begincases\n 0 s_1=s_2=ldots=s_N(v)=s_v=0\n 1 s_v=0\n x_v^w_v textotherwise\nendcases","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"where w_v is the weight of vertex v. This tensor means if both v and its neighboring vertices are not in D, i.e., s_1=s_2=ldots=s_N(v)=s_v=0, this configuration is forbidden because v is not adjacent to any member in the set. otherwise, if v is in D, it has a contribution x_v^w_v to the final result. One can check the contraction time space complexity of a DominatingSet instance by typing:","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"contraction_complexity(problem)","category":"page"},{"location":"generated/DominatingSet/#Solving-properties","page":"Dominating set problem","title":"Solving properties","text":"","category":"section"},{"location":"generated/DominatingSet/#Counting-properties","page":"Dominating set problem","title":"Counting properties","text":"","category":"section"},{"location":"generated/DominatingSet/#Domination-polynomial","page":"Dominating set problem","title":"Domination polynomial","text":"","category":"section"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"The graph polynomial for the dominating set problem is known as the domination polynomial (see arXiv:0905.2251). It is defined as","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"D(G x) = sum_k=0^gamma(G) d_k x^k","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"where d_k is the number of dominating sets of size k in graph G=(V E).","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"domination_polynomial = solve(problem, GraphPolynomial())[]","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"The domination number gamma(G) can be computed with the SizeMin property:","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"domination_number = solve(problem, SizeMin())[]","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"Similarly, we have its counting CountingMin:","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"counting_min_dominating_set = solve(problem, CountingMin())[]","category":"page"},{"location":"generated/DominatingSet/#Configuration-properties","page":"Dominating set problem","title":"Configuration properties","text":"","category":"section"},{"location":"generated/DominatingSet/#finding-minimum-dominating-set","page":"Dominating set problem","title":"finding minimum dominating set","text":"","category":"section"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"One can enumerate all minimum dominating sets with the ConfigsMin property in the program.","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"min_configs = solve(problem, ConfigsMin())[].c\n\nall(c->is_dominating_set(graph, c), min_configs)","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"show_gallery(graph, (2, 5); locs=locations, vertex_configs=min_configs, format=:svg)","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"Similarly, if one is only interested in computing one of the minimum dominating sets, one can use the graph property SingleConfigMin.","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"","category":"page"},{"location":"generated/DominatingSet/","page":"Dominating set problem","title":"Dominating set problem","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"EditURL = \"../../../examples/weighted.jl\"","category":"page"},{"location":"generated/weighted/#Weighted-problems","page":"Weighted problems","title":"Weighted problems","text":"","category":"section"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"Let us use the maximum independent set problem on Petersen graph as an example.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"using GenericTensorNetworks, Graphs\n\ngraph = Graphs.smallgraph(:petersen)","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"The following code constructs a weighted MIS problem instance.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"problem = IndependentSet(graph; weights=collect(1:10));\nnothing #hide","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"Here, the weights keyword argument can be a vector for weighted graphs or NoWeight() for unweighted graphs. Most solution space properties work for unweighted graphs also work for the weighted graphs. For example, the maximum independent set can be found as follows.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"max_config_weighted = solve(problem, SingleConfigMax())[]","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"Let us visualize the solution.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a\n\nlocations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]\n\nshow_graph(graph; locs=locations, format=:svg, vertex_colors=\n [iszero(max_config_weighted.c.data[i]) ? \"white\" : \"red\" for i=1:nv(graph)])","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"The only solution space property that can not be defined for general real-weighted (not including integer-weighted) graphs is the GraphPolynomial.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"For the weighted MIS problem, a useful solution space property is the \"energy spectrum\", i.e. the largest several configurations and their weights. We can use the solution space property is SizeMax(10) to compute the largest 10 weights.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"spectrum = solve(problem, SizeMax(10))[]","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"The return value has type ExtendedTropical, which contains one field orders.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"spectrum.orders","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"We can see the order is a vector of Tropical numbers. Similarly, we can get weighted independent sets with maximum 5 sizes as follows.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"max5_configs = solve(problem, SingleConfigMax(5))[]","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"The return value also has type ExtendedTropical, but this time the element type of orders has been changed to CountingTropical{Float64,ConfigSampler}.","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"max5_configs.orders","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"Let us visually check these configurations","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"show_gallery(graph, (1, 5); locs=locations, format=:svg, vertex_configs=[max5_configs.orders[k].c.data for k=1:5])","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"","category":"page"},{"location":"generated/weighted/","page":"Weighted problems","title":"Weighted problems","text":"This page was generated using Literate.jl.","category":"page"},{"location":"ref/#References","page":"References","title":"References","text":"","category":"section"},{"location":"ref/#Graph-problems","page":"References","title":"Graph problems","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"solve\nGraphProblem\nIndependentSet\nMaximalIS\nMatching\nColoring\nDominatingSet\nSpinGlass\nHyperSpinGlass\nMaxCut\nPaintShop\nSatisfiability\nSetCovering\nSetPacking\nOpenPitMining","category":"page"},{"location":"ref/#GenericTensorNetworks.solve","page":"References","title":"GenericTensorNetworks.solve","text":"solve(problem, property; usecuda=false, T=Float64)\n\nSolving a certain property of a graph problem.\n\nPositional Arguments\n\nproblem is the graph problem with tensor network information,\nproperty is string specifying the task. Using the maximum independent set problem as an example, it can be one of\nPartitionFunction() for computing the partition function,\nSizeMax(k=Single) for finding maximum-k set sizes,\nSizeMin(k=Single) for finding minimum-k set sizes,\nCountingMax(k=Single) for counting configurations with maximum-k sizes,\nCountingMin(k=Single) for counting configurations with minimum-k sizes,\nCountingAll() for counting all configurations,\nPartitionFunction() for counting all configurations,\nGraphPolynomial(; method=:finitefield, kwargs...) for evaluating the graph polynomial,\nSingleConfigMax(k=Single; bounded=false) for finding one maximum-k configuration for each size,\nSingleConfigMin(k=Single; bounded=false) for finding one minimum-k configuration for each size,\nConfigsMax(k=Single; bounded=true, tree_storage=false) for enumerating configurations with maximum-k sizes,\nConfigsMin(k=Single; bounded=true, tree_storage=false) for enumerating configurations with minimum-k sizes,\nConfigsAll(; tree_storage=false) for enumerating all configurations,\n\nKeyword arguments\n\nusecuda is a switch to use CUDA (if possible), user need to call statement using CUDA before turning on this switch.\nT is the \"base\" element type, sometimes can be used to reduce the memory cost.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.GraphProblem","page":"References","title":"GenericTensorNetworks.GraphProblem","text":"GraphProblem\n\nThe abstract base type of graph problems.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.IndependentSet","page":"References","title":"GenericTensorNetworks.IndependentSet","text":"IndependentSet{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem\nIndependentSet(graph; weights=NoWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe independent set problem in graph theory.\n\nPositional arguments\n\ngraph is the problem graph.\n\nKeyword arguments\n\nweights are associated with the vertices of the graph.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms on vertices, where a value can be 0 (absent in the set) or 1 (present in the set).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\nExamples\n\njulia> using GenericTensorNetworks, Graphs\n\njulia> problem = IndependentSet(smallgraph(:petersen));\n\njulia> solve(problem, ConfigsMax())\n0-dimensional Array{CountingTropical{Float64, ConfigEnumerator{10, 1, 1}}, 0}:\n(4.0, {0101010001, 1010000011, 0100100110, 0010111000, 1001001100})ₜ\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.MaximalIS","page":"References","title":"GenericTensorNetworks.MaximalIS","text":"MaximalIS{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem\nMaximalIS(graph; weights=NoWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe maximal independent set problem. In the constructor, weights are the weights of vertices.\n\nPositional arguments\n\ngraph is the problem graph.\n\nKeyword arguments\n\nweights are associated with the vertices of the graph.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (absent in the set) or 1 (present in the set).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.Matching","page":"References","title":"GenericTensorNetworks.Matching","text":"Matching{CT<:AbstractEinsum, WT<:Union{NoWeight,Vector}} <: GraphProblem\nMatching(graph; weights=NoWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe Vertex matching problem.\n\nPositional arguments\n\ngraph is the problem graph.\n\nKeyword arguments\n\nweights are associated with the edges of the graph.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms on edges, where a value can be 0 (not matched) or 1 (mathced).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.Coloring","page":"References","title":"GenericTensorNetworks.Coloring","text":"Coloring{K,CT<:AbstractEinsum, WT<:Union{NoWeight, Vector}} <: GraphProblem\nColoring{K}(graph; weights=NoWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe Vertex Coloring problem.\n\nPositional arguments\n\ngraph is the problem graph.\n\nKeyword arguments\n\nweights are associated with the edges of the graph.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms on vertices, where a value can be in 0K-1 (different colors).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.DominatingSet","page":"References","title":"GenericTensorNetworks.DominatingSet","text":"DominatingSet{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem\nDominatingSet(graph; weights=NoWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe dominating set problem.\n\nPositional arguments\n\ngraph is the problem graph.\n\nKeyword arguments\n\nweights are associated with the vertices of the graph.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms on vertices, where a value can be 0 (absent in the set) or 1 (present in the set).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.SpinGlass","page":"References","title":"GenericTensorNetworks.SpinGlass","text":"SpinGlass{TT<:MaxCut,WT1<:Union{NoWeight, Vector},WT2<:Union{ZeroWeight, Vector}} <: ReducedProblem\nSpinGlass(graph; J=NoWeight(), h=ZeroWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\nSpinGlass(M::AbstractMatrix, h::AbstractVector; kwargs...)\n\nThe spin glass problem (or cutting problem). In the output, the spin ↑ is mapped to configuration 0, while spin ↓ is mapped to configuration 1.\n\nPositional arguments\n\ngraph is the problem graph.\n\nKeyword arguments\n\nM is a symmetric matrix of the coupling strengths.\nJ is a vector of coupling strengths associated with the edges of the graph.\nh is a vector of onsite energy terms associated with the vertices of the graph.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.HyperSpinGlass","page":"References","title":"GenericTensorNetworks.HyperSpinGlass","text":"struct HyperSpinGlass{CT<:OMEinsum.AbstractEinsum, WT<:Union{NoWeight, Vector}} <: GraphProblem\n\nThe hyper-spin-glass problem is a generalization of the spin-glass problem to hypergraphs.\n\nPositional arguments\n\nn is the number of spins.\ncliques is a vector of cliques, each being a vector of vertices (integers).\n\nKeyword arguments\n\nweights are associated with the cliques.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.MaxCut","page":"References","title":"GenericTensorNetworks.MaxCut","text":"MaxCut{CT<:AbstractEinsum,WT1<:Union{NoWeight, Vector},WT2<:Union{ZeroWeight, Vector}} <: GraphProblem\nMaxCut(graph; edge_weights=NoWeight(), vertex_weights=ZeroWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe cutting problem.\n\nPositional arguments\n\ngraph is the problem graph.\n\nKeyword arguments\n\nedge_weights are associated with the edges of the graph.\nvertex_weights are associated with the vertices of the graph.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.PaintShop","page":"References","title":"GenericTensorNetworks.PaintShop","text":"PaintShop{CT<:AbstractEinsum} <: GraphProblem\nPaintShop(sequence::AbstractVector; openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe binary paint shop problem.\n\nPositional arguments\n\nKeyword arguments\n\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (the first appearence in blue) or 1 (the first appearence in red).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\nExamples\n\nOne can encode the paint shop problem abaccb as the following\n\njulia> syms = collect(\"abaccb\");\n\njulia> pb = PaintShop(syms);\n\njulia> solve(pb, SizeMin())[]\n2.0ₜ\n\njulia> solve(pb, ConfigsMin())[].c.data\n2-element Vector{StaticBitVector{3, 1}}:\n 100\n 011\n\nIn our definition, we find the maximum number of unchanged color in this sequence, i.e. (n-1) - (minimum number of color changes) In the output of maximum configurations, the two configurations are defined on 5 bonds i.e. pairs of (i, i+1), 0 means color changed, while 1 means color not changed. If we denote two \"colors\" as r and b, then the optimal painting is rbbbrr or brrrbb, both change the colors twice.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.Satisfiability","page":"References","title":"GenericTensorNetworks.Satisfiability","text":"Satisfiability{CT<:AbstractEinsum,T,WT<:Union{NoWeight, Vector}} <: GraphProblem\nSatisfiability(cnf::CNF; weights=NoWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe satisfiability problem.\n\nPositional arguments\n\ncnf is a conjunctive normal form (CNF) for specifying the satisfiability problems.\n\nKeyword arguments\n\nweights are associated with clauses.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of boolean variables, where a value can be 0 or 1.\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\nExamples\n\njulia> @bools x y z a b c\n\njulia> c1 = x ∨ ¬y\nx ∨ ¬y\n\njulia> c2 = c ∨ (¬a ∨ b)\nc ∨ ¬a ∨ b\n\njulia> c3 = (z ∨ ¬a) ∨ y\nz ∨ ¬a ∨ y\n\njulia> c4 = (c ∨ z) ∨ ¬b\nc ∨ z ∨ ¬b\n\njulia> cnf = (c1 ∧ c4) ∧ (c2 ∧ c3)\n(x ∨ ¬y) ∧ (c ∨ z ∨ ¬b) ∧ (c ∨ ¬a ∨ b) ∧ (z ∨ ¬a ∨ y)\n\njulia> gp = Satisfiability(cnf);\n\njulia> solve(gp, SizeMax())[]\n4.0ₜ\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.SetCovering","page":"References","title":"GenericTensorNetworks.SetCovering","text":"SetCovering{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem\nSetCovering(sets; weights=NoWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe set covering problem.\n\nPositional arguments\n\nsets is a vector of vectors, each set is associated with a weight specified in weights.\n\nKeyword arguments\n\nweights are associated with sets.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (absent in the set) or 1 (present in the set).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\nExamples\n\njulia> sets = [[1, 2, 5], [1, 3], [2, 4], [3, 6], [2, 3, 6]]; # each set is a vertex\n\njulia> gp = SetCovering(sets);\n\njulia> res = solve(gp, ConfigsMin())[]\n(3.0, {10110, 10101})ₜ\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.SetPacking","page":"References","title":"GenericTensorNetworks.SetPacking","text":"SetPacking{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem\nSetPacking(sets; weights=NoWeight(), openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict()\n )\n\nThe set packing problem, a generalization of independent set problem to hypergraphs.\n\nPositional arguments\n\nsets is a vector of vectors, each set is associated with a weight specified in weights.\n\nKeyword arguments\n\nweights are associated with sets.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (absent in the set) or 1 (present in the set).\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\nExamples\n\njulia> sets = [[1, 2, 5], [1, 3], [2, 4], [3, 6], [2, 3, 6]]; # each set is a vertex\n\njulia> gp = SetPacking(sets);\n\njulia> res = solve(gp, ConfigsMax())[]\n(2.0, {00110, 10010, 01100})ₜ\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.OpenPitMining","page":"References","title":"GenericTensorNetworks.OpenPitMining","text":"OpenPitMining{ET, CT<:AbstractEinsum} <: GraphProblem\nOpenPitMining(rewards; openvertices=(),\n optimizer=GreedyMethod(), simplifier=nothing,\n fixedvertices=Dict())\n\nThe open pit mining problem. This problem can be solved in polynomial time with the pseudoflow algorithm.\n\nPositional arguments\n\nrewards is a matrix of rewards.\n\nKeyword arguments\n\nopenvertices specifies labels of the output tensor.\noptimizer and simplifier are for tensor network optimization, check optimize_code for details.\nfixedvertices is a dict to specify the values of labels, where a value can be 0 (not mined) or 1 (mined)\nopenvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.\n\nExample\n\njulia> rewards = [-4 -7 -7 -17 -7 -26;\n 0 39 -7 -7 -4 0;\n 0 0 1 8 0 0;\n 0 0 0 0 0 0;\n 0 0 0 0 0 0;\n 0 0 0 0 0 0];\n\njulia> gp = OpenPitMining(rewards);\n\njulia> res = solve(gp, SingleConfigMax())[]\n(21.0, ConfigSampler{12, 1, 1}(111000100000))ₜ\n\njulia> is_valid_mining(rewards, res.c.data)\ntrue\n\njulia> print_mining(rewards, res.c.data)\n -4 -7 -7 -17 -7 -26 \n ◼ 39 -7 -7 -4 ◼ \n ◼ ◼ 1 8 ◼ ◼ \n ◼ ◼ ◼ ◼ ◼ ◼ \n ◼ ◼ ◼ ◼ ◼ ◼ \n ◼ ◼ ◼ ◼ ◼ ◼\n\nYou will the the mining is printed as green in an colored REPL.\n\n\n\n\n\n","category":"type"},{"location":"ref/#Graph-Problem-Interfaces","page":"References","title":"Graph Problem Interfaces","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"To subtype GraphProblem, a new type must contain a code field to represent the (optimized) tensor network. Interfaces GenericTensorNetworks.generate_tensors, labels, flavors and get_weights are required. nflavor is optional.","category":"page"},{"location":"ref/","page":"References","title":"References","text":"GenericTensorNetworks.generate_tensors\nlabels\nterms\nflavors\nget_weights\nchweights\nnflavor\nfixedvertices\n\nextract_result","category":"page"},{"location":"ref/#GenericTensorNetworks.generate_tensors","page":"References","title":"GenericTensorNetworks.generate_tensors","text":"generate_tensors(func, problem::GraphProblem)\n\nGenerate a vector of tensors as the inputs of the tensor network contraction code problem.code. func is a function to customize the tensors. func(symbol) returns a vector of elements, the length of which is same as the number of flavors.\n\nExample\n\nThe following code gives your the maximum independent set size\n\njulia> using Graphs, GenericTensorNetworks\n\njulia> gp = IndependentSet(smallgraph(:petersen));\n\njulia> getixsv(gp.code)\n25-element Vector{Vector{Int64}}:\n [1]\n [2]\n [3]\n [4]\n [5]\n [6]\n [7]\n [8]\n [9]\n [10]\n ⋮\n [3, 8]\n [4, 5]\n [4, 9]\n [5, 10]\n [6, 8]\n [6, 9]\n [7, 9]\n [7, 10]\n [8, 10]\n\njulia> gp.code(GenericTensorNetworks.generate_tensors(Tropical(1.0), gp)...)\n0-dimensional Array{Tropical{Float64}, 0}:\n4.0ₜ\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.labels","page":"References","title":"GenericTensorNetworks.labels","text":"labels(problem::GraphProblem) -> Vector\n\nThe labels of a graph problem is defined as the degrees of freedoms in the graph problem. e.g. for the maximum independent set problems, they are the indices of vertices: 1, 2, 3..., while for the max cut problem, they are the edges.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.terms","page":"References","title":"GenericTensorNetworks.terms","text":"terms(problem::GraphProblem) -> Vector\n\nThe terms of a graph problem is defined as the tensor labels that defining local energies (or weights) in the graph problem. e.g. for the maximum independent set problems, they are the vertex-tensor labels: [1], [2], [3]... The weight of a term is same as the exponents in the graph polynomial.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.flavors","page":"References","title":"GenericTensorNetworks.flavors","text":"flavors(::Type{<:GraphProblem}) -> Vector\n\nIt returns a vector of integers as the flavors of a degree of freedom. Its size is the same as the degree of freedom on a single vertex/edge.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.get_weights","page":"References","title":"GenericTensorNetworks.get_weights","text":"get_weights(problem::GraphProblem, i::Int) -> Vector\nget_weights(problem::GraphProblem) -> Vector\n\nThe weights for the problem or the weights for the degree of freedom specified by the i-th term if a second argument is provided. Weights are associated with terms in the graph problem. In graph polynomial, integer weights can be the exponents.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.chweights","page":"References","title":"GenericTensorNetworks.chweights","text":"chweights(problem::GraphProblem, weights) -> GraphProblem\n\nChange the weights for the problem and return a new problem instance. Weights are associated with terms in the graph problem. In graph polynomial, integer weights can be the exponents.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.nflavor","page":"References","title":"GenericTensorNetworks.nflavor","text":"nflavor(::Type{<:GraphProblem}) -> Int\n\nBond size is equal to the number of flavors.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.fixedvertices","page":"References","title":"GenericTensorNetworks.fixedvertices","text":"fixedvertices(problem::GraphProblem) -> Dict\n\nFix degree of freedoms in a graph problem to a certain value using a dict, where the key is a label, and the value should be in, e.g. [0, 1] in the indepenent set problem. When a degree of freedom is fixed, its size is 1. The optimal tensor network contraction order is then different from the default case.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.extract_result","page":"References","title":"GenericTensorNetworks.extract_result","text":"extract_result(p::ReducedProblem, output)\nextract_result(p::ReducedProblem)\n\nPost process the output of the target problem to get an output to the source problem. If the output is not provided, it will return a function instead. The result extraction rule is determined by the output type. e.g. If the output type is Tropical, it will be interpreted as the energy. If the output is a Vector, it will be interpreted as a configuration.\n\n\n\n\n\n","category":"function"},{"location":"ref/#Graph-Problem-Utilities","page":"References","title":"Graph Problem Utilities","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"is_independent_set\nis_maximal_independent_set\nis_dominating_set\nis_vertex_coloring\nis_matching\nis_set_covering\nis_set_packing\n\ncut_size\nspinglass_energy\nhyperspinglass_energy\nnum_paint_shop_color_switch\npaint_shop_coloring_from_config\nmis_compactify!\n\nCNF\nCNFClause\nBoolVar\nsatisfiable\n@bools\n∨\n¬\n∧\n\nis_valid_mining\nprint_mining","category":"page"},{"location":"ref/#GenericTensorNetworks.is_independent_set","page":"References","title":"GenericTensorNetworks.is_independent_set","text":"is_independent_set(g::SimpleGraph, config)\n\nReturn true if config (a vector of boolean numbers as the mask of vertices) is an independent set of graph g.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.is_maximal_independent_set","page":"References","title":"GenericTensorNetworks.is_maximal_independent_set","text":"is_maximal_independent_set(g::SimpleGraph, config)\n\nReturn true if config (a vector of boolean numbers as the mask of vertices) is a maximal independent set of graph g.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.is_dominating_set","page":"References","title":"GenericTensorNetworks.is_dominating_set","text":"is_dominating_set(g::SimpleGraph, config)\n\nReturn true if config (a vector of boolean numbers as the mask of vertices) is a dominating set of graph g.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.is_vertex_coloring","page":"References","title":"GenericTensorNetworks.is_vertex_coloring","text":"is_vertex_coloring(graph::SimpleGraph, config)\n\nReturns true if the coloring specified by config is a valid one, i.e. does not violate the contraints of vertices of an edges having different colors.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.is_matching","page":"References","title":"GenericTensorNetworks.is_matching","text":"is_matching(graph::SimpleGraph, config)\n\nReturns true if config is a valid matching on graph, and false if a vertex is double matched. config is a vector of boolean variables, which has one to one correspondence with edges(graph).\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.is_set_covering","page":"References","title":"GenericTensorNetworks.is_set_covering","text":"is_set_covering(sets::AbstractVector, config)\n\nReturn true if config (a vector of boolean numbers as the mask of sets) is a set covering of sets.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.is_set_packing","page":"References","title":"GenericTensorNetworks.is_set_packing","text":"is_set_packing(sets::AbstractVector, config)\n\nReturn true if config (a vector of boolean numbers as the mask of sets) is a set packing of sets.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.cut_size","page":"References","title":"GenericTensorNetworks.cut_size","text":"cut_size(g::SimpleGraph, config; edge_weights=NoWeight(), vertex_weights=ZeroWeight())\n\nCompute the cut size for the vertex configuration config (an iterator).\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.spinglass_energy","page":"References","title":"GenericTensorNetworks.spinglass_energy","text":"spinglass_energy(g::SimpleGraph, config; J=NoWeight(), h=ZeroWeight())\n\nCompute the spin glass state energy for the vertex configuration config. In the configuration, the spin ↑ is mapped to configuration 0, while spin ↓ is mapped to configuration 1. Let G=(VE) be the input graph, the hamiltonian is\n\nH = - sum_ij in E J_ij s_i s_j + sum_i in V h_i s_i\n\nwhere s_i in -1 1 stands for spin ↓ and spin ↑.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.hyperspinglass_energy","page":"References","title":"GenericTensorNetworks.hyperspinglass_energy","text":"hyperspinglass_energy(cliques, config; weights) -> Real\n\n\nCompute the energy for spin configuration config (an iterator).\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.num_paint_shop_color_switch","page":"References","title":"GenericTensorNetworks.num_paint_shop_color_switch","text":"num_paint_shop_color_switch(sequence::AbstractVector, coloring)\n\nReturns the number of color switches.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.paint_shop_coloring_from_config","page":"References","title":"GenericTensorNetworks.paint_shop_coloring_from_config","text":"paint_shop_coloring_from_config(p::PaintShop, config)\n\nReturns a valid painting from the paint shop configuration (given by the configuration solvers). The config is a sequence of 0 and 1, where 0 means painting the first appearence of a car in blue, 1 otherwise.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.mis_compactify!","page":"References","title":"GenericTensorNetworks.mis_compactify!","text":"mis_compactify!(tropicaltensor)\n\nCompactify tropical tensor for maximum independent set problem. It will eliminate some entries by setting them to zero, by the criteria that removing these entry does not change the MIS size of its parent graph (reference to be added).\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.CNF","page":"References","title":"GenericTensorNetworks.CNF","text":"CNF{T}\nCNF(clauses)\n\nBoolean expression in conjunctive normal form. clauses is a vector of CNFClause, if and only if all clauses are satisfied, this CNF is satisfied.\n\nExample\n\njulia> @bools x y z\n\njulia> cnf = (x ∨ y) ∧ (¬y ∨ z)\n(x ∨ y) ∧ (¬y ∨ z)\n\njulia> satisfiable(cnf, Dict([:x=>true, :y=>false, :z=>true]))\ntrue\n\njulia> satisfiable(cnf, Dict([:x=>false, :y=>false, :z=>true]))\nfalse\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.CNFClause","page":"References","title":"GenericTensorNetworks.CNFClause","text":"CNFClause{T}\nCNFClause(vars)\n\nA clause in CNF, its value is the logical or of vars, where vars is a vector of BoolVar.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.BoolVar","page":"References","title":"GenericTensorNetworks.BoolVar","text":"BoolVar{T}\nBoolVar(name, neg)\n\nBoolean variable for constructing CNF clauses.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.satisfiable","page":"References","title":"GenericTensorNetworks.satisfiable","text":"satisfiable(cnf::CNF, config::AbstractDict)\n\nReturns true if an assignment of variables satisfies a CNF.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.@bools","page":"References","title":"GenericTensorNetworks.@bools","text":"@bools(syms::Symbol...)\n\nCreate some boolean variables of type BoolVar in current scope that can be used in create a CNF.\n\nExample\n\njulia> @bools x y z\n\njulia> (x ∨ y) ∧ (¬y ∨ z)\n(x ∨ y) ∧ (¬y ∨ z)\n\n\n\n\n\n","category":"macro"},{"location":"ref/#GenericTensorNetworks.:∨","page":"References","title":"GenericTensorNetworks.:∨","text":"∨(vars...)\n\nLogical or applied on BoolVar and CNFClause. Returns a CNFClause.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.:¬","page":"References","title":"GenericTensorNetworks.:¬","text":"¬(var::BoolVar)\n\nNegation of a boolean variables of type BoolVar.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.:∧","page":"References","title":"GenericTensorNetworks.:∧","text":"∧(vars...)\n\nLogical and applied on CNFClause and CNF. Returns a new CNF.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.is_valid_mining","page":"References","title":"GenericTensorNetworks.is_valid_mining","text":"is_valid_mining(rewards::AbstractMatrix, config)\n\nReturn true if config (a boolean mask for the feasible region) is a valid mining of rewards.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.print_mining","page":"References","title":"GenericTensorNetworks.print_mining","text":"print_mining(rewards::AbstractMatrix, config)\n\nPrinting the mining solution in a colored REPL.\n\n\n\n\n\n","category":"function"},{"location":"ref/#Properties","page":"References","title":"Properties","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"PartitionFunction\nSizeMax\nSizeMin\nCountingAll\nCountingMax\nCountingMin\nGraphPolynomial\nSingleConfigMax\nSingleConfigMin\nConfigsAll\nConfigsMax\nConfigsMin","category":"page"},{"location":"ref/#GenericTensorNetworks.PartitionFunction","page":"References","title":"GenericTensorNetworks.PartitionFunction","text":"struct PartitionFunction{T} <: GenericTensorNetworks.AbstractProperty\n\nbeta\n\nCompute the partition function for the target problem.\n\nThe corresponding tensor element type is T.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.SizeMax","page":"References","title":"GenericTensorNetworks.SizeMax","text":"SizeMax{K} <: AbstractProperty\nSizeMax(k::Int)\n\nThe maximum-K set sizes. e.g. the largest size of the IndependentSet problem is also know as the independence number.\n\nThe corresponding tensor element type are max-plus tropical number Tropical if K is Single and ExtendedTropical if K is an integer.\nIt is compatible with weighted graph problems.\nBLAS (on CPU) and GPU are supported only if K is Single,\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.SizeMin","page":"References","title":"GenericTensorNetworks.SizeMin","text":"SizeMin{K} <: AbstractProperty\nSizeMin(k::Int)\n\nThe minimum-K set sizes. e.g. the smallest size ofthe MaximalIS problem is also known as the independent domination number.\n\nThe corresponding tensor element type are inverted max-plus tropical number Tropical if K is Single and inverted ExtendedTropical K is an integer.\n\nThe inverted Tropical number emulates the min-plus tropical number.\n\nIt is compatible with weighted graph problems.\nBLAS (on CPU) and GPU are supported only if K is Single,\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.CountingAll","page":"References","title":"GenericTensorNetworks.CountingAll","text":"CountingAll <: AbstractProperty\nCountingAll()\n\nCounting the total number of sets. e.g. for the IndependentSet problem, it counts the independent sets.\n\nThe corresponding tensor element type is Base.Real.\nThe weights on graph does not have effect.\nBLAS (GPU and CPU) and GPU are supported,\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.CountingMax","page":"References","title":"GenericTensorNetworks.CountingMax","text":"CountingMax{K} <: AbstractProperty\nCountingMax(K=Single)\n\nCounting the number of sets with largest-K size. e.g. for IndependentSet problem, it counts independent sets of size alpha(G) alpha(G)-1 ldots alpha(G)-K+1.\n\nThe corresponding tensor element type is CountingTropical if K is Single, and TruncatedPoly{K} if K is an integer.\nWeighted graph problems is only supported if K is Single.\nGPU is supported,\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.CountingMin","page":"References","title":"GenericTensorNetworks.CountingMin","text":"CountingMin{K} <: AbstractProperty\nCountingMin(K=Single)\n\nCounting the number of sets with smallest-K size.\n\nThe corresponding tensor element type is inverted CountingTropical if K is Single, and TruncatedPoly{K} if K is an integer.\nWeighted graph problems is only supported if K is Single.\nGPU is supported,\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.GraphPolynomial","page":"References","title":"GenericTensorNetworks.GraphPolynomial","text":"GraphPolynomial{METHOD} <: AbstractProperty\nGraphPolynomial(; method=:finitefield, kwargs...)\n\nCompute the graph polynomial, e.g. for IndependentSet problem, it is the independence polynomial. The METHOD type parameter can be one of the following symbols\n\nMethod Argument\n\n:finitefield, uses finite field algebra to fit the polynomial.\nThe corresponding tensor element type is Mods.Mod,\nIt does not have round-off error,\nGPU is supported,\nIt accepts keyword arguments maxorder (optional, e.g. the MIS size in the IndependentSet problem).\n:polynomial and :laurent, use (Laurent) polynomial numbers to solve the polynomial directly.\nThe corresponding tensor element types are Polynomial and LaurentPolynomial.\nIt might have small round-off error depending on the data type for storing the counting.\nIt has memory overhead that linear to the graph size.\n:fft, use fast fourier transformation to fit the polynomial.\nThe corresponding tensor element type is Base.Complex.\nIt has (controllable) round-off error.\nBLAS and GPU are supported.\nIt accepts keyword arguments maxorder (optional) and r, if r > 1, one has better precision for coefficients of large order, if r < 1, one has better precision for coefficients of small order.\n:fitting, fit the polynomial directly.\nThe corresponding tensor element type is floating point numbers like Base.Float64.\nIt has round-off error.\nBLAS and GPU are supported, it is the fastest among all methods.\n\nGraph polynomials are not defined for weighted graph problems.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.SingleConfigMax","page":"References","title":"GenericTensorNetworks.SingleConfigMax","text":"SingleConfigMax{K, BOUNDED} <: AbstractProperty\nSingleConfigMax(k::Int; bounded=false)\n\nFinding single solution for largest-K sizes, e.g. for IndependentSet problem, it is one of the maximum independent sets.\n\nThe corresponding data type is CountingTropical{Float64,<:ConfigSampler} if BOUNDED is false, Tropical otherwise.\nWeighted graph problems is supported.\nGPU is supported,\n\nKeyword Arguments\n\nbounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.SingleConfigMin","page":"References","title":"GenericTensorNetworks.SingleConfigMin","text":"SingleConfigMin{K, BOUNDED} <: AbstractProperty\nSingleConfigMin(k::Int; bounded=false)\n\nFinding single solution with smallest-K size.\n\nThe corresponding data type is inverted CountingTropical{Float64,<:ConfigSampler} if BOUNDED is false, inverted Tropical otherwise.\nWeighted graph problems is supported.\nGPU is supported,\n\nKeyword Arguments\n\nbounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.ConfigsAll","page":"References","title":"GenericTensorNetworks.ConfigsAll","text":"ConfigsAll{TREESTORAGE} <:AbstractProperty\nConfigsAll(; tree_storage=false)\n\nFind all valid configurations, e.g. for IndependentSet problem, it is finding all independent sets.\n\nThe corresponding data type is ConfigEnumerator.\nWeights do not take effect.\n\nKeyword Arguments\n\ntree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.ConfigsMax","page":"References","title":"GenericTensorNetworks.ConfigsMax","text":"ConfigsMax{K, BOUNDED, TREESTORAGE} <:AbstractProperty\nConfigsMax(K=Single; bounded=true, tree_storage=true)\n\nFind configurations with largest-K sizes, e.g. for IndependentSet problem, it is finding all independent sets of sizes alpha(G) alpha(G)-1 ldots alpha(G)-K+1.\n\nThe corresponding data type is CountingTropical{Float64,<:ConfigEnumerator} if K is Single and TruncatedPoly{K,<:ConfigEnumerator} if K is an integer.\nWeighted graph problems is only supported if K is Single.\n\nKeyword Arguments\n\nbounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.\ntree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.ConfigsMin","page":"References","title":"GenericTensorNetworks.ConfigsMin","text":"ConfigsMin{K, BOUNDED, TREESTORAGE} <:AbstractProperty\nConfigsMin(K=Single; bounded=true, tree_storage=false)\n\nFind configurations with smallest-K sizes.\n\nThe corresponding data type is inverted CountingTropical{Float64,<:ConfigEnumerator} if K is Single and inverted TruncatedPoly{K,<:ConfigEnumerator} if K is an integer.\nWeighted graph problems is only supported if K is Single.\n\nKeyword Arguments\n\nbounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.\ntree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.\n\n\n\n\n\n","category":"type"},{"location":"ref/#Element-Algebras","page":"References","title":"Element Algebras","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"is_commutative_semiring","category":"page"},{"location":"ref/#GenericTensorNetworks.is_commutative_semiring","page":"References","title":"GenericTensorNetworks.is_commutative_semiring","text":"is_commutative_semiring(a::T, b::T, c::T) where T\n\nCheck if elements a, b and c satisfied the commutative semiring requirements.\n\nbeginalign*\n(a oplus b) oplus c = a oplus (b oplus c) hspace5emtrianglerighttextcommutative monoid oplus with identity mathbb0\na oplus mathbb0 = mathbb0 oplus a = a \na oplus b = b oplus a \n\n(a odot b) odot c = a odot (b odot c) hspace5emtriangleright textcommutative monoid odot with identity mathbb1\na odot mathbb1 = mathbb1 odot a = a \na odot b = b odot a \n\na odot (boplus c) = aodot b oplus aodot c hspace5emtriangleright textleft and right distributive\n(aoplus b) odot c = aodot c oplus bodot c \n\na odot mathbb0 = mathbb0 odot a = mathbb0\nendalign*\n\n\n\n\n\n","category":"function"},{"location":"ref/","page":"References","title":"References","text":"TropicalNumbers.Tropical\nTropicalNumbers.CountingTropical\nExtendedTropical\nMods.Mod\nTruncatedPoly\nMax2Poly\nConfigEnumerator\nSumProductTree\nConfigSampler","category":"page"},{"location":"ref/#TropicalNumbers.Tropical","page":"References","title":"TropicalNumbers.Tropical","text":"TropicalMaxPlus{T} = Tropical{T} <: AbstractSemiring\n\nTropicalMaxPlus is a semiring algebra, can be described by\n\nTropical (TropicalMaxPlus), (ℝ, max, +, -Inf, 0).\n\nIt maps\n\n+ to max in regular algebra,\n* to + in regular algebra,\n1 to 0 in regular algebra,\n0 to -Inf in regular algebra (for integer content types, this is chosen as a small integer).\n\nExample\n\njulia> TropicalMaxPlus(1.0) + TropicalMaxPlus(3.0)\n3.0ₜ\n\njulia> TropicalMaxPlus(1.0) * TropicalMaxPlus(3.0)\n4.0ₜ\n\njulia> one(TropicalMaxPlusF64)\n0.0ₜ\n\njulia> zero(TropicalMaxPlusF64)\n-Infₜ\n\n\n\n\n\n","category":"type"},{"location":"ref/#TropicalNumbers.CountingTropical","page":"References","title":"TropicalNumbers.CountingTropical","text":"CountingTropical{T,CT} <: Number\n\nCounting tropical number type is also a semiring algebra. It is tropical algebra with one extra field for counting, it is introduced in arXiv:2008.06888.\n\nExample\n\njulia> CountingTropical(1.0, 5.0) + CountingTropical(3.0, 2.0)\n(3.0, 2.0)ₜ\n\njulia> CountingTropical(1.0, 5.0) * CountingTropical(3.0, 2.0)\n(4.0, 10.0)ₜ\n\njulia> one(CountingTropicalF64)\n(0.0, 1.0)ₜ\n\njulia> zero(CountingTropicalF64)\n(-Inf, 0.0)ₜ\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.ExtendedTropical","page":"References","title":"GenericTensorNetworks.ExtendedTropical","text":"ExtendedTropical{K,TO} <: Number\nExtendedTropical{K}(orders)\n\nExtended Tropical numbers with largest K orders keeped, or the TruncatedPoly without coefficients, TO is the element type of orders, usually Tropical numbers. This algebra maps\n\n+ to finding largest K values of union of two sets.\n* to finding largest K values of sum combination of two sets.\n0 to set [-Inf, -Inf, ..., -Inf, -Inf]\n1 to set [-Inf, -Inf, ..., -Inf, 0]\n\nFields\n\norders is a vector of Tropical (CountingTropical) numbers as the largest-K solution sizes (solutions).\n\nExamples\n\njulia> x = ExtendedTropical{3}(Tropical.([1.0, 2, 3]))\nExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[1.0ₜ, 2.0ₜ, 3.0ₜ])\n\njulia> y = ExtendedTropical{3}(Tropical.([-Inf, 2, 5]))\nExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[-Infₜ, 2.0ₜ, 5.0ₜ])\n\njulia> x * y\nExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[6.0ₜ, 7.0ₜ, 8.0ₜ])\n\njulia> x + y\nExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[2.0ₜ, 3.0ₜ, 5.0ₜ])\n\njulia> one(x)\nExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[-Infₜ, -Infₜ, 0.0ₜ])\n\njulia> zero(x)\nExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[-Infₜ, -Infₜ, -Infₜ])\n\n\n\n\n\n","category":"type"},{"location":"ref/#Mods.Mod","page":"References","title":"Mods.Mod","text":"Mod{m}(v) creates a modular number in mod m with value mod(v,m).\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.TruncatedPoly","page":"References","title":"GenericTensorNetworks.TruncatedPoly","text":"TruncatedPoly{K,T,TO} <: Number\nTruncatedPoly(coeffs::Tuple, maxorder)\n\nPolynomial truncated to largest K orders. T is the coefficients type and TO is the orders type.\n\nFields\n\ncoeffs is the largest-K coefficients of a polynomial. In GenericTensorNetworks, it can be the counting or enumeration of solutions.\nmaxorder is the order of a polynomial.\n\nExamples\n\njulia> TruncatedPoly((1,2,3), 6)\nx^4 + 2*x^5 + 3*x^6\n\njulia> TruncatedPoly((1,2,3), 6) * TruncatedPoly((5,2,1), 3)\n20*x^7 + 8*x^8 + 3*x^9\n\njulia> TruncatedPoly((1,2,3), 6) + TruncatedPoly((5,2,1), 3)\nx^4 + 2*x^5 + 3*x^6\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.Max2Poly","page":"References","title":"GenericTensorNetworks.Max2Poly","text":"Max2Poly{T,TO} = TruncatedPoly{2,T,TO}\nMax2Poly(a, b, maxorder)\n\nA shorthand of TruncatedPoly{2}.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.ConfigEnumerator","page":"References","title":"GenericTensorNetworks.ConfigEnumerator","text":"ConfigEnumerator{N,S,C} <: AbstractSetNumber\n\nSet algebra for enumerating configurations, where N is the length of configurations, C is the size of storage in unit of UInt64, S is the bit width to store a single element in a configuration, i.e. log2(# of flavors), for bitstrings, it is 1`.\n\nFields\n\ndata is a vector of StaticElementVector as the solution set.\n\nExamples\n\njulia> a = ConfigEnumerator([StaticBitVector([1,1,1,0,0]), StaticBitVector([1,0,0,0,1])])\n{11100, 10001}\n\njulia> b = ConfigEnumerator([StaticBitVector([0,0,0,0,0]), StaticBitVector([1,0,1,0,1])])\n{00000, 10101}\n\njulia> a + b\n{11100, 10001, 00000, 10101}\n\njulia> one(a)\n{00000}\n\njulia> zero(a)\n{}\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.SumProductTree","page":"References","title":"GenericTensorNetworks.SumProductTree","text":"SumProductTree{ET} <: AbstractSetNumber\n\nConfiguration enumerator encoded in a tree, it is the most natural representation given by a sum-product network and is often more memory efficient than putting the configurations in a vector. One can use generate_samples to sample configurations from this tree structure efficiently.\n\nFields\n\ntag is one of ZERO, ONE, LEAF, SUM, PROD.\ndata is the element stored in a LEAF node.\nleft and right are two operands of a SUM or PROD node.\n\nExamples\n\njulia> s = SumProductTree(bv\"00111\")\n00111\n\n\njulia> q = SumProductTree(bv\"10000\")\n10000\n\n\njulia> x = s + q\n+ (count = 2.0)\n├─ 00111\n└─ 10000\n\n\njulia> y = x * x\n* (count = 4.0)\n├─ + (count = 2.0)\n│ ├─ 00111\n│ └─ 10000\n└─ + (count = 2.0)\n ├─ 00111\n └─ 10000\n\n\njulia> collect(y)\n4-element Vector{StaticBitVector{5, 1}}:\n 00111\n 10111\n 10111\n 10000\n\njulia> zero(s)\n∅\n\n\n\njulia> one(s)\n00000\n\n\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.ConfigSampler","page":"References","title":"GenericTensorNetworks.ConfigSampler","text":"ConfigSampler{N,S,C} <: AbstractSetNumber\nConfigSampler(elements::StaticElementVector)\n\nThe algebra for sampling one configuration, where N is the length of configurations, C is the size of storage in unit of UInt64, S is the bit width to store a single element in a configuration, i.e. log2(# of flavors), for bitstrings, it is 1`.\n\nnote: Note\nConfigSampler is a probabilistic commutative semiring, adding two config samplers do not give you deterministic results.\n\nFields\n\ndata is a StaticElementVector as the sampled solution.\n\nExamples\n\njulia> ConfigSampler(StaticBitVector([1,1,1,0,0]))\nConfigSampler{5, 1, 1}(11100)\n\njulia> ConfigSampler(StaticBitVector([1,1,1,0,0])) + ConfigSampler(StaticBitVector([1,0,1,0,0]))\nConfigSampler{5, 1, 1}(10100)\n\njulia> ConfigSampler(StaticBitVector([1,1,1,0,0])) * ConfigSampler(StaticBitVector([0,0,0,0,1]))\nConfigSampler{5, 1, 1}(11101)\n\njulia> one(ConfigSampler{5, 1, 1})\nConfigSampler{5, 1, 1}(00000)\n\njulia> zero(ConfigSampler{5, 1, 1})\nConfigSampler{5, 1, 1}(11111)\n\n\n\n\n\n","category":"type"},{"location":"ref/","page":"References","title":"References","text":"GenericTensorNetworks also exports the Polynomial and LaurentPolynomial types defined in package Polynomials.","category":"page"},{"location":"ref/","page":"References","title":"References","text":"StaticBitVector\nStaticElementVector\nOnehotVec\nsave_configs\nload_configs\nsave_sumproduct\nload_sumproduct\n@bv_str\nonehotv\n\ngenerate_samples\nhamming_distribution","category":"page"},{"location":"ref/#GenericTensorNetworks.StaticBitVector","page":"References","title":"GenericTensorNetworks.StaticBitVector","text":"StaticBitVector{N,C} = StaticElementVector{N,1,C}\nStaticBitVector(x::AbstractVector)\n\nExamples\n\njulia> sb = StaticBitVector([1,0,0,1,1])\n10011\n\njulia> sb[3]\n0x0000000000000000\n\njulia> collect(Int, sb)\n5-element Vector{Int64}:\n 1\n 0\n 0\n 1\n 1\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.StaticElementVector","page":"References","title":"GenericTensorNetworks.StaticElementVector","text":"StaticElementVector{N,S,C}\nStaticElementVector(nflavor::Int, x::AbstractVector)\n\nN is the length of vector, C is the size of storage in unit of UInt64, S is the stride defined as the log2(# of flavors). When the number of flavors is 2, it is a StaticBitVector.\n\nFields\n\ndata is a tuple of UInt64 for storing the configuration of static elements.\n\nExamples\n\njulia> ev = StaticElementVector(3, [1,2,0,1,2])\n12012\n\njulia> ev[2]\n0x0000000000000002\n\njulia> collect(Int, ev)\n5-element Vector{Int64}:\n 1\n 2\n 0\n 1\n 2\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.OnehotVec","page":"References","title":"GenericTensorNetworks.OnehotVec","text":"OnehotVec{N,NF}\nOnehotVec{N,NF}(loc, val)\n\nOnehot vector type, N is the number of vector length, NF is the number of flavors.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GenericTensorNetworks.save_configs","page":"References","title":"GenericTensorNetworks.save_configs","text":"save_configs(filename, data::ConfigEnumerator; format=:binary)\n\nSave configurations data to file filename. The format is :binary or :text.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.load_configs","page":"References","title":"GenericTensorNetworks.load_configs","text":"load_configs(filename; format=:binary, bitlength=nothing, nflavors=2)\n\nLoad configurations from file filename. The format is :binary or :text. If the format is :binary, the bitstring length bitlength must be specified, nflavors specifies the degree of freedom.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.save_sumproduct","page":"References","title":"GenericTensorNetworks.save_sumproduct","text":"save_sumproduct(filename, t::SumProductTree)\n\nSerialize a sum-product tree into a file.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.load_sumproduct","page":"References","title":"GenericTensorNetworks.load_sumproduct","text":"load_sumproduct(filename)\n\nDeserialize a sum-product tree from a file.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.@bv_str","page":"References","title":"GenericTensorNetworks.@bv_str","text":"Constructing a static bit vector.\n\n\n\n\n\n","category":"macro"},{"location":"ref/#GenericTensorNetworks.onehotv","page":"References","title":"GenericTensorNetworks.onehotv","text":"onehotv(::Type{<:StaticElementVector}, i, v)\nonehotv(::Type{<:StaticBitVector, i)\n\nReturns a static element vector, with the value at location i being v (1 if not specified).\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.generate_samples","page":"References","title":"GenericTensorNetworks.generate_samples","text":"generate_samples(t::SumProductTree, nsamples::Int)\n\nDirect sampling configurations from a SumProductTree instance.\n\nExamples\n\njulia> using Graphs\n\njulia> g= smallgraph(:petersen)\n{10, 15} undirected simple Int64 graph\n\njulia> t = solve(IndependentSet(g), ConfigsAll(; tree_storage=true))[];\n\njulia> samples = generate_samples(t, 1000);\n\njulia> all(s->is_independent_set(g, s), samples)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.hamming_distribution","page":"References","title":"GenericTensorNetworks.hamming_distribution","text":"hamming_distribution(S, T)\n\nCompute the distribution of pair-wise Hamming distances, which is defined as:\n\nc(k) = sum_sigmain S tauin T delta(rm dist(sigma tau) k)\n\nwhere delta is a function that returns 1 if two arguments are equivalent, 0 otherwise, rm dist is the Hamming distance function.\n\nReturns the counting as a vector.\n\n\n\n\n\n","category":"function"},{"location":"ref/#Tensor-Network","page":"References","title":"Tensor Network","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"optimize_code\ngetixsv\ngetiyv\ncontraction_complexity\nestimate_memory\n@ein_str\nGreedyMethod\nTreeSA\nSABipartite\nKaHyParBipartite\nMergeVectors\nMergeGreedy","category":"page"},{"location":"ref/#OMEinsumContractionOrders.optimize_code","page":"References","title":"OMEinsumContractionOrders.optimize_code","text":"optimize_code(eincode, size_dict, optimizer = GreedyMethod(), simplifier=nothing, permute=true) -> optimized_eincode\n\nOptimize the einsum contraction code and reduce the time/space complexity of tensor network contraction. Returns a NestedEinsum instance. Input arguments are\n\neincode is an einsum contraction code instance, one of DynamicEinCode, StaticEinCode or NestedEinsum.\nsize is a dictionary of \"edge label=>edge size\" that contains the size information, one can use uniformsize(eincode, 2) to create a uniform size.\noptimizer is a CodeOptimizer instance, should be one of GreedyMethod, KaHyParBipartite, SABipartite or TreeSA. Check their docstrings for details.\nsimplifier is one of MergeVectors or MergeGreedy.\noptimize the permutation if permute is true.\n\nExamples\n\njulia> using OMEinsum\n\njulia> code = ein\"ij, jk, kl, il->\"\nij, jk, kl, il -> \n\njulia> optimize_code(code, uniformsize(code, 2), TreeSA())\nSlicedEinsum{Char, NestedEinsum{DynamicEinCode{Char}}}(Char[], ki, ki -> \n├─ jk, ij -> ki\n│ ├─ jk\n│ └─ ij\n└─ kl, il -> ki\n ├─ kl\n └─ il\n)\n\n\n\n\n\n","category":"function"},{"location":"ref/#OMEinsum.getixsv","page":"References","title":"OMEinsum.getixsv","text":"getixsv(code)\n\nGet labels of input tensors for EinCode, NestedEinsum and some other einsum like objects. Returns a vector of vectors.\n\njulia> getixsv(ein\"(ij,jk),k->i\")\n3-element Vector{Vector{Char}}:\n ['i', 'j']\n ['j', 'k']\n ['k']\n\n\n\n\n\n","category":"function"},{"location":"ref/#OMEinsum.getiyv","page":"References","title":"OMEinsum.getiyv","text":"getiy(code)\n\nGet labels of the output tensor for EinCode, NestedEinsum and some other einsum like objects. Returns a vector.\n\njulia> getiyv(ein\"(ij,jk),k->i\")\n1-element Vector{Char}:\n 'i': ASCII/Unicode U+0069 (category Ll: Letter, lowercase)\n\n\n\n\n\n","category":"function"},{"location":"ref/#OMEinsumContractionOrders.contraction_complexity","page":"References","title":"OMEinsumContractionOrders.contraction_complexity","text":"contraction_complexity(eincode, size_dict) -> ContractionComplexity\n\nReturns the time, space and read-write complexity of the einsum contraction. The returned object contains 3 fields:\n\ntime complexity tc defined as log2(number of element-wise multiplications).\nspace complexity sc defined as log2(size of the maximum intermediate tensor).\nread-write complexity rwc defined as log2(the number of read-write operations).\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.estimate_memory","page":"References","title":"GenericTensorNetworks.estimate_memory","text":"estimate_memory(\n problem::GraphProblem,\n property::GenericTensorNetworks.AbstractProperty;\n T\n) -> Any\n\n\nMemory estimation in number of bytes to compute certain property of a problem. T is the base type.\n\n\n\n\n\n","category":"function"},{"location":"ref/#OMEinsum.@ein_str","page":"References","title":"OMEinsum.@ein_str","text":"ein\"ij,jk -> ik\"(A,B)\n\nString macro interface which understands numpy.einsum's notation. Translates strings into StaticEinCode-structs that can be called to evaluate an einsum. To control evaluation order, use parentheses - instead of an EinCode, a NestedEinsum is returned which evaluates the expression according to parens. The valid character ranges for index-labels are a-z and α-ω.\n\nexample\n\njulia> a, b, c = rand(10,10), rand(10,10), rand(10,1);\n\njulia> ein\"ij,jk,kl -> il\"(a,b,c) ≈ ein\"(ij,jk),kl -> il\"(a,b,c) ≈ a * b * c\ntrue\n\n\n\n\n\n","category":"macro"},{"location":"ref/#OMEinsumContractionOrders.GreedyMethod","page":"References","title":"OMEinsumContractionOrders.GreedyMethod","text":"GreedyMethod{MT}\nGreedyMethod(; method=MinSpaceOut(), nrepeat=10)\n\nThe fast but poor greedy optimizer. Input arguments are\n\nmethod is MinSpaceDiff() or MinSpaceOut.\nMinSpaceOut choose one of the contraction that produces a minimum output tensor size,\nMinSpaceDiff choose one of the contraction that decrease the space most.\nnrepeat is the number of repeatition, returns the best contraction order.\n\n\n\n\n\n","category":"type"},{"location":"ref/#OMEinsumContractionOrders.TreeSA","page":"References","title":"OMEinsumContractionOrders.TreeSA","text":"TreeSA{RT,IT,GM}\nTreeSA(; sc_target=20, βs=collect(0.01:0.05:15), ntrials=10, niters=50,\n sc_weight=1.0, rw_weight=0.2, initializer=:greedy, greedy_config=GreedyMethod(; nrepeat=1))\n\nOptimize the einsum contraction pattern using the simulated annealing on tensor expression tree.\n\nsc_target is the target space complexity,\nntrials, βs and niters are annealing parameters, doing ntrials indepedent annealings, each has inverse tempteratures specified by βs, in each temperature, do niters updates of the tree.\nsc_weight is the relative importance factor of space complexity in the loss compared with the time complexity.\nrw_weight is the relative importance factor of memory read and write in the loss compared with the time complexity.\ninitializer specifies how to determine the initial configuration, it can be :greedy or :random. If it is using :greedy method to generate the initial configuration, it also uses two extra arguments greedy_method and greedy_nrepeat.\nnslices is the number of sliced legs, default is 0.\nfixed_slices is a vector of sliced legs, default is [].\n\nReferences\n\nRecursive Multi-Tensor Contraction for XEB Verification of Quantum Circuits\n\n\n\n\n\n","category":"type"},{"location":"ref/#OMEinsumContractionOrders.SABipartite","page":"References","title":"OMEinsumContractionOrders.SABipartite","text":"SABipartite{RT,BT}\nSABipartite(; sc_target=25, ntrials=50, βs=0.1:0.2:15.0, niters=1000\n max_group_size=40, greedy_config=GreedyMethod(), initializer=:random)\n\nOptimize the einsum code contraction order using the Simulated Annealing bipartition + Greedy approach. This program first recursively cuts the tensors into several groups using simulated annealing, with maximum group size specifed by max_group_size and maximum space complexity specified by sc_target, Then finds the contraction order inside each group with the greedy search algorithm. Other arguments are\n\nsize_dict, a dictionary that specifies leg dimensions,\nsc_target is the target space complexity, defined as log2(number of elements in the largest tensor),\nmax_group_size is the maximum size that allowed to used greedy search,\nβs is a list of inverse temperature 1/T,\nniters is the number of iteration in each temperature,\nntrials is the number of repetition (with different random seeds),\ngreedy_config configures the greedy method,\ninitializer, the partition configuration initializer, one can choose :random or :greedy (slow but better).\n\nReferences\n\nHyper-optimized tensor network contraction\n\n\n\n\n\n","category":"type"},{"location":"ref/#OMEinsumContractionOrders.KaHyParBipartite","page":"References","title":"OMEinsumContractionOrders.KaHyParBipartite","text":"KaHyParBipartite{RT,IT,GM}\nKaHyParBipartite(; sc_target, imbalances=collect(0.0:0.005:0.8),\n max_group_size=40, greedy_config=GreedyMethod())\n\nOptimize the einsum code contraction order using the KaHyPar + Greedy approach. This program first recursively cuts the tensors into several groups using KaHyPar, with maximum group size specifed by max_group_size and maximum space complexity specified by sc_target, Then finds the contraction order inside each group with the greedy search algorithm. Other arguments are\n\nsc_target is the target space complexity, defined as log2(number of elements in the largest tensor),\nimbalances is a KaHyPar parameter that controls the group sizes in hierarchical bipartition,\nmax_group_size is the maximum size that allowed to used greedy search,\ngreedy_config is a greedy optimizer.\n\nReferences\n\nHyper-optimized tensor network contraction\nSimulating the Sycamore quantum supremacy circuits\n\n\n\n\n\n","category":"type"},{"location":"ref/#OMEinsumContractionOrders.MergeVectors","page":"References","title":"OMEinsumContractionOrders.MergeVectors","text":"MergeVectors <: CodeSimplifier\nMergeVectors()\n\nContraction code simplifier (in order to reduce the time of calling optimizers) that merges vectors to closest tensors.\n\n\n\n\n\n","category":"type"},{"location":"ref/#OMEinsumContractionOrders.MergeGreedy","page":"References","title":"OMEinsumContractionOrders.MergeGreedy","text":"MergeGreedy <: CodeSimplifier\nMergeGreedy(; threshhold=-1e-12)\n\nContraction code simplifier (in order to reduce the time of calling optimizers) that merges tensors greedily if the space complexity of merged tensors is reduced (difference smaller than the threshhold).\n\n\n\n\n\n","category":"type"},{"location":"ref/#Others","page":"References","title":"Others","text":"","category":"section"},{"location":"ref/#Graph","page":"References","title":"Graph","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"show_graph\nshow_gallery\nshow_einsum\n\ndiagonal_coupled_graph\nsquare_lattice_graph\nunit_disk_graph\nline_graph\n\nrandom_diagonal_coupled_graph\nrandom_square_lattice_graph","category":"page"},{"location":"ref/#LuxorGraphPlot.show_graph","page":"References","title":"LuxorGraphPlot.show_graph","text":"show_graph([f, ]graph::SimpleGraph;\n locs=nothing,\n layout=:auto,\n optimal_distance=1.0,\n spring_mask=trues(nv(graph)),\n\n vertex_colors=nothing,\n vertex_sizes=nothing,\n vertex_stroke_colors=nothing,\n vertex_text_colors=nothing,\n edge_colors=nothing,\n texts = nothing,\n format=GraphDisplayConfig.format[],\n filename=nothing,\n kwargs...)\n\nShow a graph in VSCode, Pluto or Jupyter notebook, or save it to a file.\n\nPositional arguments\n\nf is a function that returns extra Luxor plotting statements.\ngraph is a graph instance.\n\nKeyword arguments\n\nlocs is a vector of tuples for specifying the vertex locations.\nlayout is one of [:auto, :spring, :stress], the default value is :spring if locs is nothing.\noptimal_distance is a optimal distance parameter for spring optimizer.\nspring_mask specfies which location is optimizable for spring optimizer.\nvertex_colors is a vector of color strings for specifying vertex fill colors.\nvertex_sizes is a vector of real numbers for specifying vertex sizes.\nvertex_shapes is a vector of strings for specifying vertex shapes, the string should be \"circle\" or \"box\".\nvertex_stroke_colors is a vector of color strings for specifying vertex stroke colors.\nvertex_text_colors is a vector of color strings for specifying vertex text colors.\nedge_colors is a vector of color strings for specifying edge colors.\ntexts is a vector of strings for labeling vertices.\nformat is the output format, which can be :svg, :png or :pdf.\nfilename is a string as the output filename.\n\nExtra keyword arguments\n\ngeneral\nxpad::Float64 = 1.0, the padding space in x direction\nypad::Float64 = 1.0, the padding space in y direction\nxpad_right::Float64 = 1.0, the padding space in x direction (right side)\nypad_bottom::Float64 = 1.0, the padding space in y direction (bottom side)\nbackground_color = DEFAULT_BACKGROUND_COLOR[], the background color\nunit::Float64 = DEFAULT_UNIT[], the unit distance as the number of pixels\nfontsize::Float64 = DEFAULT_FONTSIZE[], the font size\nfontface::String = \"\", the font face, leave empty to follow system\nvertex\nvertex_text_color = DEFAULT_VERTEX_TEXT_COLOR[], the default text color\nvertex_stroke_color = DEFAULT_VERTEX_STROKE_COLOR[], the default stroke color for vertices\nvertex_color = DEFAULT_VERTEX_FILL_COLOR[], the default default fill color for vertices\nvertex_size::Float64 = DEFAULT_VERTEX_SIZE[], the default vertex size\nvertex_shape::String = \"circle\", the default vertex shape, which can be \"circle\" or \"box\"\nvertex_line_width::Float64 = 1, the default vertex stroke line width\nvertex_line_style::String = \"solid\", the line style of vertex stroke, which can be one of [\"solid\", \"dotted\", \"dot\", \"dotdashed\", \"longdashed\", \"shortdashed\", \"dash\", \"dashed\", \"dotdotdashed\", \"dotdotdotdashed\"]\nedge\nedge_color = DEFAULT_EDGE_COLOR[], the default edge color\nedge_line_width::Float64 = 1, the default line width\nedge_style::String = \"solid\", the line style of edges, which can be one of [\"solid\", \"dotted\", \"dot\", \"dotdashed\", \"longdashed\", \"shortdashed\", \"dash\", \"dashed\", \"dotdotdashed\", \"dotdotdotdashed\"]\n\nExample\n\njulia> using Graphs\n\njulia> show_graph(smallgraph(:petersen); format=:png, vertex_colors=rand([\"blue\", \"red\"], 10));\n\n\n\n\n\n","category":"function"},{"location":"ref/#LuxorGraphPlot.show_gallery","page":"References","title":"LuxorGraphPlot.show_gallery","text":"show_gallery([f, ]graph::SimpleGraph, grid::Tuple{Int,Int};\n locs=nothing,\n layout=:auto,\n optimal_distance=1.0,\n spring_mask=trues(nv(graph)),\n\n vertex_configs=nothing,\n edge_configs=nothing,\n vertex_color=nothing,\n edge_color=nothing,\n\n vertex_sizes=nothing,\n vertex_shapes=nothing,\n vertex_stroke_colors=nothing,\n vertex_text_colors=nothing,\n texts=nothing,\n xpad=1.0,\n ypad=1.0,\n format=GraphDisplayConfig.format[],\n filename=nothing,\n kwargs...)\n\nShow a gallery of graphs for multiple vertex configurations or edge configurations in VSCode, Pluto or Jupyter notebook, or save it to a file.\n\nPositional arguments\n\nf is a function that returns extra Luxor plotting statements.\ngraph is a graph instance.\ngrid is the grid layout of the gallery, e.g. input value (2, 3) means a grid layout with 2 rows and 3 columns.\n\nKeyword arguments\n\nlocs is a vector of tuples for specifying the vertex locations.\nlayout is one of [:auto, :spring, :stress], the default value is :spring if locs is nothing.\noptimal_distance is a optimal distance parameter for spring optimizer.\nspring_mask specfies which location is optimizable for spring optimizer.\nvertex_configs is an iterator of bit strings for specifying vertex configurations. It will be rendered as vertex colors.\nedge_configs is an iterator of bit strings for specifying edge configurations. It will be rendered as edge colors.\nedge_color is a dictionary that specifies the edge configuration - color map.\nvertex_color is a dictionary that specifies the vertex configuration - color map.\nvertex_sizes is a vector of real numbers for specifying vertex sizes.\nvertex_shapes is a vector of strings for specifying vertex shapes, the string should be \"circle\" or \"box\".\nvertex_stroke_colors is a vector of color strings for specifying vertex stroke colors.\nvertex_text_colors is a vector of color strings for specifying vertex text colors.\ntexts is a vector of strings for labeling vertices.\nxpad is the space between two adjacent plots in x direction.\nypad is the space between two adjacent plots in y direction.\nformat is the output format, which can be :svg, :png or :pdf.\nfilename is a string as the output filename.\n\nExtra keyword arguments\n\ngeneral\nxpad::Float64 = 1.0, the padding space in x direction\nypad::Float64 = 1.0, the padding space in y direction\nxpad_right::Float64 = 1.0, the padding space in x direction (right side)\nypad_bottom::Float64 = 1.0, the padding space in y direction (bottom side)\nbackground_color = DEFAULT_BACKGROUND_COLOR[], the background color\nunit::Float64 = DEFAULT_UNIT[], the unit distance as the number of pixels\nfontsize::Float64 = DEFAULT_FONTSIZE[], the font size\nfontface::String = \"\", the font face, leave empty to follow system\nvertex\nvertex_text_color = DEFAULT_VERTEX_TEXT_COLOR[], the default text color\nvertex_stroke_color = DEFAULT_VERTEX_STROKE_COLOR[], the default stroke color for vertices\nvertex_color = DEFAULT_VERTEX_FILL_COLOR[], the default default fill color for vertices\nvertex_size::Float64 = DEFAULT_VERTEX_SIZE[], the default vertex size\nvertex_shape::String = \"circle\", the default vertex shape, which can be \"circle\" or \"box\"\nvertex_line_width::Float64 = 1, the default vertex stroke line width\nvertex_line_style::String = \"solid\", the line style of vertex stroke, which can be one of [\"solid\", \"dotted\", \"dot\", \"dotdashed\", \"longdashed\", \"shortdashed\", \"dash\", \"dashed\", \"dotdotdashed\", \"dotdotdotdashed\"]\nedge\nedge_color = DEFAULT_EDGE_COLOR[], the default edge color\nedge_line_width::Float64 = 1, the default line width\nedge_style::String = \"solid\", the line style of edges, which can be one of [\"solid\", \"dotted\", \"dot\", \"dotdashed\", \"longdashed\", \"shortdashed\", \"dash\", \"dashed\", \"dotdotdashed\", \"dotdotdotdashed\"]\n\nExample\n\njulia> using Graphs\n\njulia> show_gallery(smallgraph(:petersen), (2, 3); format=:png, vertex_configs=[rand(Bool, 10) for k=1:6]);\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.show_einsum","page":"References","title":"GenericTensorNetworks.show_einsum","text":"show_einsum(ein::AbstractEinsum;\n tensor_locs=nothing,\n label_locs=nothing, # dict\n spring::Bool=true,\n optimal_distance=1.0,\n\n tensor_size=0.3,\n tensor_color=\"black\",\n tensor_text_color=\"white\",\n annotate_tensors=false,\n\n label_size=0.15,\n label_color=\"black\",\n open_label_color=\"red\",\n annotate_labels=true,\n kwargs...\n )\n\nPositional arguments\n\nein is an Einsum contraction code (provided by package OMEinsum).\n\nKeyword arguments\n\ntensor_locs is a vector of tuples for specifying the vertex locations.\nlabel_locs is a vector of tuples for specifying the vertex locations.\nspring is switch to use spring method to optimize the location.\noptimal_distance is a optimal distance parameter for spring optimizer.\ntensor_color is a string to specify the color of tensor nodes.\ntensor_size is a real number to specify the size of tensor nodes.\ntensor_text_color is a color strings to specify tensor text color.\nannotate_tensors is a boolean switch for annotate different tensors by integers.\nlabel_size is a real number to specify label text node size.\nlabel_color is a color strings to specify label text color.\nopen_label_color is a color strings to specify open label text color.\nannotate_labels is a boolean switch for annotate different labels.\nformat is the output format, which can be :svg, :png or :pdf.\nfilename is a string as the output filename.\n\nExtra keyword arguments\n\ngeneral\nxpad::Float64 = 1.0, the padding space in x direction\nypad::Float64 = 1.0, the padding space in y direction\nxpad_right::Float64 = 1.0, the padding space in x direction (right side)\nypad_bottom::Float64 = 1.0, the padding space in y direction (bottom side)\nbackground_color = DEFAULT_BACKGROUND_COLOR[], the background color\nunit::Float64 = DEFAULT_UNIT[], the unit distance as the number of pixels\nfontsize::Float64 = DEFAULT_FONTSIZE[], the font size\nfontface::String = \"\", the font face, leave empty to follow system\nvertex\nvertex_text_color = DEFAULT_VERTEX_TEXT_COLOR[], the default text color\nvertex_stroke_color = DEFAULT_VERTEX_STROKE_COLOR[], the default stroke color for vertices\nvertex_color = DEFAULT_VERTEX_FILL_COLOR[], the default default fill color for vertices\nvertex_size::Float64 = DEFAULT_VERTEX_SIZE[], the default vertex size\nvertex_shape::String = \"circle\", the default vertex shape, which can be \"circle\" or \"box\"\nvertex_line_width::Float64 = 1, the default vertex stroke line width\nvertex_line_style::String = \"solid\", the line style of vertex stroke, which can be one of [\"solid\", \"dotted\", \"dot\", \"dotdashed\", \"longdashed\", \"shortdashed\", \"dash\", \"dashed\", \"dotdotdashed\", \"dotdotdotdashed\"]\nedge\nedge_color = DEFAULT_EDGE_COLOR[], the default edge color\nedge_line_width::Float64 = 1, the default line width\nedge_style::String = \"solid\", the line style of edges, which can be one of [\"solid\", \"dotted\", \"dot\", \"dotdashed\", \"longdashed\", \"shortdashed\", \"dash\", \"dashed\", \"dotdotdashed\", \"dotdotdotdashed\"]\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.diagonal_coupled_graph","page":"References","title":"GenericTensorNetworks.diagonal_coupled_graph","text":"diagonal_coupled_graph(mask::AbstractMatrix{Bool})\n\nCreate a masked diagonal coupled square lattice graph from a specified mask.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.square_lattice_graph","page":"References","title":"GenericTensorNetworks.square_lattice_graph","text":"square_lattice_graph(mask::AbstractMatrix{Bool})\n\nCreate a masked square lattice graph.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.unit_disk_graph","page":"References","title":"GenericTensorNetworks.unit_disk_graph","text":"unit_disk_graph(locs::AbstractVector, unit::Real)\n\nCreate a unit disk graph with locations specified by locs and unit distance unit.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.line_graph","page":"References","title":"GenericTensorNetworks.line_graph","text":"line_graph(g::SimpleGraph)\n\nReturns the line graph of g. The line graph is generated by mapping an edge to a vertex and two edges sharing a common vertex will be connected.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.random_diagonal_coupled_graph","page":"References","title":"GenericTensorNetworks.random_diagonal_coupled_graph","text":"random_diagonal_coupled_graph(m::Int, n::Int, ρ::Real)\n\nCreate a mtimes n random masked diagonal coupled square lattice graph, with number of vertices equal to lfloor m times ntimes rho rceil.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GenericTensorNetworks.random_square_lattice_graph","page":"References","title":"GenericTensorNetworks.random_square_lattice_graph","text":"random_square_lattice_graph(m::Int, n::Int, ρ::Real)\n\nCreate a random masked square lattice graph, with number of vertices fixed to lfloor mnrho rceil.\n\n\n\n\n\n","category":"function"},{"location":"ref/","page":"References","title":"References","text":"One can also use random_regular_graph and smallgraph in Graphs to build special graphs.","category":"page"},{"location":"ref/#Multiprocessing","page":"References","title":"Multiprocessing","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"GenericTensorNetworks.SimpleMultiprocessing.multiprocess_run","category":"page"},{"location":"ref/#GenericTensorNetworks.SimpleMultiprocessing.multiprocess_run","page":"References","title":"GenericTensorNetworks.SimpleMultiprocessing.multiprocess_run","text":"multiprocess_run(func, inputs::AbstractVector)\n\nExecute function func on inputs with multiple processing.\n\nExample\n\nSuppose we have a file run.jl with the following contents\n\nusing GenericTensorNetworks.SimpleMultiprocessing\n\nresults = multiprocess_run(x->x^2, randn(8))\n\nIn an terminal, you may run the script with 4 processes by typing\n\n$ julia -p4 run.jl\n From worker 2:\t[ Info: running argument -0.17544008350172655 on device 2\n From worker 5:\t[ Info: running argument 0.34578117779452555 on device 5\n From worker 3:\t[ Info: running argument 2.0312551239727705 on device 3\n From worker 4:\t[ Info: running argument -0.7319353419291961 on device 4\n From worker 2:\t[ Info: running argument 0.013132180639054629 on device 2\n From worker 3:\t[ Info: running argument 0.9960101782201602 on device 3\n From worker 4:\t[ Info: running argument -0.5613942832743966 on device 4\n From worker 5:\t[ Info: running argument 0.39460402723831134 on device 5\n\n\n\n\n\n","category":"function"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = GenericTensorNetworks","category":"page"},{"location":"#GenericTensorNetworks","page":"Home","title":"GenericTensorNetworks","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"This package implements generic tensor networks to compute solution space properties of a class of hard combinatorial problems. The solution space properties include","category":"page"},{"location":"","page":"Home","title":"Home","text":"The maximum/minimum solution sizes,\nThe number of solutions at certain sizes,\nThe enumeration of solutions at certain sizes.\nThe direct sampling of solutions at certain sizes.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The solvable problems include Independent set problem, Maximal independent set problem, Spin-glass problem, Cutting problem, Vertex matching problem, Binary paint shop problem, Coloring problem, Dominating set problem, Satisfiability problem, Set packing problem and Set covering problem.","category":"page"},{"location":"#Background-knowledge","page":"Home","title":"Background knowledge","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Please check our paper \"Computing properties of independent sets by generic programming tensor networks\". If you find our paper or software useful in your work, we would be grateful if you could cite our work. The CITATION.bib file in the root of this repository lists the relevant papers.","category":"page"},{"location":"#Quick-start","page":"Home","title":"Quick start","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"You can find a set up guide in our README. To get started, open a Julia REPL and type the following code.","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> using GenericTensorNetworks, Graphs\n\njulia> # using CUDA\n\njulia> solve(\n IndependentSet(\n Graphs.random_regular_graph(20, 3);\n optimizer = TreeSA(),\n weights = NoWeight(), # default: uniform weight 1\n openvertices = (), # default: no open vertices\n fixedvertices = Dict() # default: no fixed vertices\n ),\n GraphPolynomial();\n usecuda=false # the default value\n )\n0-dimensional Array{Polynomial{BigInt, :x}, 0}:\nPolynomial(1 + 20*x + 160*x^2 + 659*x^3 + 1500*x^4 + 1883*x^5 + 1223*x^6 + 347*x^7 + 25*x^8)","category":"page"},{"location":"","page":"Home","title":"Home","text":"Here the main function solve takes three input arguments, the problem instance of type IndependentSet, the property instance of type GraphPolynomial and an optional key word argument usecuda to decide use GPU or not. If one wants to use GPU to accelerate the computation, the using CUDA statement must uncommented.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The problem instance takes four arguments to initialize, the only positional argument is the graph instance that one wants to solve, the key word argument optimizer is for specifying the tensor network optimization algorithm, the key word argument weights is for specifying the weights of vertices as either a vector or NoWeight(). The keyword argument openvertices is a tuple of labels for specifying the degrees of freedom not summed over, and fixedvertices is a label-value dictionary for specifying the fixed values of the degree of freedoms. Here, we use TreeSA method as the tensor network optimizer, and leave weights and openvertices the default values. The TreeSA method finds the best contraction order in most of our applications, while the default GreedyMethod runs the fastest.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The first execution of this function will be a bit slow due to Julia's just in time compiling. The subsequent runs will be fast. The following diagram lists possible combinations of input arguments, where functions in the Graph are mainly defined in the package Graphs, and the rest can be found in this package.","category":"page"},{"location":"","page":"Home","title":"Home","text":"
\n\n
","category":"page"},{"location":"","page":"Home","title":"Home","text":"⠀ You can find many examples in this documentation, a good one to start with is Independent set problem.","category":"page"}] } diff --git a/dev/sumproduct/index.html b/dev/sumproduct/index.html index ed73b36b..cb260e63 100644 --- a/dev/sumproduct/index.html +++ b/dev/sumproduct/index.html @@ -24,4 +24,4 @@ │⠀⠀⠀⠀⠀⠀⠀⠀⢠⠇⠀⠀⠀⠀⠀⠀⠀⢳⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ 0 │⢀⣀⣀⣀⣀⣀⣀⣀⠎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠓⢄⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⠀⠀⠀⠀│ └────────────────────────────────────────┘ - ⠀0⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀80⠀

Here, the $x$-axis is the Hamming distance and the $y$-axis is the counting of pair-wise Hamming distances.

+ ⠀0⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀80⠀

Here, the $x$-axis is the Hamming distance and the $y$-axis is the counting of pair-wise Hamming distances.