diff --git a/stable b/stable index 678367c..3f0fd6b 120000 --- a/stable +++ b/stable @@ -1 +1 @@ -v0.1.7 \ No newline at end of file +v0.1.8 \ No newline at end of file diff --git a/v0.1 b/v0.1 index 678367c..3f0fd6b 120000 --- a/v0.1 +++ b/v0.1 @@ -1 +1 @@ -v0.1.7 \ No newline at end of file +v0.1.8 \ No newline at end of file diff --git a/v0.1.8/.documenter-siteinfo.json b/v0.1.8/.documenter-siteinfo.json new file mode 100644 index 0000000..32a7753 --- /dev/null +++ b/v0.1.8/.documenter-siteinfo.json @@ -0,0 +1 @@ +{"documenter":{"julia_version":"1.10.4","generation_timestamp":"2024-06-12T12:48:32","documenter_version":"1.4.1"}} \ No newline at end of file diff --git a/v0.1.8/assets/documenter.js b/v0.1.8/assets/documenter.js new file mode 100644 index 0000000..c6562b5 --- /dev/null +++ b/v0.1.8/assets/documenter.js @@ -0,0 +1,1050 @@ +// Generated by Documenter.jl +requirejs.config({ + paths: { + 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/julia.min', + 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/headroom.min', + 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min', + 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.8/contrib/auto-render.min', + 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min', + 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/jQuery.headroom.min', + 'katex': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.8/katex.min', + 'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min', + 'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/julia-repl.min', + }, + shim: { + "highlight-julia": { + "deps": [ + "highlight" + ] + }, + "katex-auto-render": { + "deps": [ + "katex" + ] + }, + "headroom-jquery": { + "deps": [ + "jquery", + "headroom" + ] + }, + "highlight-julia-repl": { + "deps": [ + "highlight" + ] + } +} +}); +//////////////////////////////////////////////////////////////////////////////// +require(['jquery', 'katex', 'katex-auto-render'], function($, katex, renderMathInElement) { +$(document).ready(function() { + renderMathInElement( + document.body, + { + "delimiters": [ + { + "left": "$", + "right": "$", + "display": false + }, + { + "left": "$$", + "right": "$$", + "display": true + }, + { + "left": "\\[", + "right": "\\]", + "display": true + } + ] +} + + ); +}) + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl'], function($) { +$(document).ready(function() { + hljs.highlightAll(); +}) + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +let timer = 0; +var isExpanded = true; + +$(document).on("click", ".docstring header", function () { + let articleToggleTitle = "Expand docstring"; + + 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"; + } + + $(this) + .find(".docstring-article-toggle-button") + .prop("title", articleToggleTitle); + $(this).siblings("section").slideToggle(); + }); +}); + +$(document).on("click", ".docs-article-toggle-button", function (event) { + let articleToggleTitle = "Expand docstring"; + let navArticleToggleTitle = "Expand all docstrings"; + let animationSpeed = event.noToggleAnimation ? 0 : 400; + + 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; + + $(".docstring section").slideUp(animationSpeed); + } 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"; + + $(".docstring section").slideDown(animationSpeed); + } + + $(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() { +function addCopyButtonCallbacks() { + for (const el of document.getElementsByTagName("pre")) { + const button = document.createElement("button"); + button.classList.add("copy-button", "fa-solid", "fa-copy"); + button.setAttribute("aria-label", "Copy this code block"); + button.setAttribute("title", "Copy"); + + el.appendChild(button); + + const success = function () { + button.classList.add("success", "fa-check"); + button.classList.remove("fa-copy"); + }; + + const failure = function () { + button.classList.add("error", "fa-xmark"); + button.classList.remove("fa-copy"); + }; + + button.addEventListener("click", function () { + copyToClipboard(el.innerText).then(success, failure); + + setTimeout(function () { + button.classList.add("fa-copy"); + button.classList.remove("success", "fa-check", "fa-xmark"); + }, 5000); + }); + } +} + +function copyToClipboard(text) { + // clipboard API is only available in secure contexts + if (window.navigator && window.navigator.clipboard) { + return window.navigator.clipboard.writeText(text); + } else { + return new Promise(function (resolve, reject) { + try { + const el = document.createElement("textarea"); + el.textContent = text; + el.style.position = "fixed"; + el.style.opacity = 0; + document.body.appendChild(el); + el.select(); + document.execCommand("copy"); + + resolve(); + } catch (err) { + reject(err); + } finally { + document.body.removeChild(el); + } + }); + } +} + +if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", addCopyButtonCallbacks); +} else { + addCopyButtonCallbacks(); +} + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery', 'headroom', 'headroom-jquery'], function($, Headroom) { + +// Manages the top navigation bar (hides it when the user starts scrolling down on the +// mobile). +window.Headroom = Headroom; // work around buggy module loading? +$(document).ready(function () { + $("#documenter .docs-navbar").headroom({ + tolerance: { up: 10, down: 10 }, + }); +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +$(document).ready(function () { + let meta = $("div[data-docstringscollapsed]").data(); + + if (meta?.docstringscollapsed) { + $("#documenter-article-toggle-button").trigger({ + type: "click", + noToggleAnimation: true, + }); + } +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +/* +To get an in-depth about the thought process you can refer: https://hetarth02.hashnode.dev/series/gsoc + +PSEUDOCODE: + +Searching happens automatically as the user types or adjusts the selected filters. +To preserve responsiveness, as much as possible of the slow parts of the search are done +in a web worker. Searching and result generation are done in the worker, and filtering and +DOM updates are done in the main thread. The filters are in the main thread as they should +be very quick to apply. This lets filters be changed without re-searching with minisearch +(which is possible even if filtering is on the worker thread) and also lets filters be +changed _while_ the worker is searching and without message passing (neither of which are +possible if filtering is on the worker thread) + +SEARCH WORKER: + +Import minisearch + +Build index + +On message from main thread + run search + find the first 200 unique results from each category, and compute their divs for display + note that this is necessary and sufficient information for the main thread to find the + first 200 unique results from any given filter set + post results to main thread + +MAIN: + +Launch worker + +Declare nonconstant globals (worker_is_running, last_search_text, unfiltered_results) + +On text update + if worker is not running, launch_search() + +launch_search + set worker_is_running to true, set last_search_text to the search text + post the search query to worker + +on message from worker + if last_search_text is not the same as the text in the search field, + the latest search result is not reflective of the latest search query, so update again + launch_search() + otherwise + set worker_is_running to false + + regardless, display the new search results to the user + save the unfiltered_results as a global + update_search() + +on filter click + adjust the filter selection + update_search() + +update_search + apply search filters by looping through the unfiltered_results and finding the first 200 + unique results that match the filters + + Update the DOM +*/ + +/////// SEARCH WORKER /////// + +function worker_function(documenterSearchIndex, documenterBaseURL, filters) { + importScripts( + "https://cdn.jsdelivr.net/npm/minisearch@6.1.0/dist/umd/index.min.js" + ); + + let data = documenterSearchIndex.map((x, key) => { + x["id"] = key; // minisearch requires a unique for each object + return x; + }); + + // list below is the lunr 2.1.3 list minus the intersect with names(Base) + // (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with) + // ideally we'd just filter the original list but it's not available as a variable + const stopWords = new Set([ + "a", + "able", + "about", + "across", + "after", + "almost", + "also", + "am", + "among", + "an", + "and", + "are", + "as", + "at", + "be", + "because", + "been", + "but", + "by", + "can", + "cannot", + "could", + "dear", + "did", + "does", + "either", + "ever", + "every", + "from", + "got", + "had", + "has", + "have", + "he", + "her", + "hers", + "him", + "his", + "how", + "however", + "i", + "if", + "into", + "it", + "its", + "just", + "least", + "like", + "likely", + "may", + "me", + "might", + "most", + "must", + "my", + "neither", + "no", + "nor", + "not", + "of", + "off", + "often", + "on", + "or", + "other", + "our", + "own", + "rather", + "said", + "say", + "says", + "she", + "should", + "since", + "so", + "some", + "than", + "that", + "the", + "their", + "them", + "then", + "there", + "these", + "they", + "this", + "tis", + "to", + "too", + "twas", + "us", + "wants", + "was", + "we", + "were", + "what", + "when", + "who", + "whom", + "why", + "will", + "would", + "yet", + "you", + "your", + ]); + + let index = new MiniSearch({ + fields: ["title", "text"], // fields to index for full-text search + storeFields: ["location", "title", "text", "category", "page"], // fields to return with results + processTerm: (term) => { + let word = stopWords.has(term) ? null : term; + if (word) { + // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names + word = word + .replace(/^[^a-zA-Z0-9@!]+/, "") + .replace(/[^a-zA-Z0-9@!]+$/, ""); + + word = word.toLowerCase(); + } + + return word ?? null; + }, + // add . as a separator, because otherwise "title": "Documenter.Anchors.add!", would not + // find anything if searching for "add!", only for the entire qualification + tokenize: (string) => string.split(/[\s\-\.]+/), + // options which will be applied during the search + searchOptions: { + prefix: true, + boost: { title: 100 }, + fuzzy: 2, + }, + }); + + index.addAll(data); + + /** + * Used to map characters to HTML entities. + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + const htmlEscapes = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + }; + + /** + * Used to match HTML entities and HTML characters. + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + const reUnescapedHtml = /[&<>"']/g; + const reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** + * Escape function from lodash + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + function escape(string) { + return string && reHasUnescapedHtml.test(string) + ? string.replace(reUnescapedHtml, (chr) => htmlEscapes[chr]) + : string || ""; + } + + /** + * Make the result component given a minisearch result data object and the value + * of the search input as queryString. To view the result object structure, refer: + * https://lucaong.github.io/minisearch/modules/_minisearch_.html#searchresult + * + * @param {object} result + * @param {string} querystring + * @returns string + */ + function make_search_result(result, querystring) { + let search_divider = `
`; + let display_link = + result.location.slice(Math.max(0), Math.min(50, result.location.length)) + + (result.location.length > 30 ? "..." : ""); // To cut-off the link because it messes with the overflow of the whole div + + if (result.page !== "") { + display_link += ` (${result.page})`; + } + + let textindex = new RegExp(`${querystring}`, "i").exec(result.text); + let text = + textindex !== null + ? result.text.slice( + Math.max(textindex.index - 100, 0), + Math.min( + textindex.index + querystring.length + 100, + result.text.length + ) + ) + : ""; // cut-off text before and after from the match + + text = text.length ? escape(text) : ""; + + let display_result = text.length + ? "..." + + text.replace( + new RegExp(`${escape(querystring)}`, "i"), // For first occurrence + '$&' + ) + + "..." + : ""; // highlights the match + + let in_code = false; + if (!["page", "section"].includes(result.category.toLowerCase())) { + in_code = true; + } + + // We encode the full url to escape some special characters which can lead to broken links + let result_div = ` + +
+
${escape(result.title)}
+
${result.category}
+
+

+ ${display_result} +

+
+ ${display_link} +
+
+ ${search_divider} + `; + + return result_div; + } + + self.onmessage = function (e) { + let query = e.data; + let results = index.search(query, { + filter: (result) => { + // Only return relevant results + return result.score >= 1; + }, + }); + + // Pre-filter to deduplicate and limit to 200 per category to the extent + // possible without knowing what the filters are. + let filtered_results = []; + let counts = {}; + for (let filter of filters) { + counts[filter] = 0; + } + let present = {}; + + for (let result of results) { + cat = result.category; + cnt = counts[cat]; + if (cnt < 200) { + id = cat + "---" + result.location; + if (present[id]) { + continue; + } + present[id] = true; + filtered_results.push({ + location: result.location, + category: cat, + div: make_search_result(result, query), + }); + } + } + + postMessage(filtered_results); + }; +} + +// `worker = Threads.@spawn worker_function(documenterSearchIndex)`, but in JavaScript! +const filters = [ + ...new Set(documenterSearchIndex["docs"].map((x) => x.category)), +]; +const worker_str = + "(" + + worker_function.toString() + + ")(" + + JSON.stringify(documenterSearchIndex["docs"]) + + "," + + JSON.stringify(documenterBaseURL) + + "," + + JSON.stringify(filters) + + ")"; +const worker_blob = new Blob([worker_str], { type: "text/javascript" }); +const worker = new Worker(URL.createObjectURL(worker_blob)); + +/////// SEARCH MAIN /////// + +// Whether the worker is currently handling a search. This is a boolean +// as the worker only ever handles 1 or 0 searches at a time. +var worker_is_running = false; + +// The last search text that was sent to the worker. This is used to determine +// if the worker should be launched again when it reports back results. +var last_search_text = ""; + +// The results of the last search. This, in combination with the state of the filters +// in the DOM, is used compute the results to display on calls to update_search. +var unfiltered_results = []; + +// Which filter is currently selected +var selected_filter = ""; + +$(document).on("input", ".documenter-search-input", function (event) { + if (!worker_is_running) { + launch_search(); + } +}); + +function launch_search() { + worker_is_running = true; + last_search_text = $(".documenter-search-input").val(); + worker.postMessage(last_search_text); +} + +worker.onmessage = function (e) { + if (last_search_text !== $(".documenter-search-input").val()) { + launch_search(); + } else { + worker_is_running = false; + } + + unfiltered_results = e.data; + update_search(); +}; + +$(document).on("click", ".search-filter", function () { + if ($(this).hasClass("search-filter-selected")) { + selected_filter = ""; + } else { + selected_filter = $(this).text().toLowerCase(); + } + + // This updates search results and toggles classes for UI: + update_search(); +}); + +/** + * Make/Update the search component + */ +function update_search() { + let querystring = $(".documenter-search-input").val(); + + if (querystring.trim()) { + if (selected_filter == "") { + results = unfiltered_results; + } else { + results = unfiltered_results.filter((result) => { + return selected_filter == result.category.toLowerCase(); + }); + } + + let search_result_container = ``; + let modal_filters = make_modal_body_filters(); + let search_divider = `
`; + + if (results.length) { + let links = []; + let count = 0; + let search_results = ""; + + for (var i = 0, n = results.length; i < n && count < 200; ++i) { + let result = results[i]; + if (result.location && !links.includes(result.location)) { + search_results += result.div; + count++; + links.push(result.location); + } + } + + if (count == 1) { + count_str = "1 result"; + } else if (count == 200) { + count_str = "200+ results"; + } else { + count_str = count + " results"; + } + let result_count = `
${count_str}
`; + + search_result_container = ` +
+ ${modal_filters} + ${search_divider} + ${result_count} +
+ ${search_results} +
+
+ `; + } else { + search_result_container = ` +
+ ${modal_filters} + ${search_divider} +
0 result(s)
+
+
No result found!
+ `; + } + + if ($(".search-modal-card-body").hasClass("is-justify-content-center")) { + $(".search-modal-card-body").removeClass("is-justify-content-center"); + } + + $(".search-modal-card-body").html(search_result_container); + } else { + if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) { + $(".search-modal-card-body").addClass("is-justify-content-center"); + } + + $(".search-modal-card-body").html(` +
Type something to get started!
+ `); + } +} + +/** + * Make the modal filter html + * + * @returns string + */ +function make_modal_body_filters() { + let str = filters + .map((val) => { + if (selected_filter == val.toLowerCase()) { + return `${val}`; + } else { + return `${val}`; + } + }) + .join(""); + + return ` +
+ Filters: + ${str} +
`; +} + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +// Modal settings dialog +$(document).ready(function () { + var settings = $("#documenter-settings"); + $("#documenter-settings-button").click(function () { + settings.toggleClass("is-active"); + }); + // Close the dialog if X is clicked + $("#documenter-settings button.delete").click(function () { + settings.removeClass("is-active"); + }); + // Close dialog if ESC is pressed + $(document).keyup(function (e) { + if (e.keyCode == 27) settings.removeClass("is-active"); + }); +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +$(document).ready(function () { + let search_modal_header = ` + + `; + + let initial_search_body = ` +
Type something to get started!
+ `; + + let search_modal_footer = ` + + `; + + $(document.body).append( + ` + + ` + ); + + document.querySelector(".docs-search-query").addEventListener("click", () => { + openModal(); + }); + + document + .querySelector(".close-search-modal") + .addEventListener("click", () => { + closeModal(); + }); + + $(document).on("click", ".search-result-link", function () { + closeModal(); + }); + + document.addEventListener("keydown", (event) => { + if ((event.ctrlKey || event.metaKey) && event.key === "/") { + openModal(); + } else if (event.key === "Escape") { + closeModal(); + } + + return false; + }); + + // Functions to open and close a modal + function openModal() { + let searchModal = document.querySelector("#search-modal"); + + searchModal.classList.add("is-active"); + document.querySelector(".documenter-search-input").focus(); + } + + function closeModal() { + let searchModal = document.querySelector("#search-modal"); + let initial_search_body = ` +
Type something to get started!
+ `; + + searchModal.classList.remove("is-active"); + document.querySelector(".documenter-search-input").blur(); + + if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) { + $(".search-modal-card-body").addClass("is-justify-content-center"); + } + + $(".documenter-search-input").val(""); + $(".search-modal-card-body").html(initial_search_body); + } + + document + .querySelector("#search-modal .modal-background") + .addEventListener("click", () => { + closeModal(); + }); +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +// Manages the showing and hiding of the sidebar. +$(document).ready(function () { + var sidebar = $("#documenter > .docs-sidebar"); + var sidebar_button = $("#documenter-sidebar-button"); + sidebar_button.click(function (ev) { + ev.preventDefault(); + sidebar.toggleClass("visible"); + if (sidebar.hasClass("visible")) { + // Makes sure that the current menu item is visible in the sidebar. + $("#documenter .docs-menu a.is-active").focus(); + } + }); + $("#documenter > .docs-main").bind("click", function (ev) { + if ($(ev.target).is(sidebar_button)) { + return; + } + if (sidebar.hasClass("visible")) { + sidebar.removeClass("visible"); + } + }); +}); + +// Resizes the package name / sitename in the sidebar if it is too wide. +// Inspired by: https://github.com/davatron5000/FitText.js +$(document).ready(function () { + e = $("#documenter .docs-autofit"); + function resize() { + var L = parseInt(e.css("max-width"), 10); + var L0 = e.width(); + if (L0 > L) { + var h0 = parseInt(e.css("font-size"), 10); + e.css("font-size", (L * h0) / L0); + // TODO: make sure it survives resizes? + } + } + // call once and then register events + resize(); + $(window).resize(resize); + $(window).on("orientationchange", resize); +}); + +// Scroll the navigation bar to the currently selected menu item +$(document).ready(function () { + var sidebar = $("#documenter .docs-menu").get(0); + var active = $("#documenter .docs-menu .is-active").get(0); + if (typeof active !== "undefined") { + sidebar.scrollTop = active.offsetTop - sidebar.offsetTop - 15; + } +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +// Theme picker setup +$(document).ready(function () { + // onchange callback + $("#documenter-themepicker").change(function themepick_callback(ev) { + var themename = $("#documenter-themepicker option:selected").attr("value"); + if (themename === "auto") { + // set_theme(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'); + window.localStorage.removeItem("documenter-theme"); + } else { + // set_theme(themename); + window.localStorage.setItem("documenter-theme", themename); + } + // We re-use the global function from themeswap.js to actually do the swapping. + set_theme_from_local_storage(); + }); + + // Make sure that the themepicker displays the correct theme when the theme is retrieved + // from localStorage + if (typeof window.localStorage !== "undefined") { + var theme = window.localStorage.getItem("documenter-theme"); + if (theme !== null) { + $("#documenter-themepicker option").each(function (i, e) { + e.selected = e.value === theme; + }); + } + } +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +// update the version selector with info from the siteinfo.js and ../versions.js files +$(document).ready(function () { + // If the version selector is disabled with DOCUMENTER_VERSION_SELECTOR_DISABLED in the + // siteinfo.js file, we just return immediately and not display the version selector. + if ( + typeof DOCUMENTER_VERSION_SELECTOR_DISABLED === "boolean" && + DOCUMENTER_VERSION_SELECTOR_DISABLED + ) { + return; + } + + var version_selector = $("#documenter .docs-version-selector"); + var version_selector_select = $("#documenter .docs-version-selector select"); + + version_selector_select.change(function (x) { + target_href = version_selector_select + .children("option:selected") + .get(0).value; + window.location.href = target_href; + }); + + // add the current version to the selector based on siteinfo.js, but only if the selector is empty + if ( + typeof DOCUMENTER_CURRENT_VERSION !== "undefined" && + $("#version-selector > option").length == 0 + ) { + var option = $( + "" + ); + version_selector_select.append(option); + } + + if (typeof DOC_VERSIONS !== "undefined") { + var existing_versions = version_selector_select.children("option"); + var existing_versions_texts = existing_versions.map(function (i, x) { + return x.text; + }); + DOC_VERSIONS.forEach(function (each) { + var version_url = documenterBaseURL + "/../" + each + "/"; + var existing_id = $.inArray(each, existing_versions_texts); + // if not already in the version selector, add it as a new option, + // otherwise update the old option with the URL and enable it + if (existing_id == -1) { + var option = $( + "" + ); + version_selector_select.append(option); + } else { + var option = existing_versions[existing_id]; + option.value = version_url; + option.disabled = false; + } + }); + } + + // only show the version selector if the selector has been populated + if (version_selector_select.children("option").length > 0) { + version_selector.toggleClass("visible"); + } +}); + +}) diff --git a/v0.1.8/assets/themes/documenter-dark.css b/v0.1.8/assets/themes/documenter-dark.css new file mode 100644 index 0000000..1d71701 --- /dev/null +++ b/v0.1.8/assets/themes/documenter-dark.css @@ -0,0 +1,7 @@ +html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark .file-cta,html.theme--documenter-dark .file-name,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,html.theme--documenter-dark .button{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:.4em;box-shadow:none;display:inline-flex;font-size:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 1px);position:relative;vertical-align:top}html.theme--documenter-dark .pagination-previous:focus,html.theme--documenter-dark .pagination-next:focus,html.theme--documenter-dark .pagination-link:focus,html.theme--documenter-dark .pagination-ellipsis:focus,html.theme--documenter-dark .file-cta:focus,html.theme--documenter-dark .file-name:focus,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 .button:focus,html.theme--documenter-dark .is-focused.pagination-previous,html.theme--documenter-dark .is-focused.pagination-next,html.theme--documenter-dark .is-focused.pagination-link,html.theme--documenter-dark .is-focused.pagination-ellipsis,html.theme--documenter-dark .is-focused.file-cta,html.theme--documenter-dark .is-focused.file-name,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 .is-focused.button,html.theme--documenter-dark .pagination-previous:active,html.theme--documenter-dark .pagination-next:active,html.theme--documenter-dark .pagination-link:active,html.theme--documenter-dark .pagination-ellipsis:active,html.theme--documenter-dark .file-cta:active,html.theme--documenter-dark .file-name:active,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 .button:active,html.theme--documenter-dark .is-active.pagination-previous,html.theme--documenter-dark .is-active.pagination-next,html.theme--documenter-dark .is-active.pagination-link,html.theme--documenter-dark .is-active.pagination-ellipsis,html.theme--documenter-dark .is-active.file-cta,html.theme--documenter-dark .is-active.file-name,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,html.theme--documenter-dark .is-active.button{outline:none}html.theme--documenter-dark .pagination-previous[disabled],html.theme--documenter-dark .pagination-next[disabled],html.theme--documenter-dark .pagination-link[disabled],html.theme--documenter-dark .pagination-ellipsis[disabled],html.theme--documenter-dark .file-cta[disabled],html.theme--documenter-dark .file-name[disabled],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],html.theme--documenter-dark .button[disabled],fieldset[disabled] html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark fieldset[disabled] .pagination-previous,fieldset[disabled] html.theme--documenter-dark .pagination-next,html.theme--documenter-dark fieldset[disabled] .pagination-next,fieldset[disabled] html.theme--documenter-dark .pagination-link,html.theme--documenter-dark fieldset[disabled] .pagination-link,fieldset[disabled] html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark fieldset[disabled] .pagination-ellipsis,fieldset[disabled] html.theme--documenter-dark .file-cta,html.theme--documenter-dark fieldset[disabled] .file-cta,fieldset[disabled] html.theme--documenter-dark .file-name,html.theme--documenter-dark fieldset[disabled] .file-name,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,html.theme--documenter-dark fieldset[disabled] .select select,html.theme--documenter-dark .select fieldset[disabled] select,html.theme--documenter-dark fieldset[disabled] .textarea,html.theme--documenter-dark fieldset[disabled] .input,html.theme--documenter-dark fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] html.theme--documenter-dark .button,html.theme--documenter-dark fieldset[disabled] .button{cursor:not-allowed}html.theme--documenter-dark .tabs,html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark .breadcrumb,html.theme--documenter-dark .file,html.theme--documenter-dark .button,.is-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}html.theme--documenter-dark .navbar-link:not(.is-arrowless)::after,html.theme--documenter-dark .select:not(.is-multiple):not(.is-loading)::after{border:3px solid rgba(0,0,0,0);border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:0.625em;margin-top:-0.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:0.625em}html.theme--documenter-dark .admonition:not(:last-child),html.theme--documenter-dark .tabs:not(:last-child),html.theme--documenter-dark .pagination:not(:last-child),html.theme--documenter-dark .message:not(:last-child),html.theme--documenter-dark .level:not(:last-child),html.theme--documenter-dark .breadcrumb:not(:last-child),html.theme--documenter-dark .block:not(:last-child),html.theme--documenter-dark .title:not(:last-child),html.theme--documenter-dark .subtitle:not(:last-child),html.theme--documenter-dark .table-container:not(:last-child),html.theme--documenter-dark .table:not(:last-child),html.theme--documenter-dark .progress:not(:last-child),html.theme--documenter-dark .notification:not(:last-child),html.theme--documenter-dark .content:not(:last-child),html.theme--documenter-dark .box:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .modal-close,html.theme--documenter-dark .delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:none;position:relative;vertical-align:top;width:20px}html.theme--documenter-dark .modal-close::before,html.theme--documenter-dark .delete::before,html.theme--documenter-dark .modal-close::after,html.theme--documenter-dark .delete::after{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--documenter-dark .modal-close::before,html.theme--documenter-dark .delete::before{height:2px;width:50%}html.theme--documenter-dark .modal-close::after,html.theme--documenter-dark .delete::after{height:50%;width:2px}html.theme--documenter-dark .modal-close:hover,html.theme--documenter-dark .delete:hover,html.theme--documenter-dark .modal-close:focus,html.theme--documenter-dark .delete:focus{background-color:rgba(10,10,10,0.3)}html.theme--documenter-dark .modal-close:active,html.theme--documenter-dark .delete:active{background-color:rgba(10,10,10,0.4)}html.theme--documenter-dark .is-small.modal-close,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.modal-close,html.theme--documenter-dark .is-small.delete,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.delete{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}html.theme--documenter-dark .is-medium.modal-close,html.theme--documenter-dark .is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}html.theme--documenter-dark .is-large.modal-close,html.theme--documenter-dark .is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}html.theme--documenter-dark .control.is-loading::after,html.theme--documenter-dark .select.is-loading::after,html.theme--documenter-dark .loader,html.theme--documenter-dark .button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #dbdee0;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}html.theme--documenter-dark .hero-video,html.theme--documenter-dark .modal-background,html.theme--documenter-dark .modal,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,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}html.theme--documenter-dark .navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */html,body,p,ol,ul,li,dl,dt,dd,blockquote,figure,fieldset,legend,textarea,pre,iframe,hr,h1,h2,h3,h4,h5,h6{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,*::before,*::after{box-sizing:inherit}img,video{height:auto;max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:inherit}.has-text-white{color:#fff !important}a.has-text-white:hover,a.has-text-white:focus{color:#e6e6e6 !important}.has-background-white{background-color:#fff !important}.has-text-black{color:#0a0a0a !important}a.has-text-black:hover,a.has-text-black:focus{color:#000 !important}.has-background-black{background-color:#0a0a0a !important}.has-text-light{color:#ecf0f1 !important}a.has-text-light:hover,a.has-text-light:focus{color:#cfd9db !important}.has-background-light{background-color:#ecf0f1 !important}.has-text-dark{color:#282f2f !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#111414 !important}.has-background-dark{background-color:#282f2f !important}.has-text-primary{color:#375a7f !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#28415b !important}.has-background-primary{background-color:#375a7f !important}.has-text-primary-light{color:#f1f5f9 !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#cddbe9 !important}.has-background-primary-light{background-color:#f1f5f9 !important}.has-text-primary-dark{color:#4d7eb2 !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#7198c1 !important}.has-background-primary-dark{background-color:#4d7eb2 !important}.has-text-link{color:#1abc9c !important}a.has-text-link:hover,a.has-text-link:focus{color:#148f77 !important}.has-background-link{background-color:#1abc9c !important}.has-text-link-light{color:#edfdf9 !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#c0f6ec !important}.has-background-link-light{background-color:#edfdf9 !important}.has-text-link-dark{color:#15987e !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#1bc5a4 !important}.has-background-link-dark{background-color:#15987e !important}.has-text-info{color:#024c7d !important}a.has-text-info:hover,a.has-text-info:focus{color:#012d4b !important}.has-background-info{background-color:#024c7d !important}.has-text-info-light{color:#ebf7ff !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#b9e2fe !important}.has-background-info-light{background-color:#ebf7ff !important}.has-text-info-dark{color:#0e9dfb !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#40b1fc !important}.has-background-info-dark{background-color:#0e9dfb !important}.has-text-success{color:#008438 !important}a.has-text-success:hover,a.has-text-success:focus{color:#005122 !important}.has-background-success{background-color:#008438 !important}.has-text-success-light{color:#ebfff3 !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#b8ffd6 !important}.has-background-success-light{background-color:#ebfff3 !important}.has-text-success-dark{color:#00eb64 !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#1fff7e !important}.has-background-success-dark{background-color:#00eb64 !important}.has-text-warning{color:#ad8100 !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#7a5b00 !important}.has-background-warning{background-color:#ad8100 !important}.has-text-warning-light{color:#fffaeb !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#ffedb8 !important}.has-background-warning-light{background-color:#fffaeb !important}.has-text-warning-dark{color:#d19c00 !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#ffbf05 !important}.has-background-warning-dark{background-color:#d19c00 !important}.has-text-danger{color:#9e1b0d !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#6f1309 !important}.has-background-danger{background-color:#9e1b0d !important}.has-text-danger-light{color:#fdeeec !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#fac3bd !important}.has-background-danger-light{background-color:#fdeeec !important}.has-text-danger-dark{color:#ec311d !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#f05c4c !important}.has-background-danger-dark{background-color:#ec311d !important}.has-text-black-bis{color:#121212 !important}.has-background-black-bis{background-color:#121212 !important}.has-text-black-ter{color:#242424 !important}.has-background-black-ter{background-color:#242424 !important}.has-text-grey-darker{color:#282f2f !important}.has-background-grey-darker{background-color:#282f2f !important}.has-text-grey-dark{color:#343c3d !important}.has-background-grey-dark{background-color:#343c3d !important}.has-text-grey{color:#5e6d6f !important}.has-background-grey{background-color:#5e6d6f !important}.has-text-grey-light{color:#8c9b9d !important}.has-background-grey-light{background-color:#8c9b9d !important}.has-text-grey-lighter{color:#dbdee0 !important}.has-background-grey-lighter{background-color:#dbdee0 !important}.has-text-white-ter{color:#ecf0f1 !important}.has-background-white-ter{background-color:#ecf0f1 !important}.has-text-white-bis{color:#fafafa !important}.has-background-white-bis{background-color:#fafafa !important}.is-flex-direction-row{flex-direction:row !important}.is-flex-direction-row-reverse{flex-direction:row-reverse !important}.is-flex-direction-column{flex-direction:column !important}.is-flex-direction-column-reverse{flex-direction:column-reverse !important}.is-flex-wrap-nowrap{flex-wrap:nowrap !important}.is-flex-wrap-wrap{flex-wrap:wrap !important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse !important}.is-justify-content-flex-start{justify-content:flex-start !important}.is-justify-content-flex-end{justify-content:flex-end !important}.is-justify-content-center{justify-content:center !important}.is-justify-content-space-between{justify-content:space-between !important}.is-justify-content-space-around{justify-content:space-around !important}.is-justify-content-space-evenly{justify-content:space-evenly !important}.is-justify-content-start{justify-content:start !important}.is-justify-content-end{justify-content:end !important}.is-justify-content-left{justify-content:left !important}.is-justify-content-right{justify-content:right !important}.is-align-content-flex-start{align-content:flex-start !important}.is-align-content-flex-end{align-content:flex-end !important}.is-align-content-center{align-content:center !important}.is-align-content-space-between{align-content:space-between !important}.is-align-content-space-around{align-content:space-around !important}.is-align-content-space-evenly{align-content:space-evenly !important}.is-align-content-stretch{align-content:stretch !important}.is-align-content-start{align-content:start !important}.is-align-content-end{align-content:end !important}.is-align-content-baseline{align-content:baseline !important}.is-align-items-stretch{align-items:stretch !important}.is-align-items-flex-start{align-items:flex-start !important}.is-align-items-flex-end{align-items:flex-end !important}.is-align-items-center{align-items:center !important}.is-align-items-baseline{align-items:baseline !important}.is-align-items-start{align-items:start !important}.is-align-items-end{align-items:end !important}.is-align-items-self-start{align-items:self-start !important}.is-align-items-self-end{align-items:self-end !important}.is-align-self-auto{align-self:auto !important}.is-align-self-flex-start{align-self:flex-start !important}.is-align-self-flex-end{align-self:flex-end !important}.is-align-self-center{align-self:center !important}.is-align-self-baseline{align-self:baseline !important}.is-align-self-stretch{align-self:stretch !important}.is-flex-grow-0{flex-grow:0 !important}.is-flex-grow-1{flex-grow:1 !important}.is-flex-grow-2{flex-grow:2 !important}.is-flex-grow-3{flex-grow:3 !important}.is-flex-grow-4{flex-grow:4 !important}.is-flex-grow-5{flex-grow:5 !important}.is-flex-shrink-0{flex-shrink:0 !important}.is-flex-shrink-1{flex-shrink:1 !important}.is-flex-shrink-2{flex-shrink:2 !important}.is-flex-shrink-3{flex-shrink:3 !important}.is-flex-shrink-4{flex-shrink:4 !important}.is-flex-shrink-5{flex-shrink:5 !important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-clickable{cursor:pointer !important;pointer-events:all !important}.is-clipped{overflow:hidden !important}.is-relative{position:relative !important}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !important}.is-size-1{font-size:3rem !important}.is-size-2{font-size:2.5rem !important}.is-size-3{font-size:2rem !important}.is-size-4{font-size:1.5rem !important}.is-size-5{font-size:1.25rem !important}.is-size-6{font-size:1rem !important}.is-size-7,html.theme--documenter-dark .docstring>section>a.docs-sourcelink{font-size:.75rem !important}@media screen and (max-width: 768px){.is-size-1-mobile{font-size:3rem !important}.is-size-2-mobile{font-size:2.5rem !important}.is-size-3-mobile{font-size:2rem !important}.is-size-4-mobile{font-size:1.5rem !important}.is-size-5-mobile{font-size:1.25rem !important}.is-size-6-mobile{font-size:1rem !important}.is-size-7-mobile{font-size:.75rem !important}}@media screen and (min-width: 769px),print{.is-size-1-tablet{font-size:3rem !important}.is-size-2-tablet{font-size:2.5rem !important}.is-size-3-tablet{font-size:2rem !important}.is-size-4-tablet{font-size:1.5rem !important}.is-size-5-tablet{font-size:1.25rem !important}.is-size-6-tablet{font-size:1rem !important}.is-size-7-tablet{font-size:.75rem !important}}@media screen and (max-width: 1055px){.is-size-1-touch{font-size:3rem !important}.is-size-2-touch{font-size:2.5rem !important}.is-size-3-touch{font-size:2rem !important}.is-size-4-touch{font-size:1.5rem !important}.is-size-5-touch{font-size:1.25rem !important}.is-size-6-touch{font-size:1rem !important}.is-size-7-touch{font-size:.75rem !important}}@media screen and (min-width: 1056px){.is-size-1-desktop{font-size:3rem !important}.is-size-2-desktop{font-size:2.5rem !important}.is-size-3-desktop{font-size:2rem !important}.is-size-4-desktop{font-size:1.5rem !important}.is-size-5-desktop{font-size:1.25rem !important}.is-size-6-desktop{font-size:1rem !important}.is-size-7-desktop{font-size:.75rem !important}}@media screen and (min-width: 1216px){.is-size-1-widescreen{font-size:3rem !important}.is-size-2-widescreen{font-size:2.5rem !important}.is-size-3-widescreen{font-size:2rem !important}.is-size-4-widescreen{font-size:1.5rem !important}.is-size-5-widescreen{font-size:1.25rem !important}.is-size-6-widescreen{font-size:1rem !important}.is-size-7-widescreen{font-size:.75rem !important}}@media screen and (min-width: 1408px){.is-size-1-fullhd{font-size:3rem !important}.is-size-2-fullhd{font-size:2.5rem !important}.is-size-3-fullhd{font-size:2rem !important}.is-size-4-fullhd{font-size:1.5rem !important}.is-size-5-fullhd{font-size:1.25rem !important}.is-size-6-fullhd{font-size:1rem !important}.is-size-7-fullhd{font-size:.75rem !important}}.has-text-centered{text-align:center !important}.has-text-justified{text-align:justify !important}.has-text-left{text-align:left !important}.has-text-right{text-align:right !important}@media screen and (max-width: 768px){.has-text-centered-mobile{text-align:center !important}}@media screen and (min-width: 769px),print{.has-text-centered-tablet{text-align:center !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-centered-tablet-only{text-align:center !important}}@media screen and (max-width: 1055px){.has-text-centered-touch{text-align:center !important}}@media screen and (min-width: 1056px){.has-text-centered-desktop{text-align:center !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-centered-desktop-only{text-align:center !important}}@media screen and (min-width: 1216px){.has-text-centered-widescreen{text-align:center !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-centered-widescreen-only{text-align:center !important}}@media screen and (min-width: 1408px){.has-text-centered-fullhd{text-align:center !important}}@media screen and (max-width: 768px){.has-text-justified-mobile{text-align:justify !important}}@media screen and (min-width: 769px),print{.has-text-justified-tablet{text-align:justify !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-justified-tablet-only{text-align:justify !important}}@media screen and (max-width: 1055px){.has-text-justified-touch{text-align:justify !important}}@media screen and (min-width: 1056px){.has-text-justified-desktop{text-align:justify !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-justified-desktop-only{text-align:justify !important}}@media screen and (min-width: 1216px){.has-text-justified-widescreen{text-align:justify !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-justified-widescreen-only{text-align:justify !important}}@media screen and (min-width: 1408px){.has-text-justified-fullhd{text-align:justify !important}}@media screen and (max-width: 768px){.has-text-left-mobile{text-align:left !important}}@media screen and (min-width: 769px),print{.has-text-left-tablet{text-align:left !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-left-tablet-only{text-align:left !important}}@media screen and (max-width: 1055px){.has-text-left-touch{text-align:left !important}}@media screen and (min-width: 1056px){.has-text-left-desktop{text-align:left !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-left-desktop-only{text-align:left !important}}@media screen and (min-width: 1216px){.has-text-left-widescreen{text-align:left !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-left-widescreen-only{text-align:left !important}}@media screen and (min-width: 1408px){.has-text-left-fullhd{text-align:left !important}}@media screen and (max-width: 768px){.has-text-right-mobile{text-align:right !important}}@media screen and (min-width: 769px),print{.has-text-right-tablet{text-align:right !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-right-tablet-only{text-align:right !important}}@media screen and (max-width: 1055px){.has-text-right-touch{text-align:right !important}}@media screen and (min-width: 1056px){.has-text-right-desktop{text-align:right !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-right-desktop-only{text-align:right !important}}@media screen and (min-width: 1216px){.has-text-right-widescreen{text-align:right !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-right-widescreen-only{text-align:right !important}}@media screen and (min-width: 1408px){.has-text-right-fullhd{text-align:right !important}}.is-capitalized{text-transform:capitalize !important}.is-lowercase{text-transform:lowercase !important}.is-uppercase{text-transform:uppercase !important}.is-italic{font-style:italic !important}.is-underlined{text-decoration:underline !important}.has-text-weight-light{font-weight:300 !important}.has-text-weight-normal{font-weight:400 !important}.has-text-weight-medium{font-weight:500 !important}.has-text-weight-semibold{font-weight:600 !important}.has-text-weight-bold{font-weight:700 !important}.is-family-primary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-secondary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-sans-serif{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-monospace{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-family-code{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-block{display:block !important}@media screen and (max-width: 768px){.is-block-mobile{display:block !important}}@media screen and (min-width: 769px),print{.is-block-tablet{display:block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-block-tablet-only{display:block !important}}@media screen and (max-width: 1055px){.is-block-touch{display:block !important}}@media screen and (min-width: 1056px){.is-block-desktop{display:block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-block-desktop-only{display:block !important}}@media screen and (min-width: 1216px){.is-block-widescreen{display:block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-block-widescreen-only{display:block !important}}@media screen and (min-width: 1408px){.is-block-fullhd{display:block !important}}.is-flex{display:flex !important}@media screen and (max-width: 768px){.is-flex-mobile{display:flex !important}}@media screen and (min-width: 769px),print{.is-flex-tablet{display:flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-flex-tablet-only{display:flex !important}}@media screen and (max-width: 1055px){.is-flex-touch{display:flex !important}}@media screen and (min-width: 1056px){.is-flex-desktop{display:flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-flex-desktop-only{display:flex !important}}@media screen and (min-width: 1216px){.is-flex-widescreen{display:flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-flex-widescreen-only{display:flex !important}}@media screen and (min-width: 1408px){.is-flex-fullhd{display:flex !important}}.is-inline{display:inline !important}@media screen and (max-width: 768px){.is-inline-mobile{display:inline !important}}@media screen and (min-width: 769px),print{.is-inline-tablet{display:inline !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-tablet-only{display:inline !important}}@media screen and (max-width: 1055px){.is-inline-touch{display:inline !important}}@media screen and (min-width: 1056px){.is-inline-desktop{display:inline !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-desktop-only{display:inline !important}}@media screen and (min-width: 1216px){.is-inline-widescreen{display:inline !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-widescreen-only{display:inline !important}}@media screen and (min-width: 1408px){.is-inline-fullhd{display:inline !important}}.is-inline-block{display:inline-block !important}@media screen and (max-width: 768px){.is-inline-block-mobile{display:inline-block !important}}@media screen and (min-width: 769px),print{.is-inline-block-tablet{display:inline-block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-block-tablet-only{display:inline-block !important}}@media screen and (max-width: 1055px){.is-inline-block-touch{display:inline-block !important}}@media screen and (min-width: 1056px){.is-inline-block-desktop{display:inline-block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-block-desktop-only{display:inline-block !important}}@media screen and (min-width: 1216px){.is-inline-block-widescreen{display:inline-block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-block-widescreen-only{display:inline-block !important}}@media screen and (min-width: 1408px){.is-inline-block-fullhd{display:inline-block !important}}.is-inline-flex{display:inline-flex !important}@media screen and (max-width: 768px){.is-inline-flex-mobile{display:inline-flex !important}}@media screen and (min-width: 769px),print{.is-inline-flex-tablet{display:inline-flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-flex-tablet-only{display:inline-flex !important}}@media screen and (max-width: 1055px){.is-inline-flex-touch{display:inline-flex !important}}@media screen and (min-width: 1056px){.is-inline-flex-desktop{display:inline-flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-flex-desktop-only{display:inline-flex !important}}@media screen and (min-width: 1216px){.is-inline-flex-widescreen{display:inline-flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-flex-widescreen-only{display:inline-flex !important}}@media screen and (min-width: 1408px){.is-inline-flex-fullhd{display:inline-flex !important}}.is-hidden{display:none !important}.is-sr-only{border:none !important;clip:rect(0, 0, 0, 0) !important;height:0.01em !important;overflow:hidden !important;padding:0 !important;position:absolute !important;white-space:nowrap !important;width:0.01em !important}@media screen and (max-width: 768px){.is-hidden-mobile{display:none !important}}@media screen and (min-width: 769px),print{.is-hidden-tablet{display:none !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-hidden-tablet-only{display:none !important}}@media screen and (max-width: 1055px){.is-hidden-touch{display:none !important}}@media screen and (min-width: 1056px){.is-hidden-desktop{display:none !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-hidden-desktop-only{display:none !important}}@media screen and (min-width: 1216px){.is-hidden-widescreen{display:none !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-hidden-widescreen-only{display:none !important}}@media screen and (min-width: 1408px){.is-hidden-fullhd{display:none !important}}.is-invisible{visibility:hidden !important}@media screen and (max-width: 768px){.is-invisible-mobile{visibility:hidden !important}}@media screen and (min-width: 769px),print{.is-invisible-tablet{visibility:hidden !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-invisible-tablet-only{visibility:hidden !important}}@media screen and (max-width: 1055px){.is-invisible-touch{visibility:hidden !important}}@media screen and (min-width: 1056px){.is-invisible-desktop{visibility:hidden !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-invisible-desktop-only{visibility:hidden !important}}@media screen and (min-width: 1216px){.is-invisible-widescreen{visibility:hidden !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-invisible-widescreen-only{visibility:hidden !important}}@media screen and (min-width: 1408px){.is-invisible-fullhd{visibility:hidden !important}}html.theme--documenter-dark{/*! + Theme: a11y-dark + Author: @ericwbailey + 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;overflow:auto}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 a:hover code{color:#1dd2af}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;overflow-x:hidden}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 .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/v0.1.8/assets/themes/documenter-light.css b/v0.1.8/assets/themes/documenter-light.css new file mode 100644 index 0000000..07f9d08 --- /dev/null +++ b/v0.1.8/assets/themes/documenter-light.css @@ -0,0 +1,9 @@ +.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis,.file-cta,.file-name,.select select,.textarea,.input,#documenter .docs-sidebar form.docs-search>input,.button{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:4px;box-shadow:none;display:inline-flex;font-size:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 1px);position:relative;vertical-align:top}.pagination-previous:focus,.pagination-next:focus,.pagination-link:focus,.pagination-ellipsis:focus,.file-cta:focus,.file-name:focus,.select select:focus,.textarea:focus,.input:focus,#documenter .docs-sidebar form.docs-search>input:focus,.button:focus,.is-focused.pagination-previous,.is-focused.pagination-next,.is-focused.pagination-link,.is-focused.pagination-ellipsis,.is-focused.file-cta,.is-focused.file-name,.select select.is-focused,.is-focused.textarea,.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-focused.button,.pagination-previous:active,.pagination-next:active,.pagination-link:active,.pagination-ellipsis:active,.file-cta:active,.file-name:active,.select select:active,.textarea:active,.input:active,#documenter .docs-sidebar form.docs-search>input:active,.button:active,.is-active.pagination-previous,.is-active.pagination-next,.is-active.pagination-link,.is-active.pagination-ellipsis,.is-active.file-cta,.is-active.file-name,.select select.is-active,.is-active.textarea,.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active,.is-active.button{outline:none}.pagination-previous[disabled],.pagination-next[disabled],.pagination-link[disabled],.pagination-ellipsis[disabled],.file-cta[disabled],.file-name[disabled],.select select[disabled],.textarea[disabled],.input[disabled],#documenter .docs-sidebar form.docs-search>input[disabled],.button[disabled],fieldset[disabled] .pagination-previous,fieldset[disabled] .pagination-next,fieldset[disabled] .pagination-link,fieldset[disabled] .pagination-ellipsis,fieldset[disabled] .file-cta,fieldset[disabled] .file-name,fieldset[disabled] .select select,.select fieldset[disabled] select,fieldset[disabled] .textarea,fieldset[disabled] .input,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] .button{cursor:not-allowed}.tabs,.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis,.breadcrumb,.file,.button,.is-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navbar-link:not(.is-arrowless)::after,.select:not(.is-multiple):not(.is-loading)::after{border:3px solid rgba(0,0,0,0);border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:0.625em;margin-top:-0.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:0.625em}.admonition:not(:last-child),.tabs:not(:last-child),.pagination:not(:last-child),.message:not(:last-child),.level:not(:last-child),.breadcrumb:not(:last-child),.block:not(:last-child),.title:not(:last-child),.subtitle:not(:last-child),.table-container:not(:last-child),.table:not(:last-child),.progress:not(:last-child),.notification:not(:last-child),.content:not(:last-child),.box:not(:last-child){margin-bottom:1.5rem}.modal-close,.delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:none;position:relative;vertical-align:top;width:20px}.modal-close::before,.delete::before,.modal-close::after,.delete::after{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.modal-close::before,.delete::before{height:2px;width:50%}.modal-close::after,.delete::after{height:50%;width:2px}.modal-close:hover,.delete:hover,.modal-close:focus,.delete:focus{background-color:rgba(10,10,10,0.3)}.modal-close:active,.delete:active{background-color:rgba(10,10,10,0.4)}.is-small.modal-close,#documenter .docs-sidebar form.docs-search>input.modal-close,.is-small.delete,#documenter .docs-sidebar form.docs-search>input.delete{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}.is-medium.modal-close,.is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}.is-large.modal-close,.is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}.control.is-loading::after,.select.is-loading::after,.loader,.button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #dbdbdb;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}.hero-video,.modal-background,.modal,.image.is-square img,#documenter .docs-sidebar .docs-logo>img.is-square img,.image.is-square .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,.image.is-1by1 img,#documenter .docs-sidebar .docs-logo>img.is-1by1 img,.image.is-1by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,.image.is-5by4 img,#documenter .docs-sidebar .docs-logo>img.is-5by4 img,.image.is-5by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,.image.is-4by3 img,#documenter .docs-sidebar .docs-logo>img.is-4by3 img,.image.is-4by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,.image.is-3by2 img,#documenter .docs-sidebar .docs-logo>img.is-3by2 img,.image.is-3by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,.image.is-5by3 img,#documenter .docs-sidebar .docs-logo>img.is-5by3 img,.image.is-5by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,.image.is-16by9 img,#documenter .docs-sidebar .docs-logo>img.is-16by9 img,.image.is-16by9 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,.image.is-2by1 img,#documenter .docs-sidebar .docs-logo>img.is-2by1 img,.image.is-2by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,.image.is-3by1 img,#documenter .docs-sidebar .docs-logo>img.is-3by1 img,.image.is-3by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,.image.is-4by5 img,#documenter .docs-sidebar .docs-logo>img.is-4by5 img,.image.is-4by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,.image.is-3by4 img,#documenter .docs-sidebar .docs-logo>img.is-3by4 img,.image.is-3by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,.image.is-2by3 img,#documenter .docs-sidebar .docs-logo>img.is-2by3 img,.image.is-2by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,.image.is-3by5 img,#documenter .docs-sidebar .docs-logo>img.is-3by5 img,.image.is-3by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,.image.is-9by16 img,#documenter .docs-sidebar .docs-logo>img.is-9by16 img,.image.is-9by16 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,.image.is-1by2 img,#documenter .docs-sidebar .docs-logo>img.is-1by2 img,.image.is-1by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,.image.is-1by3 img,#documenter .docs-sidebar .docs-logo>img.is-1by3 img,.image.is-1by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}.navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}.has-text-white{color:#fff !important}a.has-text-white:hover,a.has-text-white:focus{color:#e6e6e6 !important}.has-background-white{background-color:#fff !important}.has-text-black{color:#0a0a0a !important}a.has-text-black:hover,a.has-text-black:focus{color:#000 !important}.has-background-black{background-color:#0a0a0a !important}.has-text-light{color:#f5f5f5 !important}a.has-text-light:hover,a.has-text-light:focus{color:#dbdbdb !important}.has-background-light{background-color:#f5f5f5 !important}.has-text-dark{color:#363636 !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#1c1c1c !important}.has-background-dark{background-color:#363636 !important}.has-text-primary{color:#4eb5de !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#27a1d2 !important}.has-background-primary{background-color:#4eb5de !important}.has-text-primary-light{color:#eef8fc !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#c3e6f4 !important}.has-background-primary-light{background-color:#eef8fc !important}.has-text-primary-dark{color:#1a6d8e !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#228eb9 !important}.has-background-primary-dark{background-color:#1a6d8e !important}.has-text-link{color:#2e63b8 !important}a.has-text-link:hover,a.has-text-link:focus{color:#244d8f !important}.has-background-link{background-color:#2e63b8 !important}.has-text-link-light{color:#eff3fb !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#c6d6f1 !important}.has-background-link-light{background-color:#eff3fb !important}.has-text-link-dark{color:#3169c4 !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#5485d4 !important}.has-background-link-dark{background-color:#3169c4 !important}.has-text-info{color:#209cee !important}a.has-text-info:hover,a.has-text-info:focus{color:#1081cb !important}.has-background-info{background-color:#209cee !important}.has-text-info-light{color:#ecf7fe !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#bde2fa !important}.has-background-info-light{background-color:#ecf7fe !important}.has-text-info-dark{color:#0e72b4 !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#1190e3 !important}.has-background-info-dark{background-color:#0e72b4 !important}.has-text-success{color:#22c35b !important}a.has-text-success:hover,a.has-text-success:focus{color:#1a9847 !important}.has-background-success{background-color:#22c35b !important}.has-text-success-light{color:#eefcf3 !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#c2f4d4 !important}.has-background-success-light{background-color:#eefcf3 !important}.has-text-success-dark{color:#198f43 !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#21bb57 !important}.has-background-success-dark{background-color:#198f43 !important}.has-text-warning{color:#ffdd57 !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#ffd324 !important}.has-background-warning{background-color:#ffdd57 !important}.has-text-warning-light{color:#fffbeb !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#fff1b8 !important}.has-background-warning-light{background-color:#fffbeb !important}.has-text-warning-dark{color:#947600 !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#c79f00 !important}.has-background-warning-dark{background-color:#947600 !important}.has-text-danger{color:#da0b00 !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#a70800 !important}.has-background-danger{background-color:#da0b00 !important}.has-text-danger-light{color:#ffeceb !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#ffbbb8 !important}.has-background-danger-light{background-color:#ffeceb !important}.has-text-danger-dark{color:#f50c00 !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#ff3429 !important}.has-background-danger-dark{background-color:#f50c00 !important}.has-text-black-bis{color:#121212 !important}.has-background-black-bis{background-color:#121212 !important}.has-text-black-ter{color:#242424 !important}.has-background-black-ter{background-color:#242424 !important}.has-text-grey-darker{color:#363636 !important}.has-background-grey-darker{background-color:#363636 !important}.has-text-grey-dark{color:#4a4a4a !important}.has-background-grey-dark{background-color:#4a4a4a !important}.has-text-grey{color:#6b6b6b !important}.has-background-grey{background-color:#6b6b6b !important}.has-text-grey-light{color:#b5b5b5 !important}.has-background-grey-light{background-color:#b5b5b5 !important}.has-text-grey-lighter{color:#dbdbdb !important}.has-background-grey-lighter{background-color:#dbdbdb !important}.has-text-white-ter{color:#f5f5f5 !important}.has-background-white-ter{background-color:#f5f5f5 !important}.has-text-white-bis{color:#fafafa !important}.has-background-white-bis{background-color:#fafafa !important}.is-flex-direction-row{flex-direction:row !important}.is-flex-direction-row-reverse{flex-direction:row-reverse !important}.is-flex-direction-column{flex-direction:column !important}.is-flex-direction-column-reverse{flex-direction:column-reverse !important}.is-flex-wrap-nowrap{flex-wrap:nowrap !important}.is-flex-wrap-wrap{flex-wrap:wrap !important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse !important}.is-justify-content-flex-start{justify-content:flex-start !important}.is-justify-content-flex-end{justify-content:flex-end !important}.is-justify-content-center{justify-content:center !important}.is-justify-content-space-between{justify-content:space-between !important}.is-justify-content-space-around{justify-content:space-around !important}.is-justify-content-space-evenly{justify-content:space-evenly !important}.is-justify-content-start{justify-content:start !important}.is-justify-content-end{justify-content:end !important}.is-justify-content-left{justify-content:left !important}.is-justify-content-right{justify-content:right !important}.is-align-content-flex-start{align-content:flex-start !important}.is-align-content-flex-end{align-content:flex-end !important}.is-align-content-center{align-content:center !important}.is-align-content-space-between{align-content:space-between !important}.is-align-content-space-around{align-content:space-around !important}.is-align-content-space-evenly{align-content:space-evenly !important}.is-align-content-stretch{align-content:stretch !important}.is-align-content-start{align-content:start !important}.is-align-content-end{align-content:end !important}.is-align-content-baseline{align-content:baseline !important}.is-align-items-stretch{align-items:stretch !important}.is-align-items-flex-start{align-items:flex-start !important}.is-align-items-flex-end{align-items:flex-end !important}.is-align-items-center{align-items:center !important}.is-align-items-baseline{align-items:baseline !important}.is-align-items-start{align-items:start !important}.is-align-items-end{align-items:end !important}.is-align-items-self-start{align-items:self-start !important}.is-align-items-self-end{align-items:self-end !important}.is-align-self-auto{align-self:auto !important}.is-align-self-flex-start{align-self:flex-start !important}.is-align-self-flex-end{align-self:flex-end !important}.is-align-self-center{align-self:center !important}.is-align-self-baseline{align-self:baseline !important}.is-align-self-stretch{align-self:stretch !important}.is-flex-grow-0{flex-grow:0 !important}.is-flex-grow-1{flex-grow:1 !important}.is-flex-grow-2{flex-grow:2 !important}.is-flex-grow-3{flex-grow:3 !important}.is-flex-grow-4{flex-grow:4 !important}.is-flex-grow-5{flex-grow:5 !important}.is-flex-shrink-0{flex-shrink:0 !important}.is-flex-shrink-1{flex-shrink:1 !important}.is-flex-shrink-2{flex-shrink:2 !important}.is-flex-shrink-3{flex-shrink:3 !important}.is-flex-shrink-4{flex-shrink:4 !important}.is-flex-shrink-5{flex-shrink:5 !important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-clickable{cursor:pointer !important;pointer-events:all !important}.is-clipped{overflow:hidden !important}.is-relative{position:relative !important}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !important}.is-size-1{font-size:3rem !important}.is-size-2{font-size:2.5rem !important}.is-size-3{font-size:2rem !important}.is-size-4{font-size:1.5rem !important}.is-size-5{font-size:1.25rem !important}.is-size-6{font-size:1rem !important}.is-size-7,.docstring>section>a.docs-sourcelink{font-size:.75rem !important}@media screen and (max-width: 768px){.is-size-1-mobile{font-size:3rem !important}.is-size-2-mobile{font-size:2.5rem !important}.is-size-3-mobile{font-size:2rem !important}.is-size-4-mobile{font-size:1.5rem !important}.is-size-5-mobile{font-size:1.25rem !important}.is-size-6-mobile{font-size:1rem !important}.is-size-7-mobile{font-size:.75rem !important}}@media screen and (min-width: 769px),print{.is-size-1-tablet{font-size:3rem !important}.is-size-2-tablet{font-size:2.5rem !important}.is-size-3-tablet{font-size:2rem !important}.is-size-4-tablet{font-size:1.5rem !important}.is-size-5-tablet{font-size:1.25rem !important}.is-size-6-tablet{font-size:1rem !important}.is-size-7-tablet{font-size:.75rem !important}}@media screen and (max-width: 1055px){.is-size-1-touch{font-size:3rem !important}.is-size-2-touch{font-size:2.5rem !important}.is-size-3-touch{font-size:2rem !important}.is-size-4-touch{font-size:1.5rem !important}.is-size-5-touch{font-size:1.25rem !important}.is-size-6-touch{font-size:1rem !important}.is-size-7-touch{font-size:.75rem !important}}@media screen and (min-width: 1056px){.is-size-1-desktop{font-size:3rem !important}.is-size-2-desktop{font-size:2.5rem !important}.is-size-3-desktop{font-size:2rem !important}.is-size-4-desktop{font-size:1.5rem !important}.is-size-5-desktop{font-size:1.25rem !important}.is-size-6-desktop{font-size:1rem !important}.is-size-7-desktop{font-size:.75rem !important}}@media screen and (min-width: 1216px){.is-size-1-widescreen{font-size:3rem !important}.is-size-2-widescreen{font-size:2.5rem !important}.is-size-3-widescreen{font-size:2rem !important}.is-size-4-widescreen{font-size:1.5rem !important}.is-size-5-widescreen{font-size:1.25rem !important}.is-size-6-widescreen{font-size:1rem !important}.is-size-7-widescreen{font-size:.75rem !important}}@media screen and (min-width: 1408px){.is-size-1-fullhd{font-size:3rem !important}.is-size-2-fullhd{font-size:2.5rem !important}.is-size-3-fullhd{font-size:2rem !important}.is-size-4-fullhd{font-size:1.5rem !important}.is-size-5-fullhd{font-size:1.25rem !important}.is-size-6-fullhd{font-size:1rem !important}.is-size-7-fullhd{font-size:.75rem !important}}.has-text-centered{text-align:center !important}.has-text-justified{text-align:justify !important}.has-text-left{text-align:left !important}.has-text-right{text-align:right !important}@media screen and (max-width: 768px){.has-text-centered-mobile{text-align:center !important}}@media screen and (min-width: 769px),print{.has-text-centered-tablet{text-align:center !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-centered-tablet-only{text-align:center !important}}@media screen and (max-width: 1055px){.has-text-centered-touch{text-align:center !important}}@media screen and (min-width: 1056px){.has-text-centered-desktop{text-align:center !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-centered-desktop-only{text-align:center !important}}@media screen and (min-width: 1216px){.has-text-centered-widescreen{text-align:center !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-centered-widescreen-only{text-align:center !important}}@media screen and (min-width: 1408px){.has-text-centered-fullhd{text-align:center !important}}@media screen and (max-width: 768px){.has-text-justified-mobile{text-align:justify !important}}@media screen and (min-width: 769px),print{.has-text-justified-tablet{text-align:justify !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-justified-tablet-only{text-align:justify !important}}@media screen and (max-width: 1055px){.has-text-justified-touch{text-align:justify !important}}@media screen and (min-width: 1056px){.has-text-justified-desktop{text-align:justify !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-justified-desktop-only{text-align:justify !important}}@media screen and (min-width: 1216px){.has-text-justified-widescreen{text-align:justify !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-justified-widescreen-only{text-align:justify !important}}@media screen and (min-width: 1408px){.has-text-justified-fullhd{text-align:justify !important}}@media screen and (max-width: 768px){.has-text-left-mobile{text-align:left !important}}@media screen and (min-width: 769px),print{.has-text-left-tablet{text-align:left !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-left-tablet-only{text-align:left !important}}@media screen and (max-width: 1055px){.has-text-left-touch{text-align:left !important}}@media screen and (min-width: 1056px){.has-text-left-desktop{text-align:left !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-left-desktop-only{text-align:left !important}}@media screen and (min-width: 1216px){.has-text-left-widescreen{text-align:left !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-left-widescreen-only{text-align:left !important}}@media screen and (min-width: 1408px){.has-text-left-fullhd{text-align:left !important}}@media screen and (max-width: 768px){.has-text-right-mobile{text-align:right !important}}@media screen and (min-width: 769px),print{.has-text-right-tablet{text-align:right !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-right-tablet-only{text-align:right !important}}@media screen and (max-width: 1055px){.has-text-right-touch{text-align:right !important}}@media screen and (min-width: 1056px){.has-text-right-desktop{text-align:right !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-right-desktop-only{text-align:right !important}}@media screen and (min-width: 1216px){.has-text-right-widescreen{text-align:right !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-right-widescreen-only{text-align:right !important}}@media screen and (min-width: 1408px){.has-text-right-fullhd{text-align:right !important}}.is-capitalized{text-transform:capitalize !important}.is-lowercase{text-transform:lowercase !important}.is-uppercase{text-transform:uppercase !important}.is-italic{font-style:italic !important}.is-underlined{text-decoration:underline !important}.has-text-weight-light{font-weight:300 !important}.has-text-weight-normal{font-weight:400 !important}.has-text-weight-medium{font-weight:500 !important}.has-text-weight-semibold{font-weight:600 !important}.has-text-weight-bold{font-weight:700 !important}.is-family-primary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-secondary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-sans-serif{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-monospace{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-family-code{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-block{display:block !important}@media screen and (max-width: 768px){.is-block-mobile{display:block !important}}@media screen and (min-width: 769px),print{.is-block-tablet{display:block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-block-tablet-only{display:block !important}}@media screen and (max-width: 1055px){.is-block-touch{display:block !important}}@media screen and (min-width: 1056px){.is-block-desktop{display:block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-block-desktop-only{display:block !important}}@media screen and (min-width: 1216px){.is-block-widescreen{display:block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-block-widescreen-only{display:block !important}}@media screen and (min-width: 1408px){.is-block-fullhd{display:block !important}}.is-flex{display:flex !important}@media screen and (max-width: 768px){.is-flex-mobile{display:flex !important}}@media screen and (min-width: 769px),print{.is-flex-tablet{display:flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-flex-tablet-only{display:flex !important}}@media screen and (max-width: 1055px){.is-flex-touch{display:flex !important}}@media screen and (min-width: 1056px){.is-flex-desktop{display:flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-flex-desktop-only{display:flex !important}}@media screen and (min-width: 1216px){.is-flex-widescreen{display:flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-flex-widescreen-only{display:flex !important}}@media screen and (min-width: 1408px){.is-flex-fullhd{display:flex !important}}.is-inline{display:inline !important}@media screen and (max-width: 768px){.is-inline-mobile{display:inline !important}}@media screen and (min-width: 769px),print{.is-inline-tablet{display:inline !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-tablet-only{display:inline !important}}@media screen and (max-width: 1055px){.is-inline-touch{display:inline !important}}@media screen and (min-width: 1056px){.is-inline-desktop{display:inline !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-desktop-only{display:inline !important}}@media screen and (min-width: 1216px){.is-inline-widescreen{display:inline !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-widescreen-only{display:inline !important}}@media screen and (min-width: 1408px){.is-inline-fullhd{display:inline !important}}.is-inline-block{display:inline-block !important}@media screen and (max-width: 768px){.is-inline-block-mobile{display:inline-block !important}}@media screen and (min-width: 769px),print{.is-inline-block-tablet{display:inline-block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-block-tablet-only{display:inline-block !important}}@media screen and (max-width: 1055px){.is-inline-block-touch{display:inline-block !important}}@media screen and (min-width: 1056px){.is-inline-block-desktop{display:inline-block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-block-desktop-only{display:inline-block !important}}@media screen and (min-width: 1216px){.is-inline-block-widescreen{display:inline-block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-block-widescreen-only{display:inline-block !important}}@media screen and (min-width: 1408px){.is-inline-block-fullhd{display:inline-block !important}}.is-inline-flex{display:inline-flex !important}@media screen and (max-width: 768px){.is-inline-flex-mobile{display:inline-flex !important}}@media screen and (min-width: 769px),print{.is-inline-flex-tablet{display:inline-flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-flex-tablet-only{display:inline-flex !important}}@media screen and (max-width: 1055px){.is-inline-flex-touch{display:inline-flex !important}}@media screen and (min-width: 1056px){.is-inline-flex-desktop{display:inline-flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-flex-desktop-only{display:inline-flex !important}}@media screen and (min-width: 1216px){.is-inline-flex-widescreen{display:inline-flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-flex-widescreen-only{display:inline-flex !important}}@media screen and (min-width: 1408px){.is-inline-flex-fullhd{display:inline-flex !important}}.is-hidden{display:none !important}.is-sr-only{border:none !important;clip:rect(0, 0, 0, 0) !important;height:0.01em !important;overflow:hidden !important;padding:0 !important;position:absolute !important;white-space:nowrap !important;width:0.01em !important}@media screen and (max-width: 768px){.is-hidden-mobile{display:none !important}}@media screen and (min-width: 769px),print{.is-hidden-tablet{display:none !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-hidden-tablet-only{display:none !important}}@media screen and (max-width: 1055px){.is-hidden-touch{display:none !important}}@media screen and (min-width: 1056px){.is-hidden-desktop{display:none !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-hidden-desktop-only{display:none !important}}@media screen and (min-width: 1216px){.is-hidden-widescreen{display:none !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-hidden-widescreen-only{display:none !important}}@media screen and (min-width: 1408px){.is-hidden-fullhd{display:none !important}}.is-invisible{visibility:hidden !important}@media screen and (max-width: 768px){.is-invisible-mobile{visibility:hidden !important}}@media screen and (min-width: 769px),print{.is-invisible-tablet{visibility:hidden !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-invisible-tablet-only{visibility:hidden !important}}@media screen and (max-width: 1055px){.is-invisible-touch{visibility:hidden !important}}@media screen and (min-width: 1056px){.is-invisible-desktop{visibility:hidden !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-invisible-desktop-only{visibility:hidden !important}}@media screen and (min-width: 1216px){.is-invisible-widescreen{visibility:hidden !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-invisible-widescreen-only{visibility:hidden !important}}@media screen and (min-width: 1408px){.is-invisible-fullhd{visibility:hidden !important}}/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */html,body,p,ol,ul,li,dl,dt,dd,blockquote,figure,fieldset,legend,textarea,pre,iframe,hr,h1,h2,h3,h4,h5,h6{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,*::before,*::after{box-sizing:inherit}img,video{height:auto;max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:inherit}html{background-color:#fff;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%}article,aside,figure,footer,header,hgroup,section{display:block}body,button,input,optgroup,select,textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}code,pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}body{color:#222;font-size:1em;font-weight:400;line-height:1.5}a{color:#2e63b8;cursor:pointer;text-decoration:none}a strong{color:currentColor}a:hover{color:#363636}code{background-color:rgba(0,0,0,0.05);color:#000;font-size:.875em;font-weight:normal;padding:.1em}hr{background-color:#f5f5f5;border:none;display:block;height:2px;margin:1.5rem 0}img{height:auto;max-width:100%}input[type="checkbox"],input[type="radio"]{vertical-align:baseline}small{font-size:.875em}span{font-style:inherit;font-weight:inherit}strong{color:#222;font-weight:700}fieldset{border:none}pre{-webkit-overflow-scrolling:touch;background-color:#f5f5f5;color:#222;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}table td,table th{vertical-align:top}table td:not([align]),table th:not([align]){text-align:inherit}table th{color:#222}@keyframes spinAround{from{transform:rotate(0deg)}to{transform:rotate(359deg)}}.box{background-color:#fff;border-radius:6px;box-shadow:#bbb;color:#222;display:block;padding:1.25rem}a.box:hover,a.box:focus{box-shadow:0 0.5em 1em -0.125em rgba(10,10,10,0.1),0 0 0 1px #2e63b8}a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #2e63b8}.button{background-color:#fff;border-color:#dbdbdb;border-width:1px;color:#222;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}.button strong{color:inherit}.button .icon,.button .icon.is-small,.button #documenter .docs-sidebar form.docs-search>input.icon,#documenter .docs-sidebar .button form.docs-search>input.icon,.button .icon.is-medium,.button .icon.is-large{height:1.5em;width:1.5em}.button .icon:first-child:not(:last-child){margin-left:calc(-0.5em - 1px);margin-right:.25em}.button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}.button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 1px)}.button:hover,.button.is-hovered{border-color:#b5b5b5;color:#363636}.button:focus,.button.is-focused{border-color:#3c5dcd;color:#363636}.button:focus:not(:active),.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.button:active,.button.is-active{border-color:#4a4a4a;color:#363636}.button.is-text{background-color:transparent;border-color:transparent;color:#222;text-decoration:underline}.button.is-text:hover,.button.is-text.is-hovered,.button.is-text:focus,.button.is-text.is-focused{background-color:#f5f5f5;color:#222}.button.is-text:active,.button.is-text.is-active{background-color:#e8e8e8;color:#222}.button.is-text[disabled],fieldset[disabled] .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}.button.is-ghost{background:none;border-color:rgba(0,0,0,0);color:#2e63b8;text-decoration:none}.button.is-ghost:hover,.button.is-ghost.is-hovered{color:#2e63b8;text-decoration:underline}.button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}.button.is-white:hover,.button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.button.is-white:focus,.button.is-white.is-focused{border-color:transparent;color:#0a0a0a}.button.is-white:focus:not(:active),.button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}.button.is-white:active,.button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.button.is-white[disabled],fieldset[disabled] .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}.button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted:hover,.button.is-white.is-inverted.is-hovered{background-color:#000}.button.is-white.is-inverted[disabled],fieldset[disabled] .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}.button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}.button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-white.is-outlined:hover,.button.is-white.is-outlined.is-hovered,.button.is-white.is-outlined:focus,.button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}.button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-white.is-outlined.is-loading:hover::after,.button.is-white.is-outlined.is-loading.is-hovered::after,.button.is-white.is-outlined.is-loading:focus::after,.button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}.button.is-white.is-outlined[disabled],fieldset[disabled] .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-white.is-inverted.is-outlined:hover,.button.is-white.is-inverted.is-outlined.is-hovered,.button.is-white.is-inverted.is-outlined:focus,.button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted.is-outlined.is-loading:hover::after,.button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-white.is-inverted.is-outlined.is-loading:focus::after,.button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}.button.is-black:hover,.button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}.button.is-black:focus,.button.is-black.is-focused{border-color:transparent;color:#fff}.button.is-black:focus:not(:active),.button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}.button.is-black:active,.button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}.button.is-black[disabled],fieldset[disabled] .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}.button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted:hover,.button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-black.is-inverted[disabled],fieldset[disabled] .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}.button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-black.is-outlined:hover,.button.is-black.is-outlined.is-hovered,.button.is-black.is-outlined:focus,.button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}.button.is-black.is-outlined.is-loading:hover::after,.button.is-black.is-outlined.is-loading.is-hovered::after,.button.is-black.is-outlined.is-loading:focus::after,.button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-black.is-outlined[disabled],fieldset[disabled] .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-black.is-inverted.is-outlined:hover,.button.is-black.is-inverted.is-outlined.is-hovered,.button.is-black.is-inverted.is-outlined:focus,.button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted.is-outlined.is-loading:hover::after,.button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-black.is-inverted.is-outlined.is-loading:focus::after,.button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}.button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-light{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-light:hover,.button.is-light.is-hovered{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-light:focus,.button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-light:focus:not(:active),.button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}.button.is-light:active,.button.is-light.is-active{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-light[disabled],fieldset[disabled] .button.is-light{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none}.button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);color:#f5f5f5}.button.is-light.is-inverted:hover,.button.is-light.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}.button.is-light.is-inverted[disabled],fieldset[disabled] .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#f5f5f5}.button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}.button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}.button.is-light.is-outlined:hover,.button.is-light.is-outlined.is-hovered,.button.is-light.is-outlined:focus,.button.is-light.is-outlined.is-focused{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}.button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}.button.is-light.is-outlined.is-loading:hover::after,.button.is-light.is-outlined.is-loading.is-hovered::after,.button.is-light.is-outlined.is-loading:focus::after,.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}.button.is-light.is-outlined[disabled],fieldset[disabled] .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}.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)}.button.is-light.is-inverted.is-outlined:hover,.button.is-light.is-inverted.is-outlined.is-hovered,.button.is-light.is-inverted.is-outlined:focus,.button.is-light.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#f5f5f5}.button.is-light.is-inverted.is-outlined.is-loading:hover::after,.button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-light.is-inverted.is-outlined.is-loading:focus::after,.button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}.button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] .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)}.button.is-dark,.content kbd.button{background-color:#363636;border-color:transparent;color:#fff}.button.is-dark:hover,.content kbd.button:hover,.button.is-dark.is-hovered,.content kbd.button.is-hovered{background-color:#2f2f2f;border-color:transparent;color:#fff}.button.is-dark:focus,.content kbd.button:focus,.button.is-dark.is-focused,.content kbd.button.is-focused{border-color:transparent;color:#fff}.button.is-dark:focus:not(:active),.content kbd.button:focus:not(:active),.button.is-dark.is-focused:not(:active),.content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(54,54,54,0.25)}.button.is-dark:active,.content kbd.button:active,.button.is-dark.is-active,.content kbd.button.is-active{background-color:#292929;border-color:transparent;color:#fff}.button.is-dark[disabled],.content kbd.button[disabled],fieldset[disabled] .button.is-dark,fieldset[disabled] .content kbd.button,.content fieldset[disabled] kbd.button{background-color:#363636;border-color:#363636;box-shadow:none}.button.is-dark.is-inverted,.content kbd.button.is-inverted{background-color:#fff;color:#363636}.button.is-dark.is-inverted:hover,.content kbd.button.is-inverted:hover,.button.is-dark.is-inverted.is-hovered,.content kbd.button.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-dark.is-inverted[disabled],.content kbd.button.is-inverted[disabled],fieldset[disabled] .button.is-dark.is-inverted,fieldset[disabled] .content kbd.button.is-inverted,.content fieldset[disabled] kbd.button.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#363636}.button.is-dark.is-loading::after,.content kbd.button.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-dark.is-outlined,.content kbd.button.is-outlined{background-color:transparent;border-color:#363636;color:#363636}.button.is-dark.is-outlined:hover,.content kbd.button.is-outlined:hover,.button.is-dark.is-outlined.is-hovered,.content kbd.button.is-outlined.is-hovered,.button.is-dark.is-outlined:focus,.content kbd.button.is-outlined:focus,.button.is-dark.is-outlined.is-focused,.content kbd.button.is-outlined.is-focused{background-color:#363636;border-color:#363636;color:#fff}.button.is-dark.is-outlined.is-loading::after,.content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #363636 #363636 !important}.button.is-dark.is-outlined.is-loading:hover::after,.content kbd.button.is-outlined.is-loading:hover::after,.button.is-dark.is-outlined.is-loading.is-hovered::after,.content kbd.button.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-outlined.is-loading:focus::after,.content kbd.button.is-outlined.is-loading:focus::after,.button.is-dark.is-outlined.is-loading.is-focused::after,.content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-dark.is-outlined[disabled],.content kbd.button.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-outlined,fieldset[disabled] .content kbd.button.is-outlined,.content fieldset[disabled] kbd.button.is-outlined{background-color:transparent;border-color:#363636;box-shadow:none;color:#363636}.button.is-dark.is-inverted.is-outlined,.content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-dark.is-inverted.is-outlined:hover,.content kbd.button.is-inverted.is-outlined:hover,.button.is-dark.is-inverted.is-outlined.is-hovered,.content kbd.button.is-inverted.is-outlined.is-hovered,.button.is-dark.is-inverted.is-outlined:focus,.content kbd.button.is-inverted.is-outlined:focus,.button.is-dark.is-inverted.is-outlined.is-focused,.content kbd.button.is-inverted.is-outlined.is-focused{background-color:#fff;color:#363636}.button.is-dark.is-inverted.is-outlined.is-loading:hover::after,.content kbd.button.is-inverted.is-outlined.is-loading:hover::after,.button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,.content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-inverted.is-outlined.is-loading:focus::after,.content kbd.button.is-inverted.is-outlined.is-loading:focus::after,.button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,.content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #363636 #363636 !important}.button.is-dark.is-inverted.is-outlined[disabled],.content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-inverted.is-outlined,fieldset[disabled] .content kbd.button.is-inverted.is-outlined,.content fieldset[disabled] kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-primary,.docstring>section>a.button.docs-sourcelink{background-color:#4eb5de;border-color:transparent;color:#fff}.button.is-primary:hover,.docstring>section>a.button.docs-sourcelink:hover,.button.is-primary.is-hovered,.docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#43b1dc;border-color:transparent;color:#fff}.button.is-primary:focus,.docstring>section>a.button.docs-sourcelink:focus,.button.is-primary.is-focused,.docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}.button.is-primary:focus:not(:active),.docstring>section>a.button.docs-sourcelink:focus:not(:active),.button.is-primary.is-focused:not(:active),.docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(78,181,222,0.25)}.button.is-primary:active,.docstring>section>a.button.docs-sourcelink:active,.button.is-primary.is-active,.docstring>section>a.button.is-active.docs-sourcelink{background-color:#39acda;border-color:transparent;color:#fff}.button.is-primary[disabled],.docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] .button.is-primary,fieldset[disabled] .docstring>section>a.button.docs-sourcelink{background-color:#4eb5de;border-color:#4eb5de;box-shadow:none}.button.is-primary.is-inverted,.docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#4eb5de}.button.is-primary.is-inverted:hover,.docstring>section>a.button.is-inverted.docs-sourcelink:hover,.button.is-primary.is-inverted.is-hovered,.docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}.button.is-primary.is-inverted[disabled],.docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] .button.is-primary.is-inverted,fieldset[disabled] .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#4eb5de}.button.is-primary.is-loading::after,.docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}.button.is-primary.is-outlined,.docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#4eb5de;color:#4eb5de}.button.is-primary.is-outlined:hover,.docstring>section>a.button.is-outlined.docs-sourcelink:hover,.button.is-primary.is-outlined.is-hovered,.docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,.button.is-primary.is-outlined:focus,.docstring>section>a.button.is-outlined.docs-sourcelink:focus,.button.is-primary.is-outlined.is-focused,.docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#4eb5de;border-color:#4eb5de;color:#fff}.button.is-primary.is-outlined.is-loading::after,.docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #4eb5de #4eb5de !important}.button.is-primary.is-outlined.is-loading:hover::after,.docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,.button.is-primary.is-outlined.is-loading.is-hovered::after,.docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,.button.is-primary.is-outlined.is-loading:focus::after,.docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,.button.is-primary.is-outlined.is-loading.is-focused::after,.docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}.button.is-primary.is-outlined[disabled],.docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] .button.is-primary.is-outlined,fieldset[disabled] .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#4eb5de;box-shadow:none;color:#4eb5de}.button.is-primary.is-inverted.is-outlined,.docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}.button.is-primary.is-inverted.is-outlined:hover,.docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,.button.is-primary.is-inverted.is-outlined.is-hovered,.docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,.button.is-primary.is-inverted.is-outlined:focus,.docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,.button.is-primary.is-inverted.is-outlined.is-focused,.docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#4eb5de}.button.is-primary.is-inverted.is-outlined.is-loading:hover::after,.docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,.button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,.docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,.button.is-primary.is-inverted.is-outlined.is-loading:focus::after,.docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,.button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,.docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #4eb5de #4eb5de !important}.button.is-primary.is-inverted.is-outlined[disabled],.docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] .button.is-primary.is-inverted.is-outlined,fieldset[disabled] .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-primary.is-light,.docstring>section>a.button.is-light.docs-sourcelink{background-color:#eef8fc;color:#1a6d8e}.button.is-primary.is-light:hover,.docstring>section>a.button.is-light.docs-sourcelink:hover,.button.is-primary.is-light.is-hovered,.docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#e3f3fa;border-color:transparent;color:#1a6d8e}.button.is-primary.is-light:active,.docstring>section>a.button.is-light.docs-sourcelink:active,.button.is-primary.is-light.is-active,.docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#d8eff8;border-color:transparent;color:#1a6d8e}.button.is-link{background-color:#2e63b8;border-color:transparent;color:#fff}.button.is-link:hover,.button.is-link.is-hovered{background-color:#2b5eae;border-color:transparent;color:#fff}.button.is-link:focus,.button.is-link.is-focused{border-color:transparent;color:#fff}.button.is-link:focus:not(:active),.button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.button.is-link:active,.button.is-link.is-active{background-color:#2958a4;border-color:transparent;color:#fff}.button.is-link[disabled],fieldset[disabled] .button.is-link{background-color:#2e63b8;border-color:#2e63b8;box-shadow:none}.button.is-link.is-inverted{background-color:#fff;color:#2e63b8}.button.is-link.is-inverted:hover,.button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-link.is-inverted[disabled],fieldset[disabled] .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#2e63b8}.button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-link.is-outlined{background-color:transparent;border-color:#2e63b8;color:#2e63b8}.button.is-link.is-outlined:hover,.button.is-link.is-outlined.is-hovered,.button.is-link.is-outlined:focus,.button.is-link.is-outlined.is-focused{background-color:#2e63b8;border-color:#2e63b8;color:#fff}.button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #2e63b8 #2e63b8 !important}.button.is-link.is-outlined.is-loading:hover::after,.button.is-link.is-outlined.is-loading.is-hovered::after,.button.is-link.is-outlined.is-loading:focus::after,.button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-link.is-outlined[disabled],fieldset[disabled] .button.is-link.is-outlined{background-color:transparent;border-color:#2e63b8;box-shadow:none;color:#2e63b8}.button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-link.is-inverted.is-outlined:hover,.button.is-link.is-inverted.is-outlined.is-hovered,.button.is-link.is-inverted.is-outlined:focus,.button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#2e63b8}.button.is-link.is-inverted.is-outlined.is-loading:hover::after,.button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-link.is-inverted.is-outlined.is-loading:focus::after,.button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #2e63b8 #2e63b8 !important}.button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-link.is-light{background-color:#eff3fb;color:#3169c4}.button.is-link.is-light:hover,.button.is-link.is-light.is-hovered{background-color:#e4ecf8;border-color:transparent;color:#3169c4}.button.is-link.is-light:active,.button.is-link.is-light.is-active{background-color:#dae5f6;border-color:transparent;color:#3169c4}.button.is-info{background-color:#209cee;border-color:transparent;color:#fff}.button.is-info:hover,.button.is-info.is-hovered{background-color:#1497ed;border-color:transparent;color:#fff}.button.is-info:focus,.button.is-info.is-focused{border-color:transparent;color:#fff}.button.is-info:focus:not(:active),.button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(32,156,238,0.25)}.button.is-info:active,.button.is-info.is-active{background-color:#1190e3;border-color:transparent;color:#fff}.button.is-info[disabled],fieldset[disabled] .button.is-info{background-color:#209cee;border-color:#209cee;box-shadow:none}.button.is-info.is-inverted{background-color:#fff;color:#209cee}.button.is-info.is-inverted:hover,.button.is-info.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-info.is-inverted[disabled],fieldset[disabled] .button.is-info.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#209cee}.button.is-info.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-info.is-outlined{background-color:transparent;border-color:#209cee;color:#209cee}.button.is-info.is-outlined:hover,.button.is-info.is-outlined.is-hovered,.button.is-info.is-outlined:focus,.button.is-info.is-outlined.is-focused{background-color:#209cee;border-color:#209cee;color:#fff}.button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #209cee #209cee !important}.button.is-info.is-outlined.is-loading:hover::after,.button.is-info.is-outlined.is-loading.is-hovered::after,.button.is-info.is-outlined.is-loading:focus::after,.button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-info.is-outlined[disabled],fieldset[disabled] .button.is-info.is-outlined{background-color:transparent;border-color:#209cee;box-shadow:none;color:#209cee}.button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-info.is-inverted.is-outlined:hover,.button.is-info.is-inverted.is-outlined.is-hovered,.button.is-info.is-inverted.is-outlined:focus,.button.is-info.is-inverted.is-outlined.is-focused{background-color:#fff;color:#209cee}.button.is-info.is-inverted.is-outlined.is-loading:hover::after,.button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-info.is-inverted.is-outlined.is-loading:focus::after,.button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #209cee #209cee !important}.button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-info.is-light{background-color:#ecf7fe;color:#0e72b4}.button.is-info.is-light:hover,.button.is-info.is-light.is-hovered{background-color:#e0f1fd;border-color:transparent;color:#0e72b4}.button.is-info.is-light:active,.button.is-info.is-light.is-active{background-color:#d4ecfc;border-color:transparent;color:#0e72b4}.button.is-success{background-color:#22c35b;border-color:transparent;color:#fff}.button.is-success:hover,.button.is-success.is-hovered{background-color:#20b856;border-color:transparent;color:#fff}.button.is-success:focus,.button.is-success.is-focused{border-color:transparent;color:#fff}.button.is-success:focus:not(:active),.button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(34,195,91,0.25)}.button.is-success:active,.button.is-success.is-active{background-color:#1ead51;border-color:transparent;color:#fff}.button.is-success[disabled],fieldset[disabled] .button.is-success{background-color:#22c35b;border-color:#22c35b;box-shadow:none}.button.is-success.is-inverted{background-color:#fff;color:#22c35b}.button.is-success.is-inverted:hover,.button.is-success.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-success.is-inverted[disabled],fieldset[disabled] .button.is-success.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#22c35b}.button.is-success.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-success.is-outlined{background-color:transparent;border-color:#22c35b;color:#22c35b}.button.is-success.is-outlined:hover,.button.is-success.is-outlined.is-hovered,.button.is-success.is-outlined:focus,.button.is-success.is-outlined.is-focused{background-color:#22c35b;border-color:#22c35b;color:#fff}.button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #22c35b #22c35b !important}.button.is-success.is-outlined.is-loading:hover::after,.button.is-success.is-outlined.is-loading.is-hovered::after,.button.is-success.is-outlined.is-loading:focus::after,.button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-success.is-outlined[disabled],fieldset[disabled] .button.is-success.is-outlined{background-color:transparent;border-color:#22c35b;box-shadow:none;color:#22c35b}.button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-success.is-inverted.is-outlined:hover,.button.is-success.is-inverted.is-outlined.is-hovered,.button.is-success.is-inverted.is-outlined:focus,.button.is-success.is-inverted.is-outlined.is-focused{background-color:#fff;color:#22c35b}.button.is-success.is-inverted.is-outlined.is-loading:hover::after,.button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-success.is-inverted.is-outlined.is-loading:focus::after,.button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #22c35b #22c35b !important}.button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-success.is-light{background-color:#eefcf3;color:#198f43}.button.is-success.is-light:hover,.button.is-success.is-light.is-hovered{background-color:#e3faeb;border-color:transparent;color:#198f43}.button.is-success.is-light:active,.button.is-success.is-light.is-active{background-color:#d8f8e3;border-color:transparent;color:#198f43}.button.is-warning{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-warning:hover,.button.is-warning.is-hovered{background-color:#ffda4a;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-warning:focus,.button.is-warning.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-warning:focus:not(:active),.button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,221,87,0.25)}.button.is-warning:active,.button.is-warning.is-active{background-color:#ffd83e;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-warning[disabled],fieldset[disabled] .button.is-warning{background-color:#ffdd57;border-color:#ffdd57;box-shadow:none}.button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);color:#ffdd57}.button.is-warning.is-inverted:hover,.button.is-warning.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}.button.is-warning.is-inverted[disabled],fieldset[disabled] .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#ffdd57}.button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}.button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;color:#ffdd57}.button.is-warning.is-outlined:hover,.button.is-warning.is-outlined.is-hovered,.button.is-warning.is-outlined:focus,.button.is-warning.is-outlined.is-focused{background-color:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,0.7)}.button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #ffdd57 #ffdd57 !important}.button.is-warning.is-outlined.is-loading:hover::after,.button.is-warning.is-outlined.is-loading.is-hovered::after,.button.is-warning.is-outlined.is-loading:focus::after,.button.is-warning.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}.button.is-warning.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;box-shadow:none;color:#ffdd57}.button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}.button.is-warning.is-inverted.is-outlined:hover,.button.is-warning.is-inverted.is-outlined.is-hovered,.button.is-warning.is-inverted.is-outlined:focus,.button.is-warning.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#ffdd57}.button.is-warning.is-inverted.is-outlined.is-loading:hover::after,.button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-warning.is-inverted.is-outlined.is-loading:focus::after,.button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ffdd57 #ffdd57 !important}.button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-warning.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)}.button.is-warning.is-light{background-color:#fffbeb;color:#947600}.button.is-warning.is-light:hover,.button.is-warning.is-light.is-hovered{background-color:#fff8de;border-color:transparent;color:#947600}.button.is-warning.is-light:active,.button.is-warning.is-light.is-active{background-color:#fff6d1;border-color:transparent;color:#947600}.button.is-danger{background-color:#da0b00;border-color:transparent;color:#fff}.button.is-danger:hover,.button.is-danger.is-hovered{background-color:#cd0a00;border-color:transparent;color:#fff}.button.is-danger:focus,.button.is-danger.is-focused{border-color:transparent;color:#fff}.button.is-danger:focus:not(:active),.button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(218,11,0,0.25)}.button.is-danger:active,.button.is-danger.is-active{background-color:#c10a00;border-color:transparent;color:#fff}.button.is-danger[disabled],fieldset[disabled] .button.is-danger{background-color:#da0b00;border-color:#da0b00;box-shadow:none}.button.is-danger.is-inverted{background-color:#fff;color:#da0b00}.button.is-danger.is-inverted:hover,.button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-danger.is-inverted[disabled],fieldset[disabled] .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#da0b00}.button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-danger.is-outlined{background-color:transparent;border-color:#da0b00;color:#da0b00}.button.is-danger.is-outlined:hover,.button.is-danger.is-outlined.is-hovered,.button.is-danger.is-outlined:focus,.button.is-danger.is-outlined.is-focused{background-color:#da0b00;border-color:#da0b00;color:#fff}.button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #da0b00 #da0b00 !important}.button.is-danger.is-outlined.is-loading:hover::after,.button.is-danger.is-outlined.is-loading.is-hovered::after,.button.is-danger.is-outlined.is-loading:focus::after,.button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-danger.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-outlined{background-color:transparent;border-color:#da0b00;box-shadow:none;color:#da0b00}.button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-danger.is-inverted.is-outlined:hover,.button.is-danger.is-inverted.is-outlined.is-hovered,.button.is-danger.is-inverted.is-outlined:focus,.button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#da0b00}.button.is-danger.is-inverted.is-outlined.is-loading:hover::after,.button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-danger.is-inverted.is-outlined.is-loading:focus::after,.button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #da0b00 #da0b00 !important}.button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-danger.is-light{background-color:#ffeceb;color:#f50c00}.button.is-danger.is-light:hover,.button.is-danger.is-light.is-hovered{background-color:#ffe0de;border-color:transparent;color:#f50c00}.button.is-danger.is-light:active,.button.is-danger.is-light.is-active{background-color:#ffd3d1;border-color:transparent;color:#f50c00}.button.is-small,#documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}.button.is-small:not(.is-rounded),#documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:2px}.button.is-normal{font-size:1rem}.button.is-medium{font-size:1.25rem}.button.is-large{font-size:1.5rem}.button[disabled],fieldset[disabled] .button{background-color:#fff;border-color:#dbdbdb;box-shadow:none;opacity:.5}.button.is-fullwidth{display:flex;width:100%}.button.is-loading{color:transparent !important;pointer-events:none}.button.is-loading::after{position:absolute;left:calc(50% - (1em * 0.5));top:calc(50% - (1em * 0.5));position:absolute !important}.button.is-static{background-color:#f5f5f5;border-color:#dbdbdb;color:#6b6b6b;box-shadow:none;pointer-events:none}.button.is-rounded,#documenter .docs-sidebar form.docs-search>input.button{border-radius:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}.buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.buttons .button{margin-bottom:0.5rem}.buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}.buttons:last-child{margin-bottom:-0.5rem}.buttons:not(:last-child){margin-bottom:1rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:2px}.buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}.buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}.buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.buttons.has-addons .button:last-child{margin-right:0}.buttons.has-addons .button:hover,.buttons.has-addons .button.is-hovered{z-index:2}.buttons.has-addons .button:focus,.buttons.has-addons .button.is-focused,.buttons.has-addons .button:active,.buttons.has-addons .button.is-active,.buttons.has-addons .button.is-selected{z-index:3}.buttons.has-addons .button:focus:hover,.buttons.has-addons .button.is-focused:hover,.buttons.has-addons .button:active:hover,.buttons.has-addons .button.is-active:hover,.buttons.has-addons .button.is-selected:hover{z-index:4}.buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}.buttons.is-centered{justify-content:center}.buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}.buttons.is-right{justify-content:flex-end}.buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}@media screen and (max-width: 768px){.button.is-responsive.is-small,#documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}.button.is-responsive,.button.is-responsive.is-normal{font-size:.65625rem}.button.is-responsive.is-medium{font-size:.75rem}.button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.button.is-responsive.is-small,#documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}.button.is-responsive,.button.is-responsive.is-normal{font-size:.75rem}.button.is-responsive.is-medium{font-size:1rem}.button.is-responsive.is-large{font-size:1.25rem}}.container{flex-grow:1;margin:0 auto;position:relative;width:auto}.container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){.container{max-width:992px}}@media screen and (max-width: 1215px){.container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){.container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){.container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){.container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}.content li+li{margin-top:0.25em}.content p:not(:last-child),.content dl:not(:last-child),.content ol:not(:last-child),.content ul:not(:last-child),.content blockquote:not(:last-child),.content pre:not(:last-child),.content table:not(:last-child){margin-bottom:1em}.content h1,.content h2,.content h3,.content h4,.content h5,.content h6{color:#222;font-weight:600;line-height:1.125}.content h1{font-size:2em;margin-bottom:0.5em}.content h1:not(:first-child){margin-top:1em}.content h2{font-size:1.75em;margin-bottom:0.5714em}.content h2:not(:first-child){margin-top:1.1428em}.content h3{font-size:1.5em;margin-bottom:0.6666em}.content h3:not(:first-child){margin-top:1.3333em}.content h4{font-size:1.25em;margin-bottom:0.8em}.content h5{font-size:1.125em;margin-bottom:0.8888em}.content h6{font-size:1em;margin-bottom:1em}.content blockquote{background-color:#f5f5f5;border-left:5px solid #dbdbdb;padding:1.25em 1.5em}.content ol{list-style-position:outside;margin-left:2em;margin-top:1em}.content ol:not([type]){list-style-type:decimal}.content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}.content ol.is-lower-roman:not([type]){list-style-type:lower-roman}.content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}.content ol.is-upper-roman:not([type]){list-style-type:upper-roman}.content ul{list-style:disc outside;margin-left:2em;margin-top:1em}.content ul ul{list-style-type:circle;margin-top:0.5em}.content ul ul ul{list-style-type:square}.content dd{margin-left:2em}.content figure{margin-left:2em;margin-right:2em;text-align:center}.content figure:not(:first-child){margin-top:2em}.content figure:not(:last-child){margin-bottom:2em}.content figure img{display:inline-block}.content figure figcaption{font-style:italic}.content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}.content sup,.content sub{font-size:75%}.content table{width:100%}.content table td,.content table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}.content table th{color:#222}.content table th:not([align]){text-align:inherit}.content table thead td,.content table thead th{border-width:0 0 2px;color:#222}.content table tfoot td,.content table tfoot th{border-width:2px 0 0;color:#222}.content table tbody tr:last-child td,.content table tbody tr:last-child th{border-bottom-width:0}.content .tabs li+li{margin-top:0}.content.is-small,#documenter .docs-sidebar form.docs-search>input.content{font-size:.75rem}.content.is-normal{font-size:1rem}.content.is-medium{font-size:1.25rem}.content.is-large{font-size:1.5rem}.icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}.icon.is-small,#documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}.icon.is-medium{height:2rem;width:2rem}.icon.is-large{height:3rem;width:3rem}.icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}.icon-text .icon{flex-grow:0;flex-shrink:0}.icon-text .icon:not(:last-child){margin-right:.25em}.icon-text .icon:not(:first-child){margin-left:.25em}div.icon-text{display:flex}.image,#documenter .docs-sidebar .docs-logo>img{display:block;position:relative}.image img,#documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}.image img.is-rounded,#documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:9999px}.image.is-fullwidth,#documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}.image.is-square img,#documenter .docs-sidebar .docs-logo>img.is-square img,.image.is-square .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,.image.is-1by1 img,#documenter .docs-sidebar .docs-logo>img.is-1by1 img,.image.is-1by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,.image.is-5by4 img,#documenter .docs-sidebar .docs-logo>img.is-5by4 img,.image.is-5by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,.image.is-4by3 img,#documenter .docs-sidebar .docs-logo>img.is-4by3 img,.image.is-4by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,.image.is-3by2 img,#documenter .docs-sidebar .docs-logo>img.is-3by2 img,.image.is-3by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,.image.is-5by3 img,#documenter .docs-sidebar .docs-logo>img.is-5by3 img,.image.is-5by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,.image.is-16by9 img,#documenter .docs-sidebar .docs-logo>img.is-16by9 img,.image.is-16by9 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,.image.is-2by1 img,#documenter .docs-sidebar .docs-logo>img.is-2by1 img,.image.is-2by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,.image.is-3by1 img,#documenter .docs-sidebar .docs-logo>img.is-3by1 img,.image.is-3by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,.image.is-4by5 img,#documenter .docs-sidebar .docs-logo>img.is-4by5 img,.image.is-4by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,.image.is-3by4 img,#documenter .docs-sidebar .docs-logo>img.is-3by4 img,.image.is-3by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,.image.is-2by3 img,#documenter .docs-sidebar .docs-logo>img.is-2by3 img,.image.is-2by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,.image.is-3by5 img,#documenter .docs-sidebar .docs-logo>img.is-3by5 img,.image.is-3by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,.image.is-9by16 img,#documenter .docs-sidebar .docs-logo>img.is-9by16 img,.image.is-9by16 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,.image.is-1by2 img,#documenter .docs-sidebar .docs-logo>img.is-1by2 img,.image.is-1by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,.image.is-1by3 img,#documenter .docs-sidebar .docs-logo>img.is-1by3 img,.image.is-1by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}.image.is-square,#documenter .docs-sidebar .docs-logo>img.is-square,.image.is-1by1,#documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}.image.is-5by4,#documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}.image.is-4by3,#documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}.image.is-3by2,#documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}.image.is-5by3,#documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}.image.is-16by9,#documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}.image.is-2by1,#documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}.image.is-3by1,#documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}.image.is-4by5,#documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}.image.is-3by4,#documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}.image.is-2by3,#documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}.image.is-3by5,#documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}.image.is-9by16,#documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}.image.is-1by2,#documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}.image.is-1by3,#documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}.image.is-16x16,#documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}.image.is-24x24,#documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}.image.is-32x32,#documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}.image.is-48x48,#documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}.image.is-64x64,#documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}.image.is-96x96,#documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}.image.is-128x128,#documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}.notification{background-color:#f5f5f5;border-radius:4px;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}.notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}.notification strong{color:currentColor}.notification code,.notification pre{background:#fff}.notification pre code{background:transparent}.notification>.delete{right:.5rem;position:absolute;top:0.5rem}.notification .title,.notification .subtitle,.notification .content{color:currentColor}.notification.is-white{background-color:#fff;color:#0a0a0a}.notification.is-black{background-color:#0a0a0a;color:#fff}.notification.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.notification.is-dark,.content kbd.notification{background-color:#363636;color:#fff}.notification.is-primary,.docstring>section>a.notification.docs-sourcelink{background-color:#4eb5de;color:#fff}.notification.is-primary.is-light,.docstring>section>a.notification.is-light.docs-sourcelink{background-color:#eef8fc;color:#1a6d8e}.notification.is-link{background-color:#2e63b8;color:#fff}.notification.is-link.is-light{background-color:#eff3fb;color:#3169c4}.notification.is-info{background-color:#209cee;color:#fff}.notification.is-info.is-light{background-color:#ecf7fe;color:#0e72b4}.notification.is-success{background-color:#22c35b;color:#fff}.notification.is-success.is-light{background-color:#eefcf3;color:#198f43}.notification.is-warning{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.notification.is-warning.is-light{background-color:#fffbeb;color:#947600}.notification.is-danger{background-color:#da0b00;color:#fff}.notification.is-danger.is-light{background-color:#ffeceb;color:#f50c00}.progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}.progress::-webkit-progress-bar{background-color:#ededed}.progress::-webkit-progress-value{background-color:#222}.progress::-moz-progress-bar{background-color:#222}.progress::-ms-fill{background-color:#222;border:none}.progress.is-white::-webkit-progress-value{background-color:#fff}.progress.is-white::-moz-progress-bar{background-color:#fff}.progress.is-white::-ms-fill{background-color:#fff}.progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #ededed 30%)}.progress.is-black::-webkit-progress-value{background-color:#0a0a0a}.progress.is-black::-moz-progress-bar{background-color:#0a0a0a}.progress.is-black::-ms-fill{background-color:#0a0a0a}.progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #ededed 30%)}.progress.is-light::-webkit-progress-value{background-color:#f5f5f5}.progress.is-light::-moz-progress-bar{background-color:#f5f5f5}.progress.is-light::-ms-fill{background-color:#f5f5f5}.progress.is-light:indeterminate{background-image:linear-gradient(to right, #f5f5f5 30%, #ededed 30%)}.progress.is-dark::-webkit-progress-value,.content kbd.progress::-webkit-progress-value{background-color:#363636}.progress.is-dark::-moz-progress-bar,.content kbd.progress::-moz-progress-bar{background-color:#363636}.progress.is-dark::-ms-fill,.content kbd.progress::-ms-fill{background-color:#363636}.progress.is-dark:indeterminate,.content kbd.progress:indeterminate{background-image:linear-gradient(to right, #363636 30%, #ededed 30%)}.progress.is-primary::-webkit-progress-value,.docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#4eb5de}.progress.is-primary::-moz-progress-bar,.docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#4eb5de}.progress.is-primary::-ms-fill,.docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#4eb5de}.progress.is-primary:indeterminate,.docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #4eb5de 30%, #ededed 30%)}.progress.is-link::-webkit-progress-value{background-color:#2e63b8}.progress.is-link::-moz-progress-bar{background-color:#2e63b8}.progress.is-link::-ms-fill{background-color:#2e63b8}.progress.is-link:indeterminate{background-image:linear-gradient(to right, #2e63b8 30%, #ededed 30%)}.progress.is-info::-webkit-progress-value{background-color:#209cee}.progress.is-info::-moz-progress-bar{background-color:#209cee}.progress.is-info::-ms-fill{background-color:#209cee}.progress.is-info:indeterminate{background-image:linear-gradient(to right, #209cee 30%, #ededed 30%)}.progress.is-success::-webkit-progress-value{background-color:#22c35b}.progress.is-success::-moz-progress-bar{background-color:#22c35b}.progress.is-success::-ms-fill{background-color:#22c35b}.progress.is-success:indeterminate{background-image:linear-gradient(to right, #22c35b 30%, #ededed 30%)}.progress.is-warning::-webkit-progress-value{background-color:#ffdd57}.progress.is-warning::-moz-progress-bar{background-color:#ffdd57}.progress.is-warning::-ms-fill{background-color:#ffdd57}.progress.is-warning:indeterminate{background-image:linear-gradient(to right, #ffdd57 30%, #ededed 30%)}.progress.is-danger::-webkit-progress-value{background-color:#da0b00}.progress.is-danger::-moz-progress-bar{background-color:#da0b00}.progress.is-danger::-ms-fill{background-color:#da0b00}.progress.is-danger:indeterminate{background-image:linear-gradient(to right, #da0b00 30%, #ededed 30%)}.progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#ededed;background-image:linear-gradient(to right, #222 30%, #ededed 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}.progress:indeterminate::-webkit-progress-bar{background-color:transparent}.progress:indeterminate::-moz-progress-bar{background-color:transparent}.progress:indeterminate::-ms-fill{animation-name:none}.progress.is-small,#documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}.progress.is-medium{height:1.25rem}.progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}.table{background-color:#fff;color:#222}.table td,.table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}.table td.is-white,.table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}.table td.is-black,.table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.table td.is-light,.table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}.table td.is-dark,.table th.is-dark{background-color:#363636;border-color:#363636;color:#fff}.table td.is-primary,.table th.is-primary{background-color:#4eb5de;border-color:#4eb5de;color:#fff}.table td.is-link,.table th.is-link{background-color:#2e63b8;border-color:#2e63b8;color:#fff}.table td.is-info,.table th.is-info{background-color:#209cee;border-color:#209cee;color:#fff}.table td.is-success,.table th.is-success{background-color:#22c35b;border-color:#22c35b;color:#fff}.table td.is-warning,.table th.is-warning{background-color:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,0.7)}.table td.is-danger,.table th.is-danger{background-color:#da0b00;border-color:#da0b00;color:#fff}.table td.is-narrow,.table th.is-narrow{white-space:nowrap;width:1%}.table td.is-selected,.table th.is-selected{background-color:#4eb5de;color:#fff}.table td.is-selected a,.table td.is-selected strong,.table th.is-selected a,.table th.is-selected strong{color:currentColor}.table td.is-vcentered,.table th.is-vcentered{vertical-align:middle}.table th{color:#222}.table th:not([align]){text-align:left}.table tr.is-selected{background-color:#4eb5de;color:#fff}.table tr.is-selected a,.table tr.is-selected strong{color:currentColor}.table tr.is-selected td,.table tr.is-selected th{border-color:#fff;color:currentColor}.table thead{background-color:rgba(0,0,0,0)}.table thead td,.table thead th{border-width:0 0 2px;color:#222}.table tfoot{background-color:rgba(0,0,0,0)}.table tfoot td,.table tfoot th{border-width:2px 0 0;color:#222}.table tbody{background-color:rgba(0,0,0,0)}.table tbody tr:last-child td,.table tbody tr:last-child th{border-bottom-width:0}.table.is-bordered td,.table.is-bordered th{border-width:1px}.table.is-bordered tr:last-child td,.table.is-bordered tr:last-child th{border-bottom-width:1px}.table.is-fullwidth{width:100%}.table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#f5f5f5}.table.is-narrow td,.table.is-narrow th{padding:0.25em 0.5em}.table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#fafafa}.table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}.tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.tags .tag,.tags .content kbd,.content .tags kbd,.tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}.tags .tag:not(:last-child),.tags .content kbd:not(:last-child),.content .tags kbd:not(:last-child),.tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:.5rem}.tags:last-child{margin-bottom:-0.5rem}.tags:not(:last-child){margin-bottom:1rem}.tags.are-medium .tag:not(.is-normal):not(.is-large),.tags.are-medium .content kbd:not(.is-normal):not(.is-large),.content .tags.are-medium kbd:not(.is-normal):not(.is-large),.tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:1rem}.tags.are-large .tag:not(.is-normal):not(.is-medium),.tags.are-large .content kbd:not(.is-normal):not(.is-medium),.content .tags.are-large kbd:not(.is-normal):not(.is-medium),.tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}.tags.is-centered{justify-content:center}.tags.is-centered .tag,.tags.is-centered .content kbd,.content .tags.is-centered kbd,.tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}.tags.is-right{justify-content:flex-end}.tags.is-right .tag:not(:first-child),.tags.is-right .content kbd:not(:first-child),.content .tags.is-right kbd:not(:first-child),.tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}.tags.is-right .tag:not(:last-child),.tags.is-right .content kbd:not(:last-child),.content .tags.is-right kbd:not(:last-child),.tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}.tags.has-addons .tag,.tags.has-addons .content kbd,.content .tags.has-addons kbd,.tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}.tags.has-addons .tag:not(:first-child),.tags.has-addons .content kbd:not(:first-child),.content .tags.has-addons kbd:not(:first-child),.tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.tags.has-addons .tag:not(:last-child),.tags.has-addons .content kbd:not(:last-child),.content .tags.has-addons kbd:not(:last-child),.tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.tag:not(body),.content kbd:not(body),.docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#f5f5f5;border-radius:4px;color:#222;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}.tag:not(body) .delete,.content kbd:not(body) .delete,.docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}.tag.is-white:not(body),.content kbd.is-white:not(body),.docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}.tag.is-black:not(body),.content kbd.is-black:not(body),.docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}.tag.is-light:not(body),.content kbd.is-light:not(body),.docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.tag.is-dark:not(body),.content kbd:not(body),.docstring>section>a.docs-sourcelink.is-dark:not(body),.content .docstring>section>kbd:not(body){background-color:#363636;color:#fff}.tag.is-primary:not(body),.content kbd.is-primary:not(body),.docstring>section>a.docs-sourcelink:not(body){background-color:#4eb5de;color:#fff}.tag.is-primary.is-light:not(body),.content kbd.is-primary.is-light:not(body),.docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#eef8fc;color:#1a6d8e}.tag.is-link:not(body),.content kbd.is-link:not(body),.docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#2e63b8;color:#fff}.tag.is-link.is-light:not(body),.content kbd.is-link.is-light:not(body),.docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#eff3fb;color:#3169c4}.tag.is-info:not(body),.content kbd.is-info:not(body),.docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#209cee;color:#fff}.tag.is-info.is-light:not(body),.content kbd.is-info.is-light:not(body),.docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#ecf7fe;color:#0e72b4}.tag.is-success:not(body),.content kbd.is-success:not(body),.docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#22c35b;color:#fff}.tag.is-success.is-light:not(body),.content kbd.is-success.is-light:not(body),.docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#eefcf3;color:#198f43}.tag.is-warning:not(body),.content kbd.is-warning:not(body),.docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#ffdd57;color:rgba(0,0,0,0.7)}.tag.is-warning.is-light:not(body),.content kbd.is-warning.is-light:not(body),.docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fffbeb;color:#947600}.tag.is-danger:not(body),.content kbd.is-danger:not(body),.docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#da0b00;color:#fff}.tag.is-danger.is-light:not(body),.content kbd.is-danger.is-light:not(body),.docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#ffeceb;color:#f50c00}.tag.is-normal:not(body),.content kbd.is-normal:not(body),.docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.75rem}.tag.is-medium:not(body),.content kbd.is-medium:not(body),.docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:1rem}.tag.is-large:not(body),.content kbd.is-large:not(body),.docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}.tag:not(body) .icon:first-child:not(:last-child),.content kbd:not(body) .icon:first-child:not(:last-child),.docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}.tag:not(body) .icon:last-child:not(:first-child),.content kbd:not(body) .icon:last-child:not(:first-child),.docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}.tag:not(body) .icon:first-child:last-child,.content kbd:not(body) .icon:first-child:last-child,.docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}.tag.is-delete:not(body),.content kbd.is-delete:not(body),.docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}.tag.is-delete:not(body)::before,.content kbd.is-delete:not(body)::before,.docstring>section>a.docs-sourcelink.is-delete:not(body)::before,.tag.is-delete:not(body)::after,.content kbd.is-delete:not(body)::after,.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}.tag.is-delete:not(body)::before,.content kbd.is-delete:not(body)::before,.docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}.tag.is-delete:not(body)::after,.content kbd.is-delete:not(body)::after,.docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}.tag.is-delete:not(body):hover,.content kbd.is-delete:not(body):hover,.docstring>section>a.docs-sourcelink.is-delete:not(body):hover,.tag.is-delete:not(body):focus,.content kbd.is-delete:not(body):focus,.docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#e8e8e8}.tag.is-delete:not(body):active,.content kbd.is-delete:not(body):active,.docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#dbdbdb}.tag.is-rounded:not(body),#documenter .docs-sidebar form.docs-search>input:not(body),.content kbd.is-rounded:not(body),#documenter .docs-sidebar .content form.docs-search>input:not(body),.docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:9999px}a.tag:hover,.docstring>section>a.docs-sourcelink:hover{text-decoration:underline}.title,.subtitle{word-break:break-word}.title em,.title span,.subtitle em,.subtitle span{font-weight:inherit}.title sub,.subtitle sub{font-size:.75em}.title sup,.subtitle sup{font-size:.75em}.title .tag,.title .content kbd,.content .title kbd,.title .docstring>section>a.docs-sourcelink,.subtitle .tag,.subtitle .content kbd,.content .subtitle kbd,.subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}.title{color:#222;font-size:2rem;font-weight:600;line-height:1.125}.title strong{color:inherit;font-weight:inherit}.title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}.title.is-1{font-size:3rem}.title.is-2{font-size:2.5rem}.title.is-3{font-size:2rem}.title.is-4{font-size:1.5rem}.title.is-5{font-size:1.25rem}.title.is-6{font-size:1rem}.title.is-7{font-size:.75rem}.subtitle{color:#222;font-size:1.25rem;font-weight:400;line-height:1.25}.subtitle strong{color:#222;font-weight:600}.subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}.subtitle.is-1{font-size:3rem}.subtitle.is-2{font-size:2.5rem}.subtitle.is-3{font-size:2rem}.subtitle.is-4{font-size:1.5rem}.subtitle.is-5{font-size:1.25rem}.subtitle.is-6{font-size:1rem}.subtitle.is-7{font-size:.75rem}.heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}.number{align-items:center;background-color:#f5f5f5;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}.select select,.textarea,.input,#documenter .docs-sidebar form.docs-search>input{background-color:#fff;border-color:#dbdbdb;border-radius:4px;color:#222}.select select::-moz-placeholder,.textarea::-moz-placeholder,.input::-moz-placeholder,#documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:#707070}.select select::-webkit-input-placeholder,.textarea::-webkit-input-placeholder,.input::-webkit-input-placeholder,#documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:#707070}.select select:-moz-placeholder,.textarea:-moz-placeholder,.input:-moz-placeholder,#documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:#707070}.select select:-ms-input-placeholder,.textarea:-ms-input-placeholder,.input:-ms-input-placeholder,#documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:#707070}.select select:hover,.textarea:hover,.input:hover,#documenter .docs-sidebar form.docs-search>input:hover,.select select.is-hovered,.is-hovered.textarea,.is-hovered.input,#documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#b5b5b5}.select select:focus,.textarea:focus,.input:focus,#documenter .docs-sidebar form.docs-search>input:focus,.select select.is-focused,.is-focused.textarea,.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.select select:active,.textarea:active,.input:active,#documenter .docs-sidebar form.docs-search>input:active,.select select.is-active,.is-active.textarea,.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{border-color:#2e63b8;box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.select select[disabled],.textarea[disabled],.input[disabled],#documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] .select select,.select fieldset[disabled] select,fieldset[disabled] .textarea,fieldset[disabled] .input,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none;color:#6b6b6b}.select select[disabled]::-moz-placeholder,.textarea[disabled]::-moz-placeholder,.input[disabled]::-moz-placeholder,#documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] .select select::-moz-placeholder,.select fieldset[disabled] select::-moz-placeholder,fieldset[disabled] .textarea::-moz-placeholder,fieldset[disabled] .input::-moz-placeholder,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input::-moz-placeholder,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input::-moz-placeholder{color:rgba(107,107,107,0.3)}.select select[disabled]::-webkit-input-placeholder,.textarea[disabled]::-webkit-input-placeholder,.input[disabled]::-webkit-input-placeholder,#documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] .select select::-webkit-input-placeholder,.select fieldset[disabled] select::-webkit-input-placeholder,fieldset[disabled] .textarea::-webkit-input-placeholder,fieldset[disabled] .input::-webkit-input-placeholder,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input::-webkit-input-placeholder{color:rgba(107,107,107,0.3)}.select select[disabled]:-moz-placeholder,.textarea[disabled]:-moz-placeholder,.input[disabled]:-moz-placeholder,#documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] .select select:-moz-placeholder,.select fieldset[disabled] select:-moz-placeholder,fieldset[disabled] .textarea:-moz-placeholder,fieldset[disabled] .input:-moz-placeholder,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input:-moz-placeholder,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input:-moz-placeholder{color:rgba(107,107,107,0.3)}.select select[disabled]:-ms-input-placeholder,.textarea[disabled]:-ms-input-placeholder,.input[disabled]:-ms-input-placeholder,#documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] .select select:-ms-input-placeholder,.select fieldset[disabled] select:-ms-input-placeholder,fieldset[disabled] .textarea:-ms-input-placeholder,fieldset[disabled] .input:-ms-input-placeholder,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input:-ms-input-placeholder{color:rgba(107,107,107,0.3)}.textarea,.input,#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%}.textarea[readonly],.input[readonly],#documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}.is-white.textarea,.is-white.input,#documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}.is-white.textarea:focus,.is-white.input:focus,#documenter .docs-sidebar form.docs-search>input.is-white:focus,.is-white.is-focused.textarea,.is-white.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-white.textarea:active,.is-white.input:active,#documenter .docs-sidebar form.docs-search>input.is-white:active,.is-white.is-active.textarea,.is-white.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}.is-black.textarea,.is-black.input,#documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}.is-black.textarea:focus,.is-black.input:focus,#documenter .docs-sidebar form.docs-search>input.is-black:focus,.is-black.is-focused.textarea,.is-black.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-black.textarea:active,.is-black.input:active,#documenter .docs-sidebar form.docs-search>input.is-black:active,.is-black.is-active.textarea,.is-black.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}.is-light.textarea,.is-light.input,#documenter .docs-sidebar form.docs-search>input.is-light{border-color:#f5f5f5}.is-light.textarea:focus,.is-light.input:focus,#documenter .docs-sidebar form.docs-search>input.is-light:focus,.is-light.is-focused.textarea,.is-light.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-light.textarea:active,.is-light.input:active,#documenter .docs-sidebar form.docs-search>input.is-light:active,.is-light.is-active.textarea,.is-light.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}.is-dark.textarea,.content kbd.textarea,.is-dark.input,#documenter .docs-sidebar form.docs-search>input.is-dark,.content kbd.input{border-color:#363636}.is-dark.textarea:focus,.content kbd.textarea:focus,.is-dark.input:focus,#documenter .docs-sidebar form.docs-search>input.is-dark:focus,.content kbd.input:focus,.is-dark.is-focused.textarea,.content kbd.is-focused.textarea,.is-dark.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.content kbd.is-focused.input,#documenter .docs-sidebar .content form.docs-search>input.is-focused,.is-dark.textarea:active,.content kbd.textarea:active,.is-dark.input:active,#documenter .docs-sidebar form.docs-search>input.is-dark:active,.content kbd.input:active,.is-dark.is-active.textarea,.content kbd.is-active.textarea,.is-dark.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active,.content kbd.is-active.input,#documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(54,54,54,0.25)}.is-primary.textarea,.docstring>section>a.textarea.docs-sourcelink,.is-primary.input,#documenter .docs-sidebar form.docs-search>input.is-primary,.docstring>section>a.input.docs-sourcelink{border-color:#4eb5de}.is-primary.textarea:focus,.docstring>section>a.textarea.docs-sourcelink:focus,.is-primary.input:focus,#documenter .docs-sidebar form.docs-search>input.is-primary:focus,.docstring>section>a.input.docs-sourcelink:focus,.is-primary.is-focused.textarea,.docstring>section>a.is-focused.textarea.docs-sourcelink,.is-primary.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.docstring>section>a.is-focused.input.docs-sourcelink,.is-primary.textarea:active,.docstring>section>a.textarea.docs-sourcelink:active,.is-primary.input:active,#documenter .docs-sidebar form.docs-search>input.is-primary:active,.docstring>section>a.input.docs-sourcelink:active,.is-primary.is-active.textarea,.docstring>section>a.is-active.textarea.docs-sourcelink,.is-primary.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active,.docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(78,181,222,0.25)}.is-link.textarea,.is-link.input,#documenter .docs-sidebar form.docs-search>input.is-link{border-color:#2e63b8}.is-link.textarea:focus,.is-link.input:focus,#documenter .docs-sidebar form.docs-search>input.is-link:focus,.is-link.is-focused.textarea,.is-link.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-link.textarea:active,.is-link.input:active,#documenter .docs-sidebar form.docs-search>input.is-link:active,.is-link.is-active.textarea,.is-link.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.is-info.textarea,.is-info.input,#documenter .docs-sidebar form.docs-search>input.is-info{border-color:#209cee}.is-info.textarea:focus,.is-info.input:focus,#documenter .docs-sidebar form.docs-search>input.is-info:focus,.is-info.is-focused.textarea,.is-info.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-info.textarea:active,.is-info.input:active,#documenter .docs-sidebar form.docs-search>input.is-info:active,.is-info.is-active.textarea,.is-info.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(32,156,238,0.25)}.is-success.textarea,.is-success.input,#documenter .docs-sidebar form.docs-search>input.is-success{border-color:#22c35b}.is-success.textarea:focus,.is-success.input:focus,#documenter .docs-sidebar form.docs-search>input.is-success:focus,.is-success.is-focused.textarea,.is-success.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-success.textarea:active,.is-success.input:active,#documenter .docs-sidebar form.docs-search>input.is-success:active,.is-success.is-active.textarea,.is-success.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(34,195,91,0.25)}.is-warning.textarea,.is-warning.input,#documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#ffdd57}.is-warning.textarea:focus,.is-warning.input:focus,#documenter .docs-sidebar form.docs-search>input.is-warning:focus,.is-warning.is-focused.textarea,.is-warning.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-warning.textarea:active,.is-warning.input:active,#documenter .docs-sidebar form.docs-search>input.is-warning:active,.is-warning.is-active.textarea,.is-warning.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,221,87,0.25)}.is-danger.textarea,.is-danger.input,#documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#da0b00}.is-danger.textarea:focus,.is-danger.input:focus,#documenter .docs-sidebar form.docs-search>input.is-danger:focus,.is-danger.is-focused.textarea,.is-danger.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-danger.textarea:active,.is-danger.input:active,#documenter .docs-sidebar form.docs-search>input.is-danger:active,.is-danger.is-active.textarea,.is-danger.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(218,11,0,0.25)}.is-small.textarea,.is-small.input,#documenter .docs-sidebar form.docs-search>input{border-radius:2px;font-size:.75rem}.is-medium.textarea,.is-medium.input,#documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}.is-large.textarea,.is-large.input,#documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}.is-fullwidth.textarea,.is-fullwidth.input,#documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}.is-inline.textarea,.is-inline.input,#documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}.input.is-rounded,#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)}.input.is-static,#documenter .docs-sidebar form.docs-search>input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.textarea{display:block;max-width:100%;min-width:100%;padding:calc(0.75em - 1px);resize:vertical}.textarea:not([rows]){max-height:40em;min-height:8em}.textarea[rows]{height:initial}.textarea.has-fixed-size{resize:none}.radio,.checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}.radio input,.checkbox input{cursor:pointer}.radio:hover,.checkbox:hover{color:#222}.radio[disabled],.checkbox[disabled],fieldset[disabled] .radio,fieldset[disabled] .checkbox,.radio input[disabled],.checkbox input[disabled]{color:#6b6b6b;cursor:not-allowed}.radio+.radio{margin-left:.5em}.select{display:inline-block;max-width:100%;position:relative;vertical-align:top}.select:not(.is-multiple){height:2.5em}.select:not(.is-multiple):not(.is-loading)::after{border-color:#2e63b8;right:1.125em;z-index:4}.select.is-rounded select,#documenter .docs-sidebar form.docs-search>input.select select{border-radius:9999px;padding-left:1em}.select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}.select select::-ms-expand{display:none}.select select[disabled]:hover,fieldset[disabled] .select select:hover{border-color:#f5f5f5}.select select:not([multiple]){padding-right:2.5em}.select select[multiple]{height:auto;padding:0}.select select[multiple] option{padding:0.5em 1em}.select:not(.is-multiple):not(.is-loading):hover::after{border-color:#222}.select.is-white:not(:hover)::after{border-color:#fff}.select.is-white select{border-color:#fff}.select.is-white select:hover,.select.is-white select.is-hovered{border-color:#f2f2f2}.select.is-white select:focus,.select.is-white select.is-focused,.select.is-white select:active,.select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}.select.is-black:not(:hover)::after{border-color:#0a0a0a}.select.is-black select{border-color:#0a0a0a}.select.is-black select:hover,.select.is-black select.is-hovered{border-color:#000}.select.is-black select:focus,.select.is-black select.is-focused,.select.is-black select:active,.select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}.select.is-light:not(:hover)::after{border-color:#f5f5f5}.select.is-light select{border-color:#f5f5f5}.select.is-light select:hover,.select.is-light select.is-hovered{border-color:#e8e8e8}.select.is-light select:focus,.select.is-light select.is-focused,.select.is-light select:active,.select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}.select.is-dark:not(:hover)::after,.content kbd.select:not(:hover)::after{border-color:#363636}.select.is-dark select,.content kbd.select select{border-color:#363636}.select.is-dark select:hover,.content kbd.select select:hover,.select.is-dark select.is-hovered,.content kbd.select select.is-hovered{border-color:#292929}.select.is-dark select:focus,.content kbd.select select:focus,.select.is-dark select.is-focused,.content kbd.select select.is-focused,.select.is-dark select:active,.content kbd.select select:active,.select.is-dark select.is-active,.content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(54,54,54,0.25)}.select.is-primary:not(:hover)::after,.docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#4eb5de}.select.is-primary select,.docstring>section>a.select.docs-sourcelink select{border-color:#4eb5de}.select.is-primary select:hover,.docstring>section>a.select.docs-sourcelink select:hover,.select.is-primary select.is-hovered,.docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#39acda}.select.is-primary select:focus,.docstring>section>a.select.docs-sourcelink select:focus,.select.is-primary select.is-focused,.docstring>section>a.select.docs-sourcelink select.is-focused,.select.is-primary select:active,.docstring>section>a.select.docs-sourcelink select:active,.select.is-primary select.is-active,.docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(78,181,222,0.25)}.select.is-link:not(:hover)::after{border-color:#2e63b8}.select.is-link select{border-color:#2e63b8}.select.is-link select:hover,.select.is-link select.is-hovered{border-color:#2958a4}.select.is-link select:focus,.select.is-link select.is-focused,.select.is-link select:active,.select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.select.is-info:not(:hover)::after{border-color:#209cee}.select.is-info select{border-color:#209cee}.select.is-info select:hover,.select.is-info select.is-hovered{border-color:#1190e3}.select.is-info select:focus,.select.is-info select.is-focused,.select.is-info select:active,.select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(32,156,238,0.25)}.select.is-success:not(:hover)::after{border-color:#22c35b}.select.is-success select{border-color:#22c35b}.select.is-success select:hover,.select.is-success select.is-hovered{border-color:#1ead51}.select.is-success select:focus,.select.is-success select.is-focused,.select.is-success select:active,.select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(34,195,91,0.25)}.select.is-warning:not(:hover)::after{border-color:#ffdd57}.select.is-warning select{border-color:#ffdd57}.select.is-warning select:hover,.select.is-warning select.is-hovered{border-color:#ffd83e}.select.is-warning select:focus,.select.is-warning select.is-focused,.select.is-warning select:active,.select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(255,221,87,0.25)}.select.is-danger:not(:hover)::after{border-color:#da0b00}.select.is-danger select{border-color:#da0b00}.select.is-danger select:hover,.select.is-danger select.is-hovered{border-color:#c10a00}.select.is-danger select:focus,.select.is-danger select.is-focused,.select.is-danger select:active,.select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(218,11,0,0.25)}.select.is-small,#documenter .docs-sidebar form.docs-search>input.select{border-radius:2px;font-size:.75rem}.select.is-medium{font-size:1.25rem}.select.is-large{font-size:1.5rem}.select.is-disabled::after{border-color:#6b6b6b !important;opacity:0.5}.select.is-fullwidth{width:100%}.select.is-fullwidth select{width:100%}.select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:0.625em;transform:none}.select.is-loading.is-small:after,#documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}.select.is-loading.is-medium:after{font-size:1.25rem}.select.is-loading.is-large:after{font-size:1.5rem}.file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}.file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}.file.is-white:hover .file-cta,.file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.file.is-white:focus .file-cta,.file.is-white.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,255,255,0.25);color:#0a0a0a}.file.is-white:active .file-cta,.file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}.file.is-black:hover .file-cta,.file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}.file.is-black:focus .file-cta,.file.is-black.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(10,10,10,0.25);color:#fff}.file.is-black:active .file-cta,.file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}.file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-light:hover .file-cta,.file.is-light.is-hovered .file-cta{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-light:focus .file-cta,.file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(245,245,245,0.25);color:rgba(0,0,0,0.7)}.file.is-light:active .file-cta,.file.is-light.is-active .file-cta{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-dark .file-cta,.content kbd.file .file-cta{background-color:#363636;border-color:transparent;color:#fff}.file.is-dark:hover .file-cta,.content kbd.file:hover .file-cta,.file.is-dark.is-hovered .file-cta,.content kbd.file.is-hovered .file-cta{background-color:#2f2f2f;border-color:transparent;color:#fff}.file.is-dark:focus .file-cta,.content kbd.file:focus .file-cta,.file.is-dark.is-focused .file-cta,.content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(54,54,54,0.25);color:#fff}.file.is-dark:active .file-cta,.content kbd.file:active .file-cta,.file.is-dark.is-active .file-cta,.content kbd.file.is-active .file-cta{background-color:#292929;border-color:transparent;color:#fff}.file.is-primary .file-cta,.docstring>section>a.file.docs-sourcelink .file-cta{background-color:#4eb5de;border-color:transparent;color:#fff}.file.is-primary:hover .file-cta,.docstring>section>a.file.docs-sourcelink:hover .file-cta,.file.is-primary.is-hovered .file-cta,.docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#43b1dc;border-color:transparent;color:#fff}.file.is-primary:focus .file-cta,.docstring>section>a.file.docs-sourcelink:focus .file-cta,.file.is-primary.is-focused .file-cta,.docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(78,181,222,0.25);color:#fff}.file.is-primary:active .file-cta,.docstring>section>a.file.docs-sourcelink:active .file-cta,.file.is-primary.is-active .file-cta,.docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#39acda;border-color:transparent;color:#fff}.file.is-link .file-cta{background-color:#2e63b8;border-color:transparent;color:#fff}.file.is-link:hover .file-cta,.file.is-link.is-hovered .file-cta{background-color:#2b5eae;border-color:transparent;color:#fff}.file.is-link:focus .file-cta,.file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(46,99,184,0.25);color:#fff}.file.is-link:active .file-cta,.file.is-link.is-active .file-cta{background-color:#2958a4;border-color:transparent;color:#fff}.file.is-info .file-cta{background-color:#209cee;border-color:transparent;color:#fff}.file.is-info:hover .file-cta,.file.is-info.is-hovered .file-cta{background-color:#1497ed;border-color:transparent;color:#fff}.file.is-info:focus .file-cta,.file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(32,156,238,0.25);color:#fff}.file.is-info:active .file-cta,.file.is-info.is-active .file-cta{background-color:#1190e3;border-color:transparent;color:#fff}.file.is-success .file-cta{background-color:#22c35b;border-color:transparent;color:#fff}.file.is-success:hover .file-cta,.file.is-success.is-hovered .file-cta{background-color:#20b856;border-color:transparent;color:#fff}.file.is-success:focus .file-cta,.file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(34,195,91,0.25);color:#fff}.file.is-success:active .file-cta,.file.is-success.is-active .file-cta{background-color:#1ead51;border-color:transparent;color:#fff}.file.is-warning .file-cta{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-warning:hover .file-cta,.file.is-warning.is-hovered .file-cta{background-color:#ffda4a;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-warning:focus .file-cta,.file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,221,87,0.25);color:rgba(0,0,0,0.7)}.file.is-warning:active .file-cta,.file.is-warning.is-active .file-cta{background-color:#ffd83e;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-danger .file-cta{background-color:#da0b00;border-color:transparent;color:#fff}.file.is-danger:hover .file-cta,.file.is-danger.is-hovered .file-cta{background-color:#cd0a00;border-color:transparent;color:#fff}.file.is-danger:focus .file-cta,.file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(218,11,0,0.25);color:#fff}.file.is-danger:active .file-cta,.file.is-danger.is-active .file-cta{background-color:#c10a00;border-color:transparent;color:#fff}.file.is-small,#documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}.file.is-normal{font-size:1rem}.file.is-medium{font-size:1.25rem}.file.is-medium .file-icon .fa{font-size:21px}.file.is-large{font-size:1.5rem}.file.is-large .file-icon .fa{font-size:28px}.file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}.file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}.file.has-name.is-empty .file-cta{border-radius:4px}.file.has-name.is-empty .file-name{display:none}.file.is-boxed .file-label{flex-direction:column}.file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}.file.is-boxed .file-name{border-width:0 1px 1px}.file.is-boxed .file-icon{height:1.5em;width:1.5em}.file.is-boxed .file-icon .fa{font-size:21px}.file.is-boxed.is-small .file-icon .fa,#documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}.file.is-boxed.is-medium .file-icon .fa{font-size:28px}.file.is-boxed.is-large .file-icon .fa{font-size:35px}.file.is-boxed.has-name .file-cta{border-radius:4px 4px 0 0}.file.is-boxed.has-name .file-name{border-radius:0 0 4px 4px;border-width:0 1px 1px}.file.is-centered{justify-content:center}.file.is-fullwidth .file-label{width:100%}.file.is-fullwidth .file-name{flex-grow:1;max-width:none}.file.is-right{justify-content:flex-end}.file.is-right .file-cta{border-radius:0 4px 4px 0}.file.is-right .file-name{border-radius:4px 0 0 4px;border-width:1px 0 1px 1px;order:-1}.file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}.file-label:hover .file-cta{background-color:#eee;color:#222}.file-label:hover .file-name{border-color:#d5d5d5}.file-label:active .file-cta{background-color:#e8e8e8;color:#222}.file-label:active .file-name{border-color:#cfcfcf}.file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}.file-cta,.file-name{border-color:#dbdbdb;border-radius:4px;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}.file-cta{background-color:#f5f5f5;color:#222}.file-name{border-color:#dbdbdb;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}.file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}.file-icon .fa{font-size:14px}.label{color:#222;display:block;font-size:1rem;font-weight:700}.label:not(:last-child){margin-bottom:0.5em}.label.is-small,#documenter .docs-sidebar form.docs-search>input.label{font-size:.75rem}.label.is-medium{font-size:1.25rem}.label.is-large{font-size:1.5rem}.help{display:block;font-size:.75rem;margin-top:0.25rem}.help.is-white{color:#fff}.help.is-black{color:#0a0a0a}.help.is-light{color:#f5f5f5}.help.is-dark,.content kbd.help{color:#363636}.help.is-primary,.docstring>section>a.help.docs-sourcelink{color:#4eb5de}.help.is-link{color:#2e63b8}.help.is-info{color:#209cee}.help.is-success{color:#22c35b}.help.is-warning{color:#ffdd57}.help.is-danger{color:#da0b00}.field:not(:last-child){margin-bottom:0.75rem}.field.has-addons{display:flex;justify-content:flex-start}.field.has-addons .control:not(:last-child){margin-right:-1px}.field.has-addons .control:not(:first-child):not(:last-child) .button,.field.has-addons .control:not(:first-child):not(:last-child) .input,.field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,.field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}.field.has-addons .control:first-child:not(:only-child) .button,.field.has-addons .control:first-child:not(:only-child) .input,.field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,.field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}.field.has-addons .control:last-child:not(:only-child) .button,.field.has-addons .control:last-child:not(:only-child) .input,.field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,.field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}.field.has-addons .control .button:not([disabled]):hover,.field.has-addons .control .button.is-hovered:not([disabled]),.field.has-addons .control .input:not([disabled]):hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,.field.has-addons .control .input.is-hovered:not([disabled]),.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),.field.has-addons .control .select select:not([disabled]):hover,.field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}.field.has-addons .control .button:not([disabled]):focus,.field.has-addons .control .button.is-focused:not([disabled]),.field.has-addons .control .button:not([disabled]):active,.field.has-addons .control .button.is-active:not([disabled]),.field.has-addons .control .input:not([disabled]):focus,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,.field.has-addons .control .input.is-focused:not([disabled]),.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),.field.has-addons .control .input:not([disabled]):active,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,.field.has-addons .control .input.is-active:not([disabled]),.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),.field.has-addons .control .select select:not([disabled]):focus,.field.has-addons .control .select select.is-focused:not([disabled]),.field.has-addons .control .select select:not([disabled]):active,.field.has-addons .control .select select.is-active:not([disabled]){z-index:3}.field.has-addons .control .button:not([disabled]):focus:hover,.field.has-addons .control .button.is-focused:not([disabled]):hover,.field.has-addons .control .button:not([disabled]):active:hover,.field.has-addons .control .button.is-active:not([disabled]):hover,.field.has-addons .control .input:not([disabled]):focus:hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,.field.has-addons .control .input.is-focused:not([disabled]):hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,.field.has-addons .control .input:not([disabled]):active:hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,.field.has-addons .control .input.is-active:not([disabled]):hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,.field.has-addons .control .select select:not([disabled]):focus:hover,.field.has-addons .control .select select.is-focused:not([disabled]):hover,.field.has-addons .control .select select:not([disabled]):active:hover,.field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}.field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}.field.has-addons.has-addons-centered{justify-content:center}.field.has-addons.has-addons-right{justify-content:flex-end}.field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}.field.is-grouped{display:flex;justify-content:flex-start}.field.is-grouped>.control{flex-shrink:0}.field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}.field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}.field.is-grouped.is-grouped-centered{justify-content:center}.field.is-grouped.is-grouped-right{justify-content:flex-end}.field.is-grouped.is-grouped-multiline{flex-wrap:wrap}.field.is-grouped.is-grouped-multiline>.control:last-child,.field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}.field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}.field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{.field.is-horizontal{display:flex}}.field-label .label{font-size:inherit}@media screen and (max-width: 768px){.field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{.field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}.field-label.is-small,#documenter .docs-sidebar form.docs-search>input.field-label{font-size:.75rem;padding-top:0.375em}.field-label.is-normal{padding-top:0.375em}.field-label.is-medium{font-size:1.25rem;padding-top:0.375em}.field-label.is-large{font-size:1.5rem;padding-top:0.375em}}.field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{.field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}.field-body .field{margin-bottom:0}.field-body>.field{flex-shrink:1}.field-body>.field:not(.is-narrow){flex-grow:1}.field-body>.field:not(:last-child){margin-right:.75rem}}.control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}.control.has-icons-left .input:focus~.icon,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,.control.has-icons-left .select:focus~.icon,.control.has-icons-right .input:focus~.icon,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,.control.has-icons-right .select:focus~.icon{color:#222}.control.has-icons-left .input.is-small~.icon,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,.control.has-icons-left .select.is-small~.icon,.control.has-icons-right .input.is-small~.icon,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,.control.has-icons-right .select.is-small~.icon{font-size:.75rem}.control.has-icons-left .input.is-medium~.icon,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,.control.has-icons-left .select.is-medium~.icon,.control.has-icons-right .input.is-medium~.icon,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,.control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}.control.has-icons-left .input.is-large~.icon,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,.control.has-icons-left .select.is-large~.icon,.control.has-icons-right .input.is-large~.icon,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,.control.has-icons-right .select.is-large~.icon{font-size:1.5rem}.control.has-icons-left .icon,.control.has-icons-right .icon{color:#dbdbdb;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}.control.has-icons-left .input,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input,.control.has-icons-left .select select{padding-left:2.5em}.control.has-icons-left .icon.is-left{left:0}.control.has-icons-right .input,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input,.control.has-icons-right .select select{padding-right:2.5em}.control.has-icons-right .icon.is-right{right:0}.control.is-loading::after{position:absolute !important;right:.625em;top:0.625em;z-index:4}.control.is-loading.is-small:after,#documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}.control.is-loading.is-medium:after{font-size:1.25rem}.control.is-loading.is-large:after{font-size:1.5rem}.breadcrumb{font-size:1rem;white-space:nowrap}.breadcrumb a{align-items:center;color:#2e63b8;display:flex;justify-content:center;padding:0 .75em}.breadcrumb a:hover{color:#363636}.breadcrumb li{align-items:center;display:flex}.breadcrumb li:first-child a{padding-left:0}.breadcrumb li.is-active a{color:#222;cursor:default;pointer-events:none}.breadcrumb li+li::before{color:#b5b5b5;content:"\0002f"}.breadcrumb ul,.breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}.breadcrumb .icon:first-child{margin-right:.5em}.breadcrumb .icon:last-child{margin-left:.5em}.breadcrumb.is-centered ol,.breadcrumb.is-centered ul{justify-content:center}.breadcrumb.is-right ol,.breadcrumb.is-right ul{justify-content:flex-end}.breadcrumb.is-small,#documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.75rem}.breadcrumb.is-medium{font-size:1.25rem}.breadcrumb.is-large{font-size:1.5rem}.breadcrumb.has-arrow-separator li+li::before{content:"\02192"}.breadcrumb.has-bullet-separator li+li::before{content:"\02022"}.breadcrumb.has-dot-separator li+li::before{content:"\000b7"}.breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}.card{background-color:#fff;border-radius:.25rem;box-shadow:#bbb;color:#222;max-width:100%;position:relative}.card-footer:first-child,.card-content:first-child,.card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-footer:last-child,.card-content:last-child,.card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.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}.card-header-title{align-items:center;color:#222;display:flex;flex-grow:1;font-weight:700;padding:0.75rem 1rem}.card-header-title.is-centered{justify-content:center}.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}.card-image{display:block;position:relative}.card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.card-content{background-color:rgba(0,0,0,0);padding:1.5rem}.card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #ededed;align-items:stretch;display:flex}.card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}.card-footer-item:not(:last-child){border-right:1px solid #ededed}.card .media:not(:last-child){margin-bottom:1.5rem}.dropdown{display:inline-flex;position:relative;vertical-align:top}.dropdown.is-active .dropdown-menu,.dropdown.is-hoverable:hover .dropdown-menu{display:block}.dropdown.is-right .dropdown-menu{left:auto;right:0}.dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}.dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}.dropdown-content{background-color:#fff;border-radius:4px;box-shadow:#bbb;padding-bottom:.5rem;padding-top:.5rem}.dropdown-item{color:#222;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}a.dropdown-item,button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}a.dropdown-item:hover,button.dropdown-item:hover{background-color:#f5f5f5;color:#0a0a0a}a.dropdown-item.is-active,button.dropdown-item.is-active{background-color:#2e63b8;color:#fff}.dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:0.5rem 0}.level{align-items:center;justify-content:space-between}.level code{border-radius:4px}.level img{display:inline-block;vertical-align:top}.level.is-mobile{display:flex}.level.is-mobile .level-left,.level.is-mobile .level-right{display:flex}.level.is-mobile .level-left+.level-right{margin-top:0}.level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}.level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{.level{display:flex}.level>.level-item:not(.is-narrow){flex-grow:1}}.level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}.level-item .title,.level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){.level-item:not(:last-child){margin-bottom:.75rem}}.level-left,.level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.level-left .level-item.is-flexible,.level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{.level-left .level-item:not(:last-child),.level-right .level-item:not(:last-child){margin-right:.75rem}}.level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){.level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{.level-left{display:flex}}.level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{.level-right{display:flex}}.media{align-items:flex-start;display:flex;text-align:inherit}.media .content:not(:last-child){margin-bottom:.75rem}.media .media{border-top:1px solid rgba(219,219,219,0.5);display:flex;padding-top:.75rem}.media .media .content:not(:last-child),.media .media .control:not(:last-child){margin-bottom:.5rem}.media .media .media{padding-top:.5rem}.media .media .media+.media{margin-top:.5rem}.media+.media{border-top:1px solid rgba(219,219,219,0.5);margin-top:1rem;padding-top:1rem}.media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}.media-left,.media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.media-left{margin-right:1rem}.media-right{margin-left:1rem}.media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width: 768px){.media-content{overflow-x:auto}}.menu{font-size:1rem}.menu.is-small,#documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}.menu.is-medium{font-size:1.25rem}.menu.is-large{font-size:1.5rem}.menu-list{line-height:1.25}.menu-list a{border-radius:2px;color:#222;display:block;padding:0.5em 0.75em}.menu-list a:hover{background-color:#f5f5f5;color:#222}.menu-list a.is-active{background-color:#2e63b8;color:#fff}.menu-list li ul{border-left:1px solid #dbdbdb;margin:.75em;padding-left:.75em}.menu-label{color:#6b6b6b;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}.menu-label:not(:first-child){margin-top:1em}.menu-label:not(:last-child){margin-bottom:1em}.message{background-color:#f5f5f5;border-radius:4px;font-size:1rem}.message strong{color:currentColor}.message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}.message.is-small,#documenter .docs-sidebar form.docs-search>input.message{font-size:.75rem}.message.is-medium{font-size:1.25rem}.message.is-large{font-size:1.5rem}.message.is-white{background-color:#fff}.message.is-white .message-header{background-color:#fff;color:#0a0a0a}.message.is-white .message-body{border-color:#fff}.message.is-black{background-color:#fafafa}.message.is-black .message-header{background-color:#0a0a0a;color:#fff}.message.is-black .message-body{border-color:#0a0a0a}.message.is-light{background-color:#fafafa}.message.is-light .message-header{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.message.is-light .message-body{border-color:#f5f5f5}.message.is-dark,.content kbd.message{background-color:#fafafa}.message.is-dark .message-header,.content kbd.message .message-header{background-color:#363636;color:#fff}.message.is-dark .message-body,.content kbd.message .message-body{border-color:#363636}.message.is-primary,.docstring>section>a.message.docs-sourcelink{background-color:#eef8fc}.message.is-primary .message-header,.docstring>section>a.message.docs-sourcelink .message-header{background-color:#4eb5de;color:#fff}.message.is-primary .message-body,.docstring>section>a.message.docs-sourcelink .message-body{border-color:#4eb5de;color:#1a6d8e}.message.is-link{background-color:#eff3fb}.message.is-link .message-header{background-color:#2e63b8;color:#fff}.message.is-link .message-body{border-color:#2e63b8;color:#3169c4}.message.is-info{background-color:#ecf7fe}.message.is-info .message-header{background-color:#209cee;color:#fff}.message.is-info .message-body{border-color:#209cee;color:#0e72b4}.message.is-success{background-color:#eefcf3}.message.is-success .message-header{background-color:#22c35b;color:#fff}.message.is-success .message-body{border-color:#22c35b;color:#198f43}.message.is-warning{background-color:#fffbeb}.message.is-warning .message-header{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.message.is-warning .message-body{border-color:#ffdd57;color:#947600}.message.is-danger{background-color:#ffeceb}.message.is-danger .message-header{background-color:#da0b00;color:#fff}.message.is-danger .message-body{border-color:#da0b00;color:#f50c00}.message-header{align-items:center;background-color:#222;border-radius:4px 4px 0 0;color:#fff;display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.75em 1em;position:relative}.message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}.message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}.message-body{border-color:#dbdbdb;border-radius:4px;border-style:solid;border-width:0 0 0 4px;color:#222;padding:1.25em 1.5em}.message-body code,.message-body pre{background-color:#fff}.message-body pre code{background-color:rgba(0,0,0,0)}.modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}.modal.is-active{display:flex}.modal-background{background-color:rgba(10,10,10,0.86)}.modal-content,.modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px){.modal-content,.modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}.modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}.modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}.modal-card-head,.modal-card-foot{align-items:center;background-color:#f5f5f5;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}.modal-card-head{border-bottom:1px solid #dbdbdb;border-top-left-radius:6px;border-top-right-radius:6px}.modal-card-title{color:#222;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}.modal-card-foot{border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:1px solid #dbdbdb}.modal-card-foot .button:not(:last-child){margin-right:.5em}.modal-card-body{-webkit-overflow-scrolling:touch;background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}.navbar{background-color:#fff;min-height:3.25rem;position:relative;z-index:30}.navbar.is-white{background-color:#fff;color:#0a0a0a}.navbar.is-white .navbar-brand>.navbar-item,.navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}.navbar.is-white .navbar-brand>a.navbar-item:focus,.navbar.is-white .navbar-brand>a.navbar-item:hover,.navbar.is-white .navbar-brand>a.navbar-item.is-active,.navbar.is-white .navbar-brand .navbar-link:focus,.navbar.is-white .navbar-brand .navbar-link:hover,.navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){.navbar.is-white .navbar-start>.navbar-item,.navbar.is-white .navbar-start .navbar-link,.navbar.is-white .navbar-end>.navbar-item,.navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}.navbar.is-white .navbar-start>a.navbar-item:focus,.navbar.is-white .navbar-start>a.navbar-item:hover,.navbar.is-white .navbar-start>a.navbar-item.is-active,.navbar.is-white .navbar-start .navbar-link:focus,.navbar.is-white .navbar-start .navbar-link:hover,.navbar.is-white .navbar-start .navbar-link.is-active,.navbar.is-white .navbar-end>a.navbar-item:focus,.navbar.is-white .navbar-end>a.navbar-item:hover,.navbar.is-white .navbar-end>a.navbar-item.is-active,.navbar.is-white .navbar-end .navbar-link:focus,.navbar.is-white .navbar-end .navbar-link:hover,.navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-start .navbar-link::after,.navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}.navbar.is-black{background-color:#0a0a0a;color:#fff}.navbar.is-black .navbar-brand>.navbar-item,.navbar.is-black .navbar-brand .navbar-link{color:#fff}.navbar.is-black .navbar-brand>a.navbar-item:focus,.navbar.is-black .navbar-brand>a.navbar-item:hover,.navbar.is-black .navbar-brand>a.navbar-item.is-active,.navbar.is-black .navbar-brand .navbar-link:focus,.navbar.is-black .navbar-brand .navbar-link:hover,.navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}.navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-black .navbar-start>.navbar-item,.navbar.is-black .navbar-start .navbar-link,.navbar.is-black .navbar-end>.navbar-item,.navbar.is-black .navbar-end .navbar-link{color:#fff}.navbar.is-black .navbar-start>a.navbar-item:focus,.navbar.is-black .navbar-start>a.navbar-item:hover,.navbar.is-black .navbar-start>a.navbar-item.is-active,.navbar.is-black .navbar-start .navbar-link:focus,.navbar.is-black .navbar-start .navbar-link:hover,.navbar.is-black .navbar-start .navbar-link.is-active,.navbar.is-black .navbar-end>a.navbar-item:focus,.navbar.is-black .navbar-end>a.navbar-item:hover,.navbar.is-black .navbar-end>a.navbar-item.is-active,.navbar.is-black .navbar-end .navbar-link:focus,.navbar.is-black .navbar-end .navbar-link:hover,.navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}.navbar.is-black .navbar-start .navbar-link::after,.navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}.navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}.navbar.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-brand>.navbar-item,.navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-brand>a.navbar-item:focus,.navbar.is-light .navbar-brand>a.navbar-item:hover,.navbar.is-light .navbar-brand>a.navbar-item.is-active,.navbar.is-light .navbar-brand .navbar-link:focus,.navbar.is-light .navbar-brand .navbar-link:hover,.navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){.navbar.is-light .navbar-start>.navbar-item,.navbar.is-light .navbar-start .navbar-link,.navbar.is-light .navbar-end>.navbar-item,.navbar.is-light .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-start>a.navbar-item:focus,.navbar.is-light .navbar-start>a.navbar-item:hover,.navbar.is-light .navbar-start>a.navbar-item.is-active,.navbar.is-light .navbar-start .navbar-link:focus,.navbar.is-light .navbar-start .navbar-link:hover,.navbar.is-light .navbar-start .navbar-link.is-active,.navbar.is-light .navbar-end>a.navbar-item:focus,.navbar.is-light .navbar-end>a.navbar-item:hover,.navbar.is-light .navbar-end>a.navbar-item.is-active,.navbar.is-light .navbar-end .navbar-link:focus,.navbar.is-light .navbar-end .navbar-link:hover,.navbar.is-light .navbar-end .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-start .navbar-link::after,.navbar.is-light .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}}.navbar.is-dark,.content kbd.navbar{background-color:#363636;color:#fff}.navbar.is-dark .navbar-brand>.navbar-item,.content kbd.navbar .navbar-brand>.navbar-item,.navbar.is-dark .navbar-brand .navbar-link,.content kbd.navbar .navbar-brand .navbar-link{color:#fff}.navbar.is-dark .navbar-brand>a.navbar-item:focus,.content kbd.navbar .navbar-brand>a.navbar-item:focus,.navbar.is-dark .navbar-brand>a.navbar-item:hover,.content kbd.navbar .navbar-brand>a.navbar-item:hover,.navbar.is-dark .navbar-brand>a.navbar-item.is-active,.content kbd.navbar .navbar-brand>a.navbar-item.is-active,.navbar.is-dark .navbar-brand .navbar-link:focus,.content kbd.navbar .navbar-brand .navbar-link:focus,.navbar.is-dark .navbar-brand .navbar-link:hover,.content kbd.navbar .navbar-brand .navbar-link:hover,.navbar.is-dark .navbar-brand .navbar-link.is-active,.content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#292929;color:#fff}.navbar.is-dark .navbar-brand .navbar-link::after,.content kbd.navbar .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-dark .navbar-burger,.content kbd.navbar .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-dark .navbar-start>.navbar-item,.content kbd.navbar .navbar-start>.navbar-item,.navbar.is-dark .navbar-start .navbar-link,.content kbd.navbar .navbar-start .navbar-link,.navbar.is-dark .navbar-end>.navbar-item,.content kbd.navbar .navbar-end>.navbar-item,.navbar.is-dark .navbar-end .navbar-link,.content kbd.navbar .navbar-end .navbar-link{color:#fff}.navbar.is-dark .navbar-start>a.navbar-item:focus,.content kbd.navbar .navbar-start>a.navbar-item:focus,.navbar.is-dark .navbar-start>a.navbar-item:hover,.content kbd.navbar .navbar-start>a.navbar-item:hover,.navbar.is-dark .navbar-start>a.navbar-item.is-active,.content kbd.navbar .navbar-start>a.navbar-item.is-active,.navbar.is-dark .navbar-start .navbar-link:focus,.content kbd.navbar .navbar-start .navbar-link:focus,.navbar.is-dark .navbar-start .navbar-link:hover,.content kbd.navbar .navbar-start .navbar-link:hover,.navbar.is-dark .navbar-start .navbar-link.is-active,.content kbd.navbar .navbar-start .navbar-link.is-active,.navbar.is-dark .navbar-end>a.navbar-item:focus,.content kbd.navbar .navbar-end>a.navbar-item:focus,.navbar.is-dark .navbar-end>a.navbar-item:hover,.content kbd.navbar .navbar-end>a.navbar-item:hover,.navbar.is-dark .navbar-end>a.navbar-item.is-active,.content kbd.navbar .navbar-end>a.navbar-item.is-active,.navbar.is-dark .navbar-end .navbar-link:focus,.content kbd.navbar .navbar-end .navbar-link:focus,.navbar.is-dark .navbar-end .navbar-link:hover,.content kbd.navbar .navbar-end .navbar-link:hover,.navbar.is-dark .navbar-end .navbar-link.is-active,.content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#292929;color:#fff}.navbar.is-dark .navbar-start .navbar-link::after,.content kbd.navbar .navbar-start .navbar-link::after,.navbar.is-dark .navbar-end .navbar-link::after,.content kbd.navbar .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,.content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,.content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,.content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#292929;color:#fff}.navbar.is-dark .navbar-dropdown a.navbar-item.is-active,.content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#363636;color:#fff}}.navbar.is-primary,.docstring>section>a.navbar.docs-sourcelink{background-color:#4eb5de;color:#fff}.navbar.is-primary .navbar-brand>.navbar-item,.docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,.navbar.is-primary .navbar-brand .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}.navbar.is-primary .navbar-brand>a.navbar-item:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,.navbar.is-primary .navbar-brand>a.navbar-item:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,.navbar.is-primary .navbar-brand>a.navbar-item.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,.navbar.is-primary .navbar-brand .navbar-link:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,.navbar.is-primary .navbar-brand .navbar-link:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,.navbar.is-primary .navbar-brand .navbar-link.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#39acda;color:#fff}.navbar.is-primary .navbar-brand .navbar-link::after,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-burger,.docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-primary .navbar-start>.navbar-item,.docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,.navbar.is-primary .navbar-start .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,.navbar.is-primary .navbar-end>.navbar-item,.docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,.navbar.is-primary .navbar-end .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}.navbar.is-primary .navbar-start>a.navbar-item:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,.navbar.is-primary .navbar-start>a.navbar-item:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,.navbar.is-primary .navbar-start>a.navbar-item.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,.navbar.is-primary .navbar-start .navbar-link:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,.navbar.is-primary .navbar-start .navbar-link:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,.navbar.is-primary .navbar-start .navbar-link.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,.navbar.is-primary .navbar-end>a.navbar-item:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,.navbar.is-primary .navbar-end>a.navbar-item:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,.navbar.is-primary .navbar-end>a.navbar-item.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,.navbar.is-primary .navbar-end .navbar-link:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,.navbar.is-primary .navbar-end .navbar-link:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,.navbar.is-primary .navbar-end .navbar-link.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#39acda;color:#fff}.navbar.is-primary .navbar-start .navbar-link::after,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,.navbar.is-primary .navbar-end .navbar-link::after,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#39acda;color:#fff}.navbar.is-primary .navbar-dropdown a.navbar-item.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#4eb5de;color:#fff}}.navbar.is-link{background-color:#2e63b8;color:#fff}.navbar.is-link .navbar-brand>.navbar-item,.navbar.is-link .navbar-brand .navbar-link{color:#fff}.navbar.is-link .navbar-brand>a.navbar-item:focus,.navbar.is-link .navbar-brand>a.navbar-item:hover,.navbar.is-link .navbar-brand>a.navbar-item.is-active,.navbar.is-link .navbar-brand .navbar-link:focus,.navbar.is-link .navbar-brand .navbar-link:hover,.navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#2958a4;color:#fff}.navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-link .navbar-start>.navbar-item,.navbar.is-link .navbar-start .navbar-link,.navbar.is-link .navbar-end>.navbar-item,.navbar.is-link .navbar-end .navbar-link{color:#fff}.navbar.is-link .navbar-start>a.navbar-item:focus,.navbar.is-link .navbar-start>a.navbar-item:hover,.navbar.is-link .navbar-start>a.navbar-item.is-active,.navbar.is-link .navbar-start .navbar-link:focus,.navbar.is-link .navbar-start .navbar-link:hover,.navbar.is-link .navbar-start .navbar-link.is-active,.navbar.is-link .navbar-end>a.navbar-item:focus,.navbar.is-link .navbar-end>a.navbar-item:hover,.navbar.is-link .navbar-end>a.navbar-item.is-active,.navbar.is-link .navbar-end .navbar-link:focus,.navbar.is-link .navbar-end .navbar-link:hover,.navbar.is-link .navbar-end .navbar-link.is-active{background-color:#2958a4;color:#fff}.navbar.is-link .navbar-start .navbar-link::after,.navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#2958a4;color:#fff}.navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#2e63b8;color:#fff}}.navbar.is-info{background-color:#209cee;color:#fff}.navbar.is-info .navbar-brand>.navbar-item,.navbar.is-info .navbar-brand .navbar-link{color:#fff}.navbar.is-info .navbar-brand>a.navbar-item:focus,.navbar.is-info .navbar-brand>a.navbar-item:hover,.navbar.is-info .navbar-brand>a.navbar-item.is-active,.navbar.is-info .navbar-brand .navbar-link:focus,.navbar.is-info .navbar-brand .navbar-link:hover,.navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#1190e3;color:#fff}.navbar.is-info .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-info .navbar-start>.navbar-item,.navbar.is-info .navbar-start .navbar-link,.navbar.is-info .navbar-end>.navbar-item,.navbar.is-info .navbar-end .navbar-link{color:#fff}.navbar.is-info .navbar-start>a.navbar-item:focus,.navbar.is-info .navbar-start>a.navbar-item:hover,.navbar.is-info .navbar-start>a.navbar-item.is-active,.navbar.is-info .navbar-start .navbar-link:focus,.navbar.is-info .navbar-start .navbar-link:hover,.navbar.is-info .navbar-start .navbar-link.is-active,.navbar.is-info .navbar-end>a.navbar-item:focus,.navbar.is-info .navbar-end>a.navbar-item:hover,.navbar.is-info .navbar-end>a.navbar-item.is-active,.navbar.is-info .navbar-end .navbar-link:focus,.navbar.is-info .navbar-end .navbar-link:hover,.navbar.is-info .navbar-end .navbar-link.is-active{background-color:#1190e3;color:#fff}.navbar.is-info .navbar-start .navbar-link::after,.navbar.is-info .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#1190e3;color:#fff}.navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#209cee;color:#fff}}.navbar.is-success{background-color:#22c35b;color:#fff}.navbar.is-success .navbar-brand>.navbar-item,.navbar.is-success .navbar-brand .navbar-link{color:#fff}.navbar.is-success .navbar-brand>a.navbar-item:focus,.navbar.is-success .navbar-brand>a.navbar-item:hover,.navbar.is-success .navbar-brand>a.navbar-item.is-active,.navbar.is-success .navbar-brand .navbar-link:focus,.navbar.is-success .navbar-brand .navbar-link:hover,.navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#1ead51;color:#fff}.navbar.is-success .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-success .navbar-start>.navbar-item,.navbar.is-success .navbar-start .navbar-link,.navbar.is-success .navbar-end>.navbar-item,.navbar.is-success .navbar-end .navbar-link{color:#fff}.navbar.is-success .navbar-start>a.navbar-item:focus,.navbar.is-success .navbar-start>a.navbar-item:hover,.navbar.is-success .navbar-start>a.navbar-item.is-active,.navbar.is-success .navbar-start .navbar-link:focus,.navbar.is-success .navbar-start .navbar-link:hover,.navbar.is-success .navbar-start .navbar-link.is-active,.navbar.is-success .navbar-end>a.navbar-item:focus,.navbar.is-success .navbar-end>a.navbar-item:hover,.navbar.is-success .navbar-end>a.navbar-item.is-active,.navbar.is-success .navbar-end .navbar-link:focus,.navbar.is-success .navbar-end .navbar-link:hover,.navbar.is-success .navbar-end .navbar-link.is-active{background-color:#1ead51;color:#fff}.navbar.is-success .navbar-start .navbar-link::after,.navbar.is-success .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#1ead51;color:#fff}.navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#22c35b;color:#fff}}.navbar.is-warning{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-brand>.navbar-item,.navbar.is-warning .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-brand>a.navbar-item:focus,.navbar.is-warning .navbar-brand>a.navbar-item:hover,.navbar.is-warning .navbar-brand>a.navbar-item.is-active,.navbar.is-warning .navbar-brand .navbar-link:focus,.navbar.is-warning .navbar-brand .navbar-link:hover,.navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#ffd83e;color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){.navbar.is-warning .navbar-start>.navbar-item,.navbar.is-warning .navbar-start .navbar-link,.navbar.is-warning .navbar-end>.navbar-item,.navbar.is-warning .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-start>a.navbar-item:focus,.navbar.is-warning .navbar-start>a.navbar-item:hover,.navbar.is-warning .navbar-start>a.navbar-item.is-active,.navbar.is-warning .navbar-start .navbar-link:focus,.navbar.is-warning .navbar-start .navbar-link:hover,.navbar.is-warning .navbar-start .navbar-link.is-active,.navbar.is-warning .navbar-end>a.navbar-item:focus,.navbar.is-warning .navbar-end>a.navbar-item:hover,.navbar.is-warning .navbar-end>a.navbar-item.is-active,.navbar.is-warning .navbar-end .navbar-link:focus,.navbar.is-warning .navbar-end .navbar-link:hover,.navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#ffd83e;color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-start .navbar-link::after,.navbar.is-warning .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#ffd83e;color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#ffdd57;color:rgba(0,0,0,0.7)}}.navbar.is-danger{background-color:#da0b00;color:#fff}.navbar.is-danger .navbar-brand>.navbar-item,.navbar.is-danger .navbar-brand .navbar-link{color:#fff}.navbar.is-danger .navbar-brand>a.navbar-item:focus,.navbar.is-danger .navbar-brand>a.navbar-item:hover,.navbar.is-danger .navbar-brand>a.navbar-item.is-active,.navbar.is-danger .navbar-brand .navbar-link:focus,.navbar.is-danger .navbar-brand .navbar-link:hover,.navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#c10a00;color:#fff}.navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-danger .navbar-start>.navbar-item,.navbar.is-danger .navbar-start .navbar-link,.navbar.is-danger .navbar-end>.navbar-item,.navbar.is-danger .navbar-end .navbar-link{color:#fff}.navbar.is-danger .navbar-start>a.navbar-item:focus,.navbar.is-danger .navbar-start>a.navbar-item:hover,.navbar.is-danger .navbar-start>a.navbar-item.is-active,.navbar.is-danger .navbar-start .navbar-link:focus,.navbar.is-danger .navbar-start .navbar-link:hover,.navbar.is-danger .navbar-start .navbar-link.is-active,.navbar.is-danger .navbar-end>a.navbar-item:focus,.navbar.is-danger .navbar-end>a.navbar-item:hover,.navbar.is-danger .navbar-end>a.navbar-item.is-active,.navbar.is-danger .navbar-end .navbar-link:focus,.navbar.is-danger .navbar-end .navbar-link:hover,.navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#c10a00;color:#fff}.navbar.is-danger .navbar-start .navbar-link::after,.navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#c10a00;color:#fff}.navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#da0b00;color:#fff}}.navbar>.container{align-items:stretch;display:flex;min-height:3.25rem;width:100%}.navbar.has-shadow{box-shadow:0 2px 0 0 #f5f5f5}.navbar.is-fixed-bottom,.navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom{bottom:0}.navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #f5f5f5}.navbar.is-fixed-top{top:0}html.has-navbar-fixed-top,body.has-navbar-fixed-top{padding-top:3.25rem}html.has-navbar-fixed-bottom,body.has-navbar-fixed-bottom{padding-bottom:3.25rem}.navbar-brand,.navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:3.25rem}.navbar-brand a.navbar-item:focus,.navbar-brand a.navbar-item:hover{background-color:transparent}.navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}.navbar-burger{color:#222;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:block;height:3.25rem;position:relative;width:3.25rem;margin-left:auto}.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}.navbar-burger span:nth-child(1){top:calc(50% - 6px)}.navbar-burger span:nth-child(2){top:calc(50% - 1px)}.navbar-burger span:nth-child(3){top:calc(50% + 4px)}.navbar-burger:hover{background-color:rgba(0,0,0,0.05)}.navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}.navbar-burger.is-active span:nth-child(2){opacity:0}.navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}.navbar-menu{display:none}.navbar-item,.navbar-link{color:#222;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}.navbar-item .icon:only-child,.navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}a.navbar-item,.navbar-link{cursor:pointer}a.navbar-item:focus,a.navbar-item:focus-within,a.navbar-item:hover,a.navbar-item.is-active,.navbar-link:focus,.navbar-link:focus-within,.navbar-link:hover,.navbar-link.is-active{background-color:#fafafa;color:#2e63b8}.navbar-item{flex-grow:0;flex-shrink:0}.navbar-item img{max-height:1.75rem}.navbar-item.has-dropdown{padding:0}.navbar-item.is-expanded{flex-grow:1;flex-shrink:1}.navbar-item.is-tab{border-bottom:1px solid transparent;min-height:3.25rem;padding-bottom:calc(0.5rem - 1px)}.navbar-item.is-tab:focus,.navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#2e63b8}.navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#2e63b8;border-bottom-style:solid;border-bottom-width:3px;color:#2e63b8;padding-bottom:calc(0.5rem - 3px)}.navbar-content{flex-grow:1;flex-shrink:1}.navbar-link:not(.is-arrowless){padding-right:2.5em}.navbar-link:not(.is-arrowless)::after{border-color:#2e63b8;margin-top:-0.375em;right:1.125em}.navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}.navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}.navbar-divider{background-color:#f5f5f5;border:none;display:none;height:2px;margin:0.5rem 0}@media screen and (max-width: 1055px){.navbar>.container{display:block}.navbar-brand .navbar-item,.navbar-tabs .navbar-item{align-items:center;display:flex}.navbar-link::after{display:none}.navbar-menu{background-color:#fff;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}.navbar-menu.is-active{display:block}.navbar.is-fixed-bottom-touch,.navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-touch{bottom:0}.navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}.navbar.is-fixed-top-touch{top:0}.navbar.is-fixed-top .navbar-menu,.navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 3.25rem);overflow:auto}html.has-navbar-fixed-top-touch,body.has-navbar-fixed-top-touch{padding-top:3.25rem}html.has-navbar-fixed-bottom-touch,body.has-navbar-fixed-bottom-touch{padding-bottom:3.25rem}}@media screen and (min-width: 1056px){.navbar,.navbar-menu,.navbar-start,.navbar-end{align-items:stretch;display:flex}.navbar{min-height:3.25rem}.navbar.is-spaced{padding:1rem 2rem}.navbar.is-spaced .navbar-start,.navbar.is-spaced .navbar-end{align-items:center}.navbar.is-spaced a.navbar-item,.navbar.is-spaced .navbar-link{border-radius:4px}.navbar.is-transparent a.navbar-item:focus,.navbar.is-transparent a.navbar-item:hover,.navbar.is-transparent a.navbar-item.is-active,.navbar.is-transparent .navbar-link:focus,.navbar.is-transparent .navbar-link:hover,.navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}.navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}.navbar.is-transparent .navbar-dropdown a.navbar-item:focus,.navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#2e63b8}.navbar-burger{display:none}.navbar-item,.navbar-link{align-items:center;display:flex}.navbar-item.has-dropdown{align-items:stretch}.navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}.navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:2px solid #dbdbdb;border-radius:6px 6px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,0.1);top:auto}.navbar-item.is-active .navbar-dropdown,.navbar-item.is-hoverable:focus .navbar-dropdown,.navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced .navbar-item.is-active .navbar-dropdown,.navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-hoverable:focus .navbar-dropdown,.navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-hoverable:hover .navbar-dropdown,.navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}.navbar-menu{flex-grow:1;flex-shrink:0}.navbar-start{justify-content:flex-start;margin-right:auto}.navbar-end{justify-content:flex-end;margin-left:auto}.navbar-dropdown{background-color:#fff;border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:2px solid #dbdbdb;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}.navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}.navbar-dropdown a.navbar-item{padding-right:3rem}.navbar-dropdown a.navbar-item:focus,.navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#2e63b8}.navbar.is-spaced .navbar-dropdown,.navbar-dropdown.is-boxed{border-radius:6px;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}.navbar-dropdown.is-right{left:auto;right:0}.navbar-divider{display:block}.navbar>.container .navbar-brand,.container>.navbar .navbar-brand{margin-left:-.75rem}.navbar>.container .navbar-menu,.container>.navbar .navbar-menu{margin-right:-.75rem}.navbar.is-fixed-bottom-desktop,.navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-desktop{bottom:0}.navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}.navbar.is-fixed-top-desktop{top:0}html.has-navbar-fixed-top-desktop,body.has-navbar-fixed-top-desktop{padding-top:3.25rem}html.has-navbar-fixed-bottom-desktop,body.has-navbar-fixed-bottom-desktop{padding-bottom:3.25rem}html.has-spaced-navbar-fixed-top,body.has-spaced-navbar-fixed-top{padding-top:5.25rem}html.has-spaced-navbar-fixed-bottom,body.has-spaced-navbar-fixed-bottom{padding-bottom:5.25rem}a.navbar-item.is-active,.navbar-link.is-active{color:#0a0a0a}a.navbar-item.is-active:not(:focus):not(:hover),.navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}.navbar-item.has-dropdown:focus .navbar-link,.navbar-item.has-dropdown:hover .navbar-link,.navbar-item.has-dropdown.is-active .navbar-link{background-color:#fafafa}}.hero.is-fullheight-with-navbar{min-height:calc(100vh - 3.25rem)}.pagination{font-size:1rem;margin:-.25rem}.pagination.is-small,#documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}.pagination.is-medium{font-size:1.25rem}.pagination.is-large{font-size:1.5rem}.pagination.is-rounded .pagination-previous,#documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,.pagination.is-rounded .pagination-next,#documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:9999px}.pagination.is-rounded .pagination-link,#documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:9999px}.pagination,.pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}.pagination-previous,.pagination-next,.pagination-link{border-color:#dbdbdb;color:#222;min-width:2.5em}.pagination-previous:hover,.pagination-next:hover,.pagination-link:hover{border-color:#b5b5b5;color:#363636}.pagination-previous:focus,.pagination-next:focus,.pagination-link:focus{border-color:#3c5dcd}.pagination-previous:active,.pagination-next:active,.pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}.pagination-previous[disabled],.pagination-previous.is-disabled,.pagination-next[disabled],.pagination-next.is-disabled,.pagination-link[disabled],.pagination-link.is-disabled{background-color:#dbdbdb;border-color:#dbdbdb;box-shadow:none;color:#6b6b6b;opacity:0.5}.pagination-previous,.pagination-next{padding-left:.75em;padding-right:.75em;white-space:nowrap}.pagination-link.is-current{background-color:#2e63b8;border-color:#2e63b8;color:#fff}.pagination-ellipsis{color:#b5b5b5;pointer-events:none}.pagination-list{flex-wrap:wrap}.pagination-list li{list-style:none}@media screen and (max-width: 768px){.pagination{flex-wrap:wrap}.pagination-previous,.pagination-next{flex-grow:1;flex-shrink:1}.pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{.pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis{margin-bottom:0;margin-top:0}.pagination-previous{order:2}.pagination-next{order:3}.pagination{justify-content:space-between;margin-bottom:0;margin-top:0}.pagination.is-centered .pagination-previous{order:1}.pagination.is-centered .pagination-list{justify-content:center;order:2}.pagination.is-centered .pagination-next{order:3}.pagination.is-right .pagination-previous{order:1}.pagination.is-right .pagination-next{order:2}.pagination.is-right .pagination-list{justify-content:flex-end;order:3}}.panel{border-radius:6px;box-shadow:#bbb;font-size:1rem}.panel:not(:last-child){margin-bottom:1.5rem}.panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}.panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}.panel.is-white .panel-block.is-active .panel-icon{color:#fff}.panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}.panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}.panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}.panel.is-light .panel-heading{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.panel.is-light .panel-tabs a.is-active{border-bottom-color:#f5f5f5}.panel.is-light .panel-block.is-active .panel-icon{color:#f5f5f5}.panel.is-dark .panel-heading,.content kbd.panel .panel-heading{background-color:#363636;color:#fff}.panel.is-dark .panel-tabs a.is-active,.content kbd.panel .panel-tabs a.is-active{border-bottom-color:#363636}.panel.is-dark .panel-block.is-active .panel-icon,.content kbd.panel .panel-block.is-active .panel-icon{color:#363636}.panel.is-primary .panel-heading,.docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#4eb5de;color:#fff}.panel.is-primary .panel-tabs a.is-active,.docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#4eb5de}.panel.is-primary .panel-block.is-active .panel-icon,.docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#4eb5de}.panel.is-link .panel-heading{background-color:#2e63b8;color:#fff}.panel.is-link .panel-tabs a.is-active{border-bottom-color:#2e63b8}.panel.is-link .panel-block.is-active .panel-icon{color:#2e63b8}.panel.is-info .panel-heading{background-color:#209cee;color:#fff}.panel.is-info .panel-tabs a.is-active{border-bottom-color:#209cee}.panel.is-info .panel-block.is-active .panel-icon{color:#209cee}.panel.is-success .panel-heading{background-color:#22c35b;color:#fff}.panel.is-success .panel-tabs a.is-active{border-bottom-color:#22c35b}.panel.is-success .panel-block.is-active .panel-icon{color:#22c35b}.panel.is-warning .panel-heading{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.panel.is-warning .panel-tabs a.is-active{border-bottom-color:#ffdd57}.panel.is-warning .panel-block.is-active .panel-icon{color:#ffdd57}.panel.is-danger .panel-heading{background-color:#da0b00;color:#fff}.panel.is-danger .panel-tabs a.is-active{border-bottom-color:#da0b00}.panel.is-danger .panel-block.is-active .panel-icon{color:#da0b00}.panel-tabs:not(:last-child),.panel-block:not(:last-child){border-bottom:1px solid #ededed}.panel-heading{background-color:#ededed;border-radius:6px 6px 0 0;color:#222;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}.panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}.panel-tabs a{border-bottom:1px solid #dbdbdb;margin-bottom:-1px;padding:0.5em}.panel-tabs a.is-active{border-bottom-color:#4a4a4a;color:#363636}.panel-list a{color:#222}.panel-list a:hover{color:#2e63b8}.panel-block{align-items:center;color:#222;display:flex;justify-content:flex-start;padding:0.5em 0.75em}.panel-block input[type="checkbox"]{margin-right:.75em}.panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}.panel-block.is-wrapped{flex-wrap:wrap}.panel-block.is-active{border-left-color:#2e63b8;color:#363636}.panel-block.is-active .panel-icon{color:#2e63b8}.panel-block:last-child{border-bottom-left-radius:6px;border-bottom-right-radius:6px}a.panel-block,label.panel-block{cursor:pointer}a.panel-block:hover,label.panel-block:hover{background-color:#f5f5f5}.panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#6b6b6b;margin-right:.75em}.panel-icon .fa{font-size:inherit;line-height:inherit}.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}.tabs a{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;color:#222;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}.tabs a:hover{border-bottom-color:#222;color:#222}.tabs li{display:block}.tabs li.is-active a{border-bottom-color:#2e63b8;color:#2e63b8}.tabs ul{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}.tabs ul.is-left{padding-right:0.75em}.tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}.tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}.tabs .icon:first-child{margin-right:.5em}.tabs .icon:last-child{margin-left:.5em}.tabs.is-centered ul{justify-content:center}.tabs.is-right ul{justify-content:flex-end}.tabs.is-boxed a{border:1px solid transparent;border-radius:4px 4px 0 0}.tabs.is-boxed a:hover{background-color:#f5f5f5;border-bottom-color:#dbdbdb}.tabs.is-boxed li.is-active a{background-color:#fff;border-color:#dbdbdb;border-bottom-color:rgba(0,0,0,0) !important}.tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}.tabs.is-toggle a{border-color:#dbdbdb;border-style:solid;border-width:1px;margin-bottom:0;position:relative}.tabs.is-toggle a:hover{background-color:#f5f5f5;border-color:#b5b5b5;z-index:2}.tabs.is-toggle li+li{margin-left:-1px}.tabs.is-toggle li:first-child a{border-top-left-radius:4px;border-bottom-left-radius:4px}.tabs.is-toggle li:last-child a{border-top-right-radius:4px;border-bottom-right-radius:4px}.tabs.is-toggle li.is-active a{background-color:#2e63b8;border-color:#2e63b8;color:#fff;z-index:1}.tabs.is-toggle ul{border-bottom:none}.tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}.tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}.tabs.is-small,#documenter .docs-sidebar form.docs-search>input.tabs{font-size:.75rem}.tabs.is-medium{font-size:1.25rem}.tabs.is-large{font-size:1.5rem}.column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>.column.is-narrow{flex:none;width:unset}.columns.is-mobile>.column.is-full{flex:none;width:100%}.columns.is-mobile>.column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>.column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>.column.is-half{flex:none;width:50%}.columns.is-mobile>.column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>.column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>.column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>.column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>.column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>.column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>.column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>.column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>.column.is-offset-half{margin-left:50%}.columns.is-mobile>.column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>.column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>.column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>.column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>.column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>.column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>.column.is-0{flex:none;width:0%}.columns.is-mobile>.column.is-offset-0{margin-left:0%}.columns.is-mobile>.column.is-1{flex:none;width:8.33333337%}.columns.is-mobile>.column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>.column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>.column.is-offset-2{margin-left:16.66666674%}.columns.is-mobile>.column.is-3{flex:none;width:25%}.columns.is-mobile>.column.is-offset-3{margin-left:25%}.columns.is-mobile>.column.is-4{flex:none;width:33.33333337%}.columns.is-mobile>.column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>.column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>.column.is-offset-5{margin-left:41.66666674%}.columns.is-mobile>.column.is-6{flex:none;width:50%}.columns.is-mobile>.column.is-offset-6{margin-left:50%}.columns.is-mobile>.column.is-7{flex:none;width:58.33333337%}.columns.is-mobile>.column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>.column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>.column.is-offset-8{margin-left:66.66666674%}.columns.is-mobile>.column.is-9{flex:none;width:75%}.columns.is-mobile>.column.is-offset-9{margin-left:75%}.columns.is-mobile>.column.is-10{flex:none;width:83.33333337%}.columns.is-mobile>.column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>.column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>.column.is-offset-11{margin-left:91.66666674%}.columns.is-mobile>.column.is-12{flex:none;width:100%}.columns.is-mobile>.column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){.column.is-narrow-mobile{flex:none;width:unset}.column.is-full-mobile{flex:none;width:100%}.column.is-three-quarters-mobile{flex:none;width:75%}.column.is-two-thirds-mobile{flex:none;width:66.6666%}.column.is-half-mobile{flex:none;width:50%}.column.is-one-third-mobile{flex:none;width:33.3333%}.column.is-one-quarter-mobile{flex:none;width:25%}.column.is-one-fifth-mobile{flex:none;width:20%}.column.is-two-fifths-mobile{flex:none;width:40%}.column.is-three-fifths-mobile{flex:none;width:60%}.column.is-four-fifths-mobile{flex:none;width:80%}.column.is-offset-three-quarters-mobile{margin-left:75%}.column.is-offset-two-thirds-mobile{margin-left:66.6666%}.column.is-offset-half-mobile{margin-left:50%}.column.is-offset-one-third-mobile{margin-left:33.3333%}.column.is-offset-one-quarter-mobile{margin-left:25%}.column.is-offset-one-fifth-mobile{margin-left:20%}.column.is-offset-two-fifths-mobile{margin-left:40%}.column.is-offset-three-fifths-mobile{margin-left:60%}.column.is-offset-four-fifths-mobile{margin-left:80%}.column.is-0-mobile{flex:none;width:0%}.column.is-offset-0-mobile{margin-left:0%}.column.is-1-mobile{flex:none;width:8.33333337%}.column.is-offset-1-mobile{margin-left:8.33333337%}.column.is-2-mobile{flex:none;width:16.66666674%}.column.is-offset-2-mobile{margin-left:16.66666674%}.column.is-3-mobile{flex:none;width:25%}.column.is-offset-3-mobile{margin-left:25%}.column.is-4-mobile{flex:none;width:33.33333337%}.column.is-offset-4-mobile{margin-left:33.33333337%}.column.is-5-mobile{flex:none;width:41.66666674%}.column.is-offset-5-mobile{margin-left:41.66666674%}.column.is-6-mobile{flex:none;width:50%}.column.is-offset-6-mobile{margin-left:50%}.column.is-7-mobile{flex:none;width:58.33333337%}.column.is-offset-7-mobile{margin-left:58.33333337%}.column.is-8-mobile{flex:none;width:66.66666674%}.column.is-offset-8-mobile{margin-left:66.66666674%}.column.is-9-mobile{flex:none;width:75%}.column.is-offset-9-mobile{margin-left:75%}.column.is-10-mobile{flex:none;width:83.33333337%}.column.is-offset-10-mobile{margin-left:83.33333337%}.column.is-11-mobile{flex:none;width:91.66666674%}.column.is-offset-11-mobile{margin-left:91.66666674%}.column.is-12-mobile{flex:none;width:100%}.column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{.column.is-narrow,.column.is-narrow-tablet{flex:none;width:unset}.column.is-full,.column.is-full-tablet{flex:none;width:100%}.column.is-three-quarters,.column.is-three-quarters-tablet{flex:none;width:75%}.column.is-two-thirds,.column.is-two-thirds-tablet{flex:none;width:66.6666%}.column.is-half,.column.is-half-tablet{flex:none;width:50%}.column.is-one-third,.column.is-one-third-tablet{flex:none;width:33.3333%}.column.is-one-quarter,.column.is-one-quarter-tablet{flex:none;width:25%}.column.is-one-fifth,.column.is-one-fifth-tablet{flex:none;width:20%}.column.is-two-fifths,.column.is-two-fifths-tablet{flex:none;width:40%}.column.is-three-fifths,.column.is-three-fifths-tablet{flex:none;width:60%}.column.is-four-fifths,.column.is-four-fifths-tablet{flex:none;width:80%}.column.is-offset-three-quarters,.column.is-offset-three-quarters-tablet{margin-left:75%}.column.is-offset-two-thirds,.column.is-offset-two-thirds-tablet{margin-left:66.6666%}.column.is-offset-half,.column.is-offset-half-tablet{margin-left:50%}.column.is-offset-one-third,.column.is-offset-one-third-tablet{margin-left:33.3333%}.column.is-offset-one-quarter,.column.is-offset-one-quarter-tablet{margin-left:25%}.column.is-offset-one-fifth,.column.is-offset-one-fifth-tablet{margin-left:20%}.column.is-offset-two-fifths,.column.is-offset-two-fifths-tablet{margin-left:40%}.column.is-offset-three-fifths,.column.is-offset-three-fifths-tablet{margin-left:60%}.column.is-offset-four-fifths,.column.is-offset-four-fifths-tablet{margin-left:80%}.column.is-0,.column.is-0-tablet{flex:none;width:0%}.column.is-offset-0,.column.is-offset-0-tablet{margin-left:0%}.column.is-1,.column.is-1-tablet{flex:none;width:8.33333337%}.column.is-offset-1,.column.is-offset-1-tablet{margin-left:8.33333337%}.column.is-2,.column.is-2-tablet{flex:none;width:16.66666674%}.column.is-offset-2,.column.is-offset-2-tablet{margin-left:16.66666674%}.column.is-3,.column.is-3-tablet{flex:none;width:25%}.column.is-offset-3,.column.is-offset-3-tablet{margin-left:25%}.column.is-4,.column.is-4-tablet{flex:none;width:33.33333337%}.column.is-offset-4,.column.is-offset-4-tablet{margin-left:33.33333337%}.column.is-5,.column.is-5-tablet{flex:none;width:41.66666674%}.column.is-offset-5,.column.is-offset-5-tablet{margin-left:41.66666674%}.column.is-6,.column.is-6-tablet{flex:none;width:50%}.column.is-offset-6,.column.is-offset-6-tablet{margin-left:50%}.column.is-7,.column.is-7-tablet{flex:none;width:58.33333337%}.column.is-offset-7,.column.is-offset-7-tablet{margin-left:58.33333337%}.column.is-8,.column.is-8-tablet{flex:none;width:66.66666674%}.column.is-offset-8,.column.is-offset-8-tablet{margin-left:66.66666674%}.column.is-9,.column.is-9-tablet{flex:none;width:75%}.column.is-offset-9,.column.is-offset-9-tablet{margin-left:75%}.column.is-10,.column.is-10-tablet{flex:none;width:83.33333337%}.column.is-offset-10,.column.is-offset-10-tablet{margin-left:83.33333337%}.column.is-11,.column.is-11-tablet{flex:none;width:91.66666674%}.column.is-offset-11,.column.is-offset-11-tablet{margin-left:91.66666674%}.column.is-12,.column.is-12-tablet{flex:none;width:100%}.column.is-offset-12,.column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){.column.is-narrow-touch{flex:none;width:unset}.column.is-full-touch{flex:none;width:100%}.column.is-three-quarters-touch{flex:none;width:75%}.column.is-two-thirds-touch{flex:none;width:66.6666%}.column.is-half-touch{flex:none;width:50%}.column.is-one-third-touch{flex:none;width:33.3333%}.column.is-one-quarter-touch{flex:none;width:25%}.column.is-one-fifth-touch{flex:none;width:20%}.column.is-two-fifths-touch{flex:none;width:40%}.column.is-three-fifths-touch{flex:none;width:60%}.column.is-four-fifths-touch{flex:none;width:80%}.column.is-offset-three-quarters-touch{margin-left:75%}.column.is-offset-two-thirds-touch{margin-left:66.6666%}.column.is-offset-half-touch{margin-left:50%}.column.is-offset-one-third-touch{margin-left:33.3333%}.column.is-offset-one-quarter-touch{margin-left:25%}.column.is-offset-one-fifth-touch{margin-left:20%}.column.is-offset-two-fifths-touch{margin-left:40%}.column.is-offset-three-fifths-touch{margin-left:60%}.column.is-offset-four-fifths-touch{margin-left:80%}.column.is-0-touch{flex:none;width:0%}.column.is-offset-0-touch{margin-left:0%}.column.is-1-touch{flex:none;width:8.33333337%}.column.is-offset-1-touch{margin-left:8.33333337%}.column.is-2-touch{flex:none;width:16.66666674%}.column.is-offset-2-touch{margin-left:16.66666674%}.column.is-3-touch{flex:none;width:25%}.column.is-offset-3-touch{margin-left:25%}.column.is-4-touch{flex:none;width:33.33333337%}.column.is-offset-4-touch{margin-left:33.33333337%}.column.is-5-touch{flex:none;width:41.66666674%}.column.is-offset-5-touch{margin-left:41.66666674%}.column.is-6-touch{flex:none;width:50%}.column.is-offset-6-touch{margin-left:50%}.column.is-7-touch{flex:none;width:58.33333337%}.column.is-offset-7-touch{margin-left:58.33333337%}.column.is-8-touch{flex:none;width:66.66666674%}.column.is-offset-8-touch{margin-left:66.66666674%}.column.is-9-touch{flex:none;width:75%}.column.is-offset-9-touch{margin-left:75%}.column.is-10-touch{flex:none;width:83.33333337%}.column.is-offset-10-touch{margin-left:83.33333337%}.column.is-11-touch{flex:none;width:91.66666674%}.column.is-offset-11-touch{margin-left:91.66666674%}.column.is-12-touch{flex:none;width:100%}.column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){.column.is-narrow-desktop{flex:none;width:unset}.column.is-full-desktop{flex:none;width:100%}.column.is-three-quarters-desktop{flex:none;width:75%}.column.is-two-thirds-desktop{flex:none;width:66.6666%}.column.is-half-desktop{flex:none;width:50%}.column.is-one-third-desktop{flex:none;width:33.3333%}.column.is-one-quarter-desktop{flex:none;width:25%}.column.is-one-fifth-desktop{flex:none;width:20%}.column.is-two-fifths-desktop{flex:none;width:40%}.column.is-three-fifths-desktop{flex:none;width:60%}.column.is-four-fifths-desktop{flex:none;width:80%}.column.is-offset-three-quarters-desktop{margin-left:75%}.column.is-offset-two-thirds-desktop{margin-left:66.6666%}.column.is-offset-half-desktop{margin-left:50%}.column.is-offset-one-third-desktop{margin-left:33.3333%}.column.is-offset-one-quarter-desktop{margin-left:25%}.column.is-offset-one-fifth-desktop{margin-left:20%}.column.is-offset-two-fifths-desktop{margin-left:40%}.column.is-offset-three-fifths-desktop{margin-left:60%}.column.is-offset-four-fifths-desktop{margin-left:80%}.column.is-0-desktop{flex:none;width:0%}.column.is-offset-0-desktop{margin-left:0%}.column.is-1-desktop{flex:none;width:8.33333337%}.column.is-offset-1-desktop{margin-left:8.33333337%}.column.is-2-desktop{flex:none;width:16.66666674%}.column.is-offset-2-desktop{margin-left:16.66666674%}.column.is-3-desktop{flex:none;width:25%}.column.is-offset-3-desktop{margin-left:25%}.column.is-4-desktop{flex:none;width:33.33333337%}.column.is-offset-4-desktop{margin-left:33.33333337%}.column.is-5-desktop{flex:none;width:41.66666674%}.column.is-offset-5-desktop{margin-left:41.66666674%}.column.is-6-desktop{flex:none;width:50%}.column.is-offset-6-desktop{margin-left:50%}.column.is-7-desktop{flex:none;width:58.33333337%}.column.is-offset-7-desktop{margin-left:58.33333337%}.column.is-8-desktop{flex:none;width:66.66666674%}.column.is-offset-8-desktop{margin-left:66.66666674%}.column.is-9-desktop{flex:none;width:75%}.column.is-offset-9-desktop{margin-left:75%}.column.is-10-desktop{flex:none;width:83.33333337%}.column.is-offset-10-desktop{margin-left:83.33333337%}.column.is-11-desktop{flex:none;width:91.66666674%}.column.is-offset-11-desktop{margin-left:91.66666674%}.column.is-12-desktop{flex:none;width:100%}.column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){.column.is-narrow-widescreen{flex:none;width:unset}.column.is-full-widescreen{flex:none;width:100%}.column.is-three-quarters-widescreen{flex:none;width:75%}.column.is-two-thirds-widescreen{flex:none;width:66.6666%}.column.is-half-widescreen{flex:none;width:50%}.column.is-one-third-widescreen{flex:none;width:33.3333%}.column.is-one-quarter-widescreen{flex:none;width:25%}.column.is-one-fifth-widescreen{flex:none;width:20%}.column.is-two-fifths-widescreen{flex:none;width:40%}.column.is-three-fifths-widescreen{flex:none;width:60%}.column.is-four-fifths-widescreen{flex:none;width:80%}.column.is-offset-three-quarters-widescreen{margin-left:75%}.column.is-offset-two-thirds-widescreen{margin-left:66.6666%}.column.is-offset-half-widescreen{margin-left:50%}.column.is-offset-one-third-widescreen{margin-left:33.3333%}.column.is-offset-one-quarter-widescreen{margin-left:25%}.column.is-offset-one-fifth-widescreen{margin-left:20%}.column.is-offset-two-fifths-widescreen{margin-left:40%}.column.is-offset-three-fifths-widescreen{margin-left:60%}.column.is-offset-four-fifths-widescreen{margin-left:80%}.column.is-0-widescreen{flex:none;width:0%}.column.is-offset-0-widescreen{margin-left:0%}.column.is-1-widescreen{flex:none;width:8.33333337%}.column.is-offset-1-widescreen{margin-left:8.33333337%}.column.is-2-widescreen{flex:none;width:16.66666674%}.column.is-offset-2-widescreen{margin-left:16.66666674%}.column.is-3-widescreen{flex:none;width:25%}.column.is-offset-3-widescreen{margin-left:25%}.column.is-4-widescreen{flex:none;width:33.33333337%}.column.is-offset-4-widescreen{margin-left:33.33333337%}.column.is-5-widescreen{flex:none;width:41.66666674%}.column.is-offset-5-widescreen{margin-left:41.66666674%}.column.is-6-widescreen{flex:none;width:50%}.column.is-offset-6-widescreen{margin-left:50%}.column.is-7-widescreen{flex:none;width:58.33333337%}.column.is-offset-7-widescreen{margin-left:58.33333337%}.column.is-8-widescreen{flex:none;width:66.66666674%}.column.is-offset-8-widescreen{margin-left:66.66666674%}.column.is-9-widescreen{flex:none;width:75%}.column.is-offset-9-widescreen{margin-left:75%}.column.is-10-widescreen{flex:none;width:83.33333337%}.column.is-offset-10-widescreen{margin-left:83.33333337%}.column.is-11-widescreen{flex:none;width:91.66666674%}.column.is-offset-11-widescreen{margin-left:91.66666674%}.column.is-12-widescreen{flex:none;width:100%}.column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){.column.is-narrow-fullhd{flex:none;width:unset}.column.is-full-fullhd{flex:none;width:100%}.column.is-three-quarters-fullhd{flex:none;width:75%}.column.is-two-thirds-fullhd{flex:none;width:66.6666%}.column.is-half-fullhd{flex:none;width:50%}.column.is-one-third-fullhd{flex:none;width:33.3333%}.column.is-one-quarter-fullhd{flex:none;width:25%}.column.is-one-fifth-fullhd{flex:none;width:20%}.column.is-two-fifths-fullhd{flex:none;width:40%}.column.is-three-fifths-fullhd{flex:none;width:60%}.column.is-four-fifths-fullhd{flex:none;width:80%}.column.is-offset-three-quarters-fullhd{margin-left:75%}.column.is-offset-two-thirds-fullhd{margin-left:66.6666%}.column.is-offset-half-fullhd{margin-left:50%}.column.is-offset-one-third-fullhd{margin-left:33.3333%}.column.is-offset-one-quarter-fullhd{margin-left:25%}.column.is-offset-one-fifth-fullhd{margin-left:20%}.column.is-offset-two-fifths-fullhd{margin-left:40%}.column.is-offset-three-fifths-fullhd{margin-left:60%}.column.is-offset-four-fifths-fullhd{margin-left:80%}.column.is-0-fullhd{flex:none;width:0%}.column.is-offset-0-fullhd{margin-left:0%}.column.is-1-fullhd{flex:none;width:8.33333337%}.column.is-offset-1-fullhd{margin-left:8.33333337%}.column.is-2-fullhd{flex:none;width:16.66666674%}.column.is-offset-2-fullhd{margin-left:16.66666674%}.column.is-3-fullhd{flex:none;width:25%}.column.is-offset-3-fullhd{margin-left:25%}.column.is-4-fullhd{flex:none;width:33.33333337%}.column.is-offset-4-fullhd{margin-left:33.33333337%}.column.is-5-fullhd{flex:none;width:41.66666674%}.column.is-offset-5-fullhd{margin-left:41.66666674%}.column.is-6-fullhd{flex:none;width:50%}.column.is-offset-6-fullhd{margin-left:50%}.column.is-7-fullhd{flex:none;width:58.33333337%}.column.is-offset-7-fullhd{margin-left:58.33333337%}.column.is-8-fullhd{flex:none;width:66.66666674%}.column.is-offset-8-fullhd{margin-left:66.66666674%}.column.is-9-fullhd{flex:none;width:75%}.column.is-offset-9-fullhd{margin-left:75%}.column.is-10-fullhd{flex:none;width:83.33333337%}.column.is-offset-10-fullhd{margin-left:83.33333337%}.column.is-11-fullhd{flex:none;width:91.66666674%}.column.is-offset-11-fullhd{margin-left:91.66666674%}.column.is-12-fullhd{flex:none;width:100%}.column.is-offset-12-fullhd{margin-left:100%}}.columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.columns:last-child{margin-bottom:-.75rem}.columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}.columns.is-centered{justify-content:center}.columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}.columns.is-gapless>.column{margin:0;padding:0 !important}.columns.is-gapless:not(:last-child){margin-bottom:1.5rem}.columns.is-gapless:last-child{margin-bottom:0}.columns.is-mobile{display:flex}.columns.is-multiline{flex-wrap:wrap}.columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{.columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){.columns.is-desktop{display:flex}}.columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}.columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}.columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){.columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-0-fullhd{--columnGap: 0rem}}.columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){.columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-1-fullhd{--columnGap: .25rem}}.columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){.columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-2-fullhd{--columnGap: .5rem}}.columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){.columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-3-fullhd{--columnGap: .75rem}}.columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){.columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-4-fullhd{--columnGap: 1rem}}.columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){.columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}.columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){.columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}.columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){.columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}.columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){.columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-8-fullhd{--columnGap: 2rem}}.tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}.tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.tile.is-ancestor:last-child{margin-bottom:-.75rem}.tile.is-ancestor:not(:last-child){margin-bottom:.75rem}.tile.is-child{margin:0 !important}.tile.is-parent{padding:.75rem}.tile.is-vertical{flex-direction:column}.tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{.tile:not(.is-child){display:flex}.tile.is-1{flex:none;width:8.33333337%}.tile.is-2{flex:none;width:16.66666674%}.tile.is-3{flex:none;width:25%}.tile.is-4{flex:none;width:33.33333337%}.tile.is-5{flex:none;width:41.66666674%}.tile.is-6{flex:none;width:50%}.tile.is-7{flex:none;width:58.33333337%}.tile.is-8{flex:none;width:66.66666674%}.tile.is-9{flex:none;width:75%}.tile.is-10{flex:none;width:83.33333337%}.tile.is-11{flex:none;width:91.66666674%}.tile.is-12{flex:none;width:100%}}.hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}.hero .navbar{background:none}.hero .tabs ul{border-bottom:none}.hero.is-white{background-color:#fff;color:#0a0a0a}.hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-white strong{color:inherit}.hero.is-white .title{color:#0a0a0a}.hero.is-white .subtitle{color:rgba(10,10,10,0.9)}.hero.is-white .subtitle a:not(.button),.hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){.hero.is-white .navbar-menu{background-color:#fff}}.hero.is-white .navbar-item,.hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}.hero.is-white a.navbar-item:hover,.hero.is-white a.navbar-item.is-active,.hero.is-white .navbar-link:hover,.hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}.hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}.hero.is-white .tabs a:hover{opacity:1}.hero.is-white .tabs li.is-active a{color:#fff !important;opacity:1}.hero.is-white .tabs.is-boxed a,.hero.is-white .tabs.is-toggle a{color:#0a0a0a}.hero.is-white .tabs.is-boxed a:hover,.hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-white .tabs.is-boxed li.is-active a,.hero.is-white .tabs.is-boxed li.is-active a:hover,.hero.is-white .tabs.is-toggle li.is-active a,.hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){.hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}.hero.is-black{background-color:#0a0a0a;color:#fff}.hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-black strong{color:inherit}.hero.is-black .title{color:#fff}.hero.is-black .subtitle{color:rgba(255,255,255,0.9)}.hero.is-black .subtitle a:not(.button),.hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-black .navbar-menu{background-color:#0a0a0a}}.hero.is-black .navbar-item,.hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-black a.navbar-item:hover,.hero.is-black a.navbar-item.is-active,.hero.is-black .navbar-link:hover,.hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}.hero.is-black .tabs a{color:#fff;opacity:0.9}.hero.is-black .tabs a:hover{opacity:1}.hero.is-black .tabs li.is-active a{color:#0a0a0a !important;opacity:1}.hero.is-black .tabs.is-boxed a,.hero.is-black .tabs.is-toggle a{color:#fff}.hero.is-black .tabs.is-boxed a:hover,.hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-black .tabs.is-boxed li.is-active a,.hero.is-black .tabs.is-boxed li.is-active a:hover,.hero.is-black .tabs.is-toggle li.is-active a,.hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}.hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){.hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}.hero.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-light strong{color:inherit}.hero.is-light .title{color:rgba(0,0,0,0.7)}.hero.is-light .subtitle{color:rgba(0,0,0,0.9)}.hero.is-light .subtitle a:not(.button),.hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){.hero.is-light .navbar-menu{background-color:#f5f5f5}}.hero.is-light .navbar-item,.hero.is-light .navbar-link{color:rgba(0,0,0,0.7)}.hero.is-light a.navbar-item:hover,.hero.is-light a.navbar-item.is-active,.hero.is-light .navbar-link:hover,.hero.is-light .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}.hero.is-light .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}.hero.is-light .tabs a:hover{opacity:1}.hero.is-light .tabs li.is-active a{color:#f5f5f5 !important;opacity:1}.hero.is-light .tabs.is-boxed a,.hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,0.7)}.hero.is-light .tabs.is-boxed a:hover,.hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-light .tabs.is-boxed li.is-active a,.hero.is-light .tabs.is-boxed li.is-active a:hover,.hero.is-light .tabs.is-toggle li.is-active a,.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:#f5f5f5}.hero.is-light.is-bold{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}@media screen and (max-width: 768px){.hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}}.hero.is-dark,.content kbd.hero{background-color:#363636;color:#fff}.hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-dark strong,.content kbd.hero strong{color:inherit}.hero.is-dark .title,.content kbd.hero .title{color:#fff}.hero.is-dark .subtitle,.content kbd.hero .subtitle{color:rgba(255,255,255,0.9)}.hero.is-dark .subtitle a:not(.button),.content kbd.hero .subtitle a:not(.button),.hero.is-dark .subtitle strong,.content kbd.hero .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-dark .navbar-menu,.content kbd.hero .navbar-menu{background-color:#363636}}.hero.is-dark .navbar-item,.content kbd.hero .navbar-item,.hero.is-dark .navbar-link,.content kbd.hero .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-dark a.navbar-item:hover,.content kbd.hero a.navbar-item:hover,.hero.is-dark a.navbar-item.is-active,.content kbd.hero a.navbar-item.is-active,.hero.is-dark .navbar-link:hover,.content kbd.hero .navbar-link:hover,.hero.is-dark .navbar-link.is-active,.content kbd.hero .navbar-link.is-active{background-color:#292929;color:#fff}.hero.is-dark .tabs a,.content kbd.hero .tabs a{color:#fff;opacity:0.9}.hero.is-dark .tabs a:hover,.content kbd.hero .tabs a:hover{opacity:1}.hero.is-dark .tabs li.is-active a,.content kbd.hero .tabs li.is-active a{color:#363636 !important;opacity:1}.hero.is-dark .tabs.is-boxed a,.content kbd.hero .tabs.is-boxed a,.hero.is-dark .tabs.is-toggle a,.content kbd.hero .tabs.is-toggle a{color:#fff}.hero.is-dark .tabs.is-boxed a:hover,.content kbd.hero .tabs.is-boxed a:hover,.hero.is-dark .tabs.is-toggle a:hover,.content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-dark .tabs.is-boxed li.is-active a,.content kbd.hero .tabs.is-boxed li.is-active a,.hero.is-dark .tabs.is-boxed li.is-active a:hover,.hero.is-dark .tabs.is-toggle li.is-active a,.content kbd.hero .tabs.is-toggle li.is-active a,.hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#363636}.hero.is-dark.is-bold,.content kbd.hero.is-bold{background-image:linear-gradient(141deg, #1f191a 0%, #363636 71%, #46403f 100%)}@media screen and (max-width: 768px){.hero.is-dark.is-bold .navbar-menu,.content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #1f191a 0%, #363636 71%, #46403f 100%)}}.hero.is-primary,.docstring>section>a.hero.docs-sourcelink{background-color:#4eb5de;color:#fff}.hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-primary strong,.docstring>section>a.hero.docs-sourcelink strong{color:inherit}.hero.is-primary .title,.docstring>section>a.hero.docs-sourcelink .title{color:#fff}.hero.is-primary .subtitle,.docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}.hero.is-primary .subtitle a:not(.button),.docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),.hero.is-primary .subtitle strong,.docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-primary .navbar-menu,.docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#4eb5de}}.hero.is-primary .navbar-item,.docstring>section>a.hero.docs-sourcelink .navbar-item,.hero.is-primary .navbar-link,.docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-primary a.navbar-item:hover,.docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,.hero.is-primary a.navbar-item.is-active,.docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,.hero.is-primary .navbar-link:hover,.docstring>section>a.hero.docs-sourcelink .navbar-link:hover,.hero.is-primary .navbar-link.is-active,.docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#39acda;color:#fff}.hero.is-primary .tabs a,.docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}.hero.is-primary .tabs a:hover,.docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}.hero.is-primary .tabs li.is-active a,.docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{color:#4eb5de !important;opacity:1}.hero.is-primary .tabs.is-boxed a,.docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,.hero.is-primary .tabs.is-toggle a,.docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}.hero.is-primary .tabs.is-boxed a:hover,.docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,.hero.is-primary .tabs.is-toggle a:hover,.docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-primary .tabs.is-boxed li.is-active a,.docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,.hero.is-primary .tabs.is-boxed li.is-active a:hover,.hero.is-primary .tabs.is-toggle li.is-active a,.docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,.hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#4eb5de}.hero.is-primary.is-bold,.docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #1bc7de 0%, #4eb5de 71%, #5fa9e7 100%)}@media screen and (max-width: 768px){.hero.is-primary.is-bold .navbar-menu,.docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #1bc7de 0%, #4eb5de 71%, #5fa9e7 100%)}}.hero.is-link{background-color:#2e63b8;color:#fff}.hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-link strong{color:inherit}.hero.is-link .title{color:#fff}.hero.is-link .subtitle{color:rgba(255,255,255,0.9)}.hero.is-link .subtitle a:not(.button),.hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-link .navbar-menu{background-color:#2e63b8}}.hero.is-link .navbar-item,.hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-link a.navbar-item:hover,.hero.is-link a.navbar-item.is-active,.hero.is-link .navbar-link:hover,.hero.is-link .navbar-link.is-active{background-color:#2958a4;color:#fff}.hero.is-link .tabs a{color:#fff;opacity:0.9}.hero.is-link .tabs a:hover{opacity:1}.hero.is-link .tabs li.is-active a{color:#2e63b8 !important;opacity:1}.hero.is-link .tabs.is-boxed a,.hero.is-link .tabs.is-toggle a{color:#fff}.hero.is-link .tabs.is-boxed a:hover,.hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-link .tabs.is-boxed li.is-active a,.hero.is-link .tabs.is-boxed li.is-active a:hover,.hero.is-link .tabs.is-toggle li.is-active a,.hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#2e63b8}.hero.is-link.is-bold{background-image:linear-gradient(141deg, #1b6098 0%, #2e63b8 71%, #2d51d2 100%)}@media screen and (max-width: 768px){.hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #1b6098 0%, #2e63b8 71%, #2d51d2 100%)}}.hero.is-info{background-color:#209cee;color:#fff}.hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-info strong{color:inherit}.hero.is-info .title{color:#fff}.hero.is-info .subtitle{color:rgba(255,255,255,0.9)}.hero.is-info .subtitle a:not(.button),.hero.is-info .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-info .navbar-menu{background-color:#209cee}}.hero.is-info .navbar-item,.hero.is-info .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-info a.navbar-item:hover,.hero.is-info a.navbar-item.is-active,.hero.is-info .navbar-link:hover,.hero.is-info .navbar-link.is-active{background-color:#1190e3;color:#fff}.hero.is-info .tabs a{color:#fff;opacity:0.9}.hero.is-info .tabs a:hover{opacity:1}.hero.is-info .tabs li.is-active a{color:#209cee !important;opacity:1}.hero.is-info .tabs.is-boxed a,.hero.is-info .tabs.is-toggle a{color:#fff}.hero.is-info .tabs.is-boxed a:hover,.hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-info .tabs.is-boxed li.is-active a,.hero.is-info .tabs.is-boxed li.is-active a:hover,.hero.is-info .tabs.is-toggle li.is-active a,.hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#209cee}.hero.is-info.is-bold{background-image:linear-gradient(141deg, #05a6d6 0%, #209cee 71%, #3287f5 100%)}@media screen and (max-width: 768px){.hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #05a6d6 0%, #209cee 71%, #3287f5 100%)}}.hero.is-success{background-color:#22c35b;color:#fff}.hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-success strong{color:inherit}.hero.is-success .title{color:#fff}.hero.is-success .subtitle{color:rgba(255,255,255,0.9)}.hero.is-success .subtitle a:not(.button),.hero.is-success .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-success .navbar-menu{background-color:#22c35b}}.hero.is-success .navbar-item,.hero.is-success .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-success a.navbar-item:hover,.hero.is-success a.navbar-item.is-active,.hero.is-success .navbar-link:hover,.hero.is-success .navbar-link.is-active{background-color:#1ead51;color:#fff}.hero.is-success .tabs a{color:#fff;opacity:0.9}.hero.is-success .tabs a:hover{opacity:1}.hero.is-success .tabs li.is-active a{color:#22c35b !important;opacity:1}.hero.is-success .tabs.is-boxed a,.hero.is-success .tabs.is-toggle a{color:#fff}.hero.is-success .tabs.is-boxed a:hover,.hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-success .tabs.is-boxed li.is-active a,.hero.is-success .tabs.is-boxed li.is-active a:hover,.hero.is-success .tabs.is-toggle li.is-active a,.hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#22c35b}.hero.is-success.is-bold{background-image:linear-gradient(141deg, #12a02c 0%, #22c35b 71%, #1fdf83 100%)}@media screen and (max-width: 768px){.hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #12a02c 0%, #22c35b 71%, #1fdf83 100%)}}.hero.is-warning{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-warning strong{color:inherit}.hero.is-warning .title{color:rgba(0,0,0,0.7)}.hero.is-warning .subtitle{color:rgba(0,0,0,0.9)}.hero.is-warning .subtitle a:not(.button),.hero.is-warning .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){.hero.is-warning .navbar-menu{background-color:#ffdd57}}.hero.is-warning .navbar-item,.hero.is-warning .navbar-link{color:rgba(0,0,0,0.7)}.hero.is-warning a.navbar-item:hover,.hero.is-warning a.navbar-item.is-active,.hero.is-warning .navbar-link:hover,.hero.is-warning .navbar-link.is-active{background-color:#ffd83e;color:rgba(0,0,0,0.7)}.hero.is-warning .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}.hero.is-warning .tabs a:hover{opacity:1}.hero.is-warning .tabs li.is-active a{color:#ffdd57 !important;opacity:1}.hero.is-warning .tabs.is-boxed a,.hero.is-warning .tabs.is-toggle a{color:rgba(0,0,0,0.7)}.hero.is-warning .tabs.is-boxed a:hover,.hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-warning .tabs.is-boxed li.is-active a,.hero.is-warning .tabs.is-boxed li.is-active a:hover,.hero.is-warning .tabs.is-toggle li.is-active a,.hero.is-warning .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:#ffdd57}.hero.is-warning.is-bold{background-image:linear-gradient(141deg, #ffae24 0%, #ffdd57 71%, #fffa71 100%)}@media screen and (max-width: 768px){.hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #ffae24 0%, #ffdd57 71%, #fffa71 100%)}}.hero.is-danger{background-color:#da0b00;color:#fff}.hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-danger strong{color:inherit}.hero.is-danger .title{color:#fff}.hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}.hero.is-danger .subtitle a:not(.button),.hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-danger .navbar-menu{background-color:#da0b00}}.hero.is-danger .navbar-item,.hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-danger a.navbar-item:hover,.hero.is-danger a.navbar-item.is-active,.hero.is-danger .navbar-link:hover,.hero.is-danger .navbar-link.is-active{background-color:#c10a00;color:#fff}.hero.is-danger .tabs a{color:#fff;opacity:0.9}.hero.is-danger .tabs a:hover{opacity:1}.hero.is-danger .tabs li.is-active a{color:#da0b00 !important;opacity:1}.hero.is-danger .tabs.is-boxed a,.hero.is-danger .tabs.is-toggle a{color:#fff}.hero.is-danger .tabs.is-boxed a:hover,.hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-danger .tabs.is-boxed li.is-active a,.hero.is-danger .tabs.is-boxed li.is-active a:hover,.hero.is-danger .tabs.is-toggle li.is-active a,.hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#da0b00}.hero.is-danger.is-bold{background-image:linear-gradient(141deg, #a70013 0%, #da0b00 71%, #f43500 100%)}@media screen and (max-width: 768px){.hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #a70013 0%, #da0b00 71%, #f43500 100%)}}.hero.is-small .hero-body,#documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding:1.5rem}@media screen and (min-width: 769px),print{.hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{.hero.is-large .hero-body{padding:18rem 6rem}}.hero.is-halfheight .hero-body,.hero.is-fullheight .hero-body,.hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}.hero.is-halfheight .hero-body>.container,.hero.is-fullheight .hero-body>.container,.hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}.hero.is-halfheight{min-height:50vh}.hero.is-fullheight{min-height:100vh}.hero-video{overflow:hidden}.hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}.hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){.hero-video{display:none}}.hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){.hero-buttons .button{display:flex}.hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{.hero-buttons{display:flex;justify-content:center}.hero-buttons .button:not(:last-child){margin-right:1.5rem}}.hero-head,.hero-foot{flex-grow:0;flex-shrink:0}.hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width: 769px),print{.hero-body{padding:3rem 3rem}}.section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){.section{padding:3rem 3rem}.section.is-medium{padding:9rem 4.5rem}.section.is-large{padding:18rem 6rem}}.footer{background-color:#fafafa;padding:3rem 1.5rem 6rem}h1 .docs-heading-anchor,h1 .docs-heading-anchor:hover,h1 .docs-heading-anchor:visited,h2 .docs-heading-anchor,h2 .docs-heading-anchor:hover,h2 .docs-heading-anchor:visited,h3 .docs-heading-anchor,h3 .docs-heading-anchor:hover,h3 .docs-heading-anchor:visited,h4 .docs-heading-anchor,h4 .docs-heading-anchor:hover,h4 .docs-heading-anchor:visited,h5 .docs-heading-anchor,h5 .docs-heading-anchor:hover,h5 .docs-heading-anchor:visited,h6 .docs-heading-anchor,h6 .docs-heading-anchor:hover,h6 .docs-heading-anchor:visited{color:#222}h1 .docs-heading-anchor-permalink,h2 .docs-heading-anchor-permalink,h3 .docs-heading-anchor-permalink,h4 .docs-heading-anchor-permalink,h5 .docs-heading-anchor-permalink,h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}h1 .docs-heading-anchor-permalink::before,h2 .docs-heading-anchor-permalink::before,h3 .docs-heading-anchor-permalink::before,h4 .docs-heading-anchor-permalink::before,h5 .docs-heading-anchor-permalink::before,h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f0c1"}h1:hover .docs-heading-anchor-permalink,h2:hover .docs-heading-anchor-permalink,h3:hover .docs-heading-anchor-permalink,h4:hover .docs-heading-anchor-permalink,h5:hover .docs-heading-anchor-permalink,h6:hover .docs-heading-anchor-permalink{visibility:visible}.docs-dark-only{display:none !important}pre{position:relative;overflow:hidden}pre code,pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}pre code:first-of-type,pre code.hljs:first-of-type{padding-top:0.5rem !important}pre code:last-of-type,pre code.hljs:last-of-type{padding-bottom:0.5rem !important}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:#222;cursor:pointer;text-align:center}pre .copy-button:focus,pre .copy-button:hover{opacity:1;background:rgba(34,34,34,0.1);color:#2e63b8}pre .copy-button.success{color:#259a12;opacity:1}pre .copy-button.error{color:#cb3c33;opacity:1}pre:hover .copy-button{opacity:1}.admonition{background-color:#b5b5b5;border-style:solid;border-width:1px;border-color:#363636;border-radius:4px;font-size:1rem}.admonition strong{color:currentColor}.admonition.is-small,#documenter .docs-sidebar form.docs-search>input.admonition{font-size:.75rem}.admonition.is-medium{font-size:1.25rem}.admonition.is-large{font-size:1.5rem}.admonition.is-default{background-color:#b5b5b5;border-color:#363636}.admonition.is-default>.admonition-header{background-color:#363636;color:#fff}.admonition.is-default>.admonition-body{color:#fff}.admonition.is-info{background-color:#def0fc;border-color:#209cee}.admonition.is-info>.admonition-header{background-color:#209cee;color:#fff}.admonition.is-info>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-success{background-color:#bdf4d1;border-color:#22c35b}.admonition.is-success>.admonition-header{background-color:#22c35b;color:#fff}.admonition.is-success>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-warning{background-color:#fff3c5;border-color:#ffdd57}.admonition.is-warning>.admonition-header{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.admonition.is-warning>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-danger{background-color:#ffaba7;border-color:#da0b00}.admonition.is-danger>.admonition-header{background-color:#da0b00;color:#fff}.admonition.is-danger>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-compat{background-color:#bdeff5;border-color:#1db5c9}.admonition.is-compat>.admonition-header{background-color:#1db5c9;color:#fff}.admonition.is-compat>.admonition-body{color:rgba(0,0,0,0.7)}.admonition-header{color:#fff;background-color:#363636;align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}details.admonition.is-details>.admonition-header{list-style:none}details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}.admonition-body{color:#222;padding:0.5rem .75rem}.admonition-body pre{background-color:#f5f5f5}.admonition-body code{background-color:rgba(0,0,0,0.05)}.docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:1px solid #dbdbdb;box-shadow:2px 2px 3px rgba(10,10,10,0.1);max-width:100%}.docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#f5f5f5;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #dbdbdb;overflow:auto}.docstring>header code{background-color:transparent}.docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}.docstring>header .docstring-binding{margin-right:0.3em}.docstring>header .docstring-category{margin-left:0.3em}.docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #dbdbdb}.docstring>section:last-child{border-bottom:none}.docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}.docstring>section>a.docs-sourcelink:focus{opacity:1 !important}.docstring:hover>section>a.docs-sourcelink{opacity:0.2}.docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}.docstring>section:hover a.docs-sourcelink{opacity:1}.documenter-example-output{background-color:#fff}.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:#ffaba7;color:rgba(0,0,0,0.7);border-bottom:3px solid #da0b00;padding:10px 35px;text-align:center;font-size:15px}.outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}.outdated-warning-overlay a{color:#2e63b8}.outdated-warning-overlay a:hover{color:#363636}.content pre{border:1px solid #dbdbdb}.content code{font-weight:inherit}.content a code{color:#2e63b8}.content a:hover code{color:#363636}.content h1 code,.content h2 code,.content h3 code,.content h4 code,.content h5 code,.content h6 code{color:#222}.content table{display:block;width:initial;max-width:100%;overflow-x:auto}.content blockquote>ul:first-child,.content blockquote>ol:first-child,.content .admonition-body>ul:first-child,.content .admonition-body>ol:first-child{margin-top:0}pre,code{font-variant-ligatures:no-contextual}.breadcrumb a.is-disabled{cursor:default;pointer-events:none}.breadcrumb a.is-disabled,.breadcrumb a.is-disabled:hover{color:#222}.hljs{background:initial !important}.katex .katex-mathml{top:0;right:0}.katex-display,mjx-container,.MathJax_Display{margin:0.5em 0 !important}html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}li.no-marker{list-style:none}#documenter .docs-main>article{overflow-wrap:break-word}#documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){#documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){#documenter .docs-main{width:100%}#documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}#documenter .docs-main>header,#documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}#documenter .docs-main header.docs-navbar{background-color:#fff;border-bottom:1px solid #dbdbdb;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}#documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1;overflow-x:hidden}#documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}#documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}#documenter .docs-main header.docs-navbar .docs-right .docs-icon,#documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}#documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){#documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}#documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){#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}#documenter .docs-main header.docs-navbar.headroom--not-top{box-shadow:.2rem 0rem .4rem #bbb;transition-duration:0.7s;-webkit-transition-duration:0.7s}#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}}#documenter .docs-main section.footnotes{border-top:1px solid #dbdbdb}#documenter .docs-main section.footnotes li .tag:first-child,#documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,#documenter .docs-main section.footnotes li .content kbd:first-child,.content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}#documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #dbdbdb;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){#documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}#documenter .docs-main .docs-footer .docs-footer-nextpage,#documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}#documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}#documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}#documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}#documenter .docs-sidebar{display:flex;flex-direction:column;color:#0a0a0a;background-color:#f5f5f5;border-right:1px solid #dbdbdb;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}#documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #bbb}@media screen and (min-width: 1056px){#documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){#documenter .docs-sidebar{left:0;top:0}}#documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}#documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}#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}#documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}#documenter .docs-sidebar .docs-package-name a,#documenter .docs-sidebar .docs-package-name a:hover{color:#0a0a0a}#documenter .docs-sidebar .docs-version-selector{border-top:1px solid #dbdbdb;display:none;padding:0.5rem}#documenter .docs-sidebar .docs-version-selector.visible{display:flex}#documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #dbdbdb;padding-bottom:1.5rem}#documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}#documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #dbdbdb}#documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}#documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}#documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}#documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}#documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}#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}#documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}#documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}#documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}#documenter .docs-sidebar ul.docs-menu .tocitem,#documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#0a0a0a;background:#f5f5f5}#documenter .docs-sidebar ul.docs-menu a.tocitem:hover,#documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#0a0a0a;background-color:#ebebeb}#documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #dbdbdb;border-bottom:1px solid #dbdbdb;background-color:#fff}#documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,#documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#fff;color:#0a0a0a}#documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#ebebeb;color:#0a0a0a}#documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}#documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #dbdbdb}#documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}#documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}#documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}#documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}#documenter .docs-sidebar form.docs-search>input{width:14.4rem}#documenter .docs-sidebar #documenter-search-query{color:#707070;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){#documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}#documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}#documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#e0e0e0}#documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#ccc}}@media screen and (max-width: 1055px){#documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}#documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}#documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#e0e0e0}#documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#ccc}}kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(0,0,0,0.6);box-shadow:0 2px 0 1px rgba(0,0,0,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}.search-min-width-50{min-width:50%}.search-min-height-100{min-height:100%}.search-modal-card-body{max-height:calc(100vh - 15rem)}.search-result-link{border-radius:0.7em;transition:all 300ms}.search-result-link:hover,.search-result-link:focus{background-color:rgba(0,128,128,0.1)}.search-result-link .property-search-result-badge,.search-result-link .search-filter{transition:all 300ms}.property-search-result-badge,.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}.search-result-link:hover .property-search-result-badge,.search-result-link:hover .search-filter,.search-result-link:focus .property-search-result-badge,.search-result-link:focus .search-filter{color:#f1f5f9;background-color:#333}.search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}.search-filter:hover,.search-filter:focus{color:#333}.search-filter-selected{color:#f5f5f5;background-color:rgba(139,0,139,0.5)}.search-filter-selected:hover,.search-filter-selected:focus{color:#f5f5f5}.search-result-highlight{background-color:#ffdd57;color:black}.search-divider{border-bottom:1px solid #dbdbdb}.search-result-title{width:85%;color:#333}.search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}#search-modal .modal-card-body::-webkit-scrollbar,#search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}#search-modal .modal-card-body::-webkit-scrollbar-thumb,#search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}#search-modal .modal-card-body::-webkit-scrollbar-track,#search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}.w-100{width:100%}.gap-2{gap:0.5rem}.gap-4{gap:1rem}.gap-8{gap:2rem}.ansi span.sgr1{font-weight:bolder}.ansi span.sgr2{font-weight:lighter}.ansi span.sgr3{font-style:italic}.ansi span.sgr4{text-decoration:underline}.ansi span.sgr7{color:#fff;background-color:#222}.ansi span.sgr8{color:transparent}.ansi span.sgr8 span{color:transparent}.ansi span.sgr9{text-decoration:line-through}.ansi span.sgr30{color:#242424}.ansi span.sgr31{color:#a7201f}.ansi span.sgr32{color:#066f00}.ansi span.sgr33{color:#856b00}.ansi span.sgr34{color:#2149b0}.ansi span.sgr35{color:#7d4498}.ansi span.sgr36{color:#007989}.ansi span.sgr37{color:gray}.ansi span.sgr40{background-color:#242424}.ansi span.sgr41{background-color:#a7201f}.ansi span.sgr42{background-color:#066f00}.ansi span.sgr43{background-color:#856b00}.ansi span.sgr44{background-color:#2149b0}.ansi span.sgr45{background-color:#7d4498}.ansi span.sgr46{background-color:#007989}.ansi span.sgr47{background-color:gray}.ansi span.sgr90{color:#616161}.ansi span.sgr91{color:#cb3c33}.ansi span.sgr92{color:#0e8300}.ansi span.sgr93{color:#a98800}.ansi span.sgr94{color:#3c5dcd}.ansi span.sgr95{color:#9256af}.ansi span.sgr96{color:#008fa3}.ansi span.sgr97{color:#f5f5f5}.ansi span.sgr100{background-color:#616161}.ansi span.sgr101{background-color:#cb3c33}.ansi span.sgr102{background-color:#0e8300}.ansi span.sgr103{background-color:#a98800}.ansi span.sgr104{background-color:#3c5dcd}.ansi span.sgr105{background-color:#9256af}.ansi span.sgr106{background-color:#008fa3}.ansi span.sgr107{background-color:#f5f5f5}code.language-julia-repl>span.hljs-meta{color:#066f00;font-weight:bolder}/*! + Theme: Default + Description: Original highlight.js style + Author: (c) Ivan Sagalaev + Maintainer: @highlightjs/core-team + 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}.gap-4{gap:1rem} diff --git a/v0.1.8/assets/themeswap.js b/v0.1.8/assets/themeswap.js new file mode 100644 index 0000000..9f5eebe --- /dev/null +++ b/v0.1.8/assets/themeswap.js @@ -0,0 +1,84 @@ +// Small function to quickly swap out themes. Gets put into the tag.. +function set_theme_from_local_storage() { + // Initialize the theme to null, which means default + var theme = null; + // If the browser supports the localstorage and is not disabled then try to get the + // documenter theme + if (window.localStorage != null) { + // Get the user-picked theme from localStorage. May be `null`, which means the default + // theme. + theme = window.localStorage.getItem("documenter-theme"); + } + // Check if the users preference is for dark color scheme + var darkPreference = + window.matchMedia("(prefers-color-scheme: dark)").matches === true; + // Initialize a few variables for the loop: + // + // - active: will contain the index of the theme that should be active. Note that there + // is no guarantee that localStorage contains sane values. If `active` stays `null` + // we either could not find the theme or it is the default (primary) theme anyway. + // Either way, we then need to stick to the primary theme. + // + // - disabled: style sheets that should be disabled (i.e. all the theme style sheets + // that are not the currently active theme) + var active = null; + var disabled = []; + var primaryLightTheme = null; + var primaryDarkTheme = null; + for (var i = 0; i < document.styleSheets.length; i++) { + var ss = document.styleSheets[i]; + // The tag of each style sheet is expected to have a data-theme-name attribute + // which must contain the name of the theme. The names in localStorage much match this. + var themename = ss.ownerNode.getAttribute("data-theme-name"); + // attribute not set => non-theme stylesheet => ignore + if (themename === null) continue; + // To distinguish the default (primary) theme, it needs to have the data-theme-primary + // attribute set. + if (ss.ownerNode.getAttribute("data-theme-primary") !== null) { + primaryLightTheme = themename; + } + // Check if the theme is primary dark theme so that we could store its name in darkTheme + if (ss.ownerNode.getAttribute("data-theme-primary-dark") !== null) { + primaryDarkTheme = themename; + } + // If we find a matching theme (and it's not the default), we'll set active to non-null + if (themename === theme) active = i; + // Store the style sheets of inactive themes so that we could disable them + if (themename !== theme) disabled.push(ss); + } + var activeTheme = null; + if (active !== null) { + // If we did find an active theme, we'll (1) add the theme--$(theme) class to + document.getElementsByTagName("html")[0].className = "theme--" + theme; + activeTheme = theme; + } else { + // If we did _not_ find an active theme, then we need to fall back to the primary theme + // which can either be dark or light, depending on the user's OS preference. + var activeTheme = darkPreference ? primaryDarkTheme : primaryLightTheme; + // In case it somehow happens that the relevant primary theme was not found in the + // preceding loop, we abort without doing anything. + if (activeTheme === null) { + console.error("Unable to determine primary theme."); + return; + } + // When switching to the primary light theme, then we must not have a class name + // for the tag. That's only for non-primary or the primary dark theme. + if (darkPreference) { + document.getElementsByTagName("html")[0].className = + "theme--" + activeTheme; + } else { + document.getElementsByTagName("html")[0].className = ""; + } + } + for (var i = 0; i < document.styleSheets.length; i++) { + var ss = document.styleSheets[i]; + // The tag of each style sheet is expected to have a data-theme-name attribute + // which must contain the name of the theme. The names in localStorage much match this. + var themename = ss.ownerNode.getAttribute("data-theme-name"); + // attribute not set => non-theme stylesheet => ignore + if (themename === null) continue; + // we'll disable all the stylesheets, except for the active one + ss.disabled = !(themename == activeTheme); + } +} +set_theme_from_local_storage(); diff --git a/v0.1.8/assets/warner.js b/v0.1.8/assets/warner.js new file mode 100644 index 0000000..3f6f5d0 --- /dev/null +++ b/v0.1.8/assets/warner.js @@ -0,0 +1,52 @@ +function maybeAddWarning() { + // DOCUMENTER_NEWEST is defined in versions.js, DOCUMENTER_CURRENT_VERSION and DOCUMENTER_STABLE + // in siteinfo.js. + // If either of these are undefined something went horribly wrong, so we abort. + if ( + window.DOCUMENTER_NEWEST === undefined || + window.DOCUMENTER_CURRENT_VERSION === undefined || + window.DOCUMENTER_STABLE === undefined + ) { + return; + } + + // Current version is not a version number, so we can't tell if it's the newest version. Abort. + if (!/v(\d+\.)*\d+/.test(window.DOCUMENTER_CURRENT_VERSION)) { + return; + } + + // Current version is newest version, so no need to add a warning. + if (window.DOCUMENTER_NEWEST === window.DOCUMENTER_CURRENT_VERSION) { + return; + } + + // Add a noindex meta tag (unless one exists) so that search engines don't index this version of the docs. + if (document.body.querySelector('meta[name="robots"]') === null) { + const meta = document.createElement("meta"); + meta.name = "robots"; + meta.content = "noindex"; + + document.getElementsByTagName("head")[0].appendChild(meta); + } + + const div = document.createElement("div"); + div.classList.add("outdated-warning-overlay"); + const closer = document.createElement("button"); + closer.classList.add("outdated-warning-closer", "delete"); + closer.addEventListener("click", function () { + document.body.removeChild(div); + }); + const href = window.documenterBaseURL + "/../" + window.DOCUMENTER_STABLE; + div.innerHTML = + 'This documentation is not for the latest stable release, but for either the development version or an older release.
Click here to go to the documentation for the latest stable release.'; + div.appendChild(closer); + document.body.appendChild(div); +} + +if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", maybeAddWarning); +} else { + maybeAddWarning(); +} diff --git a/v0.1.8/changelog/index.html b/v0.1.8/changelog/index.html new file mode 100644 index 0000000..5caee3a --- /dev/null +++ b/v0.1.8/changelog/index.html @@ -0,0 +1,2 @@ + +Changelog · ManoptExamples.jl

Changelog

All notable changes to this Julia package will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[0.1.8] – 12/06/2024

Changed

  • use range compatible with Julia 1.6 and hence lower the compatibility entry for Julia again.

[0.1.7] – 07/06/2024

Changed

  • make Manopt.jl a weak dependency and load functions that require parts of it only load as an extension. This makes it easier to use the examples in the tests of Manopt itself.

[0.1.6] – 22/03/2024

Added

  • Hyperparameter optimization example.

[0.1.3] – 11/12/2023

Added

  • Total variation Minimization cost, proxes, and an example
  • Bézier curve cost, gradients, and an example.

[0.1.3] – 16/09/2023

Added

  • Rayleigh Quotient functions added
  • an example illustrating Euclidean gradient/HEssian conversion
  • Add Literature with DocumenterCitations

[0.1.2] – 13/06/2023

Added

  • Update examples to use Quarto
  • Add DC examples

[0.1.1] – 01/03/2023

Added

  • Rosenbrock function and examples

[0.1.0] – 18/02/2023

Added

  • Setup the project to collect example objectives for Manopt.jl which are well-documented and well-tested
  • Setup Documentation to provide one example Quarto file for every example objective to illustrate how to use them.
diff --git a/v0.1.8/contributing/index.html b/v0.1.8/contributing/index.html new file mode 100644 index 0000000..92e67e5 --- /dev/null +++ b/v0.1.8/contributing/index.html @@ -0,0 +1,2 @@ + +Contributing to ManoptExamples.jl · ManoptExamples.jl

Contributing to Manopt.jl

First, thanks for taking the time to contribute. Any contribution is appreciated and welcome.

The following is a set of guidelines to ManoptExamples.jl.

Table of Contents

I just have a question

The developer can most easily be reached in the Julia Slack channel #manifolds. You can apply for the Julia Slack workspace here if you haven't joined yet. You can also ask your question on our GitHub discussion.

How can I file an issue?

If you found a bug or want to propose a feature, we track our issues within the GitHub repository.

How can I contribute?

Add an objective

The objective in Manopt.jl represents the task to be optimised, usually phrased on an arbitrary manifold. The manifold is later specified when wrapping the objective inside a Problem.

If you have a specific objective you would like to provide here, feel free to start a new file in the src/objectives/ folder in your own fork and propose it later as a Pull Request.

If you objective works without reusing any other objective functions, then they can all just be placed in this one file. If you notice, that you are reusing for example another objectives gradient as part of your objective, please refactor the code, such that the gradient, or other function is in the corresponding file in src/functions/ and follows the naming scheme:

  • cost functions are always of the form cost_ and a fitting name
  • gradient functions are always of the gradient_ and a fitting name, followed by an !

for in-place gradients and by !! if it is a struct that can provide both.

It would be great if you could also add a small test for the functions and the problem you defined in the test/ section.

Add an example

If you have used one of the problems from here in an example or you are providing a problem together with an example, please add a corresponding Quarto Markdown file to the examples/ folder. The Markdown file should provide a short introduction to the problem and provide links to further details, maybe a paper or a preprint. Use the bib/literature.yaml file to add references (in CSL_YAML, which can for example be exported e.g. from Zotero).

Add any packages you need to the examples/ environment (see the containting Project.toml). The examples will not be run on CI, but their rendered CommonMark outpout should be included in the list of examples in the documentation of this package.

Code style

We try to follow the documentation guidelines from the Julia documentation as well as Blue Style. We run JuliaFormatter.jl on the repo in the way set in the .JuliaFormatter.toml file, which enforces a number of conventions consistent with the Blue Style.

We also follow a few internal conventions:

  • Any implemented function should be accompanied by its mathematical formulae if a closed form exists.
  • within a file the structs should come first and functions second. The only exception are constructors for the structs
  • within both blocks an alphabetical order is preferable.
  • The above implies that the mutating variant of a function follows the non-mutating variant.
  • There should be no dangling = signs.
  • Always add a newline between things of different types (struct/method/const).
  • Always add a newline between methods for different functions (including in-place/non-mutating variants).
  • Prefer to have no newline between methods for the same function; when reasonable, merge the docstrings into a generic function signature.
  • All import/using/include should be in the main module file.
  • There should only be a minimum of exports within this file, all problems should usually be later addressed as ManoptExamples.[...]
  • the Quarto Markdown files are excluded from this formatting.
diff --git a/v0.1.8/data/index.html b/v0.1.8/data/index.html new file mode 100644 index 0000000..1b432c5 --- /dev/null +++ b/v0.1.8/data/index.html @@ -0,0 +1,13 @@ + +Data · ManoptExamples.jl

Data sets

Signals on manifolds

ManoptExamples.LemniscateMethod
Lemniscate(t::Float; kwargs...)
+Lemniscate(n::integer; interval=[0.0, 2π], kwargs...)

generate the Lemniscate of Bernoulli as a curve on a manifold, by generating the curve emplying the keyword arguments below.

To be precise on the manifold M we use the tangent space at p and generate the curve

\[γ(t) \frac{a}{}\sin^2(t) + 1 \begin{pmatrix} \cos(t) \\ \cos(t)\sin(t) \end{pmatrix}\]

in the plane spanned by X and Y in the tangent space. Note that this curve is $2π$-periodic and a is the half-width of the curve.

To reproduce the first examples from [BBSW16] as a default, on the sphere p defaults to the North pole.

THe second variant generates n points equispaced in ìnterval` and calls the first variant.

Keywords

  • manifold - (Sphere(2)) the manifold to build the lemniscate on
  • p - ([0.0, 0.0, 1.0] on the sphere, `rand(M) else) the center point of the Lemniscate
  • a – (π/2.0) half-width of the Lemniscate
  • X – ([1.0, 0.0, 0.0] for the 2-sphere with default p, the first DefaultOrthonormalBasis() vector otherwise) first direction for the plane to define the Lemniscate in, unit vector recommended.
  • Y – ([0.0, 1.0, 0.0] if p is the default, the second DefaultOrthonormalBasis() vector otherwise) second direction for the plane to define the Lemniscate in, unit vector orthogonal to X recommended.
source
ManoptExamples.artificial_S1_signalFunction
artificial_S1_signal([pts=500])

generate a real-valued signal having piecewise constant, linear and quadratic intervals with jumps in between. If the resulting manifold the data lives on, is the Circle the data is also wrapped to ``[BLSW14].

Optional

  • pts: (500) number of points to sample the function
source
ManoptExamples.artificial_S1_signalMethod
artificial_S1_signal(x)

evaluate the example signal $f(x), x ∈ [0,1]$, of phase-valued data introduces in Sec. 5.1 of [BLSW14] for values outside that interval, this Signal is missing.

source
ManoptExamples.artificial_S1_slope_signalFunction
artificial_S1_slope_signal([pts=500, slope=4.])

Creates a Signal of (phase-valued) data represented on the Circle with increasing slope.

Optional

  • pts: (500) number of points to sample the function.
  • slope: (4.0) initial slope that gets increased afterwards

This data set was introduced for the numerical examples in [BLSW14]

source
ManoptExamples.artificial_S2_composite_Bezier_curveMethod
artificial_S2_composite_Bezier_curve()

Generate a composite Bézier curve on the [BG18].

It consists of 4 egments connecting the points

\[\mathbf d_0 = \begin{pmatrix} 0\\0\\1\end{pmatrix},\quad +\mathbf d_1 = \begin{pmatrix} 0\\-1\\0\end{pmatrix},\quad +\mathbf d_2 = \begin{pmatrix} -1\\0\\0\end{pmatrix},\text{ and } +\mathbf d_3 = \begin{pmatrix} 0\\0\\-1\end{pmatrix}.\]

where instead of providing the two center control points explicitly we provide them as velocities from the corresponding points, such thtat we can directly define the curve to be $C^1$.

We define

\[X_0 = \frac{π}{8\sqrt{2}}\begin{pmatrix}1\\-1\\0\end{pmatrix},\quad +X_1 = \frac{π}{4\sqrt{2}}\begin{pmatrix}1\\0\\1\end{pmatrix},\quad +X_2 = \frac{π}{4\sqrt{2}}\begin{pmatrix}0\\1\\-1\end{pmatrix},\text{ and } +X_3 = \frac{π}{8\sqrt{2}}\begin{pmatrix}-1\\1\\0\end{pmatrix},\]

where we defined each $X_i \in T_{d_i}\mathbb S^2$. We defined three BezierSegments

of cubic Bézier curves as follows

\[\begin{align*} +b_{0,0} &= d_0, \quad & b_{1,0} &= \exp_{d_0}X_0, \quad & b_{2,0} &= \exp_{d_1}X_1, \quad & b_{3,0} &= d_1\\ +b_{0,1} &= d_1, \quad & b_{1,1} &= \exp_{d_1}(-X_1), \quad & b_{2,1} &= \exp_{d_2}X_2, \quad & b_{3,1} &= d_2\\ +b_{0,2} &= d_2, \quad & b_{1,1} &= \exp_{d_2}(-X_2), \quad & b_{2,2} &= \exp_{d_3}X_3, \quad & b_{3,2} &= d_3. +\end{align*}\]

source

images on manifolds

ManoptExamples.artificial_S2_rotation_imageFunction
artificial_S2_rotation_image([pts=64, rotations=(.5,.5)])

Create an image with a rotation on each axis as a parametrization.

Optional Parameters

  • pts: (64) number of pixels along one dimension
  • rotations: ((.5,.5)) number of total rotations performed on the axes.

This dataset was used in the numerical example of Section 5.1 of [BBSW16].

source
ManoptExamples.artificial_SPD_imageFunction
artificial_SPD_image([pts=64, stepsize=1.5])

create an artificial image of symmetric positive definite matrices of size pts×pts pixel with a jump of size stepsize.

This dataset was used in the numerical example of Section 5.2 of [BBSW16].

source
ManoptExamples.artificial_SPD_image2Function
artificial_SPD_image2([pts=64, fraction=.66])

create an artificial image of symmetric positive definite matrices of size pts×pts pixel with right hand side fraction is moved upwards.

This data set was introduced in the numerical examples of Section of [BPS16]

source

Literature

[BBSW16]
M. Bačák, R. Bergmann, G. Steidl and A. Weinmann. A second order non-smooth variational model for restoring manifold-valued images. SIAM Journal on Scientific Computing 38, A567–A597 (2016), arXiv:1506.02409.
[BG18]
R. Bergmann and P.-Y. Gousenbourger. A variational model for data fitting on manifolds by minimizing the acceleration of a Bézier curve. Frontiers in Applied Mathematics and Statistics 4 (2018), arXiv:1807.10090.
[BLSW14]
R. Bergmann, F. Laus, G. Steidl and A. Weinmann. Second order differences of cyclic data and applications in variational denoising. SIAM Journal on Imaging Sciences 7, 2916–2953 (2014), arXiv:1405.5349.
[BPS16]
R. Bergmann, J. Persch and G. Steidl. A parallel Douglas Rachford algorithm for minimizing ROF-like functionals on images with values in symmetric Hadamard manifolds. SIAM Journal on Imaging Sciences 9, 901–937 (2016), arXiv:1512.02814.
[LNPS17]
F. Laus, M. Nikolova, J. Persch and G. Steidl. A nonlocal denoising algorithm for manifold-valued images using second order statistics. SIAM Journal on Imaging Sciences 10, 416–448 (2017).
diff --git a/v0.1.8/examples/Bezier-curves/index.html b/v0.1.8/examples/Bezier-curves/index.html new file mode 100644 index 0000000..fad0b30 --- /dev/null +++ b/v0.1.8/examples/Bezier-curves/index.html @@ -0,0 +1,68 @@ + +Minimizing the Acceleration of Bézier Curves on the Sphere · ManoptExamples.jl

Minimizing the Acceleration of Bézier Curves on the Sphere

Ronny Bergmann 2023-06-06

using Manifolds, Manopt, ManoptExamples

Introduction

Bézier Curves can be generalized to manifolds by generalizing the de Casteljau algorithm 📖 to work with geodesics instead of straight lines. An implementation in just a few lines as we demonstrated in [ABBR23] as

function bezier(M::AbstractManifold, t, pts::NTuple)
+    p = bezier(M, t, pts[1:(end - 1)])
+    q = bezier(M, t, pts[2:end])
+    return shortest_geodesic(M, p, q, t)
+end
+function bezier(M::AbstractManifold, t, pts::NTuple{2})
+    return shortest_geodesic(M, pts[1], pts[2], t)
+end

which is also available within this package as de_Casteljau using a simple BezierSegment struct to make it easier to also discuss the case where we compose a set of segments into a composite Bézier course.

In the following we will need the following packages and functions. They are documented in the section on Bezier Curves and were derived in [BG18] based on [PN07].

using ManoptExamples:
+    artificial_S2_composite_Bezier_curve,
+    BezierSegment,
+    de_Casteljau,
+    get_Bezier_degrees,
+    get_Bezier_inner_points,
+    get_Bezier_junctions,
+    get_Bezier_junction_tangent_vectors,
+    get_Bezier_points,
+    get_Bezier_segments,
+    grad_L2_acceleration_Bezier,
+    L2_acceleration_Bezier

This notebook reproduces the example form Section 5.2 in [BG18].

The following image illustrates how the de-Casteljau algorithm works for one segment.

A Bezier segment and illustration of the de-Casteljau algorithm

Approximating data by a curve with minimal accelartion

We first load our example data

M = Sphere(2)
+B = artificial_S2_composite_Bezier_curve()
+data_points = get_Bezier_junctions(M, B)

Which is the following cure, which clearly starts and ends slower than its speed in the middle, which can be seen by the increasing length of the gangent vectors in the middle.

The original curve

We continue to recude the points, since we “know” sme points due to the $C^1$ property: the second to last control point of the first segment $b_{0,2}$, the joint junction point connecting both segments $b_{0,3}=b_{1,0}$ and the second control point $b_{1,1}$ of the second segment have to line in the tangent space of the joint junction point. Hence we only have to store one of the control points.

We can use this reduced form as the variable to optimize and the one from the data as our initial point.

pB = get_Bezier_points(M, B, :differentiable)
+N = PowerManifold(M, NestedPowerRepresentation(), length(pB))
PowerManifold(Sphere(2, ℝ), NestedPowerRepresentation(), 8)

And we further define the acceleration of the curve as our cost function, where we discretize the acceleration at a certain set of points and set the $λ=10$

curve_samples = [range(0, 3; length=101)...] # sample curve for the gradient
+λ = 10.0
+function f(M, pB)
+    return L2_acceleration_Bezier(
+        M.manifold, pB, get_Bezier_degrees(M.manifold, B), curve_samples, λ, data_points
+    )
+end
+function grad_f(M, pB)
+    return grad_L2_acceleration_Bezier(
+        M.manifold, pB, get_Bezier_degrees(M.manifold, B), curve_samples, λ, data_points
+    )
+end
grad_f (generic function with 1 method)

Then we can optimize

x0 = pB
+pB_opt = gradient_descent(
+    N,
+    f,
+    grad_f,
+    x0;
+    stepsize=ArmijoLinesearch(N;
+        initial_stepsize=1.0,
+        retraction_method=ExponentialRetraction(),
+        contraction_factor=0.5,
+        sufficient_decrease=0.001,
+    ),
+    stopping_criterion=StopWhenChangeLess(1e-5) |
+                       StopWhenGradientNormLess(1e-7) |
+                       StopAfterIteration(300),
+    debug=[
+        :Iteration,
+        " | ",
+        :Cost,
+        " | ",
+        DebugGradientNorm(),
+        " | ",
+        DebugStepsize(),
+        " | ",
+        :Change,
+        "\n",
+        25,
+        :Stop,
+    ],
+);
Initial  | f(x): 10.647244 |  |  | 
+# 25     | f(x): 2.667564 | |grad f(p)|:0.890845571434862 | s:0.01326670131422904 | Last Change: 0.763281
+# 50     | f(x): 2.650064 | |grad f(p)|:0.05536989605165708 | s:0.05306680525691616 | Last Change: 0.081780
+# 75     | f(x): 2.649707 | |grad f(p)|:0.02135638585837997 | s:0.01326670131422904 | Last Change: 0.011590
+# 100    | f(x): 2.649700 | |grad f(p)|:0.0012887575647752057 | s:0.05306680525691616 | Last Change: 0.001745
+The algorithm performed a step with a change (2.9063044690733034e-7) less than 1.0e-5.

And we can again look at the result

The result looks as

The resulting curve

where all control points are evenly spaced and we hence have less acceleration as the final cost compared to the initial one indicates. Note that the cost is not zero, since we always have a tradeoff between approximating the initial junctinons (data points) and minimizing the acceleration.

[ABBR23]
S. D. Axen, M. Baran, R. Bergmann and K. Rzecki. Manifolds.jl: An Extensible Julia Framework for Data Analysis on Manifolds. ACM Transactions on Mathematical Software (2023), arXiv:2021.08777.
[BG18]
R. Bergmann and P.-Y. Gousenbourger. A variational model for data fitting on manifolds by minimizing the acceleration of a Bézier curve. Frontiers in Applied Mathematics and Statistics 4 (2018), arXiv:1807.10090.
[PN07]
T. Popiel and L. Noakes. Bézier curves and $C^2$ interpolation in Riemannian manifolds. Journal of Approximation Theory 148, 111–127 (2007).
diff --git a/v0.1.8/examples/Difference-of-Convex-Benchmark/index.html b/v0.1.8/examples/Difference-of-Convex-Benchmark/index.html new file mode 100644 index 0000000..635f899 --- /dev/null +++ b/v0.1.8/examples/Difference-of-Convex-Benchmark/index.html @@ -0,0 +1,165 @@ + +A Benchmark · ManoptExamples.jl

Benchmark of the Difference of Convex Algorithms

Ronny Bergmann 2023-06-06

Introduction

In this Benchmark we compare the Difference of Convex Algprithm (DCA) [BFSS23] and the Difference of Convex Proximal Point Algorithm (DCPPA) [SO15] which solve Difference of Convex (DC) problems of the form. This Benchmark reproduces the results from [BFSS23], Section 7.1.

\[\operatorname*{arg\,min}_{p\in\mathcal M}\ \ g(p) - h(p)\]

where $g,h\colon \mathcal M \to \mathbb R$ are geodesically convex function on the Riemannian manifold $\mathcal M$.

using LinearAlgebra, Random, Statistics, BenchmarkTools
+using Manifolds, Manopt, ManoptExamples
+using NamedColors, Plots
+Random.seed!(42)

and we load a few nice colors

paul_tol = load_paul_tol()
+indigo = paul_tol["mutedindigo"]
+teal = paul_tol["mutedteal"]

The DC Problem

We start with defining the two convex functions $g,h$ and their gradients as well as the DC problem $f$ and its gradient for the problem

\[ \operatorname*{arg\,min}_{p\in\mathcal M}\ \ \bigl( \log\bigr(\det(p)\bigr)\bigr)^4 - \bigl(\log \det(p) \bigr)^2.\]

where the critical points obtain a functional value of $-\frac{1}{4}$.

where $\mathcal M$ is the manifold of symmetric positive definite (SPD) matrices with the affine invariant metric, which is the default.

We first define the corresponding functions

g(M, p) = log(det(p))^4
+h(M, p) = log(det(p))^2
+f(M, p) = g(M, p) - h(M, p)

and their gradients

grad_g(M, p) = 4 * (log(det(p)))^3 * p
+grad_h(M, p) = 2 * log(det(p)) * p
+grad_f(M, p) = grad_g(M, p) - grad_h(M, p)

which we can use to verify that the gradients of $g$ and $h$ are correct. We use for that

n = 6
+M = SymmetricPositiveDefinite(n)
+p0 = log(n) * Matrix{Float64}(I, n, n);
+X0 = 1 / n * Matrix{Float64}(I, n, n);

to tall both checks

check_gradient(M, g, grad_g, p0, X0; plot=true)

and

check_gradient(M, h, grad_h, p0, X0; plot=true)

which both pass the test. We continue to define their inplace variants

function grad_g!(M, X, p)
+    copyto!(M, X, p)
+    X .*= 4 * (log(det(p)))^3
+    return X
+end
+function grad_h!(M, X, p)
+    copyto!(M, X, p)
+    X .*= 2 * (log(det(p)))
+    return X
+end
+function grad_f!(M, X, p)
+    grad_g!(M, X, p)
+    Y = copy(M, p, X)
+    grad_h!(M, Y, p)
+    X .-= Y
+    return X
+end

And compare times for both algorithms, with a bit of debug output.

@time p_min_dca = difference_of_convex_algorithm(
+    M,
+    f,
+    g,
+    grad_h!,
+    p0;
+    grad_g=grad_g!,
+    gradient=grad_f!,
+    evaluation=InplaceEvaluation(),
+    debug=[
+        :Iteration,
+        (:Cost, "f(p): %1.9f"),
+        (:GradientNorm, " |grad_f(p)|: %1.9f"),
+        (:Change, " |δp|: %1.9f"),
+        :Stop,
+        5,
+        "\n",
+    ],
+    stopping_criterion=StopAfterIteration(5000) | StopWhenGradientNormLess(1e-10),
+    sub_stopping_criterion=StopAfterIteration(100) | StopWhenGradientNormLess(1e-10),
+);
Initial f(p): 137.679053470
+# 5     f(p): -0.249956120 |grad_f(p)|: 0.046196628 |δp|: 0.201349127
+# 10    f(p): -0.249999999 |grad_f(p)|: 0.000187633 |δp|: 0.000626103
+# 15    f(p): -0.250000000 |grad_f(p)|: 0.000000772 |δp|: 0.000002574
+# 20    f(p): -0.250000000 |grad_f(p)|: 0.000000005 |δp|: 0.000000011
+The algorithm reached approximately critical point after 24 iterations; the gradient norm (7.619584706652929e-11) is less than 1.0e-10.
+  3.531235 seconds (8.71 M allocations: 628.709 MiB, 3.52% gc time, 67.16% compilation time)

The cost is

f(M, p_min_dca)
-0.25000000000000006

Similarly the DCPPA performs

@time p_min_dcppa = difference_of_convex_proximal_point(
+    M,
+    grad_h!,
+    p0;
+    g=g,
+    grad_g=grad_g!,
+    λ=i -> 1 / (2 * n),
+    cost=f,
+    gradient=grad_f!,
+    debug=[
+        :Iteration,
+        (:Cost, "f(p): %1.9f"),
+        " ",
+        (:GradientNorm, "|grad_f(p)|: %1.10f"),
+        (:Change, "|δp|: %1.10f"),
+        :Stop,
+        5,
+        "\n",
+    ],
+    evaluation=InplaceEvaluation(),
+    stepsize=ConstantStepsize(1.0),
+    stopping_criterion=StopAfterIteration(5000) | StopWhenGradientNormLess(1e-10),
+    sub_stopping_criterion=StopAfterIteration(100) | StopWhenGradientNormLess(1e-10),
+);
Initial f(p): 137.679053470 
+# 5     f(p): -0.248491803 |grad_f(p)|: 0.2793140152|δp|: 0.2753827692
+# 10    f(p): -0.249998655 |grad_f(p)|: 0.0080437374|δp|: 0.0050891316
+# 15    f(p): -0.249999999 |grad_f(p)|: 0.0002507329|δp|: 0.0001567676
+# 20    f(p): -0.250000000 |grad_f(p)|: 0.0000078348|δp|: 0.0000048968
+# 25    f(p): -0.250000000 |grad_f(p)|: 0.0000002448|δp|: 0.0000001530
+# 30    f(p): -0.250000000 |grad_f(p)|: 0.0000000076|δp|: 0.0000000048
+# 35    f(p): -0.250000000 |grad_f(p)|: 0.0000000002|δp|: 0.0000000001
+The algorithm reached approximately critical point after 37 iterations; the gradient norm (5.458071707233144e-11) is less than 1.0e-10.
+  1.341931 seconds (2.55 M allocations: 180.474 MiB, 2.46% gc time, 59.94% compilation time)

It needs a few more iterations, but the single iterations are slightly faster. Both obtain the same cost

f(M, p_min_dcppa)
-0.25

Benchmark I: Time comparison

We compare both solvers first with respect to time. We initialise two vectors to collect the results and a range of natrix sizes to test

dca_benchmarks = Dict{Int,BenchmarkTools.Trial}()
+dcppa_benchmarks = Dict{Int, BenchmarkTools.Trial}()
+N_max=14
+N = 2:N_max

and run a benchmark for both algorithms

for n in N
+    Mn = SymmetricPositiveDefinite(n)
+    pn = log(n) * Matrix{Float64}(I, n, n)
+    bdca = @benchmark difference_of_convex_algorithm(
+        $Mn,
+        $f,
+        $g,
+        $grad_h!,
+        $pn;
+        grad_g=$grad_g!,
+        gradient=$grad_f!,
+        evaluation=InplaceEvaluation(),
+        stopping_criterion=StopAfterIteration(5000) | StopWhenGradientNormLess(1e-10),
+        sub_stopping_criterion=StopAfterIteration(100) | StopWhenGradientNormLess(1e-10),
+    )
+    dca_benchmarks[n] = bdca
+    bdcppa = @benchmark difference_of_convex_proximal_point(
+        $Mn,
+        $grad_h!,
+        $pn;
+        g=$g,
+        grad_g=$grad_g!,
+        λ=i -> 1 / (2 * n),
+        cost=f,
+        gradient=grad_f!,
+        evaluation=InplaceEvaluation(),
+        stepsize=ConstantStepsize(1.0),
+        stopping_criterion=StopAfterIteration(5000) | StopWhenGradientNormLess(1e-10),
+        sub_stopping_criterion=StopAfterIteration(100) | StopWhenGradientNormLess(1e-10),
+    )
+    dcppa_benchmarks[n] = bdcppa
+end

Since we want to plot this versus the manifold dimension, we also create a vector for those and convert the times to seconds

dims = [manifold_dimension(SymmetricPositiveDefinite(n)) for n in N]
+dca_times = [mean(dca_benchmarks[n]).time / 1e9 for n in N]
+dcppa_times = [mean(dcppa_benchmarks[n]).time / 1e9 for n in N]
plot(; legend=:bottomright, xlabel="manifold dimension", ylabel="Time (sec.)")
+plot!(dims, dca_times; label="DCA", color=indigo, linewidth=2)
+plot!(dims, dcppa_times; label="DCPPA", color=teal, linewidth=2)

Benchmark II: Iterations and cost.

As a second benchmark, let’s collect the number of iterations needed and the development of the cost over dimensions.

N2 = [5,10,20,40,80]
+dims2 = [manifold_dimension(SymmetricPositiveDefinite(n)) for n in N2]
+dca_iterations = Dict{Int,Int}()
+dca_costs = Dict{Int,Vector{Float64}}()
+dcppa_iterations = Dict{Int,Int}()
+dcppa_costs = Dict{Int,Vector{Float64}}()
@time for n in N2
+    println(n)
+    Mn = SymmetricPositiveDefinite(n)
+    pn = log(n) * Matrix{Float64}(I,n,n);
+    @time dca_st = difference_of_convex_algorithm(
+        Mn, f, g, grad_h!, pn;
+        grad_g=grad_g!,
+        gradient=grad_f!,
+        evaluation = InplaceEvaluation(),
+        stopping_criterion = StopAfterIteration(5000) | StopWhenGradientNormLess(1e-10),
+        sub_stopping_criterion = StopAfterIteration(100) | StopWhenGradientNormLess(1e-10),
+        record = [:Iteration, :Cost],
+        return_state = true,
+    );
+    dca_costs[n] = get_record(dca_st, :Iteration, :Cost)
+    dca_iterations[n] = length(dca_costs[n])
+    @time dcppa_st = difference_of_convex_proximal_point(
+        Mn, grad_h!, pn;
+        g=g,
+        grad_g=grad_g!,
+        λ = i -> 1/(2*n),
+        cost = f,
+        gradient= grad_f!,
+        evaluation = InplaceEvaluation(),
+        stepsize = ConstantStepsize(1.0),
+        stopping_criterion = StopAfterIteration(5000) | StopWhenGradientNormLess(1e-10),
+        sub_stopping_criterion = StopAfterIteration(100) | StopWhenGradientNormLess(1e-10),
+        record = [:Iteration, :Cost],
+        return_state = true,
+    );
+    dcppa_costs[n] = get_record(dcppa_st, :Iteration, :Cost)
+    dcppa_iterations[n] = length(dcppa_costs[n])
+end

The iterations are like

plot(; legend=:bottomright, xlabel="manifold dimension", ylabel="Iterations")
+plot!(dims2, [values(dca_iterations)...]; label="DCA", color=indigo, linewidth=2)
+plot!(dims2, [values(dcppa_iterations)...]; label="DCPPA", color=teal, linewidth=2)

And for the developtment of the cost

where we can see that the DCA needs less iterations than the DCPPA.

Literature

[BFSS23]
R. Bergmann, O. P. Ferreira, E. M. Santos and J. C. Souza. The difference of convex algorithm on Hadamard manifolds. Preprint (2023), arXiv:2112.05250.
[SO15]
J. C. Souza and P. R. Oliveira. A proximal point algorithm for DC fuctions on Hadamard manifolds. Journal of Global Optimization 63, 797–810 (2015).
diff --git a/v0.1.8/examples/Difference-of-Convex-Benchmark_files/figure-commonmark/cell-18-output-1.svg b/v0.1.8/examples/Difference-of-Convex-Benchmark_files/figure-commonmark/cell-18-output-1.svg new file mode 100644 index 0000000..ca2e758 --- /dev/null +++ b/v0.1.8/examples/Difference-of-Convex-Benchmark_files/figure-commonmark/cell-18-output-1.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.1.8/examples/Difference-of-Convex-Benchmark_files/figure-commonmark/cell-21-output-1.svg b/v0.1.8/examples/Difference-of-Convex-Benchmark_files/figure-commonmark/cell-21-output-1.svg new file mode 100644 index 0000000..7baeb82 --- /dev/null +++ b/v0.1.8/examples/Difference-of-Convex-Benchmark_files/figure-commonmark/cell-21-output-1.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.1.8/examples/Difference-of-Convex-Benchmark_files/figure-commonmark/cell-22-output-1.svg b/v0.1.8/examples/Difference-of-Convex-Benchmark_files/figure-commonmark/cell-22-output-1.svg new file mode 100644 index 0000000..2131b9f --- /dev/null +++ b/v0.1.8/examples/Difference-of-Convex-Benchmark_files/figure-commonmark/cell-22-output-1.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.1.8/examples/Difference-of-Convex-Benchmark_files/figure-commonmark/cell-8-output-1.svg b/v0.1.8/examples/Difference-of-Convex-Benchmark_files/figure-commonmark/cell-8-output-1.svg new file mode 100644 index 0000000..d51a3c6 --- /dev/null +++ b/v0.1.8/examples/Difference-of-Convex-Benchmark_files/figure-commonmark/cell-8-output-1.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.1.8/examples/Difference-of-Convex-Benchmark_files/figure-commonmark/cell-9-output-1.svg b/v0.1.8/examples/Difference-of-Convex-Benchmark_files/figure-commonmark/cell-9-output-1.svg new file mode 100644 index 0000000..3c244f5 --- /dev/null +++ b/v0.1.8/examples/Difference-of-Convex-Benchmark_files/figure-commonmark/cell-9-output-1.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.1.8/examples/Difference-of-Convex-Frank-Wolfe/index.html b/v0.1.8/examples/Difference-of-Convex-Frank-Wolfe/index.html new file mode 100644 index 0000000..040d32b --- /dev/null +++ b/v0.1.8/examples/Difference-of-Convex-Frank-Wolfe/index.html @@ -0,0 +1,216 @@ + +Frank Wolfe comparison · ManoptExamples.jl

A comparison of the Difference of Convex and Frank Wolfe Algorithm

Ronny Bergmann 2023-11-06

Introduction

In this example we compare the Difference of Convex Algprithm (DCA) [BFSS23] with the Frank-Wolfe Algorithm, which was introduced in [WS22]. This example reproduces the results from [BFSS23], Section 7.3.

using LinearAlgebra, Random, Statistics, BenchmarkTools
+using ManifoldsBase, Manifolds, Manopt, ManoptExamples
+using NamedColors, Plots

and we load a few nice colors

paul_tol = load_paul_tol()
+indigo = paul_tol["mutedindigo"]
+teal = paul_tol["mutedteal"]

We consider the collowing constraint maximimization problem of the Fréchet mean on the symmetric positive definite matrices $\mathcal P(n)$ with the affine invariant metric. Let $q_1,\ldots,q_m \in \mathcal P(n)$ be a set of points and $\mu_1,\ldots,\mu_m$ be a set of weights, such that they sum to one. We consider then

\[\operatorname*{arg\,max}_{p\in\mathcal C}\ \ h(p)\]

with

\[h(p) = +\sum_{j=1}^m \mu_j d^2(p,q_i), +\quad \text{ where } +d^2(p,q_i) = \operatorname{tr}\bigl( + \log^2(p^{-\frac{1}{2}}q_jp^{-\frac{1}{2}}) +\big) +\qquad\text{and}\qquad +\mathcal C = \{ p\in {\mathcal M}\ |\ \bar L\preceq p \preceq \bar U \},\]

for a lower bound $L$ and an upper bound $U$ for the matrices in the positive definite sense $A \preceq B \Leftrightarrow (B-A)$ is positive semi-definite

When every one of the weights ${\mu}_1, \ldots {\mu}_m$ are equal, this function $h$ is known as the of the set $\{q_1, \dots, q_m\}$.

And for our example we set

Random.seed!(42)
+n = 20
+m = 100
+M = SymmetricPositiveDefinite(n)
+q = [rand(M) for _ in 1:m];
+w = rand(m)
+w ./=sum(w)

We use as lower and upper bound the arithmetic and geometric mean $L$ and $U$, respectively.

L = inv( sum( wi * inv(qi) for (wi, qi) in zip(w,q) ) )
+U = sum( wi * qi for (wi, qi) in zip(w,q) )

As a starting point, the Frank-Wolfe algorithm requires a feasible point. We use

p0 = (L+U)/2

And we can check that it is feasible

Common Functions

Given $p \in \mathcal M$, $X \in T_p\mathcal M$ on the symmetric positive definite matrices M, this method computes the closed form solution to

\[\operatorname*{arg\,min}_{q\in {\mathcal C}}\ \langle X, \log_p q\rangle + = \operatorname*{arg\,min}_{q\in {\mathcal C}}\ \operatorname{tr}(S\log(YqY))\]

where $\mathcal C = \{ q | L \preceq q \preceq U \}$, $S = p^{-1/2}Xp^{-1/2}$, and $Y=p^{-1/2}$.

The solution is given by $Z=X^{-1}Q\bigl( P^{\mathrm{T}}[-\operatorname{sgn}(D)]_{+}P+\hat{L}\bigr)Q^{\mathrm{T}}X^{-1}$,@ where $S=QDQ^{\mathrm{T}}$ is a diagonalization of $S$, $\hat{U}-\hat{L}=P^{\mathrm{T}}P$ with $\hat{L}=Q^{\mathrm{T}}XLXQ$ and $\hat{U}=Q^{\mathrm{T}}XUXQ$, where $[-\mbox{sgn}(D)]_{+}$ is the diagonal matrix

\[\operatorname{diag}\bigl( + [-\operatorname{sgn}(d_{11})]_{+}, \ldots, [-\operatorname{sgn}(d_{nn})]_{+} +\bigr)\]

and $D=(d_{ij})$.

@doc raw"""
+    closed_form_solution!(M, q, L, U, p X)
+
+Compute the closeed form solution of the constraint sub problem in place of ``q``.
+"""
+function closed_form_solution!(M::SymmetricPositiveDefinite, q, L, U, p, X)
+    # extract p^1/2 and p^{-1/2}
+    (p_sqrt_inv, p_sqrt) = Manifolds.spd_sqrt_and_sqrt_inv(p)
+    # Compute D & Q
+    e2 = eigen(p_sqrt_inv * X * p_sqrt_inv) # decompose Sk  = QDQ'
+    D = Diagonal(1.0 .* (e2.values .< 0))
+    Q = e2.vectors
+    #println(p)
+    Uprime = Q' * p_sqrt_inv * U * p_sqrt_inv * Q
+    Lprime = Q' * p_sqrt_inv * L * p_sqrt_inv * Q
+    P = cholesky(Hermitian(Uprime - Lprime))
+    z = P.U' * D * P.U + Lprime
+    copyto!(M, q, p_sqrt * Q * z * Q' * p_sqrt)
+    return q
+end

The Difference of Convex Formulation

We use $g(p) = \iota_{\mathcal C}(p)$ as the indicator funtion of the set $\mathcal C$. We use

function is_pos_def(p; atol=5e-13)
+    e = eigen(Symmetric(p))
+    return all((e.values .+ atol) .> 0)
+end
+function g(p, L, U)
+    return (is_pos_def(p-L) && is_pos_def(U-p)) ? 0.0 : Inf
+end
+h(M, p, w, q) = sum(wi * distance(M, p, qi)^2 for (wi, qi) in zip(w,q) )

So we can first check that p0 is feasible

g(p0,L,U) == 0.0
true

Now setting

\[\operatorname*{arg\,min}_{p\in\mathcal M}\ g(p) - h(p)\]

We look for a maximum of $h$, where $g$ is minimal, i.e. $g(p)$ is zero or in other words $p \in \mathcal C$.

The gradient of $h$ can also be implemented in closed form as

grad_h(M, p, w, q) = -2.0 * sum(wi * log(M, p, qi) for (wi, qi) in zip(w, q))
+function grad_h!(M, X, p, w, q)
+    Y = copy(M, p, X)
+    zero_vector!(M, X, p)
+    for (wi, qi) in zip(w,q)
+        log!(M, Y, p, qi)
+        Y .*= - 2.0*wi
+        X .+= Y
+    end
+    return X
+end

And we can further define the cost, which will just be $+\infty$ outside of $\mathcal C$. We define

f_dc(M, p) = g(p, L, U) - h(M, p, w, q)
+grad_h!(M, X, p) = grad_h!(M, X, p, w, q)
+function grad_f_dc!(M,X, p)
+    grad_h!(M, X, p, w, q)
+    X .*= -1.0
+    return X
+end

Here we can omit the gradient of $g$ in the definition of $\operatorname{grad} f$, since the gradient is zero at the points there it is defined, that is on any point that is not on the boundary of $\mathcal C$.

As the last step, we can provide the closed form solver for the DC sub problem given at iteration $k$ by

\[\operatorname*{arg\,min}_{p\in \mathcal C}\ + \big\langle -\operatorname{grad} h(p^{(k)}), \exp^{-1}_{p^{(k)}}p\big\rangle.\]

Which we con compute

function dc_sub_solution!(M, q, p, X)
+    closed_form_solution!(M, q, L, U, p, -X)
+    return q
+end

For safety, we might want to avoid ending up at the boundary of $\mathcal C$. That is we reduce the distance we walk towards the solution $q$ a bit.

function dc_sub_solution_safe!(M, q, p, X)
+    p_last = copy(M,p) # since p=q might be in place
+    closed_form_solution!(M, q, L, U, p, -X)
+    q_orig = copy(M,q) # since we do the following in place of q
+    a = minimum(real.(eigen(q-L).values))
+    b = minimum(real.(eigen(U-q).values))
+    s = 1.0
+    d = distance(M, p_last, q_orig);
+    # if we are close to zero, we reduce faster.
+    α = d < 1/(n^2) ? 0.66 : 0.9995;
+    i=0
+    while (a < 0) || (b < 0)
+        s *= α
+        shortest_geodesic!(M, q, p_last, q_orig, s)
+        a = minimum(real.(eigen(q-L).values))
+        b = minimum(real.(eigen(U-q).values))
+        #println("$i a: $a, b = $b with s=$s")
+        i=i+1
+        if (i>100) # safety fallback
+            #@warn " $i steps where not enough $s ($α)\n$a $b\n $(distance(M, p_last, q_orig)). Fixing by shifting EVs"
+            qe = eigen(q)
+            if a < 0
+                qe.values .+= min(1e-8, n*abs(min(a,b)))
+            else
+                qe.values .-= min(1e-8, n*abs(min(a,b)))
+            end
+            q .= qe.vectors * Diagonal(qe.values) * (qe.vectors)'
+            a = minimum(real.(eigen(q-L).values))
+            b = minimum(real.(eigen(U-q).values))
+            return q
+        end
+    end
+    return q
+end

The DoC solver run

Let’s compare both methods when they have the same stopping criteria

@time state1_dc = difference_of_convex_algorithm(M, f_dc, g, grad_h!, p0;
+    gradient=grad_f_dc!,
+    sub_problem=dc_sub_solution_safe!,
+    evaluation=InplaceEvaluation(),
+    stopping_criterion = StopAfterIteration(300) |
+        StopWhenChangeLess(1e-14) | StopWhenGradientChangeLess(M, 1e-9),
+    debug = [
+        (:Iteration, "# %-8d "), (:Cost, "F(p): %0.14f"), (:Change, " |Δp|: %0.14f "),
+        (:GradientNorm, " |grad f(p)|: %0.8f "),
+        (:GradientChange, " |Δgrad f(p)|: %0.8f"),
+        30, :Stop, "\n"],
+    record = [:Iteration, :Iterate, :Cost, RecordGradientNorm(), :Change],
+    return_state=true,
+)
Initial F(p): -0.77661458292831
+At iteration 23 the change of the gradient (3.192989916935325e-13) was less than 1.0e-9.
+ 16.161776 seconds (17.17 M allocations: 1.670 GiB, 1.83% gc time, 93.45% compilation time)
+
+# Solver state for `Manopt.jl`s Difference of Convex Algorithm
+After 23 iterations
+
+## Parameters
+* sub solver state:
+    | InplaceEvaluation()
+
+## Stopping criterion
+
+Stop When _one_ of the following are fulfilled:
+    Max Iteration 300:  not reached
+    |Δp| < 1.0e-14: not reached
+    |Δgrad f| < 1.0e-9: reached
+Overall: reached
+This indicates convergence: No
+
+## Debug
+    :Iteration = [(:Iteration, "# %-8d "), (:Cost, "F(p): %0.14f"), (:Change, " |Δp|: %0.14f "), (:GradientNorm, " |grad f(p)|: %0.8f "), (:GradientChange, " |Δgrad f(p)|: %0.8f"), "\n", 30]
+    :Stop = :Stop
+
+## Record
+(Iteration = RecordGroup([RecordIteration(), RecordIterate(Matrix{Float64}), RecordCost(), RecordGradientNorm(), RecordChange(; inverse_retraction_method=LogarithmicInverseRetraction())]),)

Let’s extract the final point and look at its cost

p1_dc = get_solver_result(state1_dc);
+f_dc(M, p1_dc)
-0.784425242474807

As well as whether (and how well) it is feasible, that is the following values should all be larger than zero.

[ extrema(eigen(p1_dc-L).values), extrema(eigen(U-p1_dc).values)]
2-element Vector{Tuple{Float64, Float64}}:
+ (1.1886583723800445e-12, 0.06669240322431051)
+ (1.3411042178831775e-5, 0.0671353506908023)

For the statistics we extract the recordings from the state

Define the Frank-Wolfe functions

For Frank wolfe, the cost is just defined as $-h(p)$ but the minimisation is constraint to $\mathcal C$, which is enfored by the oracle.

f_fw(M, p) = -h(M, p, w, q)
+function grad_f_fw!(M,X, p)
+    grad_h!(M, X, p, w, q)
+    X .*= -1.0
+    return X
+end
+oracle_fw!(M, q, p, X) = closed_form_solution!(M, q, L, U, p, X)

The FW Solver Run

Similarly we can run the Frank-Wolfe algorithm with

@time state1_fw = Frank_Wolfe_method(M, f_fw, grad_f_fw!, p0;
+    sub_problem=oracle_fw!,
+    evaluation=InplaceEvaluation(),
+    stopping_criterion = StopAfterIteration(10^4) |
+        StopWhenChangeLess(1e-14) | StopWhenGradientChangeLess(M, 1e-9),
+    debug = [
+        (:Iteration, "# %-8d "), :Cost, (:Change, " |Δp|: %0.14f "),
+        (:GradientNorm, " |grad f(p)|: %0.8f "),
+        (:GradientChange, " |Δgrad f(p)|: %0.8f"),
+        2*10^3, :Stop, "\n"],
+    record = [:Iteration, :Iterate, :Cost, RecordGradientNorm(), :Change],
+    return_state=true,
+)
Initial f(x): -0.776615
+# 2000     f(x): -0.784420 |Δp|: 0.04611942377596  |grad f(p)|: 0.17693408  |Δgrad f(p)|: 0.17555618
+# 4000     f(x): -0.784421 |Δp|: 0.00372201632005  |grad f(p)|: 0.17694619  |Δgrad f(p)|: 0.00749427
+# 6000     f(x): -0.784422 |Δp|: 0.00205683506784  |grad f(p)|: 0.17695204  |Δgrad f(p)|: 0.00414088
+# 8000     f(x): -0.784422 |Δp|: 0.00140675676260  |grad f(p)|: 0.17695565  |Δgrad f(p)|: 0.00283200
+# 10000    f(x): -0.784422 |Δp|: 0.00106177438611  |grad f(p)|: 0.17695815  |Δgrad f(p)|: 0.00213746
+The algorithm reached its maximal number of iterations (10000).
+152.781466 seconds (55.53 M allocations: 94.006 GiB, 2.12% gc time, 0.57% compilation time)
+
+# Solver state for `Manopt.jl`s Frank Wolfe Method
+After 10000 iterations
+
+## Parameters
+* inverse retraction method: LogarithmicInverseRetraction()
+* retraction method: ExponentialRetraction()
+* sub solver state:
+    | InplaceEvaluation()
+
+## Stepsize
+DecreasingStepsize(; length=2.0,  factor=1.0,  subtrahend=0.0,  shift=2)
+
+## Stopping criterion
+
+Stop When _one_ of the following are fulfilled:
+    Max Iteration 10000:    reached
+    |Δp| < 1.0e-14: not reached
+    |Δgrad f| < 1.0e-9: not reached
+Overall: reached
+This indicates convergence: No
+
+## Debug
+    :Iteration = [(:Iteration, "# %-8d "), (:Cost, "f(x): %f"), (:Change, " |Δp|: %0.14f "), (:GradientNorm, " |grad f(p)|: %0.8f "), (:GradientChange, " |Δgrad f(p)|: %0.8f"), "\n", 2000]
+    :Stop = :Stop
+
+## Record
+(Iteration = RecordGroup([RecordIteration(), RecordIterate(Matrix{Float64}), RecordCost(), RecordGradientNorm(), RecordChange(; inverse_retraction_method=LogarithmicInverseRetraction())]),)

And we take a look at this result as well

p1_fw = get_solver_result(state1_fw);
+f_dc(M, p1_fw)
-0.7844220281765162

And its feasibility

[extrema(eigen(p1_fw-L).values), extrema(eigen(U-p1_fw).values)]
2-element Vector{Tuple{Float64, Float64}}:
+ (4.904818928410655e-10, 0.06659173821656107)
+ (3.245654983213335e-5, 0.06713970236096602)

Statistics

We extract the recorded values

# DoC
+iter1_dc = get_record(state1_dc, :Iteration, :Iteration)
+pk_dc = get_record(state1_dc,:Iteration,:Iterate)
+costs1_dc = -h.(Ref(M), pk_dc, Ref(w), Ref(q))
+dc_min = minimum(costs1_dc)
+# FW
+iter1_fw = get_record(state1_fw,:Iteration,:Iteration)[1:5:end]
+pk_fw = get_record(state1_fw,:Iteration,:Iterate)[1:5:end]
+costs1_fw = -h.(Ref(M), pk_fw, Ref(w), Ref(q))

And let’s plot the result, where we measure the cost versus the minimum the difference of convex algorithm attains.

fig = plot(;
+    legend=:topright,
+    xlabel=raw"Iterations $k$ (log. scale)", ylabel=raw"Cost $f(x_k)-f^*$ (log. scale)",
+    yaxis=:log,
+    ylims=(1e-8, 10^-2),
+    xaxis=:log,
+    xlims=(1,10^4),
+)
+plot!(fig, iter1_dc, costs1_dc .- dc_min, color=indigo, label="Difference of Convex")
+plot!(fig, iter1_fw, costs1_fw .- dc_min, color=teal, label="Frank-Wolfe")

This indicates, that the difference off convex algorithm could even stop earlier with a proper stopping criterion, since after that the cost increases a bit again.

On the other hand, Frank-Wolfe still has not reached this level function value after 10^4 iterations.

Literature

[BFSS23]
R. Bergmann, O. P. Ferreira, E. M. Santos and J. C. Souza. The difference of convex algorithm on Hadamard manifolds. Preprint (2023), arXiv:2112.05250.
[WS22]
M. Weber and S. Sra. Riemannian Optimization via Frank-Wolfe Methods. Mathematical Programming 199, 525–556 (2022).
diff --git a/v0.1.8/examples/Difference-of-Convex-Frank-Wolfe_files/figure-commonmark/cell-23-output-1.svg b/v0.1.8/examples/Difference-of-Convex-Frank-Wolfe_files/figure-commonmark/cell-23-output-1.svg new file mode 100644 index 0000000..85998a9 --- /dev/null +++ b/v0.1.8/examples/Difference-of-Convex-Frank-Wolfe_files/figure-commonmark/cell-23-output-1.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.1.8/examples/Difference-of-Convex-Rosenbrock/index.html b/v0.1.8/examples/Difference-of-Convex-Rosenbrock/index.html new file mode 100644 index 0000000..8521de2 --- /dev/null +++ b/v0.1.8/examples/Difference-of-Convex-Rosenbrock/index.html @@ -0,0 +1,339 @@ + +Rosenbrock Metric · ManoptExamples.jl

Solving Rosenbrock with the Difference of Convex Algorithm

Ronny Bergmann 2023-06-06

Introduction

This example illustrates how the 📖 Rosenbrock problem can be rephrased as a difference of convex problem and with a new metric on Euclidean space. This example is the code that produces the results in [BFSS23], Section 7.2.

Both the Rosenbrock problem

\[ \operatorname*{argmin}_{x\in ℝ^2} a\bigl( x_1^2-x_2\bigr)^2 + \bigl(x_1-b\bigr)^2,\]

where $a,b>0$ and usually $b=1$ and $a \gg b$, we know the minimizer $x^* = (b,b^2)^\mathrm{T}$, and also the (Euclidean) gradient

\[\nabla f(x) = + \begin{pmatrix} + 4a(x_1^2-x_2)\\ -2a(x_1^2-x_2) + \end{pmatrix} + + + \begin{pmatrix} + 2(x_1-b)\\ 0 + \end{pmatrix}.\]

They are even available already here in ManifoldExamples.jl, see RosenbrockCost and RosenbrockGradient!!.

Furthermore, the RosenbrockMetric can be used on $ℝ^2$, that is

\[⟨X,Y⟩_{\mathrm{Rb},p} = X^\mathrm{T}G_pY, \qquad +G_p = \begin{pmatrix} + 1+4p_1^2 & -2p_1 \\ + -2p_1 & 1 +\end{pmatrix},\]

In this example we want to explore four different approaches to minimizing the Rosenbrock example, that are all based on first-order methods, i.e. using a gradient but not a Hessian.

  1. The Euclidean Gradient
  2. The Riemannian gradient descent with respect to the RosenbrockMetric
  3. The Euclidean Difference of Convex Algorithm
  4. The Riemannian Difference of Convex Algorithm respect to the RosenbrockMetric

Where we obtain a difference of convex problem by writing

\[f(x) = a\bigl( x_1^2-x_2\bigr)^2 + \bigl(x_1-b\bigr)^2 + = a\bigl( x_1^2-x_2\bigr)^2 + 2\bigl(x_1-b\bigr)^2 - \bigl(x_1-b\bigr)^2\]

that is

\[g(x) = a\bigl( x_1^2-x_2\bigr)^2 + 2\bigl(x_1-b\bigr)^2 \quad\text{ and }\quad h(x) = \bigl(x_1-b\bigr)^2\]

using LinearAlgebra, Random, Statistics
+using Manifolds, Manopt, ManoptExamples
+using NamedColors, Plots
+import Manopt: set_manopt_parameter!
+Random.seed!(42)
paul_tol = load_paul_tol()
+indigo = paul_tol["mutedindigo"]
+green = paul_tol["mutedgreen"]
+sand = paul_tol["mutedsand"]
+teal = paul_tol["mutedteal"]
+grey = paul_tol["mutedgrey"]

To emphasize the effect, we choose a quite large value of a.

a = 2*10^5
+b = 1

and use the starting point and a direction to check gradients

p0 = [0.1, 0.2]

The Euclidean Gradient Descent.

For the Euclidean gradient we can just use the same approach as in the Rosenbrock example

M = ℝ^2
+f = ManoptExamples.RosenbrockCost(M; a=a, b=b)
+∇f!! = ManoptExamples.RosenbrockGradient!!(M; a=a, b=b)

define a common debug vector

debug_vec = [
+        (:Iteration, "# %-8d "),
+        (:Cost, "F(x): %1.4e"),
+        " ",
+        (:Change, "|δp|: %1.4e | "),
+        (:GradientNorm, "|grad f|: %1.6e"),
+        :Stop,
+        "\n",
+    ]

and call the gradient descent algorithm

Eucl_GD_state = gradient_descent(M, f, ∇f!!, p0;
+    evaluation=InplaceEvaluation(),
+    debug=[debug_vec...,10^7],
+    stopping_criterion=StopAfterIteration(10^8) | StopWhenChangeLess(1e-16),
+    record=[:Iteration, :Cost],
+    return_state=true,
+)
Initial F(x): 7.2208e+03 
+# 10000000 F(x): 8.9937e-06 |δp|: 1.3835e+00 | |grad f|: 8.170355e-03
+# 20000000 F(x): 2.9474e-09 |δp|: 6.5764e-03 | |grad f|: 1.419191e-04
+# 30000000 F(x): 9.8376e-13 |δp|: 1.1918e-04 | |grad f|: 2.526295e-06
+# 40000000 F(x): 3.2830e-16 |δp|: 2.1773e-06 | |grad f|: 4.526313e-08
+# 50000000 F(x): 1.0154e-19 |δp|: 3.9803e-08 | |grad f|: 6.838240e-10
+The algorithm performed a step with a change (0.0) less than 1.0e-16.
+
+# Solver state for `Manopt.jl`s Gradient Descent
+After 53073227 iterations
+
+## Parameters
+* retraction method: ExponentialRetraction()
+
+## Stepsize
+ArmijoLinesearch() with keyword parameters
+  * initial_stepsize    = 1.0
+  * retraction_method   = ExponentialRetraction()
+  * contraction_factor  = 0.95
+  * sufficient_decrease = 0.1
+
+## Stopping criterion
+
+Stop When _one_ of the following are fulfilled:
+    Max Iteration 100000000:    not reached
+    |Δp| < 1.0e-16: reached
+Overall: reached
+This indicates convergence: Yes
+
+## Debug
+    :Iteration = [(:Iteration, "# %-8d "), (:Cost, "F(x): %1.4e"), " ", (:Change, "|δp|: %1.4e | "), (:GradientNorm, "|grad f|: %1.6e"), "\n", 10000000]
+    :Stop = :Stop
+
+## Record
+(Iteration = RecordGroup([RecordIteration(), RecordCost()]),)

The Riemannian Gradient Descent.

For the Riemannian case, we define

M_rb = MetricManifold(M, ManoptExamples.RosenbrockMetric())
MetricManifold(Euclidean(2; field=ℝ), ManoptExamples.RosenbrockMetric())

and the gradient is now adopted to the new metric

function grad_f!(M, X, p)
+    ∇f!!(M, X, p)
+    riemannian_gradient!(M, X, p, X)
+    return X
+end
+function grad_f(M, p)
+    X = zero_vector(M, p)
+    return grad_f!(M, X, p)
+end
R_GD_state = gradient_descent(M_rb, f, grad_f!, p0;
+    evaluation=InplaceEvaluation(),
+    debug=[debug_vec...,10^6],
+    stopping_criterion=StopAfterIteration(10^8) | StopWhenChangeLess(1e-16),
+    record=[:Iteration, :Cost],
+    return_state=true,
+)
Initial F(x): 7.2208e+03 
+# 1000000  F(x): 1.3571e-09 |δp|: 9.1006e-01 | |grad f|: 1.974939e-04
+# 2000000  F(x): 2.7921e-18 |δp|: 3.6836e-05 | |grad f|: 9.240792e-09
+The algorithm performed a step with a change (0.0) less than 1.0e-16.
+
+# Solver state for `Manopt.jl`s Gradient Descent
+After 2443750 iterations
+
+## Parameters
+* retraction method: ExponentialRetraction()
+
+## Stepsize
+ArmijoLinesearch() with keyword parameters
+  * initial_stepsize    = 1.0
+  * retraction_method   = ExponentialRetraction()
+  * contraction_factor  = 0.95
+  * sufficient_decrease = 0.1
+
+## Stopping criterion
+
+Stop When _one_ of the following are fulfilled:
+    Max Iteration 100000000:    not reached
+    |Δp| < 1.0e-16: reached
+Overall: reached
+This indicates convergence: Yes
+
+## Debug
+    :Iteration = [(:Iteration, "# %-8d "), (:Cost, "F(x): %1.4e"), " ", (:Change, "|δp|: %1.4e | "), (:GradientNorm, "|grad f|: %1.6e"), "\n", 1000000]
+    :Stop = :Stop
+
+## Record
+(Iteration = RecordGroup([RecordIteration(), RecordCost()]),)

The Euclidean Difference of Convex

For the convex case, we have to first introduce the two parts of the cost.

f1(M, p; a=100, b=1) = a * (p[1]^2 - p[2])^2;
+f2(M, p; a=100, b=1) = (p[1] - b[1])^2;
+g(M, p; a=100, b=1) = f1(M, p; a=a, b=b) + 2 * f2(M, p; a=a, b=b)
+h(M, p; a=100, b=1) = f2(M, p; a=a, b=b)

and their (Euclidan) gradients

function ∇h!(M, X, p; a=100, b=1)
+    X[1] = 2*(p[1]-b)
+    X[2] = 0
+    return X
+end
+function ∇h(M, p; a=100, b=1)
+    X = zero(p)
+    ∇h!(M, X, p; a=a, b=b)
+    return X
+end
+function ∇g!(M, X, p; a=100, b=1)
+    X[1] = 4*a*(p[1]^2-p[2])*p[1] + 2*2*(p[1]-b)
+    X[2] = -2*a*(p[1]^2-p[2])
+    return X
+end
+function ∇g(M, p; a=100, b=1)
+    X = zero(p)
+    ∇g!(M, X, p; a=a, b=b)
+    return X
+end

and we define for convenience

docE_g(M, p) = g(M, p; a=a, b=b)
+docE_f(M,p) = docE_g(M,p) - h(M, p; a=a, b=b)
+docE_∇h!(M, X, p) = ∇h!(M, X, p; a=a, b=b)
+docE_∇g!(M, X, p) = ∇g!(M, X, p; a=a, b=b)
+function docE_∇f!(M, X, p)
+  Y = zero_vector(M, p)
+  docE_∇g!(M, X, p)
+  docE_∇h!(M, Y, p)
+  X .-= Y
+  return X
+end

Then we call the difference of convex algorithm on Eucldiean space $ℝ^2$.

E_doc_state = difference_of_convex_algorithm(
+    M, docE_f, docE_g, docE_∇h!, p0;
+    gradient=docE_∇f!,
+    grad_g = docE_∇g!,
+    debug=[debug_vec..., 10^4],
+    evaluation=InplaceEvaluation(),
+    record=[:Iteration, :Cost],
+    stopping_criterion=StopAfterIteration(10^8) | StopWhenChangeLess(1e-16),
+    sub_hess=nothing, # Use gradient descent
+    sub_stopping_criterion=StopAfterIteration(2000) | StopWhenGradientNormLess(1e-16),
+    return_state=true,
+)
Initial F(x): 7.2208e+03 
+# 10000    F(x): 2.9705e-09 |δp|: 1.3270e+00 | |grad f|: 1.388203e-04
+# 20000    F(x): 3.3302e-16 |δp|: 1.2173e-04 | |grad f|: 4.541087e-08
+The algorithm performed a step with a change (0.0) less than 1.0e-16.
+
+# Solver state for `Manopt.jl`s Difference of Convex Algorithm
+After 26549 iterations
+
+## Parameters
+* sub solver state:
+    | # Solver state for `Manopt.jl`s Gradient Descent
+    | After 2000 iterations
+    | 
+    | ## Parameters
+    | * retraction method: ExponentialRetraction()
+    | 
+    | ## Stepsize
+    | ArmijoLinesearch() with keyword parameters
+    |   * initial_stepsize    = 1.0
+    |   * retraction_method   = ExponentialRetraction()
+    |   * contraction_factor  = 0.95
+    |   * sufficient_decrease = 0.1
+    | 
+    | ## Stopping criterion
+    | 
+    | Stop When _one_ of the following are fulfilled:
+    |     Max Iteration 2000:   reached
+    |     |grad f| < 1.0e-16: not reached
+    | Overall: reached
+    | This indicates convergence: No
+
+## Stopping criterion
+
+Stop When _one_ of the following are fulfilled:
+    Max Iteration 100000000:    not reached
+    |Δp| < 1.0e-16: reached
+Overall: reached
+This indicates convergence: Yes
+
+## Debug
+    :Iteration = [(:Iteration, "# %-8d "), (:Cost, "F(x): %1.4e"), " ", (:Change, "|δp|: %1.4e | "), (:GradientNorm, "|grad f|: %1.6e"), "\n", 10000]
+    :Stop = :Stop
+
+## Record
+(Iteration = RecordGroup([RecordIteration(), RecordCost()]),)

The Riemannian Difference of Convex

We first have to again defined the gradients with respect to the new metric

function grad_h!(M, X, p; a=100, b=1)
+    ∇h!(M, X, p; a=a, b=b)
+    riemannian_gradient!(M, X, p, X)
+    return X
+end
+function grad_h(M, p; a=100, b=1)
+    X = zero(p)
+    grad_h!(M, X, p; a=a, b=b)
+    return X
+end
+function grad_g!(M, X, p; a=100, b=1)
+    ∇g!(M, X, p; a=a,b=b)
+    riemannian_gradient!(M, X, p, X)
+    return X
+end
+function grad_g(M, p; a=100, b=1)
+    X = zero(p)
+    grad_g!(M, X, p; a=a, b=b)
+    return X
+end

While the cost of the subgradient can be infered automaticallty, we also have to provide the gradient of the sub problem. For $X \in ∂h(p^{(k)})$ the sunproblem top determine $p^{(k+1)}$ reads

\[\operatorname*{argmin}_{p\in\mathcal M} g(p) - \langle X, \log_{p^{(k)}}p\rangle\]

for which usually the cost and gradient functions are computed automatically in the difference of convex algorithm. However, in our case first the closed form solution for the adjoint differential of the logaithmic map is complicated to compute and second the gradint can even be given in a nicer form. We can first simplify in our case with $X = \operatorname{grad} h(p^{(k)})$ that

\[\phi(p) = g(p) - \langle X, \log_{p^{(k)}}p\rangle += a\bigl( p_{1}^2-p_{2}\bigr)^2 + + 2\bigl(p_{1}-b\bigr)^2 - 2(p^{(k)}_1-b)p_1 + 2(p^{(k)}_1-b)p^{(k)}_1,\]

its Euclidean gradient reads

\[\operatorname{grad}\phi(p) = + \nabla \varphi(p) + = \begin{pmatrix} + 4a p_1(p_1^2-p_2) + 4(p_1-b) - 2(p^{(k)}_1-b)\\ + -2a(p_1^2-p_2) + \end{pmatrix}\]

where we can again employ the gradient conversion from before to obtain the Riemannian gradient.

mutable struct SubGrad{P,T,V}
+    pk::P
+    Xk::T
+    a::V
+    b::V
+end
+function (ϕ::SubGrad)(M, p)
+    X = zero_vector(M, p)
+    ϕ(M, X, p)
+    return X
+end
+function (ϕ::SubGrad)(M, X, p)
+    X .= [
+        4 * ϕ.a * p[1] * (p[1]^2 - p[2]) + 4 * (p[1] - ϕ.b) - 2 * (ϕ.pk[1] - ϕ.b),
+        -2 * ϕ.a * (p[1]^2 - p[2]),
+    ]
+    riemannian_gradient!(M, X, p, X) # convert
+    return X
+end

And in orer to update the subsolvers gradient correctly, we have to overwrite

set_manopt_parameter!(ϕ::SubGrad, ::Val{:p}, p) = (ϕ.pk .= p)
+set_manopt_parameter!(ϕ::SubGrad, ::Val{:X}, X) = (ϕ.Xk .= X)

And we again introduce for ease of use

docR_g(M, p) = g(M, p; a=a, b=b)
+docR_f(M, p) = docR_g(M, p) - h(M, p; a=a, b=b)
+docR_grad_h!(M, X, p) = grad_h!(M, X, p; a=a, b=b)
+docR_grad_g!(M, X, p) = grad_g!(M, X, p; a=a, b=b)
+function docR_grad_f!(M, X, p)
+    Y = zero_vector(M, p)
+    docR_grad_g!(M, X, p)
+    docR_grad_h!(M, Y, p)
+    X .-= Y
+    return X
+end
+docR_sub_grad = SubGrad(copy(M, p0), zero_vector(M, p0), a, b)

Then we can finally call the last of our four algorithms to compare, the difference of convex algorithm with the Riemannian metric.

R_doc_state = difference_of_convex_algorithm(
+    M_rb, docR_f, docR_g, docR_grad_h!, p0;
+    gradient=docR_grad_f!,
+    grad_g = docR_grad_g!,
+    debug=[debug_vec..., 10^6],
+    evaluation=InplaceEvaluation(),
+    record=[:Iteration, :Cost],
+    stopping_criterion=StopAfterIteration(10^8) | StopWhenChangeLess(1e-16),
+    sub_grad=docR_sub_grad,
+    sub_hess = nothing, # Use gradient descent
+    sub_stopping_criterion=StopAfterIteration(2000) | StopWhenGradientNormLess(1e-16),
+    return_state=true,
+)
Initial F(x): 7.2208e+03 
+The algorithm performed a step with a change (0.0) less than 1.0e-16.
+
+# Solver state for `Manopt.jl`s Difference of Convex Algorithm
+After 1235 iterations
+
+## Parameters
+* sub solver state:
+    | # Solver state for `Manopt.jl`s Gradient Descent
+    | After 2000 iterations
+    | 
+    | ## Parameters
+    | * retraction method: ExponentialRetraction()
+    | 
+    | ## Stepsize
+    | ArmijoLinesearch() with keyword parameters
+    |   * initial_stepsize    = 1.0
+    |   * retraction_method   = ExponentialRetraction()
+    |   * contraction_factor  = 0.95
+    |   * sufficient_decrease = 0.1
+    | 
+    | ## Stopping criterion
+    | 
+    | Stop When _one_ of the following are fulfilled:
+    |     Max Iteration 2000:   reached
+    |     |grad f| < 1.0e-16: not reached
+    | Overall: reached
+    | This indicates convergence: No
+
+## Stopping criterion
+
+Stop When _one_ of the following are fulfilled:
+    Max Iteration 100000000:    not reached
+    |Δp| < 1.0e-16: reached
+Overall: reached
+This indicates convergence: Yes
+
+## Debug
+    :Iteration = [(:Iteration, "# %-8d "), (:Cost, "F(x): %1.4e"), " ", (:Change, "|δp|: %1.4e | "), (:GradientNorm, "|grad f|: %1.6e"), "\n", 1000000]
+    :Stop = :Stop
+
+## Record
+(Iteration = RecordGroup([RecordIteration(), RecordCost()]),)

Comparison in Iterations

fig = plot(;
+    legend=:topright,
+    xlabel=raw"Iterations $k$ (log. scale)", ylabel=raw"Cost $f(x)$ (log. scale)",
+    yaxis=:log,
+    ylims=(1e-16, 5*1e5),
+    xaxis=:log,
+    xlims=(1,10^8),
+)
+scatter!(fig, [1,], [f(M,p0),], label=raw"$f(p_0)$", markercolor=grey)
+egi = get_record(Eucl_GD_state, :Iteration, :Iteration)[1:10000:end] #5308 entries
+egc = get_record(Eucl_GD_state, :Iteration, :Cost)[1:10000:end] #5308 entries
+plot!(fig, egi, egc, color=teal, label="Euclidean GD")
+#
+rgi = get_record(R_GD_state, :Iteration, :Iteration)[1:1000:end] # 2444 entries
+rgc = get_record(R_GD_state, :Iteration, :Cost)[1:1000:end] # 2444 entries
+plot!(fig, rgi, rgc, color=indigo, label="Riemannian GD")
+#
+edi = get_record(E_doc_state, :Iteration, :Iteration) #26549 entries
+edc = get_record(E_doc_state, :Iteration, :Cost) #26549 entries
+plot!(fig, edi, edc, color=sand, label="Euclidean DoC")
+#
+rdi = get_record(R_doc_state, :Iteration, :Iteration) # 1235 entries
+rdc = get_record(R_doc_state, :Iteration, :Cost) # 1235 entries
+plot!(fig, rdi, rdc, color=green, label="Riemannian DoC")

And we can see that using difference of convex outperforms gradient descent, and using the Riemannian approach required less iterations than their Euclidean counterparts.

Literature

[BFSS23]
R. Bergmann, O. P. Ferreira, E. M. Santos and J. C. Souza. The difference of convex algorithm on Hadamard manifolds. Preprint (2023), arXiv:2112.05250.
diff --git a/v0.1.8/examples/Difference-of-Convex-Rosenbrock_files/figure-commonmark/cell-22-output-1.svg b/v0.1.8/examples/Difference-of-Convex-Rosenbrock_files/figure-commonmark/cell-22-output-1.svg new file mode 100644 index 0000000..9417ba6 --- /dev/null +++ b/v0.1.8/examples/Difference-of-Convex-Rosenbrock_files/figure-commonmark/cell-22-output-1.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.1.8/examples/HyperparameterOptimization/index.html b/v0.1.8/examples/HyperparameterOptimization/index.html new file mode 100644 index 0000000..e9677e6 --- /dev/null +++ b/v0.1.8/examples/HyperparameterOptimization/index.html @@ -0,0 +1,332 @@ + +Hyperparameter optimziation · ManoptExamples.jl

Hyperparameter optimization

Mateusz Baran 2024-08-03

Introduction

This example shows how to automatically select the best values of hyperparameters of optimization procedures such as retraction, vector transport, size of memory in L-BFGS or line search coefficients. Hyperparameter optimization relies on the Optuna [ASY+19] Python library because it is much more advanced than similar Julia projects, offering Bayesian optimization with conditional hyperparameters and early stopping.

General definitions

Here are some general definitions that you will most likely be able to directly use for your problem without any changes. Just remember to install optuna, for example using CondaPkg Julia library.

using Manifolds, Manopt
+using PythonCall
+using BenchmarkTools
+using LineSearches
+
+# This script requires optuna to be available through PythonCall
+# You can install it for example using
+# using CondaPkg
+# ]conda add optuna
+
+optuna = pyimport("optuna")
+
+norm_inf(M::AbstractManifold, p, X) = norm(X, Inf)
+
+# TTsuggest_ structs collect data from a calibrating optimization run
+# that is handled by compute_pruning_losses function
+
+struct TTsuggest_int
+    suggestions::Dict{String,Int}
+end
+function (s::TTsuggest_int)(name::String, a, b)
+    return s.suggestions[name]
+end
+struct TTsuggest_float
+    suggestions::Dict{String,Float64}
+end
+function (s::TTsuggest_float)(name::String, a, b; log::Bool=false)
+    return s.suggestions[name]
+end
+struct TTsuggest_categorical
+    suggestions::Dict{String,Any}
+end
+function (s::TTsuggest_categorical)(name::String, vals)
+    return s.suggestions[name]
+end
+struct TTreport
+    reported_vals::Vector{Float64}
+end
+function (r::TTreport)(val, i)
+    return push!(r.reported_vals, val)
+end
+struct TTshould_prune end
+(::TTshould_prune)() = Py(false)
+struct TracingTrial
+    suggest_int::TTsuggest_int
+    suggest_float::TTsuggest_float
+    suggest_categorical::TTsuggest_categorical
+    report::TTreport
+    should_prune::TTshould_prune
+end
+
+function compute_pruning_losses(
+    od,
+    int_suggestions::Dict{String,Int},
+    float_suggestions::Dict{String,Float64},
+    categorical_suggestions::Dict{String,Int},
+)
+    tt = TracingTrial(
+        TTsuggest_int(int_suggestions),
+        TTsuggest_float(float_suggestions),
+        TTsuggest_categorical(categorical_suggestions),
+        TTreport(Float64[]),
+        TTshould_prune(),
+    )
+    od(tt)
+    return tt.report.reported_vals
+end

The next part is your hyperparameter optimization objective. The ObjectiveData struct contains all relevant information about the sequence of specific problems. The outermost key part is the N_range field. Early stopping requires a series of progressively more complex problems. They will be attempted from the most simple one to the most complex one, and are specified by the values of N in that vector.

mutable struct ObjectiveData{TObj,TGrad}
+    obj::TObj
+    grad::TGrad
+    N_range::Vector{Int}
+    gtol::Float64
+    vts::Vector{AbstractVectorTransportMethod}
+    retrs::Vector{AbstractRetractionMethod}
+    manifold_constructors::Vector{Tuple{String,Any}}
+    pruning_losses::Vector{Float64}
+    manopt_stepsize::Vector{Tuple{String,Any}}
+    obj_loss_coeff::Float64
+end

In the example below we optimize hyperparameters on a sequence of Rosenbrock-type problems restricted to spheres:

\[\arg\min_{p \in S^{N-1}} \sum_{i=1}^{N/2} (1-p_{2i})^2 + 100 (p_{2i+1} - p_{2i}^2)^2,\]

where $N \in [2, 16, 128, 1024, 8192, 65536]$.

obj and grad are the objective and gradient, here defined as below. Note that gradient works in-place and variants without manifolds are also provided for easier comparison with other libraries like Optim.jl. It is easiest when problems for different values N can be distinguished by being defined on successively larger manifolds but the script could be modified so that it’s not necessary.

pruning_losses and compute_pruning_losses are related to early pruning used in Optuna and you shouldn’t have to modify them.

function f_rosenbrock(x)
+    result = 0.0
+    for i in 1:2:length(x)
+        result += (1.0 - x[i])^2 + 100.0 * (x[i + 1] - x[i]^2)^2
+    end
+    return result
+end
+function f_rosenbrock(::AbstractManifold, x)
+    return f_rosenbrock(x)
+end
+
+function g_rosenbrock!(storage, x)
+    for i in 1:2:length(x)
+        storage[i] = -2.0 * (1.0 - x[i]) - 400.0 * (x[i + 1] - x[i]^2) * x[i]
+        storage[i + 1] = 200.0 * (x[i + 1] - x[i]^2)
+    end
+    return storage
+end
+function g_rosenbrock!(M::AbstractManifold, storage, x)
+    g_rosenbrock!(storage, x)
+    riemannian_gradient!(M, storage, x, storage)
+    return storage
+end

Next, gtol is the tolerance used for the stopping criterion in optimization. vts and retrs are, respectively, vector transports and retraction methods selected through hyperparameter optimization. Some items need to be different for different values of N, for example the manifold over which the problem is defined. This is handled by manifold_constructors which is then defined as Tuple{String,Any}[("Sphere", N -> Manifolds.Sphere(N - 1))], where the string "Sphere" is used to identify the manifold family and the next element is a function that transforms the value of N to the manifold for the problem of size N.

Similarly, different stepsize selection methods may be considered. This is handled by the field manopt_stepsize. It will be easiest to see how it works by looking at how it is initialized:

Tuple{String,Any}[
+    ("LS-HZ", M -> Manopt.LineSearchesStepsize(ls_hz)),
+    ("Wolfe-Powell", (M, c1, c2) -> Manopt.WolfePowellLinesearch(M, c1, c2)),
+]

We have a string that identifies the line search method name and a constructor of the line search which takes relevant arguments like the manifold or a numerical parameter.

The next part is the trial evaluation procedure. This is one of the more important places which need to be customized to your problem. This is the point where we tell Optuna about the relevant optimization hyperparameters and use them to define specific problems. The hyperparameter optimization is a multiobjective problem: we want as good problem objectives as possible and as low times as possible. As Optuna doesn’t currently support multicriteria pruning, which is important for obtaining a solution in a reasonable amount of time, we use a linear combination of sub-objectives to turn the problem into a single-criterion optimization. The hyperparameter optimization objective is a linear combination of achieved objectives the relative weight is controlled by objective.obj_loss_coeff.

function (objective::ObjectiveData)(trial)
+    # Here we use optuna to select memory length for L-BFGS -- an integer in the range between 2 and 30, referenced by name "mem_len"
+    mem_len = trial.suggest_int("mem_len", 2, 30)
+
+    # Here we select a vector transport and retraction methods, one of those specified in the `ObjectiveData`.
+    vt = objective.vts[pyconvert(
+        Int,
+        trial.suggest_categorical(
+            "vector_transport_method", Vector(eachindex(objective.vts))
+        ),
+    )]
+    retr = objective.retrs[pyconvert(
+        Int,
+        trial.suggest_categorical("retraction_method", Vector(eachindex(objective.retrs))),
+    )]
+
+    # Here we select the manifold constructor, in case we want to try different manifolds for our problem. For example one could try defining a problem with orthogonality constraints on Stiefel, Grassmann or flag manifold.
+    manifold_name, manifold_constructor = objective.manifold_constructors[pyconvert(
+        Int,
+        trial.suggest_categorical(
+            "manifold", Vector(eachindex(objective.manifold_constructors))
+        ),
+    )]
+
+    # Here the stepsize selection method type is selected.
+    manopt_stepsize_name, manopt_stepsize_constructor = objective.manopt_stepsize[pyconvert(
+        Int,
+        trial.suggest_categorical(
+            "manopt_stepsize", Vector(eachindex(objective.manopt_stepsize))
+        ),
+    )]
+
+    # This parametrizes stepsize selection methods with relevant numerical parameters.
+    local c1_val, c2_val, hz_sigma
+    if manopt_stepsize_name == "Wolfe-Powell"
+        c1_val = pyconvert(
+            Float64, trial.suggest_float("Wolfe-Powell c1", 1e-5, 1e-2; log=true)
+        )
+        c2_val =
+            1.0 - pyconvert(
+                Float64, trial.suggest_float("Wolfe-Powell 1-c2", 1e-4, 1e-2; log=true)
+            )
+    elseif manopt_stepsize_name == "Improved HZ"
+        hz_sigma = pyconvert(Float64, trial.suggest_float("Improved HZ sigma", 0.1, 0.9))
+    end
+
+    # The current loss estimate, taking into account estimated loss values for larger, not-yet-evaluated values of `N`.
+    loss = sum(objective.pruning_losses)
+
+    # Here iterate over problems we want to optimize for
+    # from smallest to largest; pruning should stop the iteration early
+    # if the hyperparameter set is not promising
+    cur_i = 0
+    for N in objective.N_range
+        # Here we define the initial point for the optimization procedure
+        p0 = zeros(N)
+        p0[1] = 1
+        M = manifold_constructor(N)
+        # Here we construct the specific line search to be used
+        local ls
+        if manopt_stepsize_name == "Wolfe-Powell"
+            ls = manopt_stepsize_constructor(M, c1_val, c2_val)
+        elseif manopt_stepsize_name == "Improved HZ"
+            ls = manopt_stepsize_constructor(M, hz_sigma)
+        else
+            ls = manopt_stepsize_constructor(M)
+        end
+        manopt_time, manopt_iters, manopt_obj = benchmark_time_state(
+            ManoptQN(),
+            M,
+            N,
+            objective.obj,
+            objective.grad,
+            p0,
+            ls,
+            pyconvert(Int, mem_len),
+            objective.gtol;
+            vector_transport_method=vt,
+            retraction_method=retr,
+        )
+        # TODO: turn this into multi-criteria optimization when Optuna starts supporting
+        # pruning in such problems
+        loss -= objective.pruning_losses[cur_i + 1]
+        loss += manopt_time + objective.obj_loss_coeff * manopt_obj
+        trial.report(loss, cur_i)
+        if pyconvert(Bool, trial.should_prune().__bool__())
+            throw(PyException(optuna.TrialPruned()))
+        end
+        cur_i += 1
+    end
+    return loss
+end

In the following benchmarking code you will most likely have to adapt solver parameters. This is designed around quasi_Newton but can be adapted to any solver as needed. The example below performs a small number of trials for quick rendering but in practice you should aim for at least a few thousand trials (the n_trials parameter).

# An abstract type in case we want to try different optimization packages.
+abstract type AbstractOptimConfig end
+struct ManoptQN <: AbstractOptimConfig end
+
+# Benchmark that evaluates hyperparameters. Returns time to reach the solution, number of iterations and final value of the objective.
+function benchmark_time_state(
+    ::ManoptQN,
+    M::AbstractManifold,
+    N,
+    f,
+    g!,
+    p0,
+    stepsize::Manopt.Stepsize,
+    mem_len::Int,
+    gtol::Real;
+    kwargs...,
+)
+    manopt_sc = StopWhenGradientNormLess(gtol; norm=norm_inf) | StopAfterIteration(1000)
+    mem_len = min(mem_len, manifold_dimension(M))
+    manopt_state = quasi_Newton(
+        M,
+        f,
+        g!,
+        p0;
+        stepsize=stepsize,
+        evaluation=InplaceEvaluation(),
+        return_state=true,
+        memory_size=mem_len,
+        stopping_criterion=manopt_sc,
+        debug=[],
+        kwargs...,
+    )
+    bench_manopt = @benchmark quasi_Newton(
+        $M,
+        $f,
+        $g!,
+        $p0;
+        stepsize=$(stepsize),
+        evaluation=$(InplaceEvaluation()),
+        memory_size=$mem_len,
+        stopping_criterion=$(manopt_sc),
+        debug=[],
+        $kwargs...,
+    )
+    iters = get_count(manopt_state, :Iterations)
+    final_val = f(M, manopt_state.p)
+    return median(bench_manopt.times) / 1000, iters, final_val
+end
+
+"""
+    lbfgs_study(; pruning_coeff::Float64=0.95)
+
+Set up the example hyperparameter optimization study.
+"""
+function lbfgs_study(; pruning_coeff::Float64=0.95)
+    Ns = [2^n for n in 1:3:12]
+    ls_hz = LineSearches.HagerZhang()
+    od = ObjectiveData(
+        f_rosenbrock,
+        g_rosenbrock!,
+        Ns,
+        1e-5,
+        AbstractVectorTransportMethod[ParallelTransport(), ProjectionTransport()],
+        [ExponentialRetraction(), ProjectionRetraction()],
+        Tuple{String,Any}[("Sphere", N -> Manifolds.Sphere(N - 1))],
+        zeros(Float64, eachindex(Ns)),
+        Tuple{String,Any}[
+            ("LS-HZ", M -> Manopt.LineSearchesStepsize(ls_hz)),
+            #("Improved HZ", (M, sigma) -> HagerZhangLinesearch(M; sigma=sigma)),
+            ("Wolfe-Powell", (M, c1, c2) -> Manopt.WolfePowellLinesearch(M, c1, c2)),
+        ],
+        10.0,
+    )
+
+    # Here you need to define baseline values of all hyperparameters
+    baseline_pruning_losses = compute_pruning_losses(
+        od,
+        Dict("mem_len" => 4),
+        Dict(
+            "Wolfe-Powell c1" => 1e-4,
+            "Wolfe-Powell 1-c2" => 1e-3,
+            "Improved HZ sigma" => 0.9,
+        ),
+        Dict(
+            "vector_transport_method" => 1,
+            "retraction_method" => 1,
+            "manifold" => 1,
+            "manopt_stepsize" => 1,
+        ),
+    )
+    od.pruning_losses = pruning_coeff * baseline_pruning_losses
+
+    study = optuna.create_study(; study_name="L-BFGS")
+    # Here you can specify number of trials and timeout (in seconds).
+    study.optimize(od; n_trials=1000, timeout=500)
+    println("Best params is $(study.best_params) with value $(study.best_value)")
+    selected_manifold = od.manifold_constructors[pyconvert(Int, study.best_params["manifold"])][1]
+    selected_retraction_method = od.retrs[pyconvert(Int, study.best_params["retraction_method"])]
+    selected_vector_transport = od.vts[pyconvert(Int, study.best_params["vector_transport_method"])]
+    println("Selected manifold: $(selected_manifold)")
+    println("Selected retraction method: $(selected_retraction_method)")
+    println("Selected vector transport method: $(selected_vector_transport)")
+    return study
+end
+
+lbfgs_study()
Best params is {'mem_len': 3, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.0006125542888545935, 'Wolfe-Powell 1-c2': 0.0010744467792321093} with value 5510.963227438757
+Selected manifold: Sphere
+Selected retraction method: ExponentialRetraction()
+Selected vector transport method: ProjectionTransport()
+
+[I 2024-03-16 18:04:17,965] A new study created in memory with name: L-BFGS
+[I 2024-03-16 18:04:45,996] Trial 0 finished with value: 5639.789870295856 and parameters: {'mem_len': 26, 'vector_transport_method': 1, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.00027288064367948073, 'Wolfe-Powell 1-c2': 0.00026503788892114045}. Best is trial 0 with value: 5639.789870295856.
+[I 2024-03-16 18:05:11,860] Trial 1 finished with value: 5635.936370295855 and parameters: {'mem_len': 11, 'vector_transport_method': 1, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.002743250060163298, 'Wolfe-Powell 1-c2': 0.00037986521186922096}. Best is trial 1 with value: 5635.936370295855.
+[I 2024-03-16 18:05:39,386] Trial 2 finished with value: 5673.101441724422 and parameters: {'mem_len': 26, 'vector_transport_method': 2, 'retraction_method': 2, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.00043339485784312605, 'Wolfe-Powell 1-c2': 0.0027302649933974173}. Best is trial 1 with value: 5635.936370295855.
+[I 2024-03-16 18:06:10,279] Trial 3 finished with value: 7410.818084581564 and parameters: {'mem_len': 26, 'vector_transport_method': 1, 'retraction_method': 2, 'manifold': 1, 'manopt_stepsize': 1}. Best is trial 1 with value: 5635.936370295855.
+[I 2024-03-16 18:06:37,995] Trial 4 finished with value: 5756.566226449636 and parameters: {'mem_len': 25, 'vector_transport_method': 1, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 1}. Best is trial 1 with value: 5635.936370295855.
+[I 2024-03-16 18:06:42,755] Trial 5 pruned. 
+[I 2024-03-16 18:06:58,577] Trial 6 pruned. 
+[I 2024-03-16 18:07:15,366] Trial 7 pruned. 
+[I 2024-03-16 18:07:40,605] Trial 8 finished with value: 5581.7437274386975 and parameters: {'mem_len': 7, 'vector_transport_method': 1, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.0010567355712112379, 'Wolfe-Powell 1-c2': 0.003948002490203636}. Best is trial 8 with value: 5581.7437274386975.
+[I 2024-03-16 18:07:46,021] Trial 9 pruned. 
+[I 2024-03-16 18:08:11,512] Trial 10 finished with value: 5510.963227438757 and parameters: {'mem_len': 3, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.0006125542888545935, 'Wolfe-Powell 1-c2': 0.0010744467792321093}. Best is trial 10 with value: 5510.963227438757.
+[I 2024-03-16 18:08:35,914] Trial 11 finished with value: 5521.388656010121 and parameters: {'mem_len': 2, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.0006738829952322474, 'Wolfe-Powell 1-c2': 0.0010639659137420014}. Best is trial 10 with value: 5510.963227438757.
+[I 2024-03-16 18:09:00,317] Trial 12 finished with value: 5521.36958458155 and parameters: {'mem_len': 2, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.00010975606104676191, 'Wolfe-Powell 1-c2': 0.0007663843095951679}. Best is trial 10 with value: 5510.963227438757.
+[I 2024-03-16 18:09:24,680] Trial 13 finished with value: 5520.7020845815505 and parameters: {'mem_len': 2, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 6.743450835567536e-05, 'Wolfe-Powell 1-c2': 0.0008779759729737719}. Best is trial 10 with value: 5510.963227438757.
+[I 2024-03-16 18:09:50,268] Trial 14 pruned. 
+[I 2024-03-16 18:10:15,494] Trial 15 finished with value: 5595.119584581556 and parameters: {'mem_len': 6, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 8.147444451747575e-05, 'Wolfe-Powell 1-c2': 0.00012268601197923553}. Best is trial 10 with value: 5510.963227438757.
+[I 2024-03-16 18:10:25,264] Trial 16 pruned. 
+[I 2024-03-16 18:10:50,209] Trial 17 finished with value: 5572.474513153012 and parameters: {'mem_len': 5, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.0015998473664092935, 'Wolfe-Powell 1-c2': 0.0005109172020536229}. Best is trial 10 with value: 5510.963227438757.
+[I 2024-03-16 18:10:54,772] Trial 18 pruned. 
+[I 2024-03-16 18:11:04,534] Trial 19 pruned. 
+[I 2024-03-16 18:11:28,873] Trial 20 finished with value: 5512.3824417244705 and parameters: {'mem_len': 3, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 1.1581668103921961e-05, 'Wolfe-Powell 1-c2': 0.0002691056199427656}. Best is trial 10 with value: 5510.963227438757.
+[I 2024-03-16 18:11:53,327] Trial 21 finished with value: 5529.088227438692 and parameters: {'mem_len': 4, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 1.3645031886009879e-05, 'Wolfe-Powell 1-c2': 0.0001863385753491203}. Best is trial 10 with value: 5510.963227438757.
+[I 2024-03-16 18:12:17,911] Trial 22 finished with value: 5522.041370295835 and parameters: {'mem_len': 2, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 1.0030173525937465e-05, 'Wolfe-Powell 1-c2': 0.000543991948003312}. Best is trial 10 with value: 5510.963227438757.
+[I 2024-03-16 18:12:27,645] Trial 23 pruned. 
+[I 2024-03-16 18:12:52,163] Trial 24 finished with value: 5528.840941724406 and parameters: {'mem_len': 4, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.000245400433292576, 'Wolfe-Powell 1-c2': 0.000133639324295565}. Best is trial 10 with value: 5510.963227438757.
+
+Python: <optuna.study.study.Study object at 0x70dd985d9b50>

Summary

We’ve shown how to automatically select the best hyperparameter values for your optimization problem.

Literature

[ASY+19]
T. Akiba, S. Sano, T. Yanase, T. Ohta and M. Koyama. Optuna: A Next-generation Hyperparameter Optimization Framework. In: Proceedings of the 25th ACM SIGKDD International Conference on Knowledge Discovery and Data Mining (2019), arXiv:1907.10902.
diff --git a/v0.1.8/examples/RayleighQuotient/index.html b/v0.1.8/examples/RayleighQuotient/index.html new file mode 100644 index 0000000..f38f018 --- /dev/null +++ b/v0.1.8/examples/RayleighQuotient/index.html @@ -0,0 +1,235 @@ + +The Rayleigh Quotient · ManoptExamples.jl

The Rayleigh Quotient

Ronny Bergmann 2024-03-09

Introduction

This example reproduces a few conceptual ideas of Optimization on Manifolds that are used throughout [Bou23] using the Rayleigh quotient and explores several different ways to use the algorithms from Manopt.jl.

For a symmetric matrix $A \in \mathbb R^{n\times n}$ we consider the 📖 Rayleigh Quotient

\[\operatorname*{arg\,min}_{x \in \mathbb R^n \backslash \{0\}} +\frac{x^{\mathrm{T}}Ax}{\lVert x \rVert^2}.\]

On the sphere we can omit the denominator and obtain

\[f(p) = p^{\mathrm{T}}Ap,\qquad p ∈ 𝕊^{n-1},\]

which by itself we can again continue in the embedding as

\[\tilde f(x) = x^{\mathrm{T}}Ax,\qquad x \in \mathbb R^n.\]

This cost has the nice feature that at the minimizer $p^*\in\mathbb S^{n-1}$ the function falue $f(p^*)$ is the smalles eigenvalue of $A$.

For the embedded function $\tilde f$ the gradient and Hessian can be computed with classical methods as

\[\begin{align*} +∇\tilde f(x) &= 2Ax, \qquad x ∈ ℝ^n, +\\ +∇^2\tilde f(x)[V] &= 2AV, \qquad x, V ∈ ℝ^n. +\end{align*}\]

Similarly, cf. Examples 3.62 and 5.27 of [Bou23], the Riemannian gradient and Hessian on the manifold $\mathcal M = \mathbb S^{n-1}$ are given by

\[\begin{align*} +\operatorname{grad} f(p) &= 2Ap - 2(p^{\mathrm{T}}Ap)*p,\qquad p ∈ 𝕊^{n-1}, +\\ +\operatorname{Hess} f(p)[X] &= 2AX - 2(p^{\mathrm{T}}AX)p - 2(p^{\mathrm{T}}Ap)X,\qquad p ∈ 𝕊^{n-1}, X \in T_p𝕊^{n-1} +\end{align*}\]

Let’s first generate an example martrx $A$.

using Pkg;
+cd(@__DIR__)
+Pkg.activate("."); # use the example environment,
using LRUCache, BenchmarkTools, LinearAlgebra, Manifolds, ManoptExamples, Manopt, Random
+Random.seed!(42)
+n = 500
+A = Symmetric(randn(n, n) / n)

And the manifolds

M = Sphere(n-1)
Sphere(499, ℝ)
E = get_embedding(M)
Euclidean(500; field=ℝ)

Setup the corresponding functions

Since RayleighQuotientCost, RayleighQuotientGrad!!, and RayleighQuotientHess!! are themselves manifold agnostic we only need to initialize them once. Agnostic here means that they would compute $f$ is called with M as their first argument and $\tilde f$ if called with E.

We instantiate

f = ManoptExamples.RayleighQuotientCost(A)
+grad_f = ManoptExamples.RayleighQuotientGrad!!(A)
+Hess_f = ManoptExamples.RayleighQuotientHess!!(A)

the suffix !! also indicates that these functions both work as allocating and in-place variants. Given a starting point and some memory

p0 = [1.0, zeros(n-1)...]
+X = zero_vector(M, p0)

we can both call

Y = grad_f(M, p0)  # Allocates memory
+grad_f(M, X, p0)    # Computes in place of X and returns the result in X.
+norm(M, p0, X-Y)
0.0

Now we can use a few different variants of solvers to approaach this and this tutorial will walk you through a few of them.

First of all let’s construct the actual result – since Rayleigh quotient minimization is not necessarily the best way to compute the smallest Eigenvalue. We can also compute

λ = min(eigvals(A)...)
-0.08967721009388108

A Solver based on gradient information

Let’s first just use first-order information and since we are just starting, maybe we only derived the Euclidean gradient $\nabla \tilde f$. We can “tell” the solver, that the provided function and the gradient are defined as the Euclidean variants in the embedding. internally, Manopt.jl then issues the conversion for Euclidean gradients to the corresponding Riemannian one, cf. e.g. this tutorial section or Section 3.8 or more precisely Example 3.62 in [Bou23].

But instead of diving into all the tecnical details, we can just specify objective_type=:Euclidean to trigger the conversion. We start with a simple gradient descent

s = gradient_descent(M, f, grad_f, p0; objective_type=:Euclidean,
+    debug = [:Iteration, :Cost, :GradientNorm, 50, "\n"],
+    return_state=true,
+)
+q1 = get_solver_result(s)
+s
Initial f(x): -0.000727
+# 50    f(x): -0.088415|grad f(p)|:0.004530500043902619
+# 100   f(x): -0.089097|grad f(p)|:0.004589417101266096
+# 150   f(x): -0.089530|grad f(p)|:0.0026028331895358247
+# 200   f(x): -0.089650|grad f(p)|:0.0012359084298719039
+
+# Solver state for `Manopt.jl`s Gradient Descent
+After 200 iterations
+
+## Parameters
+* retraction method: ExponentialRetraction()
+
+## Stepsize
+ArmijoLinesearch() with keyword parameters
+  * initial_stepsize    = 1.0
+  * retraction_method   = ExponentialRetraction()
+  * contraction_factor  = 0.95
+  * sufficient_decrease = 0.1
+
+## Stopping criterion
+
+Stop When _one_ of the following are fulfilled:
+    Max Iteration 200:  reached
+    |grad f| < 1.0e-8: not reached
+Overall: reached
+This indicates convergence: No
+
+## Debug
+    :Iteration = [(:Iteration, "# %-6d"), (:Cost, "f(x): %f"), (:GradientNorm, "|grad f(p)|:%s"), "\n", 50]

From the final cost we can already see that q1 is an eigenvector to the smallest eigenvalue we obtaines above.

And we can compare this to running with the Riemannian gradient, since the RayleighQuotientGrad!! returns this one as well, when just called with the sphere as first Argument, we just have to remove the objective_type.

q2 = gradient_descent(M, f, grad_f, p0;
+    debug = [:Iteration, :Cost, :GradientNorm, 50, "\n"],
+)
+#Test that both are the same
+isapprox(M, q1,q2)
Initial f(x): -0.000727
+# 50    f(x): -0.088415|grad f(p)|:0.004530500043902567
+# 100   f(x): -0.089097|grad f(p)|:0.004589417101266063
+# 150   f(x): -0.089530|grad f(p)|:0.002602833189535808
+# 200   f(x): -0.089650|grad f(p)|:0.0012359084298719097
+
+true

We can also benchmark both

@benchmark gradient_descent($M, $f, $grad_f, $p0; objective_type=:Euclidean)
BenchmarkTools.Trial: 23 samples with 1 evaluation.
+ Range (min … max):  217.668 ms … 268.332 ms  ┊ GC (min … max): 3.21% … 3.98%
+ Time  (median):     219.032 ms               ┊ GC (median):    3.24%
+ Time  (mean ± σ):   222.029 ms ±  10.351 ms  ┊ GC (mean ± σ):  3.33% ± 0.26%
+
+   █                                                             
+  ▆█▆▃▁▃▁▃▁▅▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▃ ▁
+  218 ms           Histogram: frequency by time          268 ms <
+
+ Memory estimate: 1.13 GiB, allocs estimate: 3613.
@benchmark gradient_descent($M, $f, $grad_f, $p0)
BenchmarkTools.Trial: 149 samples with 1 evaluation.
+ Range (min … max):  31.006 ms … 163.769 ms  ┊ GC (min … max): 0.00% … 79.63%
+ Time  (median):     31.330 ms               ┊ GC (median):    0.00%
+ Time  (mean ± σ):   33.701 ms ±  11.067 ms  ┊ GC (mean ± σ):  3.40% ±  7.06%
+
+  █▃ ▂ ▁              ▃                                         
+  ██▄█▇██▆▄▁▄▄▁▇▁▁▆▁▄▆█▇▁▁▄▁▄▄▁▁▁▁▁▁▁▁▁▄▁▁▁▄▁▁▁▁▁▁▄▁▁▁▁▁▁▁▁▁▁▄ ▄
+  31 ms         Histogram: log(frequency) by time        47 ms <
+
+ Memory estimate: 11.38 MiB, allocs estimate: 3006.

From these results we see, that the conversion from the Euclidean to the Riemannian gradient does require a small amount of effort and hence reduces the performance slighly. Still, if the Euclidean Gradient is easier to compute or already available, this is in terms of coding the faster way. Finally this is a tradeoff between derivation and implementation efforts for the Riemannian gradient and a slight performance reduction when using the Euclidean one.

A Solver based (also) on (approximate) Hessian information

To also involve the Hessian, we consider the trust regions solver with three cases:

  1. Euclidean, approximating the Hessian
  2. Euclidean, providing the Hessian
  3. Riemannian, providing the Hessian but also using in-place evaluations.
q3 = trust_regions(M, f, grad_f, p0; objective_type=:Euclidean,
+    debug = [:Iteration, :Cost, :GradientNorm, 10, "\n"],
+);
Initial f(x): -0.000727
+# 10    f(x): -0.088106|grad f(p)|:0.01903913659588686
+# 20    f(x): -0.089023|grad f(p)|:0.007792334296299116
+# 30    f(x): -0.089501|grad f(p)|:0.008034300330026467
+# 40    f(x): -0.089842|grad f(p)|:0.008125526728200166
+# 50    f(x): -0.089890|grad f(p)|:0.0031244752821335416
+# 60    f(x): -0.089925|grad f(p)|:0.0029682862637714163
+# 70    f(x): -0.089962|grad f(p)|:0.002811722437216778
+# 80    f(x): -0.089997|grad f(p)|:0.0026658493010157363
+# 90    f(x): -0.090032|grad f(p)|:0.0025418974797659266
+# 100   f(x): -0.090067|grad f(p)|:0.0024485809550738955
+# 110   f(x): -0.090108|grad f(p)|:0.0023894008071780747
+# 120   f(x): -0.090155|grad f(p)|:0.002362317662908117
+# 130   f(x): -0.090208|grad f(p)|:0.0023611301647631484
+# 140   f(x): -0.090262|grad f(p)|:0.00237797866404072
+# 150   f(x): -0.090314|grad f(p)|:0.002405563029627607
+# 160   f(x): -0.090362|grad f(p)|:0.002438250821406204
+# 170   f(x): -0.090404|grad f(p)|:0.002472221074327323
+# 180   f(x): -0.090441|grad f(p)|:0.0025051377726827166
+# 190   f(x): -0.090472|grad f(p)|:0.002535721310831389
+# 200   f(x): -0.090498|grad f(p)|:0.0025633813700434637
+# 210   f(x): -0.090513|grad f(p)|:0.0025832821804127513
+# 220   f(x): -0.090513|grad f(p)|:0.0025832821804127513
+# 230   f(x): -0.090513|grad f(p)|:0.0025832821792817493
+# 240   f(x): -0.090513|grad f(p)|:0.0025832821770197098
+# 250   f(x): -0.090513|grad f(p)|:0.0025832821747576924
+# 260   f(x): -0.090513|grad f(p)|:0.002583282172495683
+# 270   f(x): -0.090513|grad f(p)|:0.0025832821702336567
+# 280   f(x): -0.090513|grad f(p)|:0.002583282167971658
+# 290   f(x): -0.090513|grad f(p)|:0.002583282165709656
+# 300   f(x): -0.090513|grad f(p)|:0.002583282163447637
+# 310   f(x): -0.090513|grad f(p)|:0.0025832821611855928
+# 320   f(x): -0.090513|grad f(p)|:0.0025832821589235814
+# 330   f(x): -0.090513|grad f(p)|:0.002583282156661572
+# 340   f(x): -0.090513|grad f(p)|:0.0025832821543995727
+# 350   f(x): -0.090513|grad f(p)|:0.002583282152137569
+# 360   f(x): -0.090513|grad f(p)|:0.0025832821498755487
+# 370   f(x): -0.090513|grad f(p)|:0.0025832821476135036
+# 380   f(x): -0.090513|grad f(p)|:0.0025832821453515035
+# 390   f(x): -0.090513|grad f(p)|:0.0025832821430894675
+# 400   f(x): -0.090513|grad f(p)|:0.0025832821408274405
+# 410   f(x): -0.090513|grad f(p)|:0.002583282138565445
+# 420   f(x): -0.090513|grad f(p)|:0.002583282136303441
+# 430   f(x): -0.090513|grad f(p)|:0.00258328213404143
+# 440   f(x): -0.090513|grad f(p)|:0.002583282131779385
+# 450   f(x): -0.090513|grad f(p)|:0.0025832821295174104
+# 460   f(x): -0.090513|grad f(p)|:0.002583282127255372
+# 470   f(x): -0.090513|grad f(p)|:0.002583282124993372
+# 480   f(x): -0.090513|grad f(p)|:0.0025832821227313313
+# 490   f(x): -0.090513|grad f(p)|:0.0025832821204693065
+# 500   f(x): -0.090513|grad f(p)|:0.002583282118207321
+# 510   f(x): -0.090513|grad f(p)|:0.0025832821159453034
+# 520   f(x): -0.090513|grad f(p)|:0.0025832821136832665
+# 530   f(x): -0.090513|grad f(p)|:0.0025832821114212673
+# 540   f(x): -0.090513|grad f(p)|:0.002583282109159243
+# 550   f(x): -0.090513|grad f(p)|:0.002583282106897217
+# 560   f(x): -0.090513|grad f(p)|:0.002583282104635213
+# 570   f(x): -0.090513|grad f(p)|:0.0025832821023731955
+# 580   f(x): -0.090513|grad f(p)|:0.0025832821001112094
+# 590   f(x): -0.090513|grad f(p)|:0.002583282097849167
+# 600   f(x): -0.090513|grad f(p)|:0.0025832820955871503
+# 610   f(x): -0.090513|grad f(p)|:0.0025832820933251325
+# 620   f(x): -0.090513|grad f(p)|:0.002583282091063122
+# 630   f(x): -0.090513|grad f(p)|:0.0025832820888010873
+# 640   f(x): -0.090513|grad f(p)|:0.0025832820865390785
+# 650   f(x): -0.090513|grad f(p)|:0.0025832820842770442
+# 660   f(x): -0.090513|grad f(p)|:0.0025832820820150576
+# 670   f(x): -0.090513|grad f(p)|:0.0025832820797530767
+# 680   f(x): -0.090513|grad f(p)|:0.0025832820774910523
+# 690   f(x): -0.090513|grad f(p)|:0.0025832820752290362
+# 700   f(x): -0.090513|grad f(p)|:0.002583282072966992
+# 710   f(x): -0.090513|grad f(p)|:0.002583282070704973
+# 720   f(x): -0.090513|grad f(p)|:0.0025832820684429532
+# 730   f(x): -0.090513|grad f(p)|:0.002583282066180946
+# 740   f(x): -0.090513|grad f(p)|:0.0025832820639189306
+# 750   f(x): -0.090513|grad f(p)|:0.0025832820616569214
+# 760   f(x): -0.090513|grad f(p)|:0.00258328205939488
+# 770   f(x): -0.090513|grad f(p)|:0.002583282057132884
+# 780   f(x): -0.090513|grad f(p)|:0.0025832820548708406
+# 790   f(x): -0.090513|grad f(p)|:0.002583282052608873
+# 800   f(x): -0.090513|grad f(p)|:0.002583282050346837
+# 810   f(x): -0.090513|grad f(p)|:0.0025832820480848214
+# 820   f(x): -0.090513|grad f(p)|:0.0025832820458228205
+# 830   f(x): -0.090513|grad f(p)|:0.0025832820435608087
+# 840   f(x): -0.090513|grad f(p)|:0.0025832820412987944
+# 850   f(x): -0.090513|grad f(p)|:0.0025832820390367726
+# 860   f(x): -0.090513|grad f(p)|:0.002583282036774768
+# 870   f(x): -0.090513|grad f(p)|:0.002583282034512706
+# 880   f(x): -0.090513|grad f(p)|:0.002583282032250709
+# 890   f(x): -0.090513|grad f(p)|:0.0025832820299886896
+# 900   f(x): -0.090513|grad f(p)|:0.002583282027726701
+# 910   f(x): -0.090513|grad f(p)|:0.002583282025464682
+# 920   f(x): -0.090513|grad f(p)|:0.0025832820232026517
+# 930   f(x): -0.090513|grad f(p)|:0.002583282020940619
+# 940   f(x): -0.090513|grad f(p)|:0.0025832820186786334
+# 950   f(x): -0.090513|grad f(p)|:0.002583282016416595
+# 960   f(x): -0.090513|grad f(p)|:0.0025832820141545986
+# 970   f(x): -0.090513|grad f(p)|:0.0025832820118925717
+# 980   f(x): -0.090513|grad f(p)|:0.0025832820096305525
+# 990   f(x): -0.090513|grad f(p)|:0.002583282007368543
+# 1000  f(x): -0.090513|grad f(p)|:0.0025832820051065217

To provide the Hessian in the high-level interface we need to prodive it as an anonymous function, since any struct is considered to (eventually) be the also optional starting point. For space reasons, let’s also shorten the debug print to only iterations 7 and 14.

q4 = trust_regions(M, f, grad_f, (E, p, X) -> Hess_f(E, p, X), p0; objective_type=:Euclidean,
+    debug = [:Iteration, :Cost, :GradientNorm, 10, "\n"],
+);
Initial f(x): -0.000727
+# 10    f(x): -0.089673|grad f(p)|:0.0033633987039373655
q5 = trust_regions(M, f, grad_f, (M, Y, p, X) -> Hess_f(M, Y, p, X), p0;
+    evaluation=InplaceEvaluation(),
+    debug = [:Iteration, :Cost, :GradientNorm, 10, "\n"],
+);
Initial f(x): -0.000727
+# 10    f(x): -0.089673|grad f(p)|:0.00336339870393737

Let’s also here compare them in benchmarks. Let’s here compare all variants in their (more performant) in-place versions.

@benchmark trust_regions($M, $f, $grad_f, $p0;
+  objective_type=:Euclidean,
+  evaluation=InplaceEvaluation(),
+)
BenchmarkTools.Trial: 10 samples with 1 evaluation.
+ Range (min … max):  488.560 ms … 542.951 ms  ┊ GC (min … max): 3.26% … 3.55%
+ Time  (median):     498.677 ms               ┊ GC (median):    3.22%
+ Time  (mean ± σ):   503.851 ms ±  17.951 ms  ┊ GC (mean ± σ):  3.27% ± 0.11%
+
+  █ ▁ ▁▁           ▁▁▁                      ▁                 ▁  
+  █▁█▁██▁▁▁▁▁▁▁▁▁▁▁███▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█ ▁
+  489 ms           Histogram: frequency by time          543 ms <
+
+ Memory estimate: 1.97 GiB, allocs estimate: 40408.
@benchmark trust_regions($M, $f, $grad_f, $((E, Y, p, X) -> Hess_f(E, Y, p, X)), $p0;
+  evaluation=InplaceEvaluation(),
+  objective_type=:Euclidean
+)
BenchmarkTools.Trial: 294 samples with 1 evaluation.
+ Range (min … max):  12.991 ms … 148.108 ms  ┊ GC (min … max): 0.00% … 87.36%
+ Time  (median):     15.369 ms               ┊ GC (median):    3.17%
+ Time  (mean ± σ):   17.014 ms ±   8.238 ms  ┊ GC (mean ± σ):  7.16% ±  7.03%
+
+       ▁  █  ▂                                                  
+  ▆▁▁▇▅█▃▆█▇▅█▄▁▆▃▂▂▁▁▂▅▂▃▅▂▁▃▃▄▂▃▅▃▁▁▁▁▂▁▂▁▁▁▁▁▁▁▁▁▁▁▁▂▁▁▃▁▂▃ ▃
+  13 ms           Histogram: frequency by time         28.6 ms <
+
+ Memory estimate: 37.43 MiB, allocs estimate: 2920.
@benchmark trust_regions($M, $f, $grad_f, $((M, Y, p, X) -> Hess_f(M, Y, p, X)), $p0;
+    evaluation=InplaceEvaluation(),
+)
BenchmarkTools.Trial: 506 samples with 1 evaluation.
+ Range (min … max):  8.717 ms … 152.718 ms  ┊ GC (min … max): 0.00% … 90.61%
+ Time  (median):     8.884 ms               ┊ GC (median):    0.00%
+ Time  (mean ± σ):   9.881 ms ±   6.537 ms  ┊ GC (mean ± σ):  4.94% ±  5.90%
+
+  ▆█▂     ▂▃    ▁                                              
+  ███▄▁▁▆▆██▇▄▆██▆▇▄▅▇▄▄▁▁▆▄▇▄▆▁▅▅▆▁▅▅▄▁▁▄▅▅▁▆▇▇▇▄▄▄▄▁▁▁▁▁▁▄▄ ▇
+  8.72 ms      Histogram: log(frequency) by time      14.7 ms <
+
+ Memory estimate: 10.77 MiB, allocs estimate: 2899.

We see that Hessian approximation is quite costly, and Gradient and Hessian conversion somewhat costly; still, they also might serve as a good starting point, before deciding to delve into computing Riemannian gradients and Hessians.

Of course all 5 runs obtained solutions close by; one might consider the gradient based runs to not have fully converged.

[distance(M, q1, q) for q ∈ [q2,q3] ]
2-element Vector{Float64}:
+ 4.471485799821605e-15
+ 0.048047538209352994
[distance(M, q3, q) for q ∈ [q4,q5] ]
2-element Vector{Float64}:
+ 0.08269488012454579
+ 0.08269488012454579

Which we can also see in the final cost, comparing it to the Eigenvalue

[f(M, q) - λ for q ∈ [q1, q2, q3, q4, q5] ]
5-element Vector{Float64}:
+  2.76900562450888e-5
+  2.769005624428389e-5
+ -0.000836208332542443
+  3.191891195797325e-16
+  3.191891195797325e-16

Summary

We illustrated several possibilities to call solvers, with both Euclidean gradient and Hessian and Riemannian gradient and Hessian, allocating and in-place function. While the performance is better for the Riemannian case, the Euclidean one is a worthy alternative, when those are easier to compute.

Literature

diff --git a/v0.1.8/examples/Riemannian-mean/index.html b/v0.1.8/examples/Riemannian-mean/index.html new file mode 100644 index 0000000..3350f4e --- /dev/null +++ b/v0.1.8/examples/Riemannian-mean/index.html @@ -0,0 +1,33 @@ + +Riemannian Mean · ManoptExamples.jl

The Riemannian Center of Mass (mean)

Ronny Bergmann 2023-07-02

Preliminary Notes

Each of the example objectives or problems stated in this package should be accompanied by a Quarto notebook that illustrates their usage, like this one.

For this first example, the objective is a very common one, for example also used in the Get started: optimize! tutorial of Manopt.jl.

The second goal of this tutorial is to also illustrate how this package provides these examples, namely in both an easy-to-use and a performant way.

There are two recommended ways to activate a reproducible environment. For most cases the recommended environment is the one in examples/. If you are programming a new, relatively short example, consider using the packages main environment, which is the same as having ManoptExamples.jl in development mode. this requires that your example does not have any (additional) dependencies beyond the ones ManoptExamples.jl has anyways.

For registered versions of ManoptExamples.jl use the environment of examples/ and – under development – add ManoptExamples.jl in development mode from the parent folder. This should be changed after a new example is within a registered version to just use the examples/ environment again.

using Pkg;
+cd(@__DIR__)
+Pkg.activate("."); # use the example environment,

Loading packages and defining data

Loading the necessary packages and defining a data set on a manifold

using ManoptExamples, Manopt, Manifolds, ManifoldDiff, Random
+Random.seed!(42)
+M = Sphere(2)
+n = 100
+σ = π / 8
+p = 1 / sqrt(2) * [1.0, 0.0, 1.0]
+data = [exp(M, p,  σ * rand(M; vector_at=p)) for i in 1:n];

Variant 1: Using the functions

We can define both the cost and gradient, RiemannianMeanCost and RiemannianMeanGradient!!, respectively. For their mathematical derivation and further explanations, we again refer to Get started: optimize!.

f = ManoptExamples.RiemannianMeanCost(data)
+grad_f = ManoptExamples.RiemannianMeanGradient!!(M, data)

Then we can for example directly call a gradient descent as

x1 = gradient_descent(M, f, grad_f, first(data))
3-element Vector{Float64}:
+ 0.6868392794567202
+ 0.006531600696673591
+ 0.7267799821044285

Variant 2: Using the objective

A shorter way to directly obtain the Manifold objective including these two functions. Here, we want to specify that the objective can do in-place-evaluations using the evaluation=-keyword. The objective can be obtained calling Riemannian_mean_objective as

rmo = ManoptExamples.Riemannian_mean_objective(
+    M, data,
+    evaluation=InplaceEvaluation(),
+)

Together with a manifold, this forms a Manopt Problem, which would usually enable to switch manifolds between solver runs. Here we could for example switch to using Euclidean(3) instead for the same data the objective is build upon.

rmp = DefaultManoptProblem(M, rmo)

This enables us to for example solve the task with different, gradient based, solvers. The first is the same as above, just not using the high-level interface

s1 = GradientDescentState(M, copy(M, first(data)))
+solve!(rmp, s1)
+x2 = get_solver_result(s1)
3-element Vector{Float64}:
+ 0.6868392794567202
+ 0.006531600696673591
+ 0.7267799821044285

but we can easily use a conjugate gradient instead

s2 = ConjugateGradientDescentState(
+    M,
+    copy(M, first(data)),
+    StopAfterIteration(100),
+    ArmijoLinesearch(M),
+    FletcherReevesCoefficient(),
+)
+solve!(rmp, s2)
+x3 = get_solver_result(s2)
3-element Vector{Float64}:
+ 0.6868393613136017
+ 0.006531541407458413
+ 0.7267799052788726
diff --git a/v0.1.8/examples/Robust-PCA/index.html b/v0.1.8/examples/Robust-PCA/index.html new file mode 100644 index 0000000..753c8ab --- /dev/null +++ b/v0.1.8/examples/Robust-PCA/index.html @@ -0,0 +1,64 @@ + +Robust PCA · ManoptExamples.jl

The Robust PCA computed on the Grassmann manifold

Ronny BergmannLaura Weigl 2023-07-02

For this example we first load the necessary packages.

using Pkg;
+cd(@__DIR__)
+Pkg.activate("."); # use the example environment,
using LinearAlgebra, Random, Statistics
+using Manifolds, Manopt, ManoptExamples
+using Plots
+Random.seed!(42)

Computing a Robust PCA

For a given matrix $D ∈ ℝ^{d×n}$ whose columns represent points in $ℝ^d$, a matrix $p ∈ ℝ^{d×m}$ is computed for a given dimension $m < n$: $p$ represents an ONB of $ℝ^{d×m}$ such that the column space of $p$ approximates the points (columns of $D$), i.e. the vectors $D_i$ as well as possible.

We compute $p$ as a minimizer over the Grassmann manifold of the cost function:

\[\begin{split} +f(p) +& = \frac{1}{n}\sum_{i=1}^{n}{\operatorname{dist}(D_i, \operatorname{span}(p))} +\\ +& = \frac{1}{n} \sum_{i=1}^{n}\lVert pp^TD_i - D_i\rVert +\end{split}\]

The output cost represents the average distance achieved with the returned $p$, an orthonormal basis (or a point on the Stiefel manifold) representing the subspace (a point on the Grassmann manifold). Notice that norms are not squared, so we have a robust cost function. This means that $f$ is nonsmooth, therefore we regularize with a pseudo-Huber loss function of smoothing parameter $ε$.

\[f_ϵ(p) = \frac{1}{n} \sum_{i=1}^n{ℓ_ϵ(\lVert pp^{\mathrm{T}}D_i - D_i\rVert)},\]

where $ℓ_ϵ(x) = \sqrt{x^2 + ϵ^2} - ϵ$.

The smoothing parameter is iteratively reduced in the final optimisation runs(with warm starts).

First, we generate random data. For illustration purposes we take points in $\mathbb R^2$ and $m=1$, that is we aim to find a robust regression line.

n = 40
+d = 2
+outliers = 15
+data = randn(d, 1) * (1:n)' + 0.05 * randn(2, n) .* [1:n 1:n]'
+# Outliers:
+permute = shuffle(1:size(data, 2))'
+data[:, permute[1:outliers]] = 30 * randn(2, outliers)
+# We are looking for a line here so we set
+m = 1

We use the Manopt toolbox to optimize the regularized cost function over the Grassmann manifold. To do this, we first need to define the problem structure.

M = Grassmann(d,m);

For the initial matrix $p_0$ we use classical PCA via singular value decomposition. Thus, we use the first $d$ left singular vectors.

Then, we compute an optimum of the cost function over the Grassmann manifold. We use a trust-region method which is implemented in Manopt.jl.

Furthermore the cost and gradient are implemented in ManoptExamples.jl. Since these are Huber regularized, both functors have the ϵ as a parameter. To compute the Riemannian gradient we first compute the Euclidian gradient. Afterwards it is projected onto the tangent space by using the orthogonal projection $pp^T - I$, which converts the Euclidean to the Riemannian gradient.

The trust-region method also requires the Hessian Matrix. By using ApproxHessianFiniteDifference using a finite difference scheme we get an approximation of the Hessian Matrix.

We run the procedure several times, where the smoothing parameter $ε$ is reduced iteratively.

ε = 1.0
+iterations = 6
+reduction = 0.5
+U, S, V = svd(data);
+p0 = U[:, 1:m]
2×1 Matrix{Float64}:
+ -0.7494248652139397
+  0.6620893983436593

Let’s generate the cost and gradient we aim to use here

f = ManoptExamples.RobustPCACost(M, data, ε)
+grad_f = ManoptExamples.RobustPCAGrad!!(M, data, ε)
ManoptExamples.RobustPCAGrad!!{Matrix{Float64}, Float64}([9.537606557855465 1.6583418797018163 … 30.833523701909474 30.512999245062304; -45.34339972619071 -1.7120433539256108 … -35.85943792458936 -32.93976007215313], 1.0, [0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0])

and check the initial cost

f(M, p0)
9.430690947905521

Now we iterate the opimization with reducing ε after every iteration, which we update in f and grad_f.

q = copy(M, p0)
+εi = ε
+for i in 1:iterations
+    f.ε = εi
+    grad_f.ε = εi
+    global q = trust_regions(
+        M,
+        f,
+        grad_f,
+        ApproxHessianFiniteDifference(
+            M, q, f;
+            vector_transport_method=ProjectionTransport(),
+            retraction_method=PolarRetraction(),
+        ),
+        q;
+        (project!)=project!,
+    )
+    global εi *= reduction
+end

When finally setting ε we can investigate the final cost

f.ε = 0.0
+f(M, q)
9.412961981726742

Finally, the results are presented visually. The data points are visualized in a scatter plot. The result of the robust PCA and (for comparison) the standard SVD solution are plotted as straight lines.

fig = plot(data[1, :], data[2, :]; seriestype=:scatter, label="Data points");
+plot!(
+    fig,
+    q[1] * [-1, 1] * 100,
+    q[2] * [-1, 1] * 100;
+    linecolor=:red,
+    linewidth=2,
+    label="Robust PCA",
+);
+plot!(
+    fig,
+    p0[1] * [-1, 1] * 100,
+    p0[2] * [-1, 1] * 100;
+    xlims=1.1 * [minimum(data[1, :]), maximum(data[1, :])],
+    ylims=1.1 * [minimum(data[2, :]), maximum(data[2, :])],
+    linewidth=2,
+    linecolor=:black,
+    label="Standard SVD",
+)

Figure 1: The result of the robust PCA vs. SVD

diff --git a/v0.1.8/examples/Robust-PCA_files/figure-commonmark/fig-pca-output-1.svg b/v0.1.8/examples/Robust-PCA_files/figure-commonmark/fig-pca-output-1.svg new file mode 100644 index 0000000..e695072 --- /dev/null +++ b/v0.1.8/examples/Robust-PCA_files/figure-commonmark/fig-pca-output-1.svg @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.1.8/examples/Rosenbrock/index.html b/v0.1.8/examples/Rosenbrock/index.html new file mode 100644 index 0000000..a1eb69e --- /dev/null +++ b/v0.1.8/examples/Rosenbrock/index.html @@ -0,0 +1,59 @@ + +Rosenbrock · ManoptExamples.jl

The Rosenbrock Function

Ronny Bergmann 2023-01-03

After loading the necessary packages

using Pkg;
+cd(@__DIR__)
+Pkg.activate("."); # use the example environment,
using Manifolds, Manopt, ManoptExamples
+using Plots

We fix the parameters for the 📖 Rosenbrock (where the wikipedia page has a slightly different parameter naming).

a = 100.0
+b = 1.0
+p0 = [1/10, 2/10]

which is defined on $\mathbb R^2$, so we need

M = ℝ^2
Euclidean(2; field=ℝ)

and can then generate both the cost and the gradient

f = ManoptExamples.RosenbrockCost(M; a=a, b=b)
+grad_f = ManoptExamples.RosenbrockGradient!!(M; a=a, b=b)
ManoptExamples.RosenbrockGradient!!{Float64}(100.0, 1.0)

For comparison, we look at the initial cost

f(M, p0)
4.42

And to illustrate, we run two small solvers with their default settings as a comparison.

Gradient Descent

We start with the gradient descent solver.

Since we need the state anyways to access the record, we also get from the return_state=true a short summary of the solver run.

gd_state = gradient_descent(M, f, grad_f, p0; record = [:Iteration, :Cost], return_state=true)
# Solver state for `Manopt.jl`s Gradient Descent
+After 200 iterations
+
+## Parameters
+* retraction method: ExponentialRetraction()
+
+## Stepsize
+ArmijoLinesearch() with keyword parameters
+  * initial_stepsize    = 1.0
+  * retraction_method   = ExponentialRetraction()
+  * contraction_factor  = 0.95
+  * sufficient_decrease = 0.1
+
+## Stopping criterion
+
+Stop When _one_ of the following are fulfilled:
+    Max Iteration 200:  reached
+    |grad f| < 1.0e-8: not reached
+Overall: reached
+This indicates convergence: No
+
+## Record
+(Iteration = RecordGroup([RecordIteration(), RecordCost()]),)

From the summary we see, that the gradient is not yet small enough, but we hit the 200 iterations (default) iteration limit. Collecting the cost recording and printing the final cost

gd_x = get_record(gd_state, :Iteration, :Iteration)
+gd_y =  get_record(gd_state, :Iteration, :Cost)
+f(M, get_solver_result(gd_state))
0.10562873187751265

Quasi Newton

We can improve this using the quasi Newton algorithm

qn_state = quasi_Newton(M, f, grad_f, p0;
+    record = [:Iteration, :Cost], return_state=true
+)
# Solver state for `Manopt.jl`s Quasi Newton Method
+After 26 iterations
+
+## Parameters
+* direction update:        limited memory InverseBFGS (size 2), projections, and ParallelTransport() as vector transport.
+* retraction method:       ExponentialRetraction()
+* vector transport method: ParallelTransport()
+
+## Stepsize
+WolfePowellLinesearch(DefaultManifold(), 0.0001, 0.999) with keyword arguments
+  * retraction_method = ExponentialRetraction()
+  * vector_transport_method = ParallelTransport()
+
+## Stopping criterion
+
+Stop When _one_ of the following are fulfilled:
+    Max Iteration 1000: not reached
+    |grad f| < 1.0e-6: reached
+Overall: reached
+This indicates convergence: Yes
+
+## Record
+(Iteration = RecordGroup([RecordIteration(), RecordCost()]),)

And we see it stops far earlier, after 45 Iterations. We again collect the recorded values

qn_x = get_record(qn_state, :Iteration, :Iteration)
+qn_y =  get_record(qn_state, :Iteration, :Cost)
+f(M, get_solver_result(qn_state))
1.4404666436813376e-18

and see that the final value is close to the one of the minimizer

f(M, ManoptExamples.minimizer(f))
0.0

which we also see if we plot the recorded cost.

fig = plot(gd_x, gd_y; linewidth=1, label="Gradient Descent");
+plot!(fig, qn_x, qn_y; linewidth=1, label="Quasi Newton")

Figure 1: The result of the robust PCA vs. SVD

diff --git a/v0.1.8/examples/Rosenbrock_files/figure-commonmark/fig-pca-output-1.svg b/v0.1.8/examples/Rosenbrock_files/figure-commonmark/fig-pca-output-1.svg new file mode 100644 index 0000000..67f8e6f --- /dev/null +++ b/v0.1.8/examples/Rosenbrock_files/figure-commonmark/fig-pca-output-1.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.1.8/examples/Total-Variation/index.html b/v0.1.8/examples/Total-Variation/index.html new file mode 100644 index 0000000..139730e --- /dev/null +++ b/v0.1.8/examples/Total-Variation/index.html @@ -0,0 +1,107 @@ + +Total Variation · ManoptExamples.jl

Total Variation Minimization

Ronny Bergmann 2023-06-06

Introduction

Total Variation denoising is an optimization problem used to denoise signals and images. The corresponding (Euclidean) objective is often called Rudin-Osher-Fatemi (ROF) model based on the paper [ROF92].

This was generalized to manifolds in [WDS14]. In this short example we will look at the ROF model for manifold-valued data, its generalizations, and how they can be solved using Manopt.jl.

The manifold-valued ROF model

Generalizing the ROF model to manifolds can be phrased as follows: Given a (discrete) signal on a manifold $s = (s_i)_{i=1}^N \in \mathbb M^n$ of length $n \in \mathbb N$, we usually assume that this signal might be noisy. For the (Euclidean) ROF model we assume that the noise is Gaussian. Then variational models for denoising usually consist of a data term $D(p,s)$ to “stay close to” $s$ and a regularizer $R(p)$. For TV regularization the data term is the squared distance and the regularizer models that without noise, neighboring values are close. We obtain

\[\operatorname*{arg\,min}_{p\in\mathcal M^n} +f(p), +\qquad +f(p) = D(p,s) + α R(p) = \sum_{i=1}^n d_{\mathcal M}^2(s_i,p_i) + α\sum_{i=1}^{n-1} d_{\mathcal M}(p_i,p_{i+1}),\]

where $α > 0$ is a weight parameter.

The challenge here is that most classical algorithm, like gradient descent or Quasi Newton, assume the cost $f(p)$ to be smooth such that the gradient exists at every point. In our setting that is not the case since the distacen is not differentiable for any $p_i=p_{i+1}$. So we have to use another technique.

The Cyclic Proximal Point algorithm

If the cost consists of a sum of functions, where each of the proximal maps is “easy to evaluate”, for best of cases in closed form, we can “apply the proximal maps in a cyclic fashion” and optain the Cyclic Proximal Point Algorithm [Bac14].

Both for the distance and the squared distance, we have generic implementations; since this happens in a cyclic manner, there is also always one of the arguments involved in the prox and never both. We can improve the performance slightly by computing all proes in parallel that do not interfer. To be precise we can compute first all proxes of distances in the regularizer that start with an odd index in parallel. Afterwards all that start with an even index.

The Optimsation

using Manifolds, Manopt, ManoptExamples, ManifoldDiff
+using ManifoldDiff: prox_distance
+using ManoptExamples: prox_Total_Variation
+n = 500 #Signal length
+σ = 0.2 # amount of noise
+α = 0.5# in the TV model

We define a few colors

using Colors, NamedColors, ColorSchemes, Plots, Random
+data_color = RGBA{Float64}(colorant"black")
+light_color = RGBA{Float64}(colorant"brightgrey")
+recon_color = RGBA{Float64}(colorant"vibrantorange")
+noisy_color = RGBA{Float64}(colorant"vibrantteal")

And we generate our data on the Circle, since that is easy to plot and nice to compare to the Euclidean case of a real-valued signal.

Random.seed!(23)
+M = Circle()
+N = PowerManifold(M, n)
+data = ManoptExamples.artificial_S1_signal(n)
+s = [exp(M, d, rand(M; vector_at=d, σ=0.2)) for d in data]
+t = range(0.0, 1.0; length=n)
+scene = scatter(
+    t,
+    data;
+    markercolor=data_color,
+    markerstrokecolor=data_color,
+    markersize=2,
+    lab="original",
+)
+scatter!(
+    scene,
+    t,
+    s;
+    markersize=2,
+    markercolor=noisy_color,
+    markerstrokecolor=noisy_color,
+    lab="noisy",
+)
+yticks!(
+    [-π, -π / 2, 0, π / 2, π],
+    [raw"$-\pi$", raw"$-\frac{\pi}{2}$", raw"$0$", raw"$\frac{\pi}{2}$", raw"$\pi$"],
+)

As mentioned above, total variation now minimized different neighbors – while keeping jumps if the are large enough. One notable difference between Euclidean and Cyclic data is, that the y-axis is in our case periodic, hence the first jump is actually not a jump but a “linear increase” that “wraps around” and the second large jump –or third overall– is actually only as small as the second jump.

Defining cost and the proximal maps, which are actually 3 proxes to be precise.

f(N, p) = ManoptExamples.L2_Total_Variation(N, s, α, p)
+proxes_f = ((N, λ, p) -> prox_distance(N, λ, s, p, 2), (N, λ, p) -> prox_Total_Variation(N, α * λ, p))

We run the algorithm

o = cyclic_proximal_point(
+    N,
+    f,
+    proxes_f,
+    s;
+    λ=i -> π / (2 * i),
+    debug=[
+        :Iteration,
+        " | ",
+        DebugProximalParameter(),
+        " | ",
+        :Cost,
+        " | ",
+        :Change,
+        "\n",
+        1000,
+        :Stop,
+    ],
+    record=[:Iteration, :Cost, :Change, :Iterate],
+    return_state=true,
+);
Initial  |  | f(x): 59.187445 | 
+# 1000   | λ:0.0015707963267948967 | f(x): 13.963912 | Last Change: 1.773283
+# 2000   | λ:0.0007853981633974483 | f(x): 13.947124 | Last Change: 0.011678
+# 3000   | λ:0.0005235987755982988 | f(x): 13.941538 | Last Change: 0.003907
+# 4000   | λ:0.00039269908169872416 | f(x): 13.938748 | Last Change: 0.001957
+# 5000   | λ:0.0003141592653589793 | f(x): 13.937075 | Last Change: 0.001175
+The algorithm reached its maximal number of iterations (5000).

We can see that the cost reduces nicely. Let’s extract the result an the recorded values

recon = get_solver_result(o)
+record = get_record(o)

We get

scene = scatter(
+    t,
+    data;
+    markercolor=data_color,
+    markerstrokecolor=data_color,
+    markersize=2,
+    lab="original",
+)
+scatter!(
+    scene,
+    t,
+    s;
+    markersize=2,
+    markercolor=light_color,
+    markerstrokecolor=light_color,
+    lab="noisy",
+)
+scatter!(
+    scene,
+    t,
+    recon;
+    markersize=2,
+    markercolor=recon_color,
+    markerstrokecolor=recon_color,
+    lab="reconstruction",
+)

Which contains the usual stair casing one expects for TV regularization, but here in a “cyclic manner”

Outlook

We can generalize the total variation also to a second order total variation. Again intuitively, while TV prefers constant areas, the $\operatorname{TV}_2$ yields a cost 0 for anything linear, which on manifolds can be generalized to equidistant on a geodesic [BBSW16]. Here we can again derive proximal maps, which for the circle again have a closed form solutoin [BLSW14] but on general manifolds these have again to be approximated.

Another extension for both first and second order TV is to apply this for manifold-valued images $S = (S_{i,j})_{i,j=1}^{m,n} \in \mathcal M^{m,n}$, where the distances in the regularizer are then used in both the first dimension $i$ and the second dimension $j$ in the data.

Technical details

This version of the example was generated with the following package versions.

Pkg.status()
Status `~/work/ManoptExamples.jl/ManoptExamples.jl/examples/Project.toml`
+  [6e4b80f9] BenchmarkTools v1.5.0
+  [35d6a980] ColorSchemes v3.25.0
+  [5ae59095] Colors v0.12.11
+  [7073ff75] IJulia v1.24.2
+  [8ac3fa9e] LRUCache v1.6.1
+  [d3d80556] LineSearches v7.2.0
+  [af67fdf4] ManifoldDiff v0.3.10
+  [1cead3c2] Manifolds v0.9.18
+  [3362f125] ManifoldsBase v0.15.10
+  [0fc0a36d] Manopt v0.4.63
+  [5b8d5e80] ManoptExamples v0.1.7 `..`
+  [51fcb6bd] NamedColors v0.2.2
+  [91a5bcdd] Plots v1.40.4
+  [6099a3de] PythonCall v0.9.20

Literature

[Bac14]
M. Bačák. Computing medians and means in Hadamard spaces. SIAM Journal on Optimization 24, 1542–1566 (2014), arXiv:1210.2145.
[BBSW16]
M. Bačák, R. Bergmann, G. Steidl and A. Weinmann. A second order non-smooth variational model for restoring manifold-valued images. SIAM Journal on Scientific Computing 38, A567–A597 (2016), arXiv:1506.02409.
[BLSW14]
R. Bergmann, F. Laus, G. Steidl and A. Weinmann. Second order differences of cyclic data and applications in variational denoising. SIAM Journal on Imaging Sciences 7, 2916–2953 (2014), arXiv:1405.5349.
[ROF92]
L. I. Rudin, S. Osher and E. Fatemi. Nonlinear total variation based noise removal algorithms. Physica D: Nonlinear Phenomena 60, 259–268 (1992).
[WDS14]
A. Weinmann, L. Demaret and M. Storath. Total variation regularization for manifold-valued data. SIAM Journal on Imaging Sciences 7, 2226–2257 (2014).
diff --git a/v0.1.8/examples/Total-Variation_files/figure-commonmark/cell-10-output-1.svg b/v0.1.8/examples/Total-Variation_files/figure-commonmark/cell-10-output-1.svg new file mode 100644 index 0000000..f5c90b3 --- /dev/null +++ b/v0.1.8/examples/Total-Variation_files/figure-commonmark/cell-10-output-1.svg @@ -0,0 +1,1551 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.1.8/examples/Total-Variation_files/figure-commonmark/cell-6-output-1.svg b/v0.1.8/examples/Total-Variation_files/figure-commonmark/cell-6-output-1.svg new file mode 100644 index 0000000..414a9ca --- /dev/null +++ b/v0.1.8/examples/Total-Variation_files/figure-commonmark/cell-6-output-1.svg @@ -0,0 +1,1048 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.1.8/examples/img/bezier/Casteljau-illustr.png b/v0.1.8/examples/img/bezier/Casteljau-illustr.png new file mode 100644 index 0000000..ecddd4a Binary files /dev/null and b/v0.1.8/examples/img/bezier/Casteljau-illustr.png differ diff --git a/v0.1.8/examples/img/bezier/bezier-acceleration-orig.png b/v0.1.8/examples/img/bezier/bezier-acceleration-orig.png new file mode 100644 index 0000000..43dd0a9 Binary files /dev/null and b/v0.1.8/examples/img/bezier/bezier-acceleration-orig.png differ diff --git a/v0.1.8/examples/img/bezier/bezier-acceleration-result.png b/v0.1.8/examples/img/bezier/bezier-acceleration-result.png new file mode 100644 index 0000000..66b41aa Binary files /dev/null and b/v0.1.8/examples/img/bezier/bezier-acceleration-result.png differ diff --git a/v0.1.8/examples/index.html b/v0.1.8/examples/index.html new file mode 100644 index 0000000..cfd4a07 --- /dev/null +++ b/v0.1.8/examples/index.html @@ -0,0 +1,2 @@ + +Overview · ManoptExamples.jl

List of Examples

NameprovidesDocumentationComment
A Benchmark for Difference of Convexcontains a few simple functions
Bézier Curves and Minimizing their Accelerationtools Bézier curves and their acceleration📚
Solving Rosenbrock with Difference of ConvexDoC split of Rosenbrock📚uses a Rosenbrock based metric
Difference of Convex vs. Frank-Wolfeclosed-form sub solver
Riemannian Mean$f$, $\operatorname{grad}f$ (A/I), objective📚
Robust PCA$f$, $\operatorname{grad}f$ (A/I), objective📚
Rosenbrock$f$, $\operatorname{grad}f$ (A/I), objective, minimizer📚
The Rayleigh Quotient$f$, $\operatorname{grad}f$ (A/I), $\operatorname{Hess}f$ (A/I), objective📚
Total Variation Minimization$f$, $\operatorname{prox}f$ (A/I), objective📚

Symbols:

  • A Allocating variant
  • I In-place variant
  • 📚 link to documented functions in the documentation
diff --git a/v0.1.8/helpers/error_measures/index.html b/v0.1.8/helpers/error_measures/index.html new file mode 100644 index 0000000..08010e2 --- /dev/null +++ b/v0.1.8/helpers/error_measures/index.html @@ -0,0 +1,2 @@ + +Error measures · ManoptExamples.jl
diff --git a/v0.1.8/index.html b/v0.1.8/index.html new file mode 100644 index 0000000..3744d21 --- /dev/null +++ b/v0.1.8/index.html @@ -0,0 +1,2 @@ + +Home · ManoptExamples.jl

Welcome to ManoptExample.jl

This package provides a set of example tasks for Manopt.jl based on either generic manifolds from the ManifoldsBase.jl interface or specific manifolds from Manifolds.jl.

Each example usually consists of

  • a cost function and additional objects, like the gradient or proximal maps, see objectives
  • an example explaining how to use these, see examples

Helping functions that are used in one or more examples can be found in the section of functions in the menu.

diff --git a/v0.1.8/objectives/index.html b/v0.1.8/objectives/index.html new file mode 100644 index 0000000..4fa4bb7 --- /dev/null +++ b/v0.1.8/objectives/index.html @@ -0,0 +1,187 @@ + +Objectives · ManoptExamples.jl

List of Objectives defined for the Examples

Rayleigh Quotient on the Sphere

See the Rayleigh example (TODO) to see these in use.

ManoptExamples.RayleighQuotientCostType
RayleighQuotientCost

A functor representing the Rayleigh Quotient cost function.

Let $A ∈ ℝ^{n×n}$ be a symmetric matrix. Then we can specify the Rayleigh Quotient in two forms. Either

\[f(p) = p^{\mathrm{T}}Ap,\qquad p ∈ 𝕊^{n-1},\]

or extended into the embedding as

\[f(x) = x^{\mathrm{T}}Ax, \qquad x ∈ ℝ^n,\]

which is not the orignal Rayleigh quotient for performance reasons, but useful if you want to use this as the Euclidean cost in the emedding of $𝕊^{n-1}$.

Fields

  • A – storing the matrix internally

Constructor

RayleighQuotientCost(A)

Create the Rayleigh cost function.

See also

RayleighQuotientGrad!!, RayleighQuotientHess!!

source
ManoptExamples.RayleighQuotientGrad!!Type
RayleighQuotientGrad!!

A functor representing the Rayleigh Quotient gradient function.

Let $A ∈ ℝ^{n×n}$ be a symmetric matrix. Then we can specify the gradient of the Rayleigh Quotient in two forms. Either

\[\operatorname{grad} f(p) = 2 Ap - 2 (p^{\mathrm{T}}Ap)*p,\qquad p ∈ 𝕊^{n-1},\]

or taking the Euclidean gradient of the Rayleigh quotient on the sphere as

\[∇f(x) = 2Ax, \qquad x ∈ ℝ^n.\]

For details, see Example 3.62 of [Bou23].

Fields

  • A – storing the matrix internally

Constructor

RayleighQuotientGrad!!(A)

Create the Rayleigh quotient gradient function.

See also

RayleighQuotientCost, RayleighQuotientHess!!

source
ManoptExamples.RayleighQuotientHess!!Type
RayleighQuotientHess!!

A functor representing the Rayleigh Quotient Hessian.

Let $A ∈ ℝ^{n×n}$ be a symmetric matrix. Then we can specify the Hessian of the Rayleigh Quotient in two forms. Either

\[\operatorname{Hess} f(p)[X] = 2 \bigl(AX - (p^{mathrm{T}}AX)p - (p^{\mathrm{T}}Ap)X\bigr),\qquad p ∈ 𝕊^{n-1}, X \in T_p𝕊^{n-1}\]

or taking the Euclidean Hessian of the Rayleigh quotient on the sphere as

\[∇^2f(x)[V] = 2AV, \qquad x, V ∈ ℝ^n.\]

For details, see Example 5.27 of [Bou23].

Fields

  • A – storing the matrix internally

Constructor

RayleighQuotientHess!!(A)

Create the Rayleigh quotient Hessian function.

See also

RayleighQuotientCost, RayleighQuotientGrad!!

source

Bézier Curves

See the Bezier Curves example to see these in use.

ManoptExamples.BezierSegmentType
BezierSegment

A type to capture a Bezier segment. With $n$ points, a Bézier segment of degree $n-1$ is stored. On the Euclidean manifold, this yields a polynomial of degree $n-1$.

This type is mainly used to encapsulate the points within a composite Bezier curve, which consist of an AbstractVector of BezierSegments where each of the points might be a nested array on a PowerManifold already.

Not that this can also be used to represent tangent vectors on the control points of a segment.

See also: de_Casteljau.

Constructor

BezierSegment(pts::AbstractVector)

Given an abstract vector of pts generate the corresponding Bézier segment.

source
ManoptExamples.L2_acceleration_BezierMethod
L2_acceleration_Bezier(M,B,pts,λ,d)

compute the value of the discrete Acceleration of the composite Bezier curve together with a data term, i.e.

\[\frac{λ}{2}\sum_{i=0}^{N} d_{\mathcal M}(d_i, c_B(i))^2+ +\sum_{i=1}^{N-1}\frac{d^2_2 [ B(t_{i-1}), B(t_{i}), B(t_{i+1})]}{\Delta_t^3}\]

where for this formula the pts along the curve are equispaced and denoted by $t_i$ and $d_2$ refers to the second order absolute difference second_order_Total_Variation (squared), the junction points are denoted by $p_i$, and to each $p_i$ corresponds one data item in the manifold points given in d. For details on the acceleration approximation, see acceleration_Bezier. Note that the Bézier-curve is given in reduces form as a point on a PowerManifold, together with the degrees of the segments and assuming a differentiable curve, the segments can internally be reconstructed.

See also

grad_L2_acceleration_Bezier, acceleration_Bezier, grad_acceleration_Bezier

source
ManoptExamples.acceleration_BezierMethod
acceleration_Bezier(
+    M::AbstractManifold,
+    B::AbstractVector{P},
+    degrees::AbstractVector{<:Integer},
+    T::AbstractVector{<:AbstractFloat},
+) where {P}

compute the value of the discrete Acceleration of the composite Bezier curve

\[\sum_{i=1}^{N-1}\frac{d^2_2 [ B(t_{i-1}), B(t_{i}), B(t_{i+1})]}{\Delta_t^3}\]

where for this formula the pts along the curve are equispaced and denoted by $t_i$, $i=1,…,N$, and $d_2$ refers to the second order absolute difference second_order_Total_Variation (squared). Note that the Bézier-curve is given in reduces form as a point on a PowerManifold, together with the degrees of the segments and assuming a differentiable curve, the segments can internally be reconstructed.

This acceleration discretization was introduced in Bergmann, Gousenbourger, Front. Appl. Math. Stat., 2018.

See also

grad_acceleration_Bezier, L2_acceleration_Bezier, grad_L2_acceleration_Bezier

source
ManoptExamples.adjoint_differential_Bezier_control_pointsMethod
adjoint_differential_Bezier_control_points(
+    M::AbstractManifold,
+    T::AbstractVector,
+    X::AbstractVector,
+)
+adjoint_differential_Bezier_control_points!(
+    M::AbstractManifold,
+    Y::AbstractVector{<:BezierSegment},
+    T::AbstractVector,
+    X::AbstractVector,
+)

Evaluate the adjoint of the differential with respect to the controlpoints at several times T. This can be computed in place of Y.

See de_Casteljau for more details on the curve.

source
ManoptExamples.adjoint_differential_Bezier_control_pointsMethod
adjoint_differential_Bezier_control_points(
+    M::AbstractManifold,
+    B::AbstractVector{<:BezierSegment},
+    t,
+    X
+)
+adjoint_differential_Bezier_control_points!(
+    M::AbstractManifold,
+    Y::AbstractVector{<:BezierSegment},
+    B::AbstractVector{<:BezierSegment},
+    t,
+    X
+)

evaluate the adjoint of the differential of a composite Bézier curve on the manifold M with respect to its control points b based on a points T$=(t_i)_{i=1}^n$ that are pointwise in $t_i∈[0,1]$ on the curve and given corresponding tangential vectors $X = (η_i)_{i=1}^n$, $η_i∈T_{β(t_i)}\mathcal M$ This can be computed in place of Y.

See de_Casteljau for more details on the curve.

source
ManoptExamples.adjoint_differential_Bezier_control_pointsMethod
adjoint_differential_Bezier_control_points(
+    M::AbstractManifold,
+    b::BezierSegment,
+    t::AbstractVector,
+    X::AbstractVector,
+)
+adjoint_differential_Bezier_control_points!(
+    M::AbstractManifold,
+    Y::BezierSegment,
+    b::BezierSegment,
+    t::AbstractVector,
+    X::AbstractVector,
+)

evaluate the adjoint of the differential of a Bézier curve on the manifold M with respect to its control points b based on a points T$=(t_i)_{i=1}^n$ that are pointwise in $t_i∈[0,1]$ on the curve and given corresponding tangential vectors $X = (η_i)_{i=1}^n$, $η_i∈T_{β(t_i)}\mathcal M$ This can be computed in place of Y.

See de_Casteljau for more details on the curve and Bergmann, Gousenbourger, Front. Appl. Math. Stat., 2018

source
ManoptExamples.adjoint_differential_Bezier_control_pointsMethod
adjoint_differential_Bezier_control_points(M::AbstractManifold, b::BezierSegment, t, η)
+adjoint_differential_Bezier_control_points!(
+    M::AbstractManifold,
+    Y::BezierSegment,
+    b::BezierSegment,
+    t,
+    η,
+)

evaluate the adjoint of the differential of a Bézier curve on the manifold M with respect to its control points b based on a point t$∈[0,1]$ on the curve and a tangent vector $η∈T_{β(t)}\mathcal M$. This can be computed in place of Y.

See de_Casteljau for more details on the curve.

source
ManoptExamples.de_CasteljauMethod
de_Casteljau(M::AbstractManifold, b::BezierSegment NTuple{N,P}) -> Function

return the Bézier curve $β(⋅;b_0,…,b_n): [0,1] → \mathcal M$ defined by the control points $b_0,…,b_n∈\mathcal M$, $n∈\mathbb N$, as a BezierSegment. This function implements de Casteljau's algorithm Casteljau, 1959, Casteljau, 1963 generalized to manifolds by Popiel, Noakes, J Approx Theo, 2007: Let $γ_{a,b}(t)$ denote the shortest geodesic connecting $a,b∈\mathcal M$. Then the curve is defined by the recursion

\[\begin{aligned} + β(t;b_0,b_1) &= \gamma_{b_0,b_1}(t)\\ + β(t;b_0,…,b_n) &= \gamma_{β(t;b_0,…,b_{n-1}), β(t;b_1,…,b_n)}(t), +\end{aligned}\]

and P is the type of a point on the Manifold M.

de_Casteljau(M::AbstractManifold, B::AbstractVector{<:BezierSegment}) -> Function

Given a vector of Bézier segments, i.e. a vector of control points $B=\bigl( (b_{0,0},…,b_{n_0,0}),…,(b_{0,m},… b_{n_m,m}) \bigr)$, where the different segments might be of different degree(s) $n_0,…,n_m$. The resulting composite Bézier curve $c_B:[0,m] → \mathcal M$ consists of $m$ segments which are Bézier curves.

\[c_B(t) := + \begin{cases} + β(t; b_{0,0},…,b_{n_0,0}) & \text{ if } t ∈[0,1]\\ + β(t-i; b_{0,i},…,b_{n_i,i}) & \text{ if } + t∈(i,i+1], \quad i∈\{1,…,m-1\}. + \end{cases}\]

de_Casteljau(M::AbstractManifold, b::BezierSegment, t::Real)
+de_Casteljau(M::AbstractManifold, B::AbstractVector{<:BezierSegment}, t::Real)
+de_Casteljau(M::AbstractManifold, b::BezierSegment, T::AbstractVector) -> AbstractVector
+de_Casteljau(
+    M::AbstractManifold,
+    B::AbstractVector{<:BezierSegment},
+    T::AbstractVector
+) -> AbstractVector

Evaluate the Bézier curve at time t or at times t in T.

source
ManoptExamples.differential_Bezier_control_pointsMethod
differential_Bezier_control_points(
+    M::AbstractManifold,
+    B::AbstractVector{<:BezierSegment},
+    T::AbstractVector
+    Ξ::AbstractVector{<:BezierSegment}
+)
+differential_Bezier_control_points!(
+    M::AbstractManifold,
+    Θ::AbstractVector{<:BezierSegment}
+    B::AbstractVector{<:BezierSegment},
+    T::AbstractVector
+    Ξ::AbstractVector{<:BezierSegment}
+)

evaluate the differential of the composite Bézier curve with respect to its control points B and tangent vectors Ξ in the tangent spaces of the control points. The result is the “change” of the curve at the points in T, which are elementwise in $[0,N]$, and each depending the corresponding segment(s). Here, $N$ is the length of B. For the mutating variant the result is computed in Θ.

See de_Casteljau for more details on the curve and Bergmann, Gousenbourger, Front. Appl. Math. Stat., 2018.

source
ManoptExamples.differential_Bezier_control_pointsMethod
differential_Bezier_control_points(
+    M::AbstractManifold,
+    B::AbstractVector{<:BezierSegment},
+    t,
+    X::AbstractVector{<:BezierSegment}
+)
+differential_Bezier_control_points!(
+    M::AbstractManifold,
+    Y::AbstractVector{<:BezierSegment}
+    B::AbstractVector{<:BezierSegment},
+    t,
+    X::AbstractVector{<:BezierSegment}
+)

evaluate the differential of the composite Bézier curve with respect to its control points B and tangent vectors Ξ in the tangent spaces of the control points. The result is the “change” of the curve at t$∈[0,N]$, which depends only on the corresponding segment. Here, $N$ is the length of B. The computation can be done in place of Y.

See de_Casteljau for more details on the curve.

source
ManoptExamples.differential_Bezier_control_pointsMethod
differential_Bezier_control_points(
+    M::AbstractManifold,
+    b::BezierSegment,
+    T::AbstractVector,
+    X::BezierSegment,
+)
+differential_Bezier_control_points!(
+    M::AbstractManifold,
+    Y,
+    b::BezierSegment,
+    T::AbstractVector,
+    X::BezierSegment,
+)

evaluate the differential of the Bézier curve with respect to its control points b and tangent vectors X in the tangent spaces of the control points. The result is the “change” of the curve at the points T, elementwise in $t∈[0,1]$. The computation can be done in place of Y.

See de_Casteljau for more details on the curve.

source
ManoptExamples.differential_Bezier_control_pointsMethod
differential_Bezier_control_points(M::AbstractManifold, b::BezierSegment, t::Float, X::BezierSegment)
+differential_Bezier_control_points!(
+    M::AbstractManifold,
+    Y,
+    b::BezierSegment,
+    t,
+    X::BezierSegment
+)

evaluate the differential of the Bézier curve with respect to its control points b and tangent vectors X given in the tangent spaces of the control points. The result is the “change” of the curve at t$∈[0,1]$. The computation can be done in place of Y.

See de_Casteljau for more details on the curve.

source
ManoptExamples.get_Bezier_degreeMethod
get_Bezier_degree(M::AbstractManifold, b::BezierSegment)

return the degree of the Bézier curve represented by the tuple b of control points on the manifold M, i.e. the number of points minus 1.

source
ManoptExamples.get_Bezier_degreesMethod
get_Bezier_degrees(M::AbstractManifold, B::AbstractVector{<:BezierSegment})

return the degrees of the components of a composite Bézier curve represented by tuples in B containing points on the manifold M.

source
ManoptExamples.get_Bezier_inner_pointsMethod
get_Bezier_inner_points(M::AbstractManifold, B::AbstractVector{<:BezierSegment} )
+get_Bezier_inner_points(M::AbstractManifold, b::BezierSegment)

returns the inner (i.e. despite start and end) points of the segments of the composite Bézier curve specified by the control points B. For a single segment b, its inner points are returned

source
ManoptExamples.get_Bezier_junction_tangent_vectorsMethod
get_Bezier_junction_tangent_vectors(M::AbstractManifold, B::AbstractVector{<:BezierSegment})
+get_Bezier_junction_tangent_vectors(M::AbstractManifold, b::BezierSegment)

returns the tangent vectors at start and end points of the composite Bézier curve pointing from a junction point to the first and last inner control points for each segment of the composite Bezier curve specified by the control points B, either a vector of segments of controlpoints.

source
ManoptExamples.get_Bezier_junctionsFunction
get_Bezier_junctions(M::AbstractManifold, B::AbstractVector{<:BezierSegment})
+get_Bezier_junctions(M::AbstractManifold, b::BezierSegment)

returns the start and end point(s) of the segments of the composite Bézier curve specified by the control points B. For just one segment b, its start and end points are returned.

source
ManoptExamples.get_Bezier_pointsFunction
get_Bezier_points(
+    M::AbstractManifold,
+    B::AbstractVector{<:BezierSegment},
+    reduce::Symbol=:default
+)
+get_Bezier_points(M::AbstractManifold, b::BezierSegment, reduce::Symbol=:default)

returns the control points of the segments of the composite Bézier curve specified by the control points B, either a vector of segments of controlpoints or a.

This method reduces the points depending on the optional reduce symbol

  • :default: no reduction is performed
  • :continuous: for a continuous function, the junction points are doubled at $b_{0,i}=b_{n_{i-1},i-1}$, so only $b_{0,i}$ is in the vector.
  • :differentiable: for a differentiable function additionally $\log_{b_{0,i}}b_{1,i} = -\log_{b_{n_{i-1},i-1}}b_{n_{i-1}-1,i-1}$ holds. hence $b_{n_{i-1}-1,i-1}$ is omitted.

If only one segment is given, all points of b, b.pts, is returned.

source
ManoptExamples.get_Bezier_segmentsMethod
get_Bezier_segments(M::AbstractManifold, c::AbstractArray{P}, d[, s::Symbol=:default])

returns the array of BezierSegments B of a composite Bézier curve reconstructed from an array c of points on the manifold M and an array of degrees d.

There are a few (reduced) representations that can get extended; see also get_Bezier_points. For ease of the following, let $c=(c_1,…,c_k)$ and $d=(d_1,…,d_m)$, where $m$ denotes the number of components the composite Bézier curve consists of. Then

  • :default: $k = m + \sum_{i=1}^m d_i$ since each component requires one point more than its degree. The points are then ordered in tuples, i.e.

    \[B = \bigl[ [c_1,…,c_{d_1+1}], (c_{d_1+2},…,c_{d_1+d_2+2}],…, [c_{k-m+1+d_m},…,c_{k}] \bigr]\]

  • :continuous: $k = 1+ \sum_{i=1}{m} d_i$, since for a continuous curve start and end point of successive components are the same, so the very first start point and the end points are stored.

    \[B = \bigl[ [c_1,…,c_{d_1+1}], [c_{d_1+1},…,c_{d_1+d_2+1}],…, [c_{k-1+d_m},…,b_{k}) \bigr]\]

  • :differentiable – for a differentiable function additionally to the last explanation, also the second point of any segment was not stored except for the first segment. Hence $k = 2 - m + \sum_{i=1}{m} d_i$ and at a junction point $b_n$ with its given prior point $c_{n-1}$, i.e. this is the last inner point of a segment, the first inner point in the next segment the junction is computed as $b = \exp_{c_n}(-\log_{c_n} c_{n-1})$ such that the assumed differentiability holds
source
ManoptExamples.grad_L2_acceleration_BezierMethod
grad_L2_acceleration_Bezier(
+    M::AbstractManifold,
+    B::AbstractVector{P},
+    degrees::AbstractVector{<:Integer},
+    T::AbstractVector,
+    λ,
+    d::AbstractVector{P}
+) where {P}

compute the gradient of the discretized acceleration of a composite Bézier curve on the Manifold M with respect to its control points B together with a data term that relates the junction points p_i to the data d with a weight $λ$ compared to the acceleration. The curve is evaluated at the points given in pts (elementwise in $[0,N]$), where $N$ is the number of segments of the Bézier curve. The summands are grad_distance for the data term and grad_acceleration_Bezier for the acceleration with interpolation constrains. Here the get_Bezier_junctions are included in the optimization, i.e. setting $λ=0$ yields the unconstrained acceleration minimization. Note that this is ill-posed, since any Bézier curve identical to a geodesic is a minimizer.

Note that the Bézier-curve is given in reduces form as a point on a PowerManifold, together with the degrees of the segments and assuming a differentiable curve, the segments can internally be reconstructed.

See also

grad_acceleration_Bezier, L2_acceleration_Bezier, acceleration_Bezier.

source
ManoptExamples.grad_acceleration_BezierMethod
grad_acceleration_Bezier(
+    M::AbstractManifold,
+    B::AbstractVector,
+    degrees::AbstractVector{<:Integer}
+    T::AbstractVector
+)

compute the gradient of the discretized acceleration of a (composite) Bézier curve $c_B(t)$ on the Manifold M with respect to its control points B given as a point on the PowerManifold assuming C1 conditions and known degrees. The curve is evaluated at the points given in T (elementwise in $[0,N]$, where $N$ is the number of segments of the Bézier curve). The get_Bezier_junctions are fixed for this gradient (interpolation constraint). For the unconstrained gradient, see grad_L2_acceleration_Bezier and set $λ=0$ therein. This gradient is computed using adjoint_Jacobi_fields. For details, see Bergmann, Gousenbourger, Front. Appl. Math. Stat., 2018. See de_Casteljau for more details on the curve.

See also

acceleration_Bezier, grad_L2_acceleration_Bezier, L2_acceleration_Bezier.

source

Riemannian Mean

See the Riemannian mean example to see these in use.

ManoptExamples.RiemannianMeanCostType
RiemannianMeanCost{P}

A functor representing the Riemannian center of mass (or Riemannian mean) cost function.

For a given set of points $d_1,\ldots,d_N$ this cost function is defined as

\[f(p) = \sum_{j=i}^N d_{mathcal M}^2(d_i, p),\]

where $d_{\mathcal M}$ is the distance on a Riemannian manifold.

Constructor

RiemannianMeanCost(M::AbstractManifold, data::AbstractVector{<:P}) where {P}

Initialize the cost function to a data set data of points on a manfiold M, where each point is of type P.

See also

RiemannianMeanGradient!!, Riemannian_mean_objective

source
ManoptExamples.RiemannianMeanGradient!!Type
RiemannianMeanGradient!!{P} where P

A functor representing the Riemannian center of mass (or Riemannian mean) cost function.

For a given set of points $d_1,\ldots,d_N$ this cost function is defined as

\[\operatorname{grad}f(p) = \sum_{j=i}^N \log_p d_i\]

where $d_{\mathcal M}$ is the distance on a Riemannian manifold and we employ grad_distance to compute the single summands.

This functor provides both the allocating variant grad_f(M,p) as well as the in-place variant grad_f!(M, X, p) which computes the gradient in-place of X.

Constructors

RiemannianMeanGradient!!(data::AbstractVector{P}, initial_vector::T=nothing) where {P,T}

Generate the Riemannian mean gradient based on some data points data an intial tangent vector initial_vector. If you do not provide an initial tangent vector to allocate the intermediate storage of a tangent vector, you can only use the allocating variant.

RiemannianMeanGradient!!(
+    M::AbstractManifold,
+    data::AbstractVector{P};
+    initial_vector::T=zero_vector(M, first(data)),
+) where {P,T}

Initialize the Riemannian mean gradient, where the internal storage for tangent vectors can be created automatically, since the Riemannian manifold M is provideed.

See also

RiemannianMeanCost, Riemannian_mean_objective

source
ManoptExamples.Riemannian_mean_objectiveFunction
Riemannian_mean_objective(data, initial_vector=nothing, evaluation=Manopt.AllocatingEvaluation())
+Riemannian_mean_objective(M, data;
+initial_vector=zero_vector(M, first(data)),
+evaluation=AllocatingEvaluton()
+)

Generate the objective for the Riemannian mean task for some given vector of data points on the Riemannian manifold M.

See also

RiemannianMeanCost, RiemannianMeanGradient!!

Note

The first constructor should only be used if an additional storage of the vector is not feasible, since initialising the initial_vector to nothing disables the in-place variant. Hence the evaluation is a positional argument, since it only can be changed, if a vector is provided.

Note

The objective is available when Manopt.jl is loaded.

source

Robust PCA

See the Robust PCA example to see these in use.

ManoptExamples.RobustPCACostType
RobustPCACost{D,F}

A functor representing the Riemannian robust PCA function on the Grassmann manifold. For some given (column) data $D∈\mathbb R^{d\times n}$ the cost function is defined on some $\operatorname{Gr}(d,m)$, $m<n$ as the sum of the distances of the columns $D_i$ to the subspace spanned by $p\in\operatorname{Gr}(d,m)$ (represented as a point on the Stiefel manifold). The function reads

\[f(U) = \frac{1}{n}\sum_{i=1}^n \lVert pp^{\mathrm{T}}D_i - D_i\rVert\]

This cost additionally provides a Huber regularisation of the cost, that is for some $ε>0$ one use $ℓ_ε(x) = \sqrt{x^2+ε^2} - ε$ in

\[f_{ε}(p) = \frac{1}{n}\sum_{i=1}^n ℓ_ε\bigl(\lVert pp^{\mathrm{T}}D_i - D_i\rVert\bigr)\]

Note that this is a mutable struct so you can adapt the $ε$ later on.

Constructor

RobustPCACost(data::AbstractMatrix, ε=1.0)
+RobustPCACost(M::Grassmann, data::AbstractMatrix, ε=1.0)

Initialize the robust PCA cost to some data $D$, and some regularization $ε$. The manifold is optional to comply with all examples, but it is not needed here to construct the cost.

source
ManoptExamples.RobustPCAGrad!!Type
RobustPCAGrad!!{D,F}

A functor representing the Riemannian robust PCA gradient on the Grassmann manifold. For some given (column) data $X∈\mathbb R^{p\times n}$ the gradient of the RobustPCACost can be computed by projecting the Euclidean gradient onto the corresponding tangent space.

Note that this is a mutable struct so you can adapt the $ε$ later on.

Constructor

RobustPCAGrad!!(data, ε=1.0)
+RobustPCAGrad!!(M::Grassmannian{d,m}, data, ε=1.0; evaluation=AllocatingEvaluation())

Initialize the robust PCA cost to some data $D$, and some regularization $ε$. The manifold is optional to comply with all examples, but it is not needed here to construct the cost. Also the evaluation= keyword is present only for unification of the interfaces. Indeed, independent of that keyword the functor always works in both variants.

source
ManoptExamples.robust_PCA_objectiveFunction
robust_PCA_objective(data::AbstractMatrix, ε=1.0; evaluation=AllocatingEvaluation())
+robust_PCA_objective(M, data::AbstractMatrix, ε=1.0; evaluation=AllocatingEvaluton())

Generate the objective for the robust PCA task for some given data $D$ and Huber regularization parameter $ε$.

See also

RobustPCACost, RobustPCAGrad!!

Note

Since the construction is independent of the manifold, that argument is optional and mainly provided to comply with other objectives. Similarly, independent of the evaluation, indeed the gradient always allows for both the allocating and the in-place variant to be used, though that keyword is used to setup the objective.

Note

The objective is available when Manopt.jl is loaded.

source

Rosenbrock Function

See the Rosenbrock example and The Difference of Convex Rosenbrock Example to see these in use.

ManoptExamples.RosenbrockCostType
RosenbrockCost

Provide the Rosenbrock function in 2D, i.e. for some $a,b ∈ ℝ$

\[f(\mathcal M, p) = a(p_1^2-p_2)^2 + (p_1-b)^2\]

which means that for the 2D case, the manifold $\mathcal M$ is ignored.

See also 📖 Rosenbrock (with slightly different parameter naming).

Constructor

f = Rosenbrock(a,b)

generates the struct/function of the Rosenbrock cost.

source
ManoptExamples.RosenbrockGradient!!Type
RosenbrockGradient

Provide Eclidean GRadient fo the Rosenbrock function in 2D, i.e. for some $a,b ∈ ℝ$

\[\nabla f(\mathcal M, p) = \begin{pmatrix} + 4a(p_1^2-p_2)p_1 + 2(p_1-b) \\ + -2a(p_1^2-p_2) +\end{pmatrix}\]

i.e. also here the manifold is ignored.

Constructor

RosenbrockGradient(a,b)

Functors

grad_f!!(M,p)
+grad_f!!(M, X, p)

evaluate the gradient at $p$ the manifold$\mathcal M$ is ignored.

source
ManoptExamples.RosenbrockMetricType
RosenbrockMetric <: AbstractMetric

A metric related to the Rosenbrock problem, where the metric at a point $p∈\mathbb R^2$ is given by

\[⟨X,Y⟩_{\mathrm{Rb},p} = X^\mathrm{T}G_pY, \qquad +G_p = \begin{pmatrix} + 1+4p_{1}^2 & -2p_{1} \\ + -2p_{1} & 1 +\end{pmatrix},\]

where the $\mathrm{Rb}$ stands for Rosenbrock

source
Base.expMethod
q = exp(::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, p, X)
+exp!(::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, q, p, X)

Compute the exponential map with respect to the RosenbrockMetric.

\[ q = \begin{pmatrix} p_1 + X_1 \\ p_2+X_2+X_1^2\end{pmatrix}\]

source
Base.logMethod
X = log(::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, p, q)
+log!(::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, X, p, q)

Compute the logarithmic map with respect to the RosenbrockMetric. The formula reads for any $j ∈ \{1,…,m\}$

\[X = \begin{pmatrix} + q_1 - p_1 \\ + q_2 - p_2 + (q_1 - p_1)^2 +\end{pmatrix}\]

source
Manifolds.inverse_local_metricMethod
inverse_local_metric(::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, p)

Return the inverse of the local metric matrix of the RosenbrockMetric in the canonical unit vector basis of the tangent space $T_p\mathbb R^2$ given as

\[G^{-1}_p = +\begin{pmatrix} + 1 & 2p_1\\ + 2p_1 & 1+4p_1^2 \\ +\end{pmatrix}.\]

source
Manifolds.local_metricMethod
local_metric(::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, p)

Return the local metric matrix of the RosenbrockMetric in the canonical unit vector basis of the tangent space $T_p\mathbb R^2$ given as

\[G_p = \begin{pmatrix} + 1+4p_1^2 & -2p_1 \\ + -2p_1 & 1 +\end{pmatrix}\]

source
ManifoldsBase.change_representerMethod
Y = change_representer(M::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, ::EuclideanMetric, p, X)
+change_representer!(M::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, Y, ::EuclideanMetric, p, X)

Given the Euclidan gradient X at p, this function computes the corresponting Riesz representer Ysuch that⟨X,Z⟩ = ⟨ Y, Z ⟩_{\mathrm{Rb},p}holds for allZ, in other wordsY = G(p)^{-1}X`.

this function is used in riemannian_gradient to convert a Euclidean into a Riemannian gradient.

source
ManifoldsBase.innerMethod
inner(M::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, p, X, Y)

Compute the inner product on $\mathbb R^2$ with respect to the RosenbrockMetric, i.e. for $X,Y \in T_p\mathcal M$ we have

\[⟨X,Y⟩_{\mathrm{Rb},p} = X^\mathrm{T}G_pY, \qquad +G_p = \begin{pmatrix} + 1+4p_1^2 & -2p_1\\ + -2p_1 & 1 +\end{pmatrix},\]

source

Total Variation

See the Total Variation example to see these in use.

ManoptExamples.Intrinsic_infimal_convolution_TV12Method
Intrinsic_infimal_convolution_TV12(M, f, u, v, α, β)

Compute the intrinsic infimal convolution model, where the addition is replaced by a mid point approach and the two functions involved are second_order_Total_Variation and Total_Variation. The model reads

\[E(u,v) = + \frac{1}{2}\sum_{i ∈ \mathcal G} + d_{\mathcal M}\bigl(g(\frac{1}{2},v_i,w_i),f_i\bigr) + +\alpha\bigl( β\mathrm{TV}(v) + (1-β)\mathrm{TV}_2(w) \bigr).\]

for more details see [BFPS17, BFPS18].

See also

Total_Variation, second_order_Total_Variation

source
ManoptExamples.Total_VariationFunction
Total_Variation(M,x [,p=2,q=1])

Compute the $\operatorname{TV}^p$ functional for data xon the PowerManifold manifold M, i.e. $\mathcal M = \mathcal N^n$, where $n ∈ \mathbb N^k$ denotes the dimensions of the data x. Let $\mathcal I_i$ denote the forward neighbors, i.e. with $\mathcal G$ as all indices from $\mathbf{1} ∈ \mathbb N^k$ to $n$ we have $\mathcal I_i = \{i+e_j, j=1,…,k\}\cap \mathcal G$. The formula reads

\[E^q(x) = \sum_{i ∈ \mathcal G} + \bigl( \sum_{j ∈ \mathcal I_i} d^p_{\mathcal M}(x_i,x_j) \bigr)^{q/p},\]

see [WDS14] for more details. In long function names, this might be shortened to TV1 and the 1 might be ommitted if only total variation is present.

See also

grad_Total_Variation, prox_Total_Variation, second_order_Total_Variation

source
ManoptExamples.adjoint_differential_forward_logsMethod
Y = adjoint_differential_forward_logs(M, p, X)
+adjoint_differential_forward_logs!(M, Y, p, X)

Compute the adjoint differential of forward_logs $F$ occurring, in the power manifold array p, the differential of the function

$F_i(p) = \sum_{j ∈ \mathcal I_i} \log_{p_i} p_j$

where $i$ runs over all indices of the PowerManifold manifold M and $\mathcal I_i$ denotes the forward neighbors of $i$ Let $n$ be the number dimensions of the PowerManifold manifold (i.e. length(size(x))). Then the input tangent vector lies on the manifold $\mathcal M' = \mathcal M^n$. The adjoint differential can be computed in place of Y.

Input

  • M – a PowerManifold manifold
  • p – an array of points on a manifold
  • X – a tangent vector to from the n-fold power of p, where n is the ndims of p

Output

Y – resulting tangent vector in $T_p\mathcal M$ representing the adjoint differentials of the logs.

source
ManoptExamples.differential_forward_logsMethod
Y = differential_forward_logs(M, p, X)
+differential_forward_logs!(M, Y, p, X)

compute the differential of forward_logs $F$ on the PowerManifold manifold M at p and direction X , in the power manifold array, the differential of the function

\[F_i(x) = \sum_{j ∈ \mathcal I_i} \log_{p_i} p_j, \quad i ∈ \mathcal G,\]

where $\mathcal G$ is the set of indices of the PowerManifold manifold M and $\mathcal I_i$ denotes the forward neighbors of $i$.

Input

  • M – a PowerManifold manifold
  • p – a point.
  • X – a tangent vector.

Output

  • Y – resulting tangent vector in $T_x\mathcal N$ representing the differentials of the logs, where $\mathcal N$ is the power manifold with the number of dimensions added to size(x). The computation can also be done in place.
source
ManoptExamples.forward_logsMethod
Y = forward_logs(M,x)
+forward_logs!(M, Y, x)

compute the forward logs $F$ (generalizing forward differences) occurring, in the power manifold array, the function

\[F_i(x) = \sum_{j ∈ \mathcal I_i} \log_{x_i} x_j,\quad i ∈ \mathcal G,\]

where $\mathcal G$ is the set of indices of the PowerManifold manifold M and $\mathcal I_i$ denotes the forward neighbors of $i$. This can also be done in place of ξ.

Input

  • M – a PowerManifold manifold
  • x – a point.

Output

  • Y – resulting tangent vector in $T_x\mathcal M$ representing the logs, where $\mathcal N$ is the power manifold with the number of dimensions added to size(x). The computation can be done in place of Y.
source
ManoptExamples.grad_Total_VariationFunction
X = grad_Total_Variation(M, λ, x[, p=1])
+grad_Total_Variation!(M, X, λ, x[, p=1])

Compute the (sub)gradient $∂f$ of all forward differences occurring, in the power manifold array, i.e. of the function

\[f(p) = \sum_{i}\sum_{j ∈ \mathcal I_i} d^p(x_i,x_j)\]

where $i$ runs over all indices of the PowerManifold manifold M and $\mathcal I_i$ denotes the forward neighbors of $i$.

Input

  • M – a PowerManifold manifold
  • x – a point.

Output

  • X – resulting tangent vector in $T_x\mathcal M$. The computation can also be done in place.
source
ManoptExamples.grad_Total_VariationMethod
X = grad_Total_Variation(M, (x,y)[, p=1])
+grad_Total_Variation!(M, X, (x,y)[, p=1])

compute the (sub) gradient of $\frac{1}{p}d^p_{\mathcal M}(x,y)$ with respect to both $x$ and $y$ (in place of X and Y).

source
ManoptExamples.grad_intrinsic_infimal_convolution_TV12Method
grad_u, grad_v = grad_intrinsic_infimal_convolution_TV12(M, f, u, v, α, β)

compute (sub)gradient of the intrinsic infimal convolution model using the mid point model of second order differences, see second_order_Total_Variation, i.e. for some $f ∈ \mathcal M$ on a PowerManifold manifold $\mathcal M$ this function computes the (sub)gradient of

\[E(u,v) = +\frac{1}{2}\sum_{i ∈ \mathcal G} d_{\mathcal M}(g(\frac{1}{2},v_i,w_i),f_i) ++ \alpha +\bigl( +β\mathrm{TV}(v) + (1-β)\mathrm{TV}_2(w) +\bigr),\]

where both total variations refer to the intrinsic ones, grad_Total_Variation and grad_second_order_Total_Variation, respectively.

source
ManoptExamples.grad_second_order_Total_VariationFunction
Y = grad_second_order_Total_Variation(M, q[, p=1])
+grad_second_order_Total_Variation!(M, Y, q[, p=1])

computes the (sub) gradient of $\frac{1}{p}d_2^p(q_1, q_2, q_3)$ with respect to all three components of $q∈\mathcal M^3$, where $d_2$ denotes the second order absolute difference using the mid point model, i.e. let

\[\mathcal C = \bigl\{ c ∈ \mathcal M \ |\ g(\tfrac{1}{2};q_1,q_3) \text{ for some geodesic }g\bigr\}\]

denote the mid points between $q_1$ and $q_3$ on the manifold $\mathcal M$. Then the absolute second order difference is defined as

\[d_2(q_1,q_2,q_3) = \min_{c ∈ \mathcal C_{q_1,q_3}} d(c, q_2).\]

While the (sub)gradient with respect to $q_2$ is easy, the other two require the evaluation of an adjoint_Jacobi_field.

The derivation of this gradient can be found in [BBSW16].

source
ManoptExamples.grad_second_order_Total_VariationFunction
grad_second_order_Total_Variation(M::PowerManifold, q[, p=1])

computes the (sub) gradient of $\frac{1}{p}d_2^p(q_1,q_2,q_3)$ with respect to all $q_1,q_2,q_3$ occurring along any array dimension in the point q, where M is the corresponding PowerManifold.

source
ManoptExamples.project_collaborative_TVFunction
project_collaborative_TV(M, λ, x, Ξ[, p=2,q=1])
+project_collaborative_TV!(M, Θ, λ, x, Ξ[, p=2,q=1])

compute the projection onto collaborative Norm unit (or α-) ball, i.e. of the function

\[F^q(x) = \sum_{i∈\mathcal G} + \Bigl( \sum_{j∈\mathcal I_i} + \sum_{k=1}^d \lVert X_{i,j}\rVert_x^p\Bigr)^\frac{q}{p},\]

where $\mathcal G$ is the set of indices for $x∈\mathcal M$ and $\mathcal I_i$ is the set of its forward neighbors. The computation can also be done in place of Θ.

This is adopted from the paper Duran, Möller, Sbert, Cremers, SIAM J Imag Sci, 2016, see their Example 3 for details.

source
ManoptExamples.prox_Total_VariationFunction
ξ = prox_Total_Variation(M,λ,x [,p=1])

compute the proximal maps $\operatorname{prox}_{λ\varphi}$ of all forward differences occurring in the power manifold array, i.e. $\varphi(xi,xj) = d_{\mathcal M}^p(xi,xj)$ with xi and xj are array elements of x and j = i+e_k, where e_k is the $k$th unit vector. The parameter λ is the prox parameter.

Input

  • M – a manifold M
  • λ – a real value, parameter of the proximal map
  • x – a point.

Optional

(default is given in brackets)

  • p – (1) exponent of the distance of the TV term

Output

  • y – resulting point containing with all mentioned proximal points evaluated (in a cyclic order). The computation can also be done in place
source
ManoptExamples.prox_Total_VariationMethod
[y1,y2] = prox_Total_Variation(M, λ, [x1,x2] [,p=1])
+prox_Total_Variation!(M, [y1,y2] λ, [x1,x2] [,p=1])

Compute the proximal map $\operatorname{prox}_{λ\varphi}$ of $φ(x,y) = d_{\mathcal M}^p(x,y)$ with parameter λ. A derivation of this closed form solution is given in see [WDS14].

Input

  • M – a manifold M
  • λ – a real value, parameter of the proximal map
  • (x1,x2) – a tuple of two points,

Optional

(default is given in brackets)

  • p – (1) exponent of the distance of the TV term

Output

  • (y1,y2) – resulting tuple of points of the $\operatorname{prox}_{λφ}($(x1,x2)$)$. The result can also be computed in place.
source
ManoptExamples.prox_parallel_TVFunction
y = prox_parallel_TV(M, λ, x [,p=1])
+prox_parallel_TV!(M, y, λ, x [,p=1])

compute the proximal maps $\operatorname{prox}_{λφ}$ of all forward differences occurring in the power manifold array, i.e. $φ(x_i,x_j) = d_{\mathcal M}^p(x_i,x_j)$ with xi and xj are array elements of x and j = i+e_k, where e_k is the $k$th unit vector. The parameter λ is the prox parameter.

Input

  • M – a PowerManifold manifold
  • λ – a real value, parameter of the proximal map
  • x – a point

Optional

(default is given in brackets)

  • p – (1) exponent of the distance of the TV term

Output

  • y – resulting Array of points with all mentioned proximal points evaluated (in a parallel within the arrays elements). The computation can also be done in place.

See also prox_Total_Variation

source
ManoptExamples.prox_second_order_Total_VariationFunction
(y1,y2,y3) = prox_second_order_Total_Variation(M,λ,(x1,x2,x3),[p=1], kwargs...)
+prox_second_order_Total_Variation!(M, y, λ,(x1,x2,x3),[p=1], kwargs...)

Compute the proximal map $\operatorname{prox}_{λ\varphi}$ of $\varphi(x_1,x_2,x_3) = d_{\mathcal M}^p(c(x_1,x_3),x_2)$ with parameter λ>0, where $c(x,z)$ denotes the mid point of a shortest geodesic from x1 to x3 that is closest to x2. The result can be computed in place of y.

Note that this function does not have a closed form solution but is solbed by a few steps of the subgradient mehtod from manopt.jl by default. See [BBSW16] for a derivation.

Input

  • M – a manifold

  • λ – a real value, parameter of the proximal map

  • (x1,x2,x3) – a tuple of three points

  • p – (1) exponent of the distance of the TV term

Optional

kwargs... – parameters for the internal subgradient_method (if M is neither Euclidean nor Circle, since for these a closed form is given)

Output

  • (y1,y2,y3) – resulting tuple of points of the proximal map. The computation can also be done in place.

    Note

    This function requires Manopt.jl to be loaded

source
ManoptExamples.prox_second_order_Total_VariationMethod
y = prox_second_order_Total_Variation(M, λ, x[, p=1])
+prox_second_order_Total_Variation!(M, y, λ, x[, p=1])

compute the proximal maps $\operatorname{prox}_{λ\varphi}$ of all centered second order differences occurring in the power manifold array, i.e. $\varphi(x_k,x_i,x_j) = d_2(x_k,x_i.x_j)$, where $k,j$ are backward and forward neighbors (along any dimension in the array of x). The parameter λ is the prox parameter.

Input

  • M – a manifold M
  • λ – a real value, parameter of the proximal map
  • x – a points.

Optional

(default is given in brackets)

  • p – (1) exponent of the distance of the TV term

Output

  • y – resulting point with all mentioned proximal points evaluated (in a cyclic order). The computation can also be done in place.
Note

This function requires Manopt.jl to be loaded

source
ManoptExamples.second_order_Total_VariationFunction
second_order_Total_Variation(M,x [,p=1])

compute the $\operatorname{TV}_2^p$ functional for data x on the PowerManifold manifoldmanifold M, i.e. $\mathcal M = \mathcal N^n$, where $n ∈ \mathbb N^k$ denotes the dimensions of the data x. Let $\mathcal I_i^{\pm}$ denote the forward and backward neighbors, respectively, i.e. with $\mathcal G$ as all indices from $\mathbf{1} ∈ \mathbb N^k$ to $n$ we have $\mathcal I^\pm_i = \{i\pm e_j, j=1,…,k\}\cap \mathcal I$. The formula then reads

\[E(x) = \sum_{i ∈ \mathcal I,\ j_1 ∈ \mathcal I^+_i,\ j_2 ∈ \mathcal I^-_i} +d^p_{\mathcal M}(c_i(x_{j_1},x_{j_2}), x_i),\]

where $c_i(⋅,⋅)$ denotes the mid point between its two arguments that is nearest to $x_i$, see [BBSW16] for a derivation.

In long function names, this might be shortened to TV2.

See also

grad_second_order_Total_Variation, prox_second_order_Total_Variation

source
ManoptExamples.second_order_Total_VariationMethod
second_order_Total_Variation(M,(x1,x2,x3) [,p=1])

Compute the $\operatorname{TV}_2^p$ functional for the 3-tuple of points (x1,x2,x3)on the manifold M. Denote by

\[ \mathcal C = \bigl\{ c ∈ \mathcal M \ |\ g(\tfrac{1}{2};x_1,x_3) \text{ for some geodesic }g\bigr\}\]

the set of mid points between $x_1$ and $x_3$. Then the function reads

\[d_2^p(x_1,x_2,x_3) = \min_{c ∈ \mathcal C} d_{\mathcal M}(c,x_2),\]

see [BBSW16] for a derivation. In long function names, this might be shortened to TV2.

See also

grad_second_order_Total_Variation, prox_second_order_Total_Variation, Total_Variation

source

Literature

[BBSW16]
M. Bačák, R. Bergmann, G. Steidl and A. Weinmann. A second order non-smooth variational model for restoring manifold-valued images. SIAM Journal on Scientific Computing 38, A567–A597 (2016), arXiv:1506.02409.
[BFPS18]
R. Bergmann, J. H. Fitschen, J. Persch and G. Steidl. Priors with coupled first and second order differences for manifold-valued image processing. Journal of Mathematical Imaging and Vision 60, 1459–1481 (2018), arXiv:1709.01343.
[BFPS17]
R. Bergmann, J. H. Fitschen, J. Persch and G. Steidl. Infimal convolution coupling of first and second order differences on manifold-valued images. In: Scale Space and Variational Methods in Computer Vision: 6th International Conference, SSVM 2017, Kolding, Denmark, June 4–8, 2017, Proceedings, edited by F. Lauze, Y. Dong and A. B. Dahl (Springer International Publishing, 2017); pp. 447–459.
[BG18]
R. Bergmann and P.-Y. Gousenbourger. A variational model for data fitting on manifolds by minimizing the acceleration of a Bézier curve. Frontiers in Applied Mathematics and Statistics 4 (2018), arXiv:1807.10090.
[Bou23]
[Cas59]
P. de Casteljau. Outillage methodes calcul (Enveloppe Soleau 40.040, Institute National de la Propriété Industrielle, Paris., 1959).
[Cas63]
P. de Casteljau. Courbes et surfaces à pôles (Microfiche P 4147-1, Institute National de la Propriété Industrielle, Paris., 1963).
[DMSC16]
J. Duran, M. Moeller, C. Sbert and D. Cremers. Collaborative Total Variation: A General Framework for Vectorial TV Models. SIAM Journal on Imaging Sciences 9, 116–151 (2016), arXiv:1508.01308.
[PN07]
T. Popiel and L. Noakes. Bézier curves and $C^2$ interpolation in Riemannian manifolds. Journal of Approximation Theory 148, 111–127 (2007).
[WDS14]
A. Weinmann, L. Demaret and M. Storath. Total variation regularization for manifold-valued data. SIAM Journal on Imaging Sciences 7, 2226–2257 (2014).
diff --git a/v0.1.8/objects.inv b/v0.1.8/objects.inv new file mode 100644 index 0000000..4db8038 Binary files /dev/null and b/v0.1.8/objects.inv differ diff --git a/v0.1.8/references.bib b/v0.1.8/references.bib new file mode 100644 index 0000000..d844eb9 --- /dev/null +++ b/v0.1.8/references.bib @@ -0,0 +1,235 @@ +% +% --- A +% +@inproceedings{AkibaSanoYanaseToshihikoTakeruKoyama:2019, + title={Optuna: A Next-generation Hyperparameter Optimization Framework}, + author={Akiba, Takuya and Sano, Shotaro and Yanase, Toshihiko and Ohta, Takeru and Koyama, Masanori}, + booktitle={Proceedings of the 25th {ACM} {SIGKDD} International Conference on Knowledge Discovery and Data Mining}, + year={2019}, + doi={10.1145/3292500.3330701}, + eprint = {1907.10902}, + eprinttype = {arXiv} +} +@article{AxenBaranBergmannRzecki:2023, + AUTHOR = {Axen, Seth D. and Baran, Mateusz and Bergmann, Ronny and Rzecki, Krzysztof}, + DOI = {10.1145/3618296}, + EPRINT = {2021.08777}, + EPRINTTYPE = {arXiv}, + ISSN = {1557-7295}, + JOURNAL = {ACM Transactions on Mathematical Software}, + TITLE = {Manifolds.jl: An Extensible Julia Framework for Data Analysis on Manifolds}, + YEAR = {2023} +} + +% +% --- B +% +@article{Bacak:2014, + AUTHOR = {Bačák, M.}, + DOI = {10.1137/140953393}, + EPRINT = {1210.2145}, + EPRINTTYPE = {arXiv}, + JOURNAL = {SIAM Journal on Optimization}, + NUMBER = {3}, + PAGES = {1542--1566}, + TITLE = {Computing medians and means in Hadamard spaces}, + VOLUME = {24}, + YEAR = {2014} +} + +@article{BacakBergmannSteidlWeinmann:2016, + AUTHOR = {Bačák, Miroslav and Bergmann, Ronny and Steidl, Gabriele and Weinmann, Andreas}, + EPRINT = {1506.02409}, + EPRINTTYPE = {arXiv}, + YEAR = {2016}, + DOI = {10.1137/15M101988X}, + JOURNAL = {SIAM Journal on Scientific Computing}, + NUMBER = {1}, + PAGES = {A567--A597}, + TITLE = {A second order non-smooth variational model for restoring manifold-valued images}, + VOLUME = {38}, +} + +@article{BergmannFerreiraSantosSouza:2023, + AUTHOR = {Bergmann, R. and Ferreira, O. P. and Santos, E. M. and Souza, J. C. O.}, + EPRINT = {2112.05250}, + EPRINTTYPE = {arXiv}, + JOURNAL = {Preprint}, + TITLE = {The difference of convex algorithm on Hadamard manifolds}, + YEAR = {2023} +} + +@incollection{BergmannFitschenPerschSteidl:2017, + AUTHOR = {Bergmann, Ronny and Fitschen, Jan Henrik and Persch, Johannes and Steidl, Gabriele}, + EDITOR = {Lauze, François and Dong, Yiqiu and Dahl, Anders Bjorholm}, + LOCATION = {Cham}, + PUBLISHER = {Springer International Publishing}, + BOOKTITLE = {Scale Space and Variational Methods in Computer Vision: 6th International Conference, SSVM 2017, Kolding, Denmark, June 4--8, 2017, Proceedings}, + YEAR = {2017}, + DOI = {10.1007/978-3-319-58771-4_36}, + PAGES = {447--459}, + TITLE = {Infimal convolution coupling of first and second order differences on manifold-valued images} +} + +@article{BergmannFitschenPerschSteidl:2018, + AUTHOR = {Bergmann, Ronny and Fitschen, Jan Henrik and Persch, Johannes and Steidl, Gabriele}, + YEAR = {2018}, + DOI = {10.1007/s10851-018-0840-y}, + EPRINT = {1709.01343}, + EPRINTTYPE = {arXiv}, + JOURNAL = {Journal of Mathematical Imaging and Vision}, + NUMBER = {9}, + PAGES = {1459--1481}, + TITLE = {Priors with coupled first and second order differences for manifold-valued image processing}, + VOLUME = {60} +} + +@article{BergmannGousenbourger:2018, + AUTHOR = {Bergmann, Ronny and Gousenbourger, Pierre-Yves}, + DOI = {10.3389/fams.2018.00059}, + EPRINT = {1807.10090}, + EPRINTTYPE = {arXiv}, + JOURNAL = {Frontiers in Applied Mathematics and Statistics}, + TITLE = {A variational model for data fitting on manifolds by minimizing the acceleration of a Bézier curve}, + VOLUME = {4}, + YEAR = {2018} +} + +@article{BergmannLausSteidlWeinmann:2014:1, + AUTHOR = {Bergmann, Ronny and Laus, Friederike and Steidl, Gabriele and Weinmann, Andreas}, + EPRINT = {1405.5349}, + EPRINTTYPE = {arXiv}, + DOI = {10.1137/140969993}, + JOURNAL = {SIAM Journal on Imaging Sciences}, + NUMBER = {4}, + PAGES = {2916--2953}, + TITLE = {Second order differences of cyclic data and applications in variational denoising}, + VOLUME = {7}, + YEAR = {2014} +} + +@article{BergmannPerschSteidl:2016, + AUTHOR = {Bergmann, Ronny and Persch, Johannes and Steidl, Gabriele}, + DOI = {10.1137/15M1052858}, + EPRINT = {1512.02814}, + EPRINTTYPE = {arXiv}, + JOURNAL = {SIAM Journal on Imaging Sciences}, + NUMBER = {4}, + PAGES = {901--937}, + TITLE = {A parallel Douglas Rachford algorithm for minimizing ROF-like functionals on images with values in symmetric Hadamard manifolds}, + VOLUME = {9}, + YEAR = {2016}, +} + +@book{Boumal:2023, + TITLE = {An Introduction to Optimization on Smooth Manifolds}, + AUTHOR = {Boumal, Nicolas}, + YEAR = {2023}, + MONTH = mar, + EDITION = {First}, + PUBLISHER = {Cambridge University Press}, + DOI = {10.1017/9781009166164}, + ABSTRACT = {Optimization on Riemannian manifolds-the result of smooth geometry and optimization merging into one elegant modern framework-spans many areas of science and engineering, including machine learning, computer vision, signal processing, dynamical systems and scientific computing. This text introduces the differential geometry and Riemannian geometry concepts that will help students and researchers in applied mathematics, computer science and engineering gain a firm mathematical grounding to use these tools confidently in their research. Its charts-last approach will prove more intuitive from an optimizer's viewpoint, and all definitions and theorems are motivated to build time-tested optimization algorithms. Starting from first principles, the text goes on to cover current research on topics including worst-case complexity and geodesic convexity. Readers will appreciate the tricks of the trade for conducting research and for numerical implementations sprinkled throughout the book.}, + ISBN = {978-1-00-916616-4}, + URL = {https://www.nicolasboumal.net/#book} +} + +@article{PopielNoakes:2007, + DOI = {10.1016/j.jat.2007.03.002}, + YEAR = {2007}, + MONTH = oct, + PUBLISHER = {Elsevier}, + VOLUME = {148}, + NUMBER = {2}, + PAGES = {111--127}, + AUTHOR = {Tomasz Popiel and Lyle Noakes}, + TITLE = {Bézier curves and $C^2$ interpolation in Riemannian manifolds}, + JOURNAL = {Journal of Approximation Theory} +} + +@techreport{deCasteljau:1959, + AUTHOR = {de Casteljau, Paul}, + INSTITUTION = {Enveloppe Soleau 40.040, Institute National de la Propriété Industrielle, Paris.}, + TITLE = {Outillage methodes calcul}, + YEAR = {1959} +} + +@techreport{deCasteljau:1963, + AUTHOR = {de Casteljau, Paul}, + INSTITUTION = {Microfiche P 4147-1, Institute National de la Propriété Industrielle, Paris.}, + TITLE = {Courbes et surfaces à pôles}, + YEAR = {1963} +} + +@article{DuranMoelleSbertCremers:2016, + AUTHOR = {Duran, J. and Moeller, M. and Sbert, C. and Cremers, D.}, + DOI = {10.1137/15M102873X}, + EPRINT = {1508.01308}, + EPRINTTYPE = {arXiv}, + JOURNAL = {SIAM Journal on Imaging Sciences}, + NUMBER = {1}, + PAGES = {116-151}, + TITLE = {Collaborative Total Variation: A General Framework for Vectorial TV Models}, + VOLUME = {9}, + YEAR = {2016}, +} + +@article{LausNikolovaPerschSteidl:2017, + AUTHOR = {Laus, F. and Nikolova, M. and Persch, J. and Steidl, G.}, + YEAR = {2017}, + DOI = {10.1137/16M1087114}, + JOURNAL = {SIAM Journal on Imaging Sciences}, + NUMBER = {1}, + PAGES = {416--448}, + TITLE = {A nonlocal denoising algorithm for manifold-valued images using second order statistics}, + VOLUME = {10} +} + +@article{RudinOsherFatemi:1992, + AUTHOR = {Rudin, Leonid I. and Osher, Stanley and Fatemi, Emad}, + DOI = {10.1016/0167-2789(92)90242-f}, + ISSN = {0167-2789}, + JOURNAL = {Physica D: Nonlinear Phenomena}, + NUMBER = {1–4}, + PAGES = {259–268}, + TITLE = {Nonlinear total variation based noise removal algorithms}, + VOLUME = {60}, + YEAR = {1992} +} + +@article{SouzaOliveira:2015, + AUTHOR = {J. C. O. Souza and P. R. Oliveira}, + DOI = {10.1007/s10898-015-0282-7}, + JOURNAL = {Journal of Global Optimization}, + MONTH = feb, + NUMBER = {4}, + PAGES = {797--810}, + PUBLISHER = {Springer Science and Business Media LLC}, + VOLUME = {63}, + TITLE = {A proximal point algorithm for DC fuctions on Hadamard manifolds}, + YEAR = {2015} +} + +@article{WeberSra:2022, + DOI = {10.1007/s10107-022-01840-5}, + YEAR = {2022}, + MONTH = jul, + PUBLISHER = {Springer Science and Business Media LLC}, + VOLUME = {199}, + NUMBER = {1-2}, + PAGES = {525--556}, + AUTHOR = {Melanie Weber and Suvrit Sra}, + TITLE = {Riemannian Optimization via Frank-Wolfe Methods}, + JOURNAL = {Mathematical Programming} +} + +@article{WeinmannDemaretStorath:2014, + AUTHOR = {Weinmann, Andreas and Demaret, Laurent and Storath, Martin}, + DOI = {10.1137/130951075}, + JOURNAL = {SIAM Journal on Imaging Sciences}, + NUMBER = {4}, + PAGES = {2226--2257}, + TITLE = {Total variation regularization for manifold-valued data}, + VOLUME = {7}, + YEAR = {2014} +} diff --git a/v0.1.8/references/index.html b/v0.1.8/references/index.html new file mode 100644 index 0000000..87a329a --- /dev/null +++ b/v0.1.8/references/index.html @@ -0,0 +1,2 @@ + +References · ManoptExamples.jl

Literature

[ASY+19]
T. Akiba, S. Sano, T. Yanase, T. Ohta and M. Koyama. Optuna: A Next-generation Hyperparameter Optimization Framework. In: Proceedings of the 25th ACM SIGKDD International Conference on Knowledge Discovery and Data Mining (2019), arXiv:1907.10902.
[ABBR23]
S. D. Axen, M. Baran, R. Bergmann and K. Rzecki. Manifolds.jl: An Extensible Julia Framework for Data Analysis on Manifolds. ACM Transactions on Mathematical Software (2023), arXiv:2021.08777.
[Bac14]
M. Bačák. Computing medians and means in Hadamard spaces. SIAM Journal on Optimization 24, 1542–1566 (2014), arXiv:1210.2145.
[BBSW16]
M. Bačák, R. Bergmann, G. Steidl and A. Weinmann. A second order non-smooth variational model for restoring manifold-valued images. SIAM Journal on Scientific Computing 38, A567–A597 (2016), arXiv:1506.02409.
[BFSS23]
R. Bergmann, O. P. Ferreira, E. M. Santos and J. C. Souza. The difference of convex algorithm on Hadamard manifolds. Preprint (2023), arXiv:2112.05250.
[BFPS18]
R. Bergmann, J. H. Fitschen, J. Persch and G. Steidl. Priors with coupled first and second order differences for manifold-valued image processing. Journal of Mathematical Imaging and Vision 60, 1459–1481 (2018), arXiv:1709.01343.
[BFPS17]
R. Bergmann, J. H. Fitschen, J. Persch and G. Steidl. Infimal convolution coupling of first and second order differences on manifold-valued images. In: Scale Space and Variational Methods in Computer Vision: 6th International Conference, SSVM 2017, Kolding, Denmark, June 4–8, 2017, Proceedings, edited by F. Lauze, Y. Dong and A. B. Dahl (Springer International Publishing, 2017); pp. 447–459.
[BG18]
R. Bergmann and P.-Y. Gousenbourger. A variational model for data fitting on manifolds by minimizing the acceleration of a Bézier curve. Frontiers in Applied Mathematics and Statistics 4 (2018), arXiv:1807.10090.
[BLSW14]
R. Bergmann, F. Laus, G. Steidl and A. Weinmann. Second order differences of cyclic data and applications in variational denoising. SIAM Journal on Imaging Sciences 7, 2916–2953 (2014), arXiv:1405.5349.
[BPS16]
R. Bergmann, J. Persch and G. Steidl. A parallel Douglas Rachford algorithm for minimizing ROF-like functionals on images with values in symmetric Hadamard manifolds. SIAM Journal on Imaging Sciences 9, 901–937 (2016), arXiv:1512.02814.
[Bou23]
[Cas59]
P. de Casteljau. Outillage methodes calcul (Enveloppe Soleau 40.040, Institute National de la Propriété Industrielle, Paris., 1959).
[Cas63]
P. de Casteljau. Courbes et surfaces à pôles (Microfiche P 4147-1, Institute National de la Propriété Industrielle, Paris., 1963).
[DMSC16]
J. Duran, M. Moeller, C. Sbert and D. Cremers. Collaborative Total Variation: A General Framework for Vectorial TV Models. SIAM Journal on Imaging Sciences 9, 116–151 (2016), arXiv:1508.01308.
[LNPS17]
F. Laus, M. Nikolova, J. Persch and G. Steidl. A nonlocal denoising algorithm for manifold-valued images using second order statistics. SIAM Journal on Imaging Sciences 10, 416–448 (2017).
[PN07]
T. Popiel and L. Noakes. Bézier curves and $C^2$ interpolation in Riemannian manifolds. Journal of Approximation Theory 148, 111–127 (2007).
[ROF92]
L. I. Rudin, S. Osher and E. Fatemi. Nonlinear total variation based noise removal algorithms. Physica D: Nonlinear Phenomena 60, 259–268 (1992).
[SO15]
J. C. Souza and P. R. Oliveira. A proximal point algorithm for DC fuctions on Hadamard manifolds. Journal of Global Optimization 63, 797–810 (2015).
[WS22]
M. Weber and S. Sra. Riemannian Optimization via Frank-Wolfe Methods. Mathematical Programming 199, 525–556 (2022).
[WDS14]
A. Weinmann, L. Demaret and M. Storath. Total variation regularization for manifold-valued data. SIAM Journal on Imaging Sciences 7, 2226–2257 (2014).
diff --git a/v0.1.8/search_index.js b/v0.1.8/search_index.js new file mode 100644 index 0000000..b8c6710 --- /dev/null +++ b/v0.1.8/search_index.js @@ -0,0 +1,3 @@ +var documenterSearchIndex = {"docs": +[{"location":"examples/Difference-of-Convex-Frank-Wolfe/#A-comparison-of-the-Difference-of-Convex-and-Frank-Wolfe-Algorithm","page":"Frank Wolfe comparison","title":"A comparison of the Difference of Convex and Frank Wolfe Algorithm","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"Ronny Bergmann 2023-11-06","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/#Introduction","page":"Frank Wolfe comparison","title":"Introduction","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"In this example we compare the Difference of Convex Algprithm (DCA) [BFSS23] with the Frank-Wolfe Algorithm, which was introduced in [WS22]. This example reproduces the results from [BFSS23], Section 7.3.","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"using LinearAlgebra, Random, Statistics, BenchmarkTools\nusing ManifoldsBase, Manifolds, Manopt, ManoptExamples\nusing NamedColors, Plots","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"and we load a few nice colors","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"paul_tol = load_paul_tol()\nindigo = paul_tol[\"mutedindigo\"]\nteal = paul_tol[\"mutedteal\"]","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"We consider the collowing constraint maximimization problem of the Fréchet mean on the symmetric positive definite matrices mathcal P(n) with the affine invariant metric. Let q_1ldotsq_m in mathcal P(n) be a set of points and mu_1ldotsmu_m be a set of weights, such that they sum to one. We consider then","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"operatorname*argmax_pinmathcal C h(p)","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"with","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"h(p) =\nsum_j=1^m mu_j d^2(pq_i)\nquad text where \nd^2(pq_i) = operatornametrbigl(\n log^2(p^-frac12q_jp^-frac12)\nbig)\nqquadtextandqquad\nmathcal C = pin mathcal M bar Lpreceq p preceq bar U ","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"for a lower bound L and an upper bound U for the matrices in the positive definite sense A preceq B Leftrightarrow (B-A) is positive semi-definite","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"When every one of the weights mu_1 ldots mu_m are equal, this function h is known as the of the set q_1 dots q_m.","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"And for our example we set","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"Random.seed!(42)\nn = 20\nm = 100\nM = SymmetricPositiveDefinite(n)\nq = [rand(M) for _ in 1:m];\nw = rand(m)\nw ./=sum(w)","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"We use as lower and upper bound the arithmetic and geometric mean L and U, respectively.","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"L = inv( sum( wi * inv(qi) for (wi, qi) in zip(w,q) ) )\nU = sum( wi * qi for (wi, qi) in zip(w,q) )","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"As a starting point, the Frank-Wolfe algorithm requires a feasible point. We use","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"p0 = (L+U)/2","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"And we can check that it is feasible","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/#Common-Functions","page":"Frank Wolfe comparison","title":"Common Functions","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"Given p in mathcal M, X in T_pmathcal M on the symmetric positive definite matrices M, this method computes the closed form solution to","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"operatorname*argmin_qin mathcal C langle X log_p qrangle\n = operatorname*argmin_qin mathcal C operatornametr(Slog(YqY))","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"where mathcal C = q L preceq q preceq U , S = p^-12Xp^-12, and Y=p^-12.","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"The solution is given by Z=X^-1Qbigl( P^mathrmT-operatornamesgn(D)_+P+hatLbigr)Q^mathrmTX^-1,@ where S=QDQ^mathrmT is a diagonalization of S, hatU-hatL=P^mathrmTP with hatL=Q^mathrmTXLXQ and hatU=Q^mathrmTXUXQ, where -mboxsgn(D)_+ is the diagonal matrix","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"operatornamediagbigl(\n -operatornamesgn(d_11)_+ ldots -operatornamesgn(d_nn)_+\nbigr)","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"and D=(d_ij).","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"@doc raw\"\"\"\n closed_form_solution!(M, q, L, U, p X)\n\nCompute the closeed form solution of the constraint sub problem in place of ``q``.\n\"\"\"\nfunction closed_form_solution!(M::SymmetricPositiveDefinite, q, L, U, p, X)\n # extract p^1/2 and p^{-1/2}\n (p_sqrt_inv, p_sqrt) = Manifolds.spd_sqrt_and_sqrt_inv(p)\n # Compute D & Q\n e2 = eigen(p_sqrt_inv * X * p_sqrt_inv) # decompose Sk = QDQ'\n D = Diagonal(1.0 .* (e2.values .< 0))\n Q = e2.vectors\n #println(p)\n Uprime = Q' * p_sqrt_inv * U * p_sqrt_inv * Q\n Lprime = Q' * p_sqrt_inv * L * p_sqrt_inv * Q\n P = cholesky(Hermitian(Uprime - Lprime))\n z = P.U' * D * P.U + Lprime\n copyto!(M, q, p_sqrt * Q * z * Q' * p_sqrt)\n return q\nend","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/#The-Difference-of-Convex-Formulation","page":"Frank Wolfe comparison","title":"The Difference of Convex Formulation","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"We use g(p) = iota_mathcal C(p) as the indicator funtion of the set mathcal C. We use","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"function is_pos_def(p; atol=5e-13)\n e = eigen(Symmetric(p))\n return all((e.values .+ atol) .> 0)\nend\nfunction g(p, L, U)\n return (is_pos_def(p-L) && is_pos_def(U-p)) ? 0.0 : Inf\nend\nh(M, p, w, q) = sum(wi * distance(M, p, qi)^2 for (wi, qi) in zip(w,q) )","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"So we can first check that p0 is feasible","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"g(p0,L,U) == 0.0","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"true","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"Now setting","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"operatorname*argmin_pinmathcal M g(p) - h(p)","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"We look for a maximum of h, where g is minimal, i.e. g(p) is zero or in other words p in mathcal C.","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"The gradient of h can also be implemented in closed form as","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"grad_h(M, p, w, q) = -2.0 * sum(wi * log(M, p, qi) for (wi, qi) in zip(w, q))\nfunction grad_h!(M, X, p, w, q)\n Y = copy(M, p, X)\n zero_vector!(M, X, p)\n for (wi, qi) in zip(w,q)\n log!(M, Y, p, qi)\n Y .*= - 2.0*wi\n X .+= Y\n end\n return X\nend","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"And we can further define the cost, which will just be +infty outside of mathcal C. We define","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"f_dc(M, p) = g(p, L, U) - h(M, p, w, q)\ngrad_h!(M, X, p) = grad_h!(M, X, p, w, q)\nfunction grad_f_dc!(M,X, p)\n grad_h!(M, X, p, w, q)\n X .*= -1.0\n return X\nend","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"Here we can omit the gradient of g in the definition of operatornamegrad f, since the gradient is zero at the points there it is defined, that is on any point that is not on the boundary of mathcal C.","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"As the last step, we can provide the closed form solver for the DC sub problem given at iteration k by","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"operatorname*argmin_pin mathcal C\n biglangle -operatornamegrad h(p^(k)) exp^-1_p^(k)pbigrangle","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"Which we con compute","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"function dc_sub_solution!(M, q, p, X)\n closed_form_solution!(M, q, L, U, p, -X)\n return q\nend","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"For safety, we might want to avoid ending up at the boundary of mathcal C. That is we reduce the distance we walk towards the solution q a bit.","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"function dc_sub_solution_safe!(M, q, p, X)\n p_last = copy(M,p) # since p=q might be in place\n closed_form_solution!(M, q, L, U, p, -X)\n q_orig = copy(M,q) # since we do the following in place of q\n a = minimum(real.(eigen(q-L).values))\n b = minimum(real.(eigen(U-q).values))\n s = 1.0\n d = distance(M, p_last, q_orig);\n # if we are close to zero, we reduce faster.\n α = d < 1/(n^2) ? 0.66 : 0.9995;\n i=0\n while (a < 0) || (b < 0)\n s *= α\n shortest_geodesic!(M, q, p_last, q_orig, s)\n a = minimum(real.(eigen(q-L).values))\n b = minimum(real.(eigen(U-q).values))\n #println(\"$i a: $a, b = $b with s=$s\")\n i=i+1\n if (i>100) # safety fallback\n #@warn \" $i steps where not enough $s ($α)\\n$a $b\\n $(distance(M, p_last, q_orig)). Fixing by shifting EVs\"\n qe = eigen(q)\n if a < 0\n qe.values .+= min(1e-8, n*abs(min(a,b)))\n else\n qe.values .-= min(1e-8, n*abs(min(a,b)))\n end\n q .= qe.vectors * Diagonal(qe.values) * (qe.vectors)'\n a = minimum(real.(eigen(q-L).values))\n b = minimum(real.(eigen(U-q).values))\n return q\n end\n end\n return q\nend","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/#The-DoC-solver-run","page":"Frank Wolfe comparison","title":"The DoC solver run","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"Let’s compare both methods when they have the same stopping criteria","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"@time state1_dc = difference_of_convex_algorithm(M, f_dc, g, grad_h!, p0;\n gradient=grad_f_dc!,\n sub_problem=dc_sub_solution_safe!,\n evaluation=InplaceEvaluation(),\n stopping_criterion = StopAfterIteration(300) |\n StopWhenChangeLess(1e-14) | StopWhenGradientChangeLess(M, 1e-9),\n debug = [\n (:Iteration, \"# %-8d \"), (:Cost, \"F(p): %0.14f\"), (:Change, \" |Δp|: %0.14f \"),\n (:GradientNorm, \" |grad f(p)|: %0.8f \"),\n (:GradientChange, \" |Δgrad f(p)|: %0.8f\"),\n 30, :Stop, \"\\n\"],\n record = [:Iteration, :Iterate, :Cost, RecordGradientNorm(), :Change],\n return_state=true,\n)","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"Initial F(p): -0.77661458292831\nAt iteration 23 the change of the gradient (3.192989916935325e-13) was less than 1.0e-9.\n 16.161776 seconds (17.17 M allocations: 1.670 GiB, 1.83% gc time, 93.45% compilation time)\n\n# Solver state for `Manopt.jl`s Difference of Convex Algorithm\nAfter 23 iterations\n\n## Parameters\n* sub solver state:\n | InplaceEvaluation()\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 300: not reached\n |Δp| < 1.0e-14: not reached\n |Δgrad f| < 1.0e-9: reached\nOverall: reached\nThis indicates convergence: No\n\n## Debug\n :Iteration = [(:Iteration, \"# %-8d \"), (:Cost, \"F(p): %0.14f\"), (:Change, \" |Δp|: %0.14f \"), (:GradientNorm, \" |grad f(p)|: %0.8f \"), (:GradientChange, \" |Δgrad f(p)|: %0.8f\"), \"\\n\", 30]\n :Stop = :Stop\n\n## Record\n(Iteration = RecordGroup([RecordIteration(), RecordIterate(Matrix{Float64}), RecordCost(), RecordGradientNorm(), RecordChange(; inverse_retraction_method=LogarithmicInverseRetraction())]),)","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"Let’s extract the final point and look at its cost","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"p1_dc = get_solver_result(state1_dc);\nf_dc(M, p1_dc)","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"-0.784425242474807","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"As well as whether (and how well) it is feasible, that is the following values should all be larger than zero.","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"[ extrema(eigen(p1_dc-L).values), extrema(eigen(U-p1_dc).values)]","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"2-element Vector{Tuple{Float64, Float64}}:\n (1.1886583723800445e-12, 0.06669240322431051)\n (1.3411042178831775e-5, 0.0671353506908023)","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"For the statistics we extract the recordings from the state","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/#Define-the-Frank-Wolfe-functions","page":"Frank Wolfe comparison","title":"Define the Frank-Wolfe functions","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"For Frank wolfe, the cost is just defined as -h(p) but the minimisation is constraint to mathcal C, which is enfored by the oracle.","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"f_fw(M, p) = -h(M, p, w, q)\nfunction grad_f_fw!(M,X, p)\n grad_h!(M, X, p, w, q)\n X .*= -1.0\n return X\nend\noracle_fw!(M, q, p, X) = closed_form_solution!(M, q, L, U, p, X)","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/#The-FW-Solver-Run","page":"Frank Wolfe comparison","title":"The FW Solver Run","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"Similarly we can run the Frank-Wolfe algorithm with","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"@time state1_fw = Frank_Wolfe_method(M, f_fw, grad_f_fw!, p0;\n sub_problem=oracle_fw!,\n evaluation=InplaceEvaluation(),\n stopping_criterion = StopAfterIteration(10^4) |\n StopWhenChangeLess(1e-14) | StopWhenGradientChangeLess(M, 1e-9),\n debug = [\n (:Iteration, \"# %-8d \"), :Cost, (:Change, \" |Δp|: %0.14f \"),\n (:GradientNorm, \" |grad f(p)|: %0.8f \"),\n (:GradientChange, \" |Δgrad f(p)|: %0.8f\"),\n 2*10^3, :Stop, \"\\n\"],\n record = [:Iteration, :Iterate, :Cost, RecordGradientNorm(), :Change],\n return_state=true,\n)","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"Initial f(x): -0.776615\n# 2000 f(x): -0.784420 |Δp|: 0.04611942377596 |grad f(p)|: 0.17693408 |Δgrad f(p)|: 0.17555618\n# 4000 f(x): -0.784421 |Δp|: 0.00372201632005 |grad f(p)|: 0.17694619 |Δgrad f(p)|: 0.00749427\n# 6000 f(x): -0.784422 |Δp|: 0.00205683506784 |grad f(p)|: 0.17695204 |Δgrad f(p)|: 0.00414088\n# 8000 f(x): -0.784422 |Δp|: 0.00140675676260 |grad f(p)|: 0.17695565 |Δgrad f(p)|: 0.00283200\n# 10000 f(x): -0.784422 |Δp|: 0.00106177438611 |grad f(p)|: 0.17695815 |Δgrad f(p)|: 0.00213746\nThe algorithm reached its maximal number of iterations (10000).\n152.781466 seconds (55.53 M allocations: 94.006 GiB, 2.12% gc time, 0.57% compilation time)\n\n# Solver state for `Manopt.jl`s Frank Wolfe Method\nAfter 10000 iterations\n\n## Parameters\n* inverse retraction method: LogarithmicInverseRetraction()\n* retraction method: ExponentialRetraction()\n* sub solver state:\n | InplaceEvaluation()\n\n## Stepsize\nDecreasingStepsize(; length=2.0, factor=1.0, subtrahend=0.0, shift=2)\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 10000: reached\n |Δp| < 1.0e-14: not reached\n |Δgrad f| < 1.0e-9: not reached\nOverall: reached\nThis indicates convergence: No\n\n## Debug\n :Iteration = [(:Iteration, \"# %-8d \"), (:Cost, \"f(x): %f\"), (:Change, \" |Δp|: %0.14f \"), (:GradientNorm, \" |grad f(p)|: %0.8f \"), (:GradientChange, \" |Δgrad f(p)|: %0.8f\"), \"\\n\", 2000]\n :Stop = :Stop\n\n## Record\n(Iteration = RecordGroup([RecordIteration(), RecordIterate(Matrix{Float64}), RecordCost(), RecordGradientNorm(), RecordChange(; inverse_retraction_method=LogarithmicInverseRetraction())]),)","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"And we take a look at this result as well","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"p1_fw = get_solver_result(state1_fw);\nf_dc(M, p1_fw)","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"-0.7844220281765162","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"And its feasibility","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"[extrema(eigen(p1_fw-L).values), extrema(eigen(U-p1_fw).values)]","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"2-element Vector{Tuple{Float64, Float64}}:\n (4.904818928410655e-10, 0.06659173821656107)\n (3.245654983213335e-5, 0.06713970236096602)","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/#Statistics","page":"Frank Wolfe comparison","title":"Statistics","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"We extract the recorded values","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"# DoC\niter1_dc = get_record(state1_dc, :Iteration, :Iteration)\npk_dc = get_record(state1_dc,:Iteration,:Iterate)\ncosts1_dc = -h.(Ref(M), pk_dc, Ref(w), Ref(q))\ndc_min = minimum(costs1_dc)\n# FW\niter1_fw = get_record(state1_fw,:Iteration,:Iteration)[1:5:end]\npk_fw = get_record(state1_fw,:Iteration,:Iterate)[1:5:end]\ncosts1_fw = -h.(Ref(M), pk_fw, Ref(w), Ref(q))","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"And let’s plot the result, where we measure the cost versus the minimum the difference of convex algorithm attains.","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"fig = plot(;\n legend=:topright,\n xlabel=raw\"Iterations $k$ (log. scale)\", ylabel=raw\"Cost $f(x_k)-f^*$ (log. scale)\",\n yaxis=:log,\n ylims=(1e-8, 10^-2),\n xaxis=:log,\n xlims=(1,10^4),\n)\nplot!(fig, iter1_dc, costs1_dc .- dc_min, color=indigo, label=\"Difference of Convex\")\nplot!(fig, iter1_fw, costs1_fw .- dc_min, color=teal, label=\"Frank-Wolfe\")","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"(Image: )","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"This indicates, that the difference off convex algorithm could even stop earlier with a proper stopping criterion, since after that the cost increases a bit again.","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"On the other hand, Frank-Wolfe still has not reached this level function value after 10^4 iterations.","category":"page"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/#Literature","page":"Frank Wolfe comparison","title":"Literature","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Frank-Wolfe/","page":"Frank Wolfe comparison","title":"Frank Wolfe comparison","text":"R. Bergmann, O. P. Ferreira, E. M. Santos and J. C. Souza. The difference of convex algorithm on Hadamard manifolds. Preprint (2023), arXiv:2112.05250.\n\n\n\nM. Weber and S. Sra. Riemannian Optimization via Frank-Wolfe Methods. Mathematical Programming 199, 525–556 (2022).\n\n\n\n","category":"page"},{"location":"references/#Literature","page":"References","title":"Literature","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"T. Akiba, S. Sano, T. Yanase, T. Ohta and M. Koyama. Optuna: A Next-generation Hyperparameter Optimization Framework. In: Proceedings of the 25th ACM SIGKDD International Conference on Knowledge Discovery and Data Mining (2019), arXiv:1907.10902.\n\n\n\nS. D. Axen, M. Baran, R. Bergmann and K. Rzecki. Manifolds.jl: An Extensible Julia Framework for Data Analysis on Manifolds. ACM Transactions on Mathematical Software (2023), arXiv:2021.08777.\n\n\n\nM. Bačák. Computing medians and means in Hadamard spaces. SIAM Journal on Optimization 24, 1542–1566 (2014), arXiv:1210.2145.\n\n\n\nM. Bačák, R. Bergmann, G. Steidl and A. Weinmann. A second order non-smooth variational model for restoring manifold-valued images. SIAM Journal on Scientific Computing 38, A567–A597 (2016), arXiv:1506.02409.\n\n\n\nR. Bergmann, O. P. Ferreira, E. M. Santos and J. C. Souza. The difference of convex algorithm on Hadamard manifolds. Preprint (2023), arXiv:2112.05250.\n\n\n\nR. Bergmann, J. H. Fitschen, J. Persch and G. Steidl. Priors with coupled first and second order differences for manifold-valued image processing. Journal of Mathematical Imaging and Vision 60, 1459–1481 (2018), arXiv:1709.01343.\n\n\n\nR. Bergmann, J. H. Fitschen, J. Persch and G. Steidl. Infimal convolution coupling of first and second order differences on manifold-valued images. In: Scale Space and Variational Methods in Computer Vision: 6th International Conference, SSVM 2017, Kolding, Denmark, June 4–8, 2017, Proceedings, edited by F. Lauze, Y. Dong and A. B. Dahl (Springer International Publishing, 2017); pp. 447–459.\n\n\n\nR. Bergmann and P.-Y. Gousenbourger. A variational model for data fitting on manifolds by minimizing the acceleration of a Bézier curve. Frontiers in Applied Mathematics and Statistics 4 (2018), arXiv:1807.10090.\n\n\n\nR. Bergmann, F. Laus, G. Steidl and A. Weinmann. Second order differences of cyclic data and applications in variational denoising. SIAM Journal on Imaging Sciences 7, 2916–2953 (2014), arXiv:1405.5349.\n\n\n\nR. Bergmann, J. Persch and G. Steidl. A parallel Douglas Rachford algorithm for minimizing ROF-like functionals on images with values in symmetric Hadamard manifolds. SIAM Journal on Imaging Sciences 9, 901–937 (2016), arXiv:1512.02814.\n\n\n\nN. Boumal. An Introduction to Optimization on Smooth Manifolds. First Edition (Cambridge University Press, 2023).\n\n\n\nP. de Casteljau. Outillage methodes calcul (Enveloppe Soleau 40.040, Institute National de la Propriété Industrielle, Paris., 1959).\n\n\n\nP. de Casteljau. Courbes et surfaces à pôles (Microfiche P 4147-1, Institute National de la Propriété Industrielle, Paris., 1963).\n\n\n\nJ. Duran, M. Moeller, C. Sbert and D. Cremers. Collaborative Total Variation: A General Framework for Vectorial TV Models. SIAM Journal on Imaging Sciences 9, 116–151 (2016), arXiv:1508.01308.\n\n\n\nF. Laus, M. Nikolova, J. Persch and G. Steidl. A nonlocal denoising algorithm for manifold-valued images using second order statistics. SIAM Journal on Imaging Sciences 10, 416–448 (2017).\n\n\n\nT. Popiel and L. Noakes. Bézier curves and C^2 interpolation in Riemannian manifolds. Journal of Approximation Theory 148, 111–127 (2007).\n\n\n\nL. I. Rudin, S. Osher and E. Fatemi. Nonlinear total variation based noise removal algorithms. Physica D: Nonlinear Phenomena 60, 259–268 (1992).\n\n\n\nJ. C. Souza and P. R. Oliveira. A proximal point algorithm for DC fuctions on Hadamard manifolds. Journal of Global Optimization 63, 797–810 (2015).\n\n\n\nM. Weber and S. Sra. Riemannian Optimization via Frank-Wolfe Methods. Mathematical Programming 199, 525–556 (2022).\n\n\n\nA. Weinmann, L. Demaret and M. Storath. Total variation regularization for manifold-valued data. SIAM Journal on Imaging Sciences 7, 2226–2257 (2014).\n\n\n\n","category":"page"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"EditURL = \"https://github.com/JuliaManifolds/Manopt.jl/blob/master/CONTRIBUTING.md\"","category":"page"},{"location":"contributing/#Contributing-to-Manopt.jl","page":"Contributing to ManoptExamples.jl","title":"Contributing to Manopt.jl","text":"","category":"section"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"First, thanks for taking the time to contribute. Any contribution is appreciated and welcome.","category":"page"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"The following is a set of guidelines to ManoptExamples.jl.","category":"page"},{"location":"contributing/#Table-of-Contents","page":"Contributing to ManoptExamples.jl","title":"Table of Contents","text":"","category":"section"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"Contributing to Manopt.jl\nTable of Contents\nI just have a question\nHow can I file an issue?\nHow can I contribute?\nAdd an objective\nCode style","category":"page"},{"location":"contributing/#I-just-have-a-question","page":"Contributing to ManoptExamples.jl","title":"I just have a question","text":"","category":"section"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"The developer can most easily be reached in the Julia Slack channel #manifolds. You can apply for the Julia Slack workspace here if you haven't joined yet. You can also ask your question on our GitHub discussion.","category":"page"},{"location":"contributing/#How-can-I-file-an-issue?","page":"Contributing to ManoptExamples.jl","title":"How can I file an issue?","text":"","category":"section"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"If you found a bug or want to propose a feature, we track our issues within the GitHub repository.","category":"page"},{"location":"contributing/#How-can-I-contribute?","page":"Contributing to ManoptExamples.jl","title":"How can I contribute?","text":"","category":"section"},{"location":"contributing/#Add-an-objective","page":"Contributing to ManoptExamples.jl","title":"Add an objective","text":"","category":"section"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"The objective in Manopt.jl represents the task to be optimised, usually phrased on an arbitrary manifold. The manifold is later specified when wrapping the objective inside a Problem.","category":"page"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"If you have a specific objective you would like to provide here, feel free to start a new file in the src/objectives/ folder in your own fork and propose it later as a Pull Request.","category":"page"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"If you objective works without reusing any other objective functions, then they can all just be placed in this one file. If you notice, that you are reusing for example another objectives gradient as part of your objective, please refactor the code, such that the gradient, or other function is in the corresponding file in src/functions/ and follows the naming scheme:","category":"page"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"cost functions are always of the form cost_ and a fitting name\ngradient functions are always of the gradient_ and a fitting name, followed by an !","category":"page"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"for in-place gradients and by !! if it is a struct that can provide both.","category":"page"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"It would be great if you could also add a small test for the functions and the problem you defined in the test/ section.","category":"page"},{"location":"contributing/#Add-an-example","page":"Contributing to ManoptExamples.jl","title":"Add an example","text":"","category":"section"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"If you have used one of the problems from here in an example or you are providing a problem together with an example, please add a corresponding Quarto Markdown file to the examples/ folder. The Markdown file should provide a short introduction to the problem and provide links to further details, maybe a paper or a preprint. Use the bib/literature.yaml file to add references (in CSL_YAML, which can for example be exported e.g. from Zotero).","category":"page"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"Add any packages you need to the examples/ environment (see the containting Project.toml). The examples will not be run on CI, but their rendered CommonMark outpout should be included in the list of examples in the documentation of this package.","category":"page"},{"location":"contributing/#Code-style","page":"Contributing to ManoptExamples.jl","title":"Code style","text":"","category":"section"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"We try to follow the documentation guidelines from the Julia documentation as well as Blue Style. We run JuliaFormatter.jl on the repo in the way set in the .JuliaFormatter.toml file, which enforces a number of conventions consistent with the Blue Style.","category":"page"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"We also follow a few internal conventions:","category":"page"},{"location":"contributing/","page":"Contributing to ManoptExamples.jl","title":"Contributing to ManoptExamples.jl","text":"Any implemented function should be accompanied by its mathematical formulae if a closed form exists.\nwithin a file the structs should come first and functions second. The only exception are constructors for the structs\nwithin both blocks an alphabetical order is preferable.\nThe above implies that the mutating variant of a function follows the non-mutating variant.\nThere should be no dangling = signs.\nAlways add a newline between things of different types (struct/method/const).\nAlways add a newline between methods for different functions (including in-place/non-mutating variants).\nPrefer to have no newline between methods for the same function; when reasonable, merge the docstrings into a generic function signature.\nAll import/using/include should be in the main module file.\nThere should only be a minimum of exports within this file, all problems should usually be later addressed as ManoptExamples.[...]\nthe Quarto Markdown files are excluded from this formatting.","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/#Benchmark-of-the-Difference-of-Convex-Algorithms","page":"A Benchmark","title":"Benchmark of the Difference of Convex Algorithms","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"Ronny Bergmann 2023-06-06","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/#Introduction","page":"A Benchmark","title":"Introduction","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"In this Benchmark we compare the Difference of Convex Algprithm (DCA) [BFSS23] and the Difference of Convex Proximal Point Algorithm (DCPPA) [SO15] which solve Difference of Convex (DC) problems of the form. This Benchmark reproduces the results from [BFSS23], Section 7.1.","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"operatorname*argmin_pinmathcal M g(p) - h(p)","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"where ghcolon mathcal M to mathbb R are geodesically convex function on the Riemannian manifold mathcal M.","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"using LinearAlgebra, Random, Statistics, BenchmarkTools\nusing Manifolds, Manopt, ManoptExamples\nusing NamedColors, Plots\nRandom.seed!(42)","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"and we load a few nice colors","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"paul_tol = load_paul_tol()\nindigo = paul_tol[\"mutedindigo\"]\nteal = paul_tol[\"mutedteal\"]","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/#The-DC-Problem","page":"A Benchmark","title":"The DC Problem","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"We start with defining the two convex functions gh and their gradients as well as the DC problem f and its gradient for the problem","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":" operatorname*argmin_pinmathcal M bigl( logbigr(det(p)bigr)bigr)^4 - bigl(log det(p) bigr)^2","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"where the critical points obtain a functional value of -frac14.","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"where mathcal M is the manifold of symmetric positive definite (SPD) matrices with the affine invariant metric, which is the default.","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"We first define the corresponding functions","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"g(M, p) = log(det(p))^4\nh(M, p) = log(det(p))^2\nf(M, p) = g(M, p) - h(M, p)","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"and their gradients","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"grad_g(M, p) = 4 * (log(det(p)))^3 * p\ngrad_h(M, p) = 2 * log(det(p)) * p\ngrad_f(M, p) = grad_g(M, p) - grad_h(M, p)","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"which we can use to verify that the gradients of g and h are correct. We use for that","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"n = 6\nM = SymmetricPositiveDefinite(n)\np0 = log(n) * Matrix{Float64}(I, n, n);\nX0 = 1 / n * Matrix{Float64}(I, n, n);","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"to tall both checks","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"check_gradient(M, g, grad_g, p0, X0; plot=true)","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"(Image: )","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"and","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"check_gradient(M, h, grad_h, p0, X0; plot=true)","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"(Image: )","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"which both pass the test. We continue to define their inplace variants","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"function grad_g!(M, X, p)\n copyto!(M, X, p)\n X .*= 4 * (log(det(p)))^3\n return X\nend\nfunction grad_h!(M, X, p)\n copyto!(M, X, p)\n X .*= 2 * (log(det(p)))\n return X\nend\nfunction grad_f!(M, X, p)\n grad_g!(M, X, p)\n Y = copy(M, p, X)\n grad_h!(M, Y, p)\n X .-= Y\n return X\nend","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"And compare times for both algorithms, with a bit of debug output.","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"@time p_min_dca = difference_of_convex_algorithm(\n M,\n f,\n g,\n grad_h!,\n p0;\n grad_g=grad_g!,\n gradient=grad_f!,\n evaluation=InplaceEvaluation(),\n debug=[\n :Iteration,\n (:Cost, \"f(p): %1.9f\"),\n (:GradientNorm, \" |grad_f(p)|: %1.9f\"),\n (:Change, \" |δp|: %1.9f\"),\n :Stop,\n 5,\n \"\\n\",\n ],\n stopping_criterion=StopAfterIteration(5000) | StopWhenGradientNormLess(1e-10),\n sub_stopping_criterion=StopAfterIteration(100) | StopWhenGradientNormLess(1e-10),\n);","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"Initial f(p): 137.679053470\n# 5 f(p): -0.249956120 |grad_f(p)|: 0.046196628 |δp|: 0.201349127\n# 10 f(p): -0.249999999 |grad_f(p)|: 0.000187633 |δp|: 0.000626103\n# 15 f(p): -0.250000000 |grad_f(p)|: 0.000000772 |δp|: 0.000002574\n# 20 f(p): -0.250000000 |grad_f(p)|: 0.000000005 |δp|: 0.000000011\nThe algorithm reached approximately critical point after 24 iterations; the gradient norm (7.619584706652929e-11) is less than 1.0e-10.\n 3.531235 seconds (8.71 M allocations: 628.709 MiB, 3.52% gc time, 67.16% compilation time)","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"The cost is","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"f(M, p_min_dca)","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"-0.25000000000000006","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"Similarly the DCPPA performs","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"@time p_min_dcppa = difference_of_convex_proximal_point(\n M,\n grad_h!,\n p0;\n g=g,\n grad_g=grad_g!,\n λ=i -> 1 / (2 * n),\n cost=f,\n gradient=grad_f!,\n debug=[\n :Iteration,\n (:Cost, \"f(p): %1.9f\"),\n \" \",\n (:GradientNorm, \"|grad_f(p)|: %1.10f\"),\n (:Change, \"|δp|: %1.10f\"),\n :Stop,\n 5,\n \"\\n\",\n ],\n evaluation=InplaceEvaluation(),\n stepsize=ConstantStepsize(1.0),\n stopping_criterion=StopAfterIteration(5000) | StopWhenGradientNormLess(1e-10),\n sub_stopping_criterion=StopAfterIteration(100) | StopWhenGradientNormLess(1e-10),\n);","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"Initial f(p): 137.679053470 \n# 5 f(p): -0.248491803 |grad_f(p)|: 0.2793140152|δp|: 0.2753827692\n# 10 f(p): -0.249998655 |grad_f(p)|: 0.0080437374|δp|: 0.0050891316\n# 15 f(p): -0.249999999 |grad_f(p)|: 0.0002507329|δp|: 0.0001567676\n# 20 f(p): -0.250000000 |grad_f(p)|: 0.0000078348|δp|: 0.0000048968\n# 25 f(p): -0.250000000 |grad_f(p)|: 0.0000002448|δp|: 0.0000001530\n# 30 f(p): -0.250000000 |grad_f(p)|: 0.0000000076|δp|: 0.0000000048\n# 35 f(p): -0.250000000 |grad_f(p)|: 0.0000000002|δp|: 0.0000000001\nThe algorithm reached approximately critical point after 37 iterations; the gradient norm (5.458071707233144e-11) is less than 1.0e-10.\n 1.341931 seconds (2.55 M allocations: 180.474 MiB, 2.46% gc time, 59.94% compilation time)","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"It needs a few more iterations, but the single iterations are slightly faster. Both obtain the same cost","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"f(M, p_min_dcppa)","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"-0.25","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/#Benchmark-I:-Time-comparison","page":"A Benchmark","title":"Benchmark I: Time comparison","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"We compare both solvers first with respect to time. We initialise two vectors to collect the results and a range of natrix sizes to test","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"dca_benchmarks = Dict{Int,BenchmarkTools.Trial}()\ndcppa_benchmarks = Dict{Int, BenchmarkTools.Trial}()\nN_max=14\nN = 2:N_max","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"and run a benchmark for both algorithms","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"for n in N\n Mn = SymmetricPositiveDefinite(n)\n pn = log(n) * Matrix{Float64}(I, n, n)\n bdca = @benchmark difference_of_convex_algorithm(\n $Mn,\n $f,\n $g,\n $grad_h!,\n $pn;\n grad_g=$grad_g!,\n gradient=$grad_f!,\n evaluation=InplaceEvaluation(),\n stopping_criterion=StopAfterIteration(5000) | StopWhenGradientNormLess(1e-10),\n sub_stopping_criterion=StopAfterIteration(100) | StopWhenGradientNormLess(1e-10),\n )\n dca_benchmarks[n] = bdca\n bdcppa = @benchmark difference_of_convex_proximal_point(\n $Mn,\n $grad_h!,\n $pn;\n g=$g,\n grad_g=$grad_g!,\n λ=i -> 1 / (2 * n),\n cost=f,\n gradient=grad_f!,\n evaluation=InplaceEvaluation(),\n stepsize=ConstantStepsize(1.0),\n stopping_criterion=StopAfterIteration(5000) | StopWhenGradientNormLess(1e-10),\n sub_stopping_criterion=StopAfterIteration(100) | StopWhenGradientNormLess(1e-10),\n )\n dcppa_benchmarks[n] = bdcppa\nend","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"Since we want to plot this versus the manifold dimension, we also create a vector for those and convert the times to seconds","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"dims = [manifold_dimension(SymmetricPositiveDefinite(n)) for n in N]\ndca_times = [mean(dca_benchmarks[n]).time / 1e9 for n in N]\ndcppa_times = [mean(dcppa_benchmarks[n]).time / 1e9 for n in N]","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"plot(; legend=:bottomright, xlabel=\"manifold dimension\", ylabel=\"Time (sec.)\")\nplot!(dims, dca_times; label=\"DCA\", color=indigo, linewidth=2)\nplot!(dims, dcppa_times; label=\"DCPPA\", color=teal, linewidth=2)","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"(Image: )","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/#Benchmark-II:-Iterations-and-cost.","page":"A Benchmark","title":"Benchmark II: Iterations and cost.","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"As a second benchmark, let’s collect the number of iterations needed and the development of the cost over dimensions.","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"N2 = [5,10,20,40,80]\ndims2 = [manifold_dimension(SymmetricPositiveDefinite(n)) for n in N2]\ndca_iterations = Dict{Int,Int}()\ndca_costs = Dict{Int,Vector{Float64}}()\ndcppa_iterations = Dict{Int,Int}()\ndcppa_costs = Dict{Int,Vector{Float64}}()","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"@time for n in N2\n println(n)\n Mn = SymmetricPositiveDefinite(n)\n pn = log(n) * Matrix{Float64}(I,n,n);\n @time dca_st = difference_of_convex_algorithm(\n Mn, f, g, grad_h!, pn;\n grad_g=grad_g!,\n gradient=grad_f!,\n evaluation = InplaceEvaluation(),\n stopping_criterion = StopAfterIteration(5000) | StopWhenGradientNormLess(1e-10),\n sub_stopping_criterion = StopAfterIteration(100) | StopWhenGradientNormLess(1e-10),\n record = [:Iteration, :Cost],\n return_state = true,\n );\n dca_costs[n] = get_record(dca_st, :Iteration, :Cost)\n dca_iterations[n] = length(dca_costs[n])\n @time dcppa_st = difference_of_convex_proximal_point(\n Mn, grad_h!, pn;\n g=g,\n grad_g=grad_g!,\n λ = i -> 1/(2*n),\n cost = f,\n gradient= grad_f!,\n evaluation = InplaceEvaluation(),\n stepsize = ConstantStepsize(1.0),\n stopping_criterion = StopAfterIteration(5000) | StopWhenGradientNormLess(1e-10),\n sub_stopping_criterion = StopAfterIteration(100) | StopWhenGradientNormLess(1e-10),\n record = [:Iteration, :Cost],\n return_state = true,\n );\n dcppa_costs[n] = get_record(dcppa_st, :Iteration, :Cost)\n dcppa_iterations[n] = length(dcppa_costs[n])\nend","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"The iterations are like","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"plot(; legend=:bottomright, xlabel=\"manifold dimension\", ylabel=\"Iterations\")\nplot!(dims2, [values(dca_iterations)...]; label=\"DCA\", color=indigo, linewidth=2)\nplot!(dims2, [values(dcppa_iterations)...]; label=\"DCPPA\", color=teal, linewidth=2)","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"(Image: )","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"And for the developtment of the cost","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"(Image: )","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"where we can see that the DCA needs less iterations than the DCPPA.","category":"page"},{"location":"examples/Difference-of-Convex-Benchmark/#Literature","page":"A Benchmark","title":"Literature","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Benchmark/","page":"A Benchmark","title":"A Benchmark","text":"R. Bergmann, O. P. Ferreira, E. M. Santos and J. C. Souza. The difference of convex algorithm on Hadamard manifolds. Preprint (2023), arXiv:2112.05250.\n\n\n\nJ. C. Souza and P. R. Oliveira. A proximal point algorithm for DC fuctions on Hadamard manifolds. Journal of Global Optimization 63, 797–810 (2015).\n\n\n\n","category":"page"},{"location":"objectives/#List-of-Objectives-defined-for-the-Examples","page":"Objectives","title":"List of Objectives defined for the Examples","text":"","category":"section"},{"location":"objectives/#Rayleigh","page":"Objectives","title":"Rayleigh Quotient on the Sphere","text":"","category":"section"},{"location":"objectives/","page":"Objectives","title":"Objectives","text":"See the Rayleigh example (TODO) to see these in use.","category":"page"},{"location":"objectives/","page":"Objectives","title":"Objectives","text":"Modules = [ManoptExamples]\nPages = [\"objectives/RayleighQuotient.jl\"]\nOrder = [:type, :function]\nPrivate = true","category":"page"},{"location":"objectives/#ManoptExamples.RayleighQuotientCost","page":"Objectives","title":"ManoptExamples.RayleighQuotientCost","text":"RayleighQuotientCost\n\nA functor representing the Rayleigh Quotient cost function.\n\nLet A ℝ^nn be a symmetric matrix. Then we can specify the Rayleigh Quotient in two forms. Either\n\nf(p) = p^mathrmTApqquad p 𝕊^n-1\n\nor extended into the embedding as\n\nf(x) = x^mathrmTAx qquad x ℝ^n\n\nwhich is not the orignal Rayleigh quotient for performance reasons, but useful if you want to use this as the Euclidean cost in the emedding of 𝕊^n-1.\n\nFields\n\nA – storing the matrix internally\n\nConstructor\n\nRayleighQuotientCost(A)\n\nCreate the Rayleigh cost function.\n\nSee also\n\nRayleighQuotientGrad!!, RayleighQuotientHess!!\n\n\n\n\n\n","category":"type"},{"location":"objectives/#ManoptExamples.RayleighQuotientGrad!!","page":"Objectives","title":"ManoptExamples.RayleighQuotientGrad!!","text":"RayleighQuotientGrad!!\n\nA functor representing the Rayleigh Quotient gradient function.\n\nLet A ℝ^nn be a symmetric matrix. Then we can specify the gradient of the Rayleigh Quotient in two forms. Either\n\noperatornamegrad f(p) = 2 Ap - 2 (p^mathrmTAp)*pqquad p 𝕊^n-1\n\nor taking the Euclidean gradient of the Rayleigh quotient on the sphere as\n\nf(x) = 2Ax qquad x ℝ^n\n\nFor details, see Example 3.62 of [Bou23].\n\nFields\n\nA – storing the matrix internally\n\nConstructor\n\nRayleighQuotientGrad!!(A)\n\nCreate the Rayleigh quotient gradient function.\n\nSee also\n\nRayleighQuotientCost, RayleighQuotientHess!!\n\n\n\n\n\n","category":"type"},{"location":"objectives/#ManoptExamples.RayleighQuotientHess!!","page":"Objectives","title":"ManoptExamples.RayleighQuotientHess!!","text":"RayleighQuotientHess!!\n\nA functor representing the Rayleigh Quotient Hessian.\n\nLet A ℝ^nn be a symmetric matrix. Then we can specify the Hessian of the Rayleigh Quotient in two forms. Either\n\noperatornameHess f(p)X = 2 bigl(AX - (p^mathrmTAX)p - (p^mathrmTAp)Xbigr)qquad p 𝕊^n-1 X in T_p𝕊^n-1\n\nor taking the Euclidean Hessian of the Rayleigh quotient on the sphere as\n\n^2f(x)V = 2AV qquad x V ℝ^n\n\nFor details, see Example 5.27 of [Bou23].\n\nFields\n\nA – storing the matrix internally\n\nConstructor\n\nRayleighQuotientHess!!(A)\n\nCreate the Rayleigh quotient Hessian function.\n\nSee also\n\nRayleighQuotientCost, RayleighQuotientGrad!!\n\n\n\n\n\n","category":"type"},{"location":"objectives/#BezierCurves","page":"Objectives","title":"Bézier Curves","text":"","category":"section"},{"location":"objectives/","page":"Objectives","title":"Objectives","text":"See the Bezier Curves example to see these in use.","category":"page"},{"location":"objectives/","page":"Objectives","title":"Objectives","text":"Modules = [ManoptExamples]\nPages = [\"objectives/BezierCurves.jl\"]\nOrder = [:type, :function]\nPrivate = true","category":"page"},{"location":"objectives/#ManoptExamples.BezierSegment","page":"Objectives","title":"ManoptExamples.BezierSegment","text":"BezierSegment\n\nA type to capture a Bezier segment. With n points, a Bézier segment of degree n-1 is stored. On the Euclidean manifold, this yields a polynomial of degree n-1.\n\nThis type is mainly used to encapsulate the points within a composite Bezier curve, which consist of an AbstractVector of BezierSegments where each of the points might be a nested array on a PowerManifold already.\n\nNot that this can also be used to represent tangent vectors on the control points of a segment.\n\nSee also: de_Casteljau.\n\nConstructor\n\nBezierSegment(pts::AbstractVector)\n\nGiven an abstract vector of pts generate the corresponding Bézier segment.\n\n\n\n\n\n","category":"type"},{"location":"objectives/#ManoptExamples.L2_acceleration_Bezier-Union{Tuple{P}, Tuple{ManifoldsBase.AbstractManifold, AbstractVector{P}, AbstractVector{<:Integer}, AbstractVector{<:AbstractFloat}, AbstractFloat, AbstractVector{P}}} where P","page":"Objectives","title":"ManoptExamples.L2_acceleration_Bezier","text":"L2_acceleration_Bezier(M,B,pts,λ,d)\n\ncompute the value of the discrete Acceleration of the composite Bezier curve together with a data term, i.e.\n\nfracλ2sum_i=0^N d_mathcal M(d_i c_B(i))^2+\nsum_i=1^N-1fracd^2_2 B(t_i-1) B(t_i) B(t_i+1)Delta_t^3\n\nwhere for this formula the pts along the curve are equispaced and denoted by t_i and d_2 refers to the second order absolute difference second_order_Total_Variation (squared), the junction points are denoted by p_i, and to each p_i corresponds one data item in the manifold points given in d. For details on the acceleration approximation, see acceleration_Bezier. Note that the Bézier-curve is given in reduces form as a point on a PowerManifold, together with the degrees of the segments and assuming a differentiable curve, the segments can internally be reconstructed.\n\nSee also\n\ngrad_L2_acceleration_Bezier, acceleration_Bezier, grad_acceleration_Bezier\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.acceleration_Bezier-Union{Tuple{P}, Tuple{ManifoldsBase.AbstractManifold, AbstractVector{P}, AbstractVector{<:Integer}, AbstractVector{<:AbstractFloat}}} where P","page":"Objectives","title":"ManoptExamples.acceleration_Bezier","text":"acceleration_Bezier(\n M::AbstractManifold,\n B::AbstractVector{P},\n degrees::AbstractVector{<:Integer},\n T::AbstractVector{<:AbstractFloat},\n) where {P}\n\ncompute the value of the discrete Acceleration of the composite Bezier curve\n\nsum_i=1^N-1fracd^2_2 B(t_i-1) B(t_i) B(t_i+1)Delta_t^3\n\nwhere for this formula the pts along the curve are equispaced and denoted by t_i, i=1N, and d_2 refers to the second order absolute difference second_order_Total_Variation (squared). Note that the Bézier-curve is given in reduces form as a point on a PowerManifold, together with the degrees of the segments and assuming a differentiable curve, the segments can internally be reconstructed.\n\nThis acceleration discretization was introduced in Bergmann, Gousenbourger, Front. Appl. Math. Stat., 2018.\n\nSee also\n\ngrad_acceleration_Bezier, L2_acceleration_Bezier, grad_L2_acceleration_Bezier\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.adjoint_differential_Bezier_control_points-Tuple{ManifoldsBase.AbstractManifold, AbstractVector{<:ManoptExamples.BezierSegment}, AbstractVector, AbstractVector}","page":"Objectives","title":"ManoptExamples.adjoint_differential_Bezier_control_points","text":"adjoint_differential_Bezier_control_points(\n M::AbstractManifold,\n T::AbstractVector,\n X::AbstractVector,\n)\nadjoint_differential_Bezier_control_points!(\n M::AbstractManifold,\n Y::AbstractVector{<:BezierSegment},\n T::AbstractVector,\n X::AbstractVector,\n)\n\nEvaluate the adjoint of the differential with respect to the controlpoints at several times T. This can be computed in place of Y.\n\nSee de_Casteljau for more details on the curve.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.adjoint_differential_Bezier_control_points-Tuple{ManifoldsBase.AbstractManifold, AbstractVector{<:ManoptExamples.BezierSegment}, Any, Any}","page":"Objectives","title":"ManoptExamples.adjoint_differential_Bezier_control_points","text":"adjoint_differential_Bezier_control_points(\n M::AbstractManifold,\n B::AbstractVector{<:BezierSegment},\n t,\n X\n)\nadjoint_differential_Bezier_control_points!(\n M::AbstractManifold,\n Y::AbstractVector{<:BezierSegment},\n B::AbstractVector{<:BezierSegment},\n t,\n X\n)\n\nevaluate the adjoint of the differential of a composite Bézier curve on the manifold M with respect to its control points b based on a points T=(t_i)_i=1^n that are pointwise in t_i01 on the curve and given corresponding tangential vectors X = (η_i)_i=1^n, η_iT_β(t_i)mathcal M This can be computed in place of Y.\n\nSee de_Casteljau for more details on the curve.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.adjoint_differential_Bezier_control_points-Tuple{ManifoldsBase.AbstractManifold, ManoptExamples.BezierSegment, AbstractVector, AbstractVector}","page":"Objectives","title":"ManoptExamples.adjoint_differential_Bezier_control_points","text":"adjoint_differential_Bezier_control_points(\n M::AbstractManifold,\n b::BezierSegment,\n t::AbstractVector,\n X::AbstractVector,\n)\nadjoint_differential_Bezier_control_points!(\n M::AbstractManifold,\n Y::BezierSegment,\n b::BezierSegment,\n t::AbstractVector,\n X::AbstractVector,\n)\n\nevaluate the adjoint of the differential of a Bézier curve on the manifold M with respect to its control points b based on a points T=(t_i)_i=1^n that are pointwise in t_i01 on the curve and given corresponding tangential vectors X = (η_i)_i=1^n, η_iT_β(t_i)mathcal M This can be computed in place of Y.\n\nSee de_Casteljau for more details on the curve and Bergmann, Gousenbourger, Front. Appl. Math. Stat., 2018\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.adjoint_differential_Bezier_control_points-Tuple{ManifoldsBase.AbstractManifold, ManoptExamples.BezierSegment, Any, Any}","page":"Objectives","title":"ManoptExamples.adjoint_differential_Bezier_control_points","text":"adjoint_differential_Bezier_control_points(M::AbstractManifold, b::BezierSegment, t, η)\nadjoint_differential_Bezier_control_points!(\n M::AbstractManifold,\n Y::BezierSegment,\n b::BezierSegment,\n t,\n η,\n)\n\nevaluate the adjoint of the differential of a Bézier curve on the manifold M with respect to its control points b based on a point t01 on the curve and a tangent vector ηT_β(t)mathcal M. This can be computed in place of Y.\n\nSee de_Casteljau for more details on the curve.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.de_Casteljau-Tuple{ManifoldsBase.AbstractManifold, Vararg{Any}}","page":"Objectives","title":"ManoptExamples.de_Casteljau","text":"de_Casteljau(M::AbstractManifold, b::BezierSegment NTuple{N,P}) -> Function\n\nreturn the Bézier curve β(b_0b_n) 01 mathcal M defined by the control points b_0b_nmathcal M, nmathbb N, as a BezierSegment. This function implements de Casteljau's algorithm Casteljau, 1959, Casteljau, 1963 generalized to manifolds by Popiel, Noakes, J Approx Theo, 2007: Let γ_ab(t) denote the shortest geodesic connecting abmathcal M. Then the curve is defined by the recursion\n\nbeginaligned\n β(tb_0b_1) = gamma_b_0b_1(t)\n β(tb_0b_n) = gamma_β(tb_0b_n-1) β(tb_1b_n)(t)\nendaligned\n\nand P is the type of a point on the Manifold M.\n\nde_Casteljau(M::AbstractManifold, B::AbstractVector{<:BezierSegment}) -> Function\n\nGiven a vector of Bézier segments, i.e. a vector of control points B=bigl( (b_00b_n_00)(b_0m b_n_mm) bigr), where the different segments might be of different degree(s) n_0n_m. The resulting composite Bézier curve c_B0m mathcal M consists of m segments which are Bézier curves.\n\nc_B(t) =\n begincases\n β(t b_00b_n_00) text if t 01\n β(t-i b_0ib_n_ii) text if \n t(ii+1 quad i1m-1\n endcases\n\nde_Casteljau(M::AbstractManifold, b::BezierSegment, t::Real)\nde_Casteljau(M::AbstractManifold, B::AbstractVector{<:BezierSegment}, t::Real)\nde_Casteljau(M::AbstractManifold, b::BezierSegment, T::AbstractVector) -> AbstractVector\nde_Casteljau(\n M::AbstractManifold,\n B::AbstractVector{<:BezierSegment},\n T::AbstractVector\n) -> AbstractVector\n\nEvaluate the Bézier curve at time t or at times t in T.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.differential_Bezier_control_points-Tuple{ManifoldsBase.AbstractManifold, AbstractVector{<:ManoptExamples.BezierSegment}, AbstractVector, AbstractVector{<:ManoptExamples.BezierSegment}}","page":"Objectives","title":"ManoptExamples.differential_Bezier_control_points","text":"differential_Bezier_control_points(\n M::AbstractManifold,\n B::AbstractVector{<:BezierSegment},\n T::AbstractVector\n Ξ::AbstractVector{<:BezierSegment}\n)\ndifferential_Bezier_control_points!(\n M::AbstractManifold,\n Θ::AbstractVector{<:BezierSegment}\n B::AbstractVector{<:BezierSegment},\n T::AbstractVector\n Ξ::AbstractVector{<:BezierSegment}\n)\n\nevaluate the differential of the composite Bézier curve with respect to its control points B and tangent vectors Ξ in the tangent spaces of the control points. The result is the “change” of the curve at the points in T, which are elementwise in 0N, and each depending the corresponding segment(s). Here, N is the length of B. For the mutating variant the result is computed in Θ.\n\nSee de_Casteljau for more details on the curve and Bergmann, Gousenbourger, Front. Appl. Math. Stat., 2018.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.differential_Bezier_control_points-Tuple{ManifoldsBase.AbstractManifold, AbstractVector{<:ManoptExamples.BezierSegment}, Any, AbstractVector{<:ManoptExamples.BezierSegment}}","page":"Objectives","title":"ManoptExamples.differential_Bezier_control_points","text":"differential_Bezier_control_points(\n M::AbstractManifold,\n B::AbstractVector{<:BezierSegment},\n t,\n X::AbstractVector{<:BezierSegment}\n)\ndifferential_Bezier_control_points!(\n M::AbstractManifold,\n Y::AbstractVector{<:BezierSegment}\n B::AbstractVector{<:BezierSegment},\n t,\n X::AbstractVector{<:BezierSegment}\n)\n\nevaluate the differential of the composite Bézier curve with respect to its control points B and tangent vectors Ξ in the tangent spaces of the control points. The result is the “change” of the curve at t0N, which depends only on the corresponding segment. Here, N is the length of B. The computation can be done in place of Y.\n\nSee de_Casteljau for more details on the curve.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.differential_Bezier_control_points-Tuple{ManifoldsBase.AbstractManifold, ManoptExamples.BezierSegment, AbstractVector, ManoptExamples.BezierSegment}","page":"Objectives","title":"ManoptExamples.differential_Bezier_control_points","text":"differential_Bezier_control_points(\n M::AbstractManifold,\n b::BezierSegment,\n T::AbstractVector,\n X::BezierSegment,\n)\ndifferential_Bezier_control_points!(\n M::AbstractManifold,\n Y,\n b::BezierSegment,\n T::AbstractVector,\n X::BezierSegment,\n)\n\nevaluate the differential of the Bézier curve with respect to its control points b and tangent vectors X in the tangent spaces of the control points. The result is the “change” of the curve at the points T, elementwise in t01. The computation can be done in place of Y.\n\nSee de_Casteljau for more details on the curve.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.differential_Bezier_control_points-Tuple{ManifoldsBase.AbstractManifold, ManoptExamples.BezierSegment, Any, ManoptExamples.BezierSegment}","page":"Objectives","title":"ManoptExamples.differential_Bezier_control_points","text":"differential_Bezier_control_points(M::AbstractManifold, b::BezierSegment, t::Float, X::BezierSegment)\ndifferential_Bezier_control_points!(\n M::AbstractManifold,\n Y,\n b::BezierSegment,\n t,\n X::BezierSegment\n)\n\nevaluate the differential of the Bézier curve with respect to its control points b and tangent vectors X given in the tangent spaces of the control points. The result is the “change” of the curve at t01. The computation can be done in place of Y.\n\nSee de_Casteljau for more details on the curve.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.get_Bezier_degree-Tuple{ManifoldsBase.AbstractManifold, ManoptExamples.BezierSegment}","page":"Objectives","title":"ManoptExamples.get_Bezier_degree","text":"get_Bezier_degree(M::AbstractManifold, b::BezierSegment)\n\nreturn the degree of the Bézier curve represented by the tuple b of control points on the manifold M, i.e. the number of points minus 1.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.get_Bezier_degrees-Tuple{ManifoldsBase.AbstractManifold, AbstractVector{<:ManoptExamples.BezierSegment}}","page":"Objectives","title":"ManoptExamples.get_Bezier_degrees","text":"get_Bezier_degrees(M::AbstractManifold, B::AbstractVector{<:BezierSegment})\n\nreturn the degrees of the components of a composite Bézier curve represented by tuples in B containing points on the manifold M.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.get_Bezier_inner_points-Tuple{ManifoldsBase.AbstractManifold, AbstractVector{<:ManoptExamples.BezierSegment}}","page":"Objectives","title":"ManoptExamples.get_Bezier_inner_points","text":"get_Bezier_inner_points(M::AbstractManifold, B::AbstractVector{<:BezierSegment} )\nget_Bezier_inner_points(M::AbstractManifold, b::BezierSegment)\n\nreturns the inner (i.e. despite start and end) points of the segments of the composite Bézier curve specified by the control points B. For a single segment b, its inner points are returned\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.get_Bezier_junction_tangent_vectors-Tuple{ManifoldsBase.AbstractManifold, AbstractVector{<:ManoptExamples.BezierSegment}}","page":"Objectives","title":"ManoptExamples.get_Bezier_junction_tangent_vectors","text":"get_Bezier_junction_tangent_vectors(M::AbstractManifold, B::AbstractVector{<:BezierSegment})\nget_Bezier_junction_tangent_vectors(M::AbstractManifold, b::BezierSegment)\n\nreturns the tangent vectors at start and end points of the composite Bézier curve pointing from a junction point to the first and last inner control points for each segment of the composite Bezier curve specified by the control points B, either a vector of segments of controlpoints.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.get_Bezier_junctions","page":"Objectives","title":"ManoptExamples.get_Bezier_junctions","text":"get_Bezier_junctions(M::AbstractManifold, B::AbstractVector{<:BezierSegment})\nget_Bezier_junctions(M::AbstractManifold, b::BezierSegment)\n\nreturns the start and end point(s) of the segments of the composite Bézier curve specified by the control points B. For just one segment b, its start and end points are returned.\n\n\n\n\n\n","category":"function"},{"location":"objectives/#ManoptExamples.get_Bezier_points","page":"Objectives","title":"ManoptExamples.get_Bezier_points","text":"get_Bezier_points(\n M::AbstractManifold,\n B::AbstractVector{<:BezierSegment},\n reduce::Symbol=:default\n)\nget_Bezier_points(M::AbstractManifold, b::BezierSegment, reduce::Symbol=:default)\n\nreturns the control points of the segments of the composite Bézier curve specified by the control points B, either a vector of segments of controlpoints or a.\n\nThis method reduces the points depending on the optional reduce symbol\n\n:default: no reduction is performed\n:continuous: for a continuous function, the junction points are doubled at b_0i=b_n_i-1i-1, so only b_0i is in the vector.\n:differentiable: for a differentiable function additionally log_b_0ib_1i = -log_b_n_i-1i-1b_n_i-1-1i-1 holds. hence b_n_i-1-1i-1 is omitted.\n\nIf only one segment is given, all points of b, b.pts, is returned.\n\n\n\n\n\n","category":"function"},{"location":"objectives/#ManoptExamples.get_Bezier_segments-Union{Tuple{P}, Tuple{ManifoldsBase.AbstractManifold, Vector{P}, Any}, Tuple{ManifoldsBase.AbstractManifold, Vector{P}, Any, Symbol}} where P","page":"Objectives","title":"ManoptExamples.get_Bezier_segments","text":"get_Bezier_segments(M::AbstractManifold, c::AbstractArray{P}, d[, s::Symbol=:default])\n\nreturns the array of BezierSegments B of a composite Bézier curve reconstructed from an array c of points on the manifold M and an array of degrees d.\n\nThere are a few (reduced) representations that can get extended; see also get_Bezier_points. For ease of the following, let c=(c_1c_k) and d=(d_1d_m), where m denotes the number of components the composite Bézier curve consists of. Then\n\n:default: k = m + sum_i=1^m d_i since each component requires one point more than its degree. The points are then ordered in tuples, i.e.\nB = bigl c_1c_d_1+1 (c_d_1+2c_d_1+d_2+2 c_k-m+1+d_mc_k bigr\n:continuous: k = 1+ sum_i=1m d_i, since for a continuous curve start and end point of successive components are the same, so the very first start point and the end points are stored.\nB = bigl c_1c_d_1+1 c_d_1+1c_d_1+d_2+1 c_k-1+d_mb_k) bigr\n:differentiable – for a differentiable function additionally to the last explanation, also the second point of any segment was not stored except for the first segment. Hence k = 2 - m + sum_i=1m d_i and at a junction point b_n with its given prior point c_n-1, i.e. this is the last inner point of a segment, the first inner point in the next segment the junction is computed as b = exp_c_n(-log_c_n c_n-1) such that the assumed differentiability holds\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.grad_L2_acceleration_Bezier-Union{Tuple{P}, Tuple{ManifoldsBase.AbstractManifold, AbstractVector{P}, AbstractVector{<:Integer}, AbstractVector, Any, AbstractVector{P}}} where P","page":"Objectives","title":"ManoptExamples.grad_L2_acceleration_Bezier","text":"grad_L2_acceleration_Bezier(\n M::AbstractManifold,\n B::AbstractVector{P},\n degrees::AbstractVector{<:Integer},\n T::AbstractVector,\n λ,\n d::AbstractVector{P}\n) where {P}\n\ncompute the gradient of the discretized acceleration of a composite Bézier curve on the Manifold M with respect to its control points B together with a data term that relates the junction points p_i to the data d with a weight λ compared to the acceleration. The curve is evaluated at the points given in pts (elementwise in 0N), where N is the number of segments of the Bézier curve. The summands are grad_distance for the data term and grad_acceleration_Bezier for the acceleration with interpolation constrains. Here the get_Bezier_junctions are included in the optimization, i.e. setting λ=0 yields the unconstrained acceleration minimization. Note that this is ill-posed, since any Bézier curve identical to a geodesic is a minimizer.\n\nNote that the Bézier-curve is given in reduces form as a point on a PowerManifold, together with the degrees of the segments and assuming a differentiable curve, the segments can internally be reconstructed.\n\nSee also\n\ngrad_acceleration_Bezier, L2_acceleration_Bezier, acceleration_Bezier.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.grad_acceleration_Bezier-Tuple{ManifoldsBase.AbstractManifold, AbstractVector, AbstractVector{<:Integer}, AbstractVector}","page":"Objectives","title":"ManoptExamples.grad_acceleration_Bezier","text":"grad_acceleration_Bezier(\n M::AbstractManifold,\n B::AbstractVector,\n degrees::AbstractVector{<:Integer}\n T::AbstractVector\n)\n\ncompute the gradient of the discretized acceleration of a (composite) Bézier curve c_B(t) on the Manifold M with respect to its control points B given as a point on the PowerManifold assuming C1 conditions and known degrees. The curve is evaluated at the points given in T (elementwise in 0N, where N is the number of segments of the Bézier curve). The get_Bezier_junctions are fixed for this gradient (interpolation constraint). For the unconstrained gradient, see grad_L2_acceleration_Bezier and set λ=0 therein. This gradient is computed using adjoint_Jacobi_fields. For details, see Bergmann, Gousenbourger, Front. Appl. Math. Stat., 2018. See de_Casteljau for more details on the curve.\n\nSee also\n\nacceleration_Bezier, grad_L2_acceleration_Bezier, L2_acceleration_Bezier.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#RiemannianMean","page":"Objectives","title":"Riemannian Mean","text":"","category":"section"},{"location":"objectives/","page":"Objectives","title":"Objectives","text":"See the Riemannian mean example to see these in use.","category":"page"},{"location":"objectives/","page":"Objectives","title":"Objectives","text":"Modules = [ManoptExamples]\nPages = [\"objectives/RiemannianMean.jl\"]\nOrder = [:type, :function]\nPrivate = true","category":"page"},{"location":"objectives/#ManoptExamples.RiemannianMeanCost","page":"Objectives","title":"ManoptExamples.RiemannianMeanCost","text":"RiemannianMeanCost{P}\n\nA functor representing the Riemannian center of mass (or Riemannian mean) cost function.\n\nFor a given set of points d_1ldotsd_N this cost function is defined as\n\nf(p) = sum_j=i^N d_mathcal M^2(d_i p)\n\nwhere d_mathcal M is the distance on a Riemannian manifold.\n\nConstructor\n\nRiemannianMeanCost(M::AbstractManifold, data::AbstractVector{<:P}) where {P}\n\nInitialize the cost function to a data set data of points on a manfiold M, where each point is of type P.\n\nSee also\n\nRiemannianMeanGradient!!, Riemannian_mean_objective\n\n\n\n\n\n","category":"type"},{"location":"objectives/#ManoptExamples.RiemannianMeanGradient!!","page":"Objectives","title":"ManoptExamples.RiemannianMeanGradient!!","text":"RiemannianMeanGradient!!{P} where P\n\nA functor representing the Riemannian center of mass (or Riemannian mean) cost function.\n\nFor a given set of points d_1ldotsd_N this cost function is defined as\n\noperatornamegradf(p) = sum_j=i^N log_p d_i\n\nwhere d_mathcal M is the distance on a Riemannian manifold and we employ grad_distance to compute the single summands.\n\nThis functor provides both the allocating variant grad_f(M,p) as well as the in-place variant grad_f!(M, X, p) which computes the gradient in-place of X.\n\nConstructors\n\nRiemannianMeanGradient!!(data::AbstractVector{P}, initial_vector::T=nothing) where {P,T}\n\nGenerate the Riemannian mean gradient based on some data points data an intial tangent vector initial_vector. If you do not provide an initial tangent vector to allocate the intermediate storage of a tangent vector, you can only use the allocating variant.\n\nRiemannianMeanGradient!!(\n M::AbstractManifold,\n data::AbstractVector{P};\n initial_vector::T=zero_vector(M, first(data)),\n) where {P,T}\n\nInitialize the Riemannian mean gradient, where the internal storage for tangent vectors can be created automatically, since the Riemannian manifold M is provideed.\n\nSee also\n\nRiemannianMeanCost, Riemannian_mean_objective\n\n\n\n\n\n","category":"type"},{"location":"objectives/#ManoptExamples.Riemannian_mean_objective","page":"Objectives","title":"ManoptExamples.Riemannian_mean_objective","text":"Riemannian_mean_objective(data, initial_vector=nothing, evaluation=Manopt.AllocatingEvaluation())\nRiemannian_mean_objective(M, data;\ninitial_vector=zero_vector(M, first(data)),\nevaluation=AllocatingEvaluton()\n)\n\nGenerate the objective for the Riemannian mean task for some given vector of data points on the Riemannian manifold M.\n\nSee also\n\nRiemannianMeanCost, RiemannianMeanGradient!!\n\nnote: Note\nThe first constructor should only be used if an additional storage of the vector is not feasible, since initialising the initial_vector to nothing disables the in-place variant. Hence the evaluation is a positional argument, since it only can be changed, if a vector is provided.\n\nnote: Note\n\n\nThe objective is available when Manopt.jl is loaded.\n\n\n\n\n\n","category":"function"},{"location":"objectives/#RobustPCA","page":"Objectives","title":"Robust PCA","text":"","category":"section"},{"location":"objectives/","page":"Objectives","title":"Objectives","text":"See the Robust PCA example to see these in use.","category":"page"},{"location":"objectives/","page":"Objectives","title":"Objectives","text":"Modules = [ManoptExamples]\nPages = [\"objectives/RobustPCA.jl\"]\nOrder = [:type, :function]\nPrivate = true","category":"page"},{"location":"objectives/#ManoptExamples.RobustPCACost","page":"Objectives","title":"ManoptExamples.RobustPCACost","text":"RobustPCACost{D,F}\n\nA functor representing the Riemannian robust PCA function on the Grassmann manifold. For some given (column) data Dmathbb R^dtimes n the cost function is defined on some operatornameGr(dm), mn as the sum of the distances of the columns D_i to the subspace spanned by pinoperatornameGr(dm) (represented as a point on the Stiefel manifold). The function reads\n\nf(U) = frac1nsum_i=1^n lVert pp^mathrmTD_i - D_irVert\n\nThis cost additionally provides a Huber regularisation of the cost, that is for some ε0 one use ℓ_ε(x) = sqrtx^2+ε^2 - ε in\n\nf_ε(p) = frac1nsum_i=1^n ℓ_εbigl(lVert pp^mathrmTD_i - D_irVertbigr)\n\nNote that this is a mutable struct so you can adapt the ε later on.\n\nConstructor\n\nRobustPCACost(data::AbstractMatrix, ε=1.0)\nRobustPCACost(M::Grassmann, data::AbstractMatrix, ε=1.0)\n\nInitialize the robust PCA cost to some data D, and some regularization ε. The manifold is optional to comply with all examples, but it is not needed here to construct the cost.\n\n\n\n\n\n","category":"type"},{"location":"objectives/#ManoptExamples.RobustPCAGrad!!","page":"Objectives","title":"ManoptExamples.RobustPCAGrad!!","text":"RobustPCAGrad!!{D,F}\n\nA functor representing the Riemannian robust PCA gradient on the Grassmann manifold. For some given (column) data Xmathbb R^ptimes n the gradient of the RobustPCACost can be computed by projecting the Euclidean gradient onto the corresponding tangent space.\n\nNote that this is a mutable struct so you can adapt the ε later on.\n\nConstructor\n\nRobustPCAGrad!!(data, ε=1.0)\nRobustPCAGrad!!(M::Grassmannian{d,m}, data, ε=1.0; evaluation=AllocatingEvaluation())\n\nInitialize the robust PCA cost to some data D, and some regularization ε. The manifold is optional to comply with all examples, but it is not needed here to construct the cost. Also the evaluation= keyword is present only for unification of the interfaces. Indeed, independent of that keyword the functor always works in both variants.\n\n\n\n\n\n","category":"type"},{"location":"objectives/#ManoptExamples.robust_PCA_objective","page":"Objectives","title":"ManoptExamples.robust_PCA_objective","text":"robust_PCA_objective(data::AbstractMatrix, ε=1.0; evaluation=AllocatingEvaluation())\nrobust_PCA_objective(M, data::AbstractMatrix, ε=1.0; evaluation=AllocatingEvaluton())\n\nGenerate the objective for the robust PCA task for some given data D and Huber regularization parameter ε.\n\nSee also\n\nRobustPCACost, RobustPCAGrad!!\n\nnote: Note\nSince the construction is independent of the manifold, that argument is optional and mainly provided to comply with other objectives. Similarly, independent of the evaluation, indeed the gradient always allows for both the allocating and the in-place variant to be used, though that keyword is used to setup the objective.\n\nnote: Note\n\n\nThe objective is available when Manopt.jl is loaded.\n\n\n\n\n\n","category":"function"},{"location":"objectives/#Rosenbrock","page":"Objectives","title":"Rosenbrock Function","text":"","category":"section"},{"location":"objectives/","page":"Objectives","title":"Objectives","text":"See the Rosenbrock example and The Difference of Convex Rosenbrock Example to see these in use.","category":"page"},{"location":"objectives/","page":"Objectives","title":"Objectives","text":"Modules = [ManoptExamples]\nPages = [\"objectives/Rosenbrock.jl\"]\nOrder = [:type, :function]\nPrivate = true","category":"page"},{"location":"objectives/#ManoptExamples.RosenbrockCost","page":"Objectives","title":"ManoptExamples.RosenbrockCost","text":"RosenbrockCost\n\nProvide the Rosenbrock function in 2D, i.e. for some ab ℝ\n\nf(mathcal M p) = a(p_1^2-p_2)^2 + (p_1-b)^2\n\nwhich means that for the 2D case, the manifold mathcal M is ignored.\n\nSee also 📖 Rosenbrock (with slightly different parameter naming).\n\nConstructor\n\nf = Rosenbrock(a,b)\n\ngenerates the struct/function of the Rosenbrock cost.\n\n\n\n\n\n","category":"type"},{"location":"objectives/#ManoptExamples.RosenbrockGradient!!","page":"Objectives","title":"ManoptExamples.RosenbrockGradient!!","text":"RosenbrockGradient\n\nProvide Eclidean GRadient fo the Rosenbrock function in 2D, i.e. for some ab ℝ\n\nnabla f(mathcal M p) = beginpmatrix\n 4a(p_1^2-p_2)p_1 + 2(p_1-b) \n -2a(p_1^2-p_2)\nendpmatrix\n\ni.e. also here the manifold is ignored.\n\nConstructor\n\nRosenbrockGradient(a,b)\n\nFunctors\n\ngrad_f!!(M,p)\ngrad_f!!(M, X, p)\n\nevaluate the gradient at p the manifoldmathcal M is ignored.\n\n\n\n\n\n","category":"type"},{"location":"objectives/#ManoptExamples.RosenbrockMetric","page":"Objectives","title":"ManoptExamples.RosenbrockMetric","text":"RosenbrockMetric <: AbstractMetric\n\nA metric related to the Rosenbrock problem, where the metric at a point pmathbb R^2 is given by\n\nXY_mathrmRbp = X^mathrmTG_pY qquad\nG_p = beginpmatrix\n 1+4p_1^2 -2p_1 \n -2p_1 1\nendpmatrix\n\nwhere the mathrmRb stands for Rosenbrock\n\n\n\n\n\n","category":"type"},{"location":"objectives/#Base.exp-Tuple{Manifolds.MetricManifold{ℝ, <:Manifolds.Euclidean{<:Union{ManifoldsBase.TypeParameter{Tuple{2}}, Tuple{var\"#s1\"} where var\"#s1\"<:Int64}, ℝ}, ManoptExamples.RosenbrockMetric}, Any, Any, Number}","page":"Objectives","title":"Base.exp","text":"q = exp(::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, p, X)\nexp!(::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, q, p, X)\n\nCompute the exponential map with respect to the RosenbrockMetric.\n\n q = beginpmatrix p_1 + X_1 p_2+X_2+X_1^2endpmatrix\n\n\n\n\n\n","category":"method"},{"location":"objectives/#Base.log-Tuple{Manifolds.MetricManifold{ℝ, <:Manifolds.Euclidean{<:Union{ManifoldsBase.TypeParameter{Tuple{2}}, Tuple{var\"#s8\"} where var\"#s8\"<:Int64}, ℝ}, ManoptExamples.RosenbrockMetric}, Any, Any}","page":"Objectives","title":"Base.log","text":"X = log(::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, p, q)\nlog!(::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, X, p, q)\n\nCompute the logarithmic map with respect to the RosenbrockMetric. The formula reads for any j 1m\n\nX = beginpmatrix\n q_1 - p_1 \n q_2 - p_2 + (q_1 - p_1)^2\nendpmatrix\n\n\n\n\n\n","category":"method"},{"location":"objectives/#Manifolds.inverse_local_metric-Tuple{Manifolds.MetricManifold{ℝ, <:Manifolds.Euclidean{<:Union{ManifoldsBase.TypeParameter{Tuple{2}}, Tuple{var\"#s1\"} where var\"#s1\"<:Int64}, ℝ}, ManoptExamples.RosenbrockMetric}, Any}","page":"Objectives","title":"Manifolds.inverse_local_metric","text":"inverse_local_metric(::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, p)\n\nReturn the inverse of the local metric matrix of the RosenbrockMetric in the canonical unit vector basis of the tangent space T_pmathbb R^2 given as\n\nG^-1_p =\nbeginpmatrix\n 1 2p_1\n 2p_1 1+4p_1^2 \nendpmatrix\n\n\n\n\n\n","category":"method"},{"location":"objectives/#Manifolds.local_metric-Tuple{Manifolds.MetricManifold{ℝ, <:Manifolds.Euclidean{<:Union{ManifoldsBase.TypeParameter{Tuple{2}}, Tuple{var\"#s1\"} where var\"#s1\"<:Int64}, ℝ}, ManoptExamples.RosenbrockMetric}, Any}","page":"Objectives","title":"Manifolds.local_metric","text":"local_metric(::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, p)\n\nReturn the local metric matrix of the RosenbrockMetric in the canonical unit vector basis of the tangent space T_pmathbb R^2 given as\n\nG_p = beginpmatrix\n 1+4p_1^2 -2p_1 \n -2p_1 1\nendpmatrix\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManifoldsBase.change_representer-Tuple{Manifolds.MetricManifold{ℝ, <:Manifolds.Euclidean{<:Union{ManifoldsBase.TypeParameter{Tuple{2}}, Tuple{var\"#s8\"} where var\"#s8\"<:Int64}, ℝ}, ManoptExamples.RosenbrockMetric}, ManifoldsBase.EuclideanMetric, Any, Any}","page":"Objectives","title":"ManifoldsBase.change_representer","text":"Y = change_representer(M::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, ::EuclideanMetric, p, X)\nchange_representer!(M::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, Y, ::EuclideanMetric, p, X)\n\nGiven the Euclidan gradient X at p, this function computes the corresponting Riesz representer Ysuch that⟨X,Z⟩ = ⟨ Y, Z ⟩_{\\mathrm{Rb},p}holds for allZ, in other wordsY = G(p)^{-1}X`.\n\nthis function is used in riemannian_gradient to convert a Euclidean into a Riemannian gradient.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManifoldsBase.inner-Tuple{Manifolds.MetricManifold{ℝ, <:Manifolds.Euclidean{<:Union{ManifoldsBase.TypeParameter{Tuple{2}}, Tuple{var\"#s1\"} where var\"#s1\"<:Int64}, ℝ}, ManoptExamples.RosenbrockMetric}, Any, Any, Any}","page":"Objectives","title":"ManifoldsBase.inner","text":"inner(M::MetricManifold{ℝ,Euclidean{Tuple{2},ℝ},RosenbrockMetric}, p, X, Y)\n\nCompute the inner product on mathbb R^2 with respect to the RosenbrockMetric, i.e. for XY in T_pmathcal M we have\n\nXY_mathrmRbp = X^mathrmTG_pY qquad\nG_p = beginpmatrix\n 1+4p_1^2 -2p_1\n -2p_1 1\nendpmatrix\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.Rosenbrock_objective","page":"Objectives","title":"ManoptExamples.Rosenbrock_objective","text":"Rosenbrock_objective(M::AbstractManifold=DefaultManifold(), a=100.0, b=1.0, evaluation=AllocatingEvaluation())\n\nReturn the gradient objective of the Rosenbrock example.\n\nSee also RosenbrockCost, RosenbrockGradient!!\n\nnote: Note\n\n\nThe objective is available when Manopt.jl is loaded.\n\n\n\n\n\n","category":"function"},{"location":"objectives/#ManoptExamples.minimizer-Tuple{ManoptExamples.RosenbrockCost}","page":"Objectives","title":"ManoptExamples.minimizer","text":"minimizer(::RosenbrockCost)\n\nReturn the minimizer of the RosenbrockCost, which is given by\n\np^* = beginpmatrix bb^2 endpmatrix\n\n\n\n\n\n","category":"method"},{"location":"objectives/#Total-Variation","page":"Objectives","title":"Total Variation","text":"","category":"section"},{"location":"objectives/","page":"Objectives","title":"Objectives","text":"See the Total Variation example to see these in use.","category":"page"},{"location":"objectives/","page":"Objectives","title":"Objectives","text":"Modules = [ManoptExamples]\nPages = [\"objectives/TotalVariation.jl\"]\nOrder = [:type, :function]\nPrivate = true","category":"page"},{"location":"objectives/#ManoptExamples.Intrinsic_infimal_convolution_TV12-Tuple{ManifoldsBase.AbstractManifold, Vararg{Any, 5}}","page":"Objectives","title":"ManoptExamples.Intrinsic_infimal_convolution_TV12","text":"Intrinsic_infimal_convolution_TV12(M, f, u, v, α, β)\n\nCompute the intrinsic infimal convolution model, where the addition is replaced by a mid point approach and the two functions involved are second_order_Total_Variation and Total_Variation. The model reads\n\nE(uv) =\n frac12sum_i mathcal G\n d_mathcal Mbigl(g(frac12v_iw_i)f_ibigr)\n +alphabigl( βmathrmTV(v) + (1-β)mathrmTV_2(w) bigr)\n\nfor more details see [BFPS17, BFPS18].\n\nSee also\n\nTotal_Variation, second_order_Total_Variation\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.L2_Total_Variation-NTuple{4, Any}","page":"Objectives","title":"ManoptExamples.L2_Total_Variation","text":"L2_Total_Variation(M, p_data, α, p)\n\ncompute the ℓ^2-TV functional on the PowerManifold M for given (fixed) data p_data (on M), a nonnegative weight α, and evaluated at p (on M), i.e.\n\nE(p) = d_mathcal M^2(fp) + alpha operatornameTV(p)\n\nSee also\n\nTotal_Variation\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.L2_Total_Variation_1_2-Tuple{ManifoldsBase.PowerManifold, Vararg{Any, 4}}","page":"Objectives","title":"ManoptExamples.L2_Total_Variation_1_2","text":"L2_Total_Variation_1_2(M, f, α, β, x)\n\ncompute the ℓ^2-TV-TV2 functional on the PowerManifold manifold M for given (fixed) data f (on M), nonnegative weight α, β, and evaluated at x (on M), i.e.\n\nE(x) = d_mathcal M^2(fx) + alphaoperatornameTV(x)\n + βoperatornameTV_2(x)\n\nSee also\n\nTotal_Variation, second_order_Total_Variation\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.L2_second_order_Total_Variation-Tuple{ManifoldsBase.PowerManifold, Any, Any, Any}","page":"Objectives","title":"ManoptExamples.L2_second_order_Total_Variation","text":"L2_second_order_Total_Variation(M, f, β, x)\n\ncompute the ℓ^2-TV2 functional on the PowerManifold manifold M for given data f, nonnegative parameter β, and evaluated at x, i.e.\n\nE(x) = d_mathcal M^2(fx) + βoperatornameTV_2(x)\n\nas used in [BBSW16].\n\nSee also\n\nsecond_order_Total_Variation\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.Total_Variation","page":"Objectives","title":"ManoptExamples.Total_Variation","text":"Total_Variation(M,x [,p=2,q=1])\n\nCompute the operatornameTV^p functional for data xon the PowerManifold manifold M, i.e. mathcal M = mathcal N^n, where n mathbb N^k denotes the dimensions of the data x. Let mathcal I_i denote the forward neighbors, i.e. with mathcal G as all indices from mathbf1 mathbb N^k to n we have mathcal I_i = i+e_j j=1kcap mathcal G. The formula reads\n\nE^q(x) = sum_i mathcal G\n bigl( sum_j mathcal I_i d^p_mathcal M(x_ix_j) bigr)^qp\n\nsee [WDS14] for more details. In long function names, this might be shortened to TV1 and the 1 might be ommitted if only total variation is present.\n\nSee also\n\ngrad_Total_Variation, prox_Total_Variation, second_order_Total_Variation\n\n\n\n\n\n","category":"function"},{"location":"objectives/#ManoptExamples.adjoint_differential_forward_logs-Union{Tuple{TPR}, Tuple{TSize}, Tuple{TM}, Tuple{𝔽}, Tuple{ManifoldsBase.PowerManifold{𝔽, TM, TSize, TPR}, Any, Any}} where {𝔽, TM, TSize, TPR}","page":"Objectives","title":"ManoptExamples.adjoint_differential_forward_logs","text":"Y = adjoint_differential_forward_logs(M, p, X)\nadjoint_differential_forward_logs!(M, Y, p, X)\n\nCompute the adjoint differential of forward_logs F occurring, in the power manifold array p, the differential of the function\n\nF_i(p) = sum_j mathcal I_i log_p_i p_j\n\nwhere i runs over all indices of the PowerManifold manifold M and mathcal I_i denotes the forward neighbors of i Let n be the number dimensions of the PowerManifold manifold (i.e. length(size(x))). Then the input tangent vector lies on the manifold mathcal M = mathcal M^n. The adjoint differential can be computed in place of Y.\n\nInput\n\nM – a PowerManifold manifold\np – an array of points on a manifold\nX – a tangent vector to from the n-fold power of p, where n is the ndims of p\n\nOutput\n\nY – resulting tangent vector in T_pmathcal M representing the adjoint differentials of the logs.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.differential_forward_logs-Tuple{ManifoldsBase.PowerManifold, Any, Any}","page":"Objectives","title":"ManoptExamples.differential_forward_logs","text":"Y = differential_forward_logs(M, p, X)\ndifferential_forward_logs!(M, Y, p, X)\n\ncompute the differential of forward_logs F on the PowerManifold manifold M at p and direction X , in the power manifold array, the differential of the function\n\nF_i(x) = sum_j mathcal I_i log_p_i p_j quad i mathcal G\n\nwhere mathcal G is the set of indices of the PowerManifold manifold M and mathcal I_i denotes the forward neighbors of i.\n\nInput\n\nM – a PowerManifold manifold\np – a point.\nX – a tangent vector.\n\nOutput\n\nY – resulting tangent vector in T_xmathcal N representing the differentials of the logs, where mathcal N is the power manifold with the number of dimensions added to size(x). The computation can also be done in place.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.forward_logs-Union{Tuple{TPR}, Tuple{TSize}, Tuple{TM}, Tuple{𝔽}, Tuple{ManifoldsBase.PowerManifold{𝔽, TM, TSize, TPR}, Any}} where {𝔽, TM, TSize, TPR}","page":"Objectives","title":"ManoptExamples.forward_logs","text":"Y = forward_logs(M,x)\nforward_logs!(M, Y, x)\n\ncompute the forward logs F (generalizing forward differences) occurring, in the power manifold array, the function\n\nF_i(x) = sum_j mathcal I_i log_x_i x_jquad i mathcal G\n\nwhere mathcal G is the set of indices of the PowerManifold manifold M and mathcal I_i denotes the forward neighbors of i. This can also be done in place of ξ.\n\nInput\n\nM – a PowerManifold manifold\nx – a point.\n\nOutput\n\nY – resulting tangent vector in T_xmathcal M representing the logs, where mathcal N is the power manifold with the number of dimensions added to size(x). The computation can be done in place of Y.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.grad_Total_Variation","page":"Objectives","title":"ManoptExamples.grad_Total_Variation","text":"X = grad_Total_Variation(M, λ, x[, p=1])\ngrad_Total_Variation!(M, X, λ, x[, p=1])\n\nCompute the (sub)gradient f of all forward differences occurring, in the power manifold array, i.e. of the function\n\nf(p) = sum_isum_j mathcal I_i d^p(x_ix_j)\n\nwhere i runs over all indices of the PowerManifold manifold M and mathcal I_i denotes the forward neighbors of i.\n\nInput\n\nM – a PowerManifold manifold\nx – a point.\n\nOutput\n\nX – resulting tangent vector in T_xmathcal M. The computation can also be done in place.\n\n\n\n\n\n","category":"function"},{"location":"objectives/#ManoptExamples.grad_Total_Variation-Union{Tuple{T}, Tuple{ManifoldsBase.AbstractManifold, Tuple{T, T}}, Tuple{ManifoldsBase.AbstractManifold, Tuple{T, T}, Any}} where T","page":"Objectives","title":"ManoptExamples.grad_Total_Variation","text":"X = grad_Total_Variation(M, (x,y)[, p=1])\ngrad_Total_Variation!(M, X, (x,y)[, p=1])\n\ncompute the (sub) gradient of frac1pd^p_mathcal M(xy) with respect to both x and y (in place of X and Y).\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.grad_intrinsic_infimal_convolution_TV12-Tuple{ManifoldsBase.AbstractManifold, Vararg{Any, 5}}","page":"Objectives","title":"ManoptExamples.grad_intrinsic_infimal_convolution_TV12","text":"grad_u, grad_v = grad_intrinsic_infimal_convolution_TV12(M, f, u, v, α, β)\n\ncompute (sub)gradient of the intrinsic infimal convolution model using the mid point model of second order differences, see second_order_Total_Variation, i.e. for some f mathcal M on a PowerManifold manifold mathcal M this function computes the (sub)gradient of\n\nE(uv) =\nfrac12sum_i mathcal G d_mathcal M(g(frac12v_iw_i)f_i)\n+ alpha\nbigl(\nβmathrmTV(v) + (1-β)mathrmTV_2(w)\nbigr)\n\nwhere both total variations refer to the intrinsic ones, grad_Total_Variation and grad_second_order_Total_Variation, respectively.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.grad_second_order_Total_Variation","page":"Objectives","title":"ManoptExamples.grad_second_order_Total_Variation","text":"Y = grad_second_order_Total_Variation(M, q[, p=1])\ngrad_second_order_Total_Variation!(M, Y, q[, p=1])\n\ncomputes the (sub) gradient of frac1pd_2^p(q_1 q_2 q_3) with respect to all three components of qmathcal M^3, where d_2 denotes the second order absolute difference using the mid point model, i.e. let\n\nmathcal C = bigl c mathcal M g(tfrac12q_1q_3) text for some geodesic gbigr\n\ndenote the mid points between q_1 and q_3 on the manifold mathcal M. Then the absolute second order difference is defined as\n\nd_2(q_1q_2q_3) = min_c mathcal C_q_1q_3 d(c q_2)\n\nWhile the (sub)gradient with respect to q_2 is easy, the other two require the evaluation of an adjoint_Jacobi_field.\n\nThe derivation of this gradient can be found in [BBSW16].\n\n\n\n\n\n","category":"function"},{"location":"objectives/#ManoptExamples.grad_second_order_Total_Variation-2","page":"Objectives","title":"ManoptExamples.grad_second_order_Total_Variation","text":"grad_second_order_Total_Variation(M::PowerManifold, q[, p=1])\n\ncomputes the (sub) gradient of frac1pd_2^p(q_1q_2q_3) with respect to all q_1q_2q_3 occurring along any array dimension in the point q, where M is the corresponding PowerManifold.\n\n\n\n\n\n","category":"function"},{"location":"objectives/#ManoptExamples.project_collaborative_TV","page":"Objectives","title":"ManoptExamples.project_collaborative_TV","text":"project_collaborative_TV(M, λ, x, Ξ[, p=2,q=1])\nproject_collaborative_TV!(M, Θ, λ, x, Ξ[, p=2,q=1])\n\ncompute the projection onto collaborative Norm unit (or α-) ball, i.e. of the function\n\nF^q(x) = sum_imathcal G\n Bigl( sum_jmathcal I_i\n sum_k=1^d lVert X_ijrVert_x^pBigr)^fracqp\n\nwhere mathcal G is the set of indices for xmathcal M and mathcal I_i is the set of its forward neighbors. The computation can also be done in place of Θ.\n\nThis is adopted from the paper Duran, Möller, Sbert, Cremers, SIAM J Imag Sci, 2016, see their Example 3 for details.\n\n\n\n\n\n","category":"function"},{"location":"objectives/#ManoptExamples.prox_Total_Variation","page":"Objectives","title":"ManoptExamples.prox_Total_Variation","text":"ξ = prox_Total_Variation(M,λ,x [,p=1])\n\ncompute the proximal maps operatornameprox_λvarphi of all forward differences occurring in the power manifold array, i.e. varphi(xixj) = d_mathcal M^p(xixj) with xi and xj are array elements of x and j = i+e_k, where e_k is the kth unit vector. The parameter λ is the prox parameter.\n\nInput\n\nM – a manifold M\nλ – a real value, parameter of the proximal map\nx – a point.\n\nOptional\n\n(default is given in brackets)\n\np – (1) exponent of the distance of the TV term\n\nOutput\n\ny – resulting point containing with all mentioned proximal points evaluated (in a cyclic order). The computation can also be done in place\n\n\n\n\n\n","category":"function"},{"location":"objectives/#ManoptExamples.prox_Total_Variation-Union{Tuple{T}, Tuple{ManifoldsBase.AbstractManifold, Number, Tuple{T, T}}, Tuple{ManifoldsBase.AbstractManifold, Number, Tuple{T, T}, Int64}} where T","page":"Objectives","title":"ManoptExamples.prox_Total_Variation","text":"[y1,y2] = prox_Total_Variation(M, λ, [x1,x2] [,p=1])\nprox_Total_Variation!(M, [y1,y2] λ, [x1,x2] [,p=1])\n\nCompute the proximal map operatornameprox_λvarphi of φ(xy) = d_mathcal M^p(xy) with parameter λ. A derivation of this closed form solution is given in see [WDS14].\n\nInput\n\nM – a manifold M\nλ – a real value, parameter of the proximal map\n(x1,x2) – a tuple of two points,\n\nOptional\n\n(default is given in brackets)\n\np – (1) exponent of the distance of the TV term\n\nOutput\n\n(y1,y2) – resulting tuple of points of the operatornameprox_λφ((x1,x2)). The result can also be computed in place.\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.prox_parallel_TV","page":"Objectives","title":"ManoptExamples.prox_parallel_TV","text":"y = prox_parallel_TV(M, λ, x [,p=1])\nprox_parallel_TV!(M, y, λ, x [,p=1])\n\ncompute the proximal maps operatornameprox_λφ of all forward differences occurring in the power manifold array, i.e. φ(x_ix_j) = d_mathcal M^p(x_ix_j) with xi and xj are array elements of x and j = i+e_k, where e_k is the kth unit vector. The parameter λ is the prox parameter.\n\nInput\n\nM – a PowerManifold manifold\nλ – a real value, parameter of the proximal map\nx – a point\n\nOptional\n\n(default is given in brackets)\n\np – (1) exponent of the distance of the TV term\n\nOutput\n\ny – resulting Array of points with all mentioned proximal points evaluated (in a parallel within the arrays elements). The computation can also be done in place.\n\nSee also prox_Total_Variation\n\n\n\n\n\n","category":"function"},{"location":"objectives/#ManoptExamples.prox_second_order_Total_Variation","page":"Objectives","title":"ManoptExamples.prox_second_order_Total_Variation","text":"(y1,y2,y3) = prox_second_order_Total_Variation(M,λ,(x1,x2,x3),[p=1], kwargs...)\nprox_second_order_Total_Variation!(M, y, λ,(x1,x2,x3),[p=1], kwargs...)\n\nCompute the proximal map operatornameprox_λvarphi of varphi(x_1x_2x_3) = d_mathcal M^p(c(x_1x_3)x_2) with parameter λ>0, where c(xz) denotes the mid point of a shortest geodesic from x1 to x3 that is closest to x2. The result can be computed in place of y.\n\nNote that this function does not have a closed form solution but is solbed by a few steps of the subgradient mehtod from manopt.jl by default. See [BBSW16] for a derivation.\n\nInput\n\nM – a manifold\nλ – a real value, parameter of the proximal map\n(x1,x2,x3) – a tuple of three points\np – (1) exponent of the distance of the TV term\n\nOptional\n\nkwargs... – parameters for the internal subgradient_method (if M is neither Euclidean nor Circle, since for these a closed form is given)\n\nOutput\n\n(y1,y2,y3) – resulting tuple of points of the proximal map. The computation can also be done in place.\nnote: Note\n\nThis function requires Manopt.jl to be loaded\n\n\n\n\n\n","category":"function"},{"location":"objectives/#ManoptExamples.prox_second_order_Total_Variation-Union{Tuple{T}, Tuple{N}, Tuple{ManifoldsBase.PowerManifold{N, T}, Any, Any}, Tuple{ManifoldsBase.PowerManifold{N, T}, Any, Any, Int64}} where {N, T}","page":"Objectives","title":"ManoptExamples.prox_second_order_Total_Variation","text":"y = prox_second_order_Total_Variation(M, λ, x[, p=1])\nprox_second_order_Total_Variation!(M, y, λ, x[, p=1])\n\ncompute the proximal maps operatornameprox_λvarphi of all centered second order differences occurring in the power manifold array, i.e. varphi(x_kx_ix_j) = d_2(x_kx_ix_j), where kj are backward and forward neighbors (along any dimension in the array of x). The parameter λ is the prox parameter.\n\nInput\n\nM – a manifold M\nλ – a real value, parameter of the proximal map\nx – a points.\n\nOptional\n\n(default is given in brackets)\n\np – (1) exponent of the distance of the TV term\n\nOutput\n\ny – resulting point with all mentioned proximal points evaluated (in a cyclic order). The computation can also be done in place.\n\nnote: Note\nThis function requires Manopt.jl to be loaded\n\n\n\n\n\n","category":"method"},{"location":"objectives/#ManoptExamples.second_order_Total_Variation","page":"Objectives","title":"ManoptExamples.second_order_Total_Variation","text":"second_order_Total_Variation(M,x [,p=1])\n\ncompute the operatornameTV_2^p functional for data x on the PowerManifold manifoldmanifold M, i.e. mathcal M = mathcal N^n, where n mathbb N^k denotes the dimensions of the data x. Let mathcal I_i^pm denote the forward and backward neighbors, respectively, i.e. with mathcal G as all indices from mathbf1 mathbb N^k to n we have mathcal I^pm_i = ipm e_j j=1kcap mathcal I. The formula then reads\n\nE(x) = sum_i mathcal I j_1 mathcal I^+_i j_2 mathcal I^-_i\nd^p_mathcal M(c_i(x_j_1x_j_2) x_i)\n\nwhere c_i() denotes the mid point between its two arguments that is nearest to x_i, see [BBSW16] for a derivation.\n\nIn long function names, this might be shortened to TV2.\n\nSee also\n\ngrad_second_order_Total_Variation, prox_second_order_Total_Variation\n\n\n\n\n\n","category":"function"},{"location":"objectives/#ManoptExamples.second_order_Total_Variation-Union{Tuple{T}, Tuple{MT}, Tuple{MT, Tuple{T, T, T}}, Tuple{MT, Tuple{T, T, T}, Any}} where {MT<:ManifoldsBase.AbstractManifold, T}","page":"Objectives","title":"ManoptExamples.second_order_Total_Variation","text":"second_order_Total_Variation(M,(x1,x2,x3) [,p=1])\n\nCompute the operatornameTV_2^p functional for the 3-tuple of points (x1,x2,x3)on the manifold M. Denote by\n\n mathcal C = bigl c mathcal M g(tfrac12x_1x_3) text for some geodesic gbigr\n\nthe set of mid points between x_1 and x_3. Then the function reads\n\nd_2^p(x_1x_2x_3) = min_c mathcal C d_mathcal M(cx_2)\n\nsee [BBSW16] for a derivation. In long function names, this might be shortened to TV2.\n\nSee also\n\ngrad_second_order_Total_Variation, prox_second_order_Total_Variation, Total_Variation\n\n\n\n\n\n","category":"method"},{"location":"objectives/#Literature","page":"Objectives","title":"Literature","text":"","category":"section"},{"location":"objectives/","page":"Objectives","title":"Objectives","text":"M. Bačák, R. Bergmann, G. Steidl and A. Weinmann. A second order non-smooth variational model for restoring manifold-valued images. SIAM Journal on Scientific Computing 38, A567–A597 (2016), arXiv:1506.02409.\n\n\n\nR. Bergmann, J. H. Fitschen, J. Persch and G. Steidl. Priors with coupled first and second order differences for manifold-valued image processing. Journal of Mathematical Imaging and Vision 60, 1459–1481 (2018), arXiv:1709.01343.\n\n\n\nR. Bergmann, J. H. Fitschen, J. Persch and G. Steidl. Infimal convolution coupling of first and second order differences on manifold-valued images. In: Scale Space and Variational Methods in Computer Vision: 6th International Conference, SSVM 2017, Kolding, Denmark, June 4–8, 2017, Proceedings, edited by F. Lauze, Y. Dong and A. B. Dahl (Springer International Publishing, 2017); pp. 447–459.\n\n\n\nR. Bergmann and P.-Y. Gousenbourger. A variational model for data fitting on manifolds by minimizing the acceleration of a Bézier curve. Frontiers in Applied Mathematics and Statistics 4 (2018), arXiv:1807.10090.\n\n\n\nN. Boumal. An Introduction to Optimization on Smooth Manifolds. First Edition (Cambridge University Press, 2023).\n\n\n\nP. de Casteljau. Outillage methodes calcul (Enveloppe Soleau 40.040, Institute National de la Propriété Industrielle, Paris., 1959).\n\n\n\nP. de Casteljau. Courbes et surfaces à pôles (Microfiche P 4147-1, Institute National de la Propriété Industrielle, Paris., 1963).\n\n\n\nJ. Duran, M. Moeller, C. Sbert and D. Cremers. Collaborative Total Variation: A General Framework for Vectorial TV Models. SIAM Journal on Imaging Sciences 9, 116–151 (2016), arXiv:1508.01308.\n\n\n\nT. Popiel and L. Noakes. Bézier curves and C^2 interpolation in Riemannian manifolds. Journal of Approximation Theory 148, 111–127 (2007).\n\n\n\nA. Weinmann, L. Demaret and M. Storath. Total variation regularization for manifold-valued data. SIAM Journal on Imaging Sciences 7, 2226–2257 (2014).\n\n\n\n","category":"page"},{"location":"examples/HyperparameterOptimization/#Hyperparameter-optimization","page":"Hyperparameter optimziation","title":"Hyperparameter optimization","text":"","category":"section"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"Mateusz Baran 2024-08-03","category":"page"},{"location":"examples/HyperparameterOptimization/#Introduction","page":"Hyperparameter optimziation","title":"Introduction","text":"","category":"section"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"This example shows how to automatically select the best values of hyperparameters of optimization procedures such as retraction, vector transport, size of memory in L-BFGS or line search coefficients. Hyperparameter optimization relies on the Optuna [ASY+19] Python library because it is much more advanced than similar Julia projects, offering Bayesian optimization with conditional hyperparameters and early stopping.","category":"page"},{"location":"examples/HyperparameterOptimization/#General-definitions","page":"Hyperparameter optimziation","title":"General definitions","text":"","category":"section"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"Here are some general definitions that you will most likely be able to directly use for your problem without any changes. Just remember to install optuna, for example using CondaPkg Julia library.","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"using Manifolds, Manopt\nusing PythonCall\nusing BenchmarkTools\nusing LineSearches\n\n# This script requires optuna to be available through PythonCall\n# You can install it for example using\n# using CondaPkg\n# ]conda add optuna\n\noptuna = pyimport(\"optuna\")\n\nnorm_inf(M::AbstractManifold, p, X) = norm(X, Inf)\n\n# TTsuggest_ structs collect data from a calibrating optimization run\n# that is handled by compute_pruning_losses function\n\nstruct TTsuggest_int\n suggestions::Dict{String,Int}\nend\nfunction (s::TTsuggest_int)(name::String, a, b)\n return s.suggestions[name]\nend\nstruct TTsuggest_float\n suggestions::Dict{String,Float64}\nend\nfunction (s::TTsuggest_float)(name::String, a, b; log::Bool=false)\n return s.suggestions[name]\nend\nstruct TTsuggest_categorical\n suggestions::Dict{String,Any}\nend\nfunction (s::TTsuggest_categorical)(name::String, vals)\n return s.suggestions[name]\nend\nstruct TTreport\n reported_vals::Vector{Float64}\nend\nfunction (r::TTreport)(val, i)\n return push!(r.reported_vals, val)\nend\nstruct TTshould_prune end\n(::TTshould_prune)() = Py(false)\nstruct TracingTrial\n suggest_int::TTsuggest_int\n suggest_float::TTsuggest_float\n suggest_categorical::TTsuggest_categorical\n report::TTreport\n should_prune::TTshould_prune\nend\n\nfunction compute_pruning_losses(\n od,\n int_suggestions::Dict{String,Int},\n float_suggestions::Dict{String,Float64},\n categorical_suggestions::Dict{String,Int},\n)\n tt = TracingTrial(\n TTsuggest_int(int_suggestions),\n TTsuggest_float(float_suggestions),\n TTsuggest_categorical(categorical_suggestions),\n TTreport(Float64[]),\n TTshould_prune(),\n )\n od(tt)\n return tt.report.reported_vals\nend","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"The next part is your hyperparameter optimization objective. The ObjectiveData struct contains all relevant information about the sequence of specific problems. The outermost key part is the N_range field. Early stopping requires a series of progressively more complex problems. They will be attempted from the most simple one to the most complex one, and are specified by the values of N in that vector.","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"mutable struct ObjectiveData{TObj,TGrad}\n obj::TObj\n grad::TGrad\n N_range::Vector{Int}\n gtol::Float64\n vts::Vector{AbstractVectorTransportMethod}\n retrs::Vector{AbstractRetractionMethod}\n manifold_constructors::Vector{Tuple{String,Any}}\n pruning_losses::Vector{Float64}\n manopt_stepsize::Vector{Tuple{String,Any}}\n obj_loss_coeff::Float64\nend","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"In the example below we optimize hyperparameters on a sequence of Rosenbrock-type problems restricted to spheres:","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"argmin_p in S^N-1 sum_i=1^N2 (1-p_2i)^2 + 100 (p_2i+1 - p_2i^2)^2","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"where N in 2 16 128 1024 8192 65536.","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"obj and grad are the objective and gradient, here defined as below. Note that gradient works in-place and variants without manifolds are also provided for easier comparison with other libraries like Optim.jl. It is easiest when problems for different values N can be distinguished by being defined on successively larger manifolds but the script could be modified so that it’s not necessary.","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"pruning_losses and compute_pruning_losses are related to early pruning used in Optuna and you shouldn’t have to modify them.","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"function f_rosenbrock(x)\n result = 0.0\n for i in 1:2:length(x)\n result += (1.0 - x[i])^2 + 100.0 * (x[i + 1] - x[i]^2)^2\n end\n return result\nend\nfunction f_rosenbrock(::AbstractManifold, x)\n return f_rosenbrock(x)\nend\n\nfunction g_rosenbrock!(storage, x)\n for i in 1:2:length(x)\n storage[i] = -2.0 * (1.0 - x[i]) - 400.0 * (x[i + 1] - x[i]^2) * x[i]\n storage[i + 1] = 200.0 * (x[i + 1] - x[i]^2)\n end\n return storage\nend\nfunction g_rosenbrock!(M::AbstractManifold, storage, x)\n g_rosenbrock!(storage, x)\n riemannian_gradient!(M, storage, x, storage)\n return storage\nend","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"Next, gtol is the tolerance used for the stopping criterion in optimization. vts and retrs are, respectively, vector transports and retraction methods selected through hyperparameter optimization. Some items need to be different for different values of N, for example the manifold over which the problem is defined. This is handled by manifold_constructors which is then defined as Tuple{String,Any}[(\"Sphere\", N -> Manifolds.Sphere(N - 1))], where the string \"Sphere\" is used to identify the manifold family and the next element is a function that transforms the value of N to the manifold for the problem of size N.","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"Similarly, different stepsize selection methods may be considered. This is handled by the field manopt_stepsize. It will be easiest to see how it works by looking at how it is initialized:","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"Tuple{String,Any}[\n (\"LS-HZ\", M -> Manopt.LineSearchesStepsize(ls_hz)),\n (\"Wolfe-Powell\", (M, c1, c2) -> Manopt.WolfePowellLinesearch(M, c1, c2)),\n]","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"We have a string that identifies the line search method name and a constructor of the line search which takes relevant arguments like the manifold or a numerical parameter.","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"The next part is the trial evaluation procedure. This is one of the more important places which need to be customized to your problem. This is the point where we tell Optuna about the relevant optimization hyperparameters and use them to define specific problems. The hyperparameter optimization is a multiobjective problem: we want as good problem objectives as possible and as low times as possible. As Optuna doesn’t currently support multicriteria pruning, which is important for obtaining a solution in a reasonable amount of time, we use a linear combination of sub-objectives to turn the problem into a single-criterion optimization. The hyperparameter optimization objective is a linear combination of achieved objectives the relative weight is controlled by objective.obj_loss_coeff.","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"function (objective::ObjectiveData)(trial)\n # Here we use optuna to select memory length for L-BFGS -- an integer in the range between 2 and 30, referenced by name \"mem_len\"\n mem_len = trial.suggest_int(\"mem_len\", 2, 30)\n\n # Here we select a vector transport and retraction methods, one of those specified in the `ObjectiveData`.\n vt = objective.vts[pyconvert(\n Int,\n trial.suggest_categorical(\n \"vector_transport_method\", Vector(eachindex(objective.vts))\n ),\n )]\n retr = objective.retrs[pyconvert(\n Int,\n trial.suggest_categorical(\"retraction_method\", Vector(eachindex(objective.retrs))),\n )]\n\n # Here we select the manifold constructor, in case we want to try different manifolds for our problem. For example one could try defining a problem with orthogonality constraints on Stiefel, Grassmann or flag manifold.\n manifold_name, manifold_constructor = objective.manifold_constructors[pyconvert(\n Int,\n trial.suggest_categorical(\n \"manifold\", Vector(eachindex(objective.manifold_constructors))\n ),\n )]\n\n # Here the stepsize selection method type is selected.\n manopt_stepsize_name, manopt_stepsize_constructor = objective.manopt_stepsize[pyconvert(\n Int,\n trial.suggest_categorical(\n \"manopt_stepsize\", Vector(eachindex(objective.manopt_stepsize))\n ),\n )]\n\n # This parametrizes stepsize selection methods with relevant numerical parameters.\n local c1_val, c2_val, hz_sigma\n if manopt_stepsize_name == \"Wolfe-Powell\"\n c1_val = pyconvert(\n Float64, trial.suggest_float(\"Wolfe-Powell c1\", 1e-5, 1e-2; log=true)\n )\n c2_val =\n 1.0 - pyconvert(\n Float64, trial.suggest_float(\"Wolfe-Powell 1-c2\", 1e-4, 1e-2; log=true)\n )\n elseif manopt_stepsize_name == \"Improved HZ\"\n hz_sigma = pyconvert(Float64, trial.suggest_float(\"Improved HZ sigma\", 0.1, 0.9))\n end\n\n # The current loss estimate, taking into account estimated loss values for larger, not-yet-evaluated values of `N`.\n loss = sum(objective.pruning_losses)\n\n # Here iterate over problems we want to optimize for\n # from smallest to largest; pruning should stop the iteration early\n # if the hyperparameter set is not promising\n cur_i = 0\n for N in objective.N_range\n # Here we define the initial point for the optimization procedure\n p0 = zeros(N)\n p0[1] = 1\n M = manifold_constructor(N)\n # Here we construct the specific line search to be used\n local ls\n if manopt_stepsize_name == \"Wolfe-Powell\"\n ls = manopt_stepsize_constructor(M, c1_val, c2_val)\n elseif manopt_stepsize_name == \"Improved HZ\"\n ls = manopt_stepsize_constructor(M, hz_sigma)\n else\n ls = manopt_stepsize_constructor(M)\n end\n manopt_time, manopt_iters, manopt_obj = benchmark_time_state(\n ManoptQN(),\n M,\n N,\n objective.obj,\n objective.grad,\n p0,\n ls,\n pyconvert(Int, mem_len),\n objective.gtol;\n vector_transport_method=vt,\n retraction_method=retr,\n )\n # TODO: turn this into multi-criteria optimization when Optuna starts supporting\n # pruning in such problems\n loss -= objective.pruning_losses[cur_i + 1]\n loss += manopt_time + objective.obj_loss_coeff * manopt_obj\n trial.report(loss, cur_i)\n if pyconvert(Bool, trial.should_prune().__bool__())\n throw(PyException(optuna.TrialPruned()))\n end\n cur_i += 1\n end\n return loss\nend","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"In the following benchmarking code you will most likely have to adapt solver parameters. This is designed around quasi_Newton but can be adapted to any solver as needed. The example below performs a small number of trials for quick rendering but in practice you should aim for at least a few thousand trials (the n_trials parameter).","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"# An abstract type in case we want to try different optimization packages.\nabstract type AbstractOptimConfig end\nstruct ManoptQN <: AbstractOptimConfig end\n\n# Benchmark that evaluates hyperparameters. Returns time to reach the solution, number of iterations and final value of the objective.\nfunction benchmark_time_state(\n ::ManoptQN,\n M::AbstractManifold,\n N,\n f,\n g!,\n p0,\n stepsize::Manopt.Stepsize,\n mem_len::Int,\n gtol::Real;\n kwargs...,\n)\n manopt_sc = StopWhenGradientNormLess(gtol; norm=norm_inf) | StopAfterIteration(1000)\n mem_len = min(mem_len, manifold_dimension(M))\n manopt_state = quasi_Newton(\n M,\n f,\n g!,\n p0;\n stepsize=stepsize,\n evaluation=InplaceEvaluation(),\n return_state=true,\n memory_size=mem_len,\n stopping_criterion=manopt_sc,\n debug=[],\n kwargs...,\n )\n bench_manopt = @benchmark quasi_Newton(\n $M,\n $f,\n $g!,\n $p0;\n stepsize=$(stepsize),\n evaluation=$(InplaceEvaluation()),\n memory_size=$mem_len,\n stopping_criterion=$(manopt_sc),\n debug=[],\n $kwargs...,\n )\n iters = get_count(manopt_state, :Iterations)\n final_val = f(M, manopt_state.p)\n return median(bench_manopt.times) / 1000, iters, final_val\nend\n\n\"\"\"\n lbfgs_study(; pruning_coeff::Float64=0.95)\n\nSet up the example hyperparameter optimization study.\n\"\"\"\nfunction lbfgs_study(; pruning_coeff::Float64=0.95)\n Ns = [2^n for n in 1:3:12]\n ls_hz = LineSearches.HagerZhang()\n od = ObjectiveData(\n f_rosenbrock,\n g_rosenbrock!,\n Ns,\n 1e-5,\n AbstractVectorTransportMethod[ParallelTransport(), ProjectionTransport()],\n [ExponentialRetraction(), ProjectionRetraction()],\n Tuple{String,Any}[(\"Sphere\", N -> Manifolds.Sphere(N - 1))],\n zeros(Float64, eachindex(Ns)),\n Tuple{String,Any}[\n (\"LS-HZ\", M -> Manopt.LineSearchesStepsize(ls_hz)),\n #(\"Improved HZ\", (M, sigma) -> HagerZhangLinesearch(M; sigma=sigma)),\n (\"Wolfe-Powell\", (M, c1, c2) -> Manopt.WolfePowellLinesearch(M, c1, c2)),\n ],\n 10.0,\n )\n\n # Here you need to define baseline values of all hyperparameters\n baseline_pruning_losses = compute_pruning_losses(\n od,\n Dict(\"mem_len\" => 4),\n Dict(\n \"Wolfe-Powell c1\" => 1e-4,\n \"Wolfe-Powell 1-c2\" => 1e-3,\n \"Improved HZ sigma\" => 0.9,\n ),\n Dict(\n \"vector_transport_method\" => 1,\n \"retraction_method\" => 1,\n \"manifold\" => 1,\n \"manopt_stepsize\" => 1,\n ),\n )\n od.pruning_losses = pruning_coeff * baseline_pruning_losses\n\n study = optuna.create_study(; study_name=\"L-BFGS\")\n # Here you can specify number of trials and timeout (in seconds).\n study.optimize(od; n_trials=1000, timeout=500)\n println(\"Best params is $(study.best_params) with value $(study.best_value)\")\n selected_manifold = od.manifold_constructors[pyconvert(Int, study.best_params[\"manifold\"])][1]\n selected_retraction_method = od.retrs[pyconvert(Int, study.best_params[\"retraction_method\"])]\n selected_vector_transport = od.vts[pyconvert(Int, study.best_params[\"vector_transport_method\"])]\n println(\"Selected manifold: $(selected_manifold)\")\n println(\"Selected retraction method: $(selected_retraction_method)\")\n println(\"Selected vector transport method: $(selected_vector_transport)\")\n return study\nend\n\nlbfgs_study()","category":"page"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"Best params is {'mem_len': 3, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.0006125542888545935, 'Wolfe-Powell 1-c2': 0.0010744467792321093} with value 5510.963227438757\nSelected manifold: Sphere\nSelected retraction method: ExponentialRetraction()\nSelected vector transport method: ProjectionTransport()\n\n[I 2024-03-16 18:04:17,965] A new study created in memory with name: L-BFGS\n[I 2024-03-16 18:04:45,996] Trial 0 finished with value: 5639.789870295856 and parameters: {'mem_len': 26, 'vector_transport_method': 1, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.00027288064367948073, 'Wolfe-Powell 1-c2': 0.00026503788892114045}. Best is trial 0 with value: 5639.789870295856.\n[I 2024-03-16 18:05:11,860] Trial 1 finished with value: 5635.936370295855 and parameters: {'mem_len': 11, 'vector_transport_method': 1, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.002743250060163298, 'Wolfe-Powell 1-c2': 0.00037986521186922096}. Best is trial 1 with value: 5635.936370295855.\n[I 2024-03-16 18:05:39,386] Trial 2 finished with value: 5673.101441724422 and parameters: {'mem_len': 26, 'vector_transport_method': 2, 'retraction_method': 2, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.00043339485784312605, 'Wolfe-Powell 1-c2': 0.0027302649933974173}. Best is trial 1 with value: 5635.936370295855.\n[I 2024-03-16 18:06:10,279] Trial 3 finished with value: 7410.818084581564 and parameters: {'mem_len': 26, 'vector_transport_method': 1, 'retraction_method': 2, 'manifold': 1, 'manopt_stepsize': 1}. Best is trial 1 with value: 5635.936370295855.\n[I 2024-03-16 18:06:37,995] Trial 4 finished with value: 5756.566226449636 and parameters: {'mem_len': 25, 'vector_transport_method': 1, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 1}. Best is trial 1 with value: 5635.936370295855.\n[I 2024-03-16 18:06:42,755] Trial 5 pruned. \n[I 2024-03-16 18:06:58,577] Trial 6 pruned. \n[I 2024-03-16 18:07:15,366] Trial 7 pruned. \n[I 2024-03-16 18:07:40,605] Trial 8 finished with value: 5581.7437274386975 and parameters: {'mem_len': 7, 'vector_transport_method': 1, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.0010567355712112379, 'Wolfe-Powell 1-c2': 0.003948002490203636}. Best is trial 8 with value: 5581.7437274386975.\n[I 2024-03-16 18:07:46,021] Trial 9 pruned. \n[I 2024-03-16 18:08:11,512] Trial 10 finished with value: 5510.963227438757 and parameters: {'mem_len': 3, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.0006125542888545935, 'Wolfe-Powell 1-c2': 0.0010744467792321093}. Best is trial 10 with value: 5510.963227438757.\n[I 2024-03-16 18:08:35,914] Trial 11 finished with value: 5521.388656010121 and parameters: {'mem_len': 2, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.0006738829952322474, 'Wolfe-Powell 1-c2': 0.0010639659137420014}. Best is trial 10 with value: 5510.963227438757.\n[I 2024-03-16 18:09:00,317] Trial 12 finished with value: 5521.36958458155 and parameters: {'mem_len': 2, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.00010975606104676191, 'Wolfe-Powell 1-c2': 0.0007663843095951679}. Best is trial 10 with value: 5510.963227438757.\n[I 2024-03-16 18:09:24,680] Trial 13 finished with value: 5520.7020845815505 and parameters: {'mem_len': 2, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 6.743450835567536e-05, 'Wolfe-Powell 1-c2': 0.0008779759729737719}. Best is trial 10 with value: 5510.963227438757.\n[I 2024-03-16 18:09:50,268] Trial 14 pruned. \n[I 2024-03-16 18:10:15,494] Trial 15 finished with value: 5595.119584581556 and parameters: {'mem_len': 6, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 8.147444451747575e-05, 'Wolfe-Powell 1-c2': 0.00012268601197923553}. Best is trial 10 with value: 5510.963227438757.\n[I 2024-03-16 18:10:25,264] Trial 16 pruned. \n[I 2024-03-16 18:10:50,209] Trial 17 finished with value: 5572.474513153012 and parameters: {'mem_len': 5, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.0015998473664092935, 'Wolfe-Powell 1-c2': 0.0005109172020536229}. Best is trial 10 with value: 5510.963227438757.\n[I 2024-03-16 18:10:54,772] Trial 18 pruned. \n[I 2024-03-16 18:11:04,534] Trial 19 pruned. \n[I 2024-03-16 18:11:28,873] Trial 20 finished with value: 5512.3824417244705 and parameters: {'mem_len': 3, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 1.1581668103921961e-05, 'Wolfe-Powell 1-c2': 0.0002691056199427656}. Best is trial 10 with value: 5510.963227438757.\n[I 2024-03-16 18:11:53,327] Trial 21 finished with value: 5529.088227438692 and parameters: {'mem_len': 4, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 1.3645031886009879e-05, 'Wolfe-Powell 1-c2': 0.0001863385753491203}. Best is trial 10 with value: 5510.963227438757.\n[I 2024-03-16 18:12:17,911] Trial 22 finished with value: 5522.041370295835 and parameters: {'mem_len': 2, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 1.0030173525937465e-05, 'Wolfe-Powell 1-c2': 0.000543991948003312}. Best is trial 10 with value: 5510.963227438757.\n[I 2024-03-16 18:12:27,645] Trial 23 pruned. \n[I 2024-03-16 18:12:52,163] Trial 24 finished with value: 5528.840941724406 and parameters: {'mem_len': 4, 'vector_transport_method': 2, 'retraction_method': 1, 'manifold': 1, 'manopt_stepsize': 2, 'Wolfe-Powell c1': 0.000245400433292576, 'Wolfe-Powell 1-c2': 0.000133639324295565}. Best is trial 10 with value: 5510.963227438757.\n\nPython: ","category":"page"},{"location":"examples/HyperparameterOptimization/#Summary","page":"Hyperparameter optimziation","title":"Summary","text":"","category":"section"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"We’ve shown how to automatically select the best hyperparameter values for your optimization problem.","category":"page"},{"location":"examples/HyperparameterOptimization/#Literature","page":"Hyperparameter optimziation","title":"Literature","text":"","category":"section"},{"location":"examples/HyperparameterOptimization/","page":"Hyperparameter optimziation","title":"Hyperparameter optimziation","text":"T. Akiba, S. Sano, T. Yanase, T. Ohta and M. Koyama. Optuna: A Next-generation Hyperparameter Optimization Framework. In: Proceedings of the 25th ACM SIGKDD International Conference on Knowledge Discovery and Data Mining (2019), arXiv:1907.10902.\n\n\n\n","category":"page"},{"location":"examples/#List-of-Examples","page":"Overview","title":"List of Examples","text":"","category":"section"},{"location":"examples/","page":"Overview","title":"Overview","text":"Name provides Documentation Comment\nA Benchmark for Difference of Convex contains a few simple functions \nBézier Curves and Minimizing their Acceleration tools Bézier curves and their acceleration 📚 \nSolving Rosenbrock with Difference of Convex DoC split of Rosenbrock 📚 uses a Rosenbrock based metric\nDifference of Convex vs. Frank-Wolfe closed-form sub solver\nRiemannian Mean f, operatornamegradf (A/I), objective 📚 \nRobust PCA f, operatornamegradf (A/I), objective 📚 \nRosenbrock f, operatornamegradf (A/I), objective, minimizer 📚 \nThe Rayleigh Quotient f, operatornamegradf (A/I), operatornameHessf (A/I), objective 📚 \nTotal Variation Minimization f, operatornameproxf (A/I), objective 📚 ","category":"page"},{"location":"examples/","page":"Overview","title":"Overview","text":"Symbols:","category":"page"},{"location":"examples/","page":"Overview","title":"Overview","text":"A Allocating variant\nI In-place variant\n📚 link to documented functions in the documentation","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/#Solving-Rosenbrock-with-the-Difference-of-Convex-Algorithm","page":"Rosenbrock Metric","title":"Solving Rosenbrock with the Difference of Convex Algorithm","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"Ronny Bergmann 2023-06-06","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/#Introduction","page":"Rosenbrock Metric","title":"Introduction","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"This example illustrates how the 📖 Rosenbrock problem can be rephrased as a difference of convex problem and with a new metric on Euclidean space. This example is the code that produces the results in [BFSS23], Section 7.2.","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"Both the Rosenbrock problem","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":" operatorname*argmin_xin ℝ^2 abigl( x_1^2-x_2bigr)^2 + bigl(x_1-bbigr)^2","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"where ab0 and usually b=1 and a gg b, we know the minimizer x^* = (bb^2)^mathrmT, and also the (Euclidean) gradient","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"nabla f(x) =\n beginpmatrix\n 4a(x_1^2-x_2) -2a(x_1^2-x_2)\n endpmatrix\n +\n beginpmatrix\n 2(x_1-b) 0\n endpmatrix","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"They are even available already here in ManifoldExamples.jl, see RosenbrockCost and RosenbrockGradient!!.","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"Furthermore, the RosenbrockMetric can be used on ℝ^2, that is","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"XY_mathrmRbp = X^mathrmTG_pY qquad\nG_p = beginpmatrix\n 1+4p_1^2 -2p_1 \n -2p_1 1\nendpmatrix","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"In this example we want to explore four different approaches to minimizing the Rosenbrock example, that are all based on first-order methods, i.e. using a gradient but not a Hessian.","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"The Euclidean Gradient\nThe Riemannian gradient descent with respect to the RosenbrockMetric\nThe Euclidean Difference of Convex Algorithm\nThe Riemannian Difference of Convex Algorithm respect to the RosenbrockMetric","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"Where we obtain a difference of convex problem by writing","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"f(x) = abigl( x_1^2-x_2bigr)^2 + bigl(x_1-bbigr)^2\n = abigl( x_1^2-x_2bigr)^2 + 2bigl(x_1-bbigr)^2 - bigl(x_1-bbigr)^2","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"that is","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"g(x) = abigl( x_1^2-x_2bigr)^2 + 2bigl(x_1-bbigr)^2 quadtext and quad h(x) = bigl(x_1-bbigr)^2","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"using LinearAlgebra, Random, Statistics\nusing Manifolds, Manopt, ManoptExamples\nusing NamedColors, Plots\nimport Manopt: set_manopt_parameter!\nRandom.seed!(42)","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"paul_tol = load_paul_tol()\nindigo = paul_tol[\"mutedindigo\"]\ngreen = paul_tol[\"mutedgreen\"]\nsand = paul_tol[\"mutedsand\"]\nteal = paul_tol[\"mutedteal\"]\ngrey = paul_tol[\"mutedgrey\"]","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"To emphasize the effect, we choose a quite large value of a.","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"a = 2*10^5\nb = 1","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"and use the starting point and a direction to check gradients","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"p0 = [0.1, 0.2]","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/#The-Euclidean-Gradient-Descent.","page":"Rosenbrock Metric","title":"The Euclidean Gradient Descent.","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"For the Euclidean gradient we can just use the same approach as in the Rosenbrock example","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"M = ℝ^2\nf = ManoptExamples.RosenbrockCost(M; a=a, b=b)\n∇f!! = ManoptExamples.RosenbrockGradient!!(M; a=a, b=b)","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"define a common debug vector","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"debug_vec = [\n (:Iteration, \"# %-8d \"),\n (:Cost, \"F(x): %1.4e\"),\n \" \",\n (:Change, \"|δp|: %1.4e | \"),\n (:GradientNorm, \"|grad f|: %1.6e\"),\n :Stop,\n \"\\n\",\n ]","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"and call the gradient descent algorithm","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"Eucl_GD_state = gradient_descent(M, f, ∇f!!, p0;\n evaluation=InplaceEvaluation(),\n debug=[debug_vec...,10^7],\n stopping_criterion=StopAfterIteration(10^8) | StopWhenChangeLess(1e-16),\n record=[:Iteration, :Cost],\n return_state=true,\n)","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"Initial F(x): 7.2208e+03 \n# 10000000 F(x): 8.9937e-06 |δp|: 1.3835e+00 | |grad f|: 8.170355e-03\n# 20000000 F(x): 2.9474e-09 |δp|: 6.5764e-03 | |grad f|: 1.419191e-04\n# 30000000 F(x): 9.8376e-13 |δp|: 1.1918e-04 | |grad f|: 2.526295e-06\n# 40000000 F(x): 3.2830e-16 |δp|: 2.1773e-06 | |grad f|: 4.526313e-08\n# 50000000 F(x): 1.0154e-19 |δp|: 3.9803e-08 | |grad f|: 6.838240e-10\nThe algorithm performed a step with a change (0.0) less than 1.0e-16.\n\n# Solver state for `Manopt.jl`s Gradient Descent\nAfter 53073227 iterations\n\n## Parameters\n* retraction method: ExponentialRetraction()\n\n## Stepsize\nArmijoLinesearch() with keyword parameters\n * initial_stepsize = 1.0\n * retraction_method = ExponentialRetraction()\n * contraction_factor = 0.95\n * sufficient_decrease = 0.1\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 100000000: not reached\n |Δp| < 1.0e-16: reached\nOverall: reached\nThis indicates convergence: Yes\n\n## Debug\n :Iteration = [(:Iteration, \"# %-8d \"), (:Cost, \"F(x): %1.4e\"), \" \", (:Change, \"|δp|: %1.4e | \"), (:GradientNorm, \"|grad f|: %1.6e\"), \"\\n\", 10000000]\n :Stop = :Stop\n\n## Record\n(Iteration = RecordGroup([RecordIteration(), RecordCost()]),)","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/#The-Riemannian-Gradient-Descent.","page":"Rosenbrock Metric","title":"The Riemannian Gradient Descent.","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"For the Riemannian case, we define","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"M_rb = MetricManifold(M, ManoptExamples.RosenbrockMetric())","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"MetricManifold(Euclidean(2; field=ℝ), ManoptExamples.RosenbrockMetric())","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"and the gradient is now adopted to the new metric","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"function grad_f!(M, X, p)\n ∇f!!(M, X, p)\n riemannian_gradient!(M, X, p, X)\n return X\nend\nfunction grad_f(M, p)\n X = zero_vector(M, p)\n return grad_f!(M, X, p)\nend","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"R_GD_state = gradient_descent(M_rb, f, grad_f!, p0;\n evaluation=InplaceEvaluation(),\n debug=[debug_vec...,10^6],\n stopping_criterion=StopAfterIteration(10^8) | StopWhenChangeLess(1e-16),\n record=[:Iteration, :Cost],\n return_state=true,\n)","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"Initial F(x): 7.2208e+03 \n# 1000000 F(x): 1.3571e-09 |δp|: 9.1006e-01 | |grad f|: 1.974939e-04\n# 2000000 F(x): 2.7921e-18 |δp|: 3.6836e-05 | |grad f|: 9.240792e-09\nThe algorithm performed a step with a change (0.0) less than 1.0e-16.\n\n# Solver state for `Manopt.jl`s Gradient Descent\nAfter 2443750 iterations\n\n## Parameters\n* retraction method: ExponentialRetraction()\n\n## Stepsize\nArmijoLinesearch() with keyword parameters\n * initial_stepsize = 1.0\n * retraction_method = ExponentialRetraction()\n * contraction_factor = 0.95\n * sufficient_decrease = 0.1\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 100000000: not reached\n |Δp| < 1.0e-16: reached\nOverall: reached\nThis indicates convergence: Yes\n\n## Debug\n :Iteration = [(:Iteration, \"# %-8d \"), (:Cost, \"F(x): %1.4e\"), \" \", (:Change, \"|δp|: %1.4e | \"), (:GradientNorm, \"|grad f|: %1.6e\"), \"\\n\", 1000000]\n :Stop = :Stop\n\n## Record\n(Iteration = RecordGroup([RecordIteration(), RecordCost()]),)","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/#The-Euclidean-Difference-of-Convex","page":"Rosenbrock Metric","title":"The Euclidean Difference of Convex","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"For the convex case, we have to first introduce the two parts of the cost.","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"f1(M, p; a=100, b=1) = a * (p[1]^2 - p[2])^2;\nf2(M, p; a=100, b=1) = (p[1] - b[1])^2;\ng(M, p; a=100, b=1) = f1(M, p; a=a, b=b) + 2 * f2(M, p; a=a, b=b)\nh(M, p; a=100, b=1) = f2(M, p; a=a, b=b)","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"and their (Euclidan) gradients","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"function ∇h!(M, X, p; a=100, b=1)\n X[1] = 2*(p[1]-b)\n X[2] = 0\n return X\nend\nfunction ∇h(M, p; a=100, b=1)\n X = zero(p)\n ∇h!(M, X, p; a=a, b=b)\n return X\nend\nfunction ∇g!(M, X, p; a=100, b=1)\n X[1] = 4*a*(p[1]^2-p[2])*p[1] + 2*2*(p[1]-b)\n X[2] = -2*a*(p[1]^2-p[2])\n return X\nend\nfunction ∇g(M, p; a=100, b=1)\n X = zero(p)\n ∇g!(M, X, p; a=a, b=b)\n return X\nend","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"and we define for convenience","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"docE_g(M, p) = g(M, p; a=a, b=b)\ndocE_f(M,p) = docE_g(M,p) - h(M, p; a=a, b=b)\ndocE_∇h!(M, X, p) = ∇h!(M, X, p; a=a, b=b)\ndocE_∇g!(M, X, p) = ∇g!(M, X, p; a=a, b=b)\nfunction docE_∇f!(M, X, p)\n Y = zero_vector(M, p)\n docE_∇g!(M, X, p)\n docE_∇h!(M, Y, p)\n X .-= Y\n return X\nend","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"Then we call the difference of convex algorithm on Eucldiean space ℝ^2.","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"E_doc_state = difference_of_convex_algorithm(\n M, docE_f, docE_g, docE_∇h!, p0;\n gradient=docE_∇f!,\n grad_g = docE_∇g!,\n debug=[debug_vec..., 10^4],\n evaluation=InplaceEvaluation(),\n record=[:Iteration, :Cost],\n stopping_criterion=StopAfterIteration(10^8) | StopWhenChangeLess(1e-16),\n sub_hess=nothing, # Use gradient descent\n sub_stopping_criterion=StopAfterIteration(2000) | StopWhenGradientNormLess(1e-16),\n return_state=true,\n)","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"Initial F(x): 7.2208e+03 \n# 10000 F(x): 2.9705e-09 |δp|: 1.3270e+00 | |grad f|: 1.388203e-04\n# 20000 F(x): 3.3302e-16 |δp|: 1.2173e-04 | |grad f|: 4.541087e-08\nThe algorithm performed a step with a change (0.0) less than 1.0e-16.\n\n# Solver state for `Manopt.jl`s Difference of Convex Algorithm\nAfter 26549 iterations\n\n## Parameters\n* sub solver state:\n | # Solver state for `Manopt.jl`s Gradient Descent\n | After 2000 iterations\n | \n | ## Parameters\n | * retraction method: ExponentialRetraction()\n | \n | ## Stepsize\n | ArmijoLinesearch() with keyword parameters\n | * initial_stepsize = 1.0\n | * retraction_method = ExponentialRetraction()\n | * contraction_factor = 0.95\n | * sufficient_decrease = 0.1\n | \n | ## Stopping criterion\n | \n | Stop When _one_ of the following are fulfilled:\n | Max Iteration 2000: reached\n | |grad f| < 1.0e-16: not reached\n | Overall: reached\n | This indicates convergence: No\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 100000000: not reached\n |Δp| < 1.0e-16: reached\nOverall: reached\nThis indicates convergence: Yes\n\n## Debug\n :Iteration = [(:Iteration, \"# %-8d \"), (:Cost, \"F(x): %1.4e\"), \" \", (:Change, \"|δp|: %1.4e | \"), (:GradientNorm, \"|grad f|: %1.6e\"), \"\\n\", 10000]\n :Stop = :Stop\n\n## Record\n(Iteration = RecordGroup([RecordIteration(), RecordCost()]),)","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/#The-Riemannian-Difference-of-Convex","page":"Rosenbrock Metric","title":"The Riemannian Difference of Convex","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"We first have to again defined the gradients with respect to the new metric","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"function grad_h!(M, X, p; a=100, b=1)\n ∇h!(M, X, p; a=a, b=b)\n riemannian_gradient!(M, X, p, X)\n return X\nend\nfunction grad_h(M, p; a=100, b=1)\n X = zero(p)\n grad_h!(M, X, p; a=a, b=b)\n return X\nend\nfunction grad_g!(M, X, p; a=100, b=1)\n ∇g!(M, X, p; a=a,b=b)\n riemannian_gradient!(M, X, p, X)\n return X\nend\nfunction grad_g(M, p; a=100, b=1)\n X = zero(p)\n grad_g!(M, X, p; a=a, b=b)\n return X\nend","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"While the cost of the subgradient can be infered automaticallty, we also have to provide the gradient of the sub problem. For X in h(p^(k)) the sunproblem top determine p^(k+1) reads","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"operatorname*argmin_pinmathcal M g(p) - langle X log_p^(k)prangle","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"for which usually the cost and gradient functions are computed automatically in the difference of convex algorithm. However, in our case first the closed form solution for the adjoint differential of the logaithmic map is complicated to compute and second the gradint can even be given in a nicer form. We can first simplify in our case with X = operatornamegrad h(p^(k)) that","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"phi(p) = g(p) - langle X log_p^(k)prangle\n= abigl( p_1^2-p_2bigr)^2\n + 2bigl(p_1-bbigr)^2 - 2(p^(k)_1-b)p_1 + 2(p^(k)_1-b)p^(k)_1","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"its Euclidean gradient reads","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"operatornamegradphi(p) =\n nabla varphi(p)\n = beginpmatrix\n 4a p_1(p_1^2-p_2) + 4(p_1-b) - 2(p^(k)_1-b)\n -2a(p_1^2-p_2)\n endpmatrix","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"where we can again employ the gradient conversion from before to obtain the Riemannian gradient.","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"mutable struct SubGrad{P,T,V}\n pk::P\n Xk::T\n a::V\n b::V\nend\nfunction (ϕ::SubGrad)(M, p)\n X = zero_vector(M, p)\n ϕ(M, X, p)\n return X\nend\nfunction (ϕ::SubGrad)(M, X, p)\n X .= [\n 4 * ϕ.a * p[1] * (p[1]^2 - p[2]) + 4 * (p[1] - ϕ.b) - 2 * (ϕ.pk[1] - ϕ.b),\n -2 * ϕ.a * (p[1]^2 - p[2]),\n ]\n riemannian_gradient!(M, X, p, X) # convert\n return X\nend","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"And in orer to update the subsolvers gradient correctly, we have to overwrite","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"set_manopt_parameter!(ϕ::SubGrad, ::Val{:p}, p) = (ϕ.pk .= p)\nset_manopt_parameter!(ϕ::SubGrad, ::Val{:X}, X) = (ϕ.Xk .= X)","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"And we again introduce for ease of use","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"docR_g(M, p) = g(M, p; a=a, b=b)\ndocR_f(M, p) = docR_g(M, p) - h(M, p; a=a, b=b)\ndocR_grad_h!(M, X, p) = grad_h!(M, X, p; a=a, b=b)\ndocR_grad_g!(M, X, p) = grad_g!(M, X, p; a=a, b=b)\nfunction docR_grad_f!(M, X, p)\n Y = zero_vector(M, p)\n docR_grad_g!(M, X, p)\n docR_grad_h!(M, Y, p)\n X .-= Y\n return X\nend\ndocR_sub_grad = SubGrad(copy(M, p0), zero_vector(M, p0), a, b)","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"Then we can finally call the last of our four algorithms to compare, the difference of convex algorithm with the Riemannian metric.","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"R_doc_state = difference_of_convex_algorithm(\n M_rb, docR_f, docR_g, docR_grad_h!, p0;\n gradient=docR_grad_f!,\n grad_g = docR_grad_g!,\n debug=[debug_vec..., 10^6],\n evaluation=InplaceEvaluation(),\n record=[:Iteration, :Cost],\n stopping_criterion=StopAfterIteration(10^8) | StopWhenChangeLess(1e-16),\n sub_grad=docR_sub_grad,\n sub_hess = nothing, # Use gradient descent\n sub_stopping_criterion=StopAfterIteration(2000) | StopWhenGradientNormLess(1e-16),\n return_state=true,\n)","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"Initial F(x): 7.2208e+03 \nThe algorithm performed a step with a change (0.0) less than 1.0e-16.\n\n# Solver state for `Manopt.jl`s Difference of Convex Algorithm\nAfter 1235 iterations\n\n## Parameters\n* sub solver state:\n | # Solver state for `Manopt.jl`s Gradient Descent\n | After 2000 iterations\n | \n | ## Parameters\n | * retraction method: ExponentialRetraction()\n | \n | ## Stepsize\n | ArmijoLinesearch() with keyword parameters\n | * initial_stepsize = 1.0\n | * retraction_method = ExponentialRetraction()\n | * contraction_factor = 0.95\n | * sufficient_decrease = 0.1\n | \n | ## Stopping criterion\n | \n | Stop When _one_ of the following are fulfilled:\n | Max Iteration 2000: reached\n | |grad f| < 1.0e-16: not reached\n | Overall: reached\n | This indicates convergence: No\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 100000000: not reached\n |Δp| < 1.0e-16: reached\nOverall: reached\nThis indicates convergence: Yes\n\n## Debug\n :Iteration = [(:Iteration, \"# %-8d \"), (:Cost, \"F(x): %1.4e\"), \" \", (:Change, \"|δp|: %1.4e | \"), (:GradientNorm, \"|grad f|: %1.6e\"), \"\\n\", 1000000]\n :Stop = :Stop\n\n## Record\n(Iteration = RecordGroup([RecordIteration(), RecordCost()]),)","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/#Comparison-in-Iterations","page":"Rosenbrock Metric","title":"Comparison in Iterations","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"fig = plot(;\n legend=:topright,\n xlabel=raw\"Iterations $k$ (log. scale)\", ylabel=raw\"Cost $f(x)$ (log. scale)\",\n yaxis=:log,\n ylims=(1e-16, 5*1e5),\n xaxis=:log,\n xlims=(1,10^8),\n)\nscatter!(fig, [1,], [f(M,p0),], label=raw\"$f(p_0)$\", markercolor=grey)\negi = get_record(Eucl_GD_state, :Iteration, :Iteration)[1:10000:end] #5308 entries\negc = get_record(Eucl_GD_state, :Iteration, :Cost)[1:10000:end] #5308 entries\nplot!(fig, egi, egc, color=teal, label=\"Euclidean GD\")\n#\nrgi = get_record(R_GD_state, :Iteration, :Iteration)[1:1000:end] # 2444 entries\nrgc = get_record(R_GD_state, :Iteration, :Cost)[1:1000:end] # 2444 entries\nplot!(fig, rgi, rgc, color=indigo, label=\"Riemannian GD\")\n#\nedi = get_record(E_doc_state, :Iteration, :Iteration) #26549 entries\nedc = get_record(E_doc_state, :Iteration, :Cost) #26549 entries\nplot!(fig, edi, edc, color=sand, label=\"Euclidean DoC\")\n#\nrdi = get_record(R_doc_state, :Iteration, :Iteration) # 1235 entries\nrdc = get_record(R_doc_state, :Iteration, :Cost) # 1235 entries\nplot!(fig, rdi, rdc, color=green, label=\"Riemannian DoC\")","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"(Image: )","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"And we can see that using difference of convex outperforms gradient descent, and using the Riemannian approach required less iterations than their Euclidean counterparts.","category":"page"},{"location":"examples/Difference-of-Convex-Rosenbrock/#Literature","page":"Rosenbrock Metric","title":"Literature","text":"","category":"section"},{"location":"examples/Difference-of-Convex-Rosenbrock/","page":"Rosenbrock Metric","title":"Rosenbrock Metric","text":"R. Bergmann, O. P. Ferreira, E. M. Santos and J. C. Souza. The difference of convex algorithm on Hadamard manifolds. Preprint (2023), arXiv:2112.05250.\n\n\n\n","category":"page"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"EditURL = \"https://github.com/JuliaManifolds/Manopt.jl/blob/master/Changelog.md\"","category":"page"},{"location":"changelog/#Changelog","page":"Changelog","title":"Changelog","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"All notable changes to this Julia package will be documented in this file.","category":"page"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.","category":"page"},{"location":"changelog/#[0.1.8]-–-12/06/2024","page":"Changelog","title":"[0.1.8] – 12/06/2024","text":"","category":"section"},{"location":"changelog/#Changed","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"use range compatible with Julia 1.6 and hence lower the compatibility entry for Julia again.","category":"page"},{"location":"changelog/#[0.1.7]-–-07/06/2024","page":"Changelog","title":"[0.1.7] – 07/06/2024","text":"","category":"section"},{"location":"changelog/#Changed-2","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"make Manopt.jl a weak dependency and load functions that require parts of it only load as an extension. This makes it easier to use the examples in the tests of Manopt itself.","category":"page"},{"location":"changelog/#[0.1.6]-–-22/03/2024","page":"Changelog","title":"[0.1.6] – 22/03/2024","text":"","category":"section"},{"location":"changelog/#Added","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Hyperparameter optimization example.","category":"page"},{"location":"changelog/#[0.1.3]-–-11/12/2023","page":"Changelog","title":"[0.1.3] – 11/12/2023","text":"","category":"section"},{"location":"changelog/#Added-2","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Total variation Minimization cost, proxes, and an example\nBézier curve cost, gradients, and an example.","category":"page"},{"location":"changelog/#[0.1.3]-–-16/09/2023","page":"Changelog","title":"[0.1.3] – 16/09/2023","text":"","category":"section"},{"location":"changelog/#Added-3","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Rayleigh Quotient functions added\nan example illustrating Euclidean gradient/HEssian conversion\nAdd Literature with DocumenterCitations","category":"page"},{"location":"changelog/#[0.1.2]-–-13/06/2023","page":"Changelog","title":"[0.1.2] – 13/06/2023","text":"","category":"section"},{"location":"changelog/#Added-4","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Update examples to use Quarto\nAdd DC examples","category":"page"},{"location":"changelog/#[0.1.1]-–-01/03/2023","page":"Changelog","title":"[0.1.1] – 01/03/2023","text":"","category":"section"},{"location":"changelog/#Added-5","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Rosenbrock function and examples","category":"page"},{"location":"changelog/#[0.1.0]-–-18/02/2023","page":"Changelog","title":"[0.1.0] – 18/02/2023","text":"","category":"section"},{"location":"changelog/#Added-6","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Setup the project to collect example objectives for Manopt.jl which are well-documented and well-tested\nSetup Documentation to provide one example Quarto file for every example objective to illustrate how to use them.","category":"page"},{"location":"examples/Bezier-curves/#Minimizing-the-Acceleration-of-Bézier-Curves-on-the-Sphere","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"","category":"section"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"Ronny Bergmann 2023-06-06","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"using Manifolds, Manopt, ManoptExamples","category":"page"},{"location":"examples/Bezier-curves/#Introduction","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Introduction","text":"","category":"section"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"Bézier Curves can be generalized to manifolds by generalizing the de Casteljau algorithm 📖 to work with geodesics instead of straight lines. An implementation in just a few lines as we demonstrated in [ABBR23] as","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"function bezier(M::AbstractManifold, t, pts::NTuple)\n p = bezier(M, t, pts[1:(end - 1)])\n q = bezier(M, t, pts[2:end])\n return shortest_geodesic(M, p, q, t)\nend\nfunction bezier(M::AbstractManifold, t, pts::NTuple{2})\n return shortest_geodesic(M, pts[1], pts[2], t)\nend","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"which is also available within this package as de_Casteljau using a simple BezierSegment struct to make it easier to also discuss the case where we compose a set of segments into a composite Bézier course.","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"In the following we will need the following packages and functions. They are documented in the section on Bezier Curves and were derived in [BG18] based on [PN07].","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"using ManoptExamples:\n artificial_S2_composite_Bezier_curve,\n BezierSegment,\n de_Casteljau,\n get_Bezier_degrees,\n get_Bezier_inner_points,\n get_Bezier_junctions,\n get_Bezier_junction_tangent_vectors,\n get_Bezier_points,\n get_Bezier_segments,\n grad_L2_acceleration_Bezier,\n L2_acceleration_Bezier","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"This notebook reproduces the example form Section 5.2 in [BG18].","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"The following image illustrates how the de-Casteljau algorithm works for one segment.","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"(Image: A Bezier segment and illustration of the de-Casteljau algorithm)","category":"page"},{"location":"examples/Bezier-curves/#Approximating-data-by-a-curve-with-minimal-accelartion","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Approximating data by a curve with minimal accelartion","text":"","category":"section"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"We first load our example data","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"M = Sphere(2)\nB = artificial_S2_composite_Bezier_curve()\ndata_points = get_Bezier_junctions(M, B)","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"Which is the following cure, which clearly starts and ends slower than its speed in the middle, which can be seen by the increasing length of the gangent vectors in the middle.","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"(Image: The original curve)","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"We continue to recude the points, since we “know” sme points due to the C^1 property: the second to last control point of the first segment b_02, the joint junction point connecting both segments b_03=b_10 and the second control point b_11 of the second segment have to line in the tangent space of the joint junction point. Hence we only have to store one of the control points.","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"We can use this reduced form as the variable to optimize and the one from the data as our initial point.","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"pB = get_Bezier_points(M, B, :differentiable)\nN = PowerManifold(M, NestedPowerRepresentation(), length(pB))","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"PowerManifold(Sphere(2, ℝ), NestedPowerRepresentation(), 8)","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"And we further define the acceleration of the curve as our cost function, where we discretize the acceleration at a certain set of points and set the λ=10","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"curve_samples = [range(0, 3; length=101)...] # sample curve for the gradient\nλ = 10.0\nfunction f(M, pB)\n return L2_acceleration_Bezier(\n M.manifold, pB, get_Bezier_degrees(M.manifold, B), curve_samples, λ, data_points\n )\nend\nfunction grad_f(M, pB)\n return grad_L2_acceleration_Bezier(\n M.manifold, pB, get_Bezier_degrees(M.manifold, B), curve_samples, λ, data_points\n )\nend","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"grad_f (generic function with 1 method)","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"Then we can optimize","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"x0 = pB\npB_opt = gradient_descent(\n N,\n f,\n grad_f,\n x0;\n stepsize=ArmijoLinesearch(N;\n initial_stepsize=1.0,\n retraction_method=ExponentialRetraction(),\n contraction_factor=0.5,\n sufficient_decrease=0.001,\n ),\n stopping_criterion=StopWhenChangeLess(1e-5) |\n StopWhenGradientNormLess(1e-7) |\n StopAfterIteration(300),\n debug=[\n :Iteration,\n \" | \",\n :Cost,\n \" | \",\n DebugGradientNorm(),\n \" | \",\n DebugStepsize(),\n \" | \",\n :Change,\n \"\\n\",\n 25,\n :Stop,\n ],\n);","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"Initial | f(x): 10.647244 | | | \n# 25 | f(x): 2.667564 | |grad f(p)|:0.890845571434862 | s:0.01326670131422904 | Last Change: 0.763281\n# 50 | f(x): 2.650064 | |grad f(p)|:0.05536989605165708 | s:0.05306680525691616 | Last Change: 0.081780\n# 75 | f(x): 2.649707 | |grad f(p)|:0.02135638585837997 | s:0.01326670131422904 | Last Change: 0.011590\n# 100 | f(x): 2.649700 | |grad f(p)|:0.0012887575647752057 | s:0.05306680525691616 | Last Change: 0.001745\nThe algorithm performed a step with a change (2.9063044690733034e-7) less than 1.0e-5.","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"And we can again look at the result","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"The result looks as","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"(Image: The resulting curve)","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"where all control points are evenly spaced and we hence have less acceleration as the final cost compared to the initial one indicates. Note that the cost is not zero, since we always have a tradeoff between approximating the initial junctinons (data points) and minimizing the acceleration.","category":"page"},{"location":"examples/Bezier-curves/","page":"Minimizing the Acceleration of Bézier Curves on the Sphere","title":"Minimizing the Acceleration of Bézier Curves on the Sphere","text":"S. D. Axen, M. Baran, R. Bergmann and K. Rzecki. Manifolds.jl: An Extensible Julia Framework for Data Analysis on Manifolds. ACM Transactions on Mathematical Software (2023), arXiv:2021.08777.\n\n\n\nR. Bergmann and P.-Y. Gousenbourger. A variational model for data fitting on manifolds by minimizing the acceleration of a Bézier curve. Frontiers in Applied Mathematics and Statistics 4 (2018), arXiv:1807.10090.\n\n\n\nT. Popiel and L. Noakes. Bézier curves and C^2 interpolation in Riemannian manifolds. Journal of Approximation Theory 148, 111–127 (2007).\n\n\n\n","category":"page"},{"location":"data/#Data-sets","page":"Data","title":"Data sets","text":"","category":"section"},{"location":"data/#Signals-on-manifolds","page":"Data","title":"Signals on manifolds","text":"","category":"section"},{"location":"data/","page":"Data","title":"Data","text":"Modules = [ManoptExamples]\nPages = [\"data/artificial_signals.jl\"]\nOrder = [:type, :function]\nPrivate = true","category":"page"},{"location":"data/#ManoptExamples.Lemniscate-Tuple{Number}","page":"Data","title":"ManoptExamples.Lemniscate","text":"Lemniscate(t::Float; kwargs...)\nLemniscate(n::integer; interval=[0.0, 2π], kwargs...)\n\ngenerate the Lemniscate of Bernoulli as a curve on a manifold, by generating the curve emplying the keyword arguments below.\n\nTo be precise on the manifold M we use the tangent space at p and generate the curve\n\nγ(t) fracasin^2(t) + 1 beginpmatrix cos(t) cos(t)sin(t) endpmatrix\n\nin the plane spanned by X and Y in the tangent space. Note that this curve is 2π-periodic and a is the half-width of the curve.\n\nTo reproduce the first examples from [BBSW16] as a default, on the sphere p defaults to the North pole.\n\nTHe second variant generates n points equispaced in ìnterval` and calls the first variant.\n\nKeywords\n\nmanifold - (Sphere(2)) the manifold to build the lemniscate on\np - ([0.0, 0.0, 1.0] on the sphere, `rand(M) else) the center point of the Lemniscate\na – (π/2.0) half-width of the Lemniscate\nX – ([1.0, 0.0, 0.0] for the 2-sphere with default p, the first DefaultOrthonormalBasis() vector otherwise) first direction for the plane to define the Lemniscate in, unit vector recommended.\nY – ([0.0, 1.0, 0.0] if p is the default, the second DefaultOrthonormalBasis() vector otherwise) second direction for the plane to define the Lemniscate in, unit vector orthogonal to X recommended.\n\n\n\n\n\n","category":"method"},{"location":"data/#ManoptExamples.artificial_S1_signal","page":"Data","title":"ManoptExamples.artificial_S1_signal","text":"artificial_S1_signal([pts=500])\n\ngenerate a real-valued signal having piecewise constant, linear and quadratic intervals with jumps in between. If the resulting manifold the data lives on, is the Circle the data is also wrapped to ``[BLSW14].\n\nOptional\n\npts: (500) number of points to sample the function\n\n\n\n\n\n","category":"function"},{"location":"data/#ManoptExamples.artificial_S1_signal-Tuple{Real}","page":"Data","title":"ManoptExamples.artificial_S1_signal","text":"artificial_S1_signal(x)\n\nevaluate the example signal f(x) x 01, of phase-valued data introduces in Sec. 5.1 of [BLSW14] for values outside that interval, this Signal is missing.\n\n\n\n\n\n","category":"method"},{"location":"data/#ManoptExamples.artificial_S1_slope_signal","page":"Data","title":"ManoptExamples.artificial_S1_slope_signal","text":"artificial_S1_slope_signal([pts=500, slope=4.])\n\nCreates a Signal of (phase-valued) data represented on the Circle with increasing slope.\n\nOptional\n\npts: (500) number of points to sample the function.\nslope: (4.0) initial slope that gets increased afterwards\n\nThis data set was introduced for the numerical examples in [BLSW14]\n\n\n\n\n\n","category":"function"},{"location":"data/#ManoptExamples.artificial_S2_composite_Bezier_curve-Tuple{}","page":"Data","title":"ManoptExamples.artificial_S2_composite_Bezier_curve","text":"artificial_S2_composite_Bezier_curve()\n\nGenerate a composite Bézier curve on the [BG18].\n\nIt consists of 4 egments connecting the points\n\nmathbf d_0 = beginpmatrix 001endpmatrixquad\nmathbf d_1 = beginpmatrix 0-10endpmatrixquad\nmathbf d_2 = beginpmatrix -100endpmatrixtext and \nmathbf d_3 = beginpmatrix 00-1endpmatrix\n\nwhere instead of providing the two center control points explicitly we provide them as velocities from the corresponding points, such thtat we can directly define the curve to be C^1.\n\nWe define\n\nX_0 = fracπ8sqrt2beginpmatrix1-10endpmatrixquad\nX_1 = fracπ4sqrt2beginpmatrix101endpmatrixquad\nX_2 = fracπ4sqrt2beginpmatrix01-1endpmatrixtext and \nX_3 = fracπ8sqrt2beginpmatrix-110endpmatrix\n\nwhere we defined each X_i in T_d_imathbb S^2. We defined three BezierSegments\n\nof cubic Bézier curves as follows\n\nbeginalign*\nb_00 = d_0 quad b_10 = exp_d_0X_0 quad b_20 = exp_d_1X_1 quad b_30 = d_1\nb_01 = d_1 quad b_11 = exp_d_1(-X_1) quad b_21 = exp_d_2X_2 quad b_31 = d_2\nb_02 = d_2 quad b_11 = exp_d_2(-X_2) quad b_22 = exp_d_3X_3 quad b_32 = d_3\nendalign*\n\n\n\n\n\n","category":"method"},{"location":"data/#images-on-manifolds","page":"Data","title":"images on manifolds","text":"","category":"section"},{"location":"data/","page":"Data","title":"Data","text":"Modules = [ManoptExamples]\nPages = [\"data/artificial_images.jl\"]\nOrder = [:type, :function]\nPrivate = true","category":"page"},{"location":"data/#ManoptExamples.artificialIn_SAR_image-Tuple{Integer}","page":"Data","title":"ManoptExamples.artificialIn_SAR_image","text":"artificialIn_SAR_image([pts=500])\n\ngenerate an artificial InSAR image, i.e. phase valued data, of size pts x pts points.\n\nThis data set was introduced for the numerical examples in [BLSW14].\n\n\n\n\n\n","category":"method"},{"location":"data/#ManoptExamples.artificial_S2_rotation_image","page":"Data","title":"ManoptExamples.artificial_S2_rotation_image","text":"artificial_S2_rotation_image([pts=64, rotations=(.5,.5)])\n\nCreate an image with a rotation on each axis as a parametrization.\n\nOptional Parameters\n\npts: (64) number of pixels along one dimension\nrotations: ((.5,.5)) number of total rotations performed on the axes.\n\nThis dataset was used in the numerical example of Section 5.1 of [BBSW16].\n\n\n\n\n\n","category":"function"},{"location":"data/#ManoptExamples.artificial_S2_whirl_image","page":"Data","title":"ManoptExamples.artificial_S2_whirl_image","text":"artificial_S2_whirl_image([pts::Int=64])\n\nGenerate an artificial image of data on the 2 sphere,\n\nArguments\n\npts: (64) size of the image in pts×pts pixel.\n\nThis example dataset was used in the numerical example in Section 5.5 of [LNPS17]\n\nIt is based on artificial_S2_rotation_image extended by small whirl patches.\n\n\n\n\n\n","category":"function"},{"location":"data/#ManoptExamples.artificial_S2_whirl_patch","page":"Data","title":"ManoptExamples.artificial_S2_whirl_patch","text":"artificial_S2_whirl_patch([pts=5])\n\ncreate a whirl within the pts×pts patch of Sphere(@ref)(2)-valued image data.\n\nThese patches are used within artificial_S2_whirl_image.\n\nOptional Parameters\n\npts: (5) size of the patch. If the number is odd, the center is the north pole.\n\n\n\n\n\n","category":"function"},{"location":"data/#ManoptExamples.artificial_SPD_image","page":"Data","title":"ManoptExamples.artificial_SPD_image","text":"artificial_SPD_image([pts=64, stepsize=1.5])\n\ncreate an artificial image of symmetric positive definite matrices of size pts×pts pixel with a jump of size stepsize.\n\nThis dataset was used in the numerical example of Section 5.2 of [BBSW16].\n\n\n\n\n\n","category":"function"},{"location":"data/#ManoptExamples.artificial_SPD_image2","page":"Data","title":"ManoptExamples.artificial_SPD_image2","text":"artificial_SPD_image2([pts=64, fraction=.66])\n\ncreate an artificial image of symmetric positive definite matrices of size pts×pts pixel with right hand side fraction is moved upwards.\n\nThis data set was introduced in the numerical examples of Section of [BPS16]\n\n\n\n\n\n","category":"function"},{"location":"data/#Literature","page":"Data","title":"Literature","text":"","category":"section"},{"location":"data/","page":"Data","title":"Data","text":"M. Bačák, R. Bergmann, G. Steidl and A. Weinmann. A second order non-smooth variational model for restoring manifold-valued images. SIAM Journal on Scientific Computing 38, A567–A597 (2016), arXiv:1506.02409.\n\n\n\nR. Bergmann and P.-Y. Gousenbourger. A variational model for data fitting on manifolds by minimizing the acceleration of a Bézier curve. Frontiers in Applied Mathematics and Statistics 4 (2018), arXiv:1807.10090.\n\n\n\nR. Bergmann, F. Laus, G. Steidl and A. Weinmann. Second order differences of cyclic data and applications in variational denoising. SIAM Journal on Imaging Sciences 7, 2916–2953 (2014), arXiv:1405.5349.\n\n\n\nR. Bergmann, J. Persch and G. Steidl. A parallel Douglas Rachford algorithm for minimizing ROF-like functionals on images with values in symmetric Hadamard manifolds. SIAM Journal on Imaging Sciences 9, 901–937 (2016), arXiv:1512.02814.\n\n\n\nF. Laus, M. Nikolova, J. Persch and G. Steidl. A nonlocal denoising algorithm for manifold-valued images using second order statistics. SIAM Journal on Imaging Sciences 10, 416–448 (2017).\n\n\n\n","category":"page"},{"location":"examples/Robust-PCA/#The-Robust-PCA-computed-on-the-Grassmann-manifold","page":"Robust PCA","title":"The Robust PCA computed on the Grassmann manifold","text":"","category":"section"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"Ronny BergmannLaura Weigl 2023-07-02","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"For this example we first load the necessary packages.","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"using Pkg;\ncd(@__DIR__)\nPkg.activate(\".\"); # use the example environment,","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"using LinearAlgebra, Random, Statistics\nusing Manifolds, Manopt, ManoptExamples\nusing Plots\nRandom.seed!(42)","category":"page"},{"location":"examples/Robust-PCA/#Computing-a-Robust-PCA","page":"Robust PCA","title":"Computing a Robust PCA","text":"","category":"section"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"For a given matrix D ℝ^dn whose columns represent points in ℝ^d, a matrix p ℝ^dm is computed for a given dimension m n: p represents an ONB of ℝ^dm such that the column space of p approximates the points (columns of D), i.e. the vectors D_i as well as possible.","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"We compute p as a minimizer over the Grassmann manifold of the cost function:","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"beginsplit\nf(p)\n = frac1nsum_i=1^noperatornamedist(D_i operatornamespan(p))\n\n = frac1n sum_i=1^nlVert pp^TD_i - D_irVert\nendsplit","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"The output cost represents the average distance achieved with the returned p, an orthonormal basis (or a point on the Stiefel manifold) representing the subspace (a point on the Grassmann manifold). Notice that norms are not squared, so we have a robust cost function. This means that f is nonsmooth, therefore we regularize with a pseudo-Huber loss function of smoothing parameter ε.","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"f_ϵ(p) = frac1n sum_i=1^nℓ_ϵ(lVert pp^mathrmTD_i - D_irVert)","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"where ℓ_ϵ(x) = sqrtx^2 + ϵ^2 - ϵ.","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"The smoothing parameter is iteratively reduced in the final optimisation runs(with warm starts).","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"First, we generate random data. For illustration purposes we take points in mathbb R^2 and m=1, that is we aim to find a robust regression line.","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"n = 40\nd = 2\noutliers = 15\ndata = randn(d, 1) * (1:n)' + 0.05 * randn(2, n) .* [1:n 1:n]'\n# Outliers:\npermute = shuffle(1:size(data, 2))'\ndata[:, permute[1:outliers]] = 30 * randn(2, outliers)\n# We are looking for a line here so we set\nm = 1","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"We use the Manopt toolbox to optimize the regularized cost function over the Grassmann manifold. To do this, we first need to define the problem structure.","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"M = Grassmann(d,m);","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"For the initial matrix p_0 we use classical PCA via singular value decomposition. Thus, we use the first d left singular vectors.","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"Then, we compute an optimum of the cost function over the Grassmann manifold. We use a trust-region method which is implemented in Manopt.jl.","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"Furthermore the cost and gradient are implemented in ManoptExamples.jl. Since these are Huber regularized, both functors have the ϵ as a parameter. To compute the Riemannian gradient we first compute the Euclidian gradient. Afterwards it is projected onto the tangent space by using the orthogonal projection pp^T - I, which converts the Euclidean to the Riemannian gradient.","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"The trust-region method also requires the Hessian Matrix. By using ApproxHessianFiniteDifference using a finite difference scheme we get an approximation of the Hessian Matrix.","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"We run the procedure several times, where the smoothing parameter ε is reduced iteratively.","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"ε = 1.0\niterations = 6\nreduction = 0.5\nU, S, V = svd(data);\np0 = U[:, 1:m]","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"2×1 Matrix{Float64}:\n -0.7494248652139397\n 0.6620893983436593","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"Let’s generate the cost and gradient we aim to use here","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"f = ManoptExamples.RobustPCACost(M, data, ε)\ngrad_f = ManoptExamples.RobustPCAGrad!!(M, data, ε)","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"ManoptExamples.RobustPCAGrad!!{Matrix{Float64}, Float64}([9.537606557855465 1.6583418797018163 … 30.833523701909474 30.512999245062304; -45.34339972619071 -1.7120433539256108 … -35.85943792458936 -32.93976007215313], 1.0, [0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0])","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"and check the initial cost","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"f(M, p0)","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"9.430690947905521","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"Now we iterate the opimization with reducing ε after every iteration, which we update in f and grad_f.","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"q = copy(M, p0)\nεi = ε\nfor i in 1:iterations\n f.ε = εi\n grad_f.ε = εi\n global q = trust_regions(\n M,\n f,\n grad_f,\n ApproxHessianFiniteDifference(\n M, q, f;\n vector_transport_method=ProjectionTransport(),\n retraction_method=PolarRetraction(),\n ),\n q;\n (project!)=project!,\n )\n global εi *= reduction\nend","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"When finally setting ε we can investigate the final cost","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"f.ε = 0.0\nf(M, q)","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"9.412961981726742","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"Finally, the results are presented visually. The data points are visualized in a scatter plot. The result of the robust PCA and (for comparison) the standard SVD solution are plotted as straight lines.","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"fig = plot(data[1, :], data[2, :]; seriestype=:scatter, label=\"Data points\");\nplot!(\n fig,\n q[1] * [-1, 1] * 100,\n q[2] * [-1, 1] * 100;\n linecolor=:red,\n linewidth=2,\n label=\"Robust PCA\",\n);\nplot!(\n fig,\n p0[1] * [-1, 1] * 100,\n p0[2] * [-1, 1] * 100;\n xlims=1.1 * [minimum(data[1, :]), maximum(data[1, :])],\n ylims=1.1 * [minimum(data[2, :]), maximum(data[2, :])],\n linewidth=2,\n linecolor=:black,\n label=\"Standard SVD\",\n)","category":"page"},{"location":"examples/Robust-PCA/","page":"Robust PCA","title":"Robust PCA","text":"(Image: Figure 1: The result of the robust PCA vs. SVD)","category":"page"},{"location":"examples/Total-Variation/#Total-Variation-Minimization","page":"Total Variation","title":"Total Variation Minimization","text":"","category":"section"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"Ronny Bergmann 2023-06-06","category":"page"},{"location":"examples/Total-Variation/#Introduction","page":"Total Variation","title":"Introduction","text":"","category":"section"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"Total Variation denoising is an optimization problem used to denoise signals and images. The corresponding (Euclidean) objective is often called Rudin-Osher-Fatemi (ROF) model based on the paper [ROF92].","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"This was generalized to manifolds in [WDS14]. In this short example we will look at the ROF model for manifold-valued data, its generalizations, and how they can be solved using Manopt.jl.","category":"page"},{"location":"examples/Total-Variation/#The-manifold-valued-ROF-model","page":"Total Variation","title":"The manifold-valued ROF model","text":"","category":"section"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"Generalizing the ROF model to manifolds can be phrased as follows: Given a (discrete) signal on a manifold s = (s_i)_i=1^N in mathbb M^n of length n in mathbb N, we usually assume that this signal might be noisy. For the (Euclidean) ROF model we assume that the noise is Gaussian. Then variational models for denoising usually consist of a data term D(ps) to “stay close to” s and a regularizer R(p). For TV regularization the data term is the squared distance and the regularizer models that without noise, neighboring values are close. We obtain","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"operatorname*argmin_pinmathcal M^n\nf(p)\nqquad\nf(p) = D(ps) + α R(p) = sum_i=1^n d_mathcal M^2(s_ip_i) + αsum_i=1^n-1 d_mathcal M(p_ip_i+1)","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"where α 0 is a weight parameter.","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"The challenge here is that most classical algorithm, like gradient descent or Quasi Newton, assume the cost f(p) to be smooth such that the gradient exists at every point. In our setting that is not the case since the distacen is not differentiable for any p_i=p_i+1. So we have to use another technique.","category":"page"},{"location":"examples/Total-Variation/#The-Cyclic-Proximal-Point-algorithm","page":"Total Variation","title":"The Cyclic Proximal Point algorithm","text":"","category":"section"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"If the cost consists of a sum of functions, where each of the proximal maps is “easy to evaluate”, for best of cases in closed form, we can “apply the proximal maps in a cyclic fashion” and optain the Cyclic Proximal Point Algorithm [Bac14].","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"Both for the distance and the squared distance, we have generic implementations; since this happens in a cyclic manner, there is also always one of the arguments involved in the prox and never both. We can improve the performance slightly by computing all proes in parallel that do not interfer. To be precise we can compute first all proxes of distances in the regularizer that start with an odd index in parallel. Afterwards all that start with an even index.","category":"page"},{"location":"examples/Total-Variation/#The-Optimsation","page":"Total Variation","title":"The Optimsation","text":"","category":"section"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"using Manifolds, Manopt, ManoptExamples, ManifoldDiff\nusing ManifoldDiff: prox_distance\nusing ManoptExamples: prox_Total_Variation\nn = 500 #Signal length\nσ = 0.2 # amount of noise\nα = 0.5# in the TV model","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"We define a few colors","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"using Colors, NamedColors, ColorSchemes, Plots, Random\ndata_color = RGBA{Float64}(colorant\"black\")\nlight_color = RGBA{Float64}(colorant\"brightgrey\")\nrecon_color = RGBA{Float64}(colorant\"vibrantorange\")\nnoisy_color = RGBA{Float64}(colorant\"vibrantteal\")","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"And we generate our data on the Circle, since that is easy to plot and nice to compare to the Euclidean case of a real-valued signal.","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"Random.seed!(23)\nM = Circle()\nN = PowerManifold(M, n)\ndata = ManoptExamples.artificial_S1_signal(n)\ns = [exp(M, d, rand(M; vector_at=d, σ=0.2)) for d in data]\nt = range(0.0, 1.0; length=n)\nscene = scatter(\n t,\n data;\n markercolor=data_color,\n markerstrokecolor=data_color,\n markersize=2,\n lab=\"original\",\n)\nscatter!(\n scene,\n t,\n s;\n markersize=2,\n markercolor=noisy_color,\n markerstrokecolor=noisy_color,\n lab=\"noisy\",\n)\nyticks!(\n [-π, -π / 2, 0, π / 2, π],\n [raw\"$-\\pi$\", raw\"$-\\frac{\\pi}{2}$\", raw\"$0$\", raw\"$\\frac{\\pi}{2}$\", raw\"$\\pi$\"],\n)","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"(Image: )","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"As mentioned above, total variation now minimized different neighbors – while keeping jumps if the are large enough. One notable difference between Euclidean and Cyclic data is, that the y-axis is in our case periodic, hence the first jump is actually not a jump but a “linear increase” that “wraps around” and the second large jump –or third overall– is actually only as small as the second jump.","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"Defining cost and the proximal maps, which are actually 3 proxes to be precise.","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"f(N, p) = ManoptExamples.L2_Total_Variation(N, s, α, p)\nproxes_f = ((N, λ, p) -> prox_distance(N, λ, s, p, 2), (N, λ, p) -> prox_Total_Variation(N, α * λ, p))","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"We run the algorithm","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"o = cyclic_proximal_point(\n N,\n f,\n proxes_f,\n s;\n λ=i -> π / (2 * i),\n debug=[\n :Iteration,\n \" | \",\n DebugProximalParameter(),\n \" | \",\n :Cost,\n \" | \",\n :Change,\n \"\\n\",\n 1000,\n :Stop,\n ],\n record=[:Iteration, :Cost, :Change, :Iterate],\n return_state=true,\n);","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"Initial | | f(x): 59.187445 | \n# 1000 | λ:0.0015707963267948967 | f(x): 13.963912 | Last Change: 1.773283\n# 2000 | λ:0.0007853981633974483 | f(x): 13.947124 | Last Change: 0.011678\n# 3000 | λ:0.0005235987755982988 | f(x): 13.941538 | Last Change: 0.003907\n# 4000 | λ:0.00039269908169872416 | f(x): 13.938748 | Last Change: 0.001957\n# 5000 | λ:0.0003141592653589793 | f(x): 13.937075 | Last Change: 0.001175\nThe algorithm reached its maximal number of iterations (5000).","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"We can see that the cost reduces nicely. Let’s extract the result an the recorded values","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"recon = get_solver_result(o)\nrecord = get_record(o)","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"We get","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"scene = scatter(\n t,\n data;\n markercolor=data_color,\n markerstrokecolor=data_color,\n markersize=2,\n lab=\"original\",\n)\nscatter!(\n scene,\n t,\n s;\n markersize=2,\n markercolor=light_color,\n markerstrokecolor=light_color,\n lab=\"noisy\",\n)\nscatter!(\n scene,\n t,\n recon;\n markersize=2,\n markercolor=recon_color,\n markerstrokecolor=recon_color,\n lab=\"reconstruction\",\n)","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"(Image: )","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"Which contains the usual stair casing one expects for TV regularization, but here in a “cyclic manner”","category":"page"},{"location":"examples/Total-Variation/#Outlook","page":"Total Variation","title":"Outlook","text":"","category":"section"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"We can generalize the total variation also to a second order total variation. Again intuitively, while TV prefers constant areas, the operatornameTV_2 yields a cost 0 for anything linear, which on manifolds can be generalized to equidistant on a geodesic [BBSW16]. Here we can again derive proximal maps, which for the circle again have a closed form solutoin [BLSW14] but on general manifolds these have again to be approximated.","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"Another extension for both first and second order TV is to apply this for manifold-valued images S = (S_ij)_ij=1^mn in mathcal M^mn, where the distances in the regularizer are then used in both the first dimension i and the second dimension j in the data.","category":"page"},{"location":"examples/Total-Variation/#Technical-details","page":"Total Variation","title":"Technical details","text":"","category":"section"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"This version of the example was generated with the following package versions.","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"Pkg.status()","category":"page"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"Status `~/work/ManoptExamples.jl/ManoptExamples.jl/examples/Project.toml`\n [6e4b80f9] BenchmarkTools v1.5.0\n [35d6a980] ColorSchemes v3.25.0\n [5ae59095] Colors v0.12.11\n [7073ff75] IJulia v1.24.2\n [8ac3fa9e] LRUCache v1.6.1\n [d3d80556] LineSearches v7.2.0\n [af67fdf4] ManifoldDiff v0.3.10\n [1cead3c2] Manifolds v0.9.18\n [3362f125] ManifoldsBase v0.15.10\n [0fc0a36d] Manopt v0.4.63\n [5b8d5e80] ManoptExamples v0.1.7 `..`\n [51fcb6bd] NamedColors v0.2.2\n [91a5bcdd] Plots v1.40.4\n [6099a3de] PythonCall v0.9.20","category":"page"},{"location":"examples/Total-Variation/#Literature","page":"Total Variation","title":"Literature","text":"","category":"section"},{"location":"examples/Total-Variation/","page":"Total Variation","title":"Total Variation","text":"M. Bačák. Computing medians and means in Hadamard spaces. SIAM Journal on Optimization 24, 1542–1566 (2014), arXiv:1210.2145.\n\n\n\nM. Bačák, R. Bergmann, G. Steidl and A. Weinmann. A second order non-smooth variational model for restoring manifold-valued images. SIAM Journal on Scientific Computing 38, A567–A597 (2016), arXiv:1506.02409.\n\n\n\nR. Bergmann, F. Laus, G. Steidl and A. Weinmann. Second order differences of cyclic data and applications in variational denoising. SIAM Journal on Imaging Sciences 7, 2916–2953 (2014), arXiv:1405.5349.\n\n\n\nL. I. Rudin, S. Osher and E. Fatemi. Nonlinear total variation based noise removal algorithms. Physica D: Nonlinear Phenomena 60, 259–268 (1992).\n\n\n\nA. Weinmann, L. Demaret and M. Storath. Total variation regularization for manifold-valued data. SIAM Journal on Imaging Sciences 7, 2226–2257 (2014).\n\n\n\n","category":"page"},{"location":"examples/Rosenbrock/#The-Rosenbrock-Function","page":"Rosenbrock","title":"The Rosenbrock Function","text":"","category":"section"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"Ronny Bergmann 2023-01-03","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"After loading the necessary packages","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"using Pkg;\ncd(@__DIR__)\nPkg.activate(\".\"); # use the example environment,","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"using Manifolds, Manopt, ManoptExamples\nusing Plots","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"We fix the parameters for the 📖 Rosenbrock (where the wikipedia page has a slightly different parameter naming).","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"a = 100.0\nb = 1.0\np0 = [1/10, 2/10]","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"which is defined on mathbb R^2, so we need","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"M = ℝ^2","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"Euclidean(2; field=ℝ)","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"and can then generate both the cost and the gradient","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"f = ManoptExamples.RosenbrockCost(M; a=a, b=b)\ngrad_f = ManoptExamples.RosenbrockGradient!!(M; a=a, b=b)","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"ManoptExamples.RosenbrockGradient!!{Float64}(100.0, 1.0)","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"For comparison, we look at the initial cost","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"f(M, p0)","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"4.42","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"And to illustrate, we run two small solvers with their default settings as a comparison.","category":"page"},{"location":"examples/Rosenbrock/#Gradient-Descent","page":"Rosenbrock","title":"Gradient Descent","text":"","category":"section"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"We start with the gradient descent solver.","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"Since we need the state anyways to access the record, we also get from the return_state=true a short summary of the solver run.","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"gd_state = gradient_descent(M, f, grad_f, p0; record = [:Iteration, :Cost], return_state=true)","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"# Solver state for `Manopt.jl`s Gradient Descent\nAfter 200 iterations\n\n## Parameters\n* retraction method: ExponentialRetraction()\n\n## Stepsize\nArmijoLinesearch() with keyword parameters\n * initial_stepsize = 1.0\n * retraction_method = ExponentialRetraction()\n * contraction_factor = 0.95\n * sufficient_decrease = 0.1\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 200: reached\n |grad f| < 1.0e-8: not reached\nOverall: reached\nThis indicates convergence: No\n\n## Record\n(Iteration = RecordGroup([RecordIteration(), RecordCost()]),)","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"From the summary we see, that the gradient is not yet small enough, but we hit the 200 iterations (default) iteration limit. Collecting the cost recording and printing the final cost","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"gd_x = get_record(gd_state, :Iteration, :Iteration)\ngd_y = get_record(gd_state, :Iteration, :Cost)\nf(M, get_solver_result(gd_state))","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"0.10562873187751265","category":"page"},{"location":"examples/Rosenbrock/#Quasi-Newton","page":"Rosenbrock","title":"Quasi Newton","text":"","category":"section"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"We can improve this using the quasi Newton algorithm","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"qn_state = quasi_Newton(M, f, grad_f, p0;\n record = [:Iteration, :Cost], return_state=true\n)","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"# Solver state for `Manopt.jl`s Quasi Newton Method\nAfter 26 iterations\n\n## Parameters\n* direction update: limited memory InverseBFGS (size 2), projections, and ParallelTransport() as vector transport.\n* retraction method: ExponentialRetraction()\n* vector transport method: ParallelTransport()\n\n## Stepsize\nWolfePowellLinesearch(DefaultManifold(), 0.0001, 0.999) with keyword arguments\n * retraction_method = ExponentialRetraction()\n * vector_transport_method = ParallelTransport()\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 1000: not reached\n |grad f| < 1.0e-6: reached\nOverall: reached\nThis indicates convergence: Yes\n\n## Record\n(Iteration = RecordGroup([RecordIteration(), RecordCost()]),)","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"And we see it stops far earlier, after 45 Iterations. We again collect the recorded values","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"qn_x = get_record(qn_state, :Iteration, :Iteration)\nqn_y = get_record(qn_state, :Iteration, :Cost)\nf(M, get_solver_result(qn_state))","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"1.4404666436813376e-18","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"and see that the final value is close to the one of the minimizer","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"f(M, ManoptExamples.minimizer(f))","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"0.0","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"which we also see if we plot the recorded cost.","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"fig = plot(gd_x, gd_y; linewidth=1, label=\"Gradient Descent\");\nplot!(fig, qn_x, qn_y; linewidth=1, label=\"Quasi Newton\")","category":"page"},{"location":"examples/Rosenbrock/","page":"Rosenbrock","title":"Rosenbrock","text":"(Image: Figure 1: The result of the robust PCA vs. SVD)","category":"page"},{"location":"examples/Riemannian-mean/#The-Riemannian-Center-of-Mass-(mean)","page":"Riemannian Mean","title":"The Riemannian Center of Mass (mean)","text":"","category":"section"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"Ronny Bergmann 2023-07-02","category":"page"},{"location":"examples/Riemannian-mean/#Preliminary-Notes","page":"Riemannian Mean","title":"Preliminary Notes","text":"","category":"section"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"Each of the example objectives or problems stated in this package should be accompanied by a Quarto notebook that illustrates their usage, like this one.","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"For this first example, the objective is a very common one, for example also used in the Get started: optimize! tutorial of Manopt.jl.","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"The second goal of this tutorial is to also illustrate how this package provides these examples, namely in both an easy-to-use and a performant way.","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"There are two recommended ways to activate a reproducible environment. For most cases the recommended environment is the one in examples/. If you are programming a new, relatively short example, consider using the packages main environment, which is the same as having ManoptExamples.jl in development mode. this requires that your example does not have any (additional) dependencies beyond the ones ManoptExamples.jl has anyways.","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"For registered versions of ManoptExamples.jl use the environment of examples/ and – under development – add ManoptExamples.jl in development mode from the parent folder. This should be changed after a new example is within a registered version to just use the examples/ environment again.","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"using Pkg;\ncd(@__DIR__)\nPkg.activate(\".\"); # use the example environment,","category":"page"},{"location":"examples/Riemannian-mean/#Loading-packages-and-defining-data","page":"Riemannian Mean","title":"Loading packages and defining data","text":"","category":"section"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"Loading the necessary packages and defining a data set on a manifold","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"using ManoptExamples, Manopt, Manifolds, ManifoldDiff, Random\nRandom.seed!(42)\nM = Sphere(2)\nn = 100\nσ = π / 8\np = 1 / sqrt(2) * [1.0, 0.0, 1.0]\ndata = [exp(M, p, σ * rand(M; vector_at=p)) for i in 1:n];","category":"page"},{"location":"examples/Riemannian-mean/#Variant-1:-Using-the-functions","page":"Riemannian Mean","title":"Variant 1: Using the functions","text":"","category":"section"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"We can define both the cost and gradient, RiemannianMeanCost and RiemannianMeanGradient!!, respectively. For their mathematical derivation and further explanations, we again refer to Get started: optimize!.","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"f = ManoptExamples.RiemannianMeanCost(data)\ngrad_f = ManoptExamples.RiemannianMeanGradient!!(M, data)","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"Then we can for example directly call a gradient descent as","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"x1 = gradient_descent(M, f, grad_f, first(data))","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"3-element Vector{Float64}:\n 0.6868392794567202\n 0.006531600696673591\n 0.7267799821044285","category":"page"},{"location":"examples/Riemannian-mean/#Variant-2:-Using-the-objective","page":"Riemannian Mean","title":"Variant 2: Using the objective","text":"","category":"section"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"A shorter way to directly obtain the Manifold objective including these two functions. Here, we want to specify that the objective can do in-place-evaluations using the evaluation=-keyword. The objective can be obtained calling Riemannian_mean_objective as","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"rmo = ManoptExamples.Riemannian_mean_objective(\n M, data,\n evaluation=InplaceEvaluation(),\n)","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"Together with a manifold, this forms a Manopt Problem, which would usually enable to switch manifolds between solver runs. Here we could for example switch to using Euclidean(3) instead for the same data the objective is build upon.","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"rmp = DefaultManoptProblem(M, rmo)","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"This enables us to for example solve the task with different, gradient based, solvers. The first is the same as above, just not using the high-level interface","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"s1 = GradientDescentState(M, copy(M, first(data)))\nsolve!(rmp, s1)\nx2 = get_solver_result(s1)","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"3-element Vector{Float64}:\n 0.6868392794567202\n 0.006531600696673591\n 0.7267799821044285","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"but we can easily use a conjugate gradient instead","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"s2 = ConjugateGradientDescentState(\n M,\n copy(M, first(data)),\n StopAfterIteration(100),\n ArmijoLinesearch(M),\n FletcherReevesCoefficient(),\n)\nsolve!(rmp, s2)\nx3 = get_solver_result(s2)","category":"page"},{"location":"examples/Riemannian-mean/","page":"Riemannian Mean","title":"Riemannian Mean","text":"3-element Vector{Float64}:\n 0.6868393613136017\n 0.006531541407458413\n 0.7267799052788726","category":"page"},{"location":"examples/RayleighQuotient/#The-Rayleigh-Quotient","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"","category":"section"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Ronny Bergmann 2024-03-09","category":"page"},{"location":"examples/RayleighQuotient/#Introduction","page":"The Rayleigh Quotient","title":"Introduction","text":"","category":"section"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"This example reproduces a few conceptual ideas of Optimization on Manifolds that are used throughout [Bou23] using the Rayleigh quotient and explores several different ways to use the algorithms from Manopt.jl.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"For a symmetric matrix A in mathbb R^ntimes n we consider the 📖 Rayleigh Quotient","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"operatorname*argmin_x in mathbb R^n backslash 0\nfracx^mathrmTAxlVert x rVert^2","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"On the sphere we can omit the denominator and obtain","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"f(p) = p^mathrmTApqquad p 𝕊^n-1","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"which by itself we can again continue in the embedding as","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"tilde f(x) = x^mathrmTAxqquad x in mathbb R^n","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"This cost has the nice feature that at the minimizer p^*inmathbb S^n-1 the function falue f(p^*) is the smalles eigenvalue of A.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"For the embedded function tilde f the gradient and Hessian can be computed with classical methods as","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"beginalign*\ntilde f(x) = 2Ax qquad x ℝ^n\n\n^2tilde f(x)V = 2AV qquad x V ℝ^n\nendalign*","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Similarly, cf. Examples 3.62 and 5.27 of [Bou23], the Riemannian gradient and Hessian on the manifold mathcal M = mathbb S^n-1 are given by","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"beginalign*\noperatornamegrad f(p) = 2Ap - 2(p^mathrmTAp)*pqquad p 𝕊^n-1\n\noperatornameHess f(p)X = 2AX - 2(p^mathrmTAX)p - 2(p^mathrmTAp)Xqquad p 𝕊^n-1 X in T_p𝕊^n-1\nendalign*","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Let’s first generate an example martrx A.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"using Pkg;\ncd(@__DIR__)\nPkg.activate(\".\"); # use the example environment,","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"using LRUCache, BenchmarkTools, LinearAlgebra, Manifolds, ManoptExamples, Manopt, Random\nRandom.seed!(42)\nn = 500\nA = Symmetric(randn(n, n) / n)","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"And the manifolds","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"M = Sphere(n-1)","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Sphere(499, ℝ)","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"E = get_embedding(M)","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Euclidean(500; field=ℝ)","category":"page"},{"location":"examples/RayleighQuotient/#Setup-the-corresponding-functions","page":"The Rayleigh Quotient","title":"Setup the corresponding functions","text":"","category":"section"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Since RayleighQuotientCost, RayleighQuotientGrad!!, and RayleighQuotientHess!! are themselves manifold agnostic we only need to initialize them once. Agnostic here means that they would compute f is called with M as their first argument and tilde f if called with E.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"We instantiate","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"f = ManoptExamples.RayleighQuotientCost(A)\ngrad_f = ManoptExamples.RayleighQuotientGrad!!(A)\nHess_f = ManoptExamples.RayleighQuotientHess!!(A)","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"the suffix !! also indicates that these functions both work as allocating and in-place variants. Given a starting point and some memory","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"p0 = [1.0, zeros(n-1)...]\nX = zero_vector(M, p0)","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"we can both call","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Y = grad_f(M, p0) # Allocates memory\ngrad_f(M, X, p0) # Computes in place of X and returns the result in X.\nnorm(M, p0, X-Y)","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"0.0","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Now we can use a few different variants of solvers to approaach this and this tutorial will walk you through a few of them.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"First of all let’s construct the actual result – since Rayleigh quotient minimization is not necessarily the best way to compute the smallest Eigenvalue. We can also compute","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"λ = min(eigvals(A)...)","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"-0.08967721009388108","category":"page"},{"location":"examples/RayleighQuotient/#A-Solver-based-on-gradient-information","page":"The Rayleigh Quotient","title":"A Solver based on gradient information","text":"","category":"section"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Let’s first just use first-order information and since we are just starting, maybe we only derived the Euclidean gradient nabla tilde f. We can “tell” the solver, that the provided function and the gradient are defined as the Euclidean variants in the embedding. internally, Manopt.jl then issues the conversion for Euclidean gradients to the corresponding Riemannian one, cf. e.g. this tutorial section or Section 3.8 or more precisely Example 3.62 in [Bou23].","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"But instead of diving into all the tecnical details, we can just specify objective_type=:Euclidean to trigger the conversion. We start with a simple gradient descent","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"s = gradient_descent(M, f, grad_f, p0; objective_type=:Euclidean,\n debug = [:Iteration, :Cost, :GradientNorm, 50, \"\\n\"],\n return_state=true,\n)\nq1 = get_solver_result(s)\ns","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Initial f(x): -0.000727\n# 50 f(x): -0.088415|grad f(p)|:0.004530500043902619\n# 100 f(x): -0.089097|grad f(p)|:0.004589417101266096\n# 150 f(x): -0.089530|grad f(p)|:0.0026028331895358247\n# 200 f(x): -0.089650|grad f(p)|:0.0012359084298719039\n\n# Solver state for `Manopt.jl`s Gradient Descent\nAfter 200 iterations\n\n## Parameters\n* retraction method: ExponentialRetraction()\n\n## Stepsize\nArmijoLinesearch() with keyword parameters\n * initial_stepsize = 1.0\n * retraction_method = ExponentialRetraction()\n * contraction_factor = 0.95\n * sufficient_decrease = 0.1\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 200: reached\n |grad f| < 1.0e-8: not reached\nOverall: reached\nThis indicates convergence: No\n\n## Debug\n :Iteration = [(:Iteration, \"# %-6d\"), (:Cost, \"f(x): %f\"), (:GradientNorm, \"|grad f(p)|:%s\"), \"\\n\", 50]","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"From the final cost we can already see that q1 is an eigenvector to the smallest eigenvalue we obtaines above.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"And we can compare this to running with the Riemannian gradient, since the RayleighQuotientGrad!! returns this one as well, when just called with the sphere as first Argument, we just have to remove the objective_type.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"q2 = gradient_descent(M, f, grad_f, p0;\n debug = [:Iteration, :Cost, :GradientNorm, 50, \"\\n\"],\n)\n#Test that both are the same\nisapprox(M, q1,q2)","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Initial f(x): -0.000727\n# 50 f(x): -0.088415|grad f(p)|:0.004530500043902567\n# 100 f(x): -0.089097|grad f(p)|:0.004589417101266063\n# 150 f(x): -0.089530|grad f(p)|:0.002602833189535808\n# 200 f(x): -0.089650|grad f(p)|:0.0012359084298719097\n\ntrue","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"We can also benchmark both","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"@benchmark gradient_descent($M, $f, $grad_f, $p0; objective_type=:Euclidean)","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"BenchmarkTools.Trial: 23 samples with 1 evaluation.\n Range (min … max): 217.668 ms … 268.332 ms ┊ GC (min … max): 3.21% … 3.98%\n Time (median): 219.032 ms ┊ GC (median): 3.24%\n Time (mean ± σ): 222.029 ms ± 10.351 ms ┊ GC (mean ± σ): 3.33% ± 0.26%\n\n █ \n ▆█▆▃▁▃▁▃▁▅▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▃ ▁\n 218 ms Histogram: frequency by time 268 ms <\n\n Memory estimate: 1.13 GiB, allocs estimate: 3613.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"@benchmark gradient_descent($M, $f, $grad_f, $p0)","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"BenchmarkTools.Trial: 149 samples with 1 evaluation.\n Range (min … max): 31.006 ms … 163.769 ms ┊ GC (min … max): 0.00% … 79.63%\n Time (median): 31.330 ms ┊ GC (median): 0.00%\n Time (mean ± σ): 33.701 ms ± 11.067 ms ┊ GC (mean ± σ): 3.40% ± 7.06%\n\n █▃ ▂ ▁ ▃ \n ██▄█▇██▆▄▁▄▄▁▇▁▁▆▁▄▆█▇▁▁▄▁▄▄▁▁▁▁▁▁▁▁▁▄▁▁▁▄▁▁▁▁▁▁▄▁▁▁▁▁▁▁▁▁▁▄ ▄\n 31 ms Histogram: log(frequency) by time 47 ms <\n\n Memory estimate: 11.38 MiB, allocs estimate: 3006.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"From these results we see, that the conversion from the Euclidean to the Riemannian gradient does require a small amount of effort and hence reduces the performance slighly. Still, if the Euclidean Gradient is easier to compute or already available, this is in terms of coding the faster way. Finally this is a tradeoff between derivation and implementation efforts for the Riemannian gradient and a slight performance reduction when using the Euclidean one.","category":"page"},{"location":"examples/RayleighQuotient/#A-Solver-based-(also)-on-(approximate)-Hessian-information","page":"The Rayleigh Quotient","title":"A Solver based (also) on (approximate) Hessian information","text":"","category":"section"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"To also involve the Hessian, we consider the trust regions solver with three cases:","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Euclidean, approximating the Hessian\nEuclidean, providing the Hessian\nRiemannian, providing the Hessian but also using in-place evaluations.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"q3 = trust_regions(M, f, grad_f, p0; objective_type=:Euclidean,\n debug = [:Iteration, :Cost, :GradientNorm, 10, \"\\n\"],\n);","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Initial f(x): -0.000727\n# 10 f(x): -0.088106|grad f(p)|:0.01903913659588686\n# 20 f(x): -0.089023|grad f(p)|:0.007792334296299116\n# 30 f(x): -0.089501|grad f(p)|:0.008034300330026467\n# 40 f(x): -0.089842|grad f(p)|:0.008125526728200166\n# 50 f(x): -0.089890|grad f(p)|:0.0031244752821335416\n# 60 f(x): -0.089925|grad f(p)|:0.0029682862637714163\n# 70 f(x): -0.089962|grad f(p)|:0.002811722437216778\n# 80 f(x): -0.089997|grad f(p)|:0.0026658493010157363\n# 90 f(x): -0.090032|grad f(p)|:0.0025418974797659266\n# 100 f(x): -0.090067|grad f(p)|:0.0024485809550738955\n# 110 f(x): -0.090108|grad f(p)|:0.0023894008071780747\n# 120 f(x): -0.090155|grad f(p)|:0.002362317662908117\n# 130 f(x): -0.090208|grad f(p)|:0.0023611301647631484\n# 140 f(x): -0.090262|grad f(p)|:0.00237797866404072\n# 150 f(x): -0.090314|grad f(p)|:0.002405563029627607\n# 160 f(x): -0.090362|grad f(p)|:0.002438250821406204\n# 170 f(x): -0.090404|grad f(p)|:0.002472221074327323\n# 180 f(x): -0.090441|grad f(p)|:0.0025051377726827166\n# 190 f(x): -0.090472|grad f(p)|:0.002535721310831389\n# 200 f(x): -0.090498|grad f(p)|:0.0025633813700434637\n# 210 f(x): -0.090513|grad f(p)|:0.0025832821804127513\n# 220 f(x): -0.090513|grad f(p)|:0.0025832821804127513\n# 230 f(x): -0.090513|grad f(p)|:0.0025832821792817493\n# 240 f(x): -0.090513|grad f(p)|:0.0025832821770197098\n# 250 f(x): -0.090513|grad f(p)|:0.0025832821747576924\n# 260 f(x): -0.090513|grad f(p)|:0.002583282172495683\n# 270 f(x): -0.090513|grad f(p)|:0.0025832821702336567\n# 280 f(x): -0.090513|grad f(p)|:0.002583282167971658\n# 290 f(x): -0.090513|grad f(p)|:0.002583282165709656\n# 300 f(x): -0.090513|grad f(p)|:0.002583282163447637\n# 310 f(x): -0.090513|grad f(p)|:0.0025832821611855928\n# 320 f(x): -0.090513|grad f(p)|:0.0025832821589235814\n# 330 f(x): -0.090513|grad f(p)|:0.002583282156661572\n# 340 f(x): -0.090513|grad f(p)|:0.0025832821543995727\n# 350 f(x): -0.090513|grad f(p)|:0.002583282152137569\n# 360 f(x): -0.090513|grad f(p)|:0.0025832821498755487\n# 370 f(x): -0.090513|grad f(p)|:0.0025832821476135036\n# 380 f(x): -0.090513|grad f(p)|:0.0025832821453515035\n# 390 f(x): -0.090513|grad f(p)|:0.0025832821430894675\n# 400 f(x): -0.090513|grad f(p)|:0.0025832821408274405\n# 410 f(x): -0.090513|grad f(p)|:0.002583282138565445\n# 420 f(x): -0.090513|grad f(p)|:0.002583282136303441\n# 430 f(x): -0.090513|grad f(p)|:0.00258328213404143\n# 440 f(x): -0.090513|grad f(p)|:0.002583282131779385\n# 450 f(x): -0.090513|grad f(p)|:0.0025832821295174104\n# 460 f(x): -0.090513|grad f(p)|:0.002583282127255372\n# 470 f(x): -0.090513|grad f(p)|:0.002583282124993372\n# 480 f(x): -0.090513|grad f(p)|:0.0025832821227313313\n# 490 f(x): -0.090513|grad f(p)|:0.0025832821204693065\n# 500 f(x): -0.090513|grad f(p)|:0.002583282118207321\n# 510 f(x): -0.090513|grad f(p)|:0.0025832821159453034\n# 520 f(x): -0.090513|grad f(p)|:0.0025832821136832665\n# 530 f(x): -0.090513|grad f(p)|:0.0025832821114212673\n# 540 f(x): -0.090513|grad f(p)|:0.002583282109159243\n# 550 f(x): -0.090513|grad f(p)|:0.002583282106897217\n# 560 f(x): -0.090513|grad f(p)|:0.002583282104635213\n# 570 f(x): -0.090513|grad f(p)|:0.0025832821023731955\n# 580 f(x): -0.090513|grad f(p)|:0.0025832821001112094\n# 590 f(x): -0.090513|grad f(p)|:0.002583282097849167\n# 600 f(x): -0.090513|grad f(p)|:0.0025832820955871503\n# 610 f(x): -0.090513|grad f(p)|:0.0025832820933251325\n# 620 f(x): -0.090513|grad f(p)|:0.002583282091063122\n# 630 f(x): -0.090513|grad f(p)|:0.0025832820888010873\n# 640 f(x): -0.090513|grad f(p)|:0.0025832820865390785\n# 650 f(x): -0.090513|grad f(p)|:0.0025832820842770442\n# 660 f(x): -0.090513|grad f(p)|:0.0025832820820150576\n# 670 f(x): -0.090513|grad f(p)|:0.0025832820797530767\n# 680 f(x): -0.090513|grad f(p)|:0.0025832820774910523\n# 690 f(x): -0.090513|grad f(p)|:0.0025832820752290362\n# 700 f(x): -0.090513|grad f(p)|:0.002583282072966992\n# 710 f(x): -0.090513|grad f(p)|:0.002583282070704973\n# 720 f(x): -0.090513|grad f(p)|:0.0025832820684429532\n# 730 f(x): -0.090513|grad f(p)|:0.002583282066180946\n# 740 f(x): -0.090513|grad f(p)|:0.0025832820639189306\n# 750 f(x): -0.090513|grad f(p)|:0.0025832820616569214\n# 760 f(x): -0.090513|grad f(p)|:0.00258328205939488\n# 770 f(x): -0.090513|grad f(p)|:0.002583282057132884\n# 780 f(x): -0.090513|grad f(p)|:0.0025832820548708406\n# 790 f(x): -0.090513|grad f(p)|:0.002583282052608873\n# 800 f(x): -0.090513|grad f(p)|:0.002583282050346837\n# 810 f(x): -0.090513|grad f(p)|:0.0025832820480848214\n# 820 f(x): -0.090513|grad f(p)|:0.0025832820458228205\n# 830 f(x): -0.090513|grad f(p)|:0.0025832820435608087\n# 840 f(x): -0.090513|grad f(p)|:0.0025832820412987944\n# 850 f(x): -0.090513|grad f(p)|:0.0025832820390367726\n# 860 f(x): -0.090513|grad f(p)|:0.002583282036774768\n# 870 f(x): -0.090513|grad f(p)|:0.002583282034512706\n# 880 f(x): -0.090513|grad f(p)|:0.002583282032250709\n# 890 f(x): -0.090513|grad f(p)|:0.0025832820299886896\n# 900 f(x): -0.090513|grad f(p)|:0.002583282027726701\n# 910 f(x): -0.090513|grad f(p)|:0.002583282025464682\n# 920 f(x): -0.090513|grad f(p)|:0.0025832820232026517\n# 930 f(x): -0.090513|grad f(p)|:0.002583282020940619\n# 940 f(x): -0.090513|grad f(p)|:0.0025832820186786334\n# 950 f(x): -0.090513|grad f(p)|:0.002583282016416595\n# 960 f(x): -0.090513|grad f(p)|:0.0025832820141545986\n# 970 f(x): -0.090513|grad f(p)|:0.0025832820118925717\n# 980 f(x): -0.090513|grad f(p)|:0.0025832820096305525\n# 990 f(x): -0.090513|grad f(p)|:0.002583282007368543\n# 1000 f(x): -0.090513|grad f(p)|:0.0025832820051065217","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"To provide the Hessian in the high-level interface we need to prodive it as an anonymous function, since any struct is considered to (eventually) be the also optional starting point. For space reasons, let’s also shorten the debug print to only iterations 7 and 14.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"q4 = trust_regions(M, f, grad_f, (E, p, X) -> Hess_f(E, p, X), p0; objective_type=:Euclidean,\n debug = [:Iteration, :Cost, :GradientNorm, 10, \"\\n\"],\n);","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Initial f(x): -0.000727\n# 10 f(x): -0.089673|grad f(p)|:0.0033633987039373655","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"q5 = trust_regions(M, f, grad_f, (M, Y, p, X) -> Hess_f(M, Y, p, X), p0;\n evaluation=InplaceEvaluation(),\n debug = [:Iteration, :Cost, :GradientNorm, 10, \"\\n\"],\n);","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Initial f(x): -0.000727\n# 10 f(x): -0.089673|grad f(p)|:0.00336339870393737","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Let’s also here compare them in benchmarks. Let’s here compare all variants in their (more performant) in-place versions.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"@benchmark trust_regions($M, $f, $grad_f, $p0;\n objective_type=:Euclidean,\n evaluation=InplaceEvaluation(),\n)","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"BenchmarkTools.Trial: 10 samples with 1 evaluation.\n Range (min … max): 488.560 ms … 542.951 ms ┊ GC (min … max): 3.26% … 3.55%\n Time (median): 498.677 ms ┊ GC (median): 3.22%\n Time (mean ± σ): 503.851 ms ± 17.951 ms ┊ GC (mean ± σ): 3.27% ± 0.11%\n\n █ ▁ ▁▁ ▁▁▁ ▁ ▁ \n █▁█▁██▁▁▁▁▁▁▁▁▁▁▁███▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█ ▁\n 489 ms Histogram: frequency by time 543 ms <\n\n Memory estimate: 1.97 GiB, allocs estimate: 40408.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"@benchmark trust_regions($M, $f, $grad_f, $((E, Y, p, X) -> Hess_f(E, Y, p, X)), $p0;\n evaluation=InplaceEvaluation(),\n objective_type=:Euclidean\n)","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"BenchmarkTools.Trial: 294 samples with 1 evaluation.\n Range (min … max): 12.991 ms … 148.108 ms ┊ GC (min … max): 0.00% … 87.36%\n Time (median): 15.369 ms ┊ GC (median): 3.17%\n Time (mean ± σ): 17.014 ms ± 8.238 ms ┊ GC (mean ± σ): 7.16% ± 7.03%\n\n ▁ █ ▂ \n ▆▁▁▇▅█▃▆█▇▅█▄▁▆▃▂▂▁▁▂▅▂▃▅▂▁▃▃▄▂▃▅▃▁▁▁▁▂▁▂▁▁▁▁▁▁▁▁▁▁▁▁▂▁▁▃▁▂▃ ▃\n 13 ms Histogram: frequency by time 28.6 ms <\n\n Memory estimate: 37.43 MiB, allocs estimate: 2920.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"@benchmark trust_regions($M, $f, $grad_f, $((M, Y, p, X) -> Hess_f(M, Y, p, X)), $p0;\n evaluation=InplaceEvaluation(),\n)","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"BenchmarkTools.Trial: 506 samples with 1 evaluation.\n Range (min … max): 8.717 ms … 152.718 ms ┊ GC (min … max): 0.00% … 90.61%\n Time (median): 8.884 ms ┊ GC (median): 0.00%\n Time (mean ± σ): 9.881 ms ± 6.537 ms ┊ GC (mean ± σ): 4.94% ± 5.90%\n\n ▆█▂ ▂▃ ▁ \n ███▄▁▁▆▆██▇▄▆██▆▇▄▅▇▄▄▁▁▆▄▇▄▆▁▅▅▆▁▅▅▄▁▁▄▅▅▁▆▇▇▇▄▄▄▄▁▁▁▁▁▁▄▄ ▇\n 8.72 ms Histogram: log(frequency) by time 14.7 ms <\n\n Memory estimate: 10.77 MiB, allocs estimate: 2899.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"We see that Hessian approximation is quite costly, and Gradient and Hessian conversion somewhat costly; still, they also might serve as a good starting point, before deciding to delve into computing Riemannian gradients and Hessians.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Of course all 5 runs obtained solutions close by; one might consider the gradient based runs to not have fully converged.","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"[distance(M, q1, q) for q ∈ [q2,q3] ]","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"2-element Vector{Float64}:\n 4.471485799821605e-15\n 0.048047538209352994","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"[distance(M, q3, q) for q ∈ [q4,q5] ]","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"2-element Vector{Float64}:\n 0.08269488012454579\n 0.08269488012454579","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"Which we can also see in the final cost, comparing it to the Eigenvalue","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"[f(M, q) - λ for q ∈ [q1, q2, q3, q4, q5] ]","category":"page"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"5-element Vector{Float64}:\n 2.76900562450888e-5\n 2.769005624428389e-5\n -0.000836208332542443\n 3.191891195797325e-16\n 3.191891195797325e-16","category":"page"},{"location":"examples/RayleighQuotient/#Summary","page":"The Rayleigh Quotient","title":"Summary","text":"","category":"section"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"We illustrated several possibilities to call solvers, with both Euclidean gradient and Hessian and Riemannian gradient and Hessian, allocating and in-place function. While the performance is better for the Riemannian case, the Euclidean one is a worthy alternative, when those are easier to compute.","category":"page"},{"location":"examples/RayleighQuotient/#Literature","page":"The Rayleigh Quotient","title":"Literature","text":"","category":"section"},{"location":"examples/RayleighQuotient/","page":"The Rayleigh Quotient","title":"The Rayleigh Quotient","text":"N. Boumal. An Introduction to Optimization on Smooth Manifolds. First Edition (Cambridge University Press, 2023).\n\n\n\n","category":"page"},{"location":"helpers/error_measures/#Error-measures","page":"Error measures","title":"Error measures","text":"","category":"section"},{"location":"helpers/error_measures/","page":"Error measures","title":"Error measures","text":"Modules = [ManoptExamples]\nPages = [\"ErrorMeasures.jl\"]\nOrder = [:type, :function]\nPrivate = true","category":"page"},{"location":"helpers/error_measures/#ManoptExamples.mean_average_error-Tuple{ManifoldsBase.AbstractManifold, Any, Any}","page":"Error measures","title":"ManoptExamples.mean_average_error","text":"mean_average_error(M,x,y)\n\nCompute the (mean) squared error between the two points x and y on the PowerManifold manifold M.\n\n\n\n\n\n","category":"method"},{"location":"helpers/error_measures/#ManoptExamples.mean_squared_error-Union{Tuple{mT}, Tuple{mT, Any, Any}} where mT<:ManifoldsBase.AbstractManifold","page":"Error measures","title":"ManoptExamples.mean_squared_error","text":"mean_squared_error(M, p, q)\n\nCompute the (mean) squared error between the two points p and q on the (power) manifold M.\n\n\n\n\n\n","category":"method"},{"location":"#Welcome-to-ManoptExample.jl","page":"Home","title":"Welcome to ManoptExample.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"ManoptExamples.ManoptExamples","category":"page"},{"location":"#ManoptExamples.ManoptExamples","page":"Home","title":"ManoptExamples.ManoptExamples","text":"🏔️⛷️ ManoptExamples.jl – A collection of research and tutorial example problems for Manopt.jl\n\n📚 Documentation: juliamanifolds.github.io/ManoptExamples.jl\n📦 Repository: github.com/JuliaManifolds/ManoptExamples.jl\n💬 Discussions: github.com/JuliaManifolds/ManoptExamples.jl/discussions\n🎯 Issues: github.com/JuliaManifolds/ManoptExamples.jl/issues\n\n\n\n\n\n","category":"module"},{"location":"","page":"Home","title":"Home","text":"This package provides a set of example tasks for Manopt.jl based on either generic manifolds from the ManifoldsBase.jl interface or specific manifolds from Manifolds.jl.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Each example usually consists of","category":"page"},{"location":"","page":"Home","title":"Home","text":"a cost function and additional objects, like the gradient or proximal maps, see objectives\nan example explaining how to use these, see examples","category":"page"},{"location":"","page":"Home","title":"Home","text":"Helping functions that are used in one or more examples can be found in the section of functions in the menu.","category":"page"}] +} diff --git a/v0.1.8/siteinfo.js b/v0.1.8/siteinfo.js new file mode 100644 index 0000000..547a867 --- /dev/null +++ b/v0.1.8/siteinfo.js @@ -0,0 +1 @@ +var DOCUMENTER_CURRENT_VERSION = "v0.1.8"; diff --git a/versions.js b/versions.js index d903b67..3fcdf59 100644 --- a/versions.js +++ b/versions.js @@ -3,5 +3,5 @@ var DOC_VERSIONS = [ "v0.1", "dev", ]; -var DOCUMENTER_NEWEST = "v0.1.7"; +var DOCUMENTER_NEWEST = "v0.1.8"; var DOCUMENTER_STABLE = "stable";