diff --git a/.gitignore b/.gitignore index b067edd..1f2d5eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,13 @@ +*.jl.*.cov +*.jl.cov +*.jl.mem +.DS_Store /Manifest.toml +/test/Manifest.toml +/dev/ +/docs/build/ +/docs/site/ +/docs/src/examples/*/*.md +/docs/src/examples/*/*.png +/docs/Manifest.toml +.vscode/ \ No newline at end of file diff --git a/Project.toml b/Project.toml index 8b64b1c..f6b7da2 100644 --- a/Project.toml +++ b/Project.toml @@ -1,23 +1,21 @@ name = "DisjunctiveProgramming" uuid = "0d27d021-0159-4c7d-b4a7-9ccb5d9366cf" authors = ["hdavid16 "] -version = "0.3.0" +version = "0.4.0" [deps] -IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" JuMP = "4076af6c-e467-56ae-b986-b466b2749572" -Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb" -Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" +Reexport = "189a3867-3050-52da-a836-e630ba90ab69" [compat] -IntervalArithmetic = "0.20" -JuMP = "1" -Suppressor = "0.2" -Symbolics = "4" -julia = "1" +JuMP = "1.15" +Reexport = "0.2, 1" +julia = "1.6" [extras] +Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" +HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Test"] +test = ["Aqua", "HiGHS", "Test"] diff --git a/README.md b/README.md index 141ba40..07368ef 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # DisjunctiveProgramming.jl -Generalized Disjunctive Programming extension to JuMP +Generalized Disjunctive Programming (GDP) extension to JuMP, based on the GDP modeling paradigm described in [Perez and Grossmann, 2023](https://arxiv.org/abs/2303.04375). ## Installation @@ -8,80 +8,210 @@ using Pkg Pkg.add("DisjunctiveProgramming") ``` +## Model + +A generalized disjunctive programming (GDP) model is created using `GDPModel()`, where the optimizer can be passed at model creation, along with other keyword arguments supported by JuMP Models. + +```julia +using DisjunctiveProgramming +using HiGHS + +model = GDPModel(HiGHS.Optimizer) +``` + +A `GDPModel` is a `JuMP Model` with a `GDPData` field in the model's `.ext` dictionary, which stores the following: + +- `Logical Variables`: Indicator variables used for the various disjuncts involved in the model's disjunctions. +- `Logical Constraints`: Selector (cardinality) or proposition (Boolean) constraints describing the relationships between the logical variables. +- `Disjunct Constraints`: Constraints associated with each disjunct in the model. +- `Disjunctions`: Disjunction constraints. +- `Solution Method`: The reformulation technique or solution method. Currently supported methods include Big-M, Hull, and Indicator Constraints. +- `Reformulation Variables`: List of JuMP variables created when reformulating a GDP model into a MIP model. +- `Reformulation Constraints`: List of constraints created when reformulating a GDP model into a MIP model. +- `Ready to Optimize`: Flag indicating if the model can be optimized. + +Additionally, the following mapping dictionaries are stored in `GDPData`: + +- `Indicator to Binary`: Maps the Logical variables to their respective reformulated Binary variables. +- `Indicator to Constraints`: Maps the Logical variables to the disjunct constraints associated with them. + +A GDP Model's `GDPData` can be accessed via: + +```julia +data = gdp_data(model) +``` + +## Logical Variables + +Logical variables are JuMP `AbstractVariable`s with two fields: `fix_value` and `start_value`. These can be optionally specified at variable creation. Logical variables are created with the `@variable` JuMP macro by adding the tag `LogicalVariable` as the last keyword argument. As with the regular `@variable` macro, variables can be named and indexed: + +```julia +@variable(model, Y[1:3], LogicalVariable) +``` + +## Logical Constraints + +Two types of logical constraints are supported: + +1. `Selector` or cardinality constraints: A subset of Logical variables is passed and `Exactly`, `AtMost`, or `AtLeast` `n` of these is allowed to be `True`. These constraints are specified with the `func` $\in$ `set` notation in `MathOptInterface` in a `@constraint` JuMP macro. It is not assumed that disjunctions have an `Exactly(1)` constraint enforced on their disjuncts upon creation. This constraint must be explicitly specified. + + ```julia + @constraint(model, [Y[1], Y[2]] in Exactly(1)) + ``` + +2. `Proposition` or Boolean constraints: These describe the relationships between Logical variables via Boolean algebra. Supported logical operators include: + + - `∨` or `logical_or` (OR, typed with `\vee + tab`). + - `∧` or `logical_and` (AND, typed with `\wedge + tab`). + - `¬` or `logical_not` (NOT, typed with `\neg + tab`). + - `⟹` of `implies` (Implication, typed with `\Longrightarrow + tab`). + - `⇔` or `iff` (double implication or equivalence, typed with `\Leftrightarrow + tab`). + + The `@constraint` JuMP macro is used to create these constraints with the `IsTrue` set: + + ```julia + @constraint(model, (Y[1] ⟹ Y[2]) in IsTrue()) + ``` + + _Note_: The parenthesis in the example above around the implication clause are only required when the parent logical operator is `⟹` or `⇔` to avoid parsing errors. + + Logical propositions can be reformulated to IP constraints by automatic reformulation to [Conjunctive Normal Form](https://en.wikipedia.org/wiki/Conjunctive_normal_form). + ## Disjunctions -After defining a JuMP model, disjunctions can be added to the model by using the `@disjunction` macro. This macro is called by `@disjunction(m, disjuncts...; kwargs...), where `disjuncts...` is a list of at least two expressions of the form: -1. A valid expression accepted by [JuMP.@constraint](https://jump.dev/JuMP.jl/stable/reference/constraints/#JuMP.@constraint). Names for the constraints or containers of constraints cannot be passed (use option 2). -2. A valid expression accepted by [JuMP.@constraints](https://jump.dev/JuMP.jl/stable/reference/constraints/#JuMP.@constraints) (using `begin...end) -3. A valid expression accepted by [JuMP.@NLconstraint](https://jump.dev/JuMP.jl/stable/reference/nlp/#JuMP.@NLconstraint). Containers of constraints cannot be passed (use option 4). Naming of non-linear constraints is not currently supported. -4. A valid expression accepted by [JuMP.@NLconstraints](https://jump.dev/JuMP.jl/stable/reference/nlp/#JuMP.@NLconstraints) (using `begin...end) -5. `Tuple` of expressions accepted by options 1 and/or 3. +Disjunctions are built by first defining the constraints associated with each disjunct. This is done via the `@constraint` JuMP macro with the extra `DisjunctConstraint` tag specifying the Logical variable associated with the constraint: -NOTES: -- Vectorized constraints (using `.` notation) are not currently supported. The current workarround is to first create the constraint with the `@constraint` macro and then use the `add_disjunction!`, instead of the `@disjunction` macro. The `add_disjunction!` function receives the same arguments as the `@disjunction` macro, with the exception that instead of creating the constraints in the disjunctions, references to previously created constraints are used for the disjuncts. -- Any constraints that are of `EqualTo` type are split into two constraints (e.g., `f(x) == 0` -> `0 <= f(x) <= 0`). This is necessary only for the Big-M reformulation of equality constraints, but is currently applied regardless of the reformulation technique. -- Any constraints that are of `Interval` type are split into two constraints (one for each bound). -- It is assumed that the disjuncts belonging to a disjunction are proper disjunctions (mutually exclussive) and only one of them will be selected (`XOR`). +```julia +@variable(model, x) +@constraint(model, x ≤ 100, DisjunctConstraint(Y[1])) +@constraint(model, x ≥ 200, DisjunctConstraint(Y[2])) +``` -The valid key-word arguments for the `@disjunction` macro are: -- `reformulation::Symbol`: `:big_m` for [Big-M Reformulation](https://optimization.mccormick.northwestern.edu/index.php/Disjunctive_inequalities#Big-M_Reformulation), `:hull` for [Hull Reformulation](https://optimization.mccormick.northwestern.edu/index.php/Disjunctive_inequalities#Convex-Hull_Reformulation) -- `M`: Big-M value used when `reformulation = :big_m`. -- `ϵ`: epsilon tolerance for the perspective function proposed by [Furman, et al. [2020]](https://link.springer.com/article/10.1007/s10589-020-00176-0). Only used when `reformulation = :hull`. -- `name::Symbol`: Name for the disjunction (also name for indicator variable used on that disjunction). If not passed (`name = missing`), a symbolic name will be generated with the prefix `disj`. The mutual exclussion constraint on the binary indicator variables can be accessed with `model[Symbol("XOR(disj_$name)")]`. +After all disjunct constraints associated with a disjunction have been defined, the disjunction is created with the `@disjunction` macro, where the disjunction is defined as a `Vector` of Logical variables associated with each disjunct: -When a disjunction is defined using the `@disjunction` macro, the disjunctions are reformulated to algebraic constraints via either Big-M or Hull reformulations. For the Hull reformulation, disaggregated variables are generated by adding the suffix `_$name$i` to the original variables, where `i` is the index of the disjunct in that disjunction. Bounding constraints are applied to the disaggregated variables and can be accessed with `model[Symbol("$_$name$i_lb")]` and `model[Symbol("$_$name$i_ub")]` for the lower bound and upper bound constraints, respectively. The aggregation constraint can be accessed with `model[Symbol("$_aggregation")]`. For Big-M reformulations, the user may provide an `M` object that represents the BigM value(s). The `M` object can be a `Number` that is applied to all constraints in the disjuncts, or a `Vector`/`Tuple` of values that are used for each of the disjuncts. For Hull reformulations, the user may provide an `ϵ` value for the perspective function (default is `ϵ = 1e-6`). The `ϵ` object can be a `Number` that is applied to all perspective functions, or a `Vector`/`Tuple` of values that are used for each of the disjuncts. +```julia +@disjunction(model, [Y[1], Y[2]]) +``` -For empty disjuncts, use `nothing` for their positional argument (e.g., `@disjunction(m, x <= 1, nothing, reformulation = :big_m)`). +Disjunctions can be nested by passing an additional `DisjunctConstraint` tag. The Logical variable in the `DisjunctConstraint` tag specifies which disjunct, the nested disjunction belongs to: -NOTE: `:gdp_variable_refs` and `:gdp_variable_names` are forbidden JuMP model object names when using *DisjunctiveProgramming.jl*. They are used to store the variable names and variable references in the original model. +```julia +@disjunction(model, Y[1:2], DisjunctConstraint(Y[3])) +``` -## Logical Propositions +Empty disjuncts are supported in GDP models. When used, the only constraints enforced on the model when the empty disjunct is selected are the global constraints and any other disjunction constraints defined. -Boolean logic can be included in the model by using the `@proposition` macro. This macro will take an expression that uses only binary variables from the model (typically a subset of the indicator variables used in the disjunctions) and one or more of the following Boolean operators: -- `∨` (or, typed with `\vee + tab`) -- `∧` (and, typed with `\wedge + tab`) -- `¬` (negation, typed with `\neg + tab`) -- `⇒` (implication, typed with `\Rightarrow + tab`) -- `⇔` (double implication or equivalence, typed with `\Leftrightarrow + tab`) -The logical proposition is then internally reformulated to an algebraic constraint that is added to the model. This constrait can be accessed with `model[Symbol("")]`. +## MIP Reformulations -## Example +The following reformulation methods are currently supported: + +1. [Big-M](https://optimization.cbe.cornell.edu/index.php?title=Disjunctive_inequalities#Big-M_Reformulation[1][2]): The `BigM` struct is created with the following optional arguments: + + - `value`: Big-M value to use. Default: `1e9`. Big-M values are currently global to the model. Constraint specific Big-M values can be supported in future releases. + - `tighten`: Boolean indicating if tightening the Big-M value should be attempted (currently supported only for linear disjunct constraints when variable bounds have been set or specified in the `variable_bounds` field). Default: `true`. + - `variable_bounds`: Dictionary specifying the lower and upper bounds for each `VariableRef` (e.g., `Dict(x => (lb, ub))`). Default: populate when calling the reformulation method. -The example below is from the [Northwestern University Process Optimization Open Textbook](https://optimization.mccormick.northwestern.edu/index.php/Disjunctive_inequalities). +2. [Hull](https://optimization.cbe.cornell.edu/index.php?title=Disjunctive_inequalities#Convex-Hull_Reformulation[1][2]): The `Hull` struct is created with the following optional arguments: -To perform the Big-M reformulation, `:big_m` is passed to the `reformulation` keyword argument. If nothing is passed to the keyword argument `M`, tight Big-M values will be inferred from the variable bounds using IntervalArithmetic.jl. If `x` is not bounded, Big-M values must be provided for either the whole system (e.g., `M = 10`) or for each of the constraint arrays in the example (e.g., `M = (10,10)`). + - `value`: `ϵ` value to use when reformulating quadratic or nonlinear constraints via the perspective function proposed by [Furman, et al. [2020]](https://link.springer.com/article/10.1007/s10589-020-00176-0). Default: `1e-6`. `ϵ` values are currently global to the model. Constraint specific tolerances can be supported in future releases. + - `variable_bounds`: Dictionary specifying the lower and upper bounds for each `VariableRef` (e.g., `Dict(x => (lb, ub))`). Default: populate when calling the reformulation method. -To perform the Hull reformulation, `reformulation = :hull`. Variables must have bounds for the reformulation to work. +3. [Indicator](https://jump.dev/JuMP.jl/stable/manual/constraints/#Indicator-constraints): This method reformulates each disjunct constraint into an indicator constraint with the Boolean reformulation counterpart of the Logical variable used to define the disjunct constraint. + +## Release Notes + +Prior to `v0.4.0`, the package did not leverage the JuMP extension capabilities and was not as robust. For these earlier releases, refer to [Perez, Joshi, and Grossmann, 2023](https://arxiv.org/abs/2304.10492v1) and the following [JuliaCon 2022 Talk](https://www.youtube.com/watch?v=AMIrgTTfUkI). + +## Example + +The example below is from the [Cornell University Computational Optimization Open Textbook](https://optimization.cbe.cornell.edu/index.php?title=Disjunctive_inequalities#Big-M_Reformulation[1][2]). ```julia using JuMP using DisjunctiveProgramming -m = Model() -@variable(m, -5 ≤ x ≤ 10) -@disjunction( - m, - 0 ≤ x ≤ 3, - 5 ≤ x ≤ 9, - reformulation=:big_m, - name=:y -) -@proposition(m, y[1] ∨ y[2]) #this is a redundant proposition +m = GDPModel() +@variable(m, 0 ≤ x[1:2] ≤ 20) +@variable(m, Y[1:2], LogicalVariable) +@constraint(m, [i = 1:2], [2,5][i] ≤ x[i] ≤ [6,9][i], DisjunctConstraint(Y[1])) +@constraint(m, [i = 1:2], [8,10][i] ≤ x[i] ≤ [11,15][i], DisjunctConstraint(Y[2])) +@disjunction(m, Y) +@constraint(m, Y in Exactly(1)) #logical constraint +## Big-M +reformulate_model(m, BigM(100, false)) #specify M value and disable M-tightening print(m) - -┌ Warning: disj_y[1] : x in [0.0, 3.0] uses the `MOI.Interval` set. Each instance of the interval set has been split into two constraints, one for each bound. -┌ Warning: disj_y[2] : x in [5.0, 9.0] uses the `MOI.Interval` set. Each instance of the interval set has been split into two constraints, one for each bound. -Feasibility -Subject to - XOR(disj_y) : y[1] + y[2] == 1.0 <- XOR constraint - y[1] ∨ y[2] : y[1] + y[2] >= 1.0 <- reformulated logical proposition (name is the proposition) - disj_y[1][lb] : -x + 5 y[1] <= 5.0 <- left-side of constraint in 1st disjunct (name is assigned to disj_y[1][lb]) - disj_y[1][ub] : x + 7 y[1] <= 10.0 <- right-side of constraint in 1st disjunct (name is assigned to disj_y[1][ub]) - disj_y[2][lb] : -x + 10 y[2] <= 5.0 <- left-side of constraint in 2nd disjunct (name is assigned to disj_y[2][lb]) - disj_y[2][ub] : x + y[2] <= 10.0 <- right-side of constraint in 2nd disjunct (name is assigned to disj_y[2][ub]) - x >= -5.0 <- variable lower bound - x <= 10.0 <- variable upper bound - y[1] binary <- indicator variable (1st disjunct) is binary - y[2] binary <- indicator variable (2nd disjunct) is binary +# Feasibility +# Subject to +# Y[1] + Y[2] = 1 +# x[1] - 100 Y[1] ≥ -98 +# x[2] - 100 Y[1] ≥ -95 +# x[1] - 100 Y[2] ≥ -92 +# x[2] - 100 Y[2] ≥ -90 +# x[1] + 100 Y[1] ≤ 106 +# x[2] + 100 Y[1] ≤ 109 +# x[1] + 100 Y[2] ≤ 111 +# x[2] + 100 Y[2] ≤ 115 +# x[1] ≥ 0 +# x[2] ≥ 0 +# x[1] ≤ 20 +# x[2] ≤ 20 +# Y[1] binary +# Y[2] binary + +## Hull +reformulate_model(m, Hull()) +print(m) +# Feasibility +# Subject to +# -x[2] + x[2]_Y[1] + x[2]_Y[2] = 0 +# -x[1] + x[1]_Y[1] + x[1]_Y[2] = 0 +# Y[1] + Y[2] = 1 +# -2 Y[1] + x[1]_Y[1] ≥ 0 +# -5 Y[1] + x[2]_Y[1] ≥ 0 +# -8 Y[2] + x[1]_Y[2] ≥ 0 +# -10 Y[2] + x[2]_Y[2] ≥ 0 +# x[2]_Y[1]_lower_bound : -x[2]_Y[1] ≤ 0 +# x[2]_Y[1]_upper_bound : -20 Y[1] + x[2]_Y[1] ≤ 0 +# x[1]_Y[1]_lower_bound : -x[1]_Y[1] ≤ 0 +# x[1]_Y[1]_upper_bound : -20 Y[1] + x[1]_Y[1] ≤ 0 +# x[2]_Y[2]_lower_bound : -x[2]_Y[2] ≤ 0 +# x[2]_Y[2]_upper_bound : -20 Y[2] + x[2]_Y[2] ≤ 0 +# x[1]_Y[2]_lower_bound : -x[1]_Y[2] ≤ 0 +# x[1]_Y[2]_upper_bound : -20 Y[2] + x[1]_Y[2] ≤ 0 +# -6 Y[1] + x[1]_Y[1] ≤ 0 +# -9 Y[1] + x[2]_Y[1] ≤ 0 +# -11 Y[2] + x[1]_Y[2] ≤ 0 +# -15 Y[2] + x[2]_Y[2] ≤ 0 +# x[1] ≥ 0 +# x[2] ≥ 0 +# x[2]_Y[1] ≥ 0 +# x[1]_Y[1] ≥ 0 +# x[2]_Y[2] ≥ 0 +# x[1]_Y[2] ≥ 0 +# x[1] ≤ 20 +# x[2] ≤ 20 +# x[2]_Y[1] ≤ 20 +# x[1]_Y[1] ≤ 20 +# x[2]_Y[2] ≤ 20 +# x[1]_Y[2] ≤ 20 +# Y[1] binary +# Y[2] binary + +## Indicator +reformulate_model(m, Indicator()) +print(m) +# Feasibility +# Subject to +# Y[1] + Y[2] = 1 +# x[1] ≥ 0 +# x[2] ≥ 0 +# x[1] ≤ 20 +# x[2] ≤ 20 +# Y[1] binary +# Y[2] binary +# Y[1] => {x[1] ∈ [2, 6]} +# Y[1] => {x[2] ∈ [5, 9]} +# Y[2] => {x[1] ∈ [8, 11]} +# Y[2] => {x[2] ∈ [10, 15]} ``` diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index a303fff..0000000 --- a/docs/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build/ -site/ diff --git a/docs/build/assets/documenter.js b/docs/build/assets/documenter.js deleted file mode 100644 index 22f0f9a..0000000 --- a/docs/build/assets/documenter.js +++ /dev/null @@ -1,260 +0,0 @@ -// Generated by Documenter.jl -requirejs.config({ - paths: { - 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/julia.min', - 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.10.3/headroom.min', - 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min', - 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/contrib/auto-render.min', - 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min', - 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.10.3/jQuery.headroom.min', - 'katex': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/katex.min', - 'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min', - 'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/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($, hljs) { -$(document).ready(function() { - hljs.initHighlighting(); -}) - -}) -//////////////////////////////////////////////////////////////////////////////// -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($) { - -// 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($) { - -// 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($) { - -function set_theme(theme) { - var active = null; - var disabled = []; - for (var i = 0; i < document.styleSheets.length; i++) { - var ss = document.styleSheets[i]; - var themename = ss.ownerNode.getAttribute("data-theme-name"); - if(themename === null) continue; // ignore non-theme stylesheets - // Find the active theme - if(themename === theme) active = ss; - else disabled.push(ss); - } - if(active !== null) { - active.disabled = false; - if(active.ownerNode.getAttribute("data-theme-primary") === null) { - document.getElementsByTagName('html')[0].className = "theme--" + theme; - } else { - document.getElementsByTagName('html')[0].className = ""; - } - disabled.forEach(function(ss){ - ss.disabled = true; - }); - } - - // Store the theme in localStorage - if(typeof(window.localStorage) !== "undefined") { - window.localStorage.setItem("documenter-theme", theme); - } else { - console.error("Browser does not support window.localStorage"); - } -} - -// Theme picker setup -$(document).ready(function() { - // onchange callback - $('#documenter-themepicker').change(function themepick_callback(ev){ - var themename = $('#documenter-themepicker option:selected').attr('value'); - set_theme(themename); - }); - - // 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() { - 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/docs/build/assets/search.js b/docs/build/assets/search.js deleted file mode 100644 index e30e907..0000000 --- a/docs/build/assets/search.js +++ /dev/null @@ -1,247 +0,0 @@ -// Generated by Documenter.jl -requirejs.config({ - paths: { - 'lunr': 'https://cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.6/lunr.min', - 'lodash': 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min', - 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min', - } -}); -//////////////////////////////////////////////////////////////////////////////// -require(['jquery', 'lunr', 'lodash'], function($, lunr, _) { - -$(document).ready(function() { - // parseUri 1.2.2 - // (c) Steven Levithan - // MIT License - function parseUri (str) { - var o = parseUri.options, - m = o.parser[o.strictMode ? "strict" : "loose"].exec(str), - uri = {}, - i = 14; - - while (i--) uri[o.key[i]] = m[i] || ""; - - uri[o.q.name] = {}; - uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { - if ($1) uri[o.q.name][$1] = $2; - }); - - return uri; - }; - parseUri.options = { - strictMode: false, - key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], - q: { - name: "queryKey", - parser: /(?:^|&)([^&=]*)=?([^&]*)/g - }, - parser: { - strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, - loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ - } - }; - - $("#search-form").submit(function(e) { - e.preventDefault() - }) - - // 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 - lunr.stopWordFilter = lunr.generateStopWordFilter([ - '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' - ]) - - // add . as a separator, because otherwise "title": "Documenter.Anchors.add!" - // would not find anything if searching for "add!", only for the entire qualification - lunr.tokenizer.separator = /[\s\-\.]+/ - - // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names - lunr.trimmer = function (token) { - return token.update(function (s) { - return s.replace(/^[^a-zA-Z0-9@!]+/, '').replace(/[^a-zA-Z0-9@!]+$/, '') - }) - } - - lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'juliaStopWordFilter') - lunr.Pipeline.registerFunction(lunr.trimmer, 'juliaTrimmer') - - var index = lunr(function () { - this.ref('location') - this.field('title',{boost: 100}) - this.field('text') - documenterSearchIndex['docs'].forEach(function(e) { - this.add(e) - }, this) - }) - var store = {} - - documenterSearchIndex['docs'].forEach(function(e) { - store[e.location] = {title: e.title, category: e.category} - }) - - $(function(){ - searchresults = $('#documenter-search-results'); - searchinfo = $('#documenter-search-info'); - searchbox = $('#documenter-search-query'); - function update_search(querystring) { - tokens = lunr.tokenizer(querystring) - results = index.query(function (q) { - tokens.forEach(function (t) { - q.term(t.toString(), { - fields: ["title"], - boost: 100, - usePipeline: true, - editDistance: 0, - wildcard: lunr.Query.wildcard.NONE - }) - q.term(t.toString(), { - fields: ["title"], - boost: 10, - usePipeline: true, - editDistance: 2, - wildcard: lunr.Query.wildcard.NONE - }) - q.term(t.toString(), { - fields: ["text"], - boost: 1, - usePipeline: true, - editDistance: 0, - wildcard: lunr.Query.wildcard.NONE - }) - }) - }) - searchinfo.text("Number of results: " + results.length) - searchresults.empty() - results.forEach(function(result) { - data = store[result.ref] - link = $(''+data.title+'') - link.attr('href', documenterBaseURL+'/'+result.ref) - cat = $('('+data.category+')') - li = $('
  • ').append(link).append(" ").append(cat) - searchresults.append(li) - }) - } - - function update_search_box() { - querystring = searchbox.val() - update_search(querystring) - } - - searchbox.keyup(_.debounce(update_search_box, 250)) - searchbox.change(update_search_box) - - search_query_uri = parseUri(window.location).queryKey["q"] - if(search_query_uri !== undefined) { - search_query = decodeURIComponent(search_query_uri.replace(/\+/g, '%20')) - searchbox.val(search_query) - } - update_search_box(); - }) -}) - -}) diff --git a/docs/build/assets/themes/documenter-dark.css b/docs/build/assets/themes/documenter-dark.css deleted file mode 100644 index ea7d803..0000000 --- a/docs/build/assets/themes/documenter-dark.css +++ /dev/null @@ -1,7638 +0,0 @@ -@charset "UTF-8"; -/* Font Awesome 5 mixin. Can be included in any rule that should render Font Awesome icons. */ -@keyframes spinAround { - from { - transform: rotate(0deg); } - to { - transform: rotate(359deg); } } - -html.theme--documenter-dark .delete, html.theme--documenter-dark .modal-close, .is-unselectable, html.theme--documenter-dark .button, html.theme--documenter-dark .file, html.theme--documenter-dark .breadcrumb, 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 .tabs { - -webkit-touch-callout: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; } - -html.theme--documenter-dark .select:not(.is-multiple):not(.is-loading)::after, html.theme--documenter-dark .navbar-link:not(.is-arrowless)::after { - border: 3px solid transparent; - 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 .box:not(:last-child), html.theme--documenter-dark .content:not(:last-child), html.theme--documenter-dark .notification:not(:last-child), html.theme--documenter-dark .progress:not(:last-child), html.theme--documenter-dark .table:not(:last-child), html.theme--documenter-dark .table-container:not(:last-child), html.theme--documenter-dark .title:not(:last-child), -html.theme--documenter-dark .subtitle:not(:last-child), html.theme--documenter-dark .block:not(:last-child), html.theme--documenter-dark .highlight:not(:last-child), html.theme--documenter-dark .breadcrumb:not(:last-child), html.theme--documenter-dark .level:not(:last-child), html.theme--documenter-dark .list:not(:last-child), html.theme--documenter-dark .message:not(:last-child), html.theme--documenter-dark .tabs:not(:last-child), html.theme--documenter-dark .admonition:not(:last-child) { - margin-bottom: 1.5rem; } - -html.theme--documenter-dark .delete, html.theme--documenter-dark .modal-close { - -moz-appearance: none; - -webkit-appearance: none; - background-color: rgba(10, 10, 10, 0.2); - border: none; - border-radius: 290486px; - 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 .delete::before, html.theme--documenter-dark .modal-close::before, html.theme--documenter-dark .delete::after, html.theme--documenter-dark .modal-close::after { - background-color: white; - content: ""; - display: block; - left: 50%; - position: absolute; - top: 50%; - transform: translateX(-50%) translateY(-50%) rotate(45deg); - transform-origin: center center; } - html.theme--documenter-dark .delete::before, html.theme--documenter-dark .modal-close::before { - height: 2px; - width: 50%; } - html.theme--documenter-dark .delete::after, html.theme--documenter-dark .modal-close::after { - height: 50%; - width: 2px; } - html.theme--documenter-dark .delete:hover, html.theme--documenter-dark .modal-close:hover, html.theme--documenter-dark .delete:focus, html.theme--documenter-dark .modal-close:focus { - background-color: rgba(10, 10, 10, 0.3); } - html.theme--documenter-dark .delete:active, html.theme--documenter-dark .modal-close:active { - background-color: rgba(10, 10, 10, 0.4); } - html.theme--documenter-dark .is-small.delete, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.delete, html.theme--documenter-dark .is-small.modal-close, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.modal-close { - height: 16px; - max-height: 16px; - max-width: 16px; - min-height: 16px; - min-width: 16px; - width: 16px; } - html.theme--documenter-dark .is-medium.delete, html.theme--documenter-dark .is-medium.modal-close { - height: 24px; - max-height: 24px; - max-width: 24px; - min-height: 24px; - min-width: 24px; - width: 24px; } - html.theme--documenter-dark .is-large.delete, html.theme--documenter-dark .is-large.modal-close { - height: 32px; - max-height: 32px; - max-width: 32px; - min-height: 32px; - min-width: 32px; - width: 32px; } - -html.theme--documenter-dark .button.is-loading::after, html.theme--documenter-dark .loader, html.theme--documenter-dark .select.is-loading::after, html.theme--documenter-dark .control.is-loading::after { - animation: spinAround 500ms infinite linear; - border: 2px solid #dbdee0; - border-radius: 290486px; - border-right-color: transparent; - border-top-color: transparent; - content: ""; - display: block; - height: 1em; - position: relative; - width: 1em; } - -.is-overlay, 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, html.theme--documenter-dark .modal, html.theme--documenter-dark .modal-background, html.theme--documenter-dark .hero-video { - bottom: 0; - left: 0; - position: absolute; - right: 0; - top: 0; } - -html.theme--documenter-dark .button, html.theme--documenter-dark .input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input, html.theme--documenter-dark .textarea, html.theme--documenter-dark .select select, html.theme--documenter-dark .file-cta, -html.theme--documenter-dark .file-name, html.theme--documenter-dark .pagination-previous, -html.theme--documenter-dark .pagination-next, -html.theme--documenter-dark .pagination-link, -html.theme--documenter-dark .pagination-ellipsis { - -moz-appearance: none; - -webkit-appearance: none; - align-items: center; - border: 1px solid transparent; - border-radius: 0.4em; - box-shadow: none; - display: inline-flex; - font-size: 15px; - height: 2.25em; - justify-content: flex-start; - line-height: 1.5; - padding-bottom: calc(0.375em - 1px); - padding-left: calc(0.625em - 1px); - padding-right: calc(0.625em - 1px); - padding-top: calc(0.375em - 1px); - position: relative; - vertical-align: top; } - html.theme--documenter-dark .button:focus, html.theme--documenter-dark .input:focus, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input:focus, html.theme--documenter-dark .textarea:focus, html.theme--documenter-dark .select select:focus, html.theme--documenter-dark .file-cta:focus, - html.theme--documenter-dark .file-name:focus, 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 .is-focused.button, 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.textarea, html.theme--documenter-dark .select select.is-focused, html.theme--documenter-dark .is-focused.file-cta, - html.theme--documenter-dark .is-focused.file-name, 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 .button:active, html.theme--documenter-dark .input:active, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input:active, html.theme--documenter-dark .textarea:active, html.theme--documenter-dark .select select:active, html.theme--documenter-dark .file-cta:active, - html.theme--documenter-dark .file-name:active, 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 .is-active.button, 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.textarea, html.theme--documenter-dark .select select.is-active, html.theme--documenter-dark .is-active.file-cta, - html.theme--documenter-dark .is-active.file-name, 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 { - outline: none; } - html.theme--documenter-dark .button[disabled], html.theme--documenter-dark .input[disabled], html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input[disabled], html.theme--documenter-dark .textarea[disabled], html.theme--documenter-dark .select select[disabled], html.theme--documenter-dark .file-cta[disabled], - html.theme--documenter-dark .file-name[disabled], 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], - fieldset[disabled] html.theme--documenter-dark .button, - html.theme--documenter-dark fieldset[disabled] .button, - fieldset[disabled] html.theme--documenter-dark .input, - html.theme--documenter-dark fieldset[disabled] .input, - fieldset[disabled] html.theme--documenter-dark #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 .textarea, - html.theme--documenter-dark fieldset[disabled] .textarea, - fieldset[disabled] html.theme--documenter-dark .select select, - html.theme--documenter-dark .select fieldset[disabled] select, - 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 .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 { - cursor: not-allowed; } - -/*! minireset.css v0.0.4 | 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, -embed, -iframe, -object, -video { - height: auto; - max-width: 100%; } - -audio { - 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: left; } - -.is-clearfix::after { - clear: both; - content: " "; - display: table; } - -.is-pulled-left { - float: left !important; } - -.is-pulled-right { - float: right !important; } - -.is-clipped { - overflow: hidden !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: 15px !important; } - -.is-size-7, html.theme--documenter-dark .docstring > section > a.docs-sourcelink { - font-size: 0.85em !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: 15px !important; } - .is-size-7-mobile { - font-size: 0.85em !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: 15px !important; } - .is-size-7-tablet { - font-size: 0.85em !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: 15px !important; } - .is-size-7-touch { - font-size: 0.85em !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: 15px !important; } - .is-size-7-desktop { - font-size: 0.85em !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: 15px !important; } - .is-size-7-widescreen { - font-size: 0.85em !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: 15px !important; } - .is-size-7-fullhd { - font-size: 0.85em !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; } - -.has-text-white { - color: white !important; } - -a.has-text-white:hover, a.has-text-white:focus { - color: #e6e6e6 !important; } - -.has-background-white { - background-color: white !important; } - -.has-text-black { - color: #0a0a0a !important; } - -a.has-text-black:hover, a.has-text-black:focus { - color: black !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-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-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-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-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-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-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; } - -.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", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", "Helvetica", "Arial", sans-serif !important; } - -.is-family-secondary { - font-family: "Lato", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", "Helvetica", "Arial", sans-serif !important; } - -.is-family-sans-serif { - font-family: "Lato", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", "Helvetica", "Arial", sans-serif !important; } - -.is-family-monospace { - font-family: "Roboto Mono", "SFMono-Regular", "Menlo", "Consolas", "Liberation Mono", "DejaVu Sans Mono", monospace !important; } - -.is-family-code { - font-family: "Roboto Mono", "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; } } - -.is-marginless { - margin: 0 !important; } - -.is-paddingless { - padding: 0 !important; } - -.is-radiusless { - border-radius: 0 !important; } - -.is-shadowless { - box-shadow: none !important; } - -.is-relative { - position: relative !important; } - -html.theme--documenter-dark { - /* This file contain the overall layout. - * - * The main container is
    that is identified by id #documenter. - */ - /* a11y-dark theme */ - /* Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css */ - /* @author: ericwbailey */ - /* Comment */ - /* Red */ - /* Orange */ - /* Yellow */ - /* Green */ - /* Blue */ - /* Purple */ } - 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 select, - html.theme--documenter-dark textarea { - font-family: "Lato", -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: "Roboto Mono", "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: #e74c3c; - font-size: 0.875em; - font-weight: normal; - padding: 0.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: 0.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: 0.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: left; } - 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 2px 3px 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.375em - 1px); - padding-left: 0.75em; - padding-right: 0.75em; - padding-top: calc(0.375em - 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.375em - 1px); - margin-right: 0.1875em; } - html.theme--documenter-dark .button .icon:last-child:not(:first-child) { - margin-left: 0.1875em; - margin-right: calc(-0.375em - 1px); } - html.theme--documenter-dark .button .icon:first-child:last-child { - margin-left: calc(-0.375em - 1px); - margin-right: calc(-0.375em - 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-white { - background-color: white; - 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: white; - border-color: transparent; - box-shadow: none; } - html.theme--documenter-dark .button.is-white.is-inverted { - background-color: #0a0a0a; - color: white; } - html.theme--documenter-dark .button.is-white.is-inverted:hover, html.theme--documenter-dark .button.is-white.is-inverted.is-hovered { - background-color: black; } - 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: white; } - 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: white; - color: white; } - 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: white; - border-color: white; - color: #0a0a0a; } - html.theme--documenter-dark .button.is-white.is-outlined.is-loading::after { - border-color: transparent transparent white white !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: white; - box-shadow: none; - color: white; } - 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: white; } - 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 white white !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: white; } - html.theme--documenter-dark .button.is-black:hover, html.theme--documenter-dark .button.is-black.is-hovered { - background-color: #040404; - border-color: transparent; - color: white; } - html.theme--documenter-dark .button.is-black:focus, html.theme--documenter-dark .button.is-black.is-focused { - border-color: transparent; - color: white; } - 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: black; - border-color: transparent; - color: white; } - html.theme--documenter-dark .button.is-black[disabled], - fieldset[disabled] html.theme--documenter-dark .button.is-black { - background-color: #0a0a0a; - border-color: transparent; - box-shadow: none; } - html.theme--documenter-dark .button.is-black.is-inverted { - background-color: white; - 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: white; - border-color: transparent; - box-shadow: none; - color: #0a0a0a; } - html.theme--documenter-dark .button.is-black.is-loading::after { - border-color: transparent transparent white white !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: white; } - 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 white white !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: white; - color: white; } - 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: white; - 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: white; - box-shadow: none; - color: white; } - html.theme--documenter-dark .button.is-light { - background-color: #ecf0f1; - border-color: transparent; - color: #282f2f; } - html.theme--documenter-dark .button.is-light:hover, html.theme--documenter-dark .button.is-light.is-hovered { - background-color: #e5eaec; - border-color: transparent; - color: #282f2f; } - html.theme--documenter-dark .button.is-light:focus, html.theme--documenter-dark .button.is-light.is-focused { - border-color: transparent; - color: #282f2f; } - 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: #282f2f; } - html.theme--documenter-dark .button.is-light[disabled], - fieldset[disabled] html.theme--documenter-dark .button.is-light { - background-color: #ecf0f1; - border-color: transparent; - box-shadow: none; } - html.theme--documenter-dark .button.is-light.is-inverted { - background-color: #282f2f; - 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: #1d2122; } - html.theme--documenter-dark .button.is-light.is-inverted[disabled], - fieldset[disabled] html.theme--documenter-dark .button.is-light.is-inverted { - background-color: #282f2f; - border-color: transparent; - box-shadow: none; - color: #ecf0f1; } - html.theme--documenter-dark .button.is-light.is-loading::after { - border-color: transparent transparent #282f2f #282f2f !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: #282f2f; } - 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 #282f2f #282f2f !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: #282f2f; - color: #282f2f; } - 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: #282f2f; - 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: #282f2f; - box-shadow: none; - color: #282f2f; } - html.theme--documenter-dark .button.is-dark, html.theme--documenter-dark .content kbd.button { - background-color: #282f2f; - border-color: transparent; - color: #ecf0f1; } - 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: #ecf0f1; } - 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: #ecf0f1; } - 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: #ecf0f1; } - 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: transparent; - box-shadow: none; } - html.theme--documenter-dark .button.is-dark.is-inverted, html.theme--documenter-dark .content kbd.button.is-inverted { - background-color: #ecf0f1; - 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: #dde4e6; } - 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: #ecf0f1; - 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 #ecf0f1 #ecf0f1 !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: #ecf0f1; } - 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 #ecf0f1 #ecf0f1 !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: #ecf0f1; - color: #ecf0f1; } - 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: #ecf0f1; - 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: #ecf0f1; - box-shadow: none; - color: #ecf0f1; } - 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: transparent; - 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-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: transparent; - 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-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: transparent; - 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-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: #007733; - 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: transparent; - 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-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: transparent; - 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-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: transparent; - 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-small, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.button { - border-radius: 3px; - font-size: 0.85em; } - html.theme--documenter-dark .button.is-normal { - font-size: 15px; } - 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: #dbdee0; - box-shadow: none; - opacity: 0.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 / 2)); - top: calc(50% - (1em / 2)); - 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: 290486px; - padding-left: 1em; - padding-right: 1em; } - 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: 0.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) { - border-radius: 3px; - font-size: 0.85em; } - 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; } - html.theme--documenter-dark .container { - flex-grow: 1; - margin: 0 auto; - position: relative; - width: auto; } - @media screen and (min-width: 1056px) { - html.theme--documenter-dark .container { - max-width: 992px; } - html.theme--documenter-dark .container.is-fluid { - margin-left: 32px; - margin-right: 32px; - max-width: none; } } - @media screen and (max-width: 1215px) { - html.theme--documenter-dark .container.is-widescreen { - max-width: 1152px; } } - @media screen and (max-width: 1407px) { - html.theme--documenter-dark .container.is-fullhd { - max-width: 1344px; } } - @media screen and (min-width: 1216px) { - html.theme--documenter-dark .container { - max-width: 1152px; } } - @media screen and (min-width: 1408px) { - html.theme--documenter-dark .container { - 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:not([type]).is-lower-alpha { - list-style-type: lower-alpha; } - html.theme--documenter-dark .content ol:not([type]).is-lower-roman { - list-style-type: lower-roman; } - html.theme--documenter-dark .content ol:not([type]).is-upper-alpha { - list-style-type: upper-alpha; } - html.theme--documenter-dark .content ol:not([type]).is-upper-roman { - 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.7rem 0.5rem; - 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: left; } - 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: 0.85em; } - 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 .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: 290486px; } - 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: 0.4em; - padding: 1.25rem 2.5rem 1.25rem 1.5rem; - position: relative; } - 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: white; } - html.theme--documenter-dark .notification pre code { - background: transparent; } - html.theme--documenter-dark .notification > .delete { - position: absolute; - right: 0.5rem; - 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: white; - color: #0a0a0a; } - html.theme--documenter-dark .notification.is-black { - background-color: #0a0a0a; - color: white; } - html.theme--documenter-dark .notification.is-light { - background-color: #ecf0f1; - color: #282f2f; } - html.theme--documenter-dark .notification.is-dark, html.theme--documenter-dark .content kbd.notification { - background-color: #282f2f; - color: #ecf0f1; } - 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-link { - background-color: #1abc9c; - color: #fff; } - html.theme--documenter-dark .notification.is-info { - background-color: #024c7d; - color: #fff; } - html.theme--documenter-dark .notification.is-success { - background-color: #008438; - color: #fff; } - html.theme--documenter-dark .notification.is-warning { - background-color: #ad8100; - color: #fff; } - html.theme--documenter-dark .notification.is-danger { - background-color: #9e1b0d; - color: #fff; } - html.theme--documenter-dark .progress { - -moz-appearance: none; - -webkit-appearance: none; - border: none; - border-radius: 290486px; - display: block; - height: 15px; - overflow: hidden; - padding: 0; - width: 100%; } - html.theme--documenter-dark .progress::-webkit-progress-bar { - background-color: #5e6d6f; } - 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: white; } - html.theme--documenter-dark .progress.is-white::-moz-progress-bar { - background-color: white; } - html.theme--documenter-dark .progress.is-white::-ms-fill { - background-color: white; } - html.theme--documenter-dark .progress.is-white:indeterminate { - background-image: linear-gradient(to right, white 30%, #5e6d6f 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%, #5e6d6f 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%, #5e6d6f 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%, #5e6d6f 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%, #5e6d6f 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%, #5e6d6f 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%, #5e6d6f 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%, #5e6d6f 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%, #5e6d6f 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%, #5e6d6f 30%); } - html.theme--documenter-dark .progress:indeterminate { - animation-duration: 1.5s; - animation-iteration-count: infinite; - animation-name: moveIndeterminate; - animation-timing-function: linear; - background-color: #5e6d6f; - background-image: linear-gradient(to right, #fff 30%, #5e6d6f 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.is-small, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.progress { - height: 0.85em; } - 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: white; - border-color: white; - 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: white; } - html.theme--documenter-dark .table td.is-light, - html.theme--documenter-dark .table th.is-light { - background-color: #ecf0f1; - border-color: #ecf0f1; - color: #282f2f; } - html.theme--documenter-dark .table td.is-dark, - html.theme--documenter-dark .table th.is-dark { - background-color: #282f2f; - border-color: #282f2f; - color: #ecf0f1; } - 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 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: transparent; } - 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: transparent; } - 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: transparent; } - 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 .docstring > section > a.docs-sourcelink, html.theme--documenter-dark .tags .content kbd, html.theme--documenter-dark .content .tags kbd { - margin-bottom: 0.5rem; } - html.theme--documenter-dark .tags .tag:not(:last-child), html.theme--documenter-dark .tags .docstring > section > a.docs-sourcelink:not(:last-child), html.theme--documenter-dark .tags .content kbd:not(:last-child), html.theme--documenter-dark .content .tags kbd:not(:last-child) { - margin-right: 0.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 .docstring > section > a.docs-sourcelink: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) { - font-size: 15px; } - html.theme--documenter-dark .tags.are-large .tag:not(.is-normal):not(.is-medium), html.theme--documenter-dark .tags.are-large .docstring > section > a.docs-sourcelink: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) { - 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 .docstring > section > a.docs-sourcelink, html.theme--documenter-dark .tags.is-centered .content kbd, html.theme--documenter-dark .content .tags.is-centered kbd { - 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 .docstring > section > a.docs-sourcelink: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) { - margin-left: 0.5rem; } - html.theme--documenter-dark .tags.is-right .tag:not(:last-child), html.theme--documenter-dark .tags.is-right .docstring > section > a.docs-sourcelink: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) { - margin-right: 0; } - html.theme--documenter-dark .tags.has-addons .tag, html.theme--documenter-dark .tags.has-addons .docstring > section > a.docs-sourcelink, html.theme--documenter-dark .tags.has-addons .content kbd, html.theme--documenter-dark .content .tags.has-addons kbd { - margin-right: 0; } - html.theme--documenter-dark .tags.has-addons .tag:not(:first-child), html.theme--documenter-dark .tags.has-addons .docstring > section > a.docs-sourcelink: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) { - margin-left: 0; - border-bottom-left-radius: 0; - border-top-left-radius: 0; } - html.theme--documenter-dark .tags.has-addons .tag:not(:last-child), html.theme--documenter-dark .tags.has-addons .docstring > section > a.docs-sourcelink: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) { - border-bottom-right-radius: 0; - border-top-right-radius: 0; } - html.theme--documenter-dark .tag:not(body), html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body), html.theme--documenter-dark .content kbd:not(body) { - align-items: center; - background-color: #282f2f; - border-radius: 0.4em; - color: #fff; - display: inline-flex; - font-size: 0.85em; - 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 .docstring > section > a.docs-sourcelink:not(body) .delete, html.theme--documenter-dark .content kbd:not(body) .delete { - margin-left: 0.25rem; - margin-right: -0.375rem; } - html.theme--documenter-dark .tag:not(body).is-white, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-white, html.theme--documenter-dark .content kbd:not(body).is-white { - background-color: white; - color: #0a0a0a; } - html.theme--documenter-dark .tag:not(body).is-black, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-black, html.theme--documenter-dark .content kbd:not(body).is-black { - background-color: #0a0a0a; - color: white; } - html.theme--documenter-dark .tag:not(body).is-light, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-light, html.theme--documenter-dark .content kbd:not(body).is-light { - background-color: #ecf0f1; - color: #282f2f; } - html.theme--documenter-dark .tag:not(body).is-dark, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-dark, html.theme--documenter-dark .content kbd:not(body) { - background-color: #282f2f; - color: #ecf0f1; } - html.theme--documenter-dark .tag:not(body).is-primary, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body), html.theme--documenter-dark .content kbd:not(body).is-primary { - background-color: #375a7f; - color: #fff; } - html.theme--documenter-dark .tag:not(body).is-link, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-link, html.theme--documenter-dark .content kbd:not(body).is-link { - background-color: #1abc9c; - color: #fff; } - html.theme--documenter-dark .tag:not(body).is-info, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-info, html.theme--documenter-dark .content kbd:not(body).is-info { - background-color: #024c7d; - color: #fff; } - html.theme--documenter-dark .tag:not(body).is-success, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-success, html.theme--documenter-dark .content kbd:not(body).is-success { - background-color: #008438; - color: #fff; } - html.theme--documenter-dark .tag:not(body).is-warning, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-warning, html.theme--documenter-dark .content kbd:not(body).is-warning { - background-color: #ad8100; - color: #fff; } - html.theme--documenter-dark .tag:not(body).is-danger, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-danger, html.theme--documenter-dark .content kbd:not(body).is-danger { - background-color: #9e1b0d; - color: #fff; } - html.theme--documenter-dark .tag:not(body).is-normal, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-normal, html.theme--documenter-dark .content kbd:not(body).is-normal { - font-size: 0.85em; } - html.theme--documenter-dark .tag:not(body).is-medium, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-medium, html.theme--documenter-dark .content kbd:not(body).is-medium { - font-size: 15px; } - html.theme--documenter-dark .tag:not(body).is-large, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-large, html.theme--documenter-dark .content kbd:not(body).is-large { - font-size: 1.25rem; } - html.theme--documenter-dark .tag: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), html.theme--documenter-dark .content kbd:not(body) .icon:first-child:not(:last-child) { - margin-left: -0.375em; - margin-right: 0.1875em; } - html.theme--documenter-dark .tag: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), html.theme--documenter-dark .content kbd:not(body) .icon:last-child:not(:first-child) { - margin-left: 0.1875em; - margin-right: -0.375em; } - html.theme--documenter-dark .tag:not(body) .icon:first-child:last-child, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body) .icon:first-child:last-child, html.theme--documenter-dark .content kbd:not(body) .icon:first-child:last-child { - margin-left: -0.375em; - margin-right: -0.375em; } - html.theme--documenter-dark .tag:not(body).is-delete, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-delete, html.theme--documenter-dark .content kbd:not(body).is-delete { - margin-left: 1px; - padding: 0; - position: relative; - width: 2em; } - html.theme--documenter-dark .tag:not(body).is-delete::before, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-delete::before, html.theme--documenter-dark .content kbd:not(body).is-delete::before, html.theme--documenter-dark .tag:not(body).is-delete::after, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-delete::after, html.theme--documenter-dark .content kbd:not(body).is-delete::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:not(body).is-delete::before, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-delete::before, html.theme--documenter-dark .content kbd:not(body).is-delete::before { - height: 1px; - width: 50%; } - html.theme--documenter-dark .tag:not(body).is-delete::after, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-delete::after, html.theme--documenter-dark .content kbd:not(body).is-delete::after { - height: 50%; - width: 1px; } - html.theme--documenter-dark .tag:not(body).is-delete:hover, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-delete:hover, html.theme--documenter-dark .content kbd:not(body).is-delete:hover, html.theme--documenter-dark .tag:not(body).is-delete:focus, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-delete:focus, html.theme--documenter-dark .content kbd:not(body).is-delete:focus { - background-color: #1d2122; } - html.theme--documenter-dark .tag:not(body).is-delete:active, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-delete:active, html.theme--documenter-dark .content kbd:not(body).is-delete:active { - background-color: #111414; } - html.theme--documenter-dark .tag:not(body).is-rounded, html.theme--documenter-dark .docstring > section > a.docs-sourcelink:not(body).is-rounded, html.theme--documenter-dark .content kbd:not(body).is-rounded, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.tag:not(body) { - border-radius: 290486px; } - 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: 0.75em; } - html.theme--documenter-dark .title sup, - html.theme--documenter-dark .subtitle sup { - font-size: 0.75em; } - html.theme--documenter-dark .title .tag, html.theme--documenter-dark .title .docstring > section > a.docs-sourcelink, html.theme--documenter-dark .title .content kbd, html.theme--documenter-dark .content .title kbd, - html.theme--documenter-dark .subtitle .tag, - html.theme--documenter-dark .subtitle .docstring > section > a.docs-sourcelink, - html.theme--documenter-dark .subtitle .content kbd, - html.theme--documenter-dark .content .subtitle kbd { - 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 + .highlight { - margin-top: -0.75rem; } - 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: 15px; } - html.theme--documenter-dark .title.is-7 { - font-size: 0.85em; } - 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: 15px; } - html.theme--documenter-dark .subtitle.is-7 { - font-size: 0.85em; } - html.theme--documenter-dark .heading { - display: block; - font-size: 11px; - letter-spacing: 1px; - margin-bottom: 5px; - text-transform: uppercase; } - html.theme--documenter-dark .highlight { - font-weight: 400; - max-width: 100%; - overflow: hidden; - padding: 0; } - html.theme--documenter-dark .highlight pre { - overflow: auto; - max-width: 100%; } - html.theme--documenter-dark .number { - align-items: center; - background-color: #282f2f; - border-radius: 290486px; - 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 .input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input, html.theme--documenter-dark .textarea, html.theme--documenter-dark .select select { - background-color: #1f2424; - border-color: #5e6d6f; - border-radius: 0.4em; - color: #dbdee0; } - html.theme--documenter-dark .input::-moz-placeholder, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input::-moz-placeholder, html.theme--documenter-dark .textarea::-moz-placeholder, html.theme--documenter-dark .select select::-moz-placeholder { - color: rgba(219, 222, 224, 0.3); } - html.theme--documenter-dark .input::-webkit-input-placeholder, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input::-webkit-input-placeholder, html.theme--documenter-dark .textarea::-webkit-input-placeholder, html.theme--documenter-dark .select select::-webkit-input-placeholder { - color: rgba(219, 222, 224, 0.3); } - html.theme--documenter-dark .input:-moz-placeholder, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input:-moz-placeholder, html.theme--documenter-dark .textarea:-moz-placeholder, html.theme--documenter-dark .select select:-moz-placeholder { - color: rgba(219, 222, 224, 0.3); } - html.theme--documenter-dark .input:-ms-input-placeholder, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input:-ms-input-placeholder, html.theme--documenter-dark .textarea:-ms-input-placeholder, html.theme--documenter-dark .select select:-ms-input-placeholder { - color: rgba(219, 222, 224, 0.3); } - html.theme--documenter-dark .input:hover, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input:hover, html.theme--documenter-dark .textarea:hover, html.theme--documenter-dark .select select:hover, html.theme--documenter-dark .is-hovered.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-hovered, html.theme--documenter-dark .is-hovered.textarea, html.theme--documenter-dark .select select.is-hovered { - border-color: #8c9b9d; } - html.theme--documenter-dark .input:focus, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input:focus, html.theme--documenter-dark .textarea:focus, html.theme--documenter-dark .select select:focus, 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.textarea, html.theme--documenter-dark .select select.is-focused, html.theme--documenter-dark .input:active, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input:active, html.theme--documenter-dark .textarea:active, html.theme--documenter-dark .select select:active, 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.textarea, html.theme--documenter-dark .select select.is-active { - border-color: #1abc9c; - box-shadow: 0 0 0 0.125em rgba(26, 188, 156, 0.25); } - html.theme--documenter-dark .input[disabled], html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input[disabled], html.theme--documenter-dark .textarea[disabled], html.theme--documenter-dark .select select[disabled], - fieldset[disabled] html.theme--documenter-dark .input, - fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input, - fieldset[disabled] html.theme--documenter-dark .textarea, - fieldset[disabled] html.theme--documenter-dark .select select { - background-color: #8c9b9d; - border-color: #282f2f; - box-shadow: none; - color: white; } - html.theme--documenter-dark .input[disabled]::-moz-placeholder, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input[disabled]::-moz-placeholder, html.theme--documenter-dark .textarea[disabled]::-moz-placeholder, html.theme--documenter-dark .select select[disabled]::-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, - fieldset[disabled] html.theme--documenter-dark .textarea::-moz-placeholder, - fieldset[disabled] html.theme--documenter-dark .select select::-moz-placeholder { - color: rgba(255, 255, 255, 0.3); } - html.theme--documenter-dark .input[disabled]::-webkit-input-placeholder, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input[disabled]::-webkit-input-placeholder, html.theme--documenter-dark .textarea[disabled]::-webkit-input-placeholder, html.theme--documenter-dark .select select[disabled]::-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, - fieldset[disabled] html.theme--documenter-dark .textarea::-webkit-input-placeholder, - fieldset[disabled] html.theme--documenter-dark .select select::-webkit-input-placeholder { - color: rgba(255, 255, 255, 0.3); } - html.theme--documenter-dark .input[disabled]:-moz-placeholder, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input[disabled]:-moz-placeholder, html.theme--documenter-dark .textarea[disabled]:-moz-placeholder, html.theme--documenter-dark .select select[disabled]:-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, - fieldset[disabled] html.theme--documenter-dark .textarea:-moz-placeholder, - fieldset[disabled] html.theme--documenter-dark .select select:-moz-placeholder { - color: rgba(255, 255, 255, 0.3); } - html.theme--documenter-dark .input[disabled]:-ms-input-placeholder, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input[disabled]:-ms-input-placeholder, html.theme--documenter-dark .textarea[disabled]:-ms-input-placeholder, html.theme--documenter-dark .select select[disabled]:-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, - fieldset[disabled] html.theme--documenter-dark .textarea:-ms-input-placeholder, - fieldset[disabled] html.theme--documenter-dark .select select:-ms-input-placeholder { - color: rgba(255, 255, 255, 0.3); } - html.theme--documenter-dark .input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input, html.theme--documenter-dark .textarea { - box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.1); - max-width: 100%; - width: 100%; } - html.theme--documenter-dark .input[readonly], html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input[readonly], html.theme--documenter-dark .textarea[readonly] { - box-shadow: none; } - html.theme--documenter-dark .is-white.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-white, html.theme--documenter-dark .is-white.textarea { - border-color: white; } - 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.textarea:focus, html.theme--documenter-dark .is-white.is-focused.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-white.is-focused, html.theme--documenter-dark .is-white.is-focused.textarea, 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.textarea:active, html.theme--documenter-dark .is-white.is-active.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-white.is-active, html.theme--documenter-dark .is-white.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.25); } - html.theme--documenter-dark .is-black.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-black, html.theme--documenter-dark .is-black.textarea { - border-color: #0a0a0a; } - 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.textarea:focus, html.theme--documenter-dark .is-black.is-focused.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-black.is-focused, html.theme--documenter-dark .is-black.is-focused.textarea, 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.textarea:active, html.theme--documenter-dark .is-black.is-active.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-black.is-active, html.theme--documenter-dark .is-black.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(10, 10, 10, 0.25); } - html.theme--documenter-dark .is-light.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-light, html.theme--documenter-dark .is-light.textarea { - border-color: #ecf0f1; } - 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.textarea:focus, html.theme--documenter-dark .is-light.is-focused.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-light.is-focused, html.theme--documenter-dark .is-light.is-focused.textarea, 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.textarea:active, html.theme--documenter-dark .is-light.is-active.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-light.is-active, html.theme--documenter-dark .is-light.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(236, 240, 241, 0.25); } - html.theme--documenter-dark .is-dark.input, html.theme--documenter-dark .content kbd.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-dark, html.theme--documenter-dark .is-dark.textarea, html.theme--documenter-dark .content kbd.textarea { - border-color: #282f2f; } - html.theme--documenter-dark .is-dark.input:focus, html.theme--documenter-dark .content kbd.input:focus, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-dark:focus, html.theme--documenter-dark .is-dark.textarea:focus, html.theme--documenter-dark .content kbd.textarea:focus, html.theme--documenter-dark .is-dark.is-focused.input, html.theme--documenter-dark .content kbd.is-focused.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-dark.is-focused, html.theme--documenter-dark .is-dark.is-focused.textarea, html.theme--documenter-dark .content kbd.is-focused.textarea, html.theme--documenter-dark .is-dark.input:active, html.theme--documenter-dark .content kbd.input:active, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-dark:active, html.theme--documenter-dark .is-dark.textarea:active, html.theme--documenter-dark .content kbd.textarea:active, html.theme--documenter-dark .is-dark.is-active.input, html.theme--documenter-dark .content kbd.is-active.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-dark.is-active, html.theme--documenter-dark .is-dark.is-active.textarea, html.theme--documenter-dark .content kbd.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(40, 47, 47, 0.25); } - html.theme--documenter-dark .is-primary.input, html.theme--documenter-dark .docstring > section > a.input.docs-sourcelink, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-primary, html.theme--documenter-dark .is-primary.textarea, html.theme--documenter-dark .docstring > section > a.textarea.docs-sourcelink { - border-color: #375a7f; } - html.theme--documenter-dark .is-primary.input:focus, html.theme--documenter-dark .docstring > section > a.input.docs-sourcelink:focus, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-primary:focus, 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.is-focused.input, html.theme--documenter-dark .docstring > section > a.is-focused.input.docs-sourcelink, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-primary.is-focused, 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.input:active, html.theme--documenter-dark .docstring > section > a.input.docs-sourcelink:active, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-primary:active, 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.is-active.input, html.theme--documenter-dark .docstring > section > a.is-active.input.docs-sourcelink, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-primary.is-active, html.theme--documenter-dark .is-primary.is-active.textarea, html.theme--documenter-dark .docstring > section > a.is-active.textarea.docs-sourcelink { - box-shadow: 0 0 0 0.125em rgba(55, 90, 127, 0.25); } - html.theme--documenter-dark .is-link.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-link, html.theme--documenter-dark .is-link.textarea { - border-color: #1abc9c; } - 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.textarea:focus, html.theme--documenter-dark .is-link.is-focused.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-link.is-focused, html.theme--documenter-dark .is-link.is-focused.textarea, 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.textarea:active, html.theme--documenter-dark .is-link.is-active.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-link.is-active, html.theme--documenter-dark .is-link.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(26, 188, 156, 0.25); } - html.theme--documenter-dark .is-info.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-info, html.theme--documenter-dark .is-info.textarea { - border-color: #024c7d; } - 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.textarea:focus, html.theme--documenter-dark .is-info.is-focused.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-info.is-focused, html.theme--documenter-dark .is-info.is-focused.textarea, 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.textarea:active, html.theme--documenter-dark .is-info.is-active.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-info.is-active, html.theme--documenter-dark .is-info.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(2, 76, 125, 0.25); } - html.theme--documenter-dark .is-success.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-success, html.theme--documenter-dark .is-success.textarea { - border-color: #008438; } - 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.textarea:focus, html.theme--documenter-dark .is-success.is-focused.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-success.is-focused, html.theme--documenter-dark .is-success.is-focused.textarea, 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.textarea:active, html.theme--documenter-dark .is-success.is-active.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-success.is-active, html.theme--documenter-dark .is-success.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(0, 132, 56, 0.25); } - html.theme--documenter-dark .is-warning.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-warning, html.theme--documenter-dark .is-warning.textarea { - border-color: #ad8100; } - 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.textarea:focus, html.theme--documenter-dark .is-warning.is-focused.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-warning.is-focused, html.theme--documenter-dark .is-warning.is-focused.textarea, 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.textarea:active, html.theme--documenter-dark .is-warning.is-active.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-warning.is-active, html.theme--documenter-dark .is-warning.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(173, 129, 0, 0.25); } - html.theme--documenter-dark .is-danger.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-danger, html.theme--documenter-dark .is-danger.textarea { - border-color: #9e1b0d; } - 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.textarea:focus, html.theme--documenter-dark .is-danger.is-focused.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-danger.is-focused, html.theme--documenter-dark .is-danger.is-focused.textarea, 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.textarea:active, html.theme--documenter-dark .is-danger.is-active.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-danger.is-active, html.theme--documenter-dark .is-danger.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(158, 27, 13, 0.25); } - html.theme--documenter-dark .is-small.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input, html.theme--documenter-dark .is-small.textarea { - border-radius: 3px; - font-size: 0.85em; } - html.theme--documenter-dark .is-medium.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-medium, html.theme--documenter-dark .is-medium.textarea { - font-size: 1.25rem; } - html.theme--documenter-dark .is-large.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-large, html.theme--documenter-dark .is-large.textarea { - font-size: 1.5rem; } - html.theme--documenter-dark .is-fullwidth.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-fullwidth, html.theme--documenter-dark .is-fullwidth.textarea { - display: block; - width: 100%; } - html.theme--documenter-dark .is-inline.input, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.is-inline, html.theme--documenter-dark .is-inline.textarea { - display: inline; - width: auto; } - html.theme--documenter-dark .input.is-rounded, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input { - border-radius: 290486px; - padding-left: 1em; - padding-right: 1em; } - 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: 0.625em; - resize: vertical; } - html.theme--documenter-dark .textarea:not([rows]) { - max-height: 600px; - min-height: 120px; } - html.theme--documenter-dark .textarea[rows] { - height: initial; } - html.theme--documenter-dark .textarea.has-fixed-size { - resize: none; } - html.theme--documenter-dark .checkbox, html.theme--documenter-dark .radio { - cursor: pointer; - display: inline-block; - line-height: 1.25; - position: relative; } - html.theme--documenter-dark .checkbox input, html.theme--documenter-dark .radio input { - cursor: pointer; } - html.theme--documenter-dark .checkbox:hover, html.theme--documenter-dark .radio:hover { - color: #8c9b9d; } - html.theme--documenter-dark .checkbox[disabled], html.theme--documenter-dark .radio[disabled], - fieldset[disabled] html.theme--documenter-dark .checkbox, - fieldset[disabled] html.theme--documenter-dark .radio { - color: white; - cursor: not-allowed; } - html.theme--documenter-dark .radio + .radio { - margin-left: 0.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.25em; } - 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: 290486px; - 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: white; } - html.theme--documenter-dark .select.is-white select { - border-color: white; } - 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: black; } - 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: 0.85em; } - 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: white; } - 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: 0.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.select.is-loading:after { - font-size: 0.85em; } - 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: white; - 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: white; } - 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: white; } - 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: white; } - html.theme--documenter-dark .file.is-black:active .file-cta, html.theme--documenter-dark .file.is-black.is-active .file-cta { - background-color: black; - border-color: transparent; - color: white; } - html.theme--documenter-dark .file.is-light .file-cta { - background-color: #ecf0f1; - border-color: transparent; - color: #282f2f; } - 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: #282f2f; } - 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: #282f2f; } - 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: #282f2f; } - 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: #ecf0f1; } - 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: #ecf0f1; } - 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: #ecf0f1; } - 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: #ecf0f1; } - 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: #007733; - 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: 0.85em; } - 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: 0.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.file.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: 0.4em 0.4em 0 0; } - html.theme--documenter-dark .file.is-boxed.has-name .file-name { - border-radius: 0 0 0.4em 0.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 0.4em 0.4em 0; } - html.theme--documenter-dark .file.is-right .file-name { - border-radius: 0.4em 0 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: #e5eaec; - color: #282f2f; } - html.theme--documenter-dark .file-label:hover .file-name { - border-color: #596668; } - html.theme--documenter-dark .file-label:active .file-cta { - background-color: #dde4e6; - color: #282f2f; } - 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: 0.4em; - font-size: 1em; - padding-left: 1em; - padding-right: 1em; - white-space: nowrap; } - html.theme--documenter-dark .file-cta { - background-color: #ecf0f1; - color: #343c3d; } - 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: left; - text-overflow: ellipsis; } - html.theme--documenter-dark .file-icon { - align-items: center; - display: flex; - height: 1em; - justify-content: center; - margin-right: 0.5em; - width: 1em; } - html.theme--documenter-dark .file-icon .fa { - font-size: 14px; } - html.theme--documenter-dark .label { - color: #282f2f; - display: block; - font-size: 15px; - 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: 0.85em; } - 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: 0.85em; - margin-top: 0.25rem; } - html.theme--documenter-dark .help.is-white { - color: white; } - 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:not([disabled]).is-hovered, - 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:not([disabled]).is-hovered, - html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search > input:not([disabled]).is-hovered, - html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search > input:not([disabled]).is-hovered, - html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):hover, - html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]).is-hovered { - z-index: 2; } - html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):focus, html.theme--documenter-dark .field.has-addons .control .button:not([disabled]).is-focused, html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):active, html.theme--documenter-dark .field.has-addons .control .button:not([disabled]).is-active, - 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:not([disabled]).is-focused, - html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search > input:not([disabled]).is-focused, - html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search > input:not([disabled]).is-focused, - 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:not([disabled]).is-active, - html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search > input:not([disabled]).is-active, - html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search > input:not([disabled]).is-active, - html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):focus, - html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]).is-focused, - html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):active, - html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]).is-active { - 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:not([disabled]).is-focused:hover, html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):active:hover, html.theme--documenter-dark .field.has-addons .control .button:not([disabled]).is-active: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:not([disabled]).is-focused:hover, - html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search > input:not([disabled]).is-focused:hover, - html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search > input:not([disabled]).is-focused: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:not([disabled]).is-active:hover, - html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search > input:not([disabled]).is-active:hover, - html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search > input:not([disabled]).is-active: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:not([disabled]).is-focused: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:not([disabled]).is-active: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: 0.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: 0.85em; - 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: 0.75rem; } } - html.theme--documenter-dark .control { - box-sizing: border-box; - clear: both; - font-size: 15px; - position: relative; - text-align: left; } - 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: #5e6d6f; } - 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-left #documenter .docs-sidebar form.docs-search > input.select ~ .icon, - html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search > input.select ~ .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, - html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search > input.select ~ .icon, - html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search > input.select ~ .icon { - font-size: 0.85em; } - 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: #dbdee0; - height: 2.25em; - pointer-events: none; - position: absolute; - top: 0; - width: 2.25em; - 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.25em; } - 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.25em; } - 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: 0.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.control.is-loading:after { - font-size: 0.85em; } - 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: 15px; - white-space: nowrap; } - html.theme--documenter-dark .breadcrumb a { - align-items: center; - color: #1abc9c; - display: flex; - justify-content: center; - padding: 0 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: 0.5em; } - html.theme--documenter-dark .breadcrumb .icon:last-child { - margin-left: 0.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: 0.85em; } - 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: white; - box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1); - color: #fff; - max-width: 100%; - position: relative; } - html.theme--documenter-dark .card-header { - background-color: transparent; - align-items: stretch; - box-shadow: 0 1px 2px 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; } - html.theme--documenter-dark .card-header-title.is-centered { - justify-content: center; } - html.theme--documenter-dark .card-header-icon { - align-items: center; - cursor: pointer; - display: flex; - justify-content: center; - padding: 0.75rem; } - html.theme--documenter-dark .card-image { - display: block; - position: relative; } - html.theme--documenter-dark .card-content { - background-color: transparent; - padding: 1rem 1.25rem; } - html.theme--documenter-dark .card-footer { - background-color: transparent; - border-top: 1px solid #5e6d6f; - 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: 0.75rem; } - html.theme--documenter-dark .card-footer-item:not(:last-child) { - border-right: 1px solid #5e6d6f; } - 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: 0.4em; - box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1); - padding-bottom: 0.5rem; - padding-top: 0.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: left; - 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: #5e6d6f; - 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: 0.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: 0.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: 0.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: 0.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 .list { - background-color: white; - border-radius: 0.4em; - box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1); } - html.theme--documenter-dark .list-item { - display: block; - padding: 0.5em 1em; } - html.theme--documenter-dark .list-item:not(a) { - color: #fff; } - html.theme--documenter-dark .list-item:first-child { - border-top-left-radius: 0.4em; - border-top-right-radius: 0.4em; } - html.theme--documenter-dark .list-item:last-child { - border-bottom-left-radius: 0.4em; - border-bottom-right-radius: 0.4em; } - html.theme--documenter-dark .list-item:not(:last-child) { - border-bottom: 1px solid #5e6d6f; } - html.theme--documenter-dark .list-item.is-active { - background-color: #1abc9c; - color: #fff; } - html.theme--documenter-dark a.list-item { - background-color: #282f2f; - cursor: pointer; } - html.theme--documenter-dark .media { - align-items: flex-start; - display: flex; - text-align: left; } - html.theme--documenter-dark .media .content:not(:last-child) { - margin-bottom: 0.75rem; } - html.theme--documenter-dark .media .media { - border-top: 1px solid rgba(94, 109, 111, 0.5); - display: flex; - padding-top: 0.75rem; } - html.theme--documenter-dark .media .media .content:not(:last-child), - html.theme--documenter-dark .media .media .control:not(:last-child) { - margin-bottom: 0.5rem; } - html.theme--documenter-dark .media .media .media { - padding-top: 0.5rem; } - html.theme--documenter-dark .media .media .media + .media { - margin-top: 0.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: left; } - @media screen and (max-width: 768px) { - html.theme--documenter-dark .media-content { - overflow-x: auto; } } - html.theme--documenter-dark .menu { - font-size: 15px; } - html.theme--documenter-dark .menu.is-small, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.menu { - font-size: 0.85em; } - 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: 0.75em; - padding-left: 0.75em; } - html.theme--documenter-dark .menu-label { - color: white; - font-size: 0.75em; - letter-spacing: 0.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: 0.4em; - font-size: 15px; } - 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: 0.85em; } - 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: white; } - html.theme--documenter-dark .message.is-white .message-header { - background-color: white; - color: #0a0a0a; } - html.theme--documenter-dark .message.is-white .message-body { - border-color: white; - color: #4d4d4d; } - html.theme--documenter-dark .message.is-black { - background-color: #fafafa; } - html.theme--documenter-dark .message.is-black .message-header { - background-color: #0a0a0a; - color: white; } - html.theme--documenter-dark .message.is-black .message-body { - border-color: #0a0a0a; - color: #090909; } - html.theme--documenter-dark .message.is-light { - background-color: #f9fafb; } - html.theme--documenter-dark .message.is-light .message-header { - background-color: #ecf0f1; - color: #282f2f; } - html.theme--documenter-dark .message.is-light .message-body { - border-color: #ecf0f1; - color: #505050; } - 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: #ecf0f1; } - html.theme--documenter-dark .message.is-dark .message-body, html.theme--documenter-dark .content kbd.message .message-body { - border-color: #282f2f; - color: #212526; } - html.theme--documenter-dark .message.is-primary, html.theme--documenter-dark .docstring > section > a.message.docs-sourcelink { - background-color: #f8fafc; } - 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: #2b4159; } - html.theme--documenter-dark .message.is-link { - background-color: #f6fefc; } - 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: #0b2f28; } - html.theme--documenter-dark .message.is-info { - background-color: #f5fbff; } - 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: #033659; } - html.theme--documenter-dark .message.is-success { - background-color: #f5fff9; } - 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: #023518; } - html.theme--documenter-dark .message.is-warning { - background-color: #fffcf5; } - 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: #3d2e03; } - html.theme--documenter-dark .message.is-danger { - background-color: #fef6f6; } - 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: #7a170c; } - html.theme--documenter-dark .message-header { - align-items: center; - background-color: #fff; - border-radius: 0.4em 0.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; - position: relative; } - html.theme--documenter-dark .message-header .delete { - flex-grow: 0; - flex-shrink: 0; - margin-left: 0.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: 0.4em; - border-style: solid; - border-width: 0 0 0 4px; - color: #fff; - padding: 1em 1.25em; } - html.theme--documenter-dark .message-body code, - html.theme--documenter-dark .message-body pre { - background-color: white; } - html.theme--documenter-dark .message-body pre code { - background-color: transparent; } - 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), print { - 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: 0.5em; } - html.theme--documenter-dark .modal-card-body { - -webkit-overflow-scrolling: touch; - background-color: white; - 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: white; - 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: white; - color: #0a0a0a; } } - html.theme--documenter-dark .navbar.is-black { - background-color: #0a0a0a; - color: white; } - html.theme--documenter-dark .navbar.is-black .navbar-brand > .navbar-item, - html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link { - color: white; } - 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: black; - color: white; } - html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link::after { - border-color: white; } - html.theme--documenter-dark .navbar.is-black .navbar-burger { - color: white; } - @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: white; } - 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: black; - color: white; } - 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: white; } - 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: black; - color: white; } - html.theme--documenter-dark .navbar.is-black .navbar-dropdown a.navbar-item.is-active { - background-color: #0a0a0a; - color: white; } } - html.theme--documenter-dark .navbar.is-light { - background-color: #ecf0f1; - color: #282f2f; } - html.theme--documenter-dark .navbar.is-light .navbar-brand > .navbar-item, - html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link { - color: #282f2f; } - 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: #282f2f; } - html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link::after { - border-color: #282f2f; } - html.theme--documenter-dark .navbar.is-light .navbar-burger { - color: #282f2f; } - @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: #282f2f; } - 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: #282f2f; } - 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: #282f2f; } - 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: #282f2f; } - html.theme--documenter-dark .navbar.is-light .navbar-dropdown a.navbar-item.is-active { - background-color: #ecf0f1; - color: #282f2f; } } - html.theme--documenter-dark .navbar.is-dark, html.theme--documenter-dark .content kbd.navbar { - background-color: #282f2f; - color: #ecf0f1; } - 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: #ecf0f1; } - 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: #ecf0f1; } - 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: #ecf0f1; } - html.theme--documenter-dark .navbar.is-dark .navbar-burger, html.theme--documenter-dark .content kbd.navbar .navbar-burger { - color: #ecf0f1; } - @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: #ecf0f1; } - 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: #ecf0f1; } - 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: #ecf0f1; } - 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: #ecf0f1; } - 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: #ecf0f1; } } - 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; - 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: transparent; - color: #1abc9c; } - html.theme--documenter-dark .navbar-item { - display: block; - 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: transparent; - border-bottom-color: #1abc9c; } - html.theme--documenter-dark .navbar-item.is-tab.is-active { - background-color: transparent; - 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: 0.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: transparent; - color: #dbdee0; } - html.theme--documenter-dark .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active { - background-color: transparent; - 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 { - 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: transparent; - color: #dbdee0; } - html.theme--documenter-dark .navbar-dropdown a.navbar-item.is-active { - background-color: transparent; - 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: transparent; } - 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: transparent; } } - html.theme--documenter-dark .hero.is-fullheight-with-navbar { - min-height: calc(100vh - 4rem); } - html.theme--documenter-dark .pagination { - font-size: 15px; - margin: -0.25rem; } - html.theme--documenter-dark .pagination.is-small, html.theme--documenter-dark #documenter .docs-sidebar form.docs-search > input.pagination { - font-size: 0.85em; } - 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: 290486px; } - 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: 290486px; } - 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: 0.25rem; - padding-left: 0.5em; - padding-right: 0.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.25em; } - 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-next[disabled], - html.theme--documenter-dark .pagination-link[disabled] { - background-color: #dbdee0; - border-color: #dbdee0; - box-shadow: none; - color: #5e6d6f; - opacity: 0.5; } - html.theme--documenter-dark .pagination-previous, - html.theme--documenter-dark .pagination-next { - padding-left: 0.75em; - padding-right: 0.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; } - @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 { - order: 2; } - html.theme--documenter-dark .pagination-next { - order: 3; } - html.theme--documenter-dark .pagination { - justify-content: space-between; } - 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 { - font-size: 15px; } - html.theme--documenter-dark .panel:not(:last-child) { - margin-bottom: 1.5rem; } - html.theme--documenter-dark .panel-heading, - html.theme--documenter-dark .panel-tabs, - html.theme--documenter-dark .panel-block { - border-bottom: 1px solid #5e6d6f; - border-left: 1px solid #5e6d6f; - border-right: 1px solid #5e6d6f; } - html.theme--documenter-dark .panel-heading:first-child, - html.theme--documenter-dark .panel-tabs:first-child, - html.theme--documenter-dark .panel-block:first-child { - border-top: 1px solid #5e6d6f; } - html.theme--documenter-dark .panel-heading { - background-color: #282f2f; - border-radius: 0.4em 0.4em 0 0; - color: #f2f2f2; - font-size: 1.25em; - font-weight: 300; - line-height: 1.25; - padding: 0.5em 0.75em; } - html.theme--documenter-dark .panel-tabs { - align-items: flex-end; - display: flex; - font-size: 0.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: 0.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 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: white; - margin-right: 0.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: 15px; - 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: 0.5em; } - html.theme--documenter-dark .tabs .icon:last-child { - margin-left: 0.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: 0.4em 0.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: white; - border-color: #5e6d6f; - border-bottom-color: transparent !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-radius: 0.4em 0 0 0.4em; } - html.theme--documenter-dark .tabs.is-toggle li:last-child a { - border-radius: 0 0.4em 0.4em 0; } - 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: 290486px; - border-top-left-radius: 290486px; - padding-left: 1.25em; } - html.theme--documenter-dark .tabs.is-toggle.is-toggle-rounded li:last-child a { - border-bottom-right-radius: 290486px; - border-top-right-radius: 290486px; - 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: 0.85em; } - 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: 0.75rem; } - .columns.is-mobile > html.theme--documenter-dark .column.is-narrow { - flex: none; } - .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.33333%; } - .columns.is-mobile > html.theme--documenter-dark .column.is-offset-1 { - margin-left: 8.33333%; } - .columns.is-mobile > html.theme--documenter-dark .column.is-2 { - flex: none; - width: 16.66667%; } - .columns.is-mobile > html.theme--documenter-dark .column.is-offset-2 { - margin-left: 16.66667%; } - .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.33333%; } - .columns.is-mobile > html.theme--documenter-dark .column.is-offset-4 { - margin-left: 33.33333%; } - .columns.is-mobile > html.theme--documenter-dark .column.is-5 { - flex: none; - width: 41.66667%; } - .columns.is-mobile > html.theme--documenter-dark .column.is-offset-5 { - margin-left: 41.66667%; } - .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.33333%; } - .columns.is-mobile > html.theme--documenter-dark .column.is-offset-7 { - margin-left: 58.33333%; } - .columns.is-mobile > html.theme--documenter-dark .column.is-8 { - flex: none; - width: 66.66667%; } - .columns.is-mobile > html.theme--documenter-dark .column.is-offset-8 { - margin-left: 66.66667%; } - .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.33333%; } - .columns.is-mobile > html.theme--documenter-dark .column.is-offset-10 { - margin-left: 83.33333%; } - .columns.is-mobile > html.theme--documenter-dark .column.is-11 { - flex: none; - width: 91.66667%; } - .columns.is-mobile > html.theme--documenter-dark .column.is-offset-11 { - margin-left: 91.66667%; } - .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; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-1-mobile { - margin-left: 8.33333%; } - html.theme--documenter-dark .column.is-2-mobile { - flex: none; - width: 16.66667%; } - html.theme--documenter-dark .column.is-offset-2-mobile { - margin-left: 16.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-4-mobile { - margin-left: 33.33333%; } - html.theme--documenter-dark .column.is-5-mobile { - flex: none; - width: 41.66667%; } - html.theme--documenter-dark .column.is-offset-5-mobile { - margin-left: 41.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-7-mobile { - margin-left: 58.33333%; } - html.theme--documenter-dark .column.is-8-mobile { - flex: none; - width: 66.66667%; } - html.theme--documenter-dark .column.is-offset-8-mobile { - margin-left: 66.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-10-mobile { - margin-left: 83.33333%; } - html.theme--documenter-dark .column.is-11-mobile { - flex: none; - width: 91.66667%; } - html.theme--documenter-dark .column.is-offset-11-mobile { - margin-left: 91.66667%; } - 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; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-1, html.theme--documenter-dark .column.is-offset-1-tablet { - margin-left: 8.33333%; } - html.theme--documenter-dark .column.is-2, html.theme--documenter-dark .column.is-2-tablet { - flex: none; - width: 16.66667%; } - html.theme--documenter-dark .column.is-offset-2, html.theme--documenter-dark .column.is-offset-2-tablet { - margin-left: 16.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-4, html.theme--documenter-dark .column.is-offset-4-tablet { - margin-left: 33.33333%; } - html.theme--documenter-dark .column.is-5, html.theme--documenter-dark .column.is-5-tablet { - flex: none; - width: 41.66667%; } - html.theme--documenter-dark .column.is-offset-5, html.theme--documenter-dark .column.is-offset-5-tablet { - margin-left: 41.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-7, html.theme--documenter-dark .column.is-offset-7-tablet { - margin-left: 58.33333%; } - html.theme--documenter-dark .column.is-8, html.theme--documenter-dark .column.is-8-tablet { - flex: none; - width: 66.66667%; } - html.theme--documenter-dark .column.is-offset-8, html.theme--documenter-dark .column.is-offset-8-tablet { - margin-left: 66.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-10, html.theme--documenter-dark .column.is-offset-10-tablet { - margin-left: 83.33333%; } - html.theme--documenter-dark .column.is-11, html.theme--documenter-dark .column.is-11-tablet { - flex: none; - width: 91.66667%; } - html.theme--documenter-dark .column.is-offset-11, html.theme--documenter-dark .column.is-offset-11-tablet { - margin-left: 91.66667%; } - 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; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-1-touch { - margin-left: 8.33333%; } - html.theme--documenter-dark .column.is-2-touch { - flex: none; - width: 16.66667%; } - html.theme--documenter-dark .column.is-offset-2-touch { - margin-left: 16.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-4-touch { - margin-left: 33.33333%; } - html.theme--documenter-dark .column.is-5-touch { - flex: none; - width: 41.66667%; } - html.theme--documenter-dark .column.is-offset-5-touch { - margin-left: 41.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-7-touch { - margin-left: 58.33333%; } - html.theme--documenter-dark .column.is-8-touch { - flex: none; - width: 66.66667%; } - html.theme--documenter-dark .column.is-offset-8-touch { - margin-left: 66.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-10-touch { - margin-left: 83.33333%; } - html.theme--documenter-dark .column.is-11-touch { - flex: none; - width: 91.66667%; } - html.theme--documenter-dark .column.is-offset-11-touch { - margin-left: 91.66667%; } - 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; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-1-desktop { - margin-left: 8.33333%; } - html.theme--documenter-dark .column.is-2-desktop { - flex: none; - width: 16.66667%; } - html.theme--documenter-dark .column.is-offset-2-desktop { - margin-left: 16.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-4-desktop { - margin-left: 33.33333%; } - html.theme--documenter-dark .column.is-5-desktop { - flex: none; - width: 41.66667%; } - html.theme--documenter-dark .column.is-offset-5-desktop { - margin-left: 41.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-7-desktop { - margin-left: 58.33333%; } - html.theme--documenter-dark .column.is-8-desktop { - flex: none; - width: 66.66667%; } - html.theme--documenter-dark .column.is-offset-8-desktop { - margin-left: 66.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-10-desktop { - margin-left: 83.33333%; } - html.theme--documenter-dark .column.is-11-desktop { - flex: none; - width: 91.66667%; } - html.theme--documenter-dark .column.is-offset-11-desktop { - margin-left: 91.66667%; } - 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; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-1-widescreen { - margin-left: 8.33333%; } - html.theme--documenter-dark .column.is-2-widescreen { - flex: none; - width: 16.66667%; } - html.theme--documenter-dark .column.is-offset-2-widescreen { - margin-left: 16.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-4-widescreen { - margin-left: 33.33333%; } - html.theme--documenter-dark .column.is-5-widescreen { - flex: none; - width: 41.66667%; } - html.theme--documenter-dark .column.is-offset-5-widescreen { - margin-left: 41.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-7-widescreen { - margin-left: 58.33333%; } - html.theme--documenter-dark .column.is-8-widescreen { - flex: none; - width: 66.66667%; } - html.theme--documenter-dark .column.is-offset-8-widescreen { - margin-left: 66.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-10-widescreen { - margin-left: 83.33333%; } - html.theme--documenter-dark .column.is-11-widescreen { - flex: none; - width: 91.66667%; } - html.theme--documenter-dark .column.is-offset-11-widescreen { - margin-left: 91.66667%; } - 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; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-1-fullhd { - margin-left: 8.33333%; } - html.theme--documenter-dark .column.is-2-fullhd { - flex: none; - width: 16.66667%; } - html.theme--documenter-dark .column.is-offset-2-fullhd { - margin-left: 16.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-4-fullhd { - margin-left: 33.33333%; } - html.theme--documenter-dark .column.is-5-fullhd { - flex: none; - width: 41.66667%; } - html.theme--documenter-dark .column.is-offset-5-fullhd { - margin-left: 41.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-7-fullhd { - margin-left: 58.33333%; } - html.theme--documenter-dark .column.is-8-fullhd { - flex: none; - width: 66.66667%; } - html.theme--documenter-dark .column.is-offset-8-fullhd { - margin-left: 66.66667%; } - 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.33333%; } - html.theme--documenter-dark .column.is-offset-10-fullhd { - margin-left: 83.33333%; } - html.theme--documenter-dark .column.is-11-fullhd { - flex: none; - width: 91.66667%; } - html.theme--documenter-dark .column.is-offset-11-fullhd { - margin-left: 91.66667%; } - 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: -0.75rem; - margin-right: -0.75rem; - margin-top: -0.75rem; } - html.theme--documenter-dark .columns:last-child { - margin-bottom: -0.75rem; } - html.theme--documenter-dark .columns:not(:last-child) { - margin-bottom: calc(1.5rem - 0.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: 0.25rem; } - @media screen and (max-width: 768px) { - html.theme--documenter-dark .columns.is-variable.is-1-mobile { - --columnGap: 0.25rem; } } - @media screen and (min-width: 769px), print { - html.theme--documenter-dark .columns.is-variable.is-1-tablet { - --columnGap: 0.25rem; } } - @media screen and (min-width: 769px) and (max-width: 1055px) { - html.theme--documenter-dark .columns.is-variable.is-1-tablet-only { - --columnGap: 0.25rem; } } - @media screen and (max-width: 1055px) { - html.theme--documenter-dark .columns.is-variable.is-1-touch { - --columnGap: 0.25rem; } } - @media screen and (min-width: 1056px) { - html.theme--documenter-dark .columns.is-variable.is-1-desktop { - --columnGap: 0.25rem; } } - @media screen and (min-width: 1056px) and (max-width: 1215px) { - html.theme--documenter-dark .columns.is-variable.is-1-desktop-only { - --columnGap: 0.25rem; } } - @media screen and (min-width: 1216px) { - html.theme--documenter-dark .columns.is-variable.is-1-widescreen { - --columnGap: 0.25rem; } } - @media screen and (min-width: 1216px) and (max-width: 1407px) { - html.theme--documenter-dark .columns.is-variable.is-1-widescreen-only { - --columnGap: 0.25rem; } } - @media screen and (min-width: 1408px) { - html.theme--documenter-dark .columns.is-variable.is-1-fullhd { - --columnGap: 0.25rem; } } - html.theme--documenter-dark .columns.is-variable.is-2 { - --columnGap: 0.5rem; } - @media screen and (max-width: 768px) { - html.theme--documenter-dark .columns.is-variable.is-2-mobile { - --columnGap: 0.5rem; } } - @media screen and (min-width: 769px), print { - html.theme--documenter-dark .columns.is-variable.is-2-tablet { - --columnGap: 0.5rem; } } - @media screen and (min-width: 769px) and (max-width: 1055px) { - html.theme--documenter-dark .columns.is-variable.is-2-tablet-only { - --columnGap: 0.5rem; } } - @media screen and (max-width: 1055px) { - html.theme--documenter-dark .columns.is-variable.is-2-touch { - --columnGap: 0.5rem; } } - @media screen and (min-width: 1056px) { - html.theme--documenter-dark .columns.is-variable.is-2-desktop { - --columnGap: 0.5rem; } } - @media screen and (min-width: 1056px) and (max-width: 1215px) { - html.theme--documenter-dark .columns.is-variable.is-2-desktop-only { - --columnGap: 0.5rem; } } - @media screen and (min-width: 1216px) { - html.theme--documenter-dark .columns.is-variable.is-2-widescreen { - --columnGap: 0.5rem; } } - @media screen and (min-width: 1216px) and (max-width: 1407px) { - html.theme--documenter-dark .columns.is-variable.is-2-widescreen-only { - --columnGap: 0.5rem; } } - @media screen and (min-width: 1408px) { - html.theme--documenter-dark .columns.is-variable.is-2-fullhd { - --columnGap: 0.5rem; } } - html.theme--documenter-dark .columns.is-variable.is-3 { - --columnGap: 0.75rem; } - @media screen and (max-width: 768px) { - html.theme--documenter-dark .columns.is-variable.is-3-mobile { - --columnGap: 0.75rem; } } - @media screen and (min-width: 769px), print { - html.theme--documenter-dark .columns.is-variable.is-3-tablet { - --columnGap: 0.75rem; } } - @media screen and (min-width: 769px) and (max-width: 1055px) { - html.theme--documenter-dark .columns.is-variable.is-3-tablet-only { - --columnGap: 0.75rem; } } - @media screen and (max-width: 1055px) { - html.theme--documenter-dark .columns.is-variable.is-3-touch { - --columnGap: 0.75rem; } } - @media screen and (min-width: 1056px) { - html.theme--documenter-dark .columns.is-variable.is-3-desktop { - --columnGap: 0.75rem; } } - @media screen and (min-width: 1056px) and (max-width: 1215px) { - html.theme--documenter-dark .columns.is-variable.is-3-desktop-only { - --columnGap: 0.75rem; } } - @media screen and (min-width: 1216px) { - html.theme--documenter-dark .columns.is-variable.is-3-widescreen { - --columnGap: 0.75rem; } } - @media screen and (min-width: 1216px) and (max-width: 1407px) { - html.theme--documenter-dark .columns.is-variable.is-3-widescreen-only { - --columnGap: 0.75rem; } } - @media screen and (min-width: 1408px) { - html.theme--documenter-dark .columns.is-variable.is-3-fullhd { - --columnGap: 0.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: -0.75rem; - margin-right: -0.75rem; - margin-top: -0.75rem; } - html.theme--documenter-dark .tile.is-ancestor:last-child { - margin-bottom: -0.75rem; } - html.theme--documenter-dark .tile.is-ancestor:not(:last-child) { - margin-bottom: 0.75rem; } - html.theme--documenter-dark .tile.is-child { - margin: 0 !important; } - html.theme--documenter-dark .tile.is-parent { - padding: 0.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.33333%; } - html.theme--documenter-dark .tile.is-2 { - flex: none; - width: 16.66667%; } - html.theme--documenter-dark .tile.is-3 { - flex: none; - width: 25%; } - html.theme--documenter-dark .tile.is-4 { - flex: none; - width: 33.33333%; } - html.theme--documenter-dark .tile.is-5 { - flex: none; - width: 41.66667%; } - html.theme--documenter-dark .tile.is-6 { - flex: none; - width: 50%; } - html.theme--documenter-dark .tile.is-7 { - flex: none; - width: 58.33333%; } - html.theme--documenter-dark .tile.is-8 { - flex: none; - width: 66.66667%; } - html.theme--documenter-dark .tile.is-9 { - flex: none; - width: 75%; } - html.theme--documenter-dark .tile.is-10 { - flex: none; - width: 83.33333%; } - html.theme--documenter-dark .tile.is-11 { - flex: none; - width: 91.66667%; } - 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: white; - 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: white; } } - 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 { - 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: white; } - html.theme--documenter-dark .hero.is-white.is-bold { - background-image: linear-gradient(141deg, #e6e6e6 0%, white 71%, white 100%); } - @media screen and (max-width: 768px) { - html.theme--documenter-dark .hero.is-white.is-bold .navbar-menu { - background-image: linear-gradient(141deg, #e6e6e6 0%, white 71%, white 100%); } } - html.theme--documenter-dark .hero.is-black { - background-color: #0a0a0a; - color: white; } - 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: white; } - 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: white; } - @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: black; - color: white; } - html.theme--documenter-dark .hero.is-black .tabs a { - color: white; - 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 { - 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: white; } - 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: white; - border-color: white; - color: #0a0a0a; } - html.theme--documenter-dark .hero.is-black.is-bold { - background-image: linear-gradient(141deg, black 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, black 0%, #0a0a0a 71%, #181616 100%); } } - html.theme--documenter-dark .hero.is-light { - background-color: #ecf0f1; - color: #282f2f; } - 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: #282f2f; } - html.theme--documenter-dark .hero.is-light .subtitle { - color: rgba(40, 47, 47, 0.9); } - html.theme--documenter-dark .hero.is-light .subtitle a:not(.button), - html.theme--documenter-dark .hero.is-light .subtitle strong { - color: #282f2f; } - @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(40, 47, 47, 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: #282f2f; } - html.theme--documenter-dark .hero.is-light .tabs a { - color: #282f2f; - 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 { - 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: #282f2f; } - 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: #282f2f; - border-color: #282f2f; - 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: #ecf0f1; } - 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: #ecf0f1; } - html.theme--documenter-dark .hero.is-dark .subtitle, html.theme--documenter-dark .content kbd.hero .subtitle { - color: rgba(236, 240, 241, 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: #ecf0f1; } - @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(236, 240, 241, 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: #ecf0f1; } - html.theme--documenter-dark .hero.is-dark .tabs a, html.theme--documenter-dark .content kbd.hero .tabs a { - color: #ecf0f1; - 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 { - 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: #ecf0f1; } - 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 .content kbd.hero .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, html.theme--documenter-dark .content kbd.hero .tabs.is-toggle li.is-active a:hover { - background-color: #ecf0f1; - border-color: #ecf0f1; - 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 { - 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 .docstring > section > a.hero.docs-sourcelink .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, html.theme--documenter-dark .docstring > section > a.hero.docs-sourcelink .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 { - 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 { - 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 { - 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 { - 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 { - 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-bottom: 1.5rem; - padding-top: 1.5rem; } - @media screen and (min-width: 769px), print { - html.theme--documenter-dark .hero.is-medium .hero-body { - padding-bottom: 9rem; - padding-top: 9rem; } } - @media screen and (min-width: 769px), print { - html.theme--documenter-dark .hero.is-large .hero-body { - padding-bottom: 18rem; - padding-top: 18rem; } } - 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; } - html.theme--documenter-dark .section { - padding: 3rem 1.5rem; } - @media screen and (min-width: 1056px) { - html.theme--documenter-dark .section.is-medium { - padding: 9rem 1.5rem; } - html.theme--documenter-dark .section.is-large { - padding: 18rem 1.5rem; } } - 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: white; } - 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: white; } - 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: white; - 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: white; } - 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: 0.4em; } - html.theme--documenter-dark .card .card-image img { - border-radius: 0.4em 0.4em 0 0; } - html.theme--documenter-dark .card .card-header { - box-shadow: none; - background-color: rgba(18, 18, 18, 0.2); - border-radius: 0.4em 0.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: white; - text-decoration: underline; } - html.theme--documenter-dark .notification.is-light a:not(.button) { - color: #282f2f; - text-decoration: underline; } - html.theme--documenter-dark .notification.is-dark a:not(.button), html.theme--documenter-dark .content kbd.notification a:not(.button) { - color: #ecf0f1; - 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 .docstring > section > a.docs-sourcelink, html.theme--documenter-dark .content kbd { - border-radius: 0.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: white; } - html.theme--documenter-dark .message-body { - border-width: 1px; - border-color: #343c3d; } - html.theme--documenter-dark .navbar { - border-radius: 0.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 0.4em 0.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: transparent; } - html.theme--documenter-dark .hero.is-black .navbar .navbar-dropdown .navbar-item:hover { - background-color: transparent; } - html.theme--documenter-dark .hero.is-light .navbar .navbar-dropdown .navbar-item:hover { - background-color: transparent; } - 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: transparent; } - 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: transparent; } - html.theme--documenter-dark .hero.is-link .navbar .navbar-dropdown .navbar-item:hover { - background-color: transparent; } - html.theme--documenter-dark .hero.is-info .navbar .navbar-dropdown .navbar-item:hover { - background-color: transparent; } - html.theme--documenter-dark .hero.is-success .navbar .navbar-dropdown .navbar-item:hover { - background-color: transparent; } - html.theme--documenter-dark .hero.is-warning .navbar .navbar-dropdown .navbar-item:hover { - background-color: transparent; } - html.theme--documenter-dark .hero.is-danger .navbar .navbar-dropdown .navbar-item:hover { - background-color: transparent; } - 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 5 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 .admonition { - background-color: #282f2f; - border-style: solid; - border-width: 1px; - border-color: #5e6d6f; - border-radius: 0.4em; - font-size: 15px; } - 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: 0.85em; } - 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; } - 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; } - 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; } - 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; } - 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; } - 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; } - html.theme--documenter-dark .admonition-header { - background-color: #5e6d6f; - align-items: center; - font-weight: 700; - justify-content: space-between; - line-height: 1.25; - padding: 0.75em; - position: relative; } - html.theme--documenter-dark .admonition-header:before { - font-family: "Font Awesome 5 Free"; - font-weight: 900; - margin-right: 0.75em; - content: "\f06a"; } - html.theme--documenter-dark .admonition-body { - color: #fff; - padding: 1em 1.25em; } - 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: transparent; - border: 1px solid #5e6d6f; - box-shadow: none; - max-width: 100%; } - html.theme--documenter-dark .docstring > header { - display: flex; - flex-grow: 1; - align-items: stretch; - padding: 0.75rem; - background-color: #282f2f; - box-shadow: 0 1px 2px rgba(10, 10, 10, 0.1); - box-shadow: none; - border-bottom: 1px solid #5e6d6f; } - html.theme--documenter-dark .docstring > header code { - background-color: transparent; } - html.theme--documenter-dark .docstring > header .docstring-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: 1rem 1.25rem; - 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: 0.625rem; - bottom: 0.5rem; } - html.theme--documenter-dark .docstring:hover > 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 .content pre { - border: 1px solid #5e6d6f; } - html.theme--documenter-dark .content code { - font-weight: inherit; } - html.theme--documenter-dark .content a code { - color: #1abc9c; } - html.theme--documenter-dark .content h1 code, html.theme--documenter-dark .content h2 code, html.theme--documenter-dark .content h3 code, html.theme--documenter-dark .content h4 code, html.theme--documenter-dark .content h5 code, html.theme--documenter-dark .content h6 code { - color: #f2f2f2; } - html.theme--documenter-dark .content table { - display: block; - width: initial; - max-width: 100%; - overflow-x: auto; } - html.theme--documenter-dark .content blockquote > ul:first-child, html.theme--documenter-dark .content blockquote > ol:first-child, html.theme--documenter-dark .content .admonition-body > ul:first-child, html.theme--documenter-dark .content .admonition-body > ol:first-child { - margin-top: 0; } - html.theme--documenter-dark .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; - padding: initial !important; } - html.theme--documenter-dark .katex .katex-mathml { - top: 0; - right: 0; } - html.theme--documenter-dark html { - -moz-osx-font-smoothing: auto; - -webkit-font-smoothing: auto; } - html.theme--documenter-dark #documenter .docs-main > article { - overflow-wrap: break-word; } - @media screen and (min-width: 1056px) { - html.theme--documenter-dark #documenter .docs-main { - max-width: 52rem; - margin-left: 20rem; - padding-right: 1rem; } } - @media screen and (max-width: 1055px) { - html.theme--documenter-dark #documenter .docs-main { - width: 100%; } - html.theme--documenter-dark #documenter .docs-main > article { - max-width: 52rem; - margin-left: auto; - margin-right: auto; - margin-bottom: 1rem; - padding: 0 1rem; } - html.theme--documenter-dark #documenter .docs-main > header, html.theme--documenter-dark #documenter .docs-main > nav { - max-width: 100%; - width: 100%; - margin: 0; } } - html.theme--documenter-dark #documenter .docs-main header.docs-navbar { - background-color: #1f2424; - border-bottom: 1px solid #5e6d6f; - z-index: 2; - min-height: 4rem; - margin-bottom: 1rem; - display: flex; } - html.theme--documenter-dark #documenter .docs-main header.docs-navbar .breadcrumb { - flex-grow: 1; } - html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right { - display: flex; - white-space: nowrap; } - 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, html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-sidebar-button { - display: inline-block; } - html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-label { - padding: 0; - margin-left: 0.3em; } - html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-settings-button { - margin: auto 0 auto 1rem; } - html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-sidebar-button { - font-size: 1.5rem; - margin: auto 0 auto 1rem; } - 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; - /* For Headroom.js */ - transition-property: top, box-shadow; - -webkit-transition-property: top, box-shadow; - /* Safari */ - transition-duration: 0.3s; - -webkit-transition-duration: 0.3s; - /* Safari */ } - html.theme--documenter-dark #documenter .docs-main header.docs-navbar.headroom--not-top { - box-shadow: 0.2rem 0rem 0.4rem #171717; - transition-duration: 0.7s; - -webkit-transition-duration: 0.7s; - /* Safari */ } - 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; - /* Safari */ } } - 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: 15px; - position: fixed; - left: -18rem; - width: 18rem; - height: 100%; - transition: left 0.3s; - /* Setting up a nicer theme style for the scrollbar */ } - html.theme--documenter-dark #documenter .docs-sidebar.visible { - left: 0; - box-shadow: 0.4rem 0rem 0.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-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; - /* Managing collapsible submenus */ } - 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: 14.25px; - 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: 11.25px; - 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 5 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: 12.75px; - 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; } - @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 #documenter .docs-main #documenter-search-info { - margin-bottom: 1rem; } - html.theme--documenter-dark #documenter .docs-main #documenter-search-results { - list-style-type: circle; - list-style-position: outside; } - html.theme--documenter-dark #documenter .docs-main #documenter-search-results li { - margin-left: 2rem; } - html.theme--documenter-dark #documenter .docs-main #documenter-search-results .docs-highlight { - background-color: yellow; } - 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 .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-builtin-name, - 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 { - display: block; - overflow-x: auto; - background: #2b2b2b; - color: #f8f8f2; - padding: 0.5em; } - 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-builtin-name, - 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; } diff --git a/docs/build/assets/themes/documenter-light.css b/docs/build/assets/themes/documenter-light.css deleted file mode 100644 index b5dbe62..0000000 --- a/docs/build/assets/themes/documenter-light.css +++ /dev/null @@ -1,7625 +0,0 @@ -@charset "UTF-8"; -/* Font Awesome 5 mixin. Can be included in any rule that should render Font Awesome icons. */ -@keyframes spinAround { - from { - transform: rotate(0deg); } - to { - transform: rotate(359deg); } } - -.delete, .modal-close, .is-unselectable, .button, .file, .breadcrumb, .pagination-previous, -.pagination-next, -.pagination-link, -.pagination-ellipsis, .tabs { - -webkit-touch-callout: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; } - -.select:not(.is-multiple):not(.is-loading)::after, .navbar-link:not(.is-arrowless)::after { - border: 3px solid transparent; - 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; } - -.box:not(:last-child), .content:not(:last-child), .notification:not(:last-child), .progress:not(:last-child), .table:not(:last-child), .table-container:not(:last-child), .title:not(:last-child), -.subtitle:not(:last-child), .block:not(:last-child), .highlight:not(:last-child), .breadcrumb:not(:last-child), .level:not(:last-child), .list:not(:last-child), .message:not(:last-child), .tabs:not(:last-child), .admonition:not(:last-child) { - margin-bottom: 1.5rem; } - -.delete, .modal-close { - -moz-appearance: none; - -webkit-appearance: none; - background-color: rgba(10, 10, 10, 0.2); - border: none; - border-radius: 290486px; - 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; } - .delete::before, .modal-close::before, .delete::after, .modal-close::after { - background-color: white; - content: ""; - display: block; - left: 50%; - position: absolute; - top: 50%; - transform: translateX(-50%) translateY(-50%) rotate(45deg); - transform-origin: center center; } - .delete::before, .modal-close::before { - height: 2px; - width: 50%; } - .delete::after, .modal-close::after { - height: 50%; - width: 2px; } - .delete:hover, .modal-close:hover, .delete:focus, .modal-close:focus { - background-color: rgba(10, 10, 10, 0.3); } - .delete:active, .modal-close:active { - background-color: rgba(10, 10, 10, 0.4); } - .is-small.delete, #documenter .docs-sidebar form.docs-search > input.delete, .is-small.modal-close, #documenter .docs-sidebar form.docs-search > input.modal-close { - height: 16px; - max-height: 16px; - max-width: 16px; - min-height: 16px; - min-width: 16px; - width: 16px; } - .is-medium.delete, .is-medium.modal-close { - height: 24px; - max-height: 24px; - max-width: 24px; - min-height: 24px; - min-width: 24px; - width: 24px; } - .is-large.delete, .is-large.modal-close { - height: 32px; - max-height: 32px; - max-width: 32px; - min-height: 32px; - min-width: 32px; - width: 32px; } - -.button.is-loading::after, .loader, .select.is-loading::after, .control.is-loading::after { - animation: spinAround 500ms infinite linear; - border: 2px solid #dbdbdb; - border-radius: 290486px; - border-right-color: transparent; - border-top-color: transparent; - content: ""; - display: block; - height: 1em; - position: relative; - width: 1em; } - -.is-overlay, .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, .modal, .modal-background, .hero-video { - bottom: 0; - left: 0; - position: absolute; - right: 0; - top: 0; } - -.button, .input, #documenter .docs-sidebar form.docs-search > input, .textarea, .select select, .file-cta, -.file-name, .pagination-previous, -.pagination-next, -.pagination-link, -.pagination-ellipsis { - -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.25em; - justify-content: flex-start; - line-height: 1.5; - padding-bottom: calc(0.375em - 1px); - padding-left: calc(0.625em - 1px); - padding-right: calc(0.625em - 1px); - padding-top: calc(0.375em - 1px); - position: relative; - vertical-align: top; } - .button:focus, .input:focus, #documenter .docs-sidebar form.docs-search > input:focus, .textarea:focus, .select select:focus, .file-cta:focus, - .file-name:focus, .pagination-previous:focus, - .pagination-next:focus, - .pagination-link:focus, - .pagination-ellipsis:focus, .is-focused.button, .is-focused.input, #documenter .docs-sidebar form.docs-search > input.is-focused, .is-focused.textarea, .select select.is-focused, .is-focused.file-cta, - .is-focused.file-name, .is-focused.pagination-previous, - .is-focused.pagination-next, - .is-focused.pagination-link, - .is-focused.pagination-ellipsis, .button:active, .input:active, #documenter .docs-sidebar form.docs-search > input:active, .textarea:active, .select select:active, .file-cta:active, - .file-name:active, .pagination-previous:active, - .pagination-next:active, - .pagination-link:active, - .pagination-ellipsis:active, .is-active.button, .is-active.input, #documenter .docs-sidebar form.docs-search > input.is-active, .is-active.textarea, .select select.is-active, .is-active.file-cta, - .is-active.file-name, .is-active.pagination-previous, - .is-active.pagination-next, - .is-active.pagination-link, - .is-active.pagination-ellipsis { - outline: none; } - .button[disabled], .input[disabled], #documenter .docs-sidebar form.docs-search > input[disabled], .textarea[disabled], .select select[disabled], .file-cta[disabled], - .file-name[disabled], .pagination-previous[disabled], - .pagination-next[disabled], - .pagination-link[disabled], - .pagination-ellipsis[disabled], - fieldset[disabled] .button, - fieldset[disabled] .input, - fieldset[disabled] #documenter .docs-sidebar form.docs-search > input, - #documenter .docs-sidebar fieldset[disabled] form.docs-search > input, - fieldset[disabled] .textarea, - fieldset[disabled] .select select, - .select fieldset[disabled] select, - fieldset[disabled] .file-cta, - fieldset[disabled] .file-name, - fieldset[disabled] .pagination-previous, - fieldset[disabled] .pagination-next, - fieldset[disabled] .pagination-link, - fieldset[disabled] .pagination-ellipsis { - cursor: not-allowed; } - -/*! minireset.css v0.0.4 | 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, -embed, -iframe, -object, -video { - height: auto; - max-width: 100%; } - -audio { - 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: left; } - -html { - background-color: white; - 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, -select, -textarea { - font-family: "Lato", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", "Helvetica", "Arial", sans-serif; } - -code, -pre { - -moz-osx-font-smoothing: auto; - -webkit-font-smoothing: auto; - font-family: "Roboto Mono", "SFMono-Regular", "Menlo", "Consolas", "Liberation Mono", "DejaVu Sans Mono", monospace; } - -body { - color: #222222; - 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: #000000; - font-size: 0.875em; - font-weight: normal; - padding: 0.1em; } - -hr { - background-color: whitesmoke; - 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: 0.875em; } - -span { - font-style: inherit; - font-weight: inherit; } - -strong { - color: #222222; - font-weight: 700; } - -fieldset { - border: none; } - -pre { - -webkit-overflow-scrolling: touch; - background-color: whitesmoke; - color: #222222; - font-size: 0.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: left; } - -table th { - color: #222222; } - -.is-clearfix::after { - clear: both; - content: " "; - display: table; } - -.is-pulled-left { - float: left !important; } - -.is-pulled-right { - float: right !important; } - -.is-clipped { - overflow: hidden !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: 0.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: 0.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: 0.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: 0.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: 0.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: 0.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: 0.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; } - -.has-text-white { - color: white !important; } - -a.has-text-white:hover, a.has-text-white:focus { - color: #e6e6e6 !important; } - -.has-background-white { - background-color: white !important; } - -.has-text-black { - color: #0a0a0a !important; } - -a.has-text-black:hover, a.has-text-black:focus { - color: black !important; } - -.has-background-black { - background-color: #0a0a0a !important; } - -.has-text-light { - color: whitesmoke !important; } - -a.has-text-light:hover, a.has-text-light:focus { - color: #dbdbdb !important; } - -.has-background-light { - background-color: whitesmoke !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-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-info { - color: #209cee !important; } - -a.has-text-info:hover, a.has-text-info:focus { - color: #0f81cc !important; } - -.has-background-info { - background-color: #209cee !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-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-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-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: #7a7a7a !important; } - -.has-background-grey { - background-color: #7a7a7a !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: whitesmoke !important; } - -.has-background-white-ter { - background-color: whitesmoke !important; } - -.has-text-white-bis { - color: #fafafa !important; } - -.has-background-white-bis { - background-color: #fafafa !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", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", "Helvetica", "Arial", sans-serif !important; } - -.is-family-secondary { - font-family: "Lato", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", "Helvetica", "Arial", sans-serif !important; } - -.is-family-sans-serif { - font-family: "Lato", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", "Helvetica", "Arial", sans-serif !important; } - -.is-family-monospace { - font-family: "Roboto Mono", "SFMono-Regular", "Menlo", "Consolas", "Liberation Mono", "DejaVu Sans Mono", monospace !important; } - -.is-family-code { - font-family: "Roboto Mono", "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; } } - -.is-marginless { - margin: 0 !important; } - -.is-paddingless { - padding: 0 !important; } - -.is-radiusless { - border-radius: 0 !important; } - -.is-shadowless { - box-shadow: none !important; } - -.is-relative { - position: relative !important; } - -.box { - background-color: white; - border-radius: 6px; - box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1); - color: #222222; - display: block; - padding: 1.25rem; } - -a.box:hover, a.box:focus { - box-shadow: 0 2px 3px 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: white; - border-color: #dbdbdb; - border-width: 1px; - color: #363636; - cursor: pointer; - justify-content: center; - padding-bottom: calc(0.375em - 1px); - padding-left: 0.75em; - padding-right: 0.75em; - padding-top: calc(0.375em - 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.375em - 1px); - margin-right: 0.1875em; } - .button .icon:last-child:not(:first-child) { - margin-left: 0.1875em; - margin-right: calc(-0.375em - 1px); } - .button .icon:first-child:last-child { - margin-left: calc(-0.375em - 1px); - margin-right: calc(-0.375em - 1px); } - .button:hover, .button.is-hovered { - border-color: #b5b5b5; - color: #363636; } - .button:focus, .button.is-focused { - border-color: #2e63b8; - 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: #222222; - text-decoration: underline; } - .button.is-text:hover, .button.is-text.is-hovered, .button.is-text:focus, .button.is-text.is-focused { - background-color: whitesmoke; - color: #222222; } - .button.is-text:active, .button.is-text.is-active { - background-color: #e8e8e8; - color: #222222; } - .button.is-text[disabled], - fieldset[disabled] .button.is-text { - background-color: transparent; - border-color: transparent; - box-shadow: none; } - .button.is-white { - background-color: white; - 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: white; - border-color: transparent; - box-shadow: none; } - .button.is-white.is-inverted { - background-color: #0a0a0a; - color: white; } - .button.is-white.is-inverted:hover, .button.is-white.is-inverted.is-hovered { - background-color: black; } - .button.is-white.is-inverted[disabled], - fieldset[disabled] .button.is-white.is-inverted { - background-color: #0a0a0a; - border-color: transparent; - box-shadow: none; - color: white; } - .button.is-white.is-loading::after { - border-color: transparent transparent #0a0a0a #0a0a0a !important; } - .button.is-white.is-outlined { - background-color: transparent; - border-color: white; - color: white; } - .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: white; - border-color: white; - color: #0a0a0a; } - .button.is-white.is-outlined.is-loading::after { - border-color: transparent transparent white white !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: white; - box-shadow: none; - color: white; } - .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: white; } - .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 white white !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: white; } - .button.is-black:hover, .button.is-black.is-hovered { - background-color: #040404; - border-color: transparent; - color: white; } - .button.is-black:focus, .button.is-black.is-focused { - border-color: transparent; - color: white; } - .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: black; - border-color: transparent; - color: white; } - .button.is-black[disabled], - fieldset[disabled] .button.is-black { - background-color: #0a0a0a; - border-color: transparent; - box-shadow: none; } - .button.is-black.is-inverted { - background-color: white; - 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: white; - border-color: transparent; - box-shadow: none; - color: #0a0a0a; } - .button.is-black.is-loading::after { - border-color: transparent transparent white white !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: white; } - .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 white white !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: white; - color: white; } - .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: white; - 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: white; - box-shadow: none; - color: white; } - .button.is-light { - background-color: whitesmoke; - border-color: transparent; - color: #363636; } - .button.is-light:hover, .button.is-light.is-hovered { - background-color: #eeeeee; - border-color: transparent; - color: #363636; } - .button.is-light:focus, .button.is-light.is-focused { - border-color: transparent; - color: #363636; } - .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: #363636; } - .button.is-light[disabled], - fieldset[disabled] .button.is-light { - background-color: whitesmoke; - border-color: transparent; - box-shadow: none; } - .button.is-light.is-inverted { - background-color: #363636; - color: whitesmoke; } - .button.is-light.is-inverted:hover, .button.is-light.is-inverted.is-hovered { - background-color: #292929; } - .button.is-light.is-inverted[disabled], - fieldset[disabled] .button.is-light.is-inverted { - background-color: #363636; - border-color: transparent; - box-shadow: none; - color: whitesmoke; } - .button.is-light.is-loading::after { - border-color: transparent transparent #363636 #363636 !important; } - .button.is-light.is-outlined { - background-color: transparent; - border-color: whitesmoke; - color: whitesmoke; } - .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: whitesmoke; - border-color: whitesmoke; - color: #363636; } - .button.is-light.is-outlined.is-loading::after { - border-color: transparent transparent whitesmoke whitesmoke !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 #363636 #363636 !important; } - .button.is-light.is-outlined[disabled], - fieldset[disabled] .button.is-light.is-outlined { - background-color: transparent; - border-color: whitesmoke; - box-shadow: none; - color: whitesmoke; } - .button.is-light.is-inverted.is-outlined { - background-color: transparent; - border-color: #363636; - color: #363636; } - .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: #363636; - color: whitesmoke; } - .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 whitesmoke whitesmoke !important; } - .button.is-light.is-inverted.is-outlined[disabled], - fieldset[disabled] .button.is-light.is-inverted.is-outlined { - background-color: transparent; - border-color: #363636; - box-shadow: none; - color: #363636; } - .button.is-dark, .content kbd.button { - background-color: #363636; - border-color: transparent; - color: whitesmoke; } - .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: whitesmoke; } - .button.is-dark:focus, .content kbd.button:focus, .button.is-dark.is-focused, .content kbd.button.is-focused { - border-color: transparent; - color: whitesmoke; } - .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: whitesmoke; } - .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: transparent; - box-shadow: none; } - .button.is-dark.is-inverted, .content kbd.button.is-inverted { - background-color: whitesmoke; - 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: #e8e8e8; } - .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: whitesmoke; - border-color: transparent; - box-shadow: none; - color: #363636; } - .button.is-dark.is-loading::after, .content kbd.button.is-loading::after { - border-color: transparent transparent whitesmoke whitesmoke !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: whitesmoke; } - .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 whitesmoke whitesmoke !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: whitesmoke; - color: whitesmoke; } - .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: whitesmoke; - 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: whitesmoke; - box-shadow: none; - color: whitesmoke; } - .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: transparent; - 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-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: transparent; - 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-info { - background-color: #209cee; - border-color: transparent; - color: #fff; } - .button.is-info:hover, .button.is-info.is-hovered { - background-color: #1496ed; - 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: #118fe4; - border-color: transparent; - color: #fff; } - .button.is-info[disabled], - fieldset[disabled] .button.is-info { - background-color: #209cee; - border-color: transparent; - 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-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: transparent; - 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-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: #ffdb4a; - 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: #ffd83d; - border-color: transparent; - color: rgba(0, 0, 0, 0.7); } - .button.is-warning[disabled], - fieldset[disabled] .button.is-warning { - background-color: #ffdd57; - border-color: transparent; - 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-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: transparent; - 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-small, #documenter .docs-sidebar form.docs-search > input.button { - border-radius: 2px; - font-size: 0.75rem; } - .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: white; - border-color: #dbdbdb; - box-shadow: none; - opacity: 0.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 / 2)); - top: calc(50% - (1em / 2)); - position: absolute !important; } - .button.is-static { - background-color: whitesmoke; - border-color: #dbdbdb; - color: #7a7a7a; - box-shadow: none; - pointer-events: none; } - .button.is-rounded, #documenter .docs-sidebar form.docs-search > input.button { - border-radius: 290486px; - padding-left: 1em; - padding-right: 1em; } - -.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: 0.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) { - border-radius: 2px; - font-size: 0.75rem; } - .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; } - -.container { - flex-grow: 1; - margin: 0 auto; - position: relative; - width: auto; } - @media screen and (min-width: 1056px) { - .container { - max-width: 992px; } - .container.is-fluid { - margin-left: 32px; - margin-right: 32px; - max-width: none; } } - @media screen and (max-width: 1215px) { - .container.is-widescreen { - max-width: 1152px; } } - @media screen and (max-width: 1407px) { - .container.is-fullhd { - max-width: 1344px; } } - @media screen and (min-width: 1216px) { - .container { - max-width: 1152px; } } - @media screen and (min-width: 1408px) { - .container { - 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: #222222; - 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: whitesmoke; - 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:not([type]).is-lower-alpha { - list-style-type: lower-alpha; } - .content ol:not([type]).is-lower-roman { - list-style-type: lower-roman; } - .content ol:not([type]).is-upper-alpha { - list-style-type: upper-alpha; } - .content ol:not([type]).is-upper-roman { - 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.7rem 0.5rem; - 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: #222222; } - .content table th:not([align]) { - text-align: left; } - .content table thead td, - .content table thead th { - border-width: 0 0 2px; - color: #222222; } - .content table tfoot td, - .content table tfoot th { - border-width: 2px 0 0; - color: #222222; } - .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: 0.75rem; } - -.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; } - -.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: 290486px; } - .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: whitesmoke; - border-radius: 4px; - padding: 1.25rem 2.5rem 1.25rem 1.5rem; - position: relative; } - .notification a:not(.button):not(.dropdown-item) { - color: currentColor; - text-decoration: underline; } - .notification strong { - color: currentColor; } - .notification code, - .notification pre { - background: white; } - .notification pre code { - background: transparent; } - .notification > .delete { - position: absolute; - right: 0.5rem; - top: 0.5rem; } - .notification .title, - .notification .subtitle, - .notification .content { - color: currentColor; } - .notification.is-white { - background-color: white; - color: #0a0a0a; } - .notification.is-black { - background-color: #0a0a0a; - color: white; } - .notification.is-light { - background-color: whitesmoke; - color: #363636; } - .notification.is-dark, .content kbd.notification { - background-color: #363636; - color: whitesmoke; } - .notification.is-primary, .docstring > section > a.notification.docs-sourcelink { - background-color: #4eb5de; - color: #fff; } - .notification.is-link { - background-color: #2e63b8; - color: #fff; } - .notification.is-info { - background-color: #209cee; - color: #fff; } - .notification.is-success { - background-color: #22c35b; - color: #fff; } - .notification.is-warning { - background-color: #ffdd57; - color: rgba(0, 0, 0, 0.7); } - .notification.is-danger { - background-color: #da0b00; - color: #fff; } - -.progress { - -moz-appearance: none; - -webkit-appearance: none; - border: none; - border-radius: 290486px; - display: block; - height: 1rem; - overflow: hidden; - padding: 0; - width: 100%; } - .progress::-webkit-progress-bar { - background-color: #dbdbdb; } - .progress::-webkit-progress-value { - background-color: #222222; } - .progress::-moz-progress-bar { - background-color: #222222; } - .progress::-ms-fill { - background-color: #222222; - border: none; } - .progress.is-white::-webkit-progress-value { - background-color: white; } - .progress.is-white::-moz-progress-bar { - background-color: white; } - .progress.is-white::-ms-fill { - background-color: white; } - .progress.is-white:indeterminate { - background-image: linear-gradient(to right, white 30%, #dbdbdb 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%, #dbdbdb 30%); } - .progress.is-light::-webkit-progress-value { - background-color: whitesmoke; } - .progress.is-light::-moz-progress-bar { - background-color: whitesmoke; } - .progress.is-light::-ms-fill { - background-color: whitesmoke; } - .progress.is-light:indeterminate { - background-image: linear-gradient(to right, whitesmoke 30%, #dbdbdb 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%, #dbdbdb 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%, #dbdbdb 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%, #dbdbdb 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%, #dbdbdb 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%, #dbdbdb 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%, #dbdbdb 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%, #dbdbdb 30%); } - .progress:indeterminate { - animation-duration: 1.5s; - animation-iteration-count: infinite; - animation-name: moveIndeterminate; - animation-timing-function: linear; - background-color: #dbdbdb; - background-image: linear-gradient(to right, #222222 30%, #dbdbdb 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.is-small, #documenter .docs-sidebar form.docs-search > input.progress { - height: 0.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: white; - color: #363636; } - .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: white; - border-color: white; - color: #0a0a0a; } - .table td.is-black, - .table th.is-black { - background-color: #0a0a0a; - border-color: #0a0a0a; - color: white; } - .table td.is-light, - .table th.is-light { - background-color: whitesmoke; - border-color: whitesmoke; - color: #363636; } - .table td.is-dark, - .table th.is-dark { - background-color: #363636; - border-color: #363636; - color: whitesmoke; } - .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 th { - color: #222222; } - .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: transparent; } - .table thead td, - .table thead th { - border-width: 0 0 2px; - color: #222222; } - .table tfoot { - background-color: transparent; } - .table tfoot td, - .table tfoot th { - border-width: 2px 0 0; - color: #222222; } - .table tbody { - background-color: transparent; } - .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: whitesmoke; } - .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 .docstring > section > a.docs-sourcelink, .tags .content kbd, .content .tags kbd { - margin-bottom: 0.5rem; } - .tags .tag:not(:last-child), .tags .docstring > section > a.docs-sourcelink:not(:last-child), .tags .content kbd:not(:last-child), .content .tags kbd:not(:last-child) { - margin-right: 0.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 .docstring > section > a.docs-sourcelink: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) { - font-size: 1rem; } - .tags.are-large .tag:not(.is-normal):not(.is-medium), .tags.are-large .docstring > section > a.docs-sourcelink: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) { - font-size: 1.25rem; } - .tags.is-centered { - justify-content: center; } - .tags.is-centered .tag, .tags.is-centered .docstring > section > a.docs-sourcelink, .tags.is-centered .content kbd, .content .tags.is-centered kbd { - 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 .docstring > section > a.docs-sourcelink:not(:first-child), .tags.is-right .content kbd:not(:first-child), .content .tags.is-right kbd:not(:first-child) { - margin-left: 0.5rem; } - .tags.is-right .tag:not(:last-child), .tags.is-right .docstring > section > a.docs-sourcelink:not(:last-child), .tags.is-right .content kbd:not(:last-child), .content .tags.is-right kbd:not(:last-child) { - margin-right: 0; } - .tags.has-addons .tag, .tags.has-addons .docstring > section > a.docs-sourcelink, .tags.has-addons .content kbd, .content .tags.has-addons kbd { - margin-right: 0; } - .tags.has-addons .tag:not(:first-child), .tags.has-addons .docstring > section > a.docs-sourcelink:not(:first-child), .tags.has-addons .content kbd:not(:first-child), .content .tags.has-addons kbd:not(:first-child) { - margin-left: 0; - border-bottom-left-radius: 0; - border-top-left-radius: 0; } - .tags.has-addons .tag:not(:last-child), .tags.has-addons .docstring > section > a.docs-sourcelink:not(:last-child), .tags.has-addons .content kbd:not(:last-child), .content .tags.has-addons kbd:not(:last-child) { - border-bottom-right-radius: 0; - border-top-right-radius: 0; } - -.tag:not(body), .docstring > section > a.docs-sourcelink:not(body), .content kbd:not(body) { - align-items: center; - background-color: whitesmoke; - border-radius: 4px; - color: #222222; - display: inline-flex; - font-size: 0.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, .docstring > section > a.docs-sourcelink:not(body) .delete, .content kbd:not(body) .delete { - margin-left: 0.25rem; - margin-right: -0.375rem; } - .tag:not(body).is-white, .docstring > section > a.docs-sourcelink:not(body).is-white, .content kbd:not(body).is-white { - background-color: white; - color: #0a0a0a; } - .tag:not(body).is-black, .docstring > section > a.docs-sourcelink:not(body).is-black, .content kbd:not(body).is-black { - background-color: #0a0a0a; - color: white; } - .tag:not(body).is-light, .docstring > section > a.docs-sourcelink:not(body).is-light, .content kbd:not(body).is-light { - background-color: whitesmoke; - color: #363636; } - .tag:not(body).is-dark, .docstring > section > a.docs-sourcelink:not(body).is-dark, .content kbd:not(body) { - background-color: #363636; - color: whitesmoke; } - .tag:not(body).is-primary, .docstring > section > a.docs-sourcelink:not(body), .content kbd:not(body).is-primary { - background-color: #4eb5de; - color: #fff; } - .tag:not(body).is-link, .docstring > section > a.docs-sourcelink:not(body).is-link, .content kbd:not(body).is-link { - background-color: #2e63b8; - color: #fff; } - .tag:not(body).is-info, .docstring > section > a.docs-sourcelink:not(body).is-info, .content kbd:not(body).is-info { - background-color: #209cee; - color: #fff; } - .tag:not(body).is-success, .docstring > section > a.docs-sourcelink:not(body).is-success, .content kbd:not(body).is-success { - background-color: #22c35b; - color: #fff; } - .tag:not(body).is-warning, .docstring > section > a.docs-sourcelink:not(body).is-warning, .content kbd:not(body).is-warning { - background-color: #ffdd57; - color: rgba(0, 0, 0, 0.7); } - .tag:not(body).is-danger, .docstring > section > a.docs-sourcelink:not(body).is-danger, .content kbd:not(body).is-danger { - background-color: #da0b00; - color: #fff; } - .tag:not(body).is-normal, .docstring > section > a.docs-sourcelink:not(body).is-normal, .content kbd:not(body).is-normal { - font-size: 0.75rem; } - .tag:not(body).is-medium, .docstring > section > a.docs-sourcelink:not(body).is-medium, .content kbd:not(body).is-medium { - font-size: 1rem; } - .tag:not(body).is-large, .docstring > section > a.docs-sourcelink:not(body).is-large, .content kbd:not(body).is-large { - font-size: 1.25rem; } - .tag:not(body) .icon:first-child:not(:last-child), .docstring > section > a.docs-sourcelink:not(body) .icon:first-child:not(:last-child), .content kbd:not(body) .icon:first-child:not(:last-child) { - margin-left: -0.375em; - margin-right: 0.1875em; } - .tag:not(body) .icon:last-child:not(:first-child), .docstring > section > a.docs-sourcelink:not(body) .icon:last-child:not(:first-child), .content kbd:not(body) .icon:last-child:not(:first-child) { - margin-left: 0.1875em; - margin-right: -0.375em; } - .tag:not(body) .icon:first-child:last-child, .docstring > section > a.docs-sourcelink:not(body) .icon:first-child:last-child, .content kbd:not(body) .icon:first-child:last-child { - margin-left: -0.375em; - margin-right: -0.375em; } - .tag:not(body).is-delete, .docstring > section > a.docs-sourcelink:not(body).is-delete, .content kbd:not(body).is-delete { - margin-left: 1px; - padding: 0; - position: relative; - width: 2em; } - .tag:not(body).is-delete::before, .docstring > section > a.docs-sourcelink:not(body).is-delete::before, .content kbd:not(body).is-delete::before, .tag:not(body).is-delete::after, .docstring > section > a.docs-sourcelink:not(body).is-delete::after, .content kbd:not(body).is-delete::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:not(body).is-delete::before, .docstring > section > a.docs-sourcelink:not(body).is-delete::before, .content kbd:not(body).is-delete::before { - height: 1px; - width: 50%; } - .tag:not(body).is-delete::after, .docstring > section > a.docs-sourcelink:not(body).is-delete::after, .content kbd:not(body).is-delete::after { - height: 50%; - width: 1px; } - .tag:not(body).is-delete:hover, .docstring > section > a.docs-sourcelink:not(body).is-delete:hover, .content kbd:not(body).is-delete:hover, .tag:not(body).is-delete:focus, .docstring > section > a.docs-sourcelink:not(body).is-delete:focus, .content kbd:not(body).is-delete:focus { - background-color: #e8e8e8; } - .tag:not(body).is-delete:active, .docstring > section > a.docs-sourcelink:not(body).is-delete:active, .content kbd:not(body).is-delete:active { - background-color: #dbdbdb; } - .tag:not(body).is-rounded, .docstring > section > a.docs-sourcelink:not(body).is-rounded, .content kbd:not(body).is-rounded, #documenter .docs-sidebar form.docs-search > input.tag:not(body) { - border-radius: 290486px; } - -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: 0.75em; } - .title sup, - .subtitle sup { - font-size: 0.75em; } - .title .tag, .title .docstring > section > a.docs-sourcelink, .title .content kbd, .content .title kbd, - .subtitle .tag, - .subtitle .docstring > section > a.docs-sourcelink, - .subtitle .content kbd, - .content .subtitle kbd { - vertical-align: middle; } - -.title { - color: #363636; - font-size: 2rem; - font-weight: 600; - line-height: 1.125; } - .title strong { - color: inherit; - font-weight: inherit; } - .title + .highlight { - margin-top: -0.75rem; } - .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: 0.75rem; } - -.subtitle { - color: #4a4a4a; - font-size: 1.25rem; - font-weight: 400; - line-height: 1.25; } - .subtitle strong { - color: #363636; - 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: 0.75rem; } - -.heading { - display: block; - font-size: 11px; - letter-spacing: 1px; - margin-bottom: 5px; - text-transform: uppercase; } - -.highlight { - font-weight: 400; - max-width: 100%; - overflow: hidden; - padding: 0; } - .highlight pre { - overflow: auto; - max-width: 100%; } - -.number { - align-items: center; - background-color: whitesmoke; - border-radius: 290486px; - 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; } - -.input, #documenter .docs-sidebar form.docs-search > input, .textarea, .select select { - background-color: white; - border-color: #dbdbdb; - border-radius: 4px; - color: #363636; } - .input::-moz-placeholder, #documenter .docs-sidebar form.docs-search > input::-moz-placeholder, .textarea::-moz-placeholder, .select select::-moz-placeholder { - color: rgba(54, 54, 54, 0.3); } - .input::-webkit-input-placeholder, #documenter .docs-sidebar form.docs-search > input::-webkit-input-placeholder, .textarea::-webkit-input-placeholder, .select select::-webkit-input-placeholder { - color: rgba(54, 54, 54, 0.3); } - .input:-moz-placeholder, #documenter .docs-sidebar form.docs-search > input:-moz-placeholder, .textarea:-moz-placeholder, .select select:-moz-placeholder { - color: rgba(54, 54, 54, 0.3); } - .input:-ms-input-placeholder, #documenter .docs-sidebar form.docs-search > input:-ms-input-placeholder, .textarea:-ms-input-placeholder, .select select:-ms-input-placeholder { - color: rgba(54, 54, 54, 0.3); } - .input:hover, #documenter .docs-sidebar form.docs-search > input:hover, .textarea:hover, .select select:hover, .is-hovered.input, #documenter .docs-sidebar form.docs-search > input.is-hovered, .is-hovered.textarea, .select select.is-hovered { - border-color: #b5b5b5; } - .input:focus, #documenter .docs-sidebar form.docs-search > input:focus, .textarea:focus, .select select:focus, .is-focused.input, #documenter .docs-sidebar form.docs-search > input.is-focused, .is-focused.textarea, .select select.is-focused, .input:active, #documenter .docs-sidebar form.docs-search > input:active, .textarea:active, .select select:active, .is-active.input, #documenter .docs-sidebar form.docs-search > input.is-active, .is-active.textarea, .select select.is-active { - border-color: #2e63b8; - box-shadow: 0 0 0 0.125em rgba(46, 99, 184, 0.25); } - .input[disabled], #documenter .docs-sidebar form.docs-search > input[disabled], .textarea[disabled], .select select[disabled], - fieldset[disabled] .input, - fieldset[disabled] #documenter .docs-sidebar form.docs-search > input, - #documenter .docs-sidebar fieldset[disabled] form.docs-search > input, - fieldset[disabled] .textarea, - fieldset[disabled] .select select, - .select fieldset[disabled] select { - background-color: whitesmoke; - border-color: whitesmoke; - box-shadow: none; - color: #7a7a7a; } - .input[disabled]::-moz-placeholder, #documenter .docs-sidebar form.docs-search > input[disabled]::-moz-placeholder, .textarea[disabled]::-moz-placeholder, .select select[disabled]::-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, - fieldset[disabled] .textarea::-moz-placeholder, - fieldset[disabled] .select select::-moz-placeholder, - .select fieldset[disabled] select::-moz-placeholder { - color: rgba(122, 122, 122, 0.3); } - .input[disabled]::-webkit-input-placeholder, #documenter .docs-sidebar form.docs-search > input[disabled]::-webkit-input-placeholder, .textarea[disabled]::-webkit-input-placeholder, .select select[disabled]::-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, - fieldset[disabled] .textarea::-webkit-input-placeholder, - fieldset[disabled] .select select::-webkit-input-placeholder, - .select fieldset[disabled] select::-webkit-input-placeholder { - color: rgba(122, 122, 122, 0.3); } - .input[disabled]:-moz-placeholder, #documenter .docs-sidebar form.docs-search > input[disabled]:-moz-placeholder, .textarea[disabled]:-moz-placeholder, .select select[disabled]:-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, - fieldset[disabled] .textarea:-moz-placeholder, - fieldset[disabled] .select select:-moz-placeholder, - .select fieldset[disabled] select:-moz-placeholder { - color: rgba(122, 122, 122, 0.3); } - .input[disabled]:-ms-input-placeholder, #documenter .docs-sidebar form.docs-search > input[disabled]:-ms-input-placeholder, .textarea[disabled]:-ms-input-placeholder, .select select[disabled]:-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, - fieldset[disabled] .textarea:-ms-input-placeholder, - fieldset[disabled] .select select:-ms-input-placeholder, - .select fieldset[disabled] select:-ms-input-placeholder { - color: rgba(122, 122, 122, 0.3); } - -.input, #documenter .docs-sidebar form.docs-search > input, .textarea { - box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.1); - max-width: 100%; - width: 100%; } - .input[readonly], #documenter .docs-sidebar form.docs-search > input[readonly], .textarea[readonly] { - box-shadow: none; } - .is-white.input, #documenter .docs-sidebar form.docs-search > input.is-white, .is-white.textarea { - border-color: white; } - .is-white.input:focus, #documenter .docs-sidebar form.docs-search > input.is-white:focus, .is-white.textarea:focus, .is-white.is-focused.input, #documenter .docs-sidebar form.docs-search > input.is-white.is-focused, .is-white.is-focused.textarea, .is-white.input:active, #documenter .docs-sidebar form.docs-search > input.is-white:active, .is-white.textarea:active, .is-white.is-active.input, #documenter .docs-sidebar form.docs-search > input.is-white.is-active, .is-white.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.25); } - .is-black.input, #documenter .docs-sidebar form.docs-search > input.is-black, .is-black.textarea { - border-color: #0a0a0a; } - .is-black.input:focus, #documenter .docs-sidebar form.docs-search > input.is-black:focus, .is-black.textarea:focus, .is-black.is-focused.input, #documenter .docs-sidebar form.docs-search > input.is-black.is-focused, .is-black.is-focused.textarea, .is-black.input:active, #documenter .docs-sidebar form.docs-search > input.is-black:active, .is-black.textarea:active, .is-black.is-active.input, #documenter .docs-sidebar form.docs-search > input.is-black.is-active, .is-black.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(10, 10, 10, 0.25); } - .is-light.input, #documenter .docs-sidebar form.docs-search > input.is-light, .is-light.textarea { - border-color: whitesmoke; } - .is-light.input:focus, #documenter .docs-sidebar form.docs-search > input.is-light:focus, .is-light.textarea:focus, .is-light.is-focused.input, #documenter .docs-sidebar form.docs-search > input.is-light.is-focused, .is-light.is-focused.textarea, .is-light.input:active, #documenter .docs-sidebar form.docs-search > input.is-light:active, .is-light.textarea:active, .is-light.is-active.input, #documenter .docs-sidebar form.docs-search > input.is-light.is-active, .is-light.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(245, 245, 245, 0.25); } - .is-dark.input, .content kbd.input, #documenter .docs-sidebar form.docs-search > input.is-dark, .is-dark.textarea, .content kbd.textarea { - border-color: #363636; } - .is-dark.input:focus, .content kbd.input:focus, #documenter .docs-sidebar form.docs-search > input.is-dark:focus, .is-dark.textarea:focus, .content kbd.textarea:focus, .is-dark.is-focused.input, .content kbd.is-focused.input, #documenter .docs-sidebar form.docs-search > input.is-dark.is-focused, .is-dark.is-focused.textarea, .content kbd.is-focused.textarea, .is-dark.input:active, .content kbd.input:active, #documenter .docs-sidebar form.docs-search > input.is-dark:active, .is-dark.textarea:active, .content kbd.textarea:active, .is-dark.is-active.input, .content kbd.is-active.input, #documenter .docs-sidebar form.docs-search > input.is-dark.is-active, .is-dark.is-active.textarea, .content kbd.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(54, 54, 54, 0.25); } - .is-primary.input, .docstring > section > a.input.docs-sourcelink, #documenter .docs-sidebar form.docs-search > input.is-primary, .is-primary.textarea, .docstring > section > a.textarea.docs-sourcelink { - border-color: #4eb5de; } - .is-primary.input:focus, .docstring > section > a.input.docs-sourcelink:focus, #documenter .docs-sidebar form.docs-search > input.is-primary:focus, .is-primary.textarea:focus, .docstring > section > a.textarea.docs-sourcelink:focus, .is-primary.is-focused.input, .docstring > section > a.is-focused.input.docs-sourcelink, #documenter .docs-sidebar form.docs-search > input.is-primary.is-focused, .is-primary.is-focused.textarea, .docstring > section > a.is-focused.textarea.docs-sourcelink, .is-primary.input:active, .docstring > section > a.input.docs-sourcelink:active, #documenter .docs-sidebar form.docs-search > input.is-primary:active, .is-primary.textarea:active, .docstring > section > a.textarea.docs-sourcelink:active, .is-primary.is-active.input, .docstring > section > a.is-active.input.docs-sourcelink, #documenter .docs-sidebar form.docs-search > input.is-primary.is-active, .is-primary.is-active.textarea, .docstring > section > a.is-active.textarea.docs-sourcelink { - box-shadow: 0 0 0 0.125em rgba(78, 181, 222, 0.25); } - .is-link.input, #documenter .docs-sidebar form.docs-search > input.is-link, .is-link.textarea { - border-color: #2e63b8; } - .is-link.input:focus, #documenter .docs-sidebar form.docs-search > input.is-link:focus, .is-link.textarea:focus, .is-link.is-focused.input, #documenter .docs-sidebar form.docs-search > input.is-link.is-focused, .is-link.is-focused.textarea, .is-link.input:active, #documenter .docs-sidebar form.docs-search > input.is-link:active, .is-link.textarea:active, .is-link.is-active.input, #documenter .docs-sidebar form.docs-search > input.is-link.is-active, .is-link.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(46, 99, 184, 0.25); } - .is-info.input, #documenter .docs-sidebar form.docs-search > input.is-info, .is-info.textarea { - border-color: #209cee; } - .is-info.input:focus, #documenter .docs-sidebar form.docs-search > input.is-info:focus, .is-info.textarea:focus, .is-info.is-focused.input, #documenter .docs-sidebar form.docs-search > input.is-info.is-focused, .is-info.is-focused.textarea, .is-info.input:active, #documenter .docs-sidebar form.docs-search > input.is-info:active, .is-info.textarea:active, .is-info.is-active.input, #documenter .docs-sidebar form.docs-search > input.is-info.is-active, .is-info.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(32, 156, 238, 0.25); } - .is-success.input, #documenter .docs-sidebar form.docs-search > input.is-success, .is-success.textarea { - border-color: #22c35b; } - .is-success.input:focus, #documenter .docs-sidebar form.docs-search > input.is-success:focus, .is-success.textarea:focus, .is-success.is-focused.input, #documenter .docs-sidebar form.docs-search > input.is-success.is-focused, .is-success.is-focused.textarea, .is-success.input:active, #documenter .docs-sidebar form.docs-search > input.is-success:active, .is-success.textarea:active, .is-success.is-active.input, #documenter .docs-sidebar form.docs-search > input.is-success.is-active, .is-success.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(34, 195, 91, 0.25); } - .is-warning.input, #documenter .docs-sidebar form.docs-search > input.is-warning, .is-warning.textarea { - border-color: #ffdd57; } - .is-warning.input:focus, #documenter .docs-sidebar form.docs-search > input.is-warning:focus, .is-warning.textarea:focus, .is-warning.is-focused.input, #documenter .docs-sidebar form.docs-search > input.is-warning.is-focused, .is-warning.is-focused.textarea, .is-warning.input:active, #documenter .docs-sidebar form.docs-search > input.is-warning:active, .is-warning.textarea:active, .is-warning.is-active.input, #documenter .docs-sidebar form.docs-search > input.is-warning.is-active, .is-warning.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(255, 221, 87, 0.25); } - .is-danger.input, #documenter .docs-sidebar form.docs-search > input.is-danger, .is-danger.textarea { - border-color: #da0b00; } - .is-danger.input:focus, #documenter .docs-sidebar form.docs-search > input.is-danger:focus, .is-danger.textarea:focus, .is-danger.is-focused.input, #documenter .docs-sidebar form.docs-search > input.is-danger.is-focused, .is-danger.is-focused.textarea, .is-danger.input:active, #documenter .docs-sidebar form.docs-search > input.is-danger:active, .is-danger.textarea:active, .is-danger.is-active.input, #documenter .docs-sidebar form.docs-search > input.is-danger.is-active, .is-danger.is-active.textarea { - box-shadow: 0 0 0 0.125em rgba(218, 11, 0, 0.25); } - .is-small.input, #documenter .docs-sidebar form.docs-search > input, .is-small.textarea { - border-radius: 2px; - font-size: 0.75rem; } - .is-medium.input, #documenter .docs-sidebar form.docs-search > input.is-medium, .is-medium.textarea { - font-size: 1.25rem; } - .is-large.input, #documenter .docs-sidebar form.docs-search > input.is-large, .is-large.textarea { - font-size: 1.5rem; } - .is-fullwidth.input, #documenter .docs-sidebar form.docs-search > input.is-fullwidth, .is-fullwidth.textarea { - display: block; - width: 100%; } - .is-inline.input, #documenter .docs-sidebar form.docs-search > input.is-inline, .is-inline.textarea { - display: inline; - width: auto; } - -.input.is-rounded, #documenter .docs-sidebar form.docs-search > input { - border-radius: 290486px; - padding-left: 1em; - padding-right: 1em; } - -.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: 0.625em; - resize: vertical; } - .textarea:not([rows]) { - max-height: 600px; - min-height: 120px; } - .textarea[rows] { - height: initial; } - .textarea.has-fixed-size { - resize: none; } - -.checkbox, .radio { - cursor: pointer; - display: inline-block; - line-height: 1.25; - position: relative; } - .checkbox input, .radio input { - cursor: pointer; } - .checkbox:hover, .radio:hover { - color: #363636; } - .checkbox[disabled], .radio[disabled], - fieldset[disabled] .checkbox, - fieldset[disabled] .radio { - color: #7a7a7a; - cursor: not-allowed; } - -.radio + .radio { - margin-left: 0.5em; } - -.select { - display: inline-block; - max-width: 100%; - position: relative; - vertical-align: top; } - .select:not(.is-multiple) { - height: 2.25em; } - .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: 290486px; - 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: whitesmoke; } - .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: #363636; } - .select.is-white:not(:hover)::after { - border-color: white; } - .select.is-white select { - border-color: white; } - .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: black; } - .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: whitesmoke; } - .select.is-light select { - border-color: whitesmoke; } - .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: #118fe4; } - .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: #ffd83d; } - .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: 0.75rem; } - .select.is-medium { - font-size: 1.25rem; } - .select.is-large { - font-size: 1.5rem; } - .select.is-disabled::after { - border-color: #7a7a7a; } - .select.is-fullwidth { - width: 100%; } - .select.is-fullwidth select { - width: 100%; } - .select.is-loading::after { - margin-top: 0; - position: absolute; - right: 0.625em; - top: 0.625em; - transform: none; } - .select.is-loading.is-small:after, #documenter .docs-sidebar form.docs-search > input.select.is-loading:after { - font-size: 0.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: white; - 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: white; } - .file.is-black:hover .file-cta, .file.is-black.is-hovered .file-cta { - background-color: #040404; - border-color: transparent; - color: white; } - .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: white; } - .file.is-black:active .file-cta, .file.is-black.is-active .file-cta { - background-color: black; - border-color: transparent; - color: white; } - .file.is-light .file-cta { - background-color: whitesmoke; - border-color: transparent; - color: #363636; } - .file.is-light:hover .file-cta, .file.is-light.is-hovered .file-cta { - background-color: #eeeeee; - border-color: transparent; - color: #363636; } - .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: #363636; } - .file.is-light:active .file-cta, .file.is-light.is-active .file-cta { - background-color: #e8e8e8; - border-color: transparent; - color: #363636; } - .file.is-dark .file-cta, .content kbd.file .file-cta { - background-color: #363636; - border-color: transparent; - color: whitesmoke; } - .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: whitesmoke; } - .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: whitesmoke; } - .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: whitesmoke; } - .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: #1496ed; - 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: #118fe4; - 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: #ffdb4a; - 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: #ffd83d; - 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: 0.75rem; } - .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.file.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: #eeeeee; - color: #363636; } - .file-label:hover .file-name { - border-color: #d5d5d5; } - .file-label:active .file-cta { - background-color: #e8e8e8; - color: #363636; } - .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: whitesmoke; - color: #4a4a4a; } - -.file-name { - border-color: #dbdbdb; - border-style: solid; - border-width: 1px 1px 1px 0; - display: block; - max-width: 16em; - overflow: hidden; - text-align: left; - text-overflow: ellipsis; } - -.file-icon { - align-items: center; - display: flex; - height: 1em; - justify-content: center; - margin-right: 0.5em; - width: 1em; } - .file-icon .fa { - font-size: 14px; } - -.label { - color: #363636; - 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: 0.75rem; } - .label.is-medium { - font-size: 1.25rem; } - .label.is-large { - font-size: 1.5rem; } - -.help { - display: block; - font-size: 0.75rem; - margin-top: 0.25rem; } - .help.is-white { - color: white; } - .help.is-black { - color: #0a0a0a; } - .help.is-light { - color: whitesmoke; } - .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:not([disabled]).is-hovered, - .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:not([disabled]).is-hovered, - .field.has-addons .control #documenter .docs-sidebar form.docs-search > input:not([disabled]).is-hovered, - #documenter .docs-sidebar .field.has-addons .control form.docs-search > input:not([disabled]).is-hovered, - .field.has-addons .control .select select:not([disabled]):hover, - .field.has-addons .control .select select:not([disabled]).is-hovered { - z-index: 2; } - .field.has-addons .control .button:not([disabled]):focus, .field.has-addons .control .button:not([disabled]).is-focused, .field.has-addons .control .button:not([disabled]):active, .field.has-addons .control .button:not([disabled]).is-active, - .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:not([disabled]).is-focused, - .field.has-addons .control #documenter .docs-sidebar form.docs-search > input:not([disabled]).is-focused, - #documenter .docs-sidebar .field.has-addons .control form.docs-search > input:not([disabled]).is-focused, - .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:not([disabled]).is-active, - .field.has-addons .control #documenter .docs-sidebar form.docs-search > input:not([disabled]).is-active, - #documenter .docs-sidebar .field.has-addons .control form.docs-search > input:not([disabled]).is-active, - .field.has-addons .control .select select:not([disabled]):focus, - .field.has-addons .control .select select:not([disabled]).is-focused, - .field.has-addons .control .select select:not([disabled]):active, - .field.has-addons .control .select select:not([disabled]).is-active { - z-index: 3; } - .field.has-addons .control .button:not([disabled]):focus:hover, .field.has-addons .control .button:not([disabled]).is-focused:hover, .field.has-addons .control .button:not([disabled]):active:hover, .field.has-addons .control .button:not([disabled]).is-active: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:not([disabled]).is-focused:hover, - .field.has-addons .control #documenter .docs-sidebar form.docs-search > input:not([disabled]).is-focused:hover, - #documenter .docs-sidebar .field.has-addons .control form.docs-search > input:not([disabled]).is-focused: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:not([disabled]).is-active:hover, - .field.has-addons .control #documenter .docs-sidebar form.docs-search > input:not([disabled]).is-active:hover, - #documenter .docs-sidebar .field.has-addons .control form.docs-search > input:not([disabled]).is-active:hover, - .field.has-addons .control .select select:not([disabled]):focus:hover, - .field.has-addons .control .select select:not([disabled]).is-focused:hover, - .field.has-addons .control .select select:not([disabled]):active:hover, - .field.has-addons .control .select select:not([disabled]).is-active: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: 0.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: 0.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: 0.75rem; } } - -.control { - box-sizing: border-box; - clear: both; - font-size: 1rem; - position: relative; - text-align: left; } - .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: #7a7a7a; } - .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-left #documenter .docs-sidebar form.docs-search > input.select ~ .icon, - #documenter .docs-sidebar .control.has-icons-left form.docs-search > input.select ~ .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, - .control.has-icons-right #documenter .docs-sidebar form.docs-search > input.select ~ .icon, - #documenter .docs-sidebar .control.has-icons-right form.docs-search > input.select ~ .icon { - font-size: 0.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.25em; - pointer-events: none; - position: absolute; - top: 0; - width: 2.25em; - 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.25em; } - .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.25em; } - .control.has-icons-right .icon.is-right { - right: 0; } - .control.is-loading::after { - position: absolute !important; - right: 0.625em; - top: 0.625em; - z-index: 4; } - .control.is-loading.is-small:after, #documenter .docs-sidebar form.docs-search > input.control.is-loading:after { - font-size: 0.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 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: #222222; - 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: 0.5em; } - .breadcrumb .icon:last-child { - margin-left: 0.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: 0.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: white; - box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1); - color: #222222; - max-width: 100%; - position: relative; } - -.card-header { - background-color: transparent; - align-items: stretch; - box-shadow: 0 1px 2px rgba(10, 10, 10, 0.1); - display: flex; } - -.card-header-title { - align-items: center; - color: #222222; - display: flex; - flex-grow: 1; - font-weight: 700; - padding: 0.75rem; } - .card-header-title.is-centered { - justify-content: center; } - -.card-header-icon { - align-items: center; - cursor: pointer; - display: flex; - justify-content: center; - padding: 0.75rem; } - -.card-image { - display: block; - position: relative; } - -.card-content { - background-color: transparent; - padding: 1rem 1.25rem; } - -.card-footer { - background-color: transparent; - border-top: 1px solid #dbdbdb; - 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: 0.75rem; } - .card-footer-item:not(:last-child) { - border-right: 1px solid #dbdbdb; } - -.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: white; - border-radius: 4px; - box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1); - padding-bottom: 0.5rem; - padding-top: 0.5rem; } - -.dropdown-item { - color: #4a4a4a; - 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: left; - white-space: nowrap; - width: 100%; } - a.dropdown-item:hover, - button.dropdown-item:hover { - background-color: whitesmoke; - color: #0a0a0a; } - a.dropdown-item.is-active, - button.dropdown-item.is-active { - background-color: #2e63b8; - color: #fff; } - -.dropdown-divider { - background-color: #dbdbdb; - 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: 0.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: 0.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: 0.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; } } - -.list { - background-color: white; - border-radius: 4px; - box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1); } - -.list-item { - display: block; - padding: 0.5em 1em; } - .list-item:not(a) { - color: #222222; } - .list-item:first-child { - border-top-left-radius: 4px; - border-top-right-radius: 4px; } - .list-item:last-child { - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; } - .list-item:not(:last-child) { - border-bottom: 1px solid #dbdbdb; } - .list-item.is-active { - background-color: #2e63b8; - color: #fff; } - -a.list-item { - background-color: whitesmoke; - cursor: pointer; } - -.media { - align-items: flex-start; - display: flex; - text-align: left; } - .media .content:not(:last-child) { - margin-bottom: 0.75rem; } - .media .media { - border-top: 1px solid rgba(219, 219, 219, 0.5); - display: flex; - padding-top: 0.75rem; } - .media .media .content:not(:last-child), - .media .media .control:not(:last-child) { - margin-bottom: 0.5rem; } - .media .media .media { - padding-top: 0.5rem; } - .media .media .media + .media { - margin-top: 0.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: left; } - -@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: 0.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: #222222; - display: block; - padding: 0.5em 0.75em; } - .menu-list a:hover { - background-color: whitesmoke; - color: #222222; } - .menu-list a.is-active { - background-color: #2e63b8; - color: #fff; } - .menu-list li ul { - border-left: 1px solid #dbdbdb; - margin: 0.75em; - padding-left: 0.75em; } - -.menu-label { - color: #7a7a7a; - font-size: 0.75em; - letter-spacing: 0.1em; - text-transform: uppercase; } - .menu-label:not(:first-child) { - margin-top: 1em; } - .menu-label:not(:last-child) { - margin-bottom: 1em; } - -.message { - background-color: whitesmoke; - 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: 0.75rem; } - .message.is-medium { - font-size: 1.25rem; } - .message.is-large { - font-size: 1.5rem; } - .message.is-white { - background-color: white; } - .message.is-white .message-header { - background-color: white; - color: #0a0a0a; } - .message.is-white .message-body { - border-color: white; - color: #4d4d4d; } - .message.is-black { - background-color: #fafafa; } - .message.is-black .message-header { - background-color: #0a0a0a; - color: white; } - .message.is-black .message-body { - border-color: #0a0a0a; - color: #090909; } - .message.is-light { - background-color: #fafafa; } - .message.is-light .message-header { - background-color: whitesmoke; - color: #363636; } - .message.is-light .message-body { - border-color: whitesmoke; - color: #505050; } - .message.is-dark, .content kbd.message { - background-color: #fafafa; } - .message.is-dark .message-header, .content kbd.message .message-header { - background-color: #363636; - color: whitesmoke; } - .message.is-dark .message-body, .content kbd.message .message-body { - border-color: #363636; - color: #2a2a2a; } - .message.is-primary, .docstring > section > a.message.docs-sourcelink { - background-color: #f6fbfd; } - .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: #1f556a; } - .message.is-link { - background-color: #f7f9fd; } - .message.is-link .message-header { - background-color: #2e63b8; - color: #fff; } - .message.is-link .message-body { - border-color: #2e63b8; - color: #264981; } - .message.is-info { - background-color: #f6fbfe; } - .message.is-info .message-header { - background-color: #209cee; - color: #fff; } - .message.is-info .message-body { - border-color: #209cee; - color: #12537e; } - .message.is-success { - background-color: #f6fdf9; } - .message.is-success .message-header { - background-color: #22c35b; - color: #fff; } - .message.is-success .message-body { - border-color: #22c35b; - color: #0f361d; } - .message.is-warning { - background-color: #fffdf5; } - .message.is-warning .message-header { - background-color: #ffdd57; - color: rgba(0, 0, 0, 0.7); } - .message.is-warning .message-body { - border-color: #ffdd57; - color: #3b3108; } - .message.is-danger { - background-color: #fff5f5; } - .message.is-danger .message-header { - background-color: #da0b00; - color: #fff; } - .message.is-danger .message-body { - border-color: #da0b00; - color: #9b0c04; } - -.message-header { - align-items: center; - background-color: #222222; - border-radius: 4px 4px 0 0; - color: #fff; - display: flex; - font-weight: 700; - justify-content: space-between; - line-height: 1.25; - padding: 0.75em; - position: relative; } - .message-header .delete { - flex-grow: 0; - flex-shrink: 0; - margin-left: 0.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: #222222; - padding: 1em 1.25em; } - .message-body code, - .message-body pre { - background-color: white; } - .message-body pre code { - background-color: transparent; } - -.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), print { - .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: whitesmoke; - 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: #222222; - 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: 0.5em; } - -.modal-card-body { - -webkit-overflow-scrolling: touch; - background-color: white; - flex-grow: 1; - flex-shrink: 1; - overflow: auto; - padding: 20px; } - -.navbar { - background-color: white; - min-height: 3.25rem; - position: relative; - z-index: 30; } - .navbar.is-white { - background-color: white; - 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: white; - color: #0a0a0a; } } - .navbar.is-black { - background-color: #0a0a0a; - color: white; } - .navbar.is-black .navbar-brand > .navbar-item, - .navbar.is-black .navbar-brand .navbar-link { - color: white; } - .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: black; - color: white; } - .navbar.is-black .navbar-brand .navbar-link::after { - border-color: white; } - .navbar.is-black .navbar-burger { - color: white; } - @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: white; } - .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: black; - color: white; } - .navbar.is-black .navbar-start .navbar-link::after, - .navbar.is-black .navbar-end .navbar-link::after { - border-color: white; } - .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: black; - color: white; } - .navbar.is-black .navbar-dropdown a.navbar-item.is-active { - background-color: #0a0a0a; - color: white; } } - .navbar.is-light { - background-color: whitesmoke; - color: #363636; } - .navbar.is-light .navbar-brand > .navbar-item, - .navbar.is-light .navbar-brand .navbar-link { - color: #363636; } - .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: #363636; } - .navbar.is-light .navbar-brand .navbar-link::after { - border-color: #363636; } - .navbar.is-light .navbar-burger { - color: #363636; } - @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: #363636; } - .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: #363636; } - .navbar.is-light .navbar-start .navbar-link::after, - .navbar.is-light .navbar-end .navbar-link::after { - border-color: #363636; } - .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: #363636; } - .navbar.is-light .navbar-dropdown a.navbar-item.is-active { - background-color: whitesmoke; - color: #363636; } } - .navbar.is-dark, .content kbd.navbar { - background-color: #363636; - color: whitesmoke; } - .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: whitesmoke; } - .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: whitesmoke; } - .navbar.is-dark .navbar-brand .navbar-link::after, .content kbd.navbar .navbar-brand .navbar-link::after { - border-color: whitesmoke; } - .navbar.is-dark .navbar-burger, .content kbd.navbar .navbar-burger { - color: whitesmoke; } - @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: whitesmoke; } - .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: whitesmoke; } - .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: whitesmoke; } - .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: whitesmoke; } - .navbar.is-dark .navbar-dropdown a.navbar-item.is-active, .content kbd.navbar .navbar-dropdown a.navbar-item.is-active { - background-color: #363636; - color: whitesmoke; } } - .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: #118fe4; - 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: #118fe4; - 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: #118fe4; - 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: #ffd83d; - 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: #ffd83d; - 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: #ffd83d; - 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 whitesmoke; } - .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 whitesmoke; } - .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: #4a4a4a; - 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: #4a4a4a; - 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 { - display: block; - 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: transparent; - border-bottom-color: #2e63b8; } - .navbar-item.is-tab.is-active { - background-color: transparent; - 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: whitesmoke; - 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: white; - 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: whitesmoke; - color: #0a0a0a; } - .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active { - background-color: whitesmoke; - color: #2e63b8; } - .navbar-burger { - display: none; } - .navbar-item, - .navbar-link { - align-items: center; - display: flex; } - .navbar-item { - 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: white; - 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: whitesmoke; - color: #0a0a0a; } - .navbar-dropdown a.navbar-item.is-active { - background-color: whitesmoke; - 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: transparent; } - .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: -0.25rem; } - .pagination.is-small, #documenter .docs-sidebar form.docs-search > input.pagination { - font-size: 0.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: 290486px; } - .pagination.is-rounded .pagination-link, #documenter .docs-sidebar form.docs-search > input.pagination .pagination-link { - border-radius: 290486px; } - -.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: 0.25rem; - padding-left: 0.5em; - padding-right: 0.5em; - text-align: center; } - -.pagination-previous, -.pagination-next, -.pagination-link { - border-color: #dbdbdb; - color: #363636; - min-width: 2.25em; } - .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: #2e63b8; } - .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-next[disabled], - .pagination-link[disabled] { - background-color: #dbdbdb; - border-color: #dbdbdb; - box-shadow: none; - color: #7a7a7a; - opacity: 0.5; } - -.pagination-previous, -.pagination-next { - padding-left: 0.75em; - padding-right: 0.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; } - -@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 { - order: 2; } - .pagination-next { - order: 3; } - .pagination { - justify-content: space-between; } - .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 { - font-size: 1rem; } - .panel:not(:last-child) { - margin-bottom: 1.5rem; } - -.panel-heading, -.panel-tabs, -.panel-block { - border-bottom: 1px solid #dbdbdb; - border-left: 1px solid #dbdbdb; - border-right: 1px solid #dbdbdb; } - .panel-heading:first-child, - .panel-tabs:first-child, - .panel-block:first-child { - border-top: 1px solid #dbdbdb; } - -.panel-heading { - background-color: whitesmoke; - border-radius: 4px 4px 0 0; - color: #222222; - font-size: 1.25em; - font-weight: 300; - line-height: 1.25; - padding: 0.5em 0.75em; } - -.panel-tabs { - align-items: flex-end; - display: flex; - font-size: 0.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: #222222; } - .panel-list a:hover { - color: #2e63b8; } - -.panel-block { - align-items: center; - color: #222222; - display: flex; - justify-content: flex-start; - padding: 0.5em 0.75em; } - .panel-block input[type="checkbox"] { - margin-right: 0.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; } - -a.panel-block, -label.panel-block { - cursor: pointer; } - a.panel-block:hover, - label.panel-block:hover { - background-color: whitesmoke; } - -.panel-icon { - display: inline-block; - font-size: 14px; - height: 1em; - line-height: 1em; - text-align: center; - vertical-align: top; - width: 1em; - color: #7a7a7a; - margin-right: 0.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: #222222; - display: flex; - justify-content: center; - margin-bottom: -1px; - padding: 0.5em 1em; - vertical-align: top; } - .tabs a:hover { - border-bottom-color: #222222; - color: #222222; } - .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: 0.5em; } - .tabs .icon:last-child { - margin-left: 0.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: whitesmoke; - border-bottom-color: #dbdbdb; } - .tabs.is-boxed li.is-active a { - background-color: white; - border-color: #dbdbdb; - border-bottom-color: transparent !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: whitesmoke; - border-color: #b5b5b5; - z-index: 2; } - .tabs.is-toggle li + li { - margin-left: -1px; } - .tabs.is-toggle li:first-child a { - border-radius: 4px 0 0 4px; } - .tabs.is-toggle li:last-child a { - border-radius: 0 4px 4px 0; } - .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: 290486px; - border-top-left-radius: 290486px; - padding-left: 1.25em; } - .tabs.is-toggle.is-toggle-rounded li:last-child a { - border-bottom-right-radius: 290486px; - border-top-right-radius: 290486px; - padding-right: 1.25em; } - .tabs.is-small, #documenter .docs-sidebar form.docs-search > input.tabs { - font-size: 0.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: 0.75rem; } - .columns.is-mobile > .column.is-narrow { - flex: none; } - .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.33333%; } - .columns.is-mobile > .column.is-offset-1 { - margin-left: 8.33333%; } - .columns.is-mobile > .column.is-2 { - flex: none; - width: 16.66667%; } - .columns.is-mobile > .column.is-offset-2 { - margin-left: 16.66667%; } - .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.33333%; } - .columns.is-mobile > .column.is-offset-4 { - margin-left: 33.33333%; } - .columns.is-mobile > .column.is-5 { - flex: none; - width: 41.66667%; } - .columns.is-mobile > .column.is-offset-5 { - margin-left: 41.66667%; } - .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.33333%; } - .columns.is-mobile > .column.is-offset-7 { - margin-left: 58.33333%; } - .columns.is-mobile > .column.is-8 { - flex: none; - width: 66.66667%; } - .columns.is-mobile > .column.is-offset-8 { - margin-left: 66.66667%; } - .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.33333%; } - .columns.is-mobile > .column.is-offset-10 { - margin-left: 83.33333%; } - .columns.is-mobile > .column.is-11 { - flex: none; - width: 91.66667%; } - .columns.is-mobile > .column.is-offset-11 { - margin-left: 91.66667%; } - .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; } - .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.33333%; } - .column.is-offset-1-mobile { - margin-left: 8.33333%; } - .column.is-2-mobile { - flex: none; - width: 16.66667%; } - .column.is-offset-2-mobile { - margin-left: 16.66667%; } - .column.is-3-mobile { - flex: none; - width: 25%; } - .column.is-offset-3-mobile { - margin-left: 25%; } - .column.is-4-mobile { - flex: none; - width: 33.33333%; } - .column.is-offset-4-mobile { - margin-left: 33.33333%; } - .column.is-5-mobile { - flex: none; - width: 41.66667%; } - .column.is-offset-5-mobile { - margin-left: 41.66667%; } - .column.is-6-mobile { - flex: none; - width: 50%; } - .column.is-offset-6-mobile { - margin-left: 50%; } - .column.is-7-mobile { - flex: none; - width: 58.33333%; } - .column.is-offset-7-mobile { - margin-left: 58.33333%; } - .column.is-8-mobile { - flex: none; - width: 66.66667%; } - .column.is-offset-8-mobile { - margin-left: 66.66667%; } - .column.is-9-mobile { - flex: none; - width: 75%; } - .column.is-offset-9-mobile { - margin-left: 75%; } - .column.is-10-mobile { - flex: none; - width: 83.33333%; } - .column.is-offset-10-mobile { - margin-left: 83.33333%; } - .column.is-11-mobile { - flex: none; - width: 91.66667%; } - .column.is-offset-11-mobile { - margin-left: 91.66667%; } - .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; } - .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.33333%; } - .column.is-offset-1, .column.is-offset-1-tablet { - margin-left: 8.33333%; } - .column.is-2, .column.is-2-tablet { - flex: none; - width: 16.66667%; } - .column.is-offset-2, .column.is-offset-2-tablet { - margin-left: 16.66667%; } - .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.33333%; } - .column.is-offset-4, .column.is-offset-4-tablet { - margin-left: 33.33333%; } - .column.is-5, .column.is-5-tablet { - flex: none; - width: 41.66667%; } - .column.is-offset-5, .column.is-offset-5-tablet { - margin-left: 41.66667%; } - .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.33333%; } - .column.is-offset-7, .column.is-offset-7-tablet { - margin-left: 58.33333%; } - .column.is-8, .column.is-8-tablet { - flex: none; - width: 66.66667%; } - .column.is-offset-8, .column.is-offset-8-tablet { - margin-left: 66.66667%; } - .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.33333%; } - .column.is-offset-10, .column.is-offset-10-tablet { - margin-left: 83.33333%; } - .column.is-11, .column.is-11-tablet { - flex: none; - width: 91.66667%; } - .column.is-offset-11, .column.is-offset-11-tablet { - margin-left: 91.66667%; } - .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; } - .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.33333%; } - .column.is-offset-1-touch { - margin-left: 8.33333%; } - .column.is-2-touch { - flex: none; - width: 16.66667%; } - .column.is-offset-2-touch { - margin-left: 16.66667%; } - .column.is-3-touch { - flex: none; - width: 25%; } - .column.is-offset-3-touch { - margin-left: 25%; } - .column.is-4-touch { - flex: none; - width: 33.33333%; } - .column.is-offset-4-touch { - margin-left: 33.33333%; } - .column.is-5-touch { - flex: none; - width: 41.66667%; } - .column.is-offset-5-touch { - margin-left: 41.66667%; } - .column.is-6-touch { - flex: none; - width: 50%; } - .column.is-offset-6-touch { - margin-left: 50%; } - .column.is-7-touch { - flex: none; - width: 58.33333%; } - .column.is-offset-7-touch { - margin-left: 58.33333%; } - .column.is-8-touch { - flex: none; - width: 66.66667%; } - .column.is-offset-8-touch { - margin-left: 66.66667%; } - .column.is-9-touch { - flex: none; - width: 75%; } - .column.is-offset-9-touch { - margin-left: 75%; } - .column.is-10-touch { - flex: none; - width: 83.33333%; } - .column.is-offset-10-touch { - margin-left: 83.33333%; } - .column.is-11-touch { - flex: none; - width: 91.66667%; } - .column.is-offset-11-touch { - margin-left: 91.66667%; } - .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; } - .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.33333%; } - .column.is-offset-1-desktop { - margin-left: 8.33333%; } - .column.is-2-desktop { - flex: none; - width: 16.66667%; } - .column.is-offset-2-desktop { - margin-left: 16.66667%; } - .column.is-3-desktop { - flex: none; - width: 25%; } - .column.is-offset-3-desktop { - margin-left: 25%; } - .column.is-4-desktop { - flex: none; - width: 33.33333%; } - .column.is-offset-4-desktop { - margin-left: 33.33333%; } - .column.is-5-desktop { - flex: none; - width: 41.66667%; } - .column.is-offset-5-desktop { - margin-left: 41.66667%; } - .column.is-6-desktop { - flex: none; - width: 50%; } - .column.is-offset-6-desktop { - margin-left: 50%; } - .column.is-7-desktop { - flex: none; - width: 58.33333%; } - .column.is-offset-7-desktop { - margin-left: 58.33333%; } - .column.is-8-desktop { - flex: none; - width: 66.66667%; } - .column.is-offset-8-desktop { - margin-left: 66.66667%; } - .column.is-9-desktop { - flex: none; - width: 75%; } - .column.is-offset-9-desktop { - margin-left: 75%; } - .column.is-10-desktop { - flex: none; - width: 83.33333%; } - .column.is-offset-10-desktop { - margin-left: 83.33333%; } - .column.is-11-desktop { - flex: none; - width: 91.66667%; } - .column.is-offset-11-desktop { - margin-left: 91.66667%; } - .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; } - .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.33333%; } - .column.is-offset-1-widescreen { - margin-left: 8.33333%; } - .column.is-2-widescreen { - flex: none; - width: 16.66667%; } - .column.is-offset-2-widescreen { - margin-left: 16.66667%; } - .column.is-3-widescreen { - flex: none; - width: 25%; } - .column.is-offset-3-widescreen { - margin-left: 25%; } - .column.is-4-widescreen { - flex: none; - width: 33.33333%; } - .column.is-offset-4-widescreen { - margin-left: 33.33333%; } - .column.is-5-widescreen { - flex: none; - width: 41.66667%; } - .column.is-offset-5-widescreen { - margin-left: 41.66667%; } - .column.is-6-widescreen { - flex: none; - width: 50%; } - .column.is-offset-6-widescreen { - margin-left: 50%; } - .column.is-7-widescreen { - flex: none; - width: 58.33333%; } - .column.is-offset-7-widescreen { - margin-left: 58.33333%; } - .column.is-8-widescreen { - flex: none; - width: 66.66667%; } - .column.is-offset-8-widescreen { - margin-left: 66.66667%; } - .column.is-9-widescreen { - flex: none; - width: 75%; } - .column.is-offset-9-widescreen { - margin-left: 75%; } - .column.is-10-widescreen { - flex: none; - width: 83.33333%; } - .column.is-offset-10-widescreen { - margin-left: 83.33333%; } - .column.is-11-widescreen { - flex: none; - width: 91.66667%; } - .column.is-offset-11-widescreen { - margin-left: 91.66667%; } - .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; } - .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.33333%; } - .column.is-offset-1-fullhd { - margin-left: 8.33333%; } - .column.is-2-fullhd { - flex: none; - width: 16.66667%; } - .column.is-offset-2-fullhd { - margin-left: 16.66667%; } - .column.is-3-fullhd { - flex: none; - width: 25%; } - .column.is-offset-3-fullhd { - margin-left: 25%; } - .column.is-4-fullhd { - flex: none; - width: 33.33333%; } - .column.is-offset-4-fullhd { - margin-left: 33.33333%; } - .column.is-5-fullhd { - flex: none; - width: 41.66667%; } - .column.is-offset-5-fullhd { - margin-left: 41.66667%; } - .column.is-6-fullhd { - flex: none; - width: 50%; } - .column.is-offset-6-fullhd { - margin-left: 50%; } - .column.is-7-fullhd { - flex: none; - width: 58.33333%; } - .column.is-offset-7-fullhd { - margin-left: 58.33333%; } - .column.is-8-fullhd { - flex: none; - width: 66.66667%; } - .column.is-offset-8-fullhd { - margin-left: 66.66667%; } - .column.is-9-fullhd { - flex: none; - width: 75%; } - .column.is-offset-9-fullhd { - margin-left: 75%; } - .column.is-10-fullhd { - flex: none; - width: 83.33333%; } - .column.is-offset-10-fullhd { - margin-left: 83.33333%; } - .column.is-11-fullhd { - flex: none; - width: 91.66667%; } - .column.is-offset-11-fullhd { - margin-left: 91.66667%; } - .column.is-12-fullhd { - flex: none; - width: 100%; } - .column.is-offset-12-fullhd { - margin-left: 100%; } } - -.columns { - margin-left: -0.75rem; - margin-right: -0.75rem; - margin-top: -0.75rem; } - .columns:last-child { - margin-bottom: -0.75rem; } - .columns:not(:last-child) { - margin-bottom: calc(1.5rem - 0.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: 0.25rem; } - @media screen and (max-width: 768px) { - .columns.is-variable.is-1-mobile { - --columnGap: 0.25rem; } } - @media screen and (min-width: 769px), print { - .columns.is-variable.is-1-tablet { - --columnGap: 0.25rem; } } - @media screen and (min-width: 769px) and (max-width: 1055px) { - .columns.is-variable.is-1-tablet-only { - --columnGap: 0.25rem; } } - @media screen and (max-width: 1055px) { - .columns.is-variable.is-1-touch { - --columnGap: 0.25rem; } } - @media screen and (min-width: 1056px) { - .columns.is-variable.is-1-desktop { - --columnGap: 0.25rem; } } - @media screen and (min-width: 1056px) and (max-width: 1215px) { - .columns.is-variable.is-1-desktop-only { - --columnGap: 0.25rem; } } - @media screen and (min-width: 1216px) { - .columns.is-variable.is-1-widescreen { - --columnGap: 0.25rem; } } - @media screen and (min-width: 1216px) and (max-width: 1407px) { - .columns.is-variable.is-1-widescreen-only { - --columnGap: 0.25rem; } } - @media screen and (min-width: 1408px) { - .columns.is-variable.is-1-fullhd { - --columnGap: 0.25rem; } } - .columns.is-variable.is-2 { - --columnGap: 0.5rem; } - @media screen and (max-width: 768px) { - .columns.is-variable.is-2-mobile { - --columnGap: 0.5rem; } } - @media screen and (min-width: 769px), print { - .columns.is-variable.is-2-tablet { - --columnGap: 0.5rem; } } - @media screen and (min-width: 769px) and (max-width: 1055px) { - .columns.is-variable.is-2-tablet-only { - --columnGap: 0.5rem; } } - @media screen and (max-width: 1055px) { - .columns.is-variable.is-2-touch { - --columnGap: 0.5rem; } } - @media screen and (min-width: 1056px) { - .columns.is-variable.is-2-desktop { - --columnGap: 0.5rem; } } - @media screen and (min-width: 1056px) and (max-width: 1215px) { - .columns.is-variable.is-2-desktop-only { - --columnGap: 0.5rem; } } - @media screen and (min-width: 1216px) { - .columns.is-variable.is-2-widescreen { - --columnGap: 0.5rem; } } - @media screen and (min-width: 1216px) and (max-width: 1407px) { - .columns.is-variable.is-2-widescreen-only { - --columnGap: 0.5rem; } } - @media screen and (min-width: 1408px) { - .columns.is-variable.is-2-fullhd { - --columnGap: 0.5rem; } } - .columns.is-variable.is-3 { - --columnGap: 0.75rem; } - @media screen and (max-width: 768px) { - .columns.is-variable.is-3-mobile { - --columnGap: 0.75rem; } } - @media screen and (min-width: 769px), print { - .columns.is-variable.is-3-tablet { - --columnGap: 0.75rem; } } - @media screen and (min-width: 769px) and (max-width: 1055px) { - .columns.is-variable.is-3-tablet-only { - --columnGap: 0.75rem; } } - @media screen and (max-width: 1055px) { - .columns.is-variable.is-3-touch { - --columnGap: 0.75rem; } } - @media screen and (min-width: 1056px) { - .columns.is-variable.is-3-desktop { - --columnGap: 0.75rem; } } - @media screen and (min-width: 1056px) and (max-width: 1215px) { - .columns.is-variable.is-3-desktop-only { - --columnGap: 0.75rem; } } - @media screen and (min-width: 1216px) { - .columns.is-variable.is-3-widescreen { - --columnGap: 0.75rem; } } - @media screen and (min-width: 1216px) and (max-width: 1407px) { - .columns.is-variable.is-3-widescreen-only { - --columnGap: 0.75rem; } } - @media screen and (min-width: 1408px) { - .columns.is-variable.is-3-fullhd { - --columnGap: 0.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: -0.75rem; - margin-right: -0.75rem; - margin-top: -0.75rem; } - .tile.is-ancestor:last-child { - margin-bottom: -0.75rem; } - .tile.is-ancestor:not(:last-child) { - margin-bottom: 0.75rem; } - .tile.is-child { - margin: 0 !important; } - .tile.is-parent { - padding: 0.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.33333%; } - .tile.is-2 { - flex: none; - width: 16.66667%; } - .tile.is-3 { - flex: none; - width: 25%; } - .tile.is-4 { - flex: none; - width: 33.33333%; } - .tile.is-5 { - flex: none; - width: 41.66667%; } - .tile.is-6 { - flex: none; - width: 50%; } - .tile.is-7 { - flex: none; - width: 58.33333%; } - .tile.is-8 { - flex: none; - width: 66.66667%; } - .tile.is-9 { - flex: none; - width: 75%; } - .tile.is-10 { - flex: none; - width: 83.33333%; } - .tile.is-11 { - flex: none; - width: 91.66667%; } - .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: white; - 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: white; } } - .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 { - 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: white; } - .hero.is-white.is-bold { - background-image: linear-gradient(141deg, #e6e6e6 0%, white 71%, white 100%); } - @media screen and (max-width: 768px) { - .hero.is-white.is-bold .navbar-menu { - background-image: linear-gradient(141deg, #e6e6e6 0%, white 71%, white 100%); } } - .hero.is-black { - background-color: #0a0a0a; - color: white; } - .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: white; } - .hero.is-black .subtitle { - color: rgba(255, 255, 255, 0.9); } - .hero.is-black .subtitle a:not(.button), - .hero.is-black .subtitle strong { - color: white; } - @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: black; - color: white; } - .hero.is-black .tabs a { - color: white; - opacity: 0.9; } - .hero.is-black .tabs a:hover { - opacity: 1; } - .hero.is-black .tabs li.is-active a { - opacity: 1; } - .hero.is-black .tabs.is-boxed a, .hero.is-black .tabs.is-toggle a { - color: white; } - .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: white; - border-color: white; - color: #0a0a0a; } - .hero.is-black.is-bold { - background-image: linear-gradient(141deg, black 0%, #0a0a0a 71%, #181616 100%); } - @media screen and (max-width: 768px) { - .hero.is-black.is-bold .navbar-menu { - background-image: linear-gradient(141deg, black 0%, #0a0a0a 71%, #181616 100%); } } - .hero.is-light { - background-color: whitesmoke; - color: #363636; } - .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: #363636; } - .hero.is-light .subtitle { - color: rgba(54, 54, 54, 0.9); } - .hero.is-light .subtitle a:not(.button), - .hero.is-light .subtitle strong { - color: #363636; } - @media screen and (max-width: 1055px) { - .hero.is-light .navbar-menu { - background-color: whitesmoke; } } - .hero.is-light .navbar-item, - .hero.is-light .navbar-link { - color: rgba(54, 54, 54, 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: #363636; } - .hero.is-light .tabs a { - color: #363636; - opacity: 0.9; } - .hero.is-light .tabs a:hover { - opacity: 1; } - .hero.is-light .tabs li.is-active a { - opacity: 1; } - .hero.is-light .tabs.is-boxed a, .hero.is-light .tabs.is-toggle a { - color: #363636; } - .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: #363636; - border-color: #363636; - color: whitesmoke; } - .hero.is-light.is-bold { - background-image: linear-gradient(141deg, #dfd8d9 0%, whitesmoke 71%, white 100%); } - @media screen and (max-width: 768px) { - .hero.is-light.is-bold .navbar-menu { - background-image: linear-gradient(141deg, #dfd8d9 0%, whitesmoke 71%, white 100%); } } - .hero.is-dark, .content kbd.hero { - background-color: #363636; - color: whitesmoke; } - .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: whitesmoke; } - .hero.is-dark .subtitle, .content kbd.hero .subtitle { - color: rgba(245, 245, 245, 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: whitesmoke; } - @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(245, 245, 245, 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: whitesmoke; } - .hero.is-dark .tabs a, .content kbd.hero .tabs a { - color: whitesmoke; - 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 { - 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: whitesmoke; } - .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, .content kbd.hero .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, .content kbd.hero .tabs.is-toggle li.is-active a:hover { - background-color: whitesmoke; - border-color: whitesmoke; - 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 { - 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, .docstring > section > a.hero.docs-sourcelink .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, .docstring > section > a.hero.docs-sourcelink .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 { - 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: #118fe4; - 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 { - 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, #04a6d7 0%, #209cee 71%, #3287f5 100%); } - @media screen and (max-width: 768px) { - .hero.is-info.is-bold .navbar-menu { - background-image: linear-gradient(141deg, #04a6d7 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 { - 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: #ffd83d; - 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 { - 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, #ffaf24 0%, #ffdd57 71%, #fffa70 100%); } - @media screen and (max-width: 768px) { - .hero.is-warning.is-bold .navbar-menu { - background-image: linear-gradient(141deg, #ffaf24 0%, #ffdd57 71%, #fffa70 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 { - 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-bottom: 1.5rem; - padding-top: 1.5rem; } - @media screen and (min-width: 769px), print { - .hero.is-medium .hero-body { - padding-bottom: 9rem; - padding-top: 9rem; } } - @media screen and (min-width: 769px), print { - .hero.is-large .hero-body { - padding-bottom: 18rem; - padding-top: 18rem; } } - .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; } - -.section { - padding: 3rem 1.5rem; } - @media screen and (min-width: 1056px) { - .section.is-medium { - padding: 9rem 1.5rem; } - .section.is-large { - padding: 18rem 1.5rem; } } - -.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: #222222; } - -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 5 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; } - -.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: 0.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: #b8dffa; - 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: #9beeb8; - 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: #ff857e; - border-color: #da0b00; } - .admonition.is-danger > .admonition-header { - background-color: #da0b00; - color: #fff; } - .admonition.is-danger > .admonition-body { - color: #fff; } - .admonition.is-compat { - background-color: #99e6f0; - 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.75em; - position: relative; } - .admonition-header:before { - font-family: "Font Awesome 5 Free"; - font-weight: 900; - margin-right: 0.75em; - content: "\f06a"; } - -.admonition-body { - color: #222222; - padding: 1em 1.25em; } - .admonition-body pre { - background-color: whitesmoke; } - .admonition-body code { - background-color: rgba(0, 0, 0, 0.05); } - -.docstring { - margin-bottom: 1em; - background-color: transparent; - border: 1px solid #dbdbdb; - box-shadow: 2px 2px 3px rgba(10, 10, 10, 0.1); - max-width: 100%; } - .docstring > header { - display: flex; - flex-grow: 1; - align-items: stretch; - padding: 0.75rem; - background-color: whitesmoke; - box-shadow: 0 1px 2px rgba(10, 10, 10, 0.1); - box-shadow: none; - border-bottom: 1px solid #dbdbdb; } - .docstring > header code { - background-color: transparent; } - .docstring > header .docstring-binding { - margin-right: 0.3em; } - .docstring > header .docstring-category { - margin-left: 0.3em; } - .docstring > section { - position: relative; - padding: 1rem 1.25rem; - 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: 0.625rem; - bottom: 0.5rem; } - .docstring:hover > section > a.docs-sourcelink { - opacity: 0.2; } - .docstring > section:hover a.docs-sourcelink { - opacity: 1; } - -.documenter-example-output { - background-color: white; } - -.content pre { - border: 1px solid #dbdbdb; } - -.content code { - font-weight: inherit; } - -.content a code { - color: #2e63b8; } - -.content h1 code, .content h2 code, .content h3 code, .content h4 code, .content h5 code, .content h6 code { - color: #222222; } - -.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; } - -.breadcrumb a.is-disabled { - cursor: default; - pointer-events: none; } - .breadcrumb a.is-disabled, .breadcrumb a.is-disabled:hover { - color: #222222; } - -.hljs { - background: initial !important; - padding: initial !important; } - -.katex .katex-mathml { - top: 0; - right: 0; } - -html { - -moz-osx-font-smoothing: auto; - -webkit-font-smoothing: auto; } - -/* This file contain the overall layout. - * - * The main container is
    that is identified by id #documenter. - */ -#documenter .docs-main > article { - overflow-wrap: break-word; } - -@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: white; - 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; } - #documenter .docs-main header.docs-navbar .docs-right { - display: flex; - white-space: nowrap; } - #documenter .docs-main header.docs-navbar .docs-right .docs-icon, #documenter .docs-main header.docs-navbar .docs-right .docs-label, #documenter .docs-main header.docs-navbar .docs-right .docs-sidebar-button { - display: inline-block; } - #documenter .docs-main header.docs-navbar .docs-right .docs-label { - padding: 0; - margin-left: 0.3em; } - #documenter .docs-main header.docs-navbar .docs-right .docs-settings-button { - margin: auto 0 auto 1rem; } - #documenter .docs-main header.docs-navbar .docs-right .docs-sidebar-button { - font-size: 1.5rem; - margin: auto 0 auto 1rem; } - #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; - /* For Headroom.js */ - transition-property: top, box-shadow; - -webkit-transition-property: top, box-shadow; - /* Safari */ - transition-duration: 0.3s; - -webkit-transition-duration: 0.3s; - /* Safari */ } - #documenter .docs-main header.docs-navbar.headroom--not-top { - box-shadow: 0.2rem 0rem 0.4rem #bbb; - transition-duration: 0.7s; - -webkit-transition-duration: 0.7s; - /* Safari */ } - #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; - /* Safari */ } } - -#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: whitesmoke; - 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; - /* Setting up a nicer theme style for the scrollbar */ } - #documenter .docs-sidebar.visible { - left: 0; - box-shadow: 0.4rem 0rem 0.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-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; - /* Managing collapsible submenus */ } - #documenter .docs-sidebar ul.docs-menu > li > .tocitem { - font-weight: bold; } - #documenter .docs-sidebar ul.docs-menu > li li { - font-size: 0.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: 0.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 5 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: whitesmoke; } - #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: white; } - #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem, #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover { - background-color: white; - 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: 0.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; } - @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: #cccccc; } } - @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: #cccccc; } } - -#documenter .docs-main #documenter-search-info { - margin-bottom: 1rem; } - -#documenter .docs-main #documenter-search-results { - list-style-type: circle; - list-style-position: outside; } - #documenter .docs-main #documenter-search-results li { - margin-left: 2rem; } - #documenter .docs-main #documenter-search-results .docs-highlight { - background-color: yellow; } - -/* - -Original highlight.js style (c) Ivan Sagalaev - -*/ -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #F0F0F0; } - -/* Base color: saturation 0; */ -.hljs, -.hljs-subst { - color: #444; } - -.hljs-comment { - color: #888888; } - -.hljs-keyword, -.hljs-attribute, -.hljs-selector-tag, -.hljs-meta-keyword, -.hljs-doctag, -.hljs-name { - font-weight: bold; } - -/* User color: hue: 0 */ -.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-selector-pseudo { - color: #BC6060; } - -/* Language color: hue: 90; */ -.hljs-literal { - color: #78A960; } - -.hljs-built_in, -.hljs-bullet, -.hljs-code, -.hljs-addition { - color: #397300; } - -/* Meta color: hue: 200 */ -.hljs-meta { - color: #1f7199; } - -.hljs-meta-string { - color: #4d99bf; } - -/* Misc effects */ -.hljs-emphasis { - font-style: italic; } - -.hljs-strong { - font-weight: bold; } diff --git a/docs/build/assets/themeswap.js b/docs/build/assets/themeswap.js deleted file mode 100644 index d466684..0000000 --- a/docs/build/assets/themeswap.js +++ /dev/null @@ -1,42 +0,0 @@ -// Small function to quickly swap out themes. Gets put into the tag.. -function set_theme_from_local_storage() { - // Browser does not support Web Storage, bail early. - if(typeof(window.localStorage) === "undefined") return; - // Get the user-picked theme from localStorage. May be `null`, which means the default - // theme. - var theme = window.localStorage.getItem("documenter-theme"); - // 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 = []; - 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. - var isprimary = (ss.ownerNode.getAttribute("data-theme-primary") !== null); - // If we find a matching theme (and it's not the default), we'll set active to non-null - if(!isprimary && themename === theme) active = i; - // Store the style sheets of inactive themes so that we could disable them - if(themename !== theme) disabled.push(ss); - } - 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; - // and (2) disable all the other theme stylesheets - disabled.forEach(function(ss){ - ss.disabled = true; - }); - } -} -set_theme_from_local_storage(); diff --git a/docs/build/index.html b/docs/build/index.html deleted file mode 100644 index f7296d2..0000000 --- a/docs/build/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -About · Julia Generalized Disjunctive Programming
    diff --git a/docs/build/search/index.html b/docs/build/search/index.html deleted file mode 100644 index 970efed..0000000 --- a/docs/build/search/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Search · Julia Generalized Disjunctive Programming

    Loading search...

      diff --git a/docs/build/search_index.js b/docs/build/search_index.js deleted file mode 100644 index f0570ac..0000000 --- a/docs/build/search_index.js +++ /dev/null @@ -1,3 +0,0 @@ -var documenterSearchIndex = {"docs": -[{"location":"#Overview","page":"About","title":"Overview","text":"","category":"section"},{"location":"","page":"About","title":"About","text":"JuGDP.jl","category":"page"}] -} diff --git a/examples/ex1.jl b/examples/ex1.jl index 659a917..b6810d7 100644 --- a/examples/ex1.jl +++ b/examples/ex1.jl @@ -1,34 +1,77 @@ using JuMP using DisjunctiveProgramming +using HiGHS -m = Model() +## Example 1: Linear GDP + +# Disjunction Method 1: Assign Logical Variables Explicitly +m = GDPModel() @variable(m, -5 ≤ x ≤ 10) -@disjunction( - m, - 0 ≤ x ≤ 3, - 5 ≤ x ≤ 9, - reformulation=:big_m, - name=:y -) -@proposition(m, y[1] ∨ y[2]) #this is a redundant proposition +@variable(m, Y[1:2], LogicalVariable) +@constraint(m, 0 ≤ x ≤ 3, DisjunctConstraint(Y[1])) +@constraint(m, 5 ≤ x, DisjunctConstraint(Y[2])) +@constraint(m, x ≤ 9, DisjunctConstraint(Y[2])) +@disjunction(m, [Y[1], Y[2]]) +@constraint(m, Y in Exactly(1)) +@objective(m, Max, x) +# Reformulate logical variables and logical constraints print(m) +# Max x +# Subject to +# x ≥ -5 +# x ≤ 10 + +## Indicator Constraints reformulation (NOTE: HiGHS doesn't support indicator constraints) +reformulate_model(m, Indicator()) +print(m) +# Max x +# Subject to +# Y[1] + Y[2] = 1 +# Y[2] => {-x ≤ -5} +# Y[2] => {x ≤ 9} +# x ≥ -5 +# x ≤ 10 +# Y[1] binary +# Y[2] binary +# Y[1] => {x ∈ [0, 3]} -# ┌ Warning: disj_y[1] : x in [0.0, 3.0] uses the `MOI.Interval` set. Each instance of the interval set has been split into two constraints, one for each bound. -# ┌ Warning: disj_y[2] : x in [5.0, 9.0] uses the `MOI.Interval` set. Each instance of the interval set has been split into two constraints, one for each bound. -# Feasibility +## BigM reformulation +set_optimizer(m, HiGHS.Optimizer) +optimize!(m, method = BigM()) +print(m) +# Max x +# Subject to +# Y[1] + Y[2] = 1 +# x - 5 Y[1] ≥ -5 +# x + 7 Y[1] ≤ 10 +# -x + 10 Y[2] ≤ 5 +# x + Y[2] ≤ 10 +# x ≥ -5 +# x ≤ 10 +# Y[1] binary +# Y[2] binary + +## Hull reformulation +optimize!(m, method = Hull()) +print(m) +# Max x # Subject to -# XOR(disj_y) : y[1] + y[2] == 1.0 <- XOR constraint -# y[1] ∨ y[2] : y[1] + y[2] >= 1.0 <- reformulated logical proposition (name is the proposition) -# disj_y[1,lb] : -x + 5 y[1] <= 5.0 <- left-side of constraint in 1st disjunct (name is assigned to disj_y[1][lb]) -# disj_y[1,ub] : x + 7 y[1] <= 10.0 <- right-side of constraint in 1st disjunct (name is assigned to disj_y[1][ub]) -# disj_y[2,lb] : -x + 10 y[2] <= 5.0 <- left-side of constraint in 2nd disjunct (name is assigned to disj_y[2][lb]) -# disj_y[2,ub] : x + y[2] <= 10.0 <- right-side of constraint in 2nd disjunct (name is assigned to disj_y[2][ub]) -# x >= -5.0 <- variable lower bound -# x <= 10.0 <- variable upper bound -# y[1] >= 0.0 <- lower bound on binary -# y[2] >= 0.0 <- lower bound on binary -# y[1] <= 1.0 <- upper bound on binary -# y[2] <= 1.0 <- upper bound on binary -# y[1] binary <- indicator variable (1st disjunct) is binary -# y[2] binary <- indicator variable (2nd disjunct) is binary \ No newline at end of file +# -x + x_Y[1] + x_Y[2] = 0 +# Y[1] + Y[2] = 1 +# x_Y[1] ≥ 0 +# x_Y[1]_lower_bound : -5 Y[1] - x_Y[1] ≤ 0 +# x_Y[1]_upper_bound : -10 Y[1] + x_Y[1] ≤ 0 +# x_Y[2]_lower_bound : -5 Y[2] - x_Y[2] ≤ 0 +# x_Y[2]_upper_bound : -10 Y[2] + x_Y[2] ≤ 0 +# -3 Y[1] + x_Y[1] ≤ 0 +# 5 Y[2] - x_Y[2] ≤ 0 +# -9 Y[2] + x_Y[2] ≤ 0 +# x ≥ -5 +# x_Y[1] ≥ -5 +# x_Y[2] ≥ -5 +# x ≤ 10 +# x_Y[1] ≤ 10 +# x_Y[2] ≤ 10 +# Y[1] binary +# Y[2] binary \ No newline at end of file diff --git a/examples/ex2.jl b/examples/ex2.jl index f7d9cc6..d23a540 100644 --- a/examples/ex2.jl +++ b/examples/ex2.jl @@ -1,42 +1,80 @@ -# https://optimization.mccormick.northwestern.edu/index.php/Disjunctive_inequalities +# https://optimization.cbe.cornell.edu/index.php?title=Disjunctive_inequalities#Big-M_Reformulation[1][2] using JuMP using DisjunctiveProgramming +using HiGHS -m = Model() -@variable(m, -5 ≤ x[1:2] ≤ 10) -@disjunction( - m, - begin - con1[i=1:2], 0 ≤ x[i] ≤ [3,4][i] - end, - begin - con2[i=1:2], [5,4][i] ≤ x[i] ≤ [9,6][i] - end, - reformulation = :big_m, - name = :y -) +m = GDPModel(HiGHS.Optimizer) +@variable(m, 0 ≤ x[1:2] ≤ 20) +@variable(m, Y[1:2], LogicalVariable) +@constraint(m, [i = 1:2], [2,5][i] ≤ x[i] ≤ [6,9][i], DisjunctConstraint(Y[1])) +@constraint(m, [i = 1:2], [8,10][i] ≤ x[i] ≤ [11,15][i], DisjunctConstraint(Y[2])) +@disjunction(m, Y) +@constraint(m, Y in Exactly(1)) #logical constraint +@objective(m, Max, sum(x)) print(m) +# Max x[1] + x[2] +# Subject to +# x[1] ≥ 0 +# x[2] ≥ 0 +# x[1] ≤ 20 +# x[2] ≤ 20 -# ┌ Warning: [con1[1] : x[1] in [0.0, 3.0], con1[2] : x[2] in [0.0, 4.0]] uses the `MOI.Interval` set. Each instance of the interval set has been split into two constraints, one for each bound. -# ┌ Warning: [con2[1] : x[1] in [5.0, 9.0], con2[2] : x[2] in [4.0, 6.0]] uses the `MOI.Interval` set. Each instance of the interval set has been split into two constraints, one for each bound. -# Feasibility +## +optimize!(m, method = BigM(100, false)) #specify M value and disable M-tightening +print(m) +# Max x[1] + x[2] +# Subject to +# Y[1] + Y[2] = 1 +# x[1] - 100 Y[1] ≥ -98 +# x[2] - 100 Y[1] ≥ -95 +# x[1] - 100 Y[2] ≥ -92 +# x[2] - 100 Y[2] ≥ -90 +# x[1] + 100 Y[1] ≤ 106 +# x[2] + 100 Y[1] ≤ 109 +# x[1] + 100 Y[2] ≤ 111 +# x[2] + 100 Y[2] ≤ 115 +# x[1] ≥ 0 +# x[2] ≥ 0 +# x[1] ≤ 20 +# x[2] ≤ 20 +# Y[1] binary +# Y[2] binary + +## +optimize!(m, method = Hull()) +print(m) +# Max x[1] + x[2] # Subject to -# XOR(disj_y) : y[1] + y[2] == 1.0 <- XOR constraint -# con1[1,lb] : -x[1] + 5 y[1] <= 5.0 <- left-side of con1[1] -# con1[1,ub] : x[1] + 7 y[1] <= 10.0 <- right-side of con1[1] -# con1[2,lb] : -x[2] + 5 y[1] <= 5.0 <- left-side of con1[2] -# con1[2,ub] : x[2] + 6 y[1] <= 10.0 <- right-side of con1[2] -# con2[1,lb] : -x[1] + 10 y[2] <= 5.0 <- left-side of con2[1] -# con2[1,ub] : x[1] + y[2] <= 10.0 <- right-side of con2[1] -# con2[2,lb] : -x[2] + 9 y[2] <= 5.0 <- left-side of con2[2] -# con2[2,ub] : x[2] + 4 y[2] <= 10.0 <- right-side of con2[2] -# x[1] >= -5.0 <- varaible bounds -# x[2] >= -5.0 <- variable bounds -# x[1] <= 10.0 <- variable bounds -# x[2] <= 10.0 <- variable bounds -# y[1] >= 0.0 <- lower bound on binary -# y[2] >= 0.0 <- lower bound on binary -# y[1] <= 1.0 <- upper bound on binary -# y[2] <= 1.0 <- upper bound on binary -# y[1] binary <- indicator variable (1st disjunct) is binary -# y[2] binary <- indicator variable (2nd disjunct) is binary \ No newline at end of file +# -x[2] + x[2]_Y[1] + x[2]_Y[2] = 0 +# -x[1] + x[1]_Y[1] + x[1]_Y[2] = 0 +# Y[1] + Y[2] = 1 +# -2 Y[1] + x[1]_Y[1] ≥ 0 +# -5 Y[1] + x[2]_Y[1] ≥ 0 +# -8 Y[2] + x[1]_Y[2] ≥ 0 +# -10 Y[2] + x[2]_Y[2] ≥ 0 +# x[2]_Y[1]_lower_bound : -x[2]_Y[1] ≤ 0 +# x[2]_Y[1]_upper_bound : -20 Y[1] + x[2]_Y[1] ≤ 0 +# x[1]_Y[1]_lower_bound : -x[1]_Y[1] ≤ 0 +# x[1]_Y[1]_upper_bound : -20 Y[1] + x[1]_Y[1] ≤ 0 +# x[2]_Y[2]_lower_bound : -x[2]_Y[2] ≤ 0 +# x[2]_Y[2]_upper_bound : -20 Y[2] + x[2]_Y[2] ≤ 0 +# x[1]_Y[2]_lower_bound : -x[1]_Y[2] ≤ 0 +# x[1]_Y[2]_upper_bound : -20 Y[2] + x[1]_Y[2] ≤ 0 +# -6 Y[1] + x[1]_Y[1] ≤ 0 +# -9 Y[1] + x[2]_Y[1] ≤ 0 +# -11 Y[2] + x[1]_Y[2] ≤ 0 +# -15 Y[2] + x[2]_Y[2] ≤ 0 +# x[1] ≥ 0 +# x[2] ≥ 0 +# x[2]_Y[1] ≥ 0 +# x[1]_Y[1] ≥ 0 +# x[2]_Y[2] ≥ 0 +# x[1]_Y[2] ≥ 0 +# x[1] ≤ 20 +# x[2] ≤ 20 +# x[2]_Y[1] ≤ 20 +# x[1]_Y[1] ≤ 20 +# x[2]_Y[2] ≤ 20 +# x[1]_Y[2] ≤ 20 +# Y[1] binary +# Y[2] binary \ No newline at end of file diff --git a/examples/ex3.jl b/examples/ex3.jl index c41f799..39481be 100644 --- a/examples/ex3.jl +++ b/examples/ex3.jl @@ -1,45 +1,57 @@ using JuMP using DisjunctiveProgramming -m = Model() +m = GDPModel() @variable(m, -5 ≤ x ≤ 10) -@disjunction( - m, - begin - exp(x) ≤ 2 - -3 ≤ x - end, - begin - 3 ≤ exp(x) - 5 ≤ x - end, - reformulation=:hull, - name=:z -) +@variable(m, Y[1:2], LogicalVariable) +@constraint(m, exp(x) <= 2, DisjunctConstraint(Y[1])) +@constraint(m, x >= -3, DisjunctConstraint(Y[1])) +@constraint(m, exp(x) >= 3, DisjunctConstraint(Y[2])) +@constraint(m, x >= 5, DisjunctConstraint(Y[2])) +@disjunction(m, Y) +@constraint(m, Y in Exactly(1)) #logical constraint +@objective(m, Max, x) print(m) +# Max x +# Subject to +# x ≥ -5 +# x ≤ 10 -# Feasibility +## +reformulate_model(m, BigM()) +print(m) +# Max x +# Subject to +# (exp(x) - 3.0) + (-1000000000 Y[2] + 1000000000) ≥ 0 +# (exp(x) - 2.0) - (-1000000000 Y[1] + 1000000000) ≤ 0 +# Y[1] + Y[2] = 1 +# x - 2 Y[1] ≥ -5 +# x - 10 Y[2] ≥ -5 +# x ≥ -5 +# x ≤ 10 +# Y[1] binary +# Y[2] binary + +## +reformulate_model(m, Hull()) +print(m) +# Max x # Subject to -# XOR(disj_z) : z[1] + z[2] == 1.0 <- XOR constraint -# x_aggregation : x - x_z1 - x_z2 == 0.0 <- aggregation of disaggregated variables -# x_z1_lb : -5 z[1] - x_z1 <= 0.0 <- lower-bound constraint on disaggregated variable x_z1 (x in 1st disjunct) -# x_z1_ub : -10 z[1] + x_z1 <= 0.0 <- upper-bound constraint on disaggregated variable x_z1 (x in 1st disjunct) -# x_z2_lb : -5 z[2] - x_z2 <= 0.0 <- lower-bound constraint on disaggregated variable x_z2 (x in 2nd disjunct) -# x_z2_ub : -10 z[2] + x_z2 <= 0.0 <- upper-bound constraint on disaggregated variable x_z2 (x in 2nd disjunct) -# x >= -5.0 <- lower-bound on x -# x_z1 >= -5.0 <- lower-bound on x_z1 (disaggregated x in 1st disjunct) -# x_z2 >= -5.0 <- lower-bound on x_z2 (disaggregated x in 2nd disjunct) -# x <= 10.0 <- upper-bound on x -# x_z1 <= 10.0 <- upper-bound on x_z1 (disaggregated x in 1st disjunct) -# x_z2 <= 10.0 <- upper-bound on x_z2 (disaggregated x in 2nd disjunct) -# z[1] >= 0.0 <- lower bound on binary -# z[2] >= 0.0 <- lower bound on binary -# z[1] <= 1.0 <- upper bound on binary -# z[2] <= 1.0 <- upper bound on binary -# z[1] binary <- indicator variable (1st disjunct) is binary -# z[2] binary <- indicator variable (2nd disjunct) is binary -# Perspective Functions: -# (-1.0e-6 + -1.9999989999999999 * z[1]) + (1.0e-6 + 0.999999 * z[1]) * exp(x_z1 / (1.0e-6 + 0.999999 * z[1])) <= 0 -# (1.0000000000000002e-6 + 2.999999 * z[2]) + (-1.0e-6 + -0.999999 * z[2]) * exp(x_z2 / (1.0e-6 + 0.999999 * z[2])) <= 0 -# -1.0 * x_z1 + -3.0 * z[1] <= 0 -# -1.0 * x_z2 + 5.0 * z[2] <= 0 \ No newline at end of file +# (((0.999999 Y[2] + 1.0e-6) * (exp(x_Y[2] / (0.999999 Y[2] + 1.0e-6)) - 3.0)) - (2.0e-6 Y[2] - 2.0e-6)) - (0) ≥ 0 +# (((0.999999 Y[1] + 1.0e-6) * (exp(x_Y[1] / (0.999999 Y[1] + 1.0e-6)) - 2.0)) - (1.0e-6 Y[1] - 1.0e-6)) - (0) ≤ 0 +# -x + x_Y[1] + x_Y[2] = 0 +# Y[1] + Y[2] = 1 +# 3 Y[1] + x_Y[1] ≥ 0 +# -5 Y[2] + x_Y[2] ≥ 0 +# x_Y[1]_lower_bound : -5 Y[1] - x_Y[1] ≤ 0 +# x_Y[1]_upper_bound : -10 Y[1] + x_Y[1] ≤ 0 +# x_Y[2]_lower_bound : -5 Y[2] - x_Y[2] ≤ 0 +# x_Y[2]_upper_bound : -10 Y[2] + x_Y[2] ≤ 0 +# x ≥ -5 +# x_Y[1] ≥ -5 +# x_Y[2] ≥ -5 +# x ≤ 10 +# x_Y[1] ≤ 10 +# x_Y[2] ≤ 10 +# Y[1] binary +# Y[2] binary \ No newline at end of file diff --git a/examples/ex4.jl b/examples/ex4.jl new file mode 100644 index 0000000..77ec314 --- /dev/null +++ b/examples/ex4.jl @@ -0,0 +1,26 @@ +using JuMP +using DisjunctiveProgramming + +# Example with proposition reformulation +# Proposition: +# ¬((Y[1] ∧ ¬Y[2]) ⇔ (Y[3] ∨ Y[4])) + +m = GDPModel() +@variable(m, Y[1:4], LogicalVariable) +@constraint(m, ¬((Y[1] ∧ ¬Y[2]) ⇔ (Y[3] ∨ Y[4])) ∈ IsTrue()) +reformulate_model(m, BigM()) +print(m) +# Feasibility +# Subject to +# -Y[1] ≥ -1 +# Y[2] ≥ 0 +# -Y[1] + Y[2] - Y[3] ≥ -1 +# Y[4] ≥ 0 +# Y[1] + Y[3] + Y[4] ≥ 1 +# -Y[2] + Y[3] + Y[4] ≥ 0 +# Y[3] ≥ 0 +# -Y[1] + Y[2] - Y[4] ≥ -1 +# Y[1] binary +# Y[2] binary +# Y[3] binary +# Y[4] binary \ No newline at end of file diff --git a/examples/ex5.jl b/examples/ex5.jl new file mode 100644 index 0000000..20b5549 --- /dev/null +++ b/examples/ex5.jl @@ -0,0 +1,35 @@ +# https://arxiv.org/pdf/2303.04375.pdf + +using JuMP +using DisjunctiveProgramming + +## +m = GDPModel() +@variable(m, 1 ≤ x[1:2] ≤ 9) +@variable(m, Y[1:2], LogicalVariable) +@variable(m, W[1:2], LogicalVariable) +@objective(m, Max, sum(x)) +@constraint(m, y1[i=1:2], [1,4][i] ≤ x[i] ≤ [3,6][i], DisjunctConstraint(Y[1])) +@constraint(m, w1[i=1:2], [1,5][i] ≤ x[i] ≤ [2,6][i], DisjunctConstraint(W[1])) +@constraint(m, w2[i=1:2], [2,4][i] ≤ x[i] ≤ [3,5][i], DisjunctConstraint(W[2])) +@constraint(m, y2[i=1:2], [8,1][i] ≤ x[i] ≤ [9,2][i], DisjunctConstraint(Y[2])) +@disjunction(m, inner, [W[1], W[2]], DisjunctConstraint(Y[1])) +@disjunction(m, outer, [Y[1], Y[2]]) +@constraint(m, Y in Exactly(1)) +@constraint(m, W in Exactly(Y[1])) + +## +reformulate_model(m, BigM()) +print(m) + +## +reformulate_model(m, Hull()) +print(m) + +## +using Polyhedra, CDDLib, Plots +relax_integrality(m) +lib = CDDLib.Library(:exact) +poly = polyhedron(vrep(polyhedron(m, lib)),lib) +proj = project(poly,1:2) +plot(proj, xlims = (0,10), ylims = (0,7), xticks = 0:10, yticks = 0:10) \ No newline at end of file diff --git a/examples/ex6.jl b/examples/ex6.jl new file mode 100644 index 0000000..0fb3ea2 --- /dev/null +++ b/examples/ex6.jl @@ -0,0 +1,60 @@ +using JuMP +using DisjunctiveProgramming + +## +m = GDPModel() +@variable(m, -5 <= x[1:3] <= 5) + +@variable(m, y[1:2], LogicalVariable) +@constraint(m, x[1] <= -2, DisjunctConstraint(y[1])) +@constraint(m, x[1] >= 2, DisjunctConstraint(y[2])) +@constraint(m, x[2] == -1, DisjunctConstraint(y[2])) +@constraint(m, x[3] == 1, DisjunctConstraint(y[2])) +@disjunction(m, y) +@constraint(m, y in Exactly(1)) + +@variable(m, w[1:2], LogicalVariable) +@constraint(m, x[2] <= -3, DisjunctConstraint(w[1])) +@constraint(m, x[2] >= 3, DisjunctConstraint(w[2])) +@constraint(m, x[3] == 0, DisjunctConstraint(w[2])) +@disjunction(m, w, DisjunctConstraint(y[1])) +@constraint(m, w in Exactly(y[1])) + +@variable(m, z[1:2], LogicalVariable) +@constraint(m, x[3] <= -4, DisjunctConstraint(z[1])) +@constraint(m, x[3] >= 4, DisjunctConstraint(z[2])) +@disjunction(m, z, DisjunctConstraint(w[1])) +@constraint(m, z in Exactly(w[1])) + +## +reformulate_model(m, BigM()) +print(m) +# Feasibility +# Subject to +# y[1] + y[2] = 1 +# -y[1] + w[1] + w[2] = 0 +# -w[1] + z[1] + z[2] = 0 +# x[3] - 9 z[2] ≥ -5 +# x[2] - 8 w[2] ≥ -5 +# x[3] - 5 w[2] ≥ -5 +# x[1] - 7 y[2] ≥ -5 +# x[2] - 4 y[2] ≥ -5 +# x[3] - 6 y[2] ≥ -5 +# x[1] + 7 y[1] ≤ 5 +# x[2] + 8 w[1] ≤ 5 +# x[3] + 9 z[1] ≤ 5 +# x[3] + 5 w[2] ≤ 5 +# x[2] + 6 y[2] ≤ 5 +# x[3] + 4 y[2] ≤ 5 +# x[1] ≥ -5 +# x[2] ≥ -5 +# x[3] ≥ -5 +# x[1] ≤ 5 +# x[2] ≤ 5 +# x[3] ≤ 5 +# y[1] binary +# y[2] binary +# w[1] binary +# w[2] binary +# z[1] binary +# z[2] binary diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..5e2b3b3 Binary files /dev/null and b/logo.png differ diff --git a/paper/.latexmkrc b/paper/.latexmkrc new file mode 100644 index 0000000..ddcb138 --- /dev/null +++ b/paper/.latexmkrc @@ -0,0 +1,6 @@ + +sub build_header { + system("ruby ./prep.rb") +} + +build_header() diff --git a/paper/bib.tex b/paper/bib.tex new file mode 100644 index 0000000..8e1819a --- /dev/null +++ b/paper/bib.tex @@ -0,0 +1,4 @@ +% **************GENERATED FILE, DO NOT EDIT************** + +\bibliographystyle{juliacon} +\bibliography{ref.bib} diff --git a/paper/bigm.png b/paper/bigm.png new file mode 100644 index 0000000..d8b8c35 Binary files /dev/null and b/paper/bigm.png differ diff --git a/paper/chr.png b/paper/chr.png new file mode 100644 index 0000000..e249526 Binary files /dev/null and b/paper/chr.png differ diff --git a/paper/header.tex b/paper/header.tex new file mode 100644 index 0000000..604ae8d --- /dev/null +++ b/paper/header.tex @@ -0,0 +1,19 @@ +% **************GENERATED FILE, DO NOT EDIT************** + +\title{My JuliaCon proceeding} + +\author[1]{1st author} +\author[1, 2]{2nd author} +\author[2]{3rd author} +\affil[1]{University} +\affil[2]{National Lab} + +\keywords{Julia, Optimization, Game theory, Compiler} + +\hypersetup{ +pdftitle = {My JuliaCon proceeding}, +pdfsubject = {JuliaCon 2019 Proceedings}, +pdfauthor = {1st author, 2nd author, 3rd author}, +pdfkeywords = {Julia, Optimization, Game theory, Compiler}, +} + diff --git a/paper/jlcode.sty b/paper/jlcode.sty new file mode 100644 index 0000000..affd6a3 --- /dev/null +++ b/paper/jlcode.sty @@ -0,0 +1,420 @@ +%% +%% Julia definition (c) 2018 by wg030 +%% +%% +%% +% keywords, literals and built-ins from: +% https://github.com/isagalaev/highlight.js/blob/master/src/languages/julia.js +% colors from: +% https://docs.julialang.org/en/stable/assets/highlightjs/default.css +% https://docs.julialang.org/en/stable/assets/documenter.css +% special unicode characters from: +% https://docs.julialang.org/en/stable/manual/unicode-input/ + + + + + +% defining the jlcode package +\def\fileversion{2.1} +\def\filedate{2018/03/06} + +\typeout{-- Package: `jlcode' \fileversion\space <\filedate> --} +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{jlcode}[\filedate\space\fileversion] + + + + + +% loading required packages +\RequirePackage{listings} +\RequirePackage{xcolor} % for coloring +\RequirePackage{textcomp} % for upright single quotes +\RequirePackage{amssymb} % for the ϰ symbol +\RequirePackage{eurosym} % for the € symbol +\PassOptionsToPackage{T1}{fontenc} +\RequirePackage{fontenc} % for the « and » symbols +\RequirePackage{calc} % for the creation of the code box + + + + + +% julia language definition +\lstdefinelanguage{julia} +{% +% +% julia's keywords: +% +morekeywords=[1] +{% +in,isa,where,baremodule,begin,break,catch,ccall,const,continue,do,else,elseif,% +end,export,finally,for,function,global,if,import,importall,let,local,macro,% +module,quote,return,try,using,while,struct,mutable,primitive,% +% legacy, to be deprecated in the next release +type,immutable,abstract,bitstype,typealias% +},% +% +% julia's literals: +% +morekeywords=[2] +{% +true,false,ARGS,C_NULL,DevNull,ENDIAN_BOM,ENV,I,Inf,Inf16,Inf32,Inf64,% +InsertionSort,JULIA_HOME,LOAD_PATH,MergeSort,NaN,NaN16,NaN32,NaN64,% +PROGRAM_FILE,QuickSort,RoundDown,RoundFromZero,RoundNearest,% +RoundNearestTiesAway,RoundNearestTiesUp,RoundToZero,RoundUp,STDERR,STDIN,% +STDOUT,VERSION,catalan,e,eu,eulergamma,golden,im,nothing,pi,γ,π,φ% +},% +% +% julia's built-ins: +% +morekeywords=[3] +{% +ANY,AbstractArray,AbstractChannel,AbstractFloat,AbstractMatrix,AbstractRNG,% +AbstractSerializer,AbstractSet,AbstractSparseArray,AbstractSparseMatrix,% +AbstractSparseVector,AbstractString,AbstractUnitRange,AbstractVecOrMat,% +AbstractVector,Any,ArgumentError,Array,AssertionError,Associative,% +Base64DecodePipe,Base64EncodePipe,Bidiagonal,BigFloat,BigInt,BitArray,% +BitMatrix,BitVector,Bool,BoundsError,BufferStream,CachingPool,% +CapturedException,CartesianIndex,CartesianRange,Cchar,Cdouble,Cfloat,Channel,% +Char,Cint,Cintmax_t,Clong,Clonglong,ClusterManager,Cmd,CodeInfo,Colon,Complex,% +Complex128,Complex32,Complex64,CompositeException,Condition,ConjArray,% +ConjMatrix,ConjVector,Cptrdiff_t,Cshort,Csize_t,Cssize_t,Cstring,Cuchar,Cuint,% +Cuintmax_t,Culong,Culonglong,Cushort,Cwchar_t,Cwstring,DataType,Date,% +DateFormat,DateTime,DenseArray,DenseMatrix,DenseVecOrMat,DenseVector,Diagonal,% +Dict,DimensionMismatch,Dims,DirectIndexString,Display,DivideError,DomainError,% +EOFError,EachLine,Enum,Enumerate,ErrorException,Exception,ExponentialBackOff,% +Expr,Factorization,FileMonitor,Float16,Float32,Float64,Function,Future,% +GlobalRef,GotoNode,HTML,Hermitian,IO,IOBuffer,IOContext,IOStream,IPAddr,IPv4,% +IPv6,IndexCartesian,IndexLinear,IndexStyle,InexactError,InitError,Int,Int128,% +Int16,Int32,Int64,Int8,IntSet,Integer,InterruptException,InvalidStateException,% +Irrational,KeyError,LabelNode,LinSpace,LineNumberNode,LoadError,% +LowerTriangular,MIME,Matrix,MersenneTwister,Method,MethodError,MethodTable,% +Module,NTuple,NewvarNode,NullException,Nullable,Number,ObjectIdDict,% +OrdinalRange,OutOfMemoryError,OverflowError,Pair,ParseError,PartialQuickSort,% +PermutedDimsArray,Pipe,PollingFileWatcher,ProcessExitedException,Ptr,QuoteNode,% +RandomDevice,Range,RangeIndex,Rational,RawFD,ReadOnlyMemoryError,Real,% +ReentrantLock,Ref,Regex,RegexMatch,RemoteChannel,RemoteException,RevString,% +RoundingMode,RowVector,SSAValue,SegmentationFault,SerializationState,Set,% +SharedArray,SharedMatrix,SharedVector,Signed,SimpleVector,Slot,SlotNumber,% +SparseMatrixCSC,SparseVector,StackFrame,StackOverflowError,StackTrace,% +StepRange,StepRangeLen,StridedArray,StridedMatrix,StridedVecOrMat,% +StridedVector,String,SubArray,SubString,SymTridiagonal,Symbol,Symmetric,% +SystemError,TCPSocket,Task,Text,TextDisplay,Timer,Tridiagonal,Tuple,Type,% +TypeError,TypeMapEntry,TypeMapLevel,TypeName,TypeVar,TypedSlot,UDPSocket,UInt,% +UInt128,UInt16,UInt32,UInt64,UInt8,UndefRefError,UndefVarError,UnicodeError,% +UniformScaling,Union,UnionAll,UnitRange,Unsigned,UpperTriangular,Val,Vararg,% +VecElement,VecOrMat,Vector,VersionNumber,Void,WeakKeyDict,WeakRef,WorkerConfig,% +WorkerPool% +},% +% +% +sensitive=true,% +% +alsoother={$},%$ +% +morecomment=[l]{\#},% +morecomment=[n]{\#=}{=\#},% +% +morestring=[b]{"},% +morestring=[m]{'},% +morestring=[s]{"""}{"""},% +morestring=[s]{r"}{"},% +morestring=[s]{b"}{"},% +morestring=[s]{v"}{"},% +morestring=[s]{raw"}{"},% +morestring=[s]{L"}{"},% +% +}[keywords,comments,strings] + + +% defining the colors for +\definecolor{jlbase}{rgb}{.28,.28,.28} % julia's base color +\definecolor{jlkeyword}{rgb}{0.4, 0.0, 0.3} % julia's keywords +\definecolor{jlliteral}{HTML}{78A960} % julia's literals +\definecolor{jlbuiltin}{HTML}{397300} % julia's built-ins +\definecolor{jlcomment}{HTML}{888888} % julia's comments +\definecolor{jlstring}{HTML}{880000} % julia's strings +\definecolor{jlbackground}{HTML}{F5F5F5} % the background of the code block +\definecolor{jlrule}{HTML}{DDDDDD} % the rule of the code block + + +% defining the ucc and the ucclit command +% for literating special unicode characters +\newcommand{\ucc}[1]{% +\ifnum\lst@mode=\lst@Pmode\relax% +{\color{jlbase}#1}% +\else% +#1% +\fi% +} + +\newcommand{\ucclit}[1]{% +\ifnum\lst@mode=\lst@Pmode\relax% +{\color{jlliteral}#1}% +\else% +#1% +\fi% +} + + +% defining a new opliterate key +\def\lst@OpLiteratekey#1\@nil@{\let\lst@ifxopliterate\lst@if + \def\lst@opliterate{#1}} +\lst@Key{opliterate}{}{\@ifstar{\lst@true \lst@OpLiteratekey} + {\lst@false\lst@OpLiteratekey}#1\@nil@} +\lst@AddToHook{SelectCharTable} + {\ifx\lst@opliterate\@empty\else + \expandafter\lst@OpLiterate\lst@opliterate{}\relax\z@ + \fi} +\def\lst@OpLiterate#1#2#3{% + \ifx\relax#2\@empty\else + \lst@CArgX #1\relax\lst@CDef + {} + {\let\lst@next\@empty + \lst@ifxopliterate + \lst@ifmode \let\lst@next\lst@CArgEmpty \fi + \fi + \ifx\lst@next\@empty + \ifx\lst@OutputBox\@gobble\else + \lst@XPrintToken \let\lst@scanmode\lst@scan@m + \lst@token{#2}\lst@length#3\relax + \lst@XPrintToken + \fi + \let\lst@next\lst@CArgEmptyGobble + \fi + \lst@next}% + \@empty + \expandafter\lst@OpLiterate + \fi} + + +% defining the \addlitjlbase and \addlitjlstring commands, +% which help a user to fix some of the known managable issues +\def\addToLiterate#1{% +\protected@edef\lst@literate{% +\unexpanded\expandafter{\lst@literate}\unexpanded{#1}}} +\lst@Key{expandliterate}{}{\addToLiterate{#1}} +\newcommand{\addlitjlbase}[3]{% +\lstset{expandliterate={#1}{{{\color{jlbase}#2}}}{#3}}} +\newcommand{\addlitjlstring}[3]{% +\lstset{expandliterate={#1}{{{\color{jlstring}#2}}}{#3}}} + + + + + +% defining the styles for +\lstset{keywordstyle={[1]\color{jlkeyword}\bfseries}} % julia's keywords +\lstset{keywordstyle={[2]\color{jlliteral}}} % julia's literals +\lstset{keywordstyle={[3]\color{jlbuiltin}}} % julia's built-ins +\lstset{commentstyle={\color{jlcomment}}} % julia's comments +\lstset{stringstyle={\color{jlstring}}} % julia's strings +\lstset{identifierstyle={\color{jlbase}}} % julia's identifiers + + +\lstset{opliterate=* +% +% julia's operators +% +{\\}{{{\color{jlbase}\lstum@backslash}}}{1} {\{}{{{\color{jlbase}\{}}}{1} +{\}}{{{\color{jlbase}\}}}}{1} {!}{{{\color{jlbase}!}}}{1} +{\%}{{{\color{jlbase}\%}}}{1} {&}{{{\color{jlbase}\&}}}{1} +{(}{{{\color{jlbase}(}}}{1} {)}{{{\color{jlbase})}}}{1} +{*}{{{\color{jlbase}*}}}{1} {+}{{{\color{jlbase}+}}}{1} +{,}{{{\color{jlbase},}}}{1} {-}{{{\color{jlbase}-}}}{1} +{.}{{{\color{jlbase}.}}}{1} {/}{{{\color{jlbase}/}}}{1} +{:}{{{\color{jlbase}:}}}{1} {;}{{{\color{jlbase};}}}{1} +{<}{{{\color{jlbase}<}}}{1} {=}{{{\color{jlbase}=}}}{1} +{>}{{{\color{jlbase}>}}}{1} {?}{{{\color{jlbase}?}}}{1} +{[}{{{\color{jlbase}[}}}{1} {]}{{{\color{jlbase}]}}}{1} +{^}{{{\color{jlbase}\^{}}}}{1} {|}{{{\color{jlbase}|}}}{1} +{~}{{{\color{jlbase}\textasciitilde{}}}}{1} +% +% julia's numbers +% +{.0}{{{\color{jlstring}.0}}}{2} {.1}{{{\color{jlstring}.1}}}{2} +{.2}{{{\color{jlstring}.2}}}{2} {.3}{{{\color{jlstring}.3}}}{2} +{.4}{{{\color{jlstring}.4}}}{2} {.5}{{{\color{jlstring}.5}}}{2} +{.6}{{{\color{jlstring}.6}}}{2} {.7}{{{\color{jlstring}.7}}}{2} +{.8}{{{\color{jlstring}.8}}}{2} {.9}{{{\color{jlstring}.9}}}{2} +% +{e+0}{{{\color{jlstring}e+0}}}{3} {e+1}{{{\color{jlstring}e+1}}}{3} +{e+2}{{{\color{jlstring}e+2}}}{3} {e+3}{{{\color{jlstring}e+3}}}{3} +{e+4}{{{\color{jlstring}e+4}}}{3} {e+5}{{{\color{jlstring}e+5}}}{3} +{e+6}{{{\color{jlstring}e+6}}}{3} {e+7}{{{\color{jlstring}e+7}}}{3} +{e+8}{{{\color{jlstring}e+8}}}{3} {e+9}{{{\color{jlstring}e+9}}}{3} +% +{0E+}{{{\color{jlstring}0E+}}}{3} {1E+}{{{\color{jlstring}1E+}}}{3} +{2E+}{{{\color{jlstring}2E+}}}{3} {3E+}{{{\color{jlstring}3E+}}}{3} +{4E+}{{{\color{jlstring}4E+}}}{3} {5E+}{{{\color{jlstring}5E+}}}{3} +{6E+}{{{\color{jlstring}6E+}}}{3} {7E+}{{{\color{jlstring}7E+}}}{3} +{8E+}{{{\color{jlstring}8E+}}}{3} {9E+}{{{\color{jlstring}9E+}}}{3} +% +{e-0}{{{\color{jlstring}e-0}}}{3} {e-1}{{{\color{jlstring}e-1}}}{3} +{e-2}{{{\color{jlstring}e-2}}}{3} {e-3}{{{\color{jlstring}e-3}}}{3} +{e-4}{{{\color{jlstring}e-4}}}{3} {e-5}{{{\color{jlstring}e-5}}}{3} +{e-6}{{{\color{jlstring}e-6}}}{3} {e-7}{{{\color{jlstring}e-7}}}{3} +{e-8}{{{\color{jlstring}e-8}}}{3} {e-9}{{{\color{jlstring}e-9}}}{3} +% +{0E-}{{{\color{jlstring}0E-}}}{3} {1E-}{{{\color{jlstring}1E-}}}{3} +{2E-}{{{\color{jlstring}2E-}}}{3} {3E-}{{{\color{jlstring}3E-}}}{3} +{4E-}{{{\color{jlstring}4E-}}}{3} {5E-}{{{\color{jlstring}5E-}}}{3} +{6E-}{{{\color{jlstring}6E-}}}{3} {7E-}{{{\color{jlstring}7E-}}}{3} +{8E-}{{{\color{jlstring}8E-}}}{3} {9E-}{{{\color{jlstring}9E-}}}{3} +} + + +% special unicode characters +%\lstset{inputencoding=utf8} +%\DeclareUnicodeCharacter{0391}{A} +\lstset{extendedchars=true} +\lstset{literate= +% +% characters that appear in latin languages +% +{á}{{\'a}}{1} {é}{{\'e}}{1} {í}{{\'i}}{1} {ó}{{\'o}}{1} {ú}{{\'u}}{1} +{Á}{{\'A}}{1} {É}{{\'E}}{1} {Í}{{\'I}}{1} {Ó}{{\'O}}{1} {Ú}{{\'U}}{1} +{à}{{\`a}}{1} {è}{{\`e}}{1} {ì}{{\`i}}{1} {ò}{{\`o}}{1} {ù}{{\`u}}{1} +{À}{{\`A}}{1} {È}{{\'E}}{1} {Ì}{{\`I}}{1} {Ò}{{\`O}}{1} {Ù}{{\`U}}{1} +{ä}{{\"a}}{1} {ë}{{\"e}}{1} {ï}{{\"i}}{1} {ö}{{\"o}}{1} {ü}{{\"u}}{1} +{Ä}{{\"A}}{1} {Ë}{{\"E}}{1} {Ï}{{\"I}}{1} {Ö}{{\"O}}{1} {Ü}{{\"U}}{1} +{â}{{\^a}}{1} {ê}{{\^e}}{1} {î}{{\^i}}{1} {ô}{{\^o}}{1} {û}{{\^u}}{1} +{Â}{{\^A}}{1} {Ê}{{\^E}}{1} {Î}{{\^I}}{1} {Ô}{{\^O}}{1} {Û}{{\^U}}{1} +{œ}{{\oe}}{1} {Œ}{{\OE}}{1} {æ}{{\ae}}{1} {Æ}{{\AE}}{1} {ß}{{\ss}}{1} +{ű}{{\H{u}}}{1} {Ű}{{\H{U}}}{1} {ő}{{\H{o}}}{1} {Ő}{{\H{O}}}{1} +{ç}{{\c c}}{1} {Ç}{{\c C}}{1} {ø}{{\o}}{1} {å}{{\r a}}{1} {Å}{{\r A}}{1} +{€}{{\euro}}{1} {£}{{\pounds}}{1} {«}{{\guillemotleft}}{1} +{»}{{\guillemotright}}{1} {ñ}{{\~n}}{1} {Ñ}{{\~N}}1 {¿}{{?`}}{1} +% +% greek capital letters +% +{Α}{{\ucc{A}}}{1} {Β}{{\ucc{B}}}{1} {Γ}{{\ucc{$\Gamma$}}}{1} +{Δ}{{\ucc{$\Delta$}}}{1} {Ε}{{\ucc{E}}}{1} {Ζ}{{\ucc{Z}}}{1} +{Η}{{\ucc{H}}}{1} {Θ}{{\ucc{$\Theta$}}}{1} {Ι}{{\ucc{I}}}{1} +{Κ}{{\ucc{K}}}{1} {Λ}{{\ucc{$\Lambda$}}}{1} {Μ}{{\ucc{M}}}{1} +{Ν}{{\ucc{N}}}{1} {Ξ}{{\ucc{$\Xi$}}}{1} {Ο}{{\ucc{O}}}{1} +{Π}{{\ucc{$\Pi$}}}{1} {Ρ}{{\ucc{P}}}{1} {Σ}{{\ucc{$\Sigma$}}}{1} +{Τ}{{\ucc{T}}}{1} {Υ}{{\ucc{$\Upsilon$}}}{1} {Φ}{{\ucc{$\Phi$}}}{1} +{Χ}{{\ucc{X}}}{1} {Ψ}{{\ucc{$\Psi$}}}{1} {Ω}{{\ucc{$\Omega$}}}{1} +% +% mircro sign + latin small letter open e +% +{µ}{{\ucc{$\mu$}}}{1} {ɛ}{{\ucc{$\varepsilon$}}}{1} +% +% greek small letters +% +{α}{{\ucc{$\alpha$}}}{1} {β}{{\ucc{$\beta$}}}{1} {γ}{{\ucclit{$\gamma$}}}{1} +{δ}{{\ucc{$\delta$}}}{1} {ε}{{\ucc{$\varepsilon$}}}{1} +{ϵ}{{\ucc{$\epsilon$}}}{1} {ζ}{{\ucc{$\zeta$}}}{1} {η}{{\ucc{$\eta$}}}{1} +{θ}{{\ucc{$\theta$}}}{1} {ϑ}{{\ucc{$\vartheta$}}}{1} {ι}{{\ucc{$\iota$}}}{1} +{κ}{{\ucc{$\kappa$}}}{1} {ϰ}{{\ucc{$\varkappa$}}}{1} {λ}{{\ucc{$\lambda$}}}{1} +{μ}{{\ucc{$\mu$}}}{1} {ν}{{\ucc{$\nu$}}}{1} {ξ}{{\ucc{$\xi$}}}{1} +{ο}{{\ucc{o}}}{1} {π}{{\ucclit{$\pi$}}}{1} {ϖ}{{\ucc{$\varpi$}}}{1} +{ρ}{{\ucc{$\rho$}}}{1} {ϱ}{{\ucc{$\varrho$}}}{1} {σ}{{\ucc{$\sigma$}}}{1} +{ς}{{\ucc{$\varsigma$}}}{1} {τ}{{\ucc{$\tau$}}}{1} {υ}{{\ucc{$\upsilon$}}}{1} +{φ}{{\ucclit{$\phi$}}}{1} {ϕ}{{\ucc{$\varphi$}}}{1} {χ}{{\ucc{$\chi$}}}{1} +{ψ}{{\ucc{$\psi$}}}{1} {ω}{{\ucc{$\omega$}}}{1} +% +% superscripts +% +{⁽}{{\ucc{${\scriptstyle {}^{(}}$}}}{1} {⁾}{{\ucc{${\scriptstyle {}^{)}}$}}}{1} +{⁺}{{\ucc{${\scriptstyle {}^{+}}$}}}{1} {⁻}{{\ucc{${\scriptstyle {}^{-}}$}}}{1} +{⁰}{{\ucc{${\scriptstyle {}^{0}}$}}}{1} {¹}{{\ucc{${\scriptstyle {}^{1}}$}}}{1} +{²}{{\ucc{${\scriptstyle {}^{2}}$}}}{1} {³}{{\ucc{${\scriptstyle {}^{3}}$}}}{1} +{⁴}{{\ucc{${\scriptstyle {}^{4}}$}}}{1} {⁵}{{\ucc{${\scriptstyle {}^{5}}$}}}{1} +{⁶}{{\ucc{${\scriptstyle {}^{6}}$}}}{1} {⁷}{{\ucc{${\scriptstyle {}^{7}}$}}}{1} +{⁸}{{\ucc{${\scriptstyle {}^{8}}$}}}{1} {⁹}{{\ucc{${\scriptstyle {}^{9}}$}}}{1} +{⁼}{{\ucc{${\scriptstyle {}^{=}}$}}}{1} {ᴬ}{{\ucc{${\scriptstyle {}^{A}}$}}}{1} +{ᴮ}{{\ucc{${\scriptstyle {}^{B}}$}}}{1} {ᴰ}{{\ucc{${\scriptstyle {}^{D}}$}}}{1} +{ᴱ}{{\ucc{${\scriptstyle {}^{E}}$}}}{1} {ᴳ}{{\ucc{${\scriptstyle {}^{G}}$}}}{1} +{ᴴ}{{\ucc{${\scriptstyle {}^{H}}$}}}{1} {ᴵ}{{\ucc{${\scriptstyle {}^{I}}$}}}{1} +{ᴶ}{{\ucc{${\scriptstyle {}^{J}}$}}}{1} {ᴷ}{{\ucc{${\scriptstyle {}^{K}}$}}}{1} +{ᴸ}{{\ucc{${\scriptstyle {}^{L}}$}}}{1} {ᴹ}{{\ucc{${\scriptstyle {}^{M}}$}}}{1} +{ᴺ}{{\ucc{${\scriptstyle {}^{N}}$}}}{1} {ᴼ}{{\ucc{${\scriptstyle {}^{O}}$}}}{1} +{ᴾ}{{\ucc{${\scriptstyle {}^{P}}$}}}{1} {ᴿ}{{\ucc{${\scriptstyle {}^{R}}$}}}{1} +{ᵀ}{{\ucc{${\scriptstyle {}^{T}}$}}}{1} {ᵁ}{{\ucc{${\scriptstyle {}^{U}}$}}}{1} +{ⱽ}{{\ucc{${\scriptstyle {}^{V}}$}}}{1} {ᵂ}{{\ucc{${\scriptstyle {}^{W}}$}}}{1} +{ᵃ}{{\ucc{${\scriptstyle {}^{a}}$}}}{1} {ᵇ}{{\ucc{${\scriptstyle {}^{b}}$}}}{1} +{ᶜ}{{\ucc{${\scriptstyle {}^{c}}$}}}{1} {ᵈ}{{\ucc{${\scriptstyle {}^{d}}$}}}{1} +{ᵉ}{{\ucc{${\scriptstyle {}^{e}}$}}}{1} {ᶠ}{{\ucc{${\scriptstyle {}^{f}}$}}}{1} +{ᵍ}{{\ucc{${\scriptstyle {}^{g}}$}}}{1} {ʰ}{{\ucc{${\scriptstyle {}^{h}}$}}}{1} +{ⁱ}{{\ucc{${\scriptstyle {}^{i}}$}}}{1} {ʲ}{{\ucc{${\scriptstyle {}^{j}}$}}}{1} +{ᵏ}{{\ucc{${\scriptstyle {}^{k}}$}}}{1} {ˡ}{{\ucc{${\scriptstyle {}^{l}}$}}}{1} +{ᵐ}{{\ucc{${\scriptstyle {}^{m}}$}}}{1} {ⁿ}{{\ucc{${\scriptstyle {}^{n}}$}}}{1} +{ᵒ}{{\ucc{${\scriptstyle {}^{o}}$}}}{1} {ᵖ}{{\ucc{${\scriptstyle {}^{p}}$}}}{1} +{ʳ}{{\ucc{${\scriptstyle {}^{r}}$}}}{1} {ˢ}{{\ucc{${\scriptstyle {}^{s}}$}}}{1} +{ᵗ}{{\ucc{${\scriptstyle {}^{t}}$}}}{1} {ᵘ}{{\ucc{${\scriptstyle {}^{u}}$}}}{1} +{ᵛ}{{\ucc{${\scriptstyle {}^{v}}$}}}{1} {ʷ}{{\ucc{${\scriptstyle {}^{w}}$}}}{1} +{ˣ}{{\ucc{${\scriptstyle {}^{x}}$}}}{1} {ʸ}{{\ucc{${\scriptstyle {}^{y}}$}}}{1} +{ᶻ}{{\ucc{${\scriptstyle {}^{z}}$}}}{1} +{ᵅ}{{\ucc{${\scriptstyle {}^{\alpha}}$}}}{1} +{ᵝ}{{\ucc{${\scriptstyle {}^{\beta}}$}}}{1} +{ᵞ}{{\ucc{${\scriptstyle {}^{\gamma}}$}}}{1} +{ᵟ}{{\ucc{${\scriptstyle {}^{\delta}}$}}}{1} +{ᵋ}{{\ucc{${\scriptstyle {}^{\varepsilon}}$}}}{1} +{ᶿ}{{\ucc{${\scriptstyle {}^{\theta}}$}}}{1} +{ᶥ}{{\ucc{${\scriptstyle {}^{\iota}}$}}}{1} +{ᶲ}{{\ucc{${\scriptstyle {}^{\phi}}$}}}{1} +{ᵡ}{{\ucc{${\scriptstyle {}^{\chi}}$}}}{1} +{ᵠ}{{\ucc{${\scriptstyle {}^{\psi}}$}}}{1} +% +% subscripts +% +{₍}{{\ucc{${\scriptstyle {}_{(}}$}}}{1} {₎}{{\ucc{${\scriptstyle {}_{)}}$}}}{1} +{₊}{{\ucc{${\scriptstyle {}_{+}}$}}}{1} {₋}{{\ucc{${\scriptstyle {}_{-}}$}}}{1} +{₀}{{\ucc{${\scriptstyle {}_{0}}$}}}{1} {₁}{{\ucc{${\scriptstyle {}_{1}}$}}}{1} +{₂}{{\ucc{${\scriptstyle {}_{2}}$}}}{1} {₃}{{\ucc{${\scriptstyle {}_{3}}$}}}{1} +{₄}{{\ucc{${\scriptstyle {}_{4}}$}}}{1} {₅}{{\ucc{${\scriptstyle {}_{5}}$}}}{1} +{₆}{{\ucc{${\scriptstyle {}_{6}}$}}}{1} {₇}{{\ucc{${\scriptstyle {}_{7}}$}}}{1} +{₈}{{\ucc{${\scriptstyle {}_{8}}$}}}{1} {₉}{{\ucc{${\scriptstyle {}_{9}}$}}}{1} +{₌}{{\ucc{${\scriptstyle {}_{=}}$}}}{1} {ₐ}{{\ucc{${\scriptstyle {}_{a}}$}}}{1} +{ₑ}{{\ucc{${\scriptstyle {}_{e}}$}}}{1} {ₕ}{{\ucc{${\scriptstyle {}_{h}}$}}}{1} +{ᵢ}{{\ucc{${\scriptstyle {}_{i}}$}}}{1} {ⱼ}{{\ucc{${\scriptstyle {}_{j}}$}}}{1} +{ₖ}{{\ucc{${\scriptstyle {}_{k}}$}}}{1} {ₗ}{{\ucc{${\scriptstyle {}_{l}}$}}}{1} +{ₘ}{{\ucc{${\scriptstyle {}_{m}}$}}}{1} {ₙ}{{\ucc{${\scriptstyle {}_{n}}$}}}{1} +{ₒ}{{\ucc{${\scriptstyle {}_{o}}$}}}{1} {ₚ}{{\ucc{${\scriptstyle {}_{p}}$}}}{1} +{ᵣ}{{\ucc{${\scriptstyle {}_{r}}$}}}{1} {ₛ}{{\ucc{${\scriptstyle {}_{s}}$}}}{1} +{ₜ}{{\ucc{${\scriptstyle {}_{t}}$}}}{1} {ᵤ}{{\ucc{${\scriptstyle {}_{u}}$}}}{1} +{ᵥ}{{\ucc{${\scriptstyle {}_{v}}$}}}{1} {ₓ}{{\ucc{${\scriptstyle {}_{x}}$}}}{1} +{ᵦ}{{\ucc{${\scriptstyle {}_{\beta}}$}}}{1} +{ᵧ}{{\ucc{${\scriptstyle {}_{\gamma}}$}}}{1} +{ᵨ}{{\ucc{${\scriptstyle {}_{\rho}}$}}}{1} +{ᵪ}{{\ucc{${\scriptstyle {}_{\chi}}$}}}{1} +{ᵩ}{{\ucc{${\scriptstyle {}_{\psi}}$}}}{1} +% +} + + + + + +% basic font +\makeatletter +\def\lstbasicfont{% + \color{jlstring}% + \ttfamily% + \lst@ifdisplaystyle\scriptsize\fi% +} +\makeatother + +% general style of the code block +\lstset{basicstyle={\lstbasicfont}} +\lstset{showstringspaces=false} +\lstset{upquote=true} +\lstset{tabsize=4} +\lstset{aboveskip={1.5\baselineskip},belowskip={1.5\baselineskip}} + +% creating the code box +\lstset{backgroundcolor=\color{jlbackground}, rulecolor=\color{jlrule}} +\lstset{frame=single, frameround=tttt} +\lstset{columns=fixed} +\newlength{\bfem} +\settowidth{\bfem}{\lstbasicfont{m}} +\newlength{\xmrgn} +\setlength{\xmrgn}{(\textwidth - 80\bfem)*\real{0.5}} +\lstset{basewidth=\bfem} + +% activating the julia style +\lstset{language=julia} diff --git a/paper/journal_dat.tex b/paper/journal_dat.tex new file mode 100644 index 0000000..a925030 --- /dev/null +++ b/paper/journal_dat.tex @@ -0,0 +1,6 @@ +% **************GENERATED FILE, DO NOT EDIT************** + +\def\@journalName{Proceedings of JuliaCon} +\def\@volume{1} +\def\@issue{1} +\def\@year{2021} diff --git a/paper/juliacon.bst b/paper/juliacon.bst new file mode 100644 index 0000000..aaf1930 --- /dev/null +++ b/paper/juliacon.bst @@ -0,0 +1,1189 @@ +% BibTeX standard bibliography style `plain' + % version 0.99a for BibTeX versions 0.99a or later, LaTeX version 2.09. + % Copyright (C) 1985, all rights reserved. + % Copying of this file is authorized only if either + % (1) you make absolutely no changes to your copy, including name, or + % (2) if you do make changes, you name it something other than + % btxbst.doc, plain.bst, unsrt.bst, alpha.bst, and abbrv.bst. + % This restriction helps ensure that all standard styles are identical. + % The file btxbst.doc has the documentation for this style. + +ENTRY + { address + author + booktitle + chapter + edition + editor + eprint + eprinttype + eprintclass + howpublished + institution + journal + key + month + note + number + organization + pages + publisher + school + series + title + type + volume + year + doi + } + {} + { label } + +INTEGERS { output.state before.all mid.sentence after.sentence after.block } + +FUNCTION {init.state.consts} +{ #0 'before.all := + #1 'mid.sentence := + #2 'after.sentence := + #3 'after.block := +} + +STRINGS { s t } + +FUNCTION {output.nonnull} +{ 's := + output.state mid.sentence = + { ", " * write$ } + { output.state after.block = + { add.period$ write$ + newline$ + "" write$ + } + { output.state before.all = + 'write$ + { add.period$ " " * write$ } + if$ + } + if$ + mid.sentence 'output.state := + } + if$ + s +} + +FUNCTION {output} +{ duplicate$ empty$ + 'pop$ + 'output.nonnull + if$ +} + +FUNCTION {output.check} +{ 't := + duplicate$ empty$ + { pop$ "empty " t * " in " * cite$ * warning$ } + 'output.nonnull + if$ +} + +FUNCTION {output.bibitem} +{ newline$ + "\bibitem{" write$ + cite$ write$ + "}" write$ + newline$ + "" + before.all 'output.state := +} + +FUNCTION {fin.entry} +{ add.period$ + write$ + newline$ +} + +FUNCTION {new.block} +{ output.state before.all = + 'skip$ + { after.block 'output.state := } + if$ +} + +FUNCTION {new.sentence} +{ output.state after.block = + 'skip$ + { output.state before.all = + 'skip$ + { after.sentence 'output.state := } + if$ + } + if$ +} + +FUNCTION {not} +{ { #0 } + { #1 } + if$ +} + +FUNCTION {and} +{ 'skip$ + { pop$ #0 } + if$ +} + +FUNCTION {or} +{ { pop$ #1 } + 'skip$ + if$ +} + +FUNCTION {new.block.checka} +{ empty$ + 'skip$ + 'new.block + if$ +} + +FUNCTION {new.block.checkb} +{ empty$ + swap$ empty$ + and + 'skip$ + 'new.block + if$ +} + +FUNCTION {new.sentence.checka} +{ empty$ + 'skip$ + 'new.sentence + if$ +} + +FUNCTION {new.sentence.checkb} +{ empty$ + swap$ empty$ + and + 'skip$ + 'new.sentence + if$ +} + +FUNCTION {field.or.null} +{ duplicate$ empty$ + { pop$ "" } + 'skip$ + if$ +} + +FUNCTION {emphasize} +{ duplicate$ empty$ + { pop$ "" } + { "{\em " swap$ * "}" * } + if$ +} + +INTEGERS { nameptr namesleft numnames } + +FUNCTION {format.names} +{ 's := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr "{ff~}{vv~}{ll}{, jj}" format.name$ 't := + nameptr #1 > + { namesleft #1 > + { ", " * t * } + { numnames #2 > + { "," * } + 'skip$ + if$ + t "others" = + { " et~al." * } + { " and " * t * } + if$ + } + if$ + } + 't + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + +FUNCTION {format.authors} +{ author empty$ + { "" } + { author format.names } + if$ +} + +FUNCTION {format.editors} +{ editor empty$ + { "" } + { editor format.names + editor num.names$ #1 > + { ", editors" * } + { ", editor" * } + if$ + } + if$ +} + +FUNCTION {format.eprint} +{ eprint empty$ + { "" } + { eprinttype empty$ + { eprintclass empty$ + { eprint } + { eprint " [" * eprintclass * "]" * } + if$ + } + { eprinttype "arxiv" = + { eprintclass empty$ + { eprinttype ":" * "\href{http://arxiv.org/abs/" * eprint * "}{" * eprint * "}" * } + { eprinttype ":" * "\href{http://arxiv.org/abs/" * eprint * "}{" * eprint * " [" * eprintclass * "]" * "}" * } + if$ + } + { eprintclass empty$ + { eprinttype ":" * eprint * } + { eprinttype ":" * eprint * " [" * eprintclass * "]" *} + if$ + } + if$ + } + if$ + } + if$ +} + +FUNCTION {format.title} +{ title empty$ + { "" } + { title "t" change.case$ } + if$ +} + +FUNCTION {n.dashify} +{ 't := + "" + { t empty$ not } + { t #1 #1 substring$ "-" = + { t #1 #2 substring$ "--" = not + { "--" * + t #2 global.max$ substring$ 't := + } + { { t #1 #1 substring$ "-" = } + { "-" * + t #2 global.max$ substring$ 't := + } + while$ + } + if$ + } + { t #1 #1 substring$ * + t #2 global.max$ substring$ 't := + } + if$ + } + while$ +} + +FUNCTION {format.date} +{ year empty$ + { month empty$ + { "" } + { "there's a month but no year in " cite$ * warning$ + month + } + if$ + } + { month empty$ + 'year + { month " " * year * } + if$ + } + if$ +} + +FUNCTION {format.btitle} +{ title emphasize +} + +FUNCTION {tie.or.space.connect} +{ duplicate$ text.length$ #3 < + { "~" } + { " " } + if$ + swap$ * * +} + +FUNCTION {either.or.check} +{ empty$ + 'pop$ + { "can't use both " swap$ * " fields in " * cite$ * warning$ } + if$ +} + +FUNCTION {format.bvolume} +{ volume empty$ + { "" } + { "volume" volume tie.or.space.connect + series empty$ + 'skip$ + { " of " * series emphasize * } + if$ + "volume and number" number either.or.check + } + if$ +} + +FUNCTION {format.number.series} +{ volume empty$ + { number empty$ + { series field.or.null } + { output.state mid.sentence = + { "number" } + { "Number" } + if$ + number tie.or.space.connect + series empty$ + { "there's a number but no series in " cite$ * warning$ } + { " in " * series * } + if$ + } + if$ + } + { "" } + if$ +} + +FUNCTION {format.edition} +{ edition empty$ + { "" } + { output.state mid.sentence = + { edition "l" change.case$ " edition" * } + { edition "t" change.case$ " edition" * } + if$ + } + if$ +} + +INTEGERS { multiresult } + +FUNCTION {multi.page.check} +{ 't := + #0 'multiresult := + { multiresult not + t empty$ not + and + } + { t #1 #1 substring$ + duplicate$ "-" = + swap$ duplicate$ "," = + swap$ "+" = + or or + { #1 'multiresult := } + { t #2 global.max$ substring$ 't := } + if$ + } + while$ + multiresult +} + +FUNCTION {format.pages} +{ pages empty$ + { "" } + { pages multi.page.check + { "pages" pages n.dashify tie.or.space.connect } + { "page" pages tie.or.space.connect } + if$ + } + if$ +} + +FUNCTION {format.vol.num.pages} +{ volume field.or.null + number empty$ + 'skip$ + { "(" number * ")" * * + volume empty$ + { "there's a number but no volume in " cite$ * warning$ } + 'skip$ + if$ + } + if$ + pages empty$ + 'skip$ + { duplicate$ empty$ + { pop$ format.pages } + { ":" * pages n.dashify * } + if$ + } + if$ +} + +FUNCTION {format.chapter.pages} +{ chapter empty$ + 'format.pages + { type empty$ + { "chapter" } + { type "l" change.case$ } + if$ + chapter tie.or.space.connect + pages empty$ + 'skip$ + { ", " * format.pages * } + if$ + } + if$ +} + +FUNCTION {format.in.ed.booktitle} +{ booktitle empty$ + { "" } + { editor empty$ + { "In " booktitle emphasize * } + { "In " format.editors * ", " * booktitle emphasize * } + if$ + } + if$ +} + +FUNCTION {empty.misc.check} +{ author empty$ title empty$ howpublished empty$ + month empty$ year empty$ note empty$ + and and and and and + key empty$ not and + { "all relevant fields are empty in " cite$ * warning$ } + 'skip$ + if$ +} + +FUNCTION {format.thesis.type} +{ type empty$ + 'skip$ + { pop$ + type "t" change.case$ + } + if$ +} + +FUNCTION {format.tr.number} +{ type empty$ + { "Technical Report" } + 'type + if$ + number empty$ + { "t" change.case$ } + { number tie.or.space.connect } + if$ +} + +FUNCTION {format.article.crossref} +{ key empty$ + { journal empty$ + { "need key or journal for " cite$ * " to crossref " * crossref * + warning$ + "" + } + { "In {\em " journal * "\/}" * } + if$ + } + { "In " key * } + if$ + " \cite{" * crossref * "}" * +} + +FUNCTION {format.crossref.editor} +{ editor #1 "{vv~}{ll}" format.name$ + editor num.names$ duplicate$ + #2 > + { pop$ " et~al." * } + { #2 < + 'skip$ + { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { " et~al." * } + { " and " * editor #2 "{vv~}{ll}" format.name$ * } + if$ + } + if$ + } + if$ +} + +FUNCTION {format.book.crossref} +{ volume empty$ + { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ + "In " + } + { "Volume" volume tie.or.space.connect + " of " * + } + if$ + editor empty$ + editor field.or.null author field.or.null = + or + { key empty$ + { series empty$ + { "need editor, key, or series for " cite$ * " to crossref " * + crossref * warning$ + "" * + } + { "{\em " * series * "\/}" * } + if$ + } + { key * } + if$ + } + { format.crossref.editor * } + if$ + " \cite{" * crossref * "}" * +} + +FUNCTION {format.incoll.inproc.crossref} +{ editor empty$ + editor field.or.null author field.or.null = + or + { key empty$ + { booktitle empty$ + { "need editor, key, or booktitle for " cite$ * " to crossref " * + crossref * warning$ + "" + } + { "In {\em " booktitle * "\/}" * } + if$ + } + { "In " key * } + if$ + } + { "In " format.crossref.editor * } + if$ + " \cite{" * crossref * "}" * +} + +% based on +% https://tex.stackexchange.com/a/127819/245 +FUNCTION {output.doi} +{ + doi empty$ + { skip$ } + { "\href{http://dx.doi.org/" doi * "}{doi:" * doi * "}" * output } + if$ +} + + +FUNCTION {article} +{ output.bibitem + format.authors "author" output.check + new.block + format.title "title" output.check + new.block + crossref missing$ + { journal emphasize "journal" output.check + format.vol.num.pages output + format.date "year" output.check + } + { format.article.crossref output.nonnull + format.pages output + } + if$ + new.block + output.doi + new.block + format.eprint output + new.block + note output + fin.entry +} + +FUNCTION {book} +{ output.bibitem + author empty$ + { format.editors "author and editor" output.check } + { format.authors output.nonnull + crossref missing$ + { "author and editor" editor either.or.check } + 'skip$ + if$ + } + if$ + new.block + format.btitle "title" output.check + crossref missing$ + { format.bvolume output + new.block + format.number.series output + new.sentence + publisher "publisher" output.check + address output + } + { new.block + format.book.crossref output.nonnull + } + if$ + format.edition output + format.date "year" output.check + new.block + output.doi + new.block + note output + fin.entry +} + +FUNCTION {booklet} +{ output.bibitem + format.authors output + new.block + format.title "title" output.check + howpublished address new.block.checkb + howpublished output + address output + format.date output + new.block + output.doi + new.block + format.eprint output + new.block + note output + fin.entry +} + +FUNCTION {inbook} +{ output.bibitem + author empty$ + { format.editors "author and editor" output.check } + { format.authors output.nonnull + crossref missing$ + { "author and editor" editor either.or.check } + 'skip$ + if$ + } + if$ + new.block + format.btitle "title" output.check + crossref missing$ + { format.bvolume output + format.chapter.pages "chapter and pages" output.check + new.block + format.number.series output + new.sentence + publisher "publisher" output.check + address output + } + { format.chapter.pages "chapter and pages" output.check + new.block + format.book.crossref output.nonnull + } + if$ + format.edition output + format.date "year" output.check + new.block + output.doi + new.block + format.eprint output + new.block + note output + fin.entry +} + +FUNCTION {incollection} +{ output.bibitem + format.authors "author" output.check + new.block + format.title "title" output.check + new.block + crossref missing$ + { format.in.ed.booktitle "booktitle" output.check + format.bvolume output + format.number.series output + format.chapter.pages output + new.sentence + publisher "publisher" output.check + address output + format.edition output + format.date "year" output.check + } + { format.incoll.inproc.crossref output.nonnull + format.chapter.pages output + } + if$ + new.block + output.doi + new.block + format.eprint output + new.block + note output + fin.entry +} + +FUNCTION {inproceedings} +{ output.bibitem + format.authors "author" output.check + new.block + format.title "title" output.check + new.block + crossref missing$ + { format.in.ed.booktitle "booktitle" output.check + format.bvolume output + format.number.series output + format.pages output + address empty$ + { organization publisher new.sentence.checkb + organization output + publisher output + format.date "year" output.check + } + { address output.nonnull + format.date "year" output.check + new.sentence + organization output + publisher output + } + if$ + } + { format.incoll.inproc.crossref output.nonnull + format.pages output + } + if$ + new.block + output.doi + new.block + format.eprint output + new.block + note output + fin.entry +} + +FUNCTION {conference} { inproceedings } + +FUNCTION {manual} +{ output.bibitem + author empty$ + { organization empty$ + 'skip$ + { organization output.nonnull + address output + } + if$ + } + { format.authors output.nonnull } + if$ + new.block + format.btitle "title" output.check + author empty$ + { organization empty$ + { address new.block.checka + address output + } + 'skip$ + if$ + } + { organization address new.block.checkb + organization output + address output + } + if$ + format.edition output + format.date output + new.block + output.doi + new.block + format.eprint output + new.block + note output + fin.entry +} + +FUNCTION {mastersthesis} +{ output.bibitem + format.authors "author" output.check + new.block + format.title "title" output.check + new.block + "Master's thesis" format.thesis.type output.nonnull + school "school" output.check + address output + format.date "year" output.check + new.block + output.doi + new.block + format.eprint output + new.block + note output + fin.entry +} + +FUNCTION {misc} +{ output.bibitem + format.authors output + title howpublished new.block.checkb + format.title output + howpublished new.block.checka + howpublished output + format.date output + new.block + output.doi + new.block + format.eprint output + new.block + note output + fin.entry + empty.misc.check +} + +FUNCTION {phdthesis} +{ output.bibitem + format.authors "author" output.check + new.block + format.btitle "title" output.check + new.block + "PhD thesis" format.thesis.type output.nonnull + school "school" output.check + address output + format.date "year" output.check + new.block + output.doi + new.block + format.eprint output + new.block + note output + fin.entry +} + +FUNCTION {proceedings} +{ output.bibitem + editor empty$ + { organization output } + { format.editors output.nonnull } + if$ + new.block + format.btitle "title" output.check + format.bvolume output + format.number.series output + address empty$ + { editor empty$ + { publisher new.sentence.checka } + { organization publisher new.sentence.checkb + organization output + } + if$ + publisher output + format.date "year" output.check + } + { address output.nonnull + format.date "year" output.check + new.sentence + editor empty$ + 'skip$ + { organization output } + if$ + publisher output + } + if$ + new.block + output.doi + new.block + format.eprint output + new.block + note output + fin.entry +} + +FUNCTION {techreport} +{ output.bibitem + format.authors "author" output.check + new.block + format.title "title" output.check + new.block + format.tr.number output.nonnull + institution "institution" output.check + address output + format.date "year" output.check + new.block + output.doi + new.block + format.eprint output + new.block + note output + fin.entry +} + +FUNCTION {unpublished} +{ output.bibitem + format.authors "author" output.check + new.block + format.title "title" output.check + new.block + output.doi + new.block + format.eprint output + new.block + note "note" output.check + format.date output + fin.entry +} + +FUNCTION {default.type} { misc } + +MACRO {jan} {"January"} + +MACRO {feb} {"February"} + +MACRO {mar} {"March"} + +MACRO {apr} {"April"} + +MACRO {may} {"May"} + +MACRO {jun} {"June"} + +MACRO {jul} {"July"} + +MACRO {aug} {"August"} + +MACRO {sep} {"September"} + +MACRO {oct} {"October"} + +MACRO {nov} {"November"} + +MACRO {dec} {"December"} + +MACRO {acmcs} {"ACM Computing Surveys"} + +MACRO {acta} {"Acta Informatica"} + +MACRO {cacm} {"Communications of the ACM"} + +MACRO {ibmjrd} {"IBM Journal of Research and Development"} + +MACRO {ibmsj} {"IBM Systems Journal"} + +MACRO {ieeese} {"IEEE Transactions on Software Engineering"} + +MACRO {ieeetc} {"IEEE Transactions on Computers"} + +MACRO {ieeetcad} + {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"} + +MACRO {ipl} {"Information Processing Letters"} + +MACRO {jacm} {"Journal of the ACM"} + +MACRO {jcss} {"Journal of Computer and System Sciences"} + +MACRO {scp} {"Science of Computer Programming"} + +MACRO {sicomp} {"SIAM Journal on Computing"} + +MACRO {tocs} {"ACM Transactions on Computer Systems"} + +MACRO {tods} {"ACM Transactions on Database Systems"} + +MACRO {tog} {"ACM Transactions on Graphics"} + +MACRO {toms} {"ACM Transactions on Mathematical Software"} + +MACRO {toois} {"ACM Transactions on Office Information Systems"} + +MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"} + +MACRO {tcs} {"Theoretical Computer Science"} + +READ + +FUNCTION {sortify} +{ purify$ + "l" change.case$ +} + +INTEGERS { len } + +FUNCTION {chop.word} +{ 's := + 'len := + s #1 len substring$ = + { s len #1 + global.max$ substring$ } + 's + if$ +} + +FUNCTION {sort.format.names} +{ 's := + #1 'nameptr := + "" + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { nameptr #1 > + { " " * } + 'skip$ + if$ + s nameptr "{vv{ } }{ll{ }}{ ff{ }}{ jj{ }}" format.name$ 't := + nameptr numnames = t "others" = and + { "et al" * } + { t sortify * } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + +FUNCTION {sort.format.title} +{ 't := + "A " #2 + "An " #3 + "The " #4 t chop.word + chop.word + chop.word + sortify + #1 global.max$ substring$ +} + +FUNCTION {author.sort} +{ author empty$ + { key empty$ + { "to sort, need author or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {author.editor.sort} +{ author empty$ + { editor empty$ + { key empty$ + { "to sort, need author, editor, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { editor sort.format.names } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {author.organization.sort} +{ author empty$ + { organization empty$ + { key empty$ + { "to sort, need author, organization, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { "The " #4 organization chop.word sortify } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {editor.organization.sort} +{ editor empty$ + { organization empty$ + { key empty$ + { "to sort, need editor, organization, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { "The " #4 organization chop.word sortify } + if$ + } + { editor sort.format.names } + if$ +} + +FUNCTION {presort} +{ type$ "book" = + type$ "inbook" = + or + 'author.editor.sort + { type$ "proceedings" = + 'editor.organization.sort + { type$ "manual" = + 'author.organization.sort + 'author.sort + if$ + } + if$ + } + if$ + " " + * + year field.or.null sortify + * + " " + * + title field.or.null + sort.format.title + * + #1 entry.max$ substring$ + 'sort.key$ := +} + +ITERATE {presort} + +SORT + +STRINGS { longest.label } + +INTEGERS { number.label longest.label.width } + +FUNCTION {initialize.longest.label} +{ "" 'longest.label := + #1 'number.label := + #0 'longest.label.width := +} + +FUNCTION {longest.label.pass} +{ number.label int.to.str$ 'label := + number.label #1 + 'number.label := + label width$ longest.label.width > + { label 'longest.label := + label width$ 'longest.label.width := + } + 'skip$ + if$ +} + +EXECUTE {initialize.longest.label} + +ITERATE {longest.label.pass} + +FUNCTION {begin.bib} +{ preamble$ empty$ + 'skip$ + { preamble$ write$ newline$ } + if$ + "\begin{thebibliography}{" longest.label * "}" * write$ newline$ +} + +EXECUTE {begin.bib} + +EXECUTE {init.state.consts} + +ITERATE {call.type$} + +FUNCTION {end.bib} +{ newline$ + "\end{thebibliography}" write$ newline$ +} + +EXECUTE {end.bib} diff --git a/paper/juliacon.cls b/paper/juliacon.cls new file mode 100644 index 0000000..e2c156f --- /dev/null +++ b/paper/juliacon.cls @@ -0,0 +1,944 @@ +%% juliacon.cls - version 1.0 + +%% Inspired by the template from the International Journal of Computer Applications (IJCA) + +\usepackage[scaled=0.92]{helvet} +\def\fileversion{v1.0} +\def\filedate{2019 04 07} +% +\NeedsTeXFormat{LaTeX2e} +\ProvidesClass{juliacon} +\RequirePackage{latexsym} +\RequirePackage{url} + +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} + +\newif\ifmanuscript +\@twosidetrue\@mparswitchtrue +% +\newdimen\trimheight +\newdimen\trimwidth +\newdimen\typeheight +\newdimen\typewidth +\newdimen\normaltextheight +\newdimen\blindfoliodrop +\newbox\tempbox +%% + +\input{journal_dat} + +% +\frenchspacing % oh lala bravo quelle belle idée +\DeclareOption{manuscript}{\manuscripttrue} +\DeclareOption{letterpaper} + {\setlength\paperheight {11.69in}% + \setlength\paperwidth {8.27in}% + \def\special@paper{8.5in,11in} + \special{papersize=8.5in,11in}} + +\DeclareOption{openbib}{% + \AtEndOfPackage{% + \renewcommand\@openbib@code{% + \advance\leftmargin\bibindent + \itemindent -\bibindent + \listparindent \itemindent + \parsep \z@ + }% + \renewcommand\newblock{\par}}% +} +% +\ExecuteOptions{letterpaper} +\ProcessOptions +% +\newcommand\refname{References} +\newcommand{\ignoretwo}[2]{} +\newcommand{\yearTwoDigits}{\expandafter\ignoretwo\the\year} +\def\@setref#1#2#3{% + \ifx#1\relax + \number 0\relax + \protect\G@refundefinedtrue + \nfss@text{\reset@font\bfseries ??}% + \@latex@warning{Reference `#3' on page \thepage \space undefined}% + \else + \expandafter#2#1\null + \fi} +% +% +\lineskip 1pt \normallineskip 1pt +\ifmanuscript +\def\baselinestretch{2} +\else +\def\baselinestretch{1} +\fi +\def\@ixpt{9} +\renewcommand\normalsize{% + \@setfontsize\normalsize\@ixpt{10pt} + \abovedisplayskip 6pt plus2pt minus1pt\belowdisplayskip \abovedisplayskip + \abovedisplayshortskip 6pt plus0pt minus 3pt + \belowdisplayshortskip 6pt plus0pt minus3pt\let\@listi\@listI} + +\newcommand\small{% + \@setfontsize\small\@ixpt{11pt}% + \abovedisplayskip 5pt plus 2pt minus 1pt\belowdisplayskip \abovedisplayskip + \abovedisplayshortskip 5pt plus0pt minus2pt\belowdisplayshortskip 5pt plus0pt + minus 2pt + \def\@listi{\leftmargin\leftmargini \topsep 5pt plus 2pt minus 1pt\parsep 0pt + plus .7pt + \itemsep 1.6pt plus .8pt}} +\newcommand\footnotesize{% +% \@setfontsize\footnotesize\@viiipt{10pt} + \@setsize\footnotesize{10pt}\viiipt\@viiipt + \abovedisplayskip 4pt plus 1pt minus 0pt\belowdisplayskip \abovedisplayskip + \abovedisplayshortskip 4pt plus 0pt minus 1pt\belowdisplayshortskip 4pt plus + 0pt minus 1pt + \def\@listi{\leftmargin\leftmargini \topsep 4pt plus 1pt minus + 0pt\parsep 0pt plus .5pt + \itemsep 1pt plus .7pt}} + +\newcommand\scriptsize{\@setfontsize\scriptsize\@viipt\@viiipt} +\newcommand\tiny{\@setfontsize\tiny\@vpt\@vipt} +\newcommand\large{\@setfontsize\large\@xiipt{14}} +\newcommand\Large{\@setfontsize\Large\@xivpt{18}} +\newcommand\LARGE{\@setfontsize\LARGE\@xviipt{20}} +\newcommand\huge{\@setfontsize\huge\@xxpt{25}} +\newcommand\Huge{\@setfontsize\Huge\@xxvpt{30}} +% +\normalsize +% +\newdimen\tempdimen +% +\setlength\trimheight{11in} +\setlength\trimwidth{8.5in} +% +\typeheight52.5pc +\typewidth42pc +\textheight52.5pc +\textwidth42pc +\advance\textheight-3pt +\newdimen\normaltextheight +\setlength\normaltextheight{\textheight} +\oddsidemargin4.5pc +\evensidemargin4.5pc +\topmargin20pt %.25in +\headheight 6pt% +\headsep 29.2pt% +\topskip6pt% +\footskip 100pt +% +\marginparwidth 0.5in +\marginparsep .125in +\columnsep24pt +\columnseprule 0pt +% +\def\titlefont{\huge\selectfont\centering\mathversion{bold}} +\def\authorfont{\fontfamily{phv}\fontsize{10}{12}\selectfont\rightskip0pt plus1fill} %\mathversion{sfnormal} +\def\rhfont{\fontfamily{phv}\fontsize{9}{10}\selectfont\mathversion{sfnormal}} + +\def\sectionfont{\fontfamily{ptm}\fontsize{9}{12}\capsshape\selectfont\raggedright} %\mathversion{rmnormal} +\def\subsectionfont{\fontfamily{ptm}\fontsize{9}{12}\selectfont} %\mathversion{rmnormal} +\def\figcaptionfont{\fontsize{8}{10}\selectfont\mathversion{normal}}% +\def\subcaptionfont{\fontsize{8}{10}\selectfont\mathversion{normal}}% +\def\subcaption#1{{\centering\subcaptionfont#1\par}} +% +\def\tablefont{\fontsize{8}{10}\selectfont}% +\def\tablecaptionfont{\fontsize{9}{11}\selectfont\centering}% +\def\tablenumfont{\fontsize{9}{11}\selectfont}% +\def\tabnotefont{\fontsize{7}{9}\selectfont} +% +\def\encodingdefault{OT1}% +\fontencoding{OT1}% +% +\DeclareFontShape{OMS}{cmsy}{m}{n}{<-> cmsy10 }{} +\DeclareFontShape{OMS}{cmsy}{b}{n}{<-> cmbsy10 }{} +\def\cal{\mathcal} +% +\def\boldmath{\mathversion{bold}} +\def\bm#1{\mathchoice + {\mbox{\boldmath$\displaystyle#1$}}% + {\mbox{\boldmath$#1$}}% + {\mbox{\boldmath$\scriptstyle#1$}}% + {\mbox{\boldmath$\scriptscriptstyle#1$}}} +% +\footnotesep 7pt +\skip\footins 15pt plus 4pt minus 3pt +\floatsep 12pt plus 2pt minus 2pt +\textfloatsep \floatsep +\intextsep 1pc plus 1pc +\dblfloatsep 12pt plus 2pt minus 2pt +\dbltextfloatsep 20pt plus 2pt minus 4pt +\@fptop 0pt plus 1fil \@fpsep 1pc plus 2fil \@fpbot 0pt plus 1fil +\@dblfptop 0pt plus 1fil \@dblfpsep 8pt plus 2fil \@dblfpbot 0pt plus 1fil +\marginparpush 6pt +\parskip 0pt \parindent 0pt \partopsep 0pt % plus .1pt FBU +\@lowpenalty 51 \@medpenalty 151 \@highpenalty 301 +\@beginparpenalty -\@lowpenalty \@endparpenalty -\@lowpenalty \@itempenalty +-\@lowpenalty +% +\def\part{\@ucheadtrue + \@startsection{part}{9}{\z@}{-10pt plus -4pt minus + -2pt}{4pt}{\reset@font\normalsize\rmfamily}} +\def\section{\@ucheadtrue + \@startsection{section}{1}{\z@}{-10pt plus -4pt minus + -2pt}{6pt}{\reset@font\fontsize{10}{12}\raggedright\rmfamily\bfseries}} +\def\subsection{\@ucheadfalse + \@startsection{subsection}{2}{\z@}{-8pt plus -2pt minus + -1pt}{6pt}{\reset@font\fontsize{10}{12}\raggedright\rmfamily\bfseries}} +\def\subsubsection{\@ucheadfalse + \@startsection{subsubsection}{3}{\parindent}{6pt plus +1pt}{-5pt}{\reset@font\fontsize{9}{10}\itshape}} +\def\paragraph{\@ucheadfalse + \@startsection{paragraph}{3}{\parindent}{6pt plus +1pt}{-5pt}{\reset@font\fontsize{10}{12}\itshape}} +%% +\renewcommand{\@seccntformat}[1]{\textup{\csname the#1\endcsname}} +\gdef\@period{.} +\def\@trivlist{\@topsepadd\topsep +\if@noskipsec \gdef\@period{}\leavevmode\gdef\@period{.}\fi + \ifvmode \advance\@topsepadd\partopsep \else \unskip\par\fi + \if@inlabel \@noparitemtrue \@noparlisttrue + \else \@noparlistfalse \@topsep\@topsepadd \fi + \advance\@topsep \parskip + \leftskip\z@\rightskip\@rightskip \parfillskip\@flushglue + \@setpar{\if@newlist\else{\@@par}\fi} \global\@newlisttrue +\@outerparskip\parskip} +% +\def\@startsection#1#2#3#4#5#6{% + \if@noskipsec \leavevmode \fi + \par + \@tempskipa #4\relax + \@afterindenttrue + \ifdim \@tempskipa <\z@ + \@tempskipa -\@tempskipa \@afterindentfalse + \fi + \if@nobreak + \everypar{}% + \ifnum#2=2 + \vskip-2pt + \fi + \else + \addpenalty\@secpenalty\addvspace\@tempskipa + \fi + \@ifstar + {\@ssect{#3}{#4}{#5}{#6}}% + {\@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}}} +% +\def\@sect#1#2#3#4#5#6[#7]#8{% + \ifnum #2>\c@secnumdepth + \let\@svsec\@empty + \else + \refstepcounter{#1}% + \if@uchead% + \protected@edef\@svsec{\@seccntformat{#1}.\quad\relax}% + \else% + \protected@edef\@svsec{\@seccntformat{#1}\quad\relax}% + \fi% + \fi + \@tempskipa #5\relax + \ifdim \@tempskipa>\z@ + \begingroup + #6{% + \@hangfrom{\hskip #3\relax\@svsec}% + \interlinepenalty \@M #8 \@@par}% + \endgroup + \csname #1mark\endcsname{#7}% + \addcontentsline{toc}{#1}{% + \ifnum #2>\c@secnumdepth \else + \protect\numberline{\csname the#1\endcsname}% + \fi + #7}% + \else + \def\@svsechd{% + #6{\hskip #3\relax + \@svsec \if@uchead\Makeuppercase{#8}\else#8\fi}% + \csname #1mark\endcsname{#7}% + \addcontentsline{toc}{#1}{% + \ifnum #2>\c@secnumdepth \else + \protect\numberline{\csname the#1\endcsname}% + \fi + #7}}% + \fi + \@xsect{#5}} + +\def\@xsect#1{\@tempskipa #1\relax + \ifdim \@tempskipa>\z@ + \par \nobreak + \vskip \@tempskipa + \@afterheading + \else \global\@nobreakfalse \global\@noskipsectrue + \everypar{\if@noskipsec \global\@noskipsecfalse + \clubpenalty\@M \hskip -\parindent + \begingroup \@svsechd\@period \endgroup \unskip + \hskip -#1 + \else \clubpenalty \@clubpenalty + \everypar{}\fi}\fi\ignorespaces} +\newif\if@uchead\@ucheadfalse +% +\setcounter{secnumdepth}{3} +\newcounter{secnumbookdepth} +\setcounter{secnumbookdepth}{3} +\newfont{\apbf}{cmbx9} +\def\appendix{\par + \setcounter{section}{0} + \setcounter{subsection}{0} + \section*{APPENDIX}\vskip10pt + \def\thesection{\Alph{section}} + \def\theHsection{\Alph{section}}} +% +\labelsep 4pt +\settowidth{\leftmargini}{(9)} \addtolength\leftmargini\labelsep +\settowidth{\leftmarginii}{(b)} \addtolength\leftmarginii\labelsep +\leftmarginiii \leftmarginii +\leftmarginiv \leftmarginii +\leftmarginv \leftmarginii +\leftmarginvi \leftmarginii +\leftmargin\leftmargini +\labelwidth\leftmargini\advance\labelwidth-\labelsep +\def\@listI{\leftmargin\leftmargini \parsep 0pt plus 1pt\topsep 6pt plus 2pt +minus 2pt\itemsep 2pt plus 1pt minus .5pt} +\let\@listi\@listI +\@listi +\def\@listii{\leftmargin\leftmarginii + \labelwidth\leftmarginii\advance\labelwidth-\labelsep + \topsep 0pt plus 1pt + \parsep 0pt plus .5pt + \itemsep \parsep} +\def\@listiii{\leftmargin\leftmarginiii + \labelwidth\leftmarginiii\advance\labelwidth-\labelsep + \topsep 0pt plus 1pt + \parsep 0pt plus .5pt + \itemsep \parsep} +\def\@listiv{\leftmargin\leftmarginiv + \labelwidth\leftmarginiv\advance\labelwidth-\labelsep} +\def\@listv{\leftmargin\leftmarginv + \labelwidth\leftmarginv\advance\labelwidth-\labelsep} +\def\@listvi{\leftmargin\leftmarginvi + \labelwidth\leftmarginvi\advance\labelwidth-\labelsep} +% +\def\enumerate{\ifnum \@enumdepth >3 \@toodeep\else + \advance\@enumdepth \@ne + \edef\@enumctr{enum\romannumeral\the\@enumdepth}\list + {\csname label\@enumctr\endcsname}{\usecounter + {\@enumctr}\def\makelabel##1{##1\hss}}\fi} +\def\longenum{\ifnum \@enumdepth >3 \@toodeep\else + \advance\@enumdepth \@ne + \edef\@enumctr{enum\romannumeral\the\@enumdepth}\list + {\csname label\@enumctr\endcsname}{\usecounter + {\@enumctr}\labelwidth\z@}\fi} +\let\endlongenum\endlist +\def\labelenumi{{\rm (}\arabic{enumi}\/{\rm )}} +\def\theenumi{\arabic{enumi}} +\def\labelenumii{{\rm (}\alph{enumii}\rm{)}} +\def\theenumii{\alph{enumii}} +\def\p@enumii{\theenumi} +\def\labelenumiii{\roman{enumiii}.} +\def\theenumiii{\roman{enumiii}} +\def\p@enumiii{\theenumi{\rm (}\theenumii{\rm )}} +\def\labelenumiv{\Alph{enumiv}.} +\def\theenumiv{\Alph{enumiv}} +\renewcommand\theenumiv{\@Alph\c@enumiv} +\def\p@enumiv{\p@enumiii\theenumiii} + +\def\p@enumiv{\p@enumiii\theenumiii} + +\renewcommand\p@enumii{\theenumi} +\renewcommand\p@enumiii{\theenumi(\theenumii)} +\renewcommand\p@enumiv{\p@enumiii\theenumiii} + +\def\itemize{\list{---\hskip -\labelsep}{\settowidth + {\leftmargin}{---}\labelwidth\leftmargin + \addtolength{\labelwidth}{-\labelsep}}} +\let\enditemize\endlist +\def\longitem{\list{---}{\labelwidth\z@ + \leftmargin\z@ \itemindent\parindent \advance\itemindent\labelsep}} +\let\endlongitem\endlist +\def\verse{\let\\=\@centercr + \list{}{\leftmargin 2pc + \itemindent -1.5em\listparindent \itemindent + \rightmargin\leftmargin\advance\leftmargin 1.5em}\item[]} +\let\endverse\endlist +\def\quotation{\list{}{\leftmargin 2pc \listparindent .5em + \itemindent\listparindent + \rightmargin\leftmargin \parsep 0pt plus 1pt}\item[]} +\let\endquotation=\endlist +\def\quote{\list{}{\leftmargin 2pc \rightmargin\leftmargin}\item[]} +\let\endquote=\endlist + +% +\newenvironment{unnumlist}{% + \list{}{% + \listparindent\parindent + \itemindent-1em + \leftmargin1em + \parsep0pt + \itemsep2pt + \partopsep0pt} + \def\makelable##1{##1}% +}{\endlist}% +% +\def\description{\list{}{\listparindent\parindent\labelwidth\z@ + \leftmargin\z@ \itemindent\parindent\advance\itemindent\labelsep + \def\makelabel##1{\it ##1}}} +\let\enddescription\endlist +% +\def\describe#1{\list{}{\listparindent\parindent\settowidth{\labelwidth}{#1}\leftmargin + \labelwidth\addtolength\leftmargin\labelsep\def\makelabel##1{##1\hfil}}} +\let\enddescribe\endlist +% +\def\program{\ifx\@currsize\normalsize\small \else \rm \fi\tabbing} +\let\endprogram\endtabbing +% +\newtheorem{theorem}{Theorem} +\newtheorem{strategy}{Strategy} +\newtheorem{property}{Property} +\newtheorem{proposition}{Proposition} +\newtheorem{lemma}[theorem]{Lemma} +\newtheorem{exam}{Example} +\newenvironment{example}{% +\italicenvfalse +\begin{exam}}{\end{exam}\italicenvtrue} +% +\newtheorem{defi}[theorem]{Definition} +\newenvironment{definition}{% +\italicenvfalse +\begin{defi}}{\end{defi}\italicenvtrue} +% +\def\@begintheorem#1#2{\trivlist \item[\hskip 10pt\hskip + \labelsep{\sc{#1}\hskip 5pt\relax #2.}] \itshape} +% +\def\@opargbegintheorem#1#2#3{\trivlist + \item[\hskip 10pt \hskip +\labelsep{\sc{#1}\savebox\@tempboxa{\sc{#3}}\ifdim + \wd\@tempboxa>\z@ \hskip 5pt\relax \sc{#2} \box\@tempboxa\fi.}] +\itshape} +% +\newif\if@qeded\global\@qededfalse +\def\proof{\global\@qededfalse\@ifnextchar[{\@xproof}{\@proof}} +\def\endproof{\if@qeded\else\qed\fi\endtrivlist} +\def\qed{\unskip\kern 10pt{\unitlength1pt\linethickness{.4pt}\framebox(5,5){}} +\global\@qededtrue} +\def\@proof{\trivlist \item[\hskip 10pt\hskip + \labelsep{\sc Proof.}]\ignorespaces} +\def\@xproof[#1]{\trivlist \item[\hskip 10pt\hskip + \labelsep{\sc Proof #1.}]\ignorespaces} +% +\def\newdef#1#2{\expandafter\@ifdefinable\csname #1\endcsname +{\@definecounter{#1}\expandafter\xdef\csname +the#1\endcsname{\@thmcounter{#1}}\global + \@namedef{#1}{\@defthm{#1}{#2}}\global + \@namedef{end#1}{\@endtheorem}}} +\def\@defthm#1#2{\refstepcounter + {#1}\@ifnextchar[{\@ydefthm{#1}{#2}}{\@xdefthm{#1}{#2}}} +\def\@xdefthm#1#2{\@begindef{#2}{\csname the#1\endcsname}\ignorespaces} +\def\@ydefthm#1#2[#3]{\trivlist \item[\hskip 10pt\hskip + \labelsep{\it #2\savebox\@tempboxa{#3}\ifdim + \wd\@tempboxa>\z@ \ \box\@tempboxa\fi.}]\ignorespaces} +\def\@begindef#1#2{\trivlist \item[\hskip 10pt\hskip + \labelsep{\it #1\ \rm #2.}]} +% +\def\theequation{\arabic{equation}} +% +\def\titlepage{\@restonecolfalse\if@twocolumn\@restonecoltrue\onecolumn + \else \newpage \fi \thispagestyle{empty}\c@page\z@} +\def\endtitlepage{\if@restonecol\twocolumn \else \newpage \fi} +% +\arraycolsep 2.5pt \tabcolsep 6pt \arrayrulewidth .4pt \doublerulesep 2pt +\tabbingsep \labelsep +% +\skip\@mpfootins = \skip\footins +\fboxsep = 3pt \fboxrule = .4pt +% +\newcounter{part} +\newcounter{section} +\newcounter{subsection}[section] +\newcounter{subsubsection}[subsection] +\newcounter{paragraph}[subsubsection] +% +\def\thepart{\Roman{part}} +\def\thesection {\arabic{section}} +\def\thesubsection {\thesection.\arabic{subsection}} +\def\thesubsubsection {\itshape\thesubsection.\arabic{subsubsection}} +\def\theparagraph {\thesubsubsection.\arabic{paragraph}} + +\def\@pnumwidth{1.55em} +\def\@tocrmarg {2.55em} +\def\@dotsep{4.5} +\setcounter{tocdepth}{3} + +\def\tableofcontents{\section*{Contents\@mkboth{CONTENTS}{CONTENTS}} + \@starttoc{toc}} +\def\l@part#1#2{\addpenalty{\@secpenalty} + \addvspace{2.25em plus 1pt} \begingroup + \@tempdima 3em \parindent \z@ \rightskip \@pnumwidth \parfillskip +-\@pnumwidth + {\large \bf \leavevmode #1\hfil \hbox to\@pnumwidth{\hss #2}}\par + \nobreak \endgroup} +\def\l@section#1#2{\addpenalty{\@secpenalty} \addvspace{1.0em plus 1pt} +\@tempdima 1.5em \begingroup + \parindent \z@ \rightskip \@pnumwidth + \parfillskip -\@pnumwidth + \bf \leavevmode #1\hfil \hbox to\@pnumwidth{\hss #2}\par + \endgroup} +\def\l@subsection{\@dottedtocline{2}{1.5em}{2.3em}} +\def\l@subsubsection{\@dottedtocline{3}{3.8em}{3.2em}} +\def\listoffigures{\section*{List of Figures\@mkboth + {LIST OF FIGURES}{LIST OF FIGURES}}\@starttoc{lof}} +\def\l@figure{\@dottedtocline{1}{1.5em}{2.3em}} +\def\listoftables{\section*{List of Tables\@mkboth + {LIST OF TABLES}{LIST OF TABLES}}\@starttoc{lot}} +\let\l@table\l@figure +% +\newif\if@restonecol +\def\theindex{\@restonecoltrue\if@twocolumn\@restonecolfalse\fi +\columnseprule \z@ +\columnsep 35pt\twocolumn[\section*{Index}] + \@mkboth{INDEX}{INDEX}\thispagestyle{plain}\parindent\z@ + \parskip\z@ plus .3pt\relax\let\item\@idxitem} +\def\@idxitem{\par\hangindent 40pt} +\def\subitem{\par\hangindent 40pt \hspace*{20pt}} +\def\subsubitem{\par\hangindent 40pt \hspace*{30pt}} +\def\endtheindex{\if@restonecol\onecolumn\else\clearpage\fi} +\def\indexspace{\par \vskip 10pt plus 5pt minus 3pt\relax} +% +\def\footnoterule{\kern-3\p@ + \hrule \@height 0.2\p@ \@width 47\p@ + \kern 2.6\p@ +} + +\long\def\@makefntext#1{\parindent 1em\noindent + $^{\@thefnmark}$#1} +% +\setcounter{topnumber}{3} +\def\topfraction{.99} +\setcounter{bottomnumber}{1} +\def\bottomfraction{.5} +\setcounter{totalnumber}{3} +\def\textfraction{.01} +\def\floatpagefraction{.85} +\setcounter{dbltopnumber}{2} +\def\dbltopfraction{.95} +\def\dblfloatpagefraction{.96} +% +\long\def\@makecaption#1#2{\vskip 1pc \setbox\@tempboxa\hbox{#1.\hskip +1em\relax #2} + \ifdim \wd\@tempboxa >\hsize #1. #2\par \else \hbox +to\hsize{\hfil\box\@tempboxa\hfil} + \fi} + +\def\nocaption{\refstepcounter\@captype \par + \vskip 1pc \hbox to\hsize{\hfil \footnotesize Figure \thefigure + \hfil}} +% +\newcounter{figure} +\def\thefigure{\@arabic\c@figure} +\def\fps@figure{tbp} +\def\ftype@figure{1} +\def\ext@figure{lof} +\def\fnum@figure{Fig.\ \thefigure}% +\def\figure{\let\normalsize\footnotesize\normalsize\@float{figure}} +\let\endfigure\end@float +\@namedef{figure*}{\@dblfloat{figure}} +\@namedef{endfigure*}{\end@dblfloat} +% +\newcounter{table} +\def\thetable{\@arabic\c@table} +\def\fps@table{tbp} +\def\ftype@table{2} +\def\ext@table{lot} +\newlength\belowcaptionskip +\setlength\belowcaptionskip{1\p@} +% +\def\FigName{figure}% +\long\def\@caption#1[#2]#3{\par\begingroup + \@parboxrestore + \normalsize \bf \centering + \@makecaption{\csname fnum@#1\endcsname}{\ignorespaces #3}\par + \endgroup} +% +% +\newbox\tbbox +\long\def\@makecaption#1#2{% + \ifx\FigName\@captype + \vskip 7.3pt + \setbox\@tempboxa\hbox{\figcaptionfont{#1}.\hskip7.3pt\relax #2\par}% + \ifdim \wd\@tempboxa >\hsize + \figcaptionfont{#1}.\hskip7.3pt\relax #2\par + \else + \centerline{\box\@tempboxa}% + \fi + \else% + \setbox\tbbox=\vbox{\hsize\tempdimen{\tablenumfont #1}\ {\tablecaptionfont #2\par}}% + \setbox\@tempboxa\hbox{\hsize\tempdimen{\tablenumfont #1}\ {\tablecaptionfont #2\par}\vphantom{jgq}}% + \ifdim \wd\@tempboxa >\tempdimen + \centerline{\box\tbbox}% + \else + \centerline{\box\@tempboxa}% + \fi + \vskip\belowcaptionskip + \fi} +% +\def\fnum@table{Table~\thetable.\ } +\def\table{\let\normalsize\footnotesize \normalsize\@float{table}} +\let\endtable\end@float +\@namedef{table*}{\@dblfloat{table}} +\@namedef{endtable*}{\end@dblfloat} +\def\ijcatable#1{\@narrowfig #1\relax + \let\caption\@atcap \let\nocaption\@atnocap + \def\@tmpnf{}\@ifnextchar[{\@xntab}{\@ntab}} +\def\endijcatable{\hbox to \textwidth{\hfil +\vbox{\hsize \@narrowfig +\box\@nfcapbox +{\baselineskip 4pt \hbox{\vrule height .4pt width \hsize}} +\vskip -1pt +\box\@nfigbox\vskip -1pt +{\baselineskip 4pt \hbox{\vrule height .4pt width \hsize}}}\hfil} +\end@float} +\def\@xntab[#1]{\def\@tmpnf{[#1]}\@ntab} +\def\@ntab{\expandafter\table\@tmpnf + \setbox\@nfigbox\vbox\bgroup + \hsize \@narrowfig \@parboxrestore} +\def\@atmakecap #1#2{\setbox\@tempboxa\hbox{#1.\hskip 1em\relax #2} + \ifdim \wd\@tempboxa >\hsize \sloppy #1.\hskip 1em\relax #2 \par \else \hbox +to\hsize{\hfil\box\@tempboxa\hfil} + \fi} +\def\@atcap{\par\egroup\refstepcounter\@captype + \@dblarg{\@atcapx\@captype}} +\long\def\@atcapx#1[#2]#3{\setbox\@nfcapbox\vbox {\hsize \wd\@nfigbox + \@parboxrestore + \@atmakecap{\csname fnum@#1\endcsname}{\ignorespaces #3}\par}} +\def\@atnocap{\egroup \refstepcounter\@captype + \setbox\@nfcapbox\vbox {\hsize \wd\@nfigbox + \hbox to\hsize{\hfil \footnotesize Table \thetable\hfil}}} +% +\newdimen\tabledim +% +\long\def\tbl#1#2{% + \setbox\tempbox\hbox{\tablefont #2}% + \tabledim\hsize\advance\tabledim by -\wd\tempbox + \tempdimen\wd\tempbox + \global\divide\tabledim\tw@ + \caption{#1} + \centerline{\box\tempbox} + }% +% +\newenvironment{tabnote}{% +\par%\addvspace{-1pt} +\tabnotefont +\@ifnextchar[{\@tabnote}{\@tabnote[]}}{% +\par} +\def\@tabnote[#1]{\def\@Tempa{#1}\leftskip\tabledim\rightskip\leftskip\ifx\@Tempa\@empty\else{\it #1:}\ \fi\ignorespaces} +% +\def\tabnoteentry#1#2{\parindent0pt\par\@hangfrom{#1}{#2}} +\def\Note#1#2{\parindent0pt\par\hangindent3.7pt{\it #1}\ #2} +% + +\def\Hline{% + \noalign{\ifnum0=`}\fi\hrule \@height .5pt \futurelet + \@tempa\@xhline} +% +\def\narrowfig#1{\@narrowfig #1\relax + \let\caption\@nfcap \let\nocaption\@nfnocap + \def\@tmpnf{}\@ifnextchar[{\@xnfig}{\@nfig}} +\def\endnarrowfig{\hbox to \textwidth{\if@nfeven + \box\@nfcapbox\hfil\box\@nfigbox + \else \box\@nfigbox\hfil\box\@nfcapbox\fi}\end@float} +\def\@xnfig[#1]{\def\@tmpnf{[#1]}\@nfig} +\def\@nfig{\expandafter\figure\@tmpnf + \setbox\@nfigbox\vbox\bgroup + \hsize \@narrowfig \@parboxrestore} +\def\@nfmakecap #1#2{\setbox\@tempboxa\hbox{#1.\hskip 1em\relax #2} + \ifdim \wd\@tempboxa >\hsize \sloppy #1.\hskip 1em\relax #2 \par \else \hbox +to\hsize{\if@nfeven\else\hfil\fi\box\@tempboxa\if@nfeven\hfil\fi} + \fi} +\def\@nfcap{\par\egroup\refstepcounter\@captype + \@dblarg{\@nfcapx\@captype}} +\long\def\@nfcapx#1[#2]#3{\@seteven + \setbox\@nfcapbox\vbox to \ht\@nfigbox + {\hsize \textwidth \advance\hsize -2pc \advance\hsize -\wd\@nfigbox + \@parboxrestore + \vfil + \@nfmakecap{\csname fnum@#1\endcsname}{\ignorespaces #3}\par + \vfil}} +\def\@nfnocap{\egroup \refstepcounter\@captype \@seteven + \setbox\@nfcapbox\vbox to \ht\@nfigbox + {\hsize \textwidth \advance\hsize -2pc \advance\hsize -\wd\@nfigbox + \@parboxrestore + \vfil + \hbox to\hsize{\if@nfeven\else\hfil\fi + \footnotesize Figure \thefigure + \if@nfeven\hfil\fi} + \vfil}} +\def\@seteven{\@nfeventrue + \@ifundefined{r@@nf\thefigure}{}{% + \edef\@tmpnf{\csname r@@nf\thefigure\endcsname}% + \edef\@tmpnf{\expandafter\@getpagenum\@tmpnf}% + \ifodd\@tmpnf\relax\@nfevenfalse\fi}% +\label{@nf\thefigure}\edef\@tmpnfx{\if@nfeven e\else o\fi} +\edef\@tmpnf{\write\@unused {\noexpand\ifodd \noexpand\c@page + \noexpand\if \@tmpnfx e\noexpand\@nfmsg{\thefigure} \noexpand\fi + \noexpand\else + \noexpand\if \@tmpnfx o\noexpand\@nfmsg{\thefigure}\noexpand\fi + \noexpand\fi }}\@tmpnf} +\def\@nfmsg#1{Bad narrowfig: Figure #1 on page \thepage} + +\newdimen\@narrowfig +\newbox\@nfigbox +\newbox\@nfcapbox +\newif\if@nfeven + + +\def\maketitle{% + \thispagestyle{titlepage}% + \newpage + \global\@topnum\z@ + \twocolumn[\@maketitle]% + \let\maketitle\relax + \global\let\@sponsors\@empty +} +% +\def\@maketitle{\newpage \thispagestyle{titlepage}\par + \begingroup \lineskip = \z@\null + \vspace{-1.75em} + \begin{picture}(5,5) + \includegraphics[width=1in]{logojuliacon.pdf} + \end{picture} + \vspace{1.75em} + \vskip -7pt\relax %-18.5pt + \parindent\z@ \LARGE {\centering \hyphenpenalty\@M + {\titlefont \@title} \par + \global\firstfoot %aiellom + \global\runningfoot %aiellom +} +\label{@firstpg} +{ +\begin{center}% + \vskip 0.1em% + {\large + \lineskip .75em% + \begin{tabular}[t]{c}% + \@author + \end{tabular}\par}% + \vskip 1.5em% + \end{center}\par + \@thanks +} + \vskip 23pt\relax + \endgroup + } +\newbox\@abstract +\newbox\@terms +\newbox\@keywords + + +% +\newenvironment{abstract} +{\section*{ABSTRACT}\par\fontsize{10}{12}\indent\ignorespaces} +{ + { \ifvoid\@terms\else\box\@terms\fi + \@keywords \@juliaconformat\empty}\vskip6pt} +% +\def\terms#1{\setbox\@terms=\vbox{\hsize20pc% + \footnotesize% + \parindent 0pt \noindent + { \section*{General Terms}} \ignorespaces #1{\vspace{-0.75em}}}} +\def\keywords#1{\gdef\@keywords{\hsize20pc% + \parindent 0pt\noindent\ignorespaces% + {{\vspace{-0.75em}} \section*{Keywords}} \ignorespaces #1{\vspace{1em}}}} +%} + +\def\category#1#2#3{\@ifnextchar + [{\@category{#1}{#2}{#3}}{\@xcategory{#1}{#2}{#3}}} +\def\@category#1#2#3[#4]{\edef\@tempa{\ifx \@categories\@empty + \else ; \fi}{\def\protect{\noexpand\protect + \noexpand}\def\and{\noexpand\and}\xdef\@categories{\@categories\@tempa #1 +[{\bf #2}]: + #3\kern\z@---\hskip\z@{\it #4}}}} +\def\@xcategory#1#2#3{\edef\@tempa{\ifx \@categories\@empty \else ; +\fi}{\def\protect{\noexpand\protect\noexpand}\def\and{\noexpand + \and}\xdef\@categories{\@categories\@tempa #1 [{\bf #2}]: #3}}} +\def\@categories{} + +\newenvironment{ackslike}[1] + {\par \footnotesize + \@ucheadfalse + \@startsection{subsection}{2}{\z@}{-16pt plus -2pt minus -1pt}{2pt}{\sf}* + {\uppercase{#1}}\par\normalsize + } + {\par} +\newenvironment{acks}{\begin{ackslike}{ \normalsize\rm\bf Acknowledgments}}{\end{ackslike}} +% + +\newcommand\headingtable{% + \begin{tabular}[b]{l} {\@journalName}\end{tabular}} +\markright{\protect\headingtable} +\mark{{}{}} +\def\bull{{\fontsize{7}{7}\selectfont\raise1.6pt\hbox{$\bullet$}}} +\def\ps@myheadings{\let\@mkboth\@gobbletwo +\def\@oddhead{ \fontsize{9}{12} \rm {{\itshape\headingtable}\hfill \@volume(\@issue), \@year}} +\def\@oddfoot{\fontsize{9}{12}\@runningfoot} +\def\@evenhead{ \fontsize{9}{12} \rm {\itshape\headingtable}\hfill \@volume(\@issue), \@year} +\def\@evenfoot{\fontsize{9}{12}\@runningfoot} +\def\sectionmark##1{}\def\subsectionmark##1{}} +% +\def\@runningfoot{} +\def\runningfoot{\def\@runningfoot{ \fontsize{9}{12} \thepage}} +\def\@firstfoot{} +\def\firstfoot{\def\@firstfoot{\fontsize{9}{12} \thepage}} +\def\ps@titlepage{\let\@mkboth\@gobbletwo +\def\@oddhead{}\def\@oddfoot{\fontsize{9}{12}\@firstfoot}\def\@evenhead{}\def\@evenfoot{\fontsize{9}{12}\@firstfoot}} +% +\def\today{\ifcase\month\or + January\or February\or March\or April\or May\or June\or + July\or August\or September\or October\or November\or December\fi + \space\number\day, \number\year} +\def\@marrayclassiv{\@addtopreamble{$\displaystyle \@nextchar$}} +\def\@marrayclassz{\ifcase \@lastchclass \@acolampacol \or \@ampacol \or + \or \or \@addamp \or + \@acolampacol \or \@firstampfalse \@acol \fi +\edef\@preamble{\@preamble + \ifcase \@chnum + \hfil$\relax\displaystyle\@sharp$\hfil \or $\relax\displaystyle\@sharp$\hfil + \or \hfil$\relax\displaystyle\@sharp$\fi}} +\def\marray{\arraycolsep 2.5pt\let\@acol\@arrayacol \let\@classz\@marrayclassz + \let\@classiv\@marrayclassiv \let\\\@arraycr\def\@halignto{}\@tabarray} +\def\endmarray{\crcr\egroup\egroup} +% +\ps@myheadings \pagenumbering{arabic} \onecolumn +% +\setlength \labelsep {.5em} +\setlength \labelwidth{\leftmargini} +\addtolength\labelwidth{-\labelsep} +\@beginparpenalty -\@lowpenalty +\@endparpenalty -\@lowpenalty +\@itempenalty -\@lowpenalty +% +\def\newdef#1{\@ifnextchar[{\@xnewdef{#1}}{\@ynewdef{#1}}} +\def\@xnewdef#1[#2]#3{\newtheorem{italic@#1}[#2]{{\em #3}}\@newdef{#1}} +\def\@ynewdef#1#2{\@ifnextchar[{\@xynewdef{#1}{#2}}{\@yynewdef{#1}{#2}}} +\def\@xynewdef#1#2[#3]{\newtheorem{italic@#1}{{\em #2}}[#3]\@newdef{#1}} +\def\@yynewdef#1#2{\newtheorem{italic@#1}{{\em #2}}\@newdef{#1}} +\def\@newdef#1{\newenvironment{#1}{\@ifnextchar[{\@xstartdef{#1}}{\@ystartdef{#1}}}{\end{italic@#1}}} +\def\@xstartdef#1[#2]{\begin{italic@#1}[{\em #2}]\rm} +\def\@ystartdef#1{\begin{italic@#1}\rm} +% +%\def\@oddfoot{\hbox{}\hfill\@runningfoot \thepage} +%\def\@evenfoot{\@runningfoot\hfill\hbox{} \thepage } +%\def\firstfootsize{\@setsize\firstfootsize{9pt}\vipt\@vipt} +\def\ps@titlepage{\let\@mkboth\@gobbletwo +\def\@oddhead{\fontsize{9}{12} \rm {\hskip 19pt\itshape}}\def\@oddfoot{\hbox{}\hfill\fontsize{9}{12}\@firstfoot}% +\def\@evenhead{}\def\@evenfoot{\firstfootsize\@firstfoot\hfill\hbox{}}} +% +\def\@listI{\leftmargin\leftmargini + \labelwidth\leftmargini\advance\labelwidth-\labelsep + \parsep 0pt plus 1pt + \topsep 6pt plus 2pt minus 2pt + \itemsep 2pt plus 1pt minus .5pt} +\let\@listi\@listI +\@listi +% +\def\longenum{\ifnum \@enumdepth >3 \@toodeep\else + \advance\@enumdepth \@ne + \edef\@enumctr{enum\romannumeral\the\@enumdepth}\list + {\csname label\@enumctr\endcsname}{\usecounter + {\@enumctr}\labelwidth\z@\leftmargin\z@ + \itemindent\parindent \advance\itemindent\labelsep}\fi} +% +\def\ack{ \par \footnotesize +\@ucheadfalse +\@startsection{subsection}{2}{\z@}{-16pt plus -2pt minus + -1pt}{2pt}{\sf}*{ACKNOWLEDGMENT}\par\normalsize +} +\def\endack{\par} + +% provide both spellings of Acknowledgment(s) +\let\acknowledgments\acks +\let\endacknowledgments\endacks +\let\acknowledgment\ack +\let\endacknowledgment\endack +% +\newcommand{\bibemph}[1]{{\em#1}} +\newcommand{\bibemphic}[1]{{\em#1\/}} +\newcommand{\bibsc}[1]{{\sc#1}} + +\newcommand\bibyear[2]{% + \unskip{\hskip8pt}\ignorespaces#1\unskip + \if..#2{\hskip6pt}\else {\hskip8pt}#2 \fi +} +% +\let\l@table\l@figure +\newdimen\bibindent +\setlength\bibindent{1.5em} +\newenvironment{thebibliography}[1] + {\section{\refname}%% + \list{\@biblabel{\@arabic\c@enumiv}}% + {\settowidth\labelwidth{\@biblabel{#1}}% + \leftmargin\labelwidth + \advance\leftmargin\labelsep + \@openbib@code + \usecounter{enumiv}% + \let\p@enumiv\@empty + \renewcommand\theenumiv{\@arabic\c@enumiv}}% + \sloppy + \clubpenalty4000 + \@clubpenalty \clubpenalty + \widowpenalty4000% + \sfcode`\.\@m} + {\def\@noitemerr + {\@latex@warning{Empty `thebibliography' environment}}% + \endlist} +\newcommand\newblock{\hskip .11em\@plus.33em\@minus.07em} +\let\@openbib@code\@empty + +% +\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm} +\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf} +\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt} +\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf} +\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit} +\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl} +\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc} +\DeclareRobustCommand*\cal{\@fontswitch\relax\mathcal} +\DeclareRobustCommand*\mit{\@fontswitch\relax\mathnormal} +% +\def\@juliaconformat{} +\def\juliaconformat#1{\gdef\@juliaconformat{\noindent{\bf JuliaCon Reference Format:}\\[2pt] #1\par}} +% +\def\received#1#2{% + \par% + \tiny + \addvspace{12\p@}% + \parindent\z@% +\small\scriptsize{Received\ #1;\ accepted\ #2}% +\par% +} + +% +\sloppy +\clubpenalty10000 +\widowpenalty10000% +\@lowpenalty 51 +\@medpenalty 151 +\@highpenalty 301 +% +\@beginparpenalty -\@lowpenalty +\@endparpenalty -\@lowpenalty +\@itempenalty -\@lowpenalty + +\voffset-5pc +\hoffset-6.03pc + +\usepackage{times} +%% \usepackage[mtbold]{mathtime} +\usepackage{bm} +\usepackage{graphicx}% Include figure files +\usepackage{hyperref} +%%\usepackage{microtype} +\renewcommand{\ttdefault}{cmtt} + +\usepackage{jlcode} + +\usepackage{authblk} + +\endinput + +% end of juliacon.cls diff --git a/paper/logojuliacon.pdf b/paper/logojuliacon.pdf new file mode 100644 index 0000000..744eaee Binary files /dev/null and b/paper/logojuliacon.pdf differ diff --git a/paper/paper.pdf b/paper/paper.pdf new file mode 100644 index 0000000..5a5d12a Binary files /dev/null and b/paper/paper.pdf differ diff --git a/paper/paper.tex b/paper/paper.tex new file mode 100644 index 0000000..62d285b --- /dev/null +++ b/paper/paper.tex @@ -0,0 +1,381 @@ +\documentclass{juliacon} +\usepackage{amsmath} +\usepackage{float} +\setcounter{page}{1} + +\begin{document} + +\title{DisjunctiveProgramming.jl: Generalized Disjunctive Programming Models and Algorithms for JuMP} +\author{ + \large Hector D. Perez, Shivank Joshi, Ignacio E. Grossmann* + \\\normalsize Carnegie Mellon University, Pittsburgh, PA, USA + \\\normalsize *grossmann@cmu.edu +} + +\maketitle + +\section*{ABSTRACT} +We present a Julia package, \verb|DisjunctiveProgramming.jl|, that extends the functionality in \verb|JuMP.jl| to allow modeling problems via logical propositions and disjunctive constraints. Such models can then be reformulated into Mixed-Integer Programs (MIPs) that can be solved with the various MIP solvers supported by JuMP. To do so, logical propositions are converted to Conjunctive Normal Form (CNF) and reformulated into equivalent algebraic constraints. Disjunctions are reformulated into mixed-integer constraints via the reformulation technique specified by the user (Big-M or Hull reformulations). The package supports reformulations for disjunctions containing linear, quadratic, and nonlinear constraints. + +\section*{Keywords} +JuMP, Mathematical Optimization, Generalized Disjunctive Programming + +\section{Introduction} +The modeling of systems with discrete and continuous decisions is commonly done in algebraic form with mixed-integer programming (MIP) models. When the problems can be defined by purely linear constraints and a linear objective function, they are referred to as mixed-integer linear programs (MILP). When nonlinearities arrise in either the feasible space or the objective function, they are called mixed-integer nonlinear programs (MINLP). +\vskip 6pt +A more systematic approach to modeling such systems is to use Generalized Disjunctive Programming (GDP) \cite{chen_grossmann_2019, grossmann_trespalacios_2013}, which generalizes the Disjunctive Programming paradigm proposed by Balas \cite{balas_2018}. GDP enables the modeling of systems from a logic-based level of abstraction that captures the fundamental rules governing such systems via algebraic constraints and logic. This formulation is useful for expressing problems in an intuitive way that relies on their logical underpinnings without needing to introduce mixed-integer constraints. GDP models are often easier to understand as related constraints are grouped into disjuncts that describe clearly defined subsets of the feasible space. The models obtained via GDP can be reformulated into the pure algebraic form best suited for the application of interest. It is also often possible to exploit the explicit logical structure of a GDP model to provide tighter relaxations than corresponding MIP models, which may improve convergence speed and robustness for solutions via advanced solution algorithms \cite{chen_grossmann_2019}. +\vskip 6pt +Within the optimization community, there is a high volume of ongoing research that relies on GDP to formulate models for a variety of applications. Due to the combinatorial nature of system design problems, the GDP paradigm has been applied to the synthesis of complex processes and networks \cite{MATOVU2022107856, ZHOU202269}, the planning and optimal control of energy systems \cite{CHO2022841, kim2022generalized}, and the modeling of chemical synthesis under uncertainty \cite{CHEN2022107616}. These and numerous other applications of GDP illustrate the benefit of having a robust package for GDP that removes much of the overhead associated with developing and testing GDP models. Although packages with GDP capabilities exist for \verb|Pyomo| \cite{chen2022pyomo} and \verb|GAMS| \cite{vecchietti1999logmip}, having such a package available in Julia can greatly accelerate research in optimization, where packages like \verb|JuMP.jl| \cite{dunning_huchette_lubin_2017} are gaining significant traction. +\vskip 6pt +This paper provides background on the GDP paradigm, and the techniques for reformulating and solving such models. It then presents the package \verb|DisjunctiveProgramming.jl| as an extension to \verb|JuMP.jl| for creating models for optimization that follow the GDP modeling paradigm and can be solved using the vast list of supported solvers \cite{dunning_huchette_lubin_2017}. A case study demonstrates the use of the package for chemical process superstructure optimization. + +\section{Generalized Disjunctive Programming} +The GDP form of modeling is an abstraction that uses both algebraic and logical constraints to capture the fundamental rules governing a system. The two main reformulation strategies to transform GDP models into their equivalent MIP models are the Big-M reformulation \cite{nemhauser_1999, TRESPALACIOS201598} and the Hull reformulation \cite{LEE20002125}, the latter of which yields tighter models at the expense of larger model sizes \cite{grossmann_lee_2003}. +\vskip 6pt + +\subsection{Model} + +The general notation for a GDP problem is given in Eq. \eqref{eq:general_gdp} - \eqref{eq:general_gdp1}. +\begin{align} + \label{eq:general_gdp} + \min \ &f(x) \\ + \text{s.t.} \ &g(x) \leq 0 \\ + &\bigvee_{i \in J_k} + \begin{bmatrix} + Y_{ik} \\ + h_{ik}(x) \leq 0 + \end{bmatrix} \quad \forall k \in K \\ + & \Omega(Y) = true \\ + & Y_{ik} \in \{true, false\} \quad \forall i \in J_k, k \in K\\ + \label{eq:general_gdp1} + & x \in X \subseteq \mathbb{R}^n +\end{align} +Here $f(x)$ is the objective function to be minimized over the continuous variable $x$, $g(x)$ represents the global constraints, $h(x)$ represents the disjunct-specific constraints, and $Y$ is the Boolean variable governing each disjunction. In this notation, there are $k$ disjunctions with $i$ disjuncts in each. Constraints $h_{ik}(x) \le 0$, are applied only if the Boolean indicator variable for the respective disjunct, $Y_{ik}$, is denoted as being active (i.e., \textit{true}) \cite{chen_grossmann_2019}. The set of logical constraints, $\Omega(Y)$, describe the logical relationships between the selections of indicator variables. These can take the form of logical propositions or constraint programming expressions. +\vskip 6pt + +In the case of a linear objective function and constraint set, the GDP model can be written as Eq. \eqref{eq:lgdp} - \eqref{eq:lgdp2}. +\begin{align} + \label{eq:lgdp} + \min \ & c^Tx \\ + \text{s.t.} \ &Ax \leq b \\ + &\bigvee_{i \in J_k} + \begin{bmatrix} + Y_{ik} \\ + B_{ik}x \leq d_{ik} + \end{bmatrix}, \quad \forall k \in K \\ + & \Omega(Y) = true \\ + \label{eq:lgdp2} + & Y_{ik} \in \{true, false\} \quad \forall i \in J_k, k \in K +\end{align} +\vskip 6pt + +\subsection{Linear GDP reformulation example} +The simplest example of a linear GDP system is given in \eqref{eq:ex} - \eqref{eq:y}, where $Y_i$ is a Boolean indicator variable that enforces the constraints in the disjunct ($Ax \le b$ or $Cx \le d$) when $true$. +\vskip 6pt +\begin{equation} + \label{eq:ex} + \begin{bmatrix} + Y_1 \\ Ax \leq b + \end{bmatrix} + \lor + \begin{bmatrix} + Y_2 \\ Cx \leq d + \end{bmatrix} +\end{equation} +\begin{equation} + \label{eq:x} + 0 \leq x \leq U +\end{equation} +\begin{equation} + \label{eq:simple_xor} + Y_1 \ \underline{\vee} \ Y_2 +\end{equation} +\begin{equation} + \label{eq:y} + Y_1, Y_2 \in \{true, false\} +\end{equation} +\vskip 6pt + +For visualization purposes and without loss of generality, the simple linear example is used to illustrate the Big-M and Hull reformulations. Figure \ref{fig:reform_figure} illustrates the feasible space of a simple linear GDP with one disjunction and two continuous variables, $x_1$ and $x_2$. The rectangle on the left is described by the constraints in the left disjunct, $Ax \leq b$. The rectangle on the right is defined by the constraints in the right disjunct, $Cx \le d$. The non-overlapping nature of the two regions is supported by the exclusive-OR relationship in Eq. \eqref{eq:simple_xor}. + +\begin{figure} + \centering + \includegraphics[scale=0.5]{solnspace.png} + \caption{Feasible solution space for example disjunction} + \label{fig:reform_figure} +\end{figure} +\vskip 6pt + + \subsubsection{Big-M Reformulation} + The Big-M reformulation for this problem is given by \eqref{eq:x}, \eqref{eq:ex_bigm1} - \eqref{eq:ex_bigm4}, where $M$ is a sufficiently large scalar that makes the particular constraint redundant when its indicator variable is not selected (i.e., $y_i = 0$). Note that the Boolean variables, $Y_i$, are replaced by binary variables, $y_i$. When the integrality constraint in Eq. \eqref{eq:ex_bigm4} is relaxed to $0 \leq x_1, x_2 \leq 1$, the resulting feasible region can be visualized by projecting the relaxed model onto the $x_1, x_2$ plane. This results in the region encapsulated by the dashed line in Figure \ref{fig:bigm}. It should be noted that the relaxed feasible region is not as tight as possible around the original feasible solution space. The choice of the large $M$ value determines the tightness of this relaxation, and the minimal value of $M$ for the optimal relaxation can be found through interval arithmetic when the model is linear. For nonlinear models, the tightest $M$ can be obtained by solving the maximization problem $\{\max h_{ik}(x): x \in X\}$. An alternate method for tight Big-M relaxations is given in \cite{TRESPALACIOS201598}. + +\begin{equation} + \label{eq:ex_bigm1} + Ax \leq b + M \cdot (1 - y_1) +\end{equation} +\begin{equation} + \label{eq:ex_bigm2} + Cx \leq d + M \cdot (1 - y_2) +\end{equation} +\begin{equation} + \label{eq:ex_bigm3} + y_1 + y_2 = 1 +\end{equation} +\begin{equation} + \label{eq:ex_bigm4} + y_1, y_2 \in \{0,1\} +\end{equation} + +\begin{figure} + \centering + \includegraphics[scale=0.5]{bigm.png} + \caption{Relaxed solution space using Big-M Reformulation} + \label{fig:bigm} +\end{figure} + +\subsubsection{Hull Reformulation} +The Hull reformulation is given by \eqref{eq:x}, \eqref{eq:ex_bigm3} - \eqref{eq:ex_hull3}, which requires lifting the model to a higher-dimensional space. When projected to the original space, the continuous relaxation of the model is tighter than its Big-M equivalent \cite{grossmann_trespalacios_2013}. The reformulation relaxation can be visualized by the region encapsulated by the dashed line in Figure \ref{fig:chr}. Note that this reformulation provides a tighter relaxation than the Big-M reformulation in Figure \ref{fig:bigm}. Also note that describing the geometry of this relaxation is more complex than the Big-M relaxation, which is made possible by the increased number of constraints and variables in the model. + +\begin{equation} + \label{eq:ex_hull1} + Ax_1 \leq by_1 +\end{equation} +\begin{equation} + \label{eq:ex_hull0} + Cx_2 \leq dy_2 +\end{equation} +\begin{equation} + \label{eq:ex_hull2} + x = x_1 + x_2 +\end{equation} +\begin{equation} + \label{eq:ex_hull3} + 0 \leq x_i \leq U y_i \quad \forall i \in \{1,2\} +\end{equation} + +\begin{figure}%[H] + \centering + \includegraphics[scale=0.5]{chr.png} + \caption{Relaxed solution space using Hull Reformulation} + \label{fig:chr} +\end{figure} +\vskip 6pt + +\subsection{Logic constraint reformulation} + +\subsubsection{Propositional Logic} +The logic propositions within the set of decision selection relationships, $\Omega$, must be converted into conjunctive normal form (CNF) to enable reformulating a GDP model as a MIP model. This means that each clause within the set of propositions must be formulated into a conjunction of disjunctions. This process can be accomplished by following the simplifying rules of propositional logic (De Morgan's laws). For boolean variables $A$, $B$, and $C$ the following rules are used for converting to CNF (in the order given below), +\begin{align*} + A \leftrightarrow B & \text{ is replaced by } (A \rightarrow B) \land (B \rightarrow A) \\ + A \rightarrow B & \text{ is replaced by } \lnot A \lor B \\ + \lnot(A \lor B) & \text{ is replaced by } \lnot A \land \lnot B \\ + \lnot(A \land B) & \text{ is replaced by } \lnot A \lor \lnot B \\ + (A \land B) \lor C & \text{ is replaced by } (A \lor C) \land (B \lor C) +\end{align*} + +Once the logic propositions are converted to CNF, each clause can be converted into an algebraic constraint with the following equivalence (Note: any negated Boolean variables, $\neg Y_i$, are replaced with $1-y_i$ in the reformulation), + +\begin{align*} + \bigvee_{i \in I} Y_i & \ \ \text{becomes} \ \ \sum_{i\in I} y_i \geq 1 \\ +\end{align*} + +Alternate approaches exist for converting propositional logic statements into CNF, which involve preserving clause satisfiability rather than clause equivalence. These approaches prevent exponential size increase in clauses and yield logically consistent results \cite{jackson_sheridan_2005}. + +\subsubsection{Constraint Programming} +Selection constraints analogous to those used in Constraint Programming (CP) can also be included in $\Omega(Y)$. These constraints are of the form "allow exactly $n$ elements in a list of Boolean variables to be $true$." This type of constraint overcomes the limitations of the Boolean exclusive-OR ($\underline{\vee}$) operator, which can only enforce that an odd number of elements in a list of Booleans be $true$. Other CP-like constraints can be obtained by replacing "exactly" with "at most" or "at least". These constraints are reformulated as follows, + +\begin{align*} + \text{exactly}(n, Y) & \ \ \text{becomes} \ \ n = \sum_i Y_i \\ + \text{atleast}(n, Y) & \ \ \text{becomes} \ \ n \leq \sum_i Y_i \\ + \text{atmost}(n, Y) & \ \ \text{becomes} \ \ n \geq \sum_i Y_i +\end{align*} + +Exclusive-OR constraints as the one given in Eq. \eqref{eq:simple_xor} are more generally modeled as $exactly(1,\{Y_1,Y_2\})$. + +\subsection{Solution Techniques} + +\subsubsection{Disjunctive branch and bound} +The disjunctive branch and bound method closely mirrors the standard branch and bound approach for the solution of mixed-integer programming problems \cite{grossmann_lee_2003}. A search tree is initialized by solving the continuous relaxation of the Big-M or Hull reformulation of the original GDP to obtain a lower bound on the optimum. Branching is then done on the disjunction with an indicator binary variable closest to 1. Two nodes are created at this point: one where the respective indicator Boolean variable is fixed to $true$ (the disjunct is enforced) and another where it is fixed to $false$ (the disjunct is removed from the disjunction). Each node is reformulated and solved to obtain a candidate lower bound. If the solution to a node results in a feasible solution that satisfies all integrality constraints, the solution is an upper bound on the optimum. Any non-integral solutions that exceed an upper bound are pruned from the search tree. The process is repeated until the lower and upper bounds are within the desired tolerance. + +\subsubsection{Logic-based outer approximation} +Logic-based outer approximation is another algorithm which mirrors a standard technique for solving mixed-integer nonlinear programming problems \cite{E.Grossmann2009}. This approach starts by identifying a set of reduced Non-Linear Programming (NLP) sub-problems obtained by fixing Boolean variables in the different disjunctions such that each disjunct is selected at least once across the set of sub-problems (set covering step). +Each sub-problem is solved to obtain an upper bound and a feasible point, about which the objective and constraints of the original GDP are linearized, and solve the resulting problem (via direct reformulation to MILP or via disjunctive branch and bound) to find a lower bound. If the lower and upper bound solutions have not converged, the Boolean variables from the previous solution are fixed and the resulting NLP is solved to find a potentially tighter upper bound solution. The procedure is repeated until convergence is obtained. + +\subsubsection{Hybrid cutting planes} +The cutting planes method is an algorithm for tightening the relaxed solution space of a problem reformulated with Big-M before solving it by adding additional constraints which remove parts of the relaxed space that are disjoint from the actual feasible solution space. These "cuts" to the relaxed solution space are derived from the tighter, hull relaxation of the problem. This algorithm provides a middle-ground for the tradeoff between the complexity and corresponding computational expense of the Hull reformulation with the less tight Big-M reformulation. \cite{trespalacios_grossmann_2016}. + +\section{DisjunctiveProgramming.jl} +The following section describes the features of the \verb|DisjunctiveProgramming.jl| package and illustrates its syntax with an example from the chemical processing industry for superstructure optimization. The use of nested disjunctions is also shown. + +\subsection{Features} +\verb|DisjunctiveProgramming.jl| allows for defining JuMP models with disjunctions that are directly reformulated via Big-M or Hull methods via the \verb|@disjunction| macro or \verb|add_disjunction!| function. Big-M values can be specified either for the entire disjunction, for each disjunct, or for each constraint in each disjunct. Alternately, if the constraints are linear, the code can use the variable bounds to perform interval arithmetic on each constraint to determine the tightest possible $M$ value to use \cite{agarwal2010automating}. For nonlinear GDP constraints, the epsilon approximation formulation for the perspective function in the Hull reformulation is used \cite{furman_sawaya_grossmann_2020}. Users can specify an epsilon tolerance value to use. Perspective functions are generated by relying on manipulation of symbolic expressions via \verb|Symbolics.jl| \cite{10.1145/3511528.3511535}. + +\vskip 6pt +Logical propositions can be added to JuMP models using expressions involving the disjunction indicator variables and the standard Boolean operators ($\Leftrightarrow, \Rightarrow, \vee, \wedge, \text{ and } \neg$) in an \verb|@proposition| macro. These are automatically converted into CNF and added as integer algebraic constraints to the model. The constraint programming constraints can also be added using the \verb|choose!| function. The expressions are also automatically reformulated into integer algebraic constraints. + +\vskip 6pt +Nesting of disjunctions is also supported. + +\subsection{Example} +To illustrate the syntax in \verb|DisjunctiveProgramming.jl| (Version 0.3.3), consider the simple superstructure optimization problem for the chemical process given in Figure \ref{fig:superstruct_opt_diagram}. In this problem a chemical plant with two candidate reactor technologies ($R_1$ and $R_2$) must be designed. If the second reactor technology is chosen, a separation system must also be installed, for which two separation technologies ($S_1$ and $S_2$) are available. The GDP model seeks to maximize the product flow ($F_7$), while discounting for reactor ($C_R$) and separator ($C_S$) installation costs as given in \eqref{eq:example_obj}, subject to the nested disjunction in \eqref{eq:example_gdp} and the global mass balances in \eqref{eq:example_global} +- \eqref{eq:example_global1}. The system variables are the flows on each stream $i$ ($F_i$) and the installation costs, with their respective bounds given in \eqref{eq:example_var1} - \eqref{eq:example_var3}. The fixed cost and process yield parameters are given by $\gamma$ and $\beta$, respectively. + +\begin{figure} + \centering + \includegraphics[scale=0.4]{superstructure_pfd.png} + \caption{Illustrative superstructure optimization problem} + \label{fig:superstruct_opt_diagram} +\end{figure} + +\begin{equation} + \label{eq:example_obj} + \max F_7 - C_R - C_S +\end{equation} +\begin{equation} + \label{eq:example_gdp} + \begin{bmatrix} + Y_{R1} \\ + F_6 = \beta_{R1} F_2 \\ + F_3 = 0 \\ + F_4 = 0 \\ + F_5 = 0 \\ + C_R = \gamma_{R1} \\ + CS = 0 + \end{bmatrix} \lor + \begin{bmatrix} + Y_{R2} \\ + F_2 = 0 \\ + F_6 = 0 \\ + F_4 = \beta_{R2} F_3 \\ + C_R = \gamma_{R2} \\ + \begin{bmatrix} + Y_{S1} \\ + F5 = \beta_{S1} F_4 \\ + C_S = \gamma_{S1} + \end{bmatrix} \lor + \begin{bmatrix} + Y_{S2} \\ + F5 = \beta_{S2} F_4 \\ + C_S = \gamma_{S2} + \end{bmatrix} + \end{bmatrix} +\end{equation} +\begin{equation} + \label{eq:example_global} + F_1 = F_2 + F_3 +\end{equation} +\begin{equation} + \label{eq:example_global1} + F_7 = F_5 + F_6 +\end{equation} +\begin{equation} + \label{eq:example_var1} + 0 \leq F_i \leq 10 \quad \forall i \in \{1,...,7\} +\end{equation} +\begin{equation} + \label{eq:example_var2} + 0 \leq C_S \leq C_S^{max} +\end{equation} +\begin{equation} + \label{eq:example_var3} + C_R^{min} \leq C_R \leq C_R^{max} +\end{equation} +\vskip 6pt + +The above system can be modeled and reformulated via the Big-M reformulation using \verb|DisjunctiveProgramming.jl|. The resulting JuMP model is then optimized using the HiGHS open-source MILP solver \cite{huangfu2018parallelizing} as shown below. + +\begin{enumerate} + \item Create the JuMP model and define the model variables and global constraints (mass balances). + +\begin{lstlisting}[language = Julia] +using DisjunctiveProgramming, JuMP, HiGHS + +# create model +m = JuMP.Model(HiGHS.Optimizer) +# add variables to model +@variable(m, 0 <= F[i = 1:7] <= 10) +@variable(m, 0 <= CS <= CSmax) +@variable(m, CRmin <= CR <= CRmax) + +# add constraints to model +@constraints(m, + begin + F[1] == F[2] + F[3] + F[7] == F[5] + F[6] + end +) +\end{lstlisting} + \item Define the inner (nested) disjunction for the separation technologies in the superstructure using the \verb|@disjunction| macro. +\begin{lstlisting}[language = Julia] +@disjunction(m, + begin + F[5] == β[:S1]*F[4] + CS == γ[:S1] + end, + begin + F[5] == β[:S2]*F[4] + CS == γ[:S2] + end, + reformulation = :big_m, # reformulation type + name = :YS # symbol for indicator variable +) +\end{lstlisting} + \item Define constraints in the outer disjunctions. +\begin{lstlisting}[language = Julia] +# define constraints in left disjunct +R1_con = @constraints(m, + begin + F[6] == β[:R1]*F[2] + [i = 3:5], F[i] == 0 + CR == γ[:R1] + CS == 0 + end +) + +# define constraints in right disjunct +R2_con = @constraints(m, + begin + F[6] == β[:R2]*F[3] + CR == γ[:R2] + end +) +\end{lstlisting} + \item Build the main disjunction using the constraint blocks defined in (3) and the \verb|add_disjunction!| function. Note that the reformulated constraints for the nested disjunction are stored in the \verb|.ext| dictionary of the model under the name of the disjunction (\verb|:YS| in this case). +\begin{lstlisting}[language = Julia] +add_disjunction!(m, + R1_con, + ( + R2_con, #general constraints in R2 disj. + m.ext[:YS] #reformulated inner disj. + ), + reformulation = :big_m, # reformulation type + name = :YR # symbol for indicator variable +) +\end{lstlisting} + \item Add the selection logical constraints using the \verb|choose!| function. The first constraint enforces that only one reactor is selected (i.e., $Y_{R_1} \ \underline{\vee} \ Y_{R_2}$). The second constraint enforces that the separation system be defined only if the second reactor ($R_2$) is selected. This constraint is equivalent to the proposition $Y_{R_2} \Leftrightarrow Y_{S_1} \ \underline{\vee} \ Y_{S_2}$. +\begin{lstlisting}[language = Julia] +YR, YS = m[:YR], m[:YS] +choose!(m, 1, YR[1], YR[2]; mode = :exactly) +choose!(m, YR[2], YS[1], YS[2]; mode = :exactly) +\end{lstlisting} + \item Add the objective function and optimize. +\begin{lstlisting}[language = Julia] +@objective(m, Max, F[7] - CS - CR) +optimize!(m) +\end{lstlisting} +\end{enumerate} + +\section{Future Work} +The next steps for the \verb|DisjunctivePrograming.jl| package rely on extending \verb|JuMP.jl| further to allow creating GDP models that are not necessarily reformulated at model creation. Such models will allow using the different GDP solution strategies, such as direct reformulation to MI(N)LP, disjunctive branch and bound, logic-based outer approximation, hybrid cutting planes, and basic steps. The updated package will leverage existing JuMP extension infrastructure and make it possible to define indexing notation for disjunctions, a new Boolean variable type, and a new disjunciton constraint type. These improvements are expected to make the package more usable, flexible, and performant for advanced applications of GDP in JuMP. + +\section{Related Work} +The popular Python package \verb|Pyomo| \cite{bynum2021pyomo, hart2011pyomo} is widely used for optimization development and includes an extension for generalized disjunctive programming \cite{chen2022pyomo}. \verb|GAMS| \cite{Bussieck2004} is a widely used optimization modeling language with support for GDP under the \verb|GAMS EMP| solver that uses \verb|LogMIP| \cite{vecchietti1999logmip}. Research is also being conducted to integrate modern process simulation technology, such as \verb|Aspen|, within the GDP paradigm \cite{NAVARROAMOROS201413}. + +\section{Conclusion} +\verb|DisjunctiveProgramming.jl| is an extension to \verb|JuMP| for creating models for optimization that are formulated according to the generalized disjunctive programming paradigm. The package provides several options for reformulations including the Big-M and Hull relaxations. This package can be used to model problems, reformulate them, and optimize them using existing mathematical programming infrastructure in \verb|JuMP|. This can be useful for industrial and academic applications of GDP, such as superstructure optimization. The capabilities of this package allow for this modeling paradigm to be exploited using \verb|Julia|'s efficient dynamically-typed systems for rapid development, building, and testing of optimization models. + +% References +\input{bib.tex} + + +\end{document} diff --git a/paper/paper.yml b/paper/paper.yml new file mode 100644 index 0000000..d403e6a --- /dev/null +++ b/paper/paper.yml @@ -0,0 +1,20 @@ +title: "DisjunctiveProgramming.jl: Generalized Disjunctive Programming Models and Algorithms for JuMP" +keywords: + - JuMP + - Mathematical Optimization + - Generalized Disjunctive Programming +authors: + - name: Hector D. Perez + orcid: 0000-0002-7374-1120 + affiliation: 1 + - name: Shivank Joshi + orcid: 0000-0002-1004-3173 + affiliation: 1 + - name: Ignacio E. Grossmann + orcid: 0000-0002-7210-084X + affiliation: 1 +affiliations: + - name: Carnegie Mellon University + index: 1 +date: 10 October 2022 +bibliography: ref.bib diff --git a/paper/prep.rb b/paper/prep.rb new file mode 100644 index 0000000..6da32f4 --- /dev/null +++ b/paper/prep.rb @@ -0,0 +1,57 @@ +# metadata generator for JuliaCon +# DO NOT EDIT + +require 'yaml' + +metadata = YAML.load_file('paper.yml') + +for k in ["title", "authors", "affiliations", "keywords", "bibliography"] + raise "Key #{k} not present in metadata" unless metadata.keys().include?(k) +end + +# ENV variables or default for issue/volume/year +issue = ENV["JLCON_ISSUE"] === nil ? 1 : ENV["JLCON_ISSUE"] +volume = ENV["JLCON_VOLUME"] === nil ? 1 : ENV["JLCON_VOLUME"] +year = ENV["JLCON_YEAR"] === nil ? 2021 : ENV["JLCON_YEAR"] +journal_name = "Proceedings of JuliaCon" # hard-coded for now + +open('header.tex', 'w') do |f| + f << "% **************GENERATED FILE, DO NOT EDIT**************\n\n" + f << "\\title{#{metadata["title"]}}\n\n" + for auth in metadata["authors"] + f << "\\author[#{auth["affiliation"]}]{#{auth["name"]}}\n" + end + for aff in metadata["affiliations"] + f << "\\affil[#{aff["index"]}]{#{aff["name"]}}\n" + end + f << "\n\\keywords{" + for i in 0...metadata["keywords"].length-1 + f << "#{metadata["keywords"][i]}, " + end + f << metadata["keywords"].last + f << "}\n\n" + + # hypersetup + f << "\\hypersetup{\n" + f << "pdftitle = {#{metadata["title"]}},\n" + f << "pdfsubject = {JuliaCon 2019 Proceedings},\n" + author_list = metadata['authors'].map { |a| a['name'] }.join(', ') + f << "pdfauthor = {#{author_list}},\n" + keyword_list = metadata['keywords'].join(', ') + f << "pdfkeywords = {#{keyword_list}},\n" + f << "}\n\n" +end + +open('journal_dat.tex', 'w') do |f| + f << "% **************GENERATED FILE, DO NOT EDIT**************\n\n" + f << "\\def\\@journalName{#{journal_name}}\n" + f << "\\def\\@volume{#{volume}}\n" + f << "\\def\\@issue{#{issue}}\n" + f << "\\def\\@year{#{year}}\n" +end + +open('bib.tex', 'w') do |f| + f << "% **************GENERATED FILE, DO NOT EDIT**************\n\n" + f << "\\bibliographystyle{juliacon}\n" + f << "\\bibliography{#{metadata["bibliography"]}}\n" +end diff --git a/paper/ref.bib b/paper/ref.bib new file mode 100644 index 0000000..e8fbeed --- /dev/null +++ b/paper/ref.bib @@ -0,0 +1,354 @@ +@inproceedings{agarwal2010automating, + title={Automating mathematical program transformations}, + author={Agarwal, Ashish and Bhat, Sooraj and Gray, Alexander and Grossmann, Ignacio E}, + booktitle={International Symposium on Practical Aspects of Declarative Languages}, + pages={134--148}, + year={2010}, + doi="10.1007/978-3-642-11503-5\_12", + organization={Springer} +} +@article{huangfu2018parallelizing, + title={Parallelizing the dual revised simplex method}, + author={Huangfu, Qi and Hall, JA Julian}, + journal={Mathematical Programming Computation}, + volume={10}, + number={1}, + pages={119--142}, + year={2018}, + doi={10.1007/s12532-017-0130-5}, + publisher={Springer} +} +@article{chen2022pyomo, + title={Pyomo. GDP: an ecosystem for logic based modeling and optimization development}, + author={Chen, Qi and Johnson, Emma S and Bernal, David E and Valentin, Romeo and Kale, Sunjeev and Bates, Johnny and Siirola, John D and Grossmann, Ignacio E}, + journal={Optimization and Engineering}, + volume={23}, + number={1}, + pages={607--642}, + year={2022}, + publisher={Springer} +} +@article{vecchietti1999logmip, + title={LOGMIP: a disjunctive 0--1 non-linear optimizer for process system models}, + author={Vecchietti, Aldo and Grossmann, Ignacio E}, + journal={Computers \& chemical engineering}, + volume={23}, + number={4-5}, + pages={555--565}, + year={1999}, + doi={10.1016/s0098-1354(98)00293-2}, + publisher={Elsevier} +} +@article{trespalacios_grossmann_2016, +title={Cutting plane algorithm for convex generalized disjunctive programs}, +volume={28}, +DOI={10.1287/ijoc.2015.0669}, +number={2}, +journal={INFORMS Journal on Computing}, +author={Trespalacios, Francisco and Grossmann, Ignacio E.}, +year={2016}, +pages={209–222} +} + +@Inbook{E.Grossmann2009, +author="E. Grossmann, Ignacio", +title="Logic-based outer approximation", +bookTitle="Encyclopedia of Optimization", +year="2009", +publisher="Springer US", +address="Boston, MA", +pages="1928--1931", +abstract="Keywords", +isbn="978-0-387-74759-0", +doi="10.1007/978-0-387-74759-0\_348", +url="https://doi.org/10.1007/978-0-387-74759-0\_348" +} + +@article{NAVARROAMOROS201413, +title = {Integration of modular process simulators under the Generalized Disjunctive Programming framework for the structural flowsheet optimization}, +journal = {Computers \& Chemical Engineering}, +volume = {67}, +pages = {13-25}, +year = {2014}, +issn = {0098-1354}, +doi = {10.1016/j.compchemeng.2014.03.014}, +url = {https://www.sciencedirect.com/science/article/pii/S0098135414000957}, +author = {Miguel A. Navarro-Amorós and Rubén Ruiz-Femenia and José A. Caballero}, +keywords = {Process synthesis, Generalized Disjunctive Programming, Modular simulators, Logic-based optimization algorithm}, +abstract = {The optimization of chemical processes where the flowsheet topology is not kept fixed is a challenging discrete-continuous optimization problem. Usually, this task has been performed through equation based models. This approach presents several problems, as tedious and complicated component properties estimation or the handling of huge problems (with thousands of equations and variables). We propose a GDP approach as an alternative to the MINLP models coupled with a flowsheet program. The novelty of this approach relies on using a commercial modular process simulator where the superstructure is drawn directly on the graphical use interface of the simulator. This methodology takes advantage of modular process simulators (specially tailored numerical methods, reliability, and robustness) and the flexibility of the GDP formulation for the modeling and solution. The optimization tool proposed is successfully applied to the synthesis of a methanol plant where different alternatives are available for the streams, equipment and process conditions.} +} + +@Inbook{Bussieck2004, +author="Bussieck, Michael R. and Meeraus, Alex", +title="General Algebraic Modeling System (GAMS)", +bookTitle="Modeling Languages in Mathematical Optimization", +year="2004", +publisher="Springer US", +address="Boston, MA", +pages="137--157", +abstract="In this chapter we will categorize the development of mathematical programming tools into three major phases and will define three major categories of models and their use. This classification will be used to describe some of the features found in GAMS to support different application environments. Selected language features, and examples of external functions and privacy and security issues are discussed and separate annexes. Finally, we will list the inputs to a problem that has been provided to all the authors by the editor of this volume.", +isbn="978-1-4613-0215-5", +doi="10.1007/978-1-4613-0215-5\_8", +url="https://doi.org/10.1007/978-1-4613-0215-5\_8" +} + +@book{bynum2021pyomo, +title={Pyomo--optimization modeling in python}, +author={Bynum, Michael L. and Hackebeil, Gabriel A. and Hart, William E. and Laird, Carl D. and Nicholson, Bethany L. and Siirola, John D. and Watson, Jean-Paul and Woodruff, David L.}, +edition={Third}, +volume={67}, +year={2021}, +publisher={Springer Science \& Business Media} +} + +@article{hart2011pyomo, +title={Pyomo: modeling and solving mathematical programs in Python}, +author={Hart, William E and Watson, Jean-Paul and Woodruff, David L}, +journal={Mathematical Programming Computation}, +volume={3}, +number={3}, +pages={219--260}, +year={2011}, +doi={10.1007/s12532-011-0026-8}, +publisher={Springer} +} + +@incollection{CHO2022841, +title = {An Optimization Model for Expansion Planning of Reliable Power Generation Systems}, +editor = {Ludovic Montastruc and Stephane Negny}, +series = {Computer Aided Chemical Engineering}, +publisher = {Elsevier}, +volume = {51}, +pages = {841-846}, +year = {2022}, +booktitle = {32nd European Symposium on Computer Aided Process Engineering}, +issn = {1570-7946}, +doi = {10.1016/B978-0-323-95879-0.50141-7}, +url = {https://www.sciencedirect.com/science/article/pii/B9780323958790501417}, +author = {Seolhee Cho and Ignacio E. Grossmann}, +keywords = {Reliability, Expansion Planning, Power systems, Optimization}, +abstract = {This paper aims to develop an optimization model for the expansion planning of reliable power generation systems. To achieve this goal, we propose an optimization model that minimizes the total cost using Generalized Disjunctive Programming (GDP). Specifically, the model determines both investment decisions (number, size, location, and time of generators to install, retire, and decommission) and operation decisions (number of operating/backup generators, operating capacity, and expected power output) by imposing penalties when the demand is not satisfied, and a system has low reliability. The model is verified through an illustrative example of two regions with four power stations over five operating periods.} +} + +@article{CHEN2022107616, +title = {Integrating stochastic programming and reliability in the optimal synthesis of chemical processes}, +journal = {Computers \& Chemical Engineering}, +volume = {157}, +pages = {107616}, +year = {2022}, +issn = {0098-1354}, +doi = {10.1016/j.compchemeng.2021.107616}, +url = {https://www.sciencedirect.com/science/article/pii/S009813542100394X}, +author = {Ying Chen and Yixin Ye and Zhihong Yuan and Ignacio E. Grossmann and Bingzhen Chen}, +keywords = {Reliability-based superstructure optimization, Stochastic programming, Endogenous and exogenous uncertainties, Logic-based outer approximation algorithm}, +abstract = {Plant availability and operating uncertainties are critical considerations for the design and operation of chemical processes as they directly impact service level and economic performance. This paper proposes a two-stage stochastic programming GDP (Generalized Disjunctive Programming) model with reliability constraints to deal with both the exogenous and endogenous uncertainties in process synthesis, where the reliability model is incorporated into the flowsheet superstructure optimization. The proposed stochastic programming model anticipates the market uncertainties through scenarios for selecting the optimal flowsheet topology, equipment sizes and operating conditions, while considering the impact of selecting parallel units for improving plant availability. An improved logic-based outer approximation algorithm is applied to solve the resulting hybrid GDP model, which effectively avoids numerical difficulties with zero flows and provides high quality design solutions. The applicability of the proposed modeling framework and the efficiency of solution strategy are illustrated with two well-known conceptual design case studies: methanol synthesis process and toluene hydrodealkylation process. The model, which integrates reliability (endogenous uncertainty) and exogenous uncertainty, shows the best economic performance with the increasing operational flexibility and plant availability.} +} + +@article{MATOVU2022107856, +title = {Synthesis and optimization of multilevel refrigeration systems using generalized disjunctive programming}, +journal = {Computers \& Chemical Engineering}, +volume = {163}, +pages = {107856}, +year = {2022}, +issn = {0098-1354}, +doi = {10.1016/j.compchemeng.2022.107856}, +url = {https://www.sciencedirect.com/science/article/pii/S0098135422001946}, +author = {Fahad Matovu and Shuhaimi Mahadzir and Rasel Ahmed and Nor Erniza Mohammad Rozali}, +keywords = {Multilevel refrigeration, GDP Modelling, Synthesis and optimization, Logic based branch and bound}, +abstract = {The synthesis and optimization of multilevel refrigeration systems is challenging because it’s a highly non-linear, multi-variable, and multi-modal problem. This work presents a novel approach to develop a complete generalized disjunctive programming model for the synthesis and optimization of multilevel refrigeration systems. The model is based on the application of mass, energy, and thermodynamic model equations and developed to optimize the total shaft work requirement of the system. The presented model is very systematic, easily manageable, and can be extendable to include all design features for refrigeration systems. The model is solvable using advanced solution algorithms such as the Logic-based branch and bound because of it’s disjunctive nature. Thus the solution is sought in reduced space and avoids the full scale as is the case with Mixed integer linear/non-linear models. The model solution yields optimal temperature/pressure levels, mass flow rates, and the shaft work consumption. A case study of the precooling cycle of the propane pre-cooled mixed refrigerant (C3MR) LNG process is used to test the proposed model. The model results are validated by simulation using Aspen Hysys software. Shaft work savings of up to 12.3% are obtained from the model results against the base case. Preliminary estimations show that cost savings of up to 2.55 MM$/y are realizable against the base case.} +} + +@article{kim2022generalized, + title={Generalized Disjunctive Programming-based, Mixed Integer Linear MPC Formulation for Optimal Operation of a District Energy System for PV Self-consumption and Grid Decarbonization: Field Implementation}, + author={Kim, Donghun}, + journal={International High Performance Buildings Conference}, + url={https://docs.lib.purdue.edu/cgi/viewcontent.cgi?article=1395\&context=ihpbc}, + year={2022} +} + +@article{ZHOU202269, +title = {Disjunctive programming model for the synthesis of property-based water supply network with multiple resources}, +journal = {Chemical Engineering Research and Design}, +volume = {187}, +pages = {69-83}, +year = {2022}, +issn = {0263-8762}, +doi = {10.1016/j.cherd.2022.08.027}, +url = {https://www.sciencedirect.com/science/article/pii/S0263876222004397}, +author = {Wenjin Zhou and Kashif Iqbal and Xiaogang Sun and Dinghui Gan and Chun Deng and José María Ponce-Ortega and Chunmao Chen}, +keywords = {Mathematicalv programming: Water supply network: Multi-source: Desalination: Optimum design}, +abstract = {Industrial water supply networks can use multiple water resources (i.e., municipal water, surface water, municipal treated wastewater, groundwater, and seawater) with their respective pre-treatment technologies to meet the industrial water demand. The water quality of each water resource varies, and the associated pre-treatment technologies provide different technical and economic efficiencies that directly impact the overall cost of the water supply network. This paper proposed a superstructure-based mathematical modeling optimization to design the multi-resources industrial water supply network with optimal pre-treatment technologies. The established model includes the relative equations among different pre-treatment units and water sinks, flow rate constraints, property constraints, logic constraints, and cost constraints. These constraints are used to describe water treatment technologies selection through general disjunctive programming (GDP) and transform them into a mixed-integer nonlinear programming (MINLP) model for the problem solution. The minimum annualized cost of the water supply network is taken as an objective function. The optimization and comparison analysis of the coastal oil refinery water supply system is illustrated. The results show that an integrated water supply network of surface water and municipal treated wastewater has the lowest annualized cost of 12.3 million CNY/y. The cost is reduced by 7.44 million CNY/y compared to municipal water as the single water resource. This integrated water supply network saves freshwater resources, provides substantial economic gains, and encourages municipal treated wastewater reuse.} +} + +@article{belotti_liberti_lodi_nannicini_tramontani_2011, +title={Disjunctive inequalities: Applications and extensions}, +DOI={10.1002/9780470400531.eorms0537}, +journal={Wiley Encyclopedia of Operations Research and Management Science}, +author={Belotti, Pietro and Liberti, Leo and Lodi, Andrea and Nannicini,Giacomo and Tramontani,Andrea}, +year={2011} +} + +@article{jackson_sheridan_2005, +title={Clause form conversions for boolean circuits}, +DOI={10.1007/11527695\_15}, +journal={Theory and Applications of Satisfiability Testing}, +author={Jackson,Paul and Sheridan,Daniel}, +year={2005}, +pages={183–198} +} + +@article{dunning_huchette_lubin_2017, +title={Jump: A modeling language for mathematical optimization}, +volume={59}, +number={2}, +journal={SIAM Review}, +author={Dunning, +Iain and Huchette, +Joey and Lubin, +Miles}, +year={2017}, +pages={295–320}, +doi = {10.1137/15M1020575}, +abstract = {JuMP is an open-source modeling language that allows users to express a wide range of optimization problems (linear, mixed-integer, quadratic, conic-quadratic, semidefinite, and nonlinear) in a high-level, algebraic syntax. JuMP takes advantage of advanced features of the Julia programming language to offer unique functionality while achieving performance on par with commercial modeling tools for standard tasks. In this work we will provide benchmarks, present the novel aspects of the implementation, and discuss how JuMP can be extended to new problem classes and composed with state-of-the-art tools for visualization and interactivity.} +} + +@article{DunningHuchetteLubin2017, +author = {Iain Dunning and Joey Huchette and Miles Lubin}, +title = {JuMP: A Modeling Language for Mathematical Optimization}, +journal = {SIAM Review}, +volume = {59}, +number = {2}, +url={https://jump.dev/JuMP.jl/stable/installation/#Supported-solvers}, +pages = {295-320}, +year = {2017}, +doi = {10.1137/15M1020575}, +} + +@Article{chen_grossmann_2019, +AUTHOR = {Chen, Qi and Grossmann, Ignacio}, +TITLE = {Modern Modeling Paradigms Using Generalized Disjunctive Programming}, +JOURNAL = {Processes}, +VOLUME = {7}, +YEAR = {2019}, +NUMBER = {11}, +ARTICLE-NUMBER = {839}, +URL = {https://www.mdpi.com/2227-9717/7/11/839}, +ISSN = {2227-9717}, +ABSTRACT = {Models involving decision variables in both discrete and continuous domain spaces are prevalent in process design. Generalized Disjunctive Programming (GDP) has emerged as a modeling framework to explicitly represent the relationship between algebraic descriptions and the logical structure of a design problem. However, fewer formulation examples exist for GDP compared to the traditional Mixed-Integer Nonlinear Programming (MINLP) modeling approach. In this paper, we propose the use of GDP as a modeling tool to organize model variants that arise due to characterization of different sections of an end-to-end process at different detail levels. We present an illustrative case study to demonstrate GDP usage for the generation of model variants catered to process synthesis integrated with purchasing and sales decisions in a techno-economic analysis. We also show how this GDP model can be used as part of a hierarchical decomposition scheme. These examples demonstrate how GDP can serve as a useful model abstraction layer for simplifying model development and upkeep, in addition to its traditional usage as a platform for advanced solution strategies.}, +DOI = {10.3390/pr7110839} +} + +@article{grossmann_trespalacios_2013, +author = {Grossmann, Ignacio E. and Trespalacios, Francisco}, +title = {Systematic modeling of discrete-continuous optimization models through generalized disjunctive programming}, +journal = {AIChE Journal}, +volume = {59}, +number = {9}, +pages = {3276-3295}, +keywords = {optimization, mixed-integer programming, logic-based optimization}, +doi = {10.1002/aic.14088}, +url = {https://aiche.onlinelibrary.wiley.com/doi/abs/10.1002/aic.14088}, +abstract = {Discrete-continuous optimization problems are commonly modeled in algebraic form as mixed-integer linear or nonlinear programming models. Since these models can be formulated in different ways, leading either to solvable or nonsolvable problems, there is a need for a systematic modeling framework that provides a fundamental understanding on the nature of these models. This work presents a modeling framework, generalized disjunctive programming (GDP), which represents problems in terms of Boolean and continuous variables, allowing the representation of constraints as algebraic equations, disjunctions and logic propositions. An overview is provided of major research results that have emerged in this area. Basic concepts are emphasized as well as the major classes of formulations that can be derived. These are illustrated with a number of examples in the area of process systems engineering. As will be shown, GDP provides a structured way for systematically deriving mixed-integer optimization models that exhibit strong continuous relaxations, which often translates into shorter computational times. © 2013 American Institute of Chemical Engineers AIChE J, 59: 3276–3295, 2013}, +year = {2013} +} + +@book{balas_2018, +place={Cham, Switzerland}, +title={Disjunctive programming}, +publisher={Springer}, +author={Balas, Egon}, +year={2018} +} + +@article{TRESPALACIOS201598, +title = {Improved Big-M reformulation for generalized disjunctive programs}, +journal = {Computers \& Chemical Engineering}, +volume = {76}, +pages = {98-103}, +year = {2015}, +issn = {0098-1354}, +doi = {10.1016/j.compchemeng.2015.02.013}, +url = {https://www.sciencedirect.com/science/article/pii/S0098135415000587}, +author = {Francisco Trespalacios and Ignacio E. Grossmann}, +keywords = {Disjunctive programming, Mixed-integer programming, Big-M}, +abstract = {In this work, we present a new Big-M reformulation for Generalized Disjunctive Programs. Unlike the traditional Big-M reformulation that uses one M-parameter for each constraint, the new approach uses multiple M-parameters for each constraint. Each of these M-parameters is associated with each alternative in the disjunction to which the constraint belongs. In this way, the proposed MINLP reformulation is at least as tight as the traditional Big-M, and it does not require additional variables or constraints. We present the new Big-M, and analyze the strength in its continuous relaxation compared to that of the traditional Big-M. The new formulation is tested by solving several instances with an NLP-based branch and bound method. The results show that, in most cases, the new reformulation requires fewer nodes and less time to find the optimal solution.} +} + +@article{LEE20002125, +title = {New algorithms for nonlinear generalized disjunctive programming}, +journal = {Computers \& Chemical Engineering}, +volume = {24}, +number = {9}, +pages = {2125-2141}, +year = {2000}, +issn = {0098-1354}, +doi = {10.1016/S0098-1354(00)00581-0}, +url = {https://www.sciencedirect.com/science/article/pii/S0098135400005810}, +author = {Sangbum Lee and Ignacio E. Grossmann}, +keywords = {Generalized disjunctive programming, Branch and bound, Mixed-integer nonlinear programming, Nonlinear convex hull}, +abstract = {Generalized disjunctive programming (GDP) has been introduced recently as an alternative model to MINLP for representing discrete/continuous optimization problems. The basic idea of GDP consists of representing discrete decisions in the continuous space with disjunctions, and constraints in the discrete space with logic propositions. In this paper, we describe a new convex nonlinear relaxation of the nonlinear GDP problem that relies on the use of the convex hull of each of the disjunctions involving nonlinear inequalities. The proposed nonlinear relaxation is used to reformulate the GDP problem as a tight MINLP problem, and for deriving a branch and bound method. Properties of these methods are given, and the relation of this method with the logic based outer-approximation method is established. Numerical results are presented for problems in jobshop scheduling, synthesis of process networks, optimal positioning of new products and batch process design.} +} + +@book{nemhauser_1999, +place={New York}, +title={Integer and combinatorial optimization}, +publisher={John Wiley and Sons}, +author={Nemhauser, George L.}, +year={1999} +} + +@article{grossmann_lee_2003, +title={Generalized Convex Disjunctive Programming: Nonlinear Convex Hull Relaxation}, +volume={26}, +DOI={10.1023/a:1025154322278}, +number={1}, +journal={Computational Optimization and Applications}, +author={Grossmann, Ignacio E. and Lee, Sangbum}, +year={2003}, +pages={83–100} +} + +@article{furman_sawaya_grossmann_2020, +title={A computationally useful algebraic representation of nonlinear disjunctive convex sets using the perspective function}, +volume={76}, +DOI={10.1007/s10589-020-00176-0}, +number={2}, +journal={Computational Optimization and Applications}, +author={Furman,Kevin C. and Sawaya, Nicolas W. and Grossmann, Ignacio E.}, +year={2020}, +pages={589–614} +} + +@article{10.1145/3511528.3511535, +author = {Gowda, Shashi and Ma, Yingbo and Cheli, Alessandro and Gw\'{o}\'{z}zd\'{z}, Maja and Shah, Viral B. and Edelman, Alan and Rackauckas, Christopher}, +title = {High-Performance Symbolic-Numerics via Multiple Dispatch}, +year = {2022}, +issue_date = {September 2021}, +publisher = {Association for Computing Machinery}, +address = {New York, NY, USA}, +volume = {55}, +number = {3}, +issn = {1932-2240}, +url = {https://doi.org/10.1145/3511528.3511535}, +doi = {10.1145/3511528.3511535}, +abstract = {As mathematical computing becomes more democratized in high-level languages, high-performance symbolic-numeric systems are necessary for domain scientists and engineers to get the best performance out of their machine without deep knowledge of code optimization. Naturally, users need different term types either to have different algebraic properties for them, or to use efficient data structures. To this end, we developed Symbolics.jl, an extendable symbolic system which uses dynamic multiple dispatch to change behavior depending on the domain needs. In this work we detail an underlying abstract term interface which allows for speed without sacrificing generality. We show that by formalizing a generic API on actions independent of implementation, we can retroactively add optimized data structures to our system without changing the pre-existing term rewriters. We showcase how this can be used to optimize term construction and give a 113x acceleration on general symbolic transformations. Further, we show that such a generic API allows for complementary term-rewriting implementations. Exploiting this feature, we demonstrate the ability to swap between classical term-rewriting simplifiers and e-graph-based term-rewriting simplifiers. We illustrate how this symbolic system improves numerical computing tasks by showcasing an e-graph ruleset which minimizes the number of CPU cycles during expression evaluation, and demonstrate how it simplifies a real-world reaction-network simulation to halve the runtime. Additionally, we show a reaction-diffusion partial differential equation solver which is able to be automatically converted into symbolic expressions via multiple dispatch tracing, which is subsequently accelerated and parallelized to give a 157x simulation speedup. Together, this presents Symbolics.jl as a next-generation symbolic-numeric computing environment geared towards modeling and simulation.}, +journal = {ACM Commun. Comput. Algebra}, +month = {jan}, +pages = {92–96}, +numpages = {5} +} + +@article{SAWAYA20051891, +title = {A cutting plane method for solving linear generalized disjunctive programming problems}, +journal = {Computers \& Chemical Engineering}, +volume = {29}, +number = {9}, +pages = {1891-1913}, +year = {2005}, +issn = {0098-1354}, +doi = {10.1016/j.compchemeng.2005.04.004}, +url = {https://www.sciencedirect.com/science/article/pii/S0098135405000992}, +author = {Nicolas W. Sawaya and Ignacio E. Grossmann}, +keywords = {MIP, Disjunctive Programming, Cutting planes, Mixed integer linear programming, Strip-packing, Retrofit planning, Job-shop scheduling}, +abstract = {Raman and Grossmann [Raman, R., \& Grossmann, I.E. (1994). Modeling and computational techniques for logic based integer programming. Computers and Chemical Engineering, 18(7), 563–578] and Lee and Grossmann [Lee, S., \& Grossmann, I.E. (2000). New algorithms for nonlinear generalized disjunctive programming. Computers and Chemical Engineering, 24, 2125–2141] have developed a reformulation of Generalized Disjunctive Programming (GDP) problems that is based on determining the convex hull of each disjunction. Although the relaxation of the reformulated problem using this method will often produce a significantly tighter lower bound when compared with the traditional big-M reformulation, the limitation of this method is that the representation of the convex hull of every disjunction requires the introduction of new disaggregated variables and additional constraints that can greatly increase the size of the problem. In order to circumvent this issue, a cutting plane method that can be applied to linear GDP problems is proposed in this paper. The method relies on converting the GDP problem into an equivalent big-M reformulation that is successively strengthened by cuts generated from an LP or QP separation problem. The sequence of problems is repeatedly solved, either until the optimal integer solution is found, or else until there is no improvement within a specified tolerance, in which case one switches to a branch and bound method. The strip-packing, retrofit planning and zero-wait job-shop scheduling problems are presented as examples to illustrate the performance of the proposed cutting plane method.} +} diff --git a/paper/solnspace.png b/paper/solnspace.png new file mode 100644 index 0000000..ec6a559 Binary files /dev/null and b/paper/solnspace.png differ diff --git a/paper/superstructure_pfd.png b/paper/superstructure_pfd.png new file mode 100644 index 0000000..7cc986c Binary files /dev/null and b/paper/superstructure_pfd.png differ diff --git a/src/DisjunctiveProgramming.jl b/src/DisjunctiveProgramming.jl index 833dd5a..3c22cad 100644 --- a/src/DisjunctiveProgramming.jl +++ b/src/DisjunctiveProgramming.jl @@ -1,18 +1,44 @@ module DisjunctiveProgramming -using JuMP, IntervalArithmetic, Symbolics, Suppressor +# Import and export JuMP +import Reexport +Reexport.@reexport using JuMP -export add_disjunction!, add_proposition! -export @disjunction, @proposition -export choose! +# Use Meta for metaprogramming +using Base.Meta -include("constraint.jl") +# Create aliases +const _MOI = JuMP.MOI +const _MOIUC = JuMP.MOIU.CleverDicts + +# Load in the source files +include("datatypes.jl") +include("model.jl") include("logic.jl") -include("bounds.jl") -include("utils.jl") +include("variables.jl") +include("constraints.jl") +include("macros.jl") +include("reformulate.jl") include("bigm.jl") include("hull.jl") -include("reformulate.jl") -include("macros.jl") +include("indicator.jl") + +# Define additional stuff that should not be exported +const _EXCLUDE_SYMBOLS = [Symbol(@__MODULE__), :eval, :include] + +# Following JuMP, export everything that doesn't start with a _ +for sym in names(@__MODULE__, all = true) + sym_string = string(sym) + if sym in _EXCLUDE_SYMBOLS || startswith(sym_string, "_") || startswith(sym_string, "@_") + continue + end + if !(Base.isidentifier(sym) || (startswith(sym_string, "@") && Base.isidentifier(sym_string[2:end]))) + continue + end + @eval export $sym +end + +# export the single character operators (excluded above) +export ∨, ∧, ¬, ⇔, ⟹ -end # module +end # end of the module \ No newline at end of file diff --git a/src/bigm.jl b/src/bigm.jl index c18c715..d4598c5 100644 --- a/src/bigm.jl +++ b/src/bigm.jl @@ -1,40 +1,199 @@ -""" - big_m_reformulation!(constr::ConstraintRef, bin_var, M, i, j, k) +################################################################################ +# BIG-M VALUE +################################################################################ +# Get Big-M value for a particular constraint +function _get_M_value(func::JuMP.AbstractJuMPScalar, set::_MOI.AbstractSet, method::BigM) + if method.tighten + M = _get_tight_M(func, set, method) + else + M = _get_M(func, set, method) + end + return M +end -Perform Big-M reformulation on a linear or quadratic constraint at index k of constraint j in disjunct i. +# Get the tightest Big-M value for a particular constraint +function _get_tight_M(func::JuMP.AbstractJuMPScalar, set::_MOI.AbstractSet, method::BigM) + M = min.(method.value, _calculate_tight_M(func, set, method)) #broadcast for when S <: MOI.Interval or MOI.EqualTo or MOI.Zeros + if any(isinf.(M)) + error("A finite Big-M value must be used. The value obtained was $M.") + end + return M +end + +# Get user-specified Big-M value +function _get_M(::JuMP.AbstractJuMPScalar, ::Union{_MOI.LessThan, _MOI.GreaterThan, _MOI.Nonnegatives, _MOI.Nonpositives}, method::BigM) + M = method.value + if isinf(M) + error("A finite Big-M value must be used. The value given was $M.") + end + return M +end +function _get_M(::JuMP.AbstractJuMPScalar, ::Union{_MOI.Interval, _MOI.EqualTo, _MOI.Zeros}, method::BigM) + M = method.value + if isinf(M) + error("A finite Big-M value must be used. The value given was $M.") + end + return [M, M] +end - big_m_reformulation!(constr::NonlinearConstraintRef, bin_var, M, i, j, k) +# Apply interval arithmetic on a linear constraint to infer the tightest Big-M value from the bounds on the constraint. +function _calculate_tight_M(func::JuMP.AffExpr, set::_MOI.LessThan, method::BigM) + return _interval_arithmetic_LessThan(func, -set.upper, method) +end +function _calculate_tight_M(func::JuMP.AffExpr, set::_MOI.GreaterThan, method::BigM) + return _interval_arithmetic_GreaterThan(func, -set.lower, method) +end +function _calculate_tight_M(func::JuMP.AffExpr, ::_MOI.Nonpositives, method::BigM) + return _interval_arithmetic_LessThan(func, 0.0, method) +end +function _calculate_tight_M(func::JuMP.AffExpr, ::_MOI.Nonnegatives, method::BigM) + return _interval_arithmetic_GreaterThan(func, 0.0, method) +end +function _calculate_tight_M(func::JuMP.AffExpr, set::_MOI.Interval, method::BigM) + return ( + _interval_arithmetic_GreaterThan(func, -set.lower, method), + _interval_arithmetic_LessThan(func, -set.upper, method) + ) +end +function _calculate_tight_M(func::JuMP.AffExpr, set::_MOI.EqualTo, method::BigM) + return ( + _interval_arithmetic_GreaterThan(func, -set.value, method), + _interval_arithmetic_LessThan(func, -set.value, method) + ) +end +function _calculate_tight_M(func::JuMP.AffExpr, ::_MOI.Zeros, method::BigM) + return ( + _interval_arithmetic_GreaterThan(func, 0.0, method), + _interval_arithmetic_LessThan(func, 0.0, method) + ) +end +# fallbacks for other scalar constraints +_calculate_tight_M(func::Union{JuMP.QuadExpr, JuMP.NonlinearExpr}, set::Union{_MOI.Interval, _MOI.EqualTo, _MOI.Zeros}, method::BigM) = (Inf, Inf) +_calculate_tight_M(func::Union{JuMP.QuadExpr, JuMP.NonlinearExpr}, set::Union{_MOI.LessThan, _MOI.GreaterThan, _MOI.Nonnegatives, _MOI.Nonpositives}, method::BigM) = Inf +_calculate_tight_M(func, set, method::BigM) = error("BigM method not implemented for constraint type $(typeof(func)) in $(typeof(set))") -Perform Big-M reformulaiton on a nonlinear constraint at index k of constraint j in disjunct i. +# get variable bounds for interval arithmetic +function _update_variable_bounds(vref::JuMP.VariableRef, method::BigM) + if JuMP.is_binary(vref) + lb = 0 + elseif !JuMP.has_lower_bound(vref) + lb = -Inf + else + lb = JuMP.lower_bound(vref) + end + if JuMP.is_binary(vref) + ub = 1 + elseif !JuMP.has_upper_bound(vref) + ub = Inf + else + ub = JuMP.upper_bound(vref) + end + return lb, ub +end - big_m_reformulation!(constr::AbstractArray{<:ConstraintRef}, bin_var, M, i, j, k) +# perform interval arithmetic to update the initial M value +function _interval_arithmetic_LessThan(func::JuMP.AffExpr, M::Float64, method::BigM) + for (var,coeff) in func.terms + JuMP.is_binary(var) && continue #skip binary variables + if coeff > 0 + M += coeff*method.variable_bounds[var][2] + else + M += coeff*method.variable_bounds[var][1] + end + end + return M + func.constant +end +function _interval_arithmetic_GreaterThan(func::JuMP.AffExpr, M::Float64, method::BigM) + for (var,coeff) in func.terms + JuMP.is_binary(var) && continue #skip binary variables + if coeff < 0 + M += coeff*method.variable_bounds[var][2] + else + M += coeff*method.variable_bounds[var][1] + end + end + return -(M + func.constant) +end -Perform Big-M reformulation on a constraint at index k of constraint j in disjunct i. -""" -function big_m_reformulation!(constr::ConstraintRef, bin_var, M, i, j, k) - M = get_reform_param(M, i, j, k; constr) - bin_var_ref = constr.model[bin_var][i] - add_to_function_constant(constr, -M) - set_normalized_coefficient(constr, bin_var_ref , M) -end -function big_m_reformulation!(constr::NonlinearConstraintRef, bin_var, M, i, j, k) - M = get_reform_param(M, i, j, k; constr) - #create symbolic variables (using Symbolics.jl) - for var_ref in constr.model[:gdp_variable_refs] - var_sym = Symbol(var_ref) - eval(:(Symbolics.@variables($var_sym)[1])) - end - bin_var_sym = Symbol("$bin_var[$i]") - λ = Num(Symbolics.Sym{Float64}(bin_var_sym)) - - #parse constr - op, lhs, rhs = parse_constraint(constr) - replace_Symvars!(lhs, constr.model) #convert JuMP variables into Symbolic variables - gx = eval(lhs) #convert the LHS of the constraint into a Symbolic expression - gx = gx - M*(1-λ) #add bigM - - #update constraint - replace_constraint(constr, gx, op, rhs) -end -big_m_reformulation!(constr::AbstractArray{<:ConstraintRef}, bin_var, M, i, j, k) = - big_m_reformulation(constr[k], bin_var, M, i, j, k) \ No newline at end of file +################################################################################ +# BIG-M REFORMULATION +################################################################################ +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::JuMP.ScalarConstraint{T, S}, + bvref::JuMP.VariableRef, + method::BigM +) where {T, S <: _MOI.LessThan} + M = _get_M_value(con.func, con.set, method) + new_func = JuMP.@expression(model, con.func - M*(1-bvref)) + reform_con = JuMP.build_constraint(error, new_func, con.set) + return [reform_con] +end +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::JuMP.VectorConstraint{T, S, R}, + bvref::JuMP.VariableRef, + method::BigM +) where {T, S <: _MOI.Nonpositives, R} + M = [_get_M_value(func, con.set, method) for func in con.func] + new_func = JuMP.@expression(model, [i=1:con.set.dimension], + con.func[i] - M[i]*(1-bvref) + ) + reform_con = JuMP.build_constraint(error, new_func, con.set) + return [reform_con] +end +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::JuMP.ScalarConstraint{T, S}, + bvref::JuMP.VariableRef, + method::BigM +) where {T, S <: _MOI.GreaterThan} + M = _get_M_value(con.func, con.set, method) + new_func = JuMP.@expression(model, con.func + M*(1-bvref)) + reform_con = JuMP.build_constraint(error, new_func, con.set) + return [reform_con] +end +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::JuMP.VectorConstraint{T, S, R}, + bvref::JuMP.VariableRef, + method::BigM +) where {T, S <: _MOI.Nonnegatives, R} + M = [_get_M_value(func, con.set, method) for func in con.func] + new_func = JuMP.@expression(model, [i=1:con.set.dimension], + con.func[i] + M[i]*(1-bvref) + ) + reform_con = JuMP.build_constraint(error, new_func, con.set) + return [reform_con] +end +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::JuMP.ScalarConstraint{T, S}, + bvref::JuMP.VariableRef, + method::BigM +) where {T, S <: Union{_MOI.Interval, _MOI.EqualTo}} + M = _get_M_value(con.func, con.set, method) + new_func_gt = JuMP.@expression(model, con.func + M[1]*(1-bvref)) + new_func_lt = JuMP.@expression(model, con.func - M[2]*(1-bvref)) + set_values = _set_values(con.set) + reform_con_gt = JuMP.build_constraint(error, new_func_gt, _MOI.GreaterThan(set_values[1])) + reform_con_lt = JuMP.build_constraint(error, new_func_lt, _MOI.LessThan(set_values[2])) + return [reform_con_gt, reform_con_lt] +end +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::JuMP.VectorConstraint{T, S, R}, + bvref::JuMP.VariableRef, + method::BigM +) where {T, S <: _MOI.Zeros, R} + M = [_get_M_value(func, con.set, method) for func in con.func] + new_func_nn = JuMP.@expression(model, [i=1:con.set.dimension], + con.func[i] + M[i][1]*(1-bvref) + ) + new_func_np = JuMP.@expression(model, [i=1:con.set.dimension], + con.func[i] - M[i][2]*(1-bvref) + ) + reform_con_nn = JuMP.build_constraint(error, new_func_nn, _MOI.Nonnegatives(con.set.dimension)) + reform_con_np = JuMP.build_constraint(error, new_func_np, _MOI.Nonpositives(con.set.dimension)) + return [reform_con_nn, reform_con_np] +end \ No newline at end of file diff --git a/src/bounds.jl b/src/bounds.jl deleted file mode 100644 index ac2fa3b..0000000 --- a/src/bounds.jl +++ /dev/null @@ -1,77 +0,0 @@ -""" - apply_interval_arithmetic(constr) - -Apply interval arithmetic on a constraint to find the bounds on the constraint. -""" -function apply_interval_arithmetic(constr) - #convert constraints into Expr to replace variables with interval sets and determine bounds - constr_type, constr_func_expr, constr_rhs = parse_constraint(constr) - #create a map of variables to their bounds - interval_map = Dict() - vars = all_variables(constr.model)#constr.model[:gdp_variable_constrs] - obj_dict = object_dictionary(constr.model) - bounds_dict = :variable_bounds_dict in keys(obj_dict) ? obj_dict[:variable_bounds_dict] : Dict() #NOTE: should pass as an keyword argument - for var in vars - LB, UB = get_bounds(var, bounds_dict) - interval_map[string(var)] = LB..UB - end - constr_func_expr = replace_intevals!(constr_func_expr, interval_map) - #get bounds on the entire expression - func_bounds = eval(constr_func_expr) - Mlo = func_bounds.lo - constr_rhs - Mhi = func_bounds.hi - constr_rhs - M = constr_type == :(<=) ? Mhi : Mlo - isinf(M) && error("M parameter for $constr cannot be infered due to lack of variable bounds.") - return M -end - -""" - get_bounds(var::VariableRef) - -Get bounds on a variable. - - get_bounds(var, bounds_dict::Dict) - -Get bounds on a variable. Check if a bounds dictionary has been provided with bounds for that value. - - get_bounds(var::AbstractArray{VariableRef}, bounds_dict::Dict, LB, UB) - -Update lower bound `LB` and upper bound `UB` on a variable container. -""" -function get_bounds(var::VariableRef) - LB = has_lower_bound(var) ? lower_bound(var) : (is_binary(var) ? 0 : -Inf) - UB = has_upper_bound(var) ? upper_bound(var) : (is_binary(var) ? 1 : Inf) - return LB, UB -end -function get_bounds(var::VariableRef, bounds_dict::Dict) - if string(var) in keys(bounds_dict) - return bounds_dict[string(var)] - else - return get_bounds(var) - end -end -function get_bounds(var::AbstractArray{VariableRef}, bounds_dict::Dict, LB, UB) - #populate UB and LB - for idx in eachindex(var) - LB[idx], UB[idx] = get_bounds(var[idx], bounds_dict) - end - return LB, UB -end -function get_bounds(var::Array{VariableRef}, bounds_dict::Dict) - #initialize - LB, UB = zeros(size(var)), zeros(size(var)) - return get_bounds(var, bounds_dict, LB, UB) -end -function get_bounds(var::Containers.DenseAxisArray, bounds_dict::Dict) - #initialize - LB = Containers.DenseAxisArray(zeros(size(var)), axes(var)...) - UB = Containers.DenseAxisArray(zeros(size(var)), axes(var)...) - return get_bounds(var, bounds_dict, LB, UB) -end -function get_gounds(var::Containers.SparseAxisArray, bounds_dict::Dict) - #initialize - idxs = keys(var.data) - LB = Containers.SparseAxisArray(Dict(idx => 0. for idx in idxs)) - UB = Containers.SparseAxisArray(Dict(idx => 0. for idx in idxs)) - return get_bounds(var, bounds_dict, LB, UB) -end \ No newline at end of file diff --git a/src/constraint.jl b/src/constraint.jl index 08b44da..e69de29 100644 --- a/src/constraint.jl +++ b/src/constraint.jl @@ -1,206 +0,0 @@ -is_interval_constraint(con_ref::ConstraintRef) = constraint_object(con_ref).set isa MOI.Interval -is_interval_constraint(con_ref::NonlinearConstraintRef) = count(i -> i == :(<=), Meta.parse(string(con_ref)).args) == 2 -is_equality_constraint(con_ref::ConstraintRef) = constraint_object(con_ref).set isa MOI.EqualTo -is_equality_constraint(con_ref::NonlinearConstraintRef) = Meta.parse(string(con_ref)).args[1] == :(==) -JuMP.name(con_ref::NonlinearConstraintRef) = "" - -""" - check_constraint!(m::Model, constr::Tuple) - -Check constraints in a disjunction Tuple. - - check_constraint!(m::Model, constr_j, constr_list::Vector) - -Check nested constraint and update `constr_list`. - - check_constraint!(m::Model, constr) - -Check constraint in a Model. - - check_constraint!(m::Model, constr::Nothing) - -Return nothing for an empty disjunct. -""" -function check_constraint!(m::Model, constr::Tuple) - constr_list = [] - map(constr_j -> check_constraint!(m, constr_j, constr_list), constr) - return Tuple(constr_list) -end -function check_constraint!(m::Model, constr_j::Tuple, constr_list::Vector) - map(constr_jk -> check_constraint!(m, constr_jk, constr_list), constr_j) -end -function check_constraint!(m::Model, constr_j::AbstractArray{<:ConstraintRef}, constr_list::Vector) - push!(constr_list, check_constraint!(m, constr_j)) -end -function check_constraint!(m::Model, constr_j::ConstraintRef, constr_list::Vector) - push!(constr_list, check_constraint!(m, constr_j)) -end -function check_constraint!(m::Model, constr::ConstraintRef) - @assert all(is_valid(m, constr)) "$constr is not a valid constraint." - new_constr = split_constraint(m, constr) - if isnothing(new_constr) - new_constr = constr - else - constr_name = gen_constraint_name(constr) - m[constr_name] = new_constr - # constr_str = split(string(constr),"}")[end] - # @warn "$constr_str uses the `MOI.Interval` or `MOI.EqualTo` set. Each instance of the interval set has been split into two constraints, one for each bound." - delete_original_constraint!(m, constr) - end - return new_constr -end -function check_constraint!(m::Model, constr::AbstractArray{<:ConstraintRef}) - @assert all(is_valid.(m, constr)) "$constr is not a valid constraint." - if !any(is_interval_constraint.(constr)) && !any(is_equality_constraint.(constr)) - new_constr = constr - else - idxs = get_indices(constr) - constr_dict = Dict(union( - [ - split_constraint(m, constr[idx...]) |> - i -> isnothing(i) ? - (idx...,"") => constr[idx...] : - [(idx...,"lb") => i[1], (idx...,"ub") => i[2]] - for idx in idxs - ]... - )) - new_constr = Containers.SparseAxisArray(constr_dict) - constr_name = gen_constraint_name(constr) - m[constr_name] = new_constr - # constr_str = split(string(constr),"}")[end] - # @warn "$constr_str uses the `MOI.Interval` or `MOI.EqualTo` set. Each instance of the interval set has been split into two constraints, one for each bound." - delete_original_constraint!(m, constr) - end - return new_constr -end -check_constraint!(m::Model, constr::Nothing) = nothing - -""" - split_constraint(m::Model, constr::NonlinearConstraintRef) - -Split a nonlinear constraint that is an Interval or EqualTo constraint. - - split_constraint(m::Model, constr::ConstraintRef, constr_name::String = name(constr)) - -Split a linear or quadratic constraint. - - split_constraint(m::Model, constr_obj::ScalarConstraint, lb_name::String, ub_name::String) - -Split a constraint that is a MOI.EqualTo or MOI.Interval. - - split_constraint(m::Model, func::Union{AffExpr,QuadExpr}, lb::Float64, ub::Float64, lb_name::String, ub_name::String) - -Create split constraint for linear or quadratic constraint. - - split_constraint(m::Model, constr::ConstraintRef, constr_func_expr::Expr, lb::Float64, ub::Float64) - -Split a nonlinear constraint. - - split_constraint(args...) - -Return nothing for an empty disjunct. -""" -function split_constraint(m::Model, constr::NonlinearConstraintRef) - constr_expr = Meta.parse(string(constr)) - if constr_expr.args[1] == :(==) #replace == for lb <= expr <= ub and split - lb, ub = 0, 0#rhs is always 0, but could get obtained from: constr_expr.args[3] - constr_func_expr = copy(constr_expr.args[2]) - new_constraints = split_constraint(m, constr, constr_func_expr, lb, ub) - return new_constraints - elseif count(x -> x == :(<=), constr_expr.args) == 2 #split lb <= expr <= ub - lb = constr_expr.args[1] - ub = constr_expr.args[5] - constr_func_expr = copy(constr_expr.args[3]) #get func part of constraint - new_constraints = split_constraint(m, constr, constr_func_expr, lb, ub) - return new_constraints - else - return nothing - end -end -function split_constraint(m::Model, constr::ConstraintRef, constr_name::String = name(constr)) - if isempty(constr_name) - constr_name = "[$constr]" - end - lb_name = name_split_constraint(constr_name, :lb) - ub_name = name_split_constraint(constr_name, :ub) - constr_obj = constraint_object(constr) - new_constraints = split_constraint(m, constr_obj, lb_name, ub_name) - - return new_constraints -end -function split_constraint(m::Model, func::Union{AffExpr,QuadExpr}, lb::Float64, ub::Float64, lb_name::String, ub_name::String) - return [ - @constraint(m, lb <= func, base_name = lb_name), - @constraint(m, func <= ub, base_name = ub_name) - ] -end -function split_constraint(m::Model, constr_obj::ScalarConstraint{T,<:MOI.EqualTo}, lb_name::String, ub_name::String) where T - split_constraint(m, constr_obj.func, constr_obj.set.value, constr_obj.set.value, lb_name, ub_name) -end -function split_constraint(m::Model, constr_obj::ScalarConstraint{T,<:MOI.Interval}, lb_name::String, ub_name::String) where T - split_constraint(m, constr_obj.func, constr_obj.set.lower, constr_obj.set.upper, lb_name, ub_name) -end -function split_constraint(m::Model, constr::ConstraintRef, constr_func_expr::Expr, lb::Float64, ub::Float64) - replace_JuMPvars!(constr_func_expr, m) #replace Expr with JuMP vars - #replace original constraint with lb <= func - lb_constr = JuMP._NonlinearConstraint( - JuMP._NonlinearExprData(m, constr_func_expr), - lb, - Inf - ) - m.nlp_data.nlconstr[constr.index.value] = lb_constr - #create new constraint for func <= ub - constr_expr_ub = Expr(:call, :(<=), constr_func_expr, ub) - ub_constr = add_nonlinear_constraint(m, constr_expr_ub) - - return [constr, ub_constr] -end -split_constraint(args...) = nothing - -delete_original_constraint!(m::Model, constr::ConstraintRef) = delete(m,constr) -delete_original_constraint!(m::Model, constr::NonlinearConstraintRef) = nothing -delete_original_constraint!(m::Model, constr::AbstractArray{<:ConstraintRef}) = map(c -> delete_original_constraint!(m,c), constr) - -""" - parse_constraint(constr::ConstraintRef) - -Extract constraint operator symbol (op), constraint function expression (LHS), and constraint RHS. -""" -function parse_constraint(constr::ConstraintRef) - #check function has a single comparrison operator (<=, >=, ==) - constr_str = replace(split(string(constr),": ")[end], " " => "", "²" => "^2") #remove name, blanks and power notation - constr_expr = Meta.parse(constr_str).args - op = constr_expr[1] #comparrison operator - lhs = constr_expr[2] #LHS of the constraint - rhs = constr_expr[3] #RHS of constraint - return op, lhs, rhs -end - -""" - -""" -function replace_constraint(constr::NonlinearConstraintRef, sym_expr, op, rhs) - #convert symbolic function to expression - expr = Base.remove_linenums!(build_function(sym_expr)).args[2].args[1] - #replace symbolic variables by their JuMP variables and math operators with their symbols - m = constr.model - replace_JuMPvars!(expr, m) - replace_operators!(expr) - # determine bounds of original constraint (if op is ==, both bounds are set to rhs) - upper_b = (op == :(>=)) ? Inf : rhs - lower_b = (op == :(<=)) ? -Inf : rhs - # replace NL constraint currently in the model with the reformulated one - m.nlp_data.nlconstr[constr.index.value] = JuMP._NonlinearConstraint(JuMP._NonlinearExprData(m, expr), lower_b, upper_b) -end -function replace_constraint(constr::ConstraintRef, sym_expr, op, rhs) - #convert symbolic function to expression - op = eval(op) - expr = Base.remove_linenums!(build_function(op(sym_expr,rhs))).args[2].args[1] - #replace symbolic variables by their JuMP variables and math operators with their symbols - m = constr.model - replace_JuMPvars!(expr, m) - replace_operators!(expr) - #add a nonlinear constraint with the perspective function and delete old constraint - add_nonlinear_constraint(m, expr) - delete(m, constr) -end \ No newline at end of file diff --git a/src/constraints.jl b/src/constraints.jl new file mode 100644 index 0000000..1c8941f --- /dev/null +++ b/src/constraints.jl @@ -0,0 +1,541 @@ +################################################################################ +# HELPER SET MAPPING FUNCTIONS +################################################################################ +# helper functions to get the value of an MOI set +_set_value(set::_MOI.LessThan) = set.upper +_set_value(set::_MOI.GreaterThan) = set.lower +_set_value(set::_MOI.EqualTo) = set.value +_set_values(set::_MOI.EqualTo) = (set.value, set.value) +_set_values(set::_MOI.Interval) = (set.lower, set.upper) + +# helper functions to reformulate vector constraints to indicator constraints +_vec_to_scalar_set(set::_MOI.Nonpositives) = _MOI.LessThan(0) +_vec_to_scalar_set(set::_MOI.Nonnegatives) = _MOI.GreaterThan(0) +_vec_to_scalar_set(set::_MOI.Zeros) = _MOI.EqualTo(0) + +# helper functions to map jump selector to moi selector sets +_jump_to_moi_selector(set::Exactly) = _MOIExactly +_jump_to_moi_selector(set::AtLeast) = _MOIAtLeast +_jump_to_moi_selector(set::AtMost) = _MOIAtMost + +# helper functions to map selectors to scalar sets +_vec_to_scalar_set(set::_MOIExactly) = _MOI.EqualTo +_vec_to_scalar_set(set::_MOIAtLeast) = _MOI.GreaterThan +_vec_to_scalar_set(set::_MOIAtMost) = _MOI.LessThan + +################################################################################ +# BOILERPLATE EXTENSION METHODS +################################################################################ +for (RefType, loc) in ((:DisjunctConstraintRef, :disjunct_constraints), + (:DisjunctionRef, :disjunctions), + (:LogicalConstraintRef, :logical_constraints)) + @eval begin + @doc """ + JuMP.owner_model(cref::$($RefType)) + + Return the model to which `cref` belongs. + """ + JuMP.owner_model(cref::$RefType) = cref.model + + @doc """ + JuMP.index(cref::$($RefType)) + + Return the index constraint associated with `cref`. + """ + JuMP.index(cref::$RefType) = cref.index + + @doc """ + JuMP.is_valid(model::JuMP.Model, cref::$($RefType)) + + Return `true` if `cref` refers to a valid constraint in the `GDP model`. + """ + function JuMP.is_valid(model::JuMP.Model, cref::$RefType) # TODO: generalize for AbstractModel + return model === JuMP.owner_model(cref) + end + + # Get the ConstraintData object + function _constraint_data(cref::$RefType) + return gdp_data(JuMP.owner_model(cref)).$loc[JuMP.index(cref)] + end + + @doc """ + JuMP.name(cref::$($RefType)) + + Get a constraint's name attribute. + """ + function JuMP.name(cref::$RefType) + return _constraint_data(cref).name + end + + @doc """ + JuMP.set_name(cref::$($RefType), name::String) + + Set a constraint's name attribute. + """ + function JuMP.set_name(cref::$RefType, name::String) + _constraint_data(cref).name = name + _set_ready_to_optimize(JuMP.owner_model(cref), false) + return + end + + @doc """ + JuMP.constraint_object(cref::$($RefType)) + + Return the underlying constraint data for the constraint + referenced by `cref`. + """ + function JuMP.constraint_object(cref::$RefType) + return _constraint_data(cref).constraint + end + + # Extend Base methods + function Base.:(==)(cref1::$RefType, cref2::$RefType) + return cref1.model === cref2.model && cref1.index == cref2.index + end + Base.copy(cref::$RefType) = cref + @doc """ + Base.getindex(map::JuMP.GenericReferenceMap, cref::$($RefType)) + + ... + """ + function Base.getindex(map::JuMP.ReferenceMap, cref::$RefType) + $RefType(map.model, JuMP.index(cref)) + end + end +end + +# Extend delete +""" + JuMP.delete(model::JuMP.Model, cref::DisjunctionRef) + +Delete a disjunction constraint from the `GDP model`. +""" +function JuMP.delete(model::JuMP.Model, cref::DisjunctionRef) + @assert JuMP.is_valid(model, cref) "Disjunctive constraint does not belong to model." + cidx = JuMP.index(cref) + dict = _disjunctions(model) + delete!(dict, cidx) + _set_ready_to_optimize(model, false) + return +end + +""" + JuMP.delete(model::JuMP.Model, cref::DisjunctConstraintRef) + +Delete a disjunct constraint from the `GDP model`. +""" +function JuMP.delete(model::JuMP.Model, cref::DisjunctConstraintRef) + @assert JuMP.is_valid(model, cref) "Disjunctive constraint does not belong to model." + cidx = JuMP.index(cref) + dict = _disjunct_constraints(model) + delete!(dict, cidx) + _set_ready_to_optimize(model, false) + return +end + +""" + JuMP.delete(model::JuMP.Model, cref::LogicalConstraintRef) + +Delete a logical constraint from the `GDP model`. +""" +function JuMP.delete(model::JuMP.Model, cref::LogicalConstraintRef) + @assert JuMP.is_valid(model, cref) "Logical constraint does not belong to model." + cidx = JuMP.index(cref) + dict = _logical_constraints(model) + delete!(dict, cidx) + _set_ready_to_optimize(model, false) + return +end + +################################################################################ +# Disjunct Constraints +################################################################################ +function _check_expression(expr) + vars = Set{JuMP.VariableRef}() + _interrogate_variables(v -> push!(vars, v), expr) + if any(JuMP.is_binary.(vars)) || any(JuMP.is_integer.(vars)) + error("Disjunct constraints cannot contain binary or integer variables.") + end + return +end +""" + JuMP.build_constraint( + _error::Function, + func, + set::_MOI.AbstractScalarSet, + tag::DisjunctConstraint + )::_DisjunctConstraint + +Extend `JuMP.build_constraint` to add constraints to disjuncts. This in +combination with `JuMP.add_constraint` enables the use of +`@constraint(model, [name], constr_expr, tag)`, where tag is a +`DisjunctConstraint(::Type{LogicalVariableRef})`. The user must specify the +`LogicalVariable` to use as the indicator for the `_DisjunctConstraint` being created. +""" +function JuMP.build_constraint( + _error::Function, + func, + set::_MOI.AbstractScalarSet, + tag::DisjunctConstraint +) + _check_expression(func) + constr = JuMP.build_constraint(_error, func, set) + return _DisjunctConstraint(constr, tag.indicator) +end + +# Allows for building DisjunctConstraints for VectorConstraints since these get parsed differently by JuMP (JuMP changes the set to a MOI.AbstractScalarSet) +for SetType in ( + JuMP.Nonnegatives, JuMP.Nonpositives, JuMP.Zeros, + MOI.Nonnegatives, MOI.Nonpositives, MOI.Zeros +) + @eval begin + @doc """ + JuMP.build_constraint( + _error::Function, + func, + set::$($SetType), + tag::DisjunctConstraint + )::_DisjunctConstraint + + Extend `JuMP.build_constraint` to add `VectorConstraint`s to disjuncts. + """ + function JuMP.build_constraint( + _error::Function, + func, + set::$SetType, + tag::DisjunctConstraint + ) + _check_expression(func) + constr = JuMP.build_constraint(_error, func, set) + return _DisjunctConstraint(constr, tag.indicator) + end + end +end + +# Allow intervals to handle tags +function JuMP.build_constraint( + _error::Function, + func::JuMP.AbstractJuMPScalar, + lb::Real, + ub::Real, + tag::DisjunctConstraint +) + _check_expression(func) + constr = JuMP.build_constraint(_error, func, lb, ub) + func = JuMP.jump_function(constr) + set = JuMP.moi_set(constr) + return JuMP.build_constraint(_error, func, set, tag) +end + +""" + JuMP.add_constraint( + model::JuMP.Model, + con::_DisjunctConstraint, + name::String = "" + )::DisjunctConstraintRef + +Extend `JuMP.add_constraint` to add a [`_DisjunctConstraint`](@ref) to a [`GDPModel`](@ref). +The constraint is added to the `GDPData` in the `.ext` dictionary of the `GDPModel`. +""" +function JuMP.add_constraint( + model::JuMP.Model, + con::_DisjunctConstraint, + name::String = "" +) + is_gdp_model(model) || error("Can only add disjunct constraints to `GDPModel`s.") + data = ConstraintData(con.constr, name) + idx = _MOIUC.add_item(gdp_data(model).disjunct_constraints, data) + _add_indicator_var(con, DisjunctConstraintRef(model, idx), model) + return DisjunctConstraintRef(model, idx) +end + +################################################################################ +# DISJUNCTIONS +################################################################################ +# Add the variable mappings +function _add_indicator_var( + con::_DisjunctConstraint{C, LogicalVariableRef}, + cref, + model + ) where {C <: JuMP.AbstractConstraint} + JuMP.is_valid(model, con.lvref) || error("Logical variable belongs to a different model.") + if !haskey(_indicator_to_constraints(model), con.lvref) + _indicator_to_constraints(model)[con.lvref] = Vector{Union{DisjunctConstraintRef, DisjunctionRef}}() + end + push!(_indicator_to_constraints(model)[con.lvref], cref) + return +end +# check disjunction +function _check_disjunction(_error, lvrefs::AbstractVector{LogicalVariableRef}, model::JuMP.Model) + isequal(unique(lvrefs),lvrefs) || _error("Not all the logical indicator variables are unique.") + for lvref in lvrefs + if !JuMP.is_valid(model, lvref) + _error("`$lvref` is not a valid logical variable reference.") + end + end + return lvrefs +end + +# fallback +function _check_disjunction(_error, lvrefs, model::JuMP.Model) + _error("Unrecognized disjunction input structure.") # TODO add details on proper syntax +end + +# Write the main function for creating disjunctions that is macro friendly +function _create_disjunction( + _error::Function, + model::JuMP.Model, # TODO: generalize to AbstractModel + structure::AbstractVector, #generalize for containers + name::String, + nested::Bool +) + is_gdp_model(model) || error("Can only add disjunctions to `GDPModel`s.") + + # build the disjunction + indicators = _check_disjunction(_error, structure, model) + disjunction = Disjunction(indicators, nested) + + # add it to the model + disjunction_data = ConstraintData(disjunction, name) + idx = _MOIUC.add_item(_disjunctions(model), disjunction_data) + + _set_ready_to_optimize(model, false) + return DisjunctionRef(model, idx) +end + +# Disjunction build for unnested disjunctions +function _disjunction( + _error::Function, + model::JuMP.Model, # TODO: generalize to AbstractModel + structure::AbstractVector, #generalize for containers + name::String +) + return _create_disjunction(_error, model, structure, name, false) +end + +# Fallback disjunction build for nonvector structure +function _disjunction( + _error::Function, + model::JuMP.Model, # TODO: generalize to AbstractModel + structure, + name::String +) + _error("Unrecognized disjunction input structure.") +end + +# Disjunction build for nested disjunctions +function _disjunction( + _error::Function, + model::JuMP.Model, # TODO: generalize to AbstractModel + structure, + name::String, + tag::DisjunctConstraint +) + dref = _create_disjunction(_error, model, structure, name, true) + obj = JuMP.constraint_object(dref) + _add_indicator_var(_DisjunctConstraint(obj, tag.indicator), dref, model) + return dref +end + +# General fallback for additional arguments +function _disjunction( + _error::Function, + model::JuMP.Model, # TODO: generalize to AbstractModel + structure, + name::String, + extra... +) + for arg in extra + _error("Unrecognized argument `$arg`.") + end +end + +""" + disjunction( + model::JuMP.Model, + disjunct_indicators::Vector{LogicalVariableRef} + name::String = "" + ) + +Function to add a [`Disjunction`](@ref) to a [`GDPModel`](@ref). + + disjunction( + model::JuMP.Model, + disjunct_indicators::Vector{LogicalVariableRef}, + nested_tag::DisjunctConstraint, + name::String = "" + ) + +Function to add a nested [`Disjunction`](@ref) to a [`GDPModel`](@ref). +""" +function disjunction( + model::JuMP.Model, + disjunct_indicators, + name::String = "" +) # TODO add kw argument to build exactly 1 constraint + return _disjunction(error, model, disjunct_indicators, name) +end +function disjunction( + model::JuMP.Model, + disjunct_indicators, + nested_tag::DisjunctConstraint, + name::String = "", +) # TODO add kw argument to build exactly 1 constraint + return _disjunction(error, model, disjunct_indicators, name, nested_tag) +end + +################################################################################ +# LOGICAL CONSTRAINTS +################################################################################ +JuMP.operator_to_set(_error::Function, ::Val{:⟹}) = _error( + "Cannot use ⟹ in a MOI set (invalid right-hand side). If you are seeing this error, " * + "you likely added a logical constraint of the form A ⟹ B ∈ IsTrue(). " * + "Instead, you should enclose the constraint function in parenthesis: " * + "(A ⟹ B) ∈ IsTrue()." +) +JuMP.operator_to_set(_error::Function, ::Val{:⇔}) = _error( + "Cannot use ⇔ in a MOI set (invalid right-hand side). If you are seeing this error, " * + "you likely added a logical constraint of the form A ⇔ B ∈ IsTrue(). " * + "Instead, you should enclose the constraint function in parenthesis: " * + "(A ⇔ B) ∈ IsTrue()." +) + +""" + function JuMP.build_constraint( + _error::Function, + func::AbstractVector{T}, + set::S + ) where {T <: Union{LogicalVariableRef, _LogicalExpr}, S <: Union{Exactly, AtLeast, AtMost}} + +Extend `JuMP.build_constraint` to add logical cardinality constraints to a [`GDPModel`](@ref). +This in combination with `JuMP.add_constraint` enables the use of +`@constraint(model, [name], logical_expr in set)`, where set can be either of the following +cardinality sets: `AtLeast(n)`, `AtMost(n)`, or `Exactly(n)`. + +## Example + +To select exactly 1 logical variable `Y` to be `true`, do +(the same can be done with `AtLeast(n)` and `AtMost(n)`): + +```jldoctest +julia> model = GDPModel(); +julia> @variable(model, Y[i = 1:2], LogicalVariable); +julia> @constraint(model, [Y[1], Y[2]] in Exactly(1)); +``` + + JuMP.build_constraint( + _error::Function, + func::_LogicalExpr, + set::IsTrue + ) + +Extend `JuMP.build_constraint` to add logical propositional constraints to a [`GDPModel`](@ref). +This in combination with `JuMP.add_constraint` enables the use of +`@constraint(model, [name], logical_expr in IsTrue())` to define a Boolean expression that must +either be true or false. +""" +function JuMP.build_constraint( # Cardinality logical constraint + _error::Function, + func::AbstractVector{T}, # allow any vector-like JuMP container + set::S # TODO: generalize to allow CP sets from MOI +) where {T <: LogicalVariableRef, S <: Union{Exactly, AtLeast, AtMost}} + new_set = _jump_to_moi_selector(set)(length(func) + 1) + new_func = Union{Number,LogicalVariableRef}[set.value, func...] + return JuMP.VectorConstraint(new_func, new_set) +end +function JuMP.build_constraint( # Cardinality logical constraint + _error::Function, + func::AbstractVector, + set::S # TODO: generalize to allow CP sets from MOI +) where {S <: Union{Exactly, AtLeast, AtMost}} + _error("Selector constraints can only be applied to a Vector or Container of LogicalVariableRefs.") +end + +# Proposition logical constraint: _LogicalExpr +function JuMP.build_constraint( + _error::Function, + func::_LogicalExpr, + set::IsTrue + ) + if !(func.head in _LogicalOperatorHeads) + _error("Unrecognized logical operator `$(func.head)`.") + else + return JuMP.ScalarConstraint(func, set) + end +end + +# Fallback for LogicalVariableRef in IsTrue +function JuMP.build_constraint( + _error::Function, + func::LogicalVariableRef, + set::IsTrue + ) + _error( + "Logical propositions must be of the form `logical_expr in IsTrue()`. " * + "If you are trying to fix a logical variable, use `fix(logical_var, true)` instead." + ) +end + +# Fallback for Affine/Quad expressions +function JuMP.build_constraint( + _error::Function, + expr::Union{JuMP.GenericAffExpr{C, LogicalVariableRef}, JuMP.GenericQuadExpr{C, LogicalVariableRef}}, + set::_MOI.AbstractScalarSet +) where {C} + _error("Cannot add, subtract, or multiply with logical variables.") +end + +# Fallback for other set types (TODO: we could relax this later if needed) +function JuMP.build_constraint( + _error::Function, + expr::Union{LogicalVariableRef, _LogicalExpr}, + set::_MOI.AbstractScalarSet +) + _error("Invalid set `$set` for logical constraint.") +end + +""" + function JuMP.add_constraint( + model::JuMP.Model, + c::JuMP.ScalarConstraint{<:F, S}, + name::String = "" + ) where {F <: Union{LogicalVariableRef, _LogicalExpr}, S} + +Extend `JuMP.add_constraint` to allow creating logical proposition constraints +for a [`GDPModel`](@ref) with the `@constraint` macro. + + function JuMP.add_constraint( + model::JuMP.Model, + c::JuMP.VectorConstraint{<:F, S, Shape}, + name::String = "" + ) where {F <: Union{Number, LogicalVariableRef, _LogicalExpr}, S, Shape} + +Extend `JuMP.add_constraint` to allow creating logical cardinality constraints +for a [`GDPModel`](@ref) with the `@constraint` macro. +""" +function JuMP.add_constraint( + model::JuMP.Model, + c::JuMP.ScalarConstraint{F, S}, + name::String = "" +) where {F <: Union{LogicalVariableRef, _LogicalExpr}, S <: IsTrue} + is_gdp_model(model) || error("Can only add logical constraints to `GDPModel`s.") + @assert all(JuMP.is_valid.(model, _get_constraint_variables(model, c))) "Constraint variables do not belong to model." + constr_data = ConstraintData(c, name) + idx = _MOIUC.add_item(_logical_constraints(model), constr_data) + _set_ready_to_optimize(model, false) + return LogicalConstraintRef(model, idx) +end +function JuMP.add_constraint( + model::JuMP.Model, + c::JuMP.VectorConstraint{F, S, Shape}, + name::String = "" +) where {F, S <: Union{_MOIAtLeast, _MOIAtMost, _MOIExactly}, Shape} + is_gdp_model(model) || error("Can only add logical constraints to `GDPModel`s.") + @assert all(JuMP.is_valid.(model, _get_constraint_variables(model, c))) "Constraint variables do not belong to model." + constr_data = ConstraintData(c, name) + idx = _MOIUC.add_item(_logical_constraints(model), constr_data) + _set_ready_to_optimize(model, false) + return LogicalConstraintRef(model, idx) +end + +# TODO create bridges for MOI sets for and use BridgeableConstraint with build_constraint diff --git a/src/datatypes.jl b/src/datatypes.jl new file mode 100644 index 0000000..b477358 --- /dev/null +++ b/src/datatypes.jl @@ -0,0 +1,420 @@ +################################################################################ +# LOGICAL VARIABLES +################################################################################ + +""" + LogicalVariable <: JuMP.AbstractVariable + +A variable type the logical variables associated with disjuncts in a [`Disjunction`](@ref). + +**Fields** +- `fix_value::Union{Nothing, Bool}`: A fixed boolean value if there is one. +- `start_value::Union{Nothing, Bool}`: An initial guess if there is one. +""" +struct LogicalVariable <: JuMP.AbstractVariable + fix_value::Union{Nothing, Bool} + start_value::Union{Nothing, Bool} +end + +""" + LogicalVariableData + +A type for storing [`LogicalVariable`](@ref)s and any meta-data they +possess. + +**Fields** +- `variable::LogicalVariable`: The variable object. +- `name::String`: The name of the variable. +""" +mutable struct LogicalVariableData + variable::LogicalVariable + name::String +end + +""" + LogicalVariableIndex + +A type for storing the index of a [`LogicalVariable`](@ref). + +**Fields** +- `value::Int64`: The index value. +""" +struct LogicalVariableIndex + value::Int64 +end + +""" + LogicalVariableRef + +A type for looking up logical variables. +""" +struct LogicalVariableRef <: JuMP.AbstractVariableRef + model::JuMP.Model # TODO: generalize for AbstractModels + index::LogicalVariableIndex +end + +################################################################################ +# LOGICAL PROPOSITION SETS +################################################################################ +struct IsTrue <: _MOI.AbstractScalarSet end + +################################################################################ +# LOGICAL SELECTOR (CARDINALITY) SETS +################################################################################ +# TODO check required methods for AbstractVectorSet: +# All AbstractVectorSets of type S must implement: +# • dimension, unless the dimension is +# stored in the set.dimension field +# • Utilities.set_dot, unless the dot +# product between two vectors in the set +# is equivalent to LinearAlgebra.dot. +""" + _MOIAtLeast <: _MOI.AbstractVectorSet + +MOI level set for AtLeast constraints, see [`AtLeast`](@ref) for recommended syntax. +""" +struct _MOIAtLeast <: _MOI.AbstractVectorSet + dimension::Int +end + +""" + _MOIAtMost <: _MOI.AbstractVectorSet + +MOI level set for AtMost constraints, see [`AtMost`](@ref) for recommended syntax. +""" +struct _MOIAtMost <: _MOI.AbstractVectorSet + dimension::Int +end + +""" + _MOIExactly <: _MOI.AbstractVectorSet + +MOI level set for Exactly constraints, see [`Exactly`](@ref) for recommended syntax. +""" +struct _MOIExactly <: _MOI.AbstractVectorSet + dimension::Int +end + +# Create our own JuMP level sets to infer the dimension using the expression +""" + AtLeast{T<:Union{Int,LogicalVariableRef}} <: JuMP.AbstractVectorSet + +Convenient alias for using [`_MOIAtLeast`](@ref). +""" +struct AtLeast{T<:Union{Int,LogicalVariableRef}} <: JuMP.AbstractVectorSet + value::T +end + +""" + AtMost{T<:Union{Int,LogicalVariableRef}} <: JuMP.AbstractVectorSet + +Convenient alias for using [`_MOIAtMost`](@ref). +""" +struct AtMost{T<:Union{Int,LogicalVariableRef}} <: JuMP.AbstractVectorSet + value::T +end + +""" + Exactly <: JuMP.AbstractVectorSet + +Convenient alias for using [`_MOIExactly`](@ref). +""" +struct Exactly{T<:Union{Int,LogicalVariableRef}} <: JuMP.AbstractVectorSet + value::T +end + +# Extend JuMP.moi_set as needed +JuMP.moi_set(set::AtLeast, dim::Int) = _MOIAtLeast(dim) +JuMP.moi_set(set::AtMost, dim::Int) = _MOIAtMost(dim) +JuMP.moi_set(set::Exactly, dim::Int) = _MOIExactly(dim) + +################################################################################ +# LOGICAL CONSTRAINTS +################################################################################ +const _LogicalExpr = JuMP.GenericNonlinearExpr{LogicalVariableRef} + +""" + ConstraintData{C <: JuMP.AbstractConstraint} + +A type for storing constraint objects in [`GDPData`](@ref) and any meta-data +they possess. + +**Fields** +- `constraint::C`: The constraint. +- `name::String`: The name of the proposition. +""" +mutable struct ConstraintData{C <: JuMP.AbstractConstraint} + constraint::C + name::String +end + +""" + LogicalConstraintIndex + +A type for storing the index of a logical constraint. + +**Fields** +- `value::Int64`: The index value. +""" +struct LogicalConstraintIndex + value::Int64 +end + +""" + LogicalConstraintRef + +A type for looking up logical constraints. +""" +struct LogicalConstraintRef + model::JuMP.Model # TODO: generalize for AbstractModels + index::LogicalConstraintIndex +end + +################################################################################ +# DISJUNCT CONSTRAINTS +################################################################################ +""" + DisjunctConstraint + +Used as a tag for constraints that will be used in disjunctions. This is done via +the following syntax: +```julia-repl +julia> @constraint(model, [constr_expr], DisjunctConstraint) + +julia> @constraint(model, [constr_expr], DisjunctConstraint(lvref)) +``` +where `lvref` is a [`LogicalVariableRef`](@ref) that will ultimately be associated +with the disjunct the constraint is added to. If no `lvref` is given, then one is +generated when the disjunction is created. +""" +struct DisjunctConstraint + indicator::LogicalVariableRef +end + +# Create internal type for temporarily packaging constraints for disjuncts +struct _DisjunctConstraint{C <: JuMP.AbstractConstraint, L <: LogicalVariableRef} + constr::C + lvref::L +end + +""" + DisjunctConstraintIndex + +A type for storing the index of a [`DisjunctConstraint`](@ref). + +**Fields** +- `value::Int64`: The index value. +""" +struct DisjunctConstraintIndex + value::Int64 +end + +""" + DisjunctConstraintRef + +A type for looking up disjunctive constraints. +""" +struct DisjunctConstraintRef + model::JuMP.Model # TODO: generalize for AbstractModels + index::DisjunctConstraintIndex +end + +################################################################################ +# DISJUNCTIONS +################################################################################ +""" + Disjunction <: JuMP.AbstractConstraint + +A type for a disjunctive constraint that is comprised of a collection of +disjuncts of indicated by a unique [`LogicalVariableRef`](@ref). + +**Fields** +- `indicators::Vector{LogicalVariableRef}`: The references to the logical variables +(indicators) that uniquely identify each disjunct in the disjunction. +- `nested::Bool`: Is this disjunction nested within another disjunction? +""" +struct Disjunction <: JuMP.AbstractConstraint + indicators::Vector{LogicalVariableRef} + nested::Bool +end + +""" + DisjunctionIndex + +A type for storing the index of a [`Disjunction`](@ref). + +**Fields** +- `value::Int64`: The index value. +""" +struct DisjunctionIndex + value::Int64 +end + +""" + DisjunctionRef + +A type for looking up disjunctive constraints. +""" +struct DisjunctionRef + model::JuMP.Model # TODO: generalize for AbstractModels + index::DisjunctionIndex +end + +################################################################################ +# CLEVER DICTS +################################################################################ + +## Extend the CleverDicts key access methods +# index_to_key +function _MOIUC.index_to_key(::Type{LogicalVariableIndex}, index::Int64) + return LogicalVariableIndex(index) +end +function _MOIUC.index_to_key(::Type{DisjunctConstraintIndex}, index::Int64) + return DisjunctConstraintIndex(index) +end +function _MOIUC.index_to_key(::Type{DisjunctionIndex}, index::Int64) + return DisjunctionIndex(index) +end +function _MOIUC.index_to_key(::Type{LogicalConstraintIndex}, index::Int64) + return LogicalConstraintIndex(index) +end + +# key_to_index +function _MOIUC.key_to_index(key::LogicalVariableIndex) + return key.value +end +function _MOIUC.key_to_index(key::DisjunctConstraintIndex) + return key.value +end +function _MOIUC.key_to_index(key::DisjunctionIndex) + return key.value +end +function _MOIUC.key_to_index(key::LogicalConstraintIndex) + return key.value +end + +################################################################################ +# SOLUTION METHODS +################################################################################ + +""" + AbstractSolutionMethod + +An abstract type for solution methods used to solve `GDPModel`s. +""" +abstract type AbstractSolutionMethod end + +""" + AbstractReformulationMethod <: AbstractSolutionMethod + +An abstract type for reformulation approaches used to solve `GDPModel`s. +""" +abstract type AbstractReformulationMethod <: AbstractSolutionMethod end + +""" + BigM <: AbstractReformulationMethod + +A type for using the big-M reformulation approach for disjunctive constraints. + +**Fields** +- `value::Float64`: Big-M value (default = `1e9`). +- `tight::Bool`: Attempt to tighten the Big-M value (default = `true`)? +""" +struct BigM <: AbstractReformulationMethod + value::Float64 + tighten::Bool + variable_bounds::Dict{JuMP.VariableRef, Tuple{Float64, Float64}} # TODO support other number types? + function BigM(val = 1e9, tight = true) + new(val, tight, Dict{JuMP.VariableRef, Tuple{Float64, Float64}}()) + end +end # TODO add fields if needed + +""" + Hull <: AbstractReformulationMethod + +A type for using the convex hull reformulation approach for disjunctive +constraints. + +**Fields** +- `value::Float64`: epsilon value for nonlinear hull reformulations (default = `1e-6`). +""" +struct Hull <: AbstractReformulationMethod # TODO add fields if needed + value::Float64 + variable_bounds::Dict{JuMP.VariableRef, Tuple{Float64, Float64}} # TODO support other number types? + function Hull(ϵ::Float64 = 1e-6) + new(ϵ, Dict{JuMP.VariableRef, Tuple{Float64, Float64}}()) + end + function Hull(ϵ::Float64, v_bounds::Dict{JuMP.VariableRef, Tuple{Float64, Float64}}) + new(ϵ, v_bounds) + end +end + + +# temp struct to store variable disaggregations (reset for each disjunction) +mutable struct _Hull <: AbstractReformulationMethod + value::Float64 + variable_bounds::Dict{JuMP.VariableRef, Tuple{Float64, Float64}} # TODO support other number types? + disjunction_variables::Dict{JuMP.VariableRef, Vector{JuMP.VariableRef}} + disjunct_variables::Dict{Tuple{JuMP.VariableRef,JuMP.VariableRef}, JuMP.VariableRef} + function _Hull(method::Hull, vrefs::Set{JuMP.VariableRef}) + new( + method.value, + method.variable_bounds, + Dict{JuMP.VariableRef, Vector{JuMP.VariableRef}}(vref => Vector{JuMP.VariableRef}() for vref in vrefs), + Dict{Tuple{JuMP.VariableRef,JuMP.VariableRef}, JuMP.VariableRef}() + ) + end +end + +""" + Indicator <: AbstractReformulationMethod + +A type for using indicator constraint approach for linear disjunctive constraints. +""" +struct Indicator <: AbstractReformulationMethod end + +################################################################################ +# GDP Data +################################################################################ +""" + GDPData + +The core type for storing information in a [`GDPModel`](@ref). +""" +mutable struct GDPData + # Objects + logical_variables::_MOIUC.CleverDict{LogicalVariableIndex, LogicalVariableData} + logical_constraints::_MOIUC.CleverDict{LogicalConstraintIndex, ConstraintData} + disjunct_constraints::_MOIUC.CleverDict{DisjunctConstraintIndex, ConstraintData} + disjunctions::_MOIUC.CleverDict{DisjunctionIndex, ConstraintData{Disjunction}} + + # Indicator variable mappings + indicator_to_binary::Dict{LogicalVariableRef, JuMP.VariableRef} + indicator_to_constraints::Dict{LogicalVariableRef, Vector{Union{DisjunctConstraintRef, DisjunctionRef}}} + + # Reformulation variables and constraints + reformulation_variables::Vector{JuMP.VariableRef} + reformulation_constraints::Vector{JuMP.ConstraintRef} + + # Solution data + solution_method::Union{Nothing, AbstractSolutionMethod} + ready_to_optimize::Bool + + # Default constructor + function GDPData() + new(_MOIUC.CleverDict{LogicalVariableIndex, LogicalVariableData}(), + _MOIUC.CleverDict{LogicalConstraintIndex, ConstraintData}(), + _MOIUC.CleverDict{DisjunctConstraintIndex, ConstraintData}(), + _MOIUC.CleverDict{DisjunctionIndex, ConstraintData{Disjunction}}(), + Dict{LogicalVariableRef, JuMP.VariableRef}(), + Dict{LogicalVariableRef, Vector{Union{DisjunctConstraintRef, DisjunctionRef}}}(), + Vector{JuMP.VariableRef}(), + Vector{JuMP.ConstraintRef}(), + nothing, + false, + ) + end + function GDPData(args...) + new(args...) + end +end diff --git a/src/gdp.jl b/src/gdp.jl index 82eddde..e69de29 100644 --- a/src/gdp.jl +++ b/src/gdp.jl @@ -1,22 +0,0 @@ -mutable struct Disjunct - constraints::Vector{AbstractConstraint} - indicator::VariableRef -end - -mutable struct DisjunctionConstraint <: AbstractConstraint - disjuncts::Vector{Disjunct} -end - -mutable struct GDPdata - gdp_variable_refs::Vector - gdp_variable_names::Vector - disjunctions::Dict -end - -function GDPModel() - model = Model() - model.ext[:GDPdata] = GDPdata() - # model.optimize_hook = - - return model -end \ No newline at end of file diff --git a/src/hull.jl b/src/hull.jl index a36f70d..a80acd1 100644 --- a/src/hull.jl +++ b/src/hull.jl @@ -1,170 +1,245 @@ -CI = MOI.ConstraintIndex -SAF = MOI.ScalarAffineFunction - -""" - hull_reformulation!(constr::ConstraintRef{<:AbstractModel, CI{SAF{T},V}}, bin_var, args...) where {T,V} - -Apply the hull reformulation to a linear constraint. - - hull_reformulation!(constr::ConstraintRef, bin_var, eps, i, j, k) - -Apply the hull reformulation to a nonlinear constraint (includes quadratic) at index k of constraint j in disjunct i. - - hull_reformulation!(constr::AbstractArray{<:ConstraintRef}, bin_var, eps, i, j, k) - -Call the hull reformulation on a constraint at index k of constraint j in disjunct i. -""" -function hull_reformulation!(constr::ConstraintRef{<:AbstractModel, CI{SAF{T},V}}, bin_var, args...) where {T,V} - #check constraint type - i = args[2] #get disjunct index - bin_var_ref = constr.model[bin_var][i] - #replace each variable with its disaggregated version - for var_ref in constr.model[:gdp_variable_refs] - #get disaggregated variable reference - var_name_i = name_disaggregated_variable(var_ref, bin_var, i) - var_i_ref = variable_by_name(constr.model, var_name_i) - #check var_ref is present in the constraint - coeff = normalized_coefficient(constr, var_ref) - iszero(coeff) && continue #if not present, skip - #swap variable for disaggregated variable - set_normalized_coefficient(constr, var_ref, 0) #remove original variable - set_normalized_coefficient(constr, var_i_ref, coeff) #add disaggregated variable +################################################################################ +# VARIABLE DISAGGREGATION +################################################################################ +function _update_variable_bounds(vref::JuMP.VariableRef, method::Hull) + if JuMP.is_binary(vref) #not used + lb, ub = 0, 1 + elseif !JuMP.has_lower_bound(vref) || !JuMP.has_upper_bound(vref) + error("Variable $vref must have both lower and upper bounds defined when using the Hull reformulation.") + else + lb = min(0, JuMP.lower_bound(vref)) + ub = max(0, JuMP.upper_bound(vref)) end - #multiply RHS constant by binary variable - rhs = normalized_rhs(constr) #get rhs - set_normalized_rhs(constr, 0) #set rhs to 0 - set_normalized_coefficient(constr, bin_var_ref, -rhs) #add binary variable (same as multiplying rhs constant by binary variable) -end -function hull_reformulation!(constr::ConstraintRef, bin_var, eps, i, j, k) - eps = get_reform_param(eps, i, j, k) - #create symbolic variables (using Symbolics.jl) - sym_vars = Dict( - symbolic_variable(var_ref) => symbolic_variable(name_disaggregated_variable(var_ref, bin_var, i)) - for var_ref in constr.model[:gdp_variable_refs] + return lb, ub +end +function _disaggregate_variables(model::JuMP.Model, lvref::LogicalVariableRef, vrefs::Set{JuMP.VariableRef}, method::_Hull) + #create disaggregated variables for that disjunct + for vref in vrefs + JuMP.is_binary(vref) && continue #skip binary variables + _disaggregate_variable(model, lvref, vref, method) #create disaggregated var for that disjunct + end +end +function _disaggregate_variable(model::JuMP.Model, lvref::LogicalVariableRef, vref::JuMP.VariableRef, method::_Hull) + #create disaggregated vref + lb, ub = method.variable_bounds[vref] + dvref = JuMP.@variable(model, base_name = "$(vref)_$(lvref)", lower_bound = lb, upper_bound = ub) + push!(_reformulation_variables(model), dvref) + #get binary indicator variable + bvref = _indicator_to_binary(model)[lvref] + #temp storage + if !haskey(method.disjunction_variables, vref) + method.disjunction_variables[vref] = Vector{JuMP.VariableRef}() + end + push!(method.disjunction_variables[vref], dvref) + method.disjunct_variables[vref, bvref] = dvref + #create bounding constraints + dvname = JuMP.name(dvref) + lbname = isempty(dvname) ? "" : "$(dvname)_lower_bound" + ubname = isempty(dvname) ? "" : "$(dvname)_upper_bound" + new_con_lb_ref = JuMP.add_constraint(model, + JuMP.build_constraint(error, lb*bvref - dvref, _MOI.LessThan(0)), + lbname ) - ϵ = eps #epsilon parameter for perspective function (See Furman, Sawaya, Grossmann [2020] perspecive function) - bin_var_sym = Symbol("$bin_var[$i]") - λ = Num(Symbolics.Sym{Float64}(bin_var_sym)) - FSG1 = Num(Symbolics.Sym{Float64}(gensym())) #this will become: [(1-ϵ)⋅λ + ϵ] (See Furman, Sawaya, Grossmann [2020] perspecive function) - FSG2 = Num(Symbolics.Sym{Float64}(gensym())) #this will become: ϵ⋅(1-λ) (See Furman, Sawaya, Grossmann [2020] perspecive function) - - #parse constr - op, lhs, rhs = parse_constraint(constr) - replace_Symvars!(lhs, constr.model) #convert JuMP variables into Symbolic variables - gx = eval(lhs) #convert the LHS of the constraint into a Symbolic expression - #use symbolic substitution to obtain the following expression: - #[(1-ϵ)⋅λ + ϵ]⋅g(v/[(1-ϵ)⋅λ + ϵ]) - ϵ⋅g(0)⋅(1-λ) <= 0 - #first term - g1 = FSG1*substitute(gx, Dict(var => var_i/FSG1 for (var,var_i) in sym_vars)) - #second term - g0 = substitute(gx, Dict(var => 0 for var in keys(sym_vars))) - @assert !isinf(g0.val) "Hull reformulation has failed for non-linear constraint $constr: $gx is not defined at 0. Perspective function is undetermined." - g2 = FSG2*g0 - #create perspective function and simplify - pers_func = simplify(g1 - g2, expand = true) - #replace FSG expressions & simplify - pers_func = substitute(pers_func, Dict(FSG1 => (1-ϵ)*λ+ϵ, - FSG2 => ϵ*(1-λ))) - pers_func = simplify(pers_func) - replace_constraint(constr, pers_func, op, rhs) -end -hull_reformulation!(constr::AbstractArray{<:ConstraintRef}, bin_var, eps, i, j, k) = - hull_reformulation!(constr[k], bin_var, eps, i, j, k) + new_con_ub_ref = JuMP.add_constraint(model, + JuMP.build_constraint(error, dvref - ub*bvref, _MOI.LessThan(0)), + ubname + ) + push!(_reformulation_constraints(model), new_con_lb_ref, new_con_ub_ref) + return dvref +end -""" - disaggregate_variables(m::Model, disj, bin_var) +################################################################################ +# VARIABLE AGGREGATION +################################################################################ +function _aggregate_variable(model::JuMP.Model, ref_cons::Vector{JuMP.AbstractConstraint}, vref::JuMP.VariableRef, method::_Hull) + JuMP.is_binary(vref) && return #skip binary variables + con_expr = JuMP.@expression(model, -vref + sum(method.disjunction_variables[vref])) + push!(ref_cons, + JuMP.build_constraint(error, con_expr, _MOI.EqualTo(0)) + ) + return +end -Disaggregate all variables in the model and tag them with the disjunction name. -""" -function disaggregate_variables(m::Model, disj, bin_var) - #check that variables are bounded - var_refs = m[:gdp_variable_refs] - @assert all((has_upper_bound.(var_refs) .&& has_lower_bound.(var_refs)) .|| is_binary.(var_refs)) "All variables must be bounded to perform the Hull reformulation." - #reformulate variables - obj_dict = object_dictionary(m) - bounds_dict = :variable_bounds_dict in keys(obj_dict) ? obj_dict[:variable_bounds_dict] : Dict() #NOTE: should pass as an keyword argument - for var in get_constraint_variables(m,disj)#var_name in m[:gdp_variable_names] - # var = m[var_name] - var_name = name(var) - #define UB and LB - LB, UB = get_bounds(var, bounds_dict) - #disaggregate variable and add bounding constraints - sum_vars = AffExpr(0) #initialize sum of disaggregated variables - for i in eachindex(disj) - var_name_i_str = "$(var_name)_$(bin_var)_$i" - var_name_i = Symbol(var_name_i_str) - #create disaggregated variable - m[var_name_i] = add_disaggregated_variable(m, var, LB, UB, var_name_i_str) - #apply bounding constraints on disaggregated variable - var_i_lb = "$(var_name_i)_lb" - var_i_ub = "$(var_name_i)_ub" - m[Symbol(var_i_lb)] = @constraint(m, LB * m[bin_var][i] .- m[var_name_i] .<= 0, base_name = var_i_lb) - m[Symbol(var_i_ub)] = @constraint(m, m[var_name_i] .- UB * m[bin_var][i] .<= 0, base_name = var_i_ub) - #update disaggregated sum expression - add_to_expression!(sum_vars, 1, m[var_name_i]) +################################################################################ +# CONSTRAINT DISAGGREGATION +################################################################################ +# variable +function _disaggregate_expression(model::JuMP.Model, vref::JuMP.VariableRef, bvref::JuMP.VariableRef, method::_Hull) + if JuMP.is_binary(vref) || !haskey(method.disjunct_variables, (vref, bvref)) #keep any binary variables or nested disaggregated variables unchanged + return vref + else #replace with disaggregated form + return method.disjunct_variables[vref, bvref] + end +end +# affine expression +function _disaggregate_expression(model::JuMP.Model, aff::JuMP.AffExpr, bvref::JuMP.VariableRef, method::_Hull) + new_expr = JuMP.@expression(model, aff.constant*bvref) #multiply constant by binary indicator variable + for (vref, coeff) in aff.terms + if JuMP.is_binary(vref) || !haskey(method.disjunct_variables, (vref, bvref)) #keep any binary variables or nested disaggregated variables unchanged + JuMP.add_to_expression!(new_expr, coeff*vref) + else #replace other vars with disaggregated form + dvref = method.disjunct_variables[vref, bvref] + JuMP.add_to_expression!(new_expr, coeff*dvref) end - #sum disaggregated variables - aggr_con = "$(var)_$(bin_var)_aggregation" - m[Symbol(aggr_con)] = @constraint(m, var == sum_vars, base_name = aggr_con) end + return new_expr +end +# quadratic expression +# TODO review what happens when there are bilinear terms with binary variables involved since these are not being disaggregated +# (e.g., complementarity constraints; though likely irrelevant)... +function _disaggregate_expression(model::JuMP.Model, quad::JuMP.QuadExpr, bvref::JuMP.VariableRef, method::_Hull) + #get affine part + new_expr = _disaggregate_expression(model, quad.aff, bvref, method) + #get nonlinear part + ϵ = method.value + for (pair, coeff) in quad.terms + da_ref = method.disjunct_variables[pair.a, bvref] + db_ref = method.disjunct_variables[pair.b, bvref] + new_expr += coeff * da_ref * db_ref / ((1-ϵ)*bvref+ϵ) + end + return new_expr +end +# constant in NonlinearExpr +function _disaggregate_nl_expression(model::JuMP.Model, c::Number, ::JuMP.VariableRef, method::_Hull) + return c +end +# variable in NonlinearExpr +function _disaggregate_nl_expression(model::JuMP.Model, vref::JuMP.VariableRef, bvref::JuMP.VariableRef, method::_Hull) + ϵ = method.value + dvref = method.disjunct_variables[vref, bvref] + new_var = dvref / ((1-ϵ)*bvref+ϵ) + return new_var +end +# affine expression in NonlinearExpr +function _disaggregate_nl_expression(model::JuMP.Model, aff::JuMP.AffExpr, bvref::JuMP.VariableRef, method::_Hull) + new_expr = aff.constant + ϵ = method.value + for (vref, coeff) in aff.terms + if JuMP.is_binary(vref) #keep any binary variables undisaggregated + dvref = vref + else #replace other vars with disaggregated form + dvref = method.disjunct_variables[vref, bvref] + end + new_expr += coeff * dvref / ((1-ϵ)*bvref+ϵ) + end + return new_expr +end +# quadratic expression in NonlinearExpr +function _disaggregate_nl_expression(model::JuMP.Model, quad::JuMP.QuadExpr, bvref::JuMP.VariableRef, method::_Hull) + #get affine part + new_expr = _disaggregate_nl_expression(model, quad.aff, bvref, method) + #get quadratic part + ϵ = method.value + for (pair, coeff) in quad.terms + da_ref = method.disjunct_variables[pair.a, bvref] + db_ref = method.disjunct_variables[pair.b, bvref] + new_expr += coeff * da_ref * db_ref / ((1-ϵ)*bvref+ϵ)^2 + end + return new_expr +end +# nonlinear expression in NonlinearExpr +function _disaggregate_nl_expression(model::JuMP.Model, nlp::JuMP.NonlinearExpr, bvref::JuMP.VariableRef, method::_Hull) + new_args = Vector{Any}(undef, length(nlp.args)) + for (i,arg) in enumerate(nlp.args) + new_args[i] = _disaggregate_nl_expression(model, arg, bvref, method) + end + new_expr = JuMP.NonlinearExpr(nlp.head, new_args) + return new_expr end -""" - add_disaggregated_variable(m::Model, var::VariableRef, LB, UB, base_name) - -Disaggreagate a variable with lower bound `LB`, upper bound `UB`, and name `base_name`. - - add_disaggregated_variable(m::Model, var::AbstractArray{VariableRef}, LB, UB, base_name) - -Disaggregate a variable block stored in an Array or DenseAxisArray. - - add_disaggregated_variable(m::Model, var::Containers.SparseAxisArray, LB, UB, base_name) - -Disaggregate a variable block stored in a SparseAxisArray. -""" -function add_disaggregated_variable(m::Model, var::VariableRef, LB, UB, base_name) - @variable( - m, - lower_bound = min(LB,0), - upper_bound = max(UB,0), - binary = is_binary(var), - integer = is_integer(var), - base_name = base_name +################################################################################ +# HULL REFORMULATION +################################################################################ +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::JuMP.ScalarConstraint{T, S}, + bvref::JuMP.VariableRef, + method::_Hull +) where {T <: Union{JuMP.VariableRef, JuMP.AffExpr, JuMP.QuadExpr}, S <: Union{_MOI.LessThan, _MOI.GreaterThan, _MOI.EqualTo}} + new_func = _disaggregate_expression(model, con.func, bvref, method) + set_value = _set_value(con.set) + new_func -= set_value*bvref + reform_con = JuMP.build_constraint(error, new_func, S(0)) + return [reform_con] +end +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::JuMP.VectorConstraint{T, S, R}, + bvref::JuMP.VariableRef, + method::_Hull +) where {T <: Union{JuMP.VariableRef, JuMP.AffExpr, JuMP.QuadExpr}, S <: Union{_MOI.Nonpositives, _MOI.Nonnegatives, _MOI.Zeros}, R} + new_func = JuMP.@expression(model, [i=1:con.set.dimension], + _disaggregate_expression(model, con.func[i], bvref, method) ) + reform_con = JuMP.build_constraint(error, new_func, con.set) + return [reform_con] end -function add_disaggregated_variable(m::Model, var::AbstractArray{VariableRef}, LB, UB, base_name) - idxs = Iterators.product(axes(var)...) - var_i_array = [ - add_disaggregated_variable(m, var[idx...], LB[idx...], UB[idx...], "$base_name[$(join(idx,","))]") - for idx in idxs - ] - return containerize(var, var_i_array) -end -function add_disaggregated_variable(m::Model, var::Containers.SparseAxisArray, LB, UB, base_name) - idxs = keys(var.data) - var_i_dict = Dict( - idx => add_disaggregated_variable(m, var[idx], LB[idx], UB[idx], "$base_name[$(join(idx,","))]") - for idx in idxs +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::JuMP.ScalarConstraint{T, S}, + bvref::JuMP.VariableRef, + method::_Hull +) where {T <: JuMP.GenericNonlinearExpr, S <: Union{_MOI.LessThan, _MOI.GreaterThan, _MOI.EqualTo}} + con_func = _disaggregate_nl_expression(model, con.func, bvref, method) + con_func0 = JuMP.value(v -> 0.0, con.func) + if isinf(con_func0) + error("Operator `$(con.func.head)` is not defined at 0, causing the perspective function on the Hull reformulation to fail.") + end + ϵ = method.value + set_value = _set_value(con.set) + new_func = JuMP.@expression(model, ((1-ϵ)*bvref+ϵ)*con_func - ϵ*(1-bvref)*con_func0 - set_value*bvref) + reform_con = JuMP.build_constraint(error, new_func, S(0)) + return [reform_con] +end +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::JuMP.VectorConstraint{T, S, R}, + bvref::JuMP.VariableRef, + method::_Hull +) where {T <: JuMP.GenericNonlinearExpr, S <: Union{_MOI.Nonpositives, _MOI.Nonnegatives, _MOI.Zeros}, R} + con_func = JuMP.@expression(model, [i=1:con.set.dimension], + _disaggregate_nl_expression(model, con.func[i], bvref, method) + ) + con_func0 = JuMP.value.(v -> 0.0, con.func) + if any(isinf.(con_func0)) + error("At least of of the operators `$([func.head for func in con.func])` is not defined at 0, causing the perspective function on the Hull reformulation to fail.") + end + ϵ = method.value + new_func = JuMP.@expression(model, [i=1:con.set.dimension], + ((1-ϵ)*bvref+ϵ)*con_func[i] - ϵ*(1-bvref)*con_func0[i] ) - return Containers.SparseAxisArray(var_i_dict) + reform_con = JuMP.build_constraint(error, new_func, con.set) + return [reform_con] end -containerize(var::Array, arr) = arr -containerize(var::Containers.DenseAxisArray, arr) = Containers.DenseAxisArray(arr, axes(var)...) - -""" - sum_disaggregated_variables(m::Model, disj, bin_var) - -Add constraint that global variable is equal to the sum of the disaggregated copies. -""" -function sum_disaggregated_variables(m::Model, disj, bin_var) - for var in m[:gdp_variable_refs] - dis_vars = [] - for i in eachindex(disj) - var_name_i = name_disaggregated_variable(var, bin_var, i) - var_i = variable_by_name(m, var_name_i) - push!(dis_vars, var_i) - end - aggr_con = "$(var)_$(bin_var)_aggregation" - m[Symbol(aggr_con)] = @constraint(m, var == sum(dis_vars), base_name = aggr_con) +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::JuMP.ScalarConstraint{T, S}, + bvref::JuMP.VariableRef, + method::_Hull +) where {T <: Union{JuMP.VariableRef, JuMP.AffExpr, JuMP.QuadExpr}, S <: _MOI.Interval} + new_func = _disaggregate_expression(model, con.func, bvref, method) + new_func_gt = JuMP.@expression(model, new_func - con.set.lower*bvref) + new_func_lt = JuMP.@expression(model, new_func - con.set.upper*bvref) + reform_con_gt = JuMP.build_constraint(error, new_func_gt, _MOI.GreaterThan(0)) + reform_con_lt = JuMP.build_constraint(error, new_func_lt, _MOI.LessThan(0)) + return [reform_con_gt, reform_con_lt] +end +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::JuMP.ScalarConstraint{T, S}, + bvref::JuMP.VariableRef, + method::_Hull +) where {T <: JuMP.GenericNonlinearExpr, S <: _MOI.Interval} + con_func = _disaggregate_nl_expression(model, con.func, bvref, method) + con_func0 = JuMP.value(v -> 0.0, con.func) + if isinf(con_func0) + error("Operator `$(con.func.head)` is not defined at 0, causing the perspective function on the Hull reformulation to fail.") end + ϵ = method.value + new_func = JuMP.@expression(model, ((1-ϵ)*bvref+ϵ) * con_func - ϵ*(1-bvref)*con_func0) + new_func_gt = JuMP.@expression(model, new_func - con.set.lower*bvref) + new_func_lt = JuMP.@expression(model, new_func - con.set.upper*bvref) + reform_con_gt = JuMP.build_constraint(error, new_func_gt, _MOI.GreaterThan(0)) + reform_con_lt = JuMP.build_constraint(error, new_func_lt, _MOI.LessThan(0)) + return [reform_con_gt, reform_con_lt] end \ No newline at end of file diff --git a/src/indicator.jl b/src/indicator.jl new file mode 100644 index 0000000..2aabb13 --- /dev/null +++ b/src/indicator.jl @@ -0,0 +1,35 @@ +################################################################################ +# INDICATOR REFORMULATION +################################################################################ +#scalar disjunct constraint +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::JuMP.ScalarConstraint{T, S}, + bvref::JuMP.VariableRef, + method::Indicator +) where {T, S} + reform_con = JuMP.build_constraint(error, [1*bvref, con.func], _MOI.Indicator{_MOI.ACTIVATE_ON_ONE}(con.set)) + return [reform_con] +end +#vectorized disjunct constraint +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::JuMP.VectorConstraint{T, S}, + bvref::JuMP.VariableRef, + method::Indicator +) where {T, S} + set = _vec_to_scalar_set(con.set) + return [ + JuMP.build_constraint(error, [1*bvref, f], _MOI.Indicator{_MOI.ACTIVATE_ON_ONE}(set)) + for f in con.func + ] +end +#nested indicator reformulation. NOTE: the user needs to provide the appropriate linking constraint for the logical variables for this to work (e.g. w in Exactly(y[1]) to link the parent disjunct y[1] to the nested disjunction w) +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::JuMP.VectorConstraint{T, S}, + bvref::JuMP.VariableRef, + method::Indicator +) where {T, S <: _MOI.Indicator} + return [con] +end \ No newline at end of file diff --git a/src/logic.jl b/src/logic.jl index 1a9a1a9..56eb198 100644 --- a/src/logic.jl +++ b/src/logic.jl @@ -1,53 +1,31 @@ -""" - choose!(m::Model, n::Int, vars::VariableRef...; mode) - -Add constraint to select n elements from the list of variables. Options for mode -are `:at_least`, `:at_most`, `:exactly`. -""" -function choose!(m::Model, n::Int, vars::VariableRef...; mode=:exactly) - @assert length(vars) >= n "Not enough variables passed." - @assert all(is_valid.(m, vars)) "Invalid VariableRefs passed." - add_selection!(m, n, vars...; mode) -end -function choose!(m::Model, vars::VariableRef...; mode=:exactly) - @assert all(is_valid.(m, vars)) "Invalid VariableRefs passed." - n = vars[1] #first variable is the n - add_selection!(m, n, vars...; mode) -end -function add_selection!(m::Model, n, vars::VariableRef...; mode::Symbol) - display(n) - if mode == :exactly - display(@constraint(m, sum(vars) == n)) - elseif mode == :at_least - @constraint(m, sum(vars) ≥ n) - elseif mode == :at_most - @constraint(m, sum(vars) ≥ n) - end +################################################################################ +# LOGIC OPERATORS +################################################################################ +function _op_fallback(name) + error("`$name` is only supported for logical expressions") end -""" - add_proposition!(m::Model, expr::Expr) - -Convert logical proposition expression into conjunctive normal form. -""" -function add_proposition!(m::Model, expr::Expr) - expr_name = Symbol("{$expr}") #get name to register reformulated logical proposition - replace_Symvars!(expr, m; logical_proposition = true) #replace all JuMP variables with Symbolic variables - clause_list = to_cnf!(expr) - #replace symbolic variables with JuMP variables and boolean operators with their algebraic counterparts - for clause in clause_list - replace_JuMPvars!(clause, m) - replace_logic_operators!(clause) +# Define all the logical operators +const _LogicalOperatorHeads = (:(==), :(=>), :||, :&&, :!) +for (name, alt, head) in ( + (:⇔, :iff, :(==)), # \Leftrightarrow + tab + (:⟹, :implies, :(=>)) # Longrightarrow + tab + ) + # make operators + @eval begin + const $name = JuMP.NonlinearOperator((vs...) -> _op_fallback($(Meta.quot(name))), $(Meta.quot(head))) + const $alt = JuMP.NonlinearOperator((vs...) -> _op_fallback($(Meta.quot(alt))), $(Meta.quot(head))) end - #generate and simplify JuMP expressions for the lhs of the algebraic constraints - lhs = eval.(clause_list) - drop_zeros!.(lhs) - unique!(lhs) - #generate JuMP constraints for the logical proposition - if length(lhs) == 1 - m[expr_name] = @constraint(m, lhs[1] >= 1, base_name = string(expr_name)) - else - m[expr_name] = @constraint(m, [i = eachindex(lhs)], lhs[i] >= 1, base_name = string(expr_name)) +end +for (name, alt, head, func) in ( + (:∨, :logical_or, :||, :(|)), # \vee + tab + (:∧, :logical_and, :&&, :(&)), # \wedge + tab + (:¬, :logical_not, :!, :(!)) # \neg + tab + ) + # make operators + @eval begin + const $name = JuMP.NonlinearOperator($func, $(Meta.quot(head))) + const $alt = JuMP.NonlinearOperator($func, $(Meta.quot(head))) end end @@ -67,224 +45,266 @@ function to_cnf!(expr::Expr) return clause_list end -""" - check_logical_proposition(expr::Expr) - -Validate logical proposition provided. -""" -function check_logical_proposition(expr::Expr) - #NOTE: this is quick and dirty (uses Suppressor.jl). A more robust approach should traverse the expression tree to verify that only valid boolean symbols and model variables are used. - dump_str = @capture_out dump(expr, maxdepth = typemax(Int)) #caputre dump - dump_arr = split(dump_str,"\n") #split by \n - filter!(i -> occursin("1:",i), dump_arr) #filter only first args in each subexpression - @assert all(occursin.("1: Symbol ",dump_arr)) "Logical expression does not use valid Boolean symbols: ∨, ∧, ¬, ⇒, ⇔." - operator_list = map(i -> split(i, "Symbol ")[2], dump_arr) - @assert isempty(setdiff(operator_list, ["∨", "∧", "¬", "⇒", "⇔", "variables"])) "Logical expression does not use valid model variables or allowed Boolean symbols (∨, ∧, ¬, ⇒, ⇔)." +################################################################################ +# CONJUNCTIVE NORMAL FORM +################################################################################ +function _to_cnf(lexpr::_LogicalExpr) + #NOTE: some redundant constraints may be created in the process. + # For example A ∨ ¬B ∨ B is always true and is reformulated + # to the redundant constraint A ≥ 0. + lexpr |> + _eliminate_equivalence |> + _eliminate_implication |> + _move_negations_inward |> + _distribute_and_over_or |> + _flatten end -""" - eliminate_equivalence!(expr) - -Eliminate equivalence logical operator. -""" -function eliminate_equivalence!(expr) - if expr isa Expr - if expr.args[1] == :⇔ - @assert length(expr.args) == 3 "Double implication cannot have more than two clauses." - A1 = expr.args[2] - B1 = expr.args[3] - A2 = A1 isa Expr ? copy(A1) : A1 - B2 = B1 isa Expr ? copy(B1) : B1 - expr.args[1] = :∧ - expr.args[2] = :($A1 ⇒ $B1) - expr.args[3] = :($B2 ⇒ $A2) - end - for i in eachindex(expr.args) - expr.args[i] = eliminate_equivalence!(expr.args[i]) +# Eliminate the equivalence operator `⇔` by replacing it with two implications. +function _eliminate_equivalence(lvar::LogicalVariableRef) + return lvar +end +function _eliminate_equivalence(lexpr::_LogicalExpr) + if lexpr.head == :(==) + A = _eliminate_equivalence(lexpr.args[1]) + if length(lexpr.args) > 2 + nested = _LogicalExpr(:(==), Vector{Any}(lexpr.args[2:end])) + B = _eliminate_equivalence(nested) + elseif length(lexpr.args) == 2 + B = _eliminate_equivalence(lexpr.args[2]) + else + error("The equivalence logic operator must have at least two arguments.") end + new_lexpr = _LogicalExpr(:&&, Any[ + _LogicalExpr(:(=>), Any[A, B]), + _LogicalExpr(:(=>), Any[B, A]) + ]) + else + new_lexpr = _LogicalExpr(lexpr.head, Any[ + _eliminate_equivalence(arg) for arg in lexpr.args + ]) end - - return expr + return new_lexpr end -""" - eliminate_implication!(expr) - -Eliminate implication logical operator. -""" -function eliminate_implication!(expr) - if expr isa Expr - if expr.args[1] == :⇒ - @assert length(expr.args) == 3 "Implication cannot have more than two clauses." - A = expr.args[2] - expr.args[1] = :∨ - expr.args[2] = :(¬$A) - end - for i in eachindex(expr.args) - expr.args[i] = eliminate_implication!(expr.args[i]) +# Eliminate the implication operator `⟹` by replacing it with a disjunction. +function _eliminate_implication(lvar::LogicalVariableRef) + return lvar +end +function _eliminate_implication(lexpr::_LogicalExpr) + if lexpr.head == :(=>) + if length(lexpr.args) != 2 + error("The implication operator must have two clauses.") end + A = _eliminate_implication(lexpr.args[1]) + B = _eliminate_implication(lexpr.args[2]) + new_lexpr = _LogicalExpr(:||, Any[ + _LogicalExpr(:!, Any[A]), + B + ]) + else + new_lexpr = _LogicalExpr(lexpr.head, Any[ + _eliminate_implication(arg) for arg in lexpr.args + ]) end - - return expr + return new_lexpr end -""" - move_negations_inwards!(expr) - -Move negation inwards in logical proposition expression. -""" -function move_negations_inwards!(expr) - if expr isa Expr - if expr.args[1] == :¬ - @assert length(expr.args) == 2 "Negation cannot have more than one clause." - A = expr.args[2] - if A isa Expr #only modify if an expression (not a Symbolic variable) is being negated - if A.args[1] == :∨ - expr.args = negate_or!(A).args - elseif A.args[1] == :∧ - expr.args = negate_and!(A).args - elseif A.args[1] == :¬ - expr = negate_negation!(A) - end - end - end - if expr isa Expr - for i in eachindex(expr.args) - expr.args[i] = move_negations_inwards!(expr.args[i]) - end +# Move negations inward by applying De Morgan's laws. +function _move_negations_inward(lvar::LogicalVariableRef) + return lvar +end +function _move_negations_inward(lexpr::_LogicalExpr) + if lexpr.head == :! + if length(lexpr.args) != 1 + error("The negation operator can only have 1 clause.") end + new_lexpr = _negate(lexpr.args[1]) + else + new_lexpr = _LogicalExpr(lexpr.head, Any[ + _move_negations_inward(arg) for arg in lexpr.args + ]) end - - return expr + return new_lexpr end -""" - negate_or!(expr) - -Negate OR boolean operator. -""" -function negate_or!(expr) - @assert expr.args[1] == :∨ "Cannot call negate_or! unless the top operator is an OR operator." - expr.args[1] = :∧ #flip OR to AND - expr.args[2] = :(¬$(expr.args[2])) - expr.args[3] = :(¬$(expr.args[3])) - - return expr +function _negate(lvar::LogicalVariableRef) + return _LogicalExpr(:!, Any[lvar]) end - -""" - negate_and!(expr) - -Negate AND boolean operator. -""" -function negate_and!(expr) - @assert expr.args[1] == :∧ "Cannot call negate_and! unless the top operator is an AND operator." - expr.args[1] = :∨ #flip AND to OR - expr.args[2] = :(¬$(expr.args[2])) - expr.args[3] = :(¬$(expr.args[3])) - - return expr +function _negate(lexpr::_LogicalExpr) + if lexpr.head == :|| + return _negate_or(lexpr) + elseif lexpr.head == :&& + return _negate_and(lexpr) + elseif lexpr.head == :! + return _negate_negation(lexpr) + else + error("Unexpected operator `$(lexpr.head)`in logic expression.") + end end -""" - negate_negation!(expr) +function _negate_or(lexpr::_LogicalExpr) + if length(lexpr.args) < 2 + error("The OR operator must have at least two clauses.") + end + return _LogicalExpr(:&&, Any[ #flip OR to AND + _move_negations_inward(_LogicalExpr(:!, Any[arg])) + for arg in lexpr.args + ]) +end -Negate negation boolean operator. -""" -function negate_negation!(expr) - @assert expr.args[1] == :¬ "Cannot call negate_negation! unless the top operator is a Negation operator." - @assert length(expr.args) == 2 "Negation cannot have more than one clause." - expr = expr.args[2] #remove negation - - return expr +function _negate_and(lexpr::_LogicalExpr) + if length(lexpr.args) < 2 + error("The AND operator must have at least two clauses.") + end + return _LogicalExpr(:||, Any[ #flip AND to OR + _move_negations_inward(_LogicalExpr(:!, Any[arg])) + for arg in lexpr.args + ]) end -""" - distribute_and_over_or!(expr) +function _negate_negation(lexpr::_LogicalExpr) + if length(lexpr.args) != 1 + error("The negation operator can only have 1 clause.") + end + return _move_negations_inward(lexpr.args[1]) +end -Distribute AND over OR boolean operators. -""" -function distribute_and_over_or!(expr) - if expr isa Expr - if expr.args[1] == :∨ - # op = expr.args[1] - A = expr.args[2] #first clause - B = expr.args[3] #second clause - if A isa Expr && A.args[1] == :∧ #first clause has AND - C = A.args[2] #first subclause - D = A.args[3] #second subclause - expr.args[1] = :∧ #flip OR to AND in main expr - expr.args[2] = :($C ∨ $B) - expr.args[3] = :($D ∨ $B) - elseif B isa Expr && B.args[1] == :∧ #second clause has AND - C = B.args[2] #first subclause - D = B.args[3] #second subclause - expr.args[1] = :∧ #flip OR to AND in main expr - expr.args[2] = :($C ∨ $A) - expr.args[3] = :($D ∨ $A) - end +function _distribute_and_over_or(lvar::LogicalVariableRef) + return lvar +end +function _distribute_and_over_or(lexpr0::_LogicalExpr) + lexpr = _flatten(lexpr0) + if lexpr.head == :|| + if length(lexpr.args) < 2 + error("The OR operator must have at least two clauses.") end - for i in eachindex(expr.args) - expr.args[i] = distribute_and_over_or!(expr.args[i]) + loc = findfirst(arg -> arg isa _LogicalExpr ? arg.head == :&& : false, lexpr.args) + if !isnothing(loc) + new_lexpr = _LogicalExpr(:&&, Any[ + _distribute_and_over_or( + _LogicalExpr(:||, Any[arg_i, lexpr.args[setdiff(1:end,loc)]...]) + ) + for arg_i in lexpr.args[loc].args + ]) + else + new_lexpr = lexpr end + else + new_lexpr = _LogicalExpr(lexpr.head, Any[ + _distribute_and_over_or(arg) for arg in lexpr.args + ]) end - - return expr + return new_lexpr end -""" - extract_clauses(expr) - -Extract clauses from conjunctive normal form. -""" -function extract_clauses(expr) - clauses = [] - if expr isa Expr - if expr.args[1] == :∨ - push!(clauses, expr) - else - for i in 2:length(expr.args) - push!(clauses, extract_clauses(expr.args[i])...) +# Flatten netsed OR / AND operators and replace them with their n-ary form. +# For example, ∨(∨(A, B), C) is replaced with ∨(A, B, C). +function _flatten(lvar::LogicalVariableRef) + return lvar +end +function _flatten(lexpr::_LogicalExpr) + if lexpr.head in (:&&, :||) + nary_args = Set{Any}() + for arg in lexpr.args + if arg isa LogicalVariableRef + push!(nary_args, arg) + elseif _isa_literal(arg) + push!(nary_args, arg) + elseif arg.head == lexpr.head + arg_flat = _flatten(arg) + for a in arg_flat.args + push!(nary_args, _flatten(a)) + end + else + arg_flat = _flatten(arg) + push!(nary_args, arg_flat) end end + new_lexpr = _LogicalExpr(lexpr.head, collect(nary_args)) + else + new_lexpr = _LogicalExpr(lexpr.head, Any[ + _flatten(arg) for arg in lexpr.args + ]) end - - return clauses + return new_lexpr end -""" - distribute_and_over_or_recursively!(expr) +################################################################################ +# SELECTOR REFORMULATION +################################################################################ +# cardinality constraint reformulation +function _reformulate_selector(model::JuMP.Model, func, set::Union{_MOIAtLeast, _MOIAtMost, _MOIExactly}) + dict = _indicator_to_binary(model) + bvrefs = [dict[lvref] for lvref in func[2:end]] + new_set = _vec_to_scalar_set(set)(func[1].constant) + cref = JuMP.add_constraint(model, + JuMP.build_constraint(error, JuMP.@expression(model, sum(bvrefs)), new_set) + ) + push!(_reformulation_constraints(model), cref) +end +function _reformulate_selector(model::JuMP.Model, func::Vector{LogicalVariableRef}, set::Union{_MOIAtLeast, _MOIAtMost, _MOIExactly}) + dict = _indicator_to_binary(model) + bvref, bvrefs... = [dict[lvref] for lvref in func] + new_set = _vec_to_scalar_set(set)(0) + cref = JuMP.add_constraint(model, + JuMP.build_constraint(error, JuMP.@expression(model, sum(bvrefs) - bvref), new_set) + ) + push!(_reformulation_constraints(model), cref) +end -Distribute AND over OR boolean operators recursively throughout the expression tree. -""" -function distribute_and_over_or_recursively!(expr) - distribute_and_over_or!(expr) - clause_list = extract_clauses(expr) - wrong_clauses = filter(i -> occursin("∧",string(i)), clause_list) - if !isempty(wrong_clauses) - clause_list = distribute_and_over_or_recursively!(expr) +################################################################################ +# PROPOSITION REFORMULATION +################################################################################ +function _reformulate_proposition(model::JuMP.Model, lexpr::_LogicalExpr) + expr = _to_cnf(lexpr) + if expr.head == :&& + for arg in expr.args + _add_reformulated_proposition(model, arg) + end + elseif expr.head in (:||, :!) && all(_isa_literal.(expr.args)) + _add_reformulated_proposition(model, expr) + else + error("Expression $expr was not converted to proper Conjunctive Normal Form.") end +end - return unique!(clause_list) +# helper to determine if an object is a logic literal (i.e. a logic variable or its negation) +_isa_literal(v::LogicalVariableRef) = true +_isa_literal(v::_LogicalExpr) = (v.head == :!) && (length(v.args) == 1) && _isa_literal(v.args[1]) +_isa_literal(v) = false + +function _add_reformulated_proposition(model::JuMP.Model, arg::Union{LogicalVariableRef,_LogicalExpr}) + func = _reformulate_clause(model, arg) + if !isempty(func.terms) && !all(iszero.(values(func.terms))) + con = JuMP.build_constraint(error, func, _MOI.GreaterThan(1)) + cref = JuMP.add_constraint(model, con) + push!(_reformulation_constraints(model), cref) + end + return end -""" - replace_logic_operators!(expr) +function _reformulate_clause(model::JuMP.Model, lvref::LogicalVariableRef) + func = 1 * _indicator_to_binary(model)[lvref] + return func +end -Replace ∨ for +; replace ¬ for 1 - var. -""" -function replace_logic_operators!(expr) - if expr isa Expr - if expr.args[1] == :∨ - expr.args[1] = :(+) - elseif expr.args[1] == :¬ - A = expr.args[2] - expr = :(1 - $A) - end - for i in 2:length(expr.args) - expr.args[i] = replace_logic_operators!(expr.args[i]) +function _reformulate_clause(model::JuMP.Model, lexpr::_LogicalExpr) + func = zero(JuMP.AffExpr) #initialize func expression + if _isa_literal(lexpr) + JuMP.add_to_expression!(func, 1 - _reformulate_clause(model, lexpr.args[1])) + elseif lexpr.head == :|| + for literal in lexpr.args + if literal isa LogicalVariableRef + JuMP.add_to_expression!(func, _reformulate_clause(model, literal)) + elseif _isa_literal(literal) + JuMP.add_to_expression!(func, 1 - _reformulate_clause(model, literal.args[1])) + else + error("Expression was not converted to proper Conjunctive Normal Form:\n$literal is not a literal.") + end end + else + error("Expression was not converted to proper Conjunctive Normal Form:\n$lexpr.") end - - return expr + return func end \ No newline at end of file diff --git a/src/macros.jl b/src/macros.jl index c0da064..1ea2aff 100644 --- a/src/macros.jl +++ b/src/macros.jl @@ -1,145 +1,358 @@ -""" - disjunction(m, args...) +################################################################################ +# BASIC HELPERS +################################################################################ +# Macro error function +# inspired from https://github.com/jump-dev/JuMP.jl/blob/709d41b78e56efb4f2c54414266b30932010bd5a/src/macros.jl#L923-L928 +function _macro_error(macroname, args, source, str...) + error("At $(source.file):$(source.line): `@$macroname($(join(args, ", ")))`: ", + str...) +end -Add disjunction macro. -""" -macro disjunction(m, args...) - #get disjunction (pos_args) and keyword arguments - pos_args, kw_args, _ = Containers._extract_kw_args(args) - @assert length(pos_args) > 1 "At least 2 disjuncts must be included. If there is an empty disjunct, use `nothing`." - - #get kw_args and set defaults if missing - reformulation = filter(i -> i.args[1] == :reformulation, kw_args) - if !isempty(reformulation) - reformulation = reformulation[1].args[2] - reformulation_kind = eval(reformulation) - @assert reformulation_kind in [:big_m, :hull] "Invalid reformulation method passed to keyword argument `:reformulation`. Valid options are :big_m (Big-M Reformulation) and :hull (Hull Reformulation)." - if reformulation_kind == :big_m - M = filter(i -> i.args[1] == :M, kw_args) - param = !isempty(M) ? M[1].args[2] : :(missing) - elseif reformulation_kind == :hull - ϵ = filter(i -> i.args[1] == :ϵ, kw_args) - param = !isempty(ϵ) ? ϵ[1].args[2] : :(1e-6) - else - end +# Escape when needed +# taken from https://github.com/jump-dev/JuMP.jl/blob/709d41b78e56efb4f2c54414266b30932010bd5a/src/macros.jl#L895-L897 +_esc_non_constant(x::Number) = x +_esc_non_constant(x::Expr) = isexpr(x,:quote) ? x : esc(x) +_esc_non_constant(x) = esc(x) + +# Extract the name from a macro expression +# Inspired from https://github.com/jump-dev/JuMP.jl/blob/45ce630b51fb1d72f1ff8fed35a887d84ef3edf7/src/Containers/macro.jl#L8-L17 +_get_name(c::Symbol) = c +_get_name(c::Nothing) = () +_get_name(c::AbstractString) = c +function _get_name(c::Expr) + if isexpr(c, :string) + return c else - throw(UndefKeywordError(:reformulation)) + return c.args[1] end - name = filter(i -> i.args[1] == :name, kw_args) - if !isempty(name) - name = name[1].args[2] - disj_name = Symbol("disj_",eval(name)) - else - name = :(Symbol("disj",gensym())) - disj_name = eval(name) - end - - #create constraints for each disjunction - disj_names = [Symbol("$(disj_name)[$i]") for i in eachindex(pos_args)] - disjunction = [] - for (d,dname) in zip(pos_args,disj_names) - if Meta.isexpr(d, :tuple) - for (j,di) in enumerate(d.args) - i = findfirst(x -> x == d, pos_args) - dname_j = Symbol("$(disj_name)[$i,$j]") - d.args[j] = add_disjunction_constraint(m, di, dname_j) - end - push!(disjunction, d) - else - push!(disjunction, add_disjunction_constraint(m, d, dname)) +end + +# Given a base_name and idxvars, returns an expression that constructs the name +# of the object. +# Inspired from https://github.com/jump-dev/JuMP.jl/blob/709d41b78e56efb4f2c54414266b30932010bd5a/src/macros.jl#L930-L946 +function _name_call(base_name, idxvars) + if isempty(idxvars) || base_name == "" + return base_name + end + ex = Expr(:call, :string, base_name, "[") + for i in eachindex(idxvars) + # Converting the arguments to strings before concatenating is faster: + # https://github.com/JuliaLang/julia/issues/29550. + esc_idxvar = esc(idxvars[i]) + push!(ex.args, :(string($esc_idxvar))) + i < length(idxvars) && push!(ex.args, ",") + end + push!(ex.args, "]") + return ex +end + +# Process macro arugments +function _extract_kwargs(args) + arg_list = collect(args) + if !isempty(args) && isexpr(args[1], :parameters) + p = popfirst!(arg_list) + append!(arg_list, p.args) + end + extra_kwargs = filter(x -> isexpr(x, :(=)) && x.args[1] != :container && + x.args[1] != :base_name, arg_list) + container_type = :Auto + base_name = nothing + for kw in arg_list + if isexpr(kw, :(=)) && kw.args[1] == :container + container_type = kw.args[2] + elseif isexpr(kw, :(=)) && kw.args[1] == :base_name + base_name = esc(kw.args[2]) end end + pos_args = filter!(x -> !isexpr(x, :(=)), arg_list) + return pos_args, extra_kwargs, container_type, base_name +end - # #XOR constraint name - # xor_con = Symbol("XOR($disj_name)") - - #build disjunction - code = quote - @assert !in($name, keys(object_dictionary($m))) "The disjunction name $name is already registered in the model. Specify new name." - $m[$name] = @variable($m, [eachindex($disjunction)], Bin, base_name = string($name), lower_bound = 0, upper_bound = 1) - # @constraint($m, $xor_con, sum($m[$name]) == 1) - reformulate_disjunction($m, $(disjunction...); bin_var = $name, reformulation = $reformulation, param = $param) +# Add on keyword arguments to a function call expression and escape the expressions +# Adapted from https://github.com/jump-dev/JuMP.jl/blob/d9cd5fb16c2d0a7e1c06aa9941923492fc9a28b5/src/macros.jl#L11-L36 +function _add_kwargs(call, kwargs) + for kw in kwargs + push!(call.args, esc(Expr(:kw, kw.args...))) end + return +end - return esc(code) +# Add on positional args to a function call and escape +# Adapted from https://github.com/jump-dev/JuMP.jl/blob/a325eb638d9470204edb2ef548e93e59af56cc19/src/macros.jl#L57C1-L65C4 +function _add_positional_args(call, args) + kw_args = filter(arg -> isexpr(arg, :kw), call.args) + filter!(arg -> !isexpr(arg, :kw), call.args) + for arg in args + push!(call.args, esc(arg)) + end + append!(call.args, kw_args) + return end -""" - add_disjunction_constraint(m, d, dname) +# Determine if an expression contains any index variable symbols +function _has_idxvars(expr, idxvars) + expr in idxvars && return true + if expr isa Expr + return any(_has_idxvars(a, idxvars) for a in expr.args) + end + return false +end -Add disjunction constraint with name dname. -""" -function add_disjunction_constraint(m, d, dname) - if Meta.isexpr(d, :block) - d = quote - try - @constraints($m,$d) - catch e - if e isa ErrorException - @NLconstraints($m,$d) - else - throw(e) - end - end - end - elseif Meta.isexpr(d, (:call, :comparison)) - d = quote - try - @constraint($m,$dname,$d) - catch e - if e isa ErrorException - @NLconstraint($m,$d) - else - throw(e) - end - end - end +# Ensure a model argument is valid +# Inspired from https://github.com/jump-dev/JuMP.jl/blob/d9cd5fb16c2d0a7e1c06aa9941923492fc9a28b5/src/macros.jl#L38-L44 +function _valid_model(_error::Function, model, name) + is_gdp_model(model) || _error("$name is not a `GDPModel`.") +end + +# Check if a macro julia variable can be registered +# Adapted from https://github.com/jump-dev/JuMP.jl/blob/d9cd5fb16c2d0a7e1c06aa9941923492fc9a28b5/src/macros.jl#L66-L86 +function _error_if_cannot_register( + _error::Function, + model, + name::Symbol + ) + if haskey(JuMP.object_dictionary(model), name) + _error("An object of name $name is already attached to this model. If ", + "this is intended, consider using the anonymous construction ", + "syntax, e.g., `x = @macro_name(model, ...)` where the name ", + "of the object does not appear inside the macro. Alternatively, ", + "use `unregister(model, :$(name))` to first unregister the ", + "existing name from the model. Note that this will not delete ", + "the object; it will just remove the reference at ", + "`model[:$(name)]`") end - - return d + return end +# Update the creation code to register and assign the object to the name +# Inspired from https://github.com/jump-dev/JuMP.jl/blob/d9cd5fb16c2d0a7e1c06aa9941923492fc9a28b5/src/macros.jl#L88-L120 +function _macro_assign_and_return(_error, code, name, model) + return quote + _error_if_cannot_register($_error, $model, $(quot(name))) + $(esc(name)) = $code + $model[$(quot(name))] = $(esc(name)) + end +end + +# Wrap the macro generated code for better stacttraces (assumes model is escaped) +# Inspired from https://github.com/jump-dev/JuMP.jl/blob/d9cd5fb16c2d0a7e1c06aa9941923492fc9a28b5/src/macros.jl#L46-L64 +function _finalize_macro(_error, model, code, source::LineNumberNode) + return Expr(:block, source, + :(_valid_model($_error, $model, $(quot(model.args[1])))), code) +end + +################################################################################ +# DISJUNCTION MACRO +################################################################################ """ - add_disjunction!(m::Model,disj...;reformulation::Symbol,M=missing,ϵ=1e-6,name=missing) + @disjunction(model, expr, kw_args...) + +Add a disjunction described by the expression `expr`, +which must be a `Vector` of `LogicalVariableRef`s. -Add disjunction and reformulate. + @disjunction(model, ref[i=..., j=..., ...], expr, kw_args...) + +Add a group of disjunction described by the expression `expr` parameterized +by `i`, `j`, ..., which must be a `Vector` of `LogicalVariableRef`s. + +The recognized keyword arguments in `kw_args` are the following: +- `base_name`: Sets the name prefix used to generate constraint names. + It corresponds to the constraint name for scalar constraints, otherwise, + the constraint names are set to `base_name[...]` for each index `...` + of the axes `axes`. +- `container`: Specify the container type. """ -function add_disjunction!(m::Model,disj...;reformulation::Symbol,M=missing,ϵ=1e-6,name=missing) - #run checks - @assert reformulation in [:big_m, :hull] "Invalid reformulation method passed to keyword argument `:reformulation`. Valid options are :big_m (Big-M Reformulation) and :hull (Hull Reformulation)." - @assert length(disj) > 1 "At least 2 disjuncts must be included. If there is an empty disjunct, use `nothing`." - - #get kw_args and set defaults if missing - param = reformulation == :big_m ? M : ϵ - bin_var = ismissing(name) ? Symbol("disj",gensym()) : name - disj_name = ismissing(name) ? bin_var : Symbol("disj_",name) - - # #XOR constraint name - # xor_con = "XOR($disj_name)" - - #apply reformulation - # @assert !in(bin_var, keys(object_dictionary(m))) "The disjunction name $bin_var is already registered in the model. Specify new name." - if bin_var in keys(object_dictionary(m)) - @assert length(disj) <= length(m[bin_var]) "The disjunction name $bin_var is already registered in the model and its size is smaller than the number of disjunts. Specify new name." +macro disjunction(model, args...) + # prepare the model + esc_model = esc(model) + + # define error message function + _error(str...) = _macro_error(:disjunction, (model, args...), + __source__, str...) + + # parse the arguments + pos_args, extra_kwargs, container_type, base_name = _extract_kwargs(args) + + # initial processing of positional arguments + length(pos_args) >= 1 || _error("Not enough arguments, please see docs for accepted `@disjunction` syntax..") + y = first(pos_args) + extra = pos_args[2:end] + if isexpr(args[1], :block) + _error("Invalid syntax. Did you mean to use `@disjunctions`?") + end + + # TODO: three cases lead to problems when julia variables are used for DisjunctConstraint tags + # which violate the cases considered in the table further below. The three cases are + # (i) @disjunction(m, Y[1, :], tag[1]) --> gets confused for @disjunction(m, name[...], Y[1, :]) (Case 2 below) + # (ii) @disjunction(m, Y, tagref) --> gets confused for @disjunction(m, name, Y) (Case 1 below) + # (iii) @disjunction(m, Y[1, :], tagref) --> gets confused for @disjunction(m, name[...], Y) (Case 2 below) + + # Determine if a reference/container argument was given by the user + # There are 9 cases to consider: + # Case | y | type of y | y.head + # -----+------------------------------------+-----------+------------ + # 1 | name | Symbol | NA + # 2 | name[1:2] | Expr | :ref + # 3 | name[i = 1:2, j = 1:2; i + j >= 3] | Expr | :typed_vcat + # 4 | [1:2] | Expr | :vect + # 5 | [i = 1:2, j = 1:2; i + j >= 3] | Expr | :vcat + # 6 | [Y[1], Y[2]] or [Y[i] for i in I] | Expr | :vect or :comprehension + # 7 | Y | Symbol | NA + # 8 | Y[1, :] | Expr | :ref + # 9 | some very wrong syntax | Expr | anything else + + # Case 8 + if isexpr(y, :ref) && (isempty(extra) || isexpr(extra[1], :call)) + c = gensym() + x = _esc_non_constant(y) + is_anon = true + # Cases 2, 3, 5 + elseif isexpr(y, (:vcat, :ref, :typed_vcat)) + length(extra) >= 1 || _error("No disjunction expression was given, please see docs for accepted `@disjunction` syntax..") + c = y + x = _esc_non_constant(popfirst!(extra)) + is_anon = isexpr(y, :vcat) # check for Case 5 + # Cases 1, 4 + elseif (isa(y, Symbol) || isexpr(y, :vect)) && + !isempty(extra) && + (isa(extra[1], Symbol) || isexpr(extra[1], (:vect, :comprehension, :ref))) + c = y + x = _esc_non_constant(popfirst!(extra)) + is_anon = isexpr(y, :vect) # check for Case 4 + # Cases 6, 7 + elseif isa(y, Symbol) || isexpr(y, (:vect, :comprehension)) + c = gensym() + x = _esc_non_constant(y) + is_anon = true + # Case 9 + else + _error("Unrecognized syntax, please see docs for accepted `@disjunction` syntax.") + end + + # process the name + name = _get_name(c) + if isnothing(base_name) + base_name = is_anon ? "" : string(name) + end + if !isa(name, Symbol) && !is_anon + _error("Expression $name should not be used as a disjunction name. Use " * + "the \"anonymous\" syntax $name = @disjunction(model, " * + "...) instead.") + end + + # make the creation code + if isa(c, Symbol) + # easy case with single parameter + creation_code = :( _disjunction($_error, $esc_model, $x, $base_name) ) + _add_positional_args(creation_code, extra) + _add_kwargs(creation_code, extra_kwargs) + else + # we have a container of parameters + idxvars, inds = JuMP.Containers.build_ref_sets(_error, c) + if model in idxvars + _error("Index $(model) is the same symbol as the model. Use a ", + "different name for the index.") + end + name_code = _name_call(base_name, idxvars) + disjunction_call = :( _disjunction($_error, $esc_model, $x, $name_code) ) + _add_positional_args(disjunction_call, extra) + _add_kwargs(disjunction_call, extra_kwargs) + creation_code = JuMP.Containers.container_code(idxvars, inds, disjunction_call, + container_type) + end + + # finalize the macro + if is_anon + macro_code = creation_code else - #create indicator variable - m[bin_var] = @variable(m, [eachindex(disj)], Bin, base_name = string(bin_var), lower_bound = 0, upper_bound = 1) + macro_code = _macro_assign_and_return(_error, creation_code, name, + esc_model) end - # #add xor constraint on binary variable - # m[Symbol(xor_con)] = @constraint(m, sum(m[bin_var]) == 1, base_name = xor_con) - #reformulate disjunction - reformulate_disjunction(m, disj...; bin_var, reformulation, param) + return _finalize_macro(_error, esc_model, macro_code, __source__) end +# Pluralize the @disjunction macro +# Inspired from https://github.com/jump-dev/JuMP.jl/blob/9037ed9334720bd04bc372e5915cc042a4895e5b/src/macros.jl#L1489-L1547 """ - proposition(m, expr) + @disjunctions(model, args...) + +Adds groups of disjunctions at once, in the same fashion as the `@disjunction` macro. + +The model must be the first argument, and multiple disjunctions can be added on multiple +lines wrapped in a `begin ... end` block. + +The macro returns a tuple containing the disjunctions that were defined. + +## Example + +```jldoctest +julia> model = GDPModel(); + +julia> @variable(model, w); + +julia> @variable(model, x); + +julia> @variable(model, Y[1:4], LogicalVariable); -Add logical proposition macro. +julia> @constraint(model, [i=1:2], w == i, DisjunctConstraint(Y[i])); + +julia> @constraint(model, [i=3:4], x == i, DisjunctConstraint(Y[i])); + +julia> @disjunctions(model, begin + [Y[1], Y[2]] + [Y[3], Y[4]] + end); +```` """ -macro proposition(m, expr) - #get args - expr = QuoteNode(expr) - code = :(DisjunctiveProgramming.add_proposition!($m, $expr)) - - return esc(code) -end +macro disjunctions(m, x) + if !(isa(x, Expr) && x.head == :block) + error( + "Invalid syntax for @disjunctions. The second argument must be a `begin end` " * + "block. For example:\n" * + "```julia\n@disjunctions(model, begin\n # ... lines here ...\nend)\n```." + ) + end + @assert isa(x.args[1], LineNumberNode) + lastline = x.args[1] + code = Expr(:tuple) + singular = Expr(:., DisjunctiveProgramming, :($(QuoteNode(Symbol("@disjunction"))))) + for it in x.args + if isa(it, LineNumberNode) + lastline = it + elseif isexpr(it, :tuple) # line with commas + args = [] + # Keyword arguments have to appear like: + # x, (start = 10, lower_bound = 5) + # because of the precedence of "=". + for ex in it.args + if isexpr(ex, :tuple) # embedded tuple + append!(args, ex.args) + else + push!(args, ex) + end + end + macro_call = esc( + Expr( + :macrocall, + singular, + lastline, + m, + args..., + ), + ) + push!(code.args, macro_call) + else # stand-alone symbol or expression + macro_call = esc( + Expr( + :macrocall, + singular, + lastline, + m, + it, + ), + ) + push!(code.args, macro_call) + end + end + return code +end \ No newline at end of file diff --git a/src/model.jl b/src/model.jl new file mode 100644 index 0000000..288a077 --- /dev/null +++ b/src/model.jl @@ -0,0 +1,84 @@ +################################################################################ +# GDP MODEL +################################################################################ + +""" + GDPModel([optimizer]; [kwargs...])::JuMP.Model + +The core model object for building general disjunction programming models. +""" +function GDPModel(args...; kwargs...) + model = JuMP.Model(args...; kwargs...) + model.ext[:GDP] = GDPData() + JuMP.set_optimize_hook(model, _optimize_hook) + return model +end + +# Define what should happen to solve a GDPModel +# See https://github.com/jump-dev/JuMP.jl/blob/9ea1df38fd320f864ab4c93c78631d0f15939c0b/src/JuMP.jl#L718-L745 +function _optimize_hook( + model::JuMP.Model; + method::AbstractSolutionMethod + ) # can add more kwargs if wanted + if !_ready_to_optimize(model) || _solution_method(model) != method + reformulate_model(model, method) + end + return JuMP.optimize!(model; ignore_optimize_hook = true) +end + +################################################################################ +# GDP DATA +################################################################################ + +""" + gdp_data(model::JuMP.Model)::GDPData + +Extract the [`GDPData`](@ref) from a `GDPModel`. +""" +function gdp_data(model::JuMP.Model) + is_gdp_model(model) || error("Cannot access GDP data from a regular `JuMP.Model`.") + return model.ext[:GDP] +end + +""" + is_gdp_model(model::JuMP.Model)::Bool + +Return if `model` was created via the [`GDPModel`](@ref) constructor. +""" +function is_gdp_model(model::JuMP.Model) + return haskey(model.ext, :GDP) +end + +""" + disjunction_indicators(disjunction::DisjunctionRef) + +Return LogicalVariableRefs associated with a disjunction. +""" +function disjunction_indicators(disjunction::DisjunctionRef) + model, idx = disjunction.model, disjunction.index + return _disjunctions(model)[idx].constraint.indicators +end + +# Create accessors for GDP data fields +_logical_variables(model::JuMP.Model) = gdp_data(model).logical_variables +_logical_constraints(model::JuMP.Model) = gdp_data(model).logical_constraints +_disjunct_constraints(model::JuMP.Model) = gdp_data(model).disjunct_constraints +_disjunctions(model::JuMP.Model) = gdp_data(model).disjunctions +_indicator_to_binary(model::JuMP.Model) = gdp_data(model).indicator_to_binary +_indicator_to_constraints(model::JuMP.Model) = gdp_data(model).indicator_to_constraints +_reformulation_variables(model::JuMP.Model) = gdp_data(model).reformulation_variables +_reformulation_constraints(model::JuMP.Model) = gdp_data(model).reformulation_constraints +_ready_to_optimize(model::JuMP.Model) = gdp_data(model).ready_to_optimize # Determine if the model is ready to call `optimize!` without a optimize hook +_solution_method(model::JuMP.Model) = gdp_data(model).solution_method # Get the current solution method + +# Update the ready_to_optimize field +function _set_ready_to_optimize(model::JuMP.Model, is_ready::Bool) + gdp_data(model).ready_to_optimize = is_ready + return +end + +# Set the solution method +function _set_solution_method(model::JuMP.Model, method::AbstractSolutionMethod) + gdp_data(model).solution_method = method + return +end \ No newline at end of file diff --git a/src/reformulate.jl b/src/reformulate.jl index 680a6ad..fd1c3c8 100644 --- a/src/reformulate.jl +++ b/src/reformulate.jl @@ -1,82 +1,169 @@ +################################################################################ +# REFORMULATE +################################################################################ """ - reformulate_disjunction(m::Model, disj...; bin_var, reformulation, param) + reformulate_model(model::JuMP.Model, method::AbstractSolutionMethod) -Reformulate disjunction on a JuMP model. +Reformulate a `GDPModel` using the specified `method`. Prior to reformulation, +all previous reformulation variables and constraints are deleted. +""" +function reformulate_model(model::JuMP.Model, method::AbstractSolutionMethod) + #clear all previous reformulations + _clear_reformulations(model) + #reformulate + _reformulate_logical_variables(model) + _reformulate_disjunctions(model, method) + _reformulate_logical_constraints(model) + #set solution method + _set_solution_method(model, method) + _set_ready_to_optimize(model, true) +end - reformulate_disjunction(disj, bin_var, reformulation, param) +function _clear_reformulations(model::JuMP.Model) + JuMP.delete.(model, _reformulation_constraints(model)) + JuMP.delete.(model, _reformulation_variables(model)) + empty!(gdp_data(model).reformulation_constraints) + empty!(gdp_data(model).reformulation_variables) +end -Reformulate disjunction. -""" -function reformulate_disjunction(m::Model, disj...; bin_var, reformulation, param) - #check disj - disj = [check_constraint!(m, constr) for constr in disj]#check_disjunction!(m, disj) - #get original variable refs and variable names - vars = setdiff(all_variables(m), m[bin_var]) - var_names = unique(Symbol.([split("$var","[")[1] for var in vars])) - if !in(:gdp_variable_refs, keys(object_dictionary(m))) - @expression(m, gdp_variable_refs, vars) - end - if !in(:gdp_variable_names, keys(object_dictionary(m))) - @expression(m, gdp_variable_names, var_names) - end - #run reformulation - if reformulation == :hull - disaggregate_variables(m, disj, bin_var) - # sum_disaggregated_variables(m, disj, bin_var) +################################################################################ +# LOGICAL VARIABLES +################################################################################ +# create binary (indicator) variables for logic variables. +function _reformulate_logical_variables(model::JuMP.Model) + for (lv_idx, lv_data) in _logical_variables(model) + lv = lv_data.variable + lvref = LogicalVariableRef(model, lv_idx) + bvref = JuMP.@variable(model, base_name = lv_data.name, binary = true, start = lv.start_value) + if JuMP.is_fixed(lvref) + JuMP.fix(bvref, JuMP.fix_value(lvref)) + end + push!(_reformulation_variables(model), bvref) + _indicator_to_binary(model)[lvref] = bvref end - reformulate_disjunction(disj, bin_var, reformulation, param) +end - #show new constraints as a Dict - new_constraints = Dict{Symbol,Any}( - Symbol(bin_var,"[$i]") => disj[i] for i in eachindex(disj) - ) - # new_constraints[Symbol(bin_var,"_XOR")] = constraint_by_name(m, "XOR(disj_$bin_var)") - if reformulation == :hull - for var in get_constraint_variables(m,disj)#m[:gdp_variable_refs] - agg_con_name = "$(var)_$(bin_var)_aggregation" - new_constraints[Symbol(agg_con_name)] = constraint_by_name(m, agg_con_name) +################################################################################ +# DISJUNCTIONS +################################################################################ +# disjunctions +function _reformulate_all_disjunctions(model::JuMP.Model, method::AbstractReformulationMethod) + for (_, disj) in _disjunctions(model) + disj.constraint.nested && continue #only reformulate top level disjunctions + ref_cons = reformulate_disjunction(model, disj.constraint, method) + for (i, ref_con) in enumerate(ref_cons) + name = isempty(disj.name) ? "" : string(disj.name,"_$i") + cref = JuMP.add_constraint(model, ref_con, name) + push!(_reformulation_constraints(model), cref) end end - return new_constraints - - #remove model.optimize_hook ? - - # return m[bin_var] end -function reformulate_disjunction(disj, bin_var, reformulation, param) - for (i,constr) in enumerate(disj) - reformulate_constraint(constr, bin_var, reformulation, param, i) - end +function _reformulate_disjunctions(model::JuMP.Model, method::AbstractReformulationMethod) + _reformulate_all_disjunctions(model, method) +end +function _reformulate_disjunctions(model::JuMP.Model, method::BigM) + method.tighten && _query_variable_bounds(model, method) + _reformulate_all_disjunctions(model, method) +end +function _reformulate_disjunctions(model::JuMP.Model, method::Hull) + _query_variable_bounds(model, method) + _reformulate_all_disjunctions(model, method) end +# disjuncts """ - reformulate_constraint(constr::Tuple, bin_var, reformulation, param, i) + reformulate_disjunction( + model::JuMP.Model, + disj::Disjunction, + method::AbstractReformulationMethod + ) where {T<:Disjunction} -Reformulate a Tuple of constraints. +Reformulate a disjunction using the specified `method`. Current reformulation methods include +`BigM`, `Hull`, and `Indicator`. This method can be extended for other reformulation techniques. - reformulate_constraint(constr::AbstractArray{<:ConstraintRef}, bin_var, reformulation, param, i, j = missing) +The `disj` field is the `ConstraintData` object for the disjunction, stored in the +`disjunctions` field of the `GDPData` object. +""" +# generic fallback (e.g., BigM, Indicator) +function reformulate_disjunction(model::JuMP.Model, disj::Disjunction, method::AbstractReformulationMethod) + ref_cons = Vector{JuMP.AbstractConstraint}() #store reformulated constraints + for d in disj.indicators + _reformulate_disjunct(model, ref_cons, d, method) + end + return ref_cons +end +# hull specific +function reformulate_disjunction(model::JuMP.Model, disj::Disjunction, method::Hull) + ref_cons = Vector{JuMP.AbstractConstraint}() #store reformulated constraints + disj_vrefs = _get_disjunction_variables(model, disj) + hull = _Hull(method, disj_vrefs) + for d in disj.indicators #reformulate each disjunct + _disaggregate_variables(model, d, disj_vrefs, hull) #disaggregate variables for that disjunct + _reformulate_disjunct(model, ref_cons, d, hull) + end + for vref in disj_vrefs #create sum constraint for disaggregated variables + _aggregate_variable(model, ref_cons, vref, hull) + end + return ref_cons +end +function reformulate_disjunction(model::JuMP.Model, disj::Disjunction, method::_Hull) + return reformulate_disjunction(model, disj, Hull(method.value, method.variable_bounds)) +end -Reformulate a block of constraints. +# individual disjuncts +function _reformulate_disjunct(model::JuMP.Model, ref_cons::Vector{JuMP.AbstractConstraint}, lvref::LogicalVariableRef, method::AbstractReformulationMethod) + #reformulate each constraint and add to the model + bvref = _indicator_to_binary(model)[lvref] + !haskey(_indicator_to_constraints(model), lvref) && return #skip if disjunct is empty + for cref in _indicator_to_constraints(model)[lvref] + con = JuMP.constraint_object(cref) + append!(ref_cons, reformulate_disjunct_constraint(model, con, bvref, method)) + end + return +end - reformulate_constraint(constr::ConstraintRef, bin_var, reformulation, param, i, j = missing, k = missing) +_index_to_constraint(model::JuMP.Model, cidx::DisjunctConstraintIndex) = _disjunct_constraints(model)[cidx] +_index_to_constraint(model::JuMP.Model, cidx::DisjunctionIndex) = _disjunctions(model)[cidx] -Reformulate a constraint. -""" -function reformulate_constraint(constr::Tuple, bin_var, reformulation, param, i) - for (j,constr_j) in enumerate(constr) - reformulate_constraint(constr_j, bin_var, reformulation, param, i, j) +# reformulation for nested disjunction +# NOTE: name of inner disjunction (if given) is currently lost (not passed upwards) +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::Disjunction, + bvref::JuMP.VariableRef, + method::AbstractReformulationMethod +) + ref_cons = reformulate_disjunction(model, con, method) + new_ref_cons = Vector{JuMP.AbstractConstraint}() + for ref_con in ref_cons + append!(new_ref_cons, reformulate_disjunct_constraint(model, ref_con, bvref, method)) end + return new_ref_cons end -function reformulate_constraint(constr::AbstractArray{<:ConstraintRef}, bin_var, reformulation, param, i, j = missing) - for k in eachindex(constr) - reformulate_constraint(constr[k], bin_var, reformulation, param, i, j, k) - end + +# reformulation fallback for individual disjunct constraints +function reformulate_disjunct_constraint( + model::JuMP.Model, + con::JuMP.AbstractConstraint, + bvref::JuMP.VariableRef, + method::AbstractReformulationMethod +) + error("$(typeof(method)) reformulation for constraint $con is not supported yet.") end -function reformulate_constraint(constr::ConstraintRef, bin_var, reformulation, param, i, j = missing, k = missing) - if reformulation == :big_m - big_m_reformulation!(constr, bin_var, param, i, j, k) - elseif reformulation == :hull - hull_reformulation!(constr, bin_var, param, i, j, k) + +################################################################################ +# LOGICAL CONSTRAINT REFORMULATION +################################################################################ +# all logical constraints +function _reformulate_logical_constraints(model::JuMP.Model) + for (_, lcon) in _logical_constraints(model) + _reformulate_logical_constraint(model, lcon.constraint.func, lcon.constraint.set) end end -reformulate_constraint(args...) = nothing +# individual logical constraints +function _reformulate_logical_constraint(model::JuMP.Model, func, set::Union{_MOIAtMost, _MOIAtLeast, _MOIExactly}) + return _reformulate_selector(model, func, set) +end +function _reformulate_logical_constraint(model::JuMP.Model, func, set::IsTrue) + return _reformulate_proposition(model, func) +end \ No newline at end of file diff --git a/src/utils.jl b/src/utils.jl index 9642d01..e69de29 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1,163 +0,0 @@ -""" - get_indices(arr::Containers.SparseAxisArray) - -Get indices in SparseAxisArray. - - get_indices(arr) - -Get indices in Array or DenseAxisArray. -""" -get_indices(arr::Containers.SparseAxisArray) = keys(arr.data) -get_indices(arr) = Iterators.product(axes(arr)...) - -get_reform_param(param::Missing, args...; constr) = - apply_interval_arithmetic(constr) -get_reform_param(param::Number, args...; kwargs...) = param -get_reform_param(param::Union{Vector,Tuple}, i::Int, args...; kwargs...) = - get_reform_param(param[i], args...; kwargs...) -function get_reform_param(param::Dict, args...; kwargs...) - arg_list = [arg for arg in args if !ismissing(arg)] #remove mising if j or k are missing - get_reform_param(param[arg_list...]; kwargs...) -end - -""" - get_constraint_variables(m::Model, con) - -Get variables that have non-zero coefficients in the passed constraint, -constraint container, or disjunction -""" -function get_constraint_variables(m::Model, con::ConstraintRef) - return filter( - var_ref -> - !iszero(normalized_coefficient(con, var_ref)), - m[:gdp_variable_refs] - ) -end - -function get_constraint_variables(m::Model, con::Union{Containers.SparseAxisArray, Containers.DenseAxisArray, Array{<:ConstraintRef}}) - return union( - [ - get_constraint_variables(m,con[idx]) - for idx in eachindex(con) - ]... - ) -end -function get_constraint_variables(m::Model, disjunction) - return union( - [ - get_constraint_variables(m, disj) - for disj in disjunction if !isnothing(disj) - ]... - ) -end - -""" - gen_constraint_name(constr) - -Generate constraint name for a constraint to be split (Interval or EqualTo). -""" -function gen_constraint_name(constr) - constr_name = name.(constr) - if any(isempty.(constr_name)) - constr_name = gensym("constraint") - elseif !isa(constr_name, String) - c_names = union(first.(split.(constr_name,"["))) - if length(c_names) == 1 - constr_name = c_names[1] - else - constr_name = gensym("constraint") - end - end - - return Symbol("$(constr_name)_split") -end - -function replace_Symvars!(expr, model; logical_proposition = false) - #replace JuMP variables with symbolic variables - name = join(split(string(expr)," ")) - var = variable_by_name(model, name) - if !isnothing(var) - logical_proposition && @assert is_binary(var) "Only binary variables are allowed in $expr." - return Symbol(name) - end - if expr isa Expr - for i in eachindex(expr.args) - expr.args[i] = replace_Symvars!(expr.args[i], model) - end - end - - return expr -end - -function replace_JuMPvars!(expr, model) - #replace symbolic variables and any matching expressions with JuMP variables - var = variable_by_name(model, string(expr)) - !isnothing(var) && return var - if expr isa Expr #run recursion - for i in eachindex(expr.args) - expr.args[i] = replace_JuMPvars!(expr.args[i], model) - end - end - - return expr -end - -function replace_operators!(expr) - #replace operators with their symbol. NOTE: Is this still needed for the hull_reformulation! of nl constraints? (check this) - if expr isa Expr #run recursion - for i in eachindex(expr.args) - expr.args[i] = replace_operators!(expr.args[i]) - end - elseif expr isa Function #replace Function with its symbol - return Symbol(expr) - end - - return expr -end - -function replace_intevals!(expr, intervals) - #replace variables with their intervals - expr_str = replace(string(expr), ", " => ",") #remove any blank space after index commas - if expr_str in keys(intervals) #check if expression is one of the model variables in the intervals dict - return intervals[expr_str] #replace expression with interval - elseif expr isa Expr - if length(expr.args) == 1 #run recursive relation on the leaf node on expression tree - expr.args[i] = replace_intevals!(expr.args[i], intervals) - else #run recursive relation on each internal node of the expression tree, but skip the first element, which will always be the operator (this will avoid issues if the user creates a model variable called exp) - for i in 2:length(expr.args) - expr.args[i] = replace_intevals!(expr.args[i], intervals) - end - end - end - - return expr -end - -function symbolic_variable(var_ref) - var_sym = Symbol(var_ref) - return eval(:(Symbolics.@variables($var_sym)[1])) -end - -function name_disaggregated_variable(var_ref, bin_var, i) - # #get disaggregated variable reference - # if occursin("[", string(var_ref)) - # var_name_i = replace(string(var_ref), "[" => "_$bin_var$i[") - # else - # var_name_i = "$(var_ref)_$bin_var$i" - # end - var_name = name(var_ref) - var_name_i = "$(var_name)_$(bin_var)_$i" - - return var_name_i -end - -function name_split_constraint(con_name, side) - #get disaggregated variable reference - if occursin("[", string(con_name)) - con_name = replace(string(con_name), "]" => ",$side]") - else - con_name = "$(con_name)[$side]" - end - - return con_name -end diff --git a/src/variables.jl b/src/variables.jl new file mode 100644 index 0000000..a3f79a8 --- /dev/null +++ b/src/variables.jl @@ -0,0 +1,337 @@ +################################################################################ +# LOGICAL VARIABLES +################################################################################ +""" + JuMP.build_variable(_error::Function, info::JuMP.VariableInfo, + ::Type{LogicalVariable})::LogicalVariable + +Extend `JuMP.build_variable` to work with logical variables. This in +combination with `JuMP.add_variable` enables the use of +`@variable(model, [var_expr], LogicalVariable)`. +""" +function JuMP.build_variable( + _error::Function, + info::JuMP.VariableInfo, + tag::Type{LogicalVariable}; + kwargs... + ) + # check for invalid input + for (k, _) in kwargs + _error("Unsupported keyword argument `$k`.") + end + if info.has_lb || info.has_ub + _error("Logical variables cannot have bounds.") + elseif info.integer + _error("Logical variables cannot be integer valued.") + elseif info.has_fix && !isone(info.fix) && !iszero(info.fix) + _error("Invalid fix value, must be 0 or 1.") + elseif info.has_start && !isone(info.start) && !iszero(info.start) + _error("Invalid start value, must be 0 or 1.") + end + + # create the variable + fix = info.has_fix ? Bool(info.fix) : nothing + start = info.has_start ? Bool(info.start) : nothing + return LogicalVariable(fix, start) +end + +""" + JuMP.add_variable(model::JuMP.Model, v::LogicalVariable, + name::String = "")::LogicalVariableRef + +Extend `JuMP.add_variable` for [`LogicalVariable`](@ref)s. This +helps enable `@variable(model, [var_expr], LogicalVariable)`. +""" +function JuMP.add_variable( + model::JuMP.Model, + v::LogicalVariable, + name::String = "" + ) + is_gdp_model(model) || error("Can only add logical variables to `GDPModel`s.") + data = LogicalVariableData(v, name) + idx = _MOIUC.add_item(_logical_variables(model), data) + _set_ready_to_optimize(model, false) + return LogicalVariableRef(model, idx) +end + +# Base extensions +Base.copy(v::LogicalVariableRef) = v +Base.broadcastable(v::LogicalVariableRef) = Ref(v) +Base.length(v::LogicalVariableRef) = 1 +function Base.:(==)(v::LogicalVariableRef, w::LogicalVariableRef) + return v.model === w.model && v.index == w.index +end +function Base.getindex(map::JuMP.ReferenceMap, vref::LogicalVariableRef) + return LogicalVariableRef(map.model, JuMP.index(vref)) +end + +# JuMP extensions +""" + JuMP.owner_model(vref::LogicalVariableRef) + +Return the `GDP model` to which `vref` belongs. +""" +JuMP.owner_model(vref::LogicalVariableRef) = vref.model + +""" + JuMP.index(vref::LogicalVariableRef) + +Return the index of logical variable that associated with `vref`. +""" +JuMP.index(vref::LogicalVariableRef) = vref.index + +""" + JuMP.isequal_canonical(v::LogicalVariableRef, w::LogicalVariableRef) + +Return `true` if `v` and `w` refer to the same logical variable in the same +`GDP model`. +""" +JuMP.isequal_canonical(v::LogicalVariableRef, w::LogicalVariableRef) = v == w + +""" + JuMP.is_valid(model::JuMP.Model, vref::LogicalVariableRef) + +Return `true` if `vref` refers to a valid logical variable in `GDP model`. +""" +function JuMP.is_valid(model::JuMP.Model, vref::LogicalVariableRef) + return model === JuMP.owner_model(vref) +end + +""" + JuMP.name(vref::LogicalVariableRef) + +Get a logical variable's name attribute. +""" +function JuMP.name(vref::LogicalVariableRef) + data = gdp_data(JuMP.owner_model(vref)) + return data.logical_variables[JuMP.index(vref)].name +end + +""" + JuMP.set_name(vref::LogicalVariableRef, name::String) + +Set a logical variable's name attribute. +""" +function JuMP.set_name(vref::LogicalVariableRef, name::String) + model = JuMP.owner_model(vref) + data = gdp_data(model) + data.logical_variables[JuMP.index(vref)].name = name + _set_ready_to_optimize(model, false) + return +end + +""" + JuMP.start_value(vref::LogicalVariableRef) + +Return the start value of the logical variable `vref`. +""" +function JuMP.start_value(vref::LogicalVariableRef) + data = gdp_data(JuMP.owner_model(vref)) + return data.logical_variables[JuMP.index(vref)].variable.start_value +end + +""" + JuMP.set_start_value(vref::LogicalVariableRef, value::Union{Nothing, Bool}) + +Set the start value of the logical variable `vref`. + +Pass `nothing` to unset the start value. +""" +function JuMP.set_start_value( + vref::LogicalVariableRef, + value::Union{Nothing, Bool} + ) + model = JuMP.owner_model(vref) + data = gdp_data(model) + var = data.logical_variables[JuMP.index(vref)].variable + new_var = LogicalVariable(var.fix_value, value) + data.logical_variables[JuMP.index(vref)].variable = new_var + _set_ready_to_optimize(model, false) + return +end +""" + JuMP.is_fixed(vref::LogicalVariableRef) + +Return `true` if `vref` is a fixed variable. If + `true`, the fixed value can be queried with + fix_value. +""" +function JuMP.is_fixed(vref::LogicalVariableRef) + data = gdp_data(JuMP.owner_model(vref)) + return !isnothing(data.logical_variables[JuMP.index(vref)].variable.fix_value) +end + +""" + JuMP.fix_value(vref::LogicalVariableRef) + +Return the value to which a logical variable is fixed. +""" +function JuMP.fix_value(vref::LogicalVariableRef) + data = gdp_data(JuMP.owner_model(vref)) + return data.logical_variables[JuMP.index(vref)].variable.fix_value +end + +""" + JuMP.fix(vref::LogicalVariableRef, value::Bool) + +Fix a logical variable to a value. Update the fixing +constraint if one exists, otherwise create a +new one. +""" +function JuMP.fix(vref::LogicalVariableRef, value::Bool) + model = JuMP.owner_model(vref) + data = gdp_data(model) + var = data.logical_variables[JuMP.index(vref)].variable + new_var = LogicalVariable(value, var.start_value) + data.logical_variables[JuMP.index(vref)].variable = new_var + _set_ready_to_optimize(model, false) + return +end + +""" + JuMP.unfix(vref::LogicalVariableRef) + +Delete the fixed value of a logical variable. +""" +function JuMP.unfix(vref::LogicalVariableRef) + model = JuMP.owner_model(vref) + data = gdp_data(model) + var = data.logical_variables[JuMP.index(vref)].variable + new_var = LogicalVariable(nothing, var.start_value) + data.logical_variables[JuMP.index(vref)].variable = new_var + _set_ready_to_optimize(model, false) + return +end + +""" + JuMP.delete(model::JuMP.Model, vref::LogicalVariableRef) + +Delete the logical variable associated with `vref` from the `GDP model`. +""" +function JuMP.delete(model::JuMP.Model, vref::LogicalVariableRef) + @assert JuMP.is_valid(model, vref) "Variable does not belong to model." + vidx = JuMP.index(vref) + dict = _logical_variables(model) + #delete any disjunct constraints associated with the logical variables in the disjunction + if haskey(_indicator_to_constraints(model), vref) + crefs = _indicator_to_constraints(model)[vref] + JuMP.delete.(model, crefs) + delete!(_indicator_to_constraints(model), vref) + end + #delete any disjunctions that have the logical variable + for (didx, ddata) in _disjunctions(model) + if vref in ddata.constraint.indicators + setdiff!(ddata.constraint.indicators, [vref]) + JuMP.delete(model, DisjunctionRef(model, didx)) + end + end + #delete any logical constraints involving the logical variables + for (cidx, cdata) in _logical_constraints(model) + lvars = _get_constraint_variables(model, cdata.constraint) + if vref in lvars + JuMP.delete(model, LogicalConstraintRef(model, cidx)) + end + end + #delete the logical variable + delete!(dict, vidx) + delete!(_indicator_to_binary(model), vref) + #not ready to optimize + _set_ready_to_optimize(model, false) + return +end + +################################################################################ +# VARIABLE INTERROGATION +################################################################################ +function _query_variable_bounds(model::JuMP.Model, method::Union{Hull, BigM}) + for var in JuMP.all_variables(model) + method.variable_bounds[var] = _update_variable_bounds(var, method) + end +end + +function _get_disjunction_variables(model::JuMP.Model, disj::Disjunction) + vars = Set{JuMP.VariableRef}() + for lvref in disj.indicators + !haskey(_indicator_to_constraints(model), lvref) && continue #skip if disjunct is empty + for cref in _indicator_to_constraints(model)[lvref] + con = JuMP.constraint_object(cref) + _interrogate_variables(v -> push!(vars, v), con) + end + end + return vars +end + +function _get_constraint_variables(model::JuMP.Model, con::Union{JuMP.ScalarConstraint, JuMP.VectorConstraint}) + vars = Set{Union{JuMP.VariableRef, LogicalVariableRef}}() + _interrogate_variables(v -> push!(vars, v), con.func) + return vars +end + +# Constant +function _interrogate_variables(interrogator::Function, c::Number) + return +end + +# VariableRef/LogicalVariableRef +function _interrogate_variables(interrogator::Function, var::Union{JuMP.VariableRef, LogicalVariableRef}) + interrogator(var) + return +end + +# AffExpr +function _interrogate_variables(interrogator::Function, aff::JuMP.GenericAffExpr) + for (var, _) in aff.terms + interrogator(var) + end + return +end + +# QuadExpr +function _interrogate_variables(interrogator::Function, quad::JuMP.QuadExpr) + for (pair, _) in quad.terms + interrogator(pair.a) + interrogator(pair.b) + end + _interrogate_variables(interrogator, quad.aff) + return +end + +# NonlinearExpr and _LogicalExpr (T <: Union{JuMP.VariableRef, LogicalVariableRef}) +function _interrogate_variables(interrogator::Function, nlp::JuMP.GenericNonlinearExpr{T}) where {T} + for arg in nlp.args + _interrogate_variables(interrogator, arg) + end + # TODO avoid recursion. See InfiniteOpt.jl for alternate method that avoids stackoverflow errors with deeply nested expressions: + # https://github.com/infiniteopt/InfiniteOpt.jl/blob/cb6dd6ae40fe0144b1dd75da0739ea6e305d5357/src/expressions.jl#L520-L534 + return +end + +# Constraint +function _interrogate_variables(interrogator::Function, con::Union{JuMP.ScalarConstraint, JuMP.VectorConstraint}) + _interrogate_variables(interrogator, con.func) +end + +# AbstractArray +function _interrogate_variables(interrogator::Function, arr::AbstractArray) + _interrogate_variables.(interrogator, arr) + return +end + +# Set +function _interrogate_variables(interrogator::Function, set::Set) + _interrogate_variables.(interrogator, set) + return +end + +# Nested disjunction +function _interrogate_variables(interrogator::Function, disj::Disjunction) + model = JuMP.owner_model(disj.indicators[1]) + dvars = _get_disjunction_variables(model, disj) + _interrogate_variables(interrogator, dvars) + return +end + +# Fallback +function _interrogate_variables(interrogator::Function, other) + error("Cannot extract variables from object of type $(typeof(other)).") +end \ No newline at end of file diff --git a/test/aqua.jl b/test/aqua.jl new file mode 100644 index 0000000..b5191d4 --- /dev/null +++ b/test/aqua.jl @@ -0,0 +1,5 @@ +using Aqua +using DisjunctiveProgramming + +Aqua.test_all(DisjunctiveProgramming, ambiguities = false) +Aqua.test_ambiguities(DisjunctiveProgramming) \ No newline at end of file diff --git a/test/constraints/bigm.jl b/test/constraints/bigm.jl new file mode 100644 index 0000000..b1666b9 --- /dev/null +++ b/test/constraints/bigm.jl @@ -0,0 +1,329 @@ +function test_default_bigm() + method = BigM() + @test method.value == 1e9 + @test method.tighten +end + +function test_default_tighten_bigm() + method = BigM(100) + @test method.value == 100 + @test method.tighten +end + +function test_set_bigm() + method = BigM(1e6, false) + @test method.value == 1e6 + @test !method.tighten +end + +function test_get_M_1sided() + model = GDPModel() + @variable(model, x) + @variable(model, y, LogicalVariable) + @constraint(model, con, 3*x <= 1, DisjunctConstraint(y)) + cobj = constraint_object(con) + M = DP._get_M(cobj.func, cobj.set, BigM(100, false)) + @test M == 100 + @test_throws ErrorException DP._get_M(cobj.func, cobj.set, BigM(Inf, false)) +end + +function test_get_tight_M_1sided() + model = GDPModel() + @variable(model, x) + @variable(model, y, LogicalVariable) + @constraint(model, con, 3*x <= 1, DisjunctConstraint(y)) + cobj = constraint_object(con) + + method = BigM(100) + DP._query_variable_bounds(model, method) + M = DP._get_tight_M(cobj.func, cobj.set, method) + @test M == 100 + + method = BigM(Inf) + DP._query_variable_bounds(model, method) + @test_throws ErrorException DP._get_tight_M(cobj.func, cobj.set, method) + + set_upper_bound(x, 10) + method = BigM() + DP._query_variable_bounds(model, method) + M = DP._get_tight_M(cobj.func, cobj.set, method) + @test M == 29 +end + +function test_get_M_2sided() + model = GDPModel() + @variable(model, x) + @variable(model, y, LogicalVariable) + @constraint(model, con, 3*x == 1, DisjunctConstraint(y)) + cobj = constraint_object(con) + + method = BigM(100) + M = DP._get_M(cobj.func, cobj.set, method) + @test M[1] == 100 + @test M[2] == 100 + + method = BigM(Inf) + @test_throws ErrorException DP._get_M(cobj.func, cobj.set, method) +end + +function test_get_tight_M_2sided() + model = GDPModel() + @variable(model, x) + @variable(model, y, LogicalVariable) + @constraint(model, con, 3*x == 1, DisjunctConstraint(y)) + cobj = constraint_object(con) + + method = BigM(100) + DP._query_variable_bounds(model, method) + M = DP._get_tight_M(cobj.func, cobj.set, method) + @test M[1] == 100 + @test M[2] == 100 + + method = BigM(Inf) + DP._query_variable_bounds(model, method) + @test_throws ErrorException DP._get_tight_M(cobj.func, cobj.set, method) + + set_lower_bound(x, -10) + set_upper_bound(x, 10) + method = BigM() + DP._query_variable_bounds(model, method) + M = DP._get_tight_M(cobj.func, cobj.set, method) + @test M[1] == 31 + @test M[2] == 29 +end + +function test_interval_arithmetic_LessThan() + model = Model() + @variable(model, x[1:3]) + @variable(model, y, Bin) + @expression(model, func, -x[1] + 2*x[2] - 3*x[3] + 4*y + 5) + + method = BigM() + DP._query_variable_bounds(model, method) + M = DP._interval_arithmetic_LessThan(func, 0.0, method) + @test isinf(M) + + set_upper_bound.(x, 10) + method = BigM() + DP._query_variable_bounds(model, method) + M = DP._interval_arithmetic_LessThan(func, 0.0, method) + @test isinf(M) + + set_lower_bound.(x, -10) + method = BigM() + DP._query_variable_bounds(model, method) + M = DP._interval_arithmetic_LessThan(func, 0.0, method) + @test M == -(-10) + 2*10 - 3*(-10) + 5 +end + +function test_interval_arithmetic_GreaterThan() + model = Model() + @variable(model, x[1:3]) + @variable(model, y, Bin) + @expression(model, func, -x[1] + 2*x[2] - 3*x[3] + 4*y + 5) + + method = BigM() + DP._query_variable_bounds(model, method) + M = DP._interval_arithmetic_GreaterThan(func, 0.0, method) + @test isinf(M) + + set_upper_bound.(x, 10) + method = BigM() + DP._query_variable_bounds(model, method) + M = DP._interval_arithmetic_GreaterThan(func, 0.0, method) + @test isinf(M) + + set_lower_bound.(x, -10) + method = BigM() + DP._query_variable_bounds(model, method) + M = DP._interval_arithmetic_GreaterThan(func, 0.0, method) + @test -M == -(10) + 2*(-10) - 3*(10) + 5 +end + +function test_calculate_tight_M() + model = Model() + @variable(model, -1 <= x <= 1) + method = BigM() + DP._query_variable_bounds(model, method) + M = DP._calculate_tight_M(1*x, MOI.LessThan(5.0), method) + @test M == -4 + M = DP._calculate_tight_M(1*x, MOI.GreaterThan(5.0), method) + @test -M == -6 + M = DP._calculate_tight_M(1*x, MOI.Nonpositives(3), method) + @test M == 1 + M = DP._calculate_tight_M(1*x, MOI.Nonnegatives(3), method) + @test -M == -1 + M = DP._calculate_tight_M(1*x, MOI.Interval(5.0, 5.0), method) + @test -M[1] == -6 + @test M[2] == -4 + M = DP._calculate_tight_M(1*x, MOI.EqualTo(5.0), method) + @test -M[1] == -6 + @test M[2] == -4 + M = DP._calculate_tight_M(1*x, MOI.Zeros(3), method) + @test -M[1] == -1 + @test M[2] == 1 + for ex in (x^2, exp(x)), set in (MOI.LessThan(5.0), MOI.GreaterThan(5.0), MOI.Nonpositives(4), MOI.Nonnegatives(4)) + M = DP._calculate_tight_M(ex, set, method) + @test isinf(M) + end + for ex in (x^2, exp(x)), set in (MOI.Interval(5.0,5.0), MOI.EqualTo(5.0), MOI.Zeros(4)) + M = DP._calculate_tight_M(ex, set, method) + @test all(isinf.(M)) + end + @test_throws ErrorException DP._calculate_tight_M(1*x, MOI.SOS1([1.0,3.0,2.5]), method) +end + +function test_lessthan_bigm() + model = GDPModel() + @variable(model, x) + @variable(model, y, LogicalVariable) + @constraint(model, con, x <= 5, DisjunctConstraint(y)) + + DP._reformulate_logical_variables(model) + bvref = DP._indicator_to_binary(model)[y] + ref = reformulate_disjunct_constraint(model, constraint_object(con), bvref, BigM(100, false)) + @test length(ref) == 1 + @test ref[1].func == x - 100*(-bvref) + @test ref[1].set == MOI.LessThan(5.0 + 100) +end + +function test_nonpositives_bigm() + model = GDPModel() + @variable(model, x) + @variable(model, y, LogicalVariable) + @constraint(model, con, [x; x] <= [5; 5], DisjunctConstraint(y)) + + DP._reformulate_logical_variables(model) + bvref = DP._indicator_to_binary(model)[y] + ref = reformulate_disjunct_constraint(model, constraint_object(con), bvref, BigM(100, false)) + @test length(ref) == 1 + @test ref[1].func[1] == x - 5 - 100*(1-bvref) + @test ref[1].func[2] == x - 5 - 100*(1-bvref) + @test ref[1].set == MOI.Nonpositives(2) +end + +function test_greaterhan_bigm() + model = GDPModel() + @variable(model, x) + @variable(model, y, LogicalVariable) + @constraint(model, con, x >= 5, DisjunctConstraint(y)) + + DP._reformulate_logical_variables(model) + bvref = DP._indicator_to_binary(model)[y] + ref = reformulate_disjunct_constraint(model, constraint_object(con), bvref, BigM(100, false)) + @test length(ref) == 1 + @test ref[1].func == x + 100*(-bvref) + @test ref[1].set == MOI.GreaterThan(5.0 - 100) +end + +function test_nonnegatives_bigm() + model = GDPModel() + @variable(model, x) + @variable(model, y, LogicalVariable) + @constraint(model, con, [x; x] >= [5; 5], DisjunctConstraint(y)) + + DP._reformulate_logical_variables(model) + bvref = DP._indicator_to_binary(model)[y] + ref = reformulate_disjunct_constraint(model, constraint_object(con), bvref, BigM(100, false)) + @test length(ref) == 1 + @test ref[1].func[1] == x - 5 + 100*(1-bvref) + @test ref[1].func[2] == x - 5 + 100*(1-bvref) + @test ref[1].set == MOI.Nonnegatives(2) +end + +function test_greaterhan_bigm() + model = GDPModel() + @variable(model, x) + @variable(model, y, LogicalVariable) + @constraint(model, con, x == 5, DisjunctConstraint(y)) + + DP._reformulate_logical_variables(model) + bvref = DP._indicator_to_binary(model)[y] + ref = reformulate_disjunct_constraint(model, constraint_object(con), bvref, BigM(100, false)) + @test length(ref) == 2 + @test ref[1].func == x + 100*(-bvref) + @test ref[1].set == MOI.GreaterThan(5.0 - 100) + @test ref[2].func == x - 100*(-bvref) + @test ref[2].set == MOI.LessThan(5.0 + 100) +end + +function test_greaterhan_bigm() + model = GDPModel() + @variable(model, x) + @variable(model, y, LogicalVariable) + @constraint(model, con, 5 <= x <= 5, DisjunctConstraint(y)) + + DP._reformulate_logical_variables(model) + bvref = DP._indicator_to_binary(model)[y] + ref = reformulate_disjunct_constraint(model, constraint_object(con), bvref, BigM(100, false)) + @test length(ref) == 2 + @test ref[1].func == x + 100*(-bvref) + @test ref[1].set == MOI.GreaterThan(5.0 - 100) + @test ref[2].func == x - 100*(-bvref) + @test ref[2].set == MOI.LessThan(5.0 + 100) +end + +function test_zeros_bigm() + model = GDPModel() + @variable(model, x) + @variable(model, y, LogicalVariable) + @constraint(model, con, [x; x] == [5; 5], DisjunctConstraint(y)) + + DP._reformulate_logical_variables(model) + bvref = DP._indicator_to_binary(model)[y] + ref = reformulate_disjunct_constraint(model, constraint_object(con), bvref, BigM(100, false)) + @test length(ref) == 2 + @test ref[1].func[1] == x - 5 + 100*(1-bvref) + @test ref[1].func[2] == x - 5 + 100*(1-bvref) + @test ref[1].set == MOI.Nonnegatives(2) + @test ref[2].func[1] == x - 5 - 100*(1-bvref) + @test ref[2].func[2] == x - 5 - 100*(1-bvref) + @test ref[2].set == MOI.Nonpositives(2) +end + +function test_nested_bigm() + model = GDPModel() + @variable(model, -100 <= x <= 100) + @variable(model, y[1:2], LogicalVariable) + @variable(model, z[1:2], LogicalVariable) + @constraint(model, x <= 5, DisjunctConstraint(y[1])) + @constraint(model, x >= 5, DisjunctConstraint(y[2])) + @disjunction(model, inner, y, DisjunctConstraint(z[1])) + @constraint(model, x <= 10, DisjunctConstraint(z[1])) + @constraint(model, x >= 10, DisjunctConstraint(z[2])) + @disjunction(model, outer, z) + + reformulate_model(model, BigM()) + bvrefs = DP._indicator_to_binary(model) + refcons = constraint_object.(DP._reformulation_constraints(model)) + @test length(refcons) == 4 + @test refcons[1].func == x - 95*(-bvrefs[y[1]]) + @test refcons[1].set == MOI.LessThan(5.0 + 95) + @test refcons[2].func == x + 105*(-bvrefs[y[2]]) + @test refcons[2].set == MOI.GreaterThan(5.0 - 105) + @test refcons[3].func == x - 90*(-bvrefs[z[1]]) + @test refcons[3].set == MOI.LessThan(10.0 + 90) + @test refcons[4].func == x + 110*(-bvrefs[z[2]]) + @test refcons[4].set == MOI.GreaterThan(10.0 - 110) +end + +@testset "BigM Reformulation" begin + test_default_bigm() + test_default_tighten_bigm() + test_set_bigm() + test_get_M_1sided() + test_get_tight_M_1sided() + test_get_M_2sided() + test_get_tight_M_2sided() + test_interval_arithmetic_LessThan() + test_interval_arithmetic_GreaterThan() + test_calculate_tight_M() + test_lessthan_bigm() + test_nonpositives_bigm() + test_greaterhan_bigm() + test_nonnegatives_bigm() + test_greaterhan_bigm() + test_greaterhan_bigm() + test_zeros_bigm() + test_nested_bigm() +end \ No newline at end of file diff --git a/test/constraints/disjunct.jl b/test/constraints/disjunct.jl new file mode 100644 index 0000000..c840199 --- /dev/null +++ b/test/constraints/disjunct.jl @@ -0,0 +1,98 @@ +function test_disjunct_add_fail() + model = GDPModel() + @variable(model, x) + @variable(GDPModel(), y, LogicalVariable) + @test_macro_throws UndefVarError @constraint(model, x == 1, DisjunctConstraint(y)) # logical variable from another model + + @variable(model, w, LogicalVariable) + @variable(model, z, Bin) + @test_macro_throws UndefVarError @constraint(model, z == 1, DisjunctConstraint(w)) # binary variable +end + +function test_disjunct_add_success() + model = GDPModel() + @variable(model, x) + @variable(model, y, LogicalVariable) + c1 = @constraint(model, x == 1, DisjunctConstraint(y)) + @constraint(model, c2, x == 1, DisjunctConstraint(y)) + @test owner_model(c1) == model + @test is_valid(model, c1) + @test index(c1) == DisjunctConstraintIndex(1) + @test name(c1) == "" + @test name(c2) == "c2" + @test haskey(DP._disjunct_constraints(model), index(c1)) + @test haskey(DP._disjunct_constraints(model), index(c2)) + @test haskey(DP._indicator_to_constraints(model), y) + @test DP._indicator_to_constraints(model)[y] == [c1, c2] + @test DP._disjunct_constraints(model)[index(c1)] == DP._constraint_data(c1) + @test constraint_object(c1).set == MOI.EqualTo(1.0) + @test constraint_object(c1).func == constraint_object(c2).func == 1x + @test constraint_object(c1).set == constraint_object(c2).set + @test c1 == copy(c1) +end + +function test_disjunct_add_array() + model = GDPModel() + @variable(model, x) + @variable(model, y[1:2, 1:3], LogicalVariable) + @constraint(model, con[i=1:2, j=1:3], x == 1, DisjunctConstraint(y[i,j])) + @test con isa Matrix{DisjunctConstraintRef} + @test length(con) == 6 +end + +function test_disjunct_add_dense_axis() + model = GDPModel() + @variable(model, x) + I = ["a", "b", "c"] + J = [1, 2] + @variable(model, y[I, J], LogicalVariable) + @constraint(model, con[i=I, j=J], x == 1, DisjunctConstraint(y[i,j])) + + @test con isa Containers.DenseAxisArray + @test con.axes[1] == ["a","b","c"] + @test con.axes[2] == [1,2] + @test con.data isa Matrix{DisjunctConstraintRef} +end + +function test_disjunct_add_sparse_axis() + model = GDPModel() + @variable(model, x) + @variable(model, y[1:3, 1:3], LogicalVariable) + @constraint(model, con[i=1:3, j=1:3; j > i], x==i+j, DisjunctConstraint(y[i,j])) + + @test con isa Containers.SparseAxisArray + @test length(con) == 3 + @test con.names == (:i, :j) + @test Set(keys(con.data)) == Set([(1,2),(1,3),(2,3)]) +end + +function test_disjunct_set_name() + model = GDPModel() + @variable(model, x) + @variable(model, y, LogicalVariable) + c1 = @constraint(model, x == 1, DisjunctConstraint(y)) + set_name(c1, "new name") + @test name(c1) == "new name" +end + +function test_disjunct_delete() + model = GDPModel() + @variable(model, x) + @variable(model, y, LogicalVariable) + @constraint(model, c1, x == 1, DisjunctConstraint(y)) + + @test_throws AssertionError delete(GDPModel(), c1) + delete(model, c1) + @test !haskey(gdp_data(model).disjunct_constraints, index(c1)) + @test !DP._ready_to_optimize(model) +end + +@testset "Disjunct Constraints" begin + test_disjunct_add_fail() + test_disjunct_add_success() + test_disjunct_add_array() + test_disjunct_add_dense_axis() + test_disjunct_add_sparse_axis() + test_disjunct_set_name() + test_disjunct_delete() +end \ No newline at end of file diff --git a/test/constraints/hull.jl b/test/constraints/hull.jl new file mode 100644 index 0000000..a6be5c1 --- /dev/null +++ b/test/constraints/hull.jl @@ -0,0 +1,538 @@ +function test_default_hull() + method = Hull() + @test method.value == 1e-6 +end + +function test_set_hull() + method = Hull(0.001) + @test method.value == 0.001 +end + +function test_query_variable_bounds() + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, -100 <= y <= -10) + method = Hull() + DP._query_variable_bounds(model, method) + @test haskey(method.variable_bounds, x) + @test haskey(method.variable_bounds, y) + @test method.variable_bounds[x] == (0, 100) + @test method.variable_bounds[y] == (-100, 0) +end + +function test_query_variable_bounds_error1() + model = GDPModel() + @variable(model, x <= 100) + method = Hull() + @test_throws ErrorException DP._query_variable_bounds(model, method) +end + +function test_query_variable_bounds_error2() + model = GDPModel() + @variable(model, -100 <= x) + method = Hull() + @test_throws ErrorException DP._query_variable_bounds(model, method) +end + +function test_disaggregate_variables() + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, y, Bin) + @variable(model, z, LogicalVariable) + vrefs = Set([x,y]) + DP._reformulate_logical_variables(model) + method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.))), vrefs) + DP._disaggregate_variables(model, z, vrefs, method) + + refvars = DP._reformulation_variables(model) + @test length(refvars) == 2 + zbin = variable_by_name(model, "z") + @test zbin in refvars + x_z = variable_by_name(model, "x_z") + @test x_z in refvars + @test has_lower_bound(x_z) && lower_bound(x_z) == 0 + @test has_upper_bound(x_z) && upper_bound(x_z) == 100 + @test name(x_z) == "x_z" + x_z_lb = constraint_by_name(model, "x_z_lower_bound") |> constraint_object + @test x_z_lb.func == -x_z + @test x_z_lb.set == MOI.LessThan(0.) + x_z_ub = constraint_by_name(model, "x_z_upper_bound") |> constraint_object + @test x_z_ub.func == -100zbin + x_z + @test x_z_ub.set == MOI.LessThan(0.) +end + +function test_aggregate_variable() + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + vrefs = Set([x]) + DP._reformulate_logical_variables(model) + method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.))), vrefs) + DP._disaggregate_variables(model, z, vrefs, method) + refcons = Vector{JuMP.AbstractConstraint}() + DP._aggregate_variable(model, refcons, x, method) + @test length(refcons) == 1 + @test refcons[1].func == -x + sum(method.disjunction_variables[x]) + @test refcons[1].set == MOI.EqualTo(0.) +end + +function test_disaggregate_expression_affine() + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + DP._reformulate_logical_variables(model) + bvrefs = DP._indicator_to_binary(model) + + vrefs = Set([x]) + method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.))), vrefs) + DP._disaggregate_variables(model, z, vrefs, method) + + refexpr = DP._disaggregate_expression(model, 2x + 1, bvrefs[z], method) + x_z = variable_by_name(model, "x_z") + zbin = variable_by_name(model, "z") + @test refexpr == 2x_z + 1zbin +end + +function test_disaggregate_expression_quadratic() + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + DP._reformulate_logical_variables(model) + bvrefs = DP._indicator_to_binary(model) + + vrefs = Set([x]) + method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.))), vrefs) + DP._disaggregate_variables(model, z, vrefs, method) + + refexpr = DP._disaggregate_expression(model, 2x^2 + 1, bvrefs[z], method) + x_z = variable_by_name(model, "x_z") + zbin = variable_by_name(model, "z") + ϵ = method.value + @test refexpr.head == :+ + @test 1zbin in refexpr.args + arg2 = setdiff(refexpr.args, [1zbin])[1] + @test arg2.head == :/ + @test 2x_z^2 in arg2.args + @test (1-ϵ)*zbin+ϵ in arg2.args +end + +function test_disaggregate_nl_expression_c() + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + DP._reformulate_logical_variables(model) + bvrefs = DP._indicator_to_binary(model) + + vrefs = Set([x]) + method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.))), vrefs) + DP._disaggregate_variables(model, z, vrefs, method) + + refexpr = DP._disaggregate_nl_expression(model, 1, bvrefs[z], method) + @test refexpr == 1 +end + +function test_disaggregate_nl_expression_var() + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + DP._reformulate_logical_variables(model) + bvrefs = DP._indicator_to_binary(model) + + vrefs = Set([x]) + method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.))), vrefs) + DP._disaggregate_variables(model, z, vrefs, method) + + refexpr = DP._disaggregate_nl_expression(model, x, bvrefs[z], method) + x_z = variable_by_name(model, "x_z") + zbin = variable_by_name(model, "z") + ϵ = method.value + @test refexpr.head == :/ + @test x_z in refexpr.args + @test (1-ϵ)*zbin+ϵ in refexpr.args +end + +function test_disaggregate_nl_expression_aff() + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + DP._reformulate_logical_variables(model) + bvrefs = DP._indicator_to_binary(model) + + vrefs = Set([x]) + method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.))), vrefs) + DP._disaggregate_variables(model, z, vrefs, method) + + refexpr = DP._disaggregate_nl_expression(model, 2x + 1, bvrefs[z], method) + x_z = variable_by_name(model, "x_z") + zbin = variable_by_name(model, "z") + ϵ = method.value + @test refexpr.head == :+ + @test 1 in refexpr.args + arg2 = setdiff(refexpr.args, [1])[1] + @test arg2.head == :/ + @test 2x_z in arg2.args + @test (1-ϵ)*zbin+ϵ in arg2.args +end + +function test_disaggregate_nl_expression_quad() + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + DP._reformulate_logical_variables(model) + bvrefs = DP._indicator_to_binary(model) + + vrefs = Set([x]) + method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.))), vrefs) + DP._disaggregate_variables(model, z, vrefs, method) + + refexpr = DP._disaggregate_nl_expression(model, 2x^2 + 1, bvrefs[z], method) + x_z = variable_by_name(model, "x_z") + zbin = variable_by_name(model, "z") + ϵ = method.value + @test refexpr.head == :+ + @test 1 in refexpr.args + arg2 = setdiff(refexpr.args, [1])[1] + @test arg2.head == :/ + @test 2x_z^2 in arg2.args + @test ((1-ϵ)*zbin+ϵ)^2 in arg2.args +end + +function test_disaggregate_nl_expession() + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + DP._reformulate_logical_variables(model) + bvrefs = DP._indicator_to_binary(model) + + vrefs = Set([x]) + method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.))), vrefs) + DP._disaggregate_variables(model, z, vrefs, method) + + refexpr = DP._disaggregate_nl_expression(model, 2x^3 + 1, bvrefs[z], method) + x_z = variable_by_name(model, "x_z") + zbin = variable_by_name(model, "z") + ϵ = method.value + @test refexpr.head == :+ + @test 1 in refexpr.args + arg2 = setdiff(refexpr.args, [1zbin])[1] + @test arg2.head == :* + @test 2 in arg2.args + arg3 = setdiff(arg2.args, [2])[1] + @test arg3.head == :^ + @test arg3.args[2] == 3 + @test arg3.args[1].head == :/ + @test x_z in arg3.args[1].args + @test (1-ϵ)*zbin+ϵ in arg3.args[1].args +end +#less than, greater than, equalto +function test_scalar_var_hull_1sided(moiset) + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + @constraint(model, con, x in moiset(5), DisjunctConstraint(z)) + DP._reformulate_logical_variables(model) + zbin = variable_by_name(model, "z") + method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.))), Set([x])) + DP._disaggregate_variables(model, z, Set([x]), method) + x_z = variable_by_name(model, "x_z") + ref = reformulate_disjunct_constraint(model, constraint_object(con), zbin, method) + @test length(ref) == 1 + @test ref[1].func == x_z - 5*zbin + @test ref[1].set isa moiset + @test DP._set_value(ref[1].set) == 0 +end +#less than, greater than, equalto +function test_scalar_affine_hull_1sided(moiset) + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + @constraint(model, con, 1x in moiset(5), DisjunctConstraint(z)) + DP._reformulate_logical_variables(model) + zbin = variable_by_name(model, "z") + method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.))), Set([x])) + DP._disaggregate_variables(model, z, Set([x]), method) + x_z = variable_by_name(model, "x_z") + ref = reformulate_disjunct_constraint(model, constraint_object(con), zbin, method) + @test length(ref) == 1 + @test ref[1].func == x_z - 5*zbin + @test ref[1].set isa moiset + @test DP._set_value(ref[1].set) == 0 +end +#nonpositives, nonnegatives, zeros +function test_vector_var_hull_1sided(moiset) + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + @constraint(model, con, [x; x] in moiset(2), DisjunctConstraint(z)) + DP._reformulate_logical_variables(model) + zbin = variable_by_name(model, "z") + method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.))), Set([x])) + DP._disaggregate_variables(model, z, Set([x]), method) + x_z = variable_by_name(model, "x_z") + ref = reformulate_disjunct_constraint(model, constraint_object(con), zbin, method) + @test length(ref) == 1 + @test ref[1].func == [x_z; x_z] + @test ref[1].set == moiset(2) +end +#nonpositives, nonnegatives, zeros +function test_vector_affine_hull_1sided(moiset) + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + @constraint(model, con, [x - 5; x - 5] in moiset(2), DisjunctConstraint(z)) + DP._reformulate_logical_variables(model) + zbin = variable_by_name(model, "z") + method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.))), Set([x])) + DP._disaggregate_variables(model, z, Set([x]), method) + x_z = variable_by_name(model, "x_z") + ref = reformulate_disjunct_constraint(model, constraint_object(con), zbin, method) + @test length(ref) == 1 + @test ref[1].func == [x_z - 5*zbin; x_z - 5*zbin] + @test ref[1].set == moiset(2) +end +#less than, greater than, equalto +function test_scalar_quadratic_hull_1sided(moiset) + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + @constraint(model, con, x^2 in moiset(5), DisjunctConstraint(z)) + DP._reformulate_logical_variables(model) + zbin = variable_by_name(model, "z") + ϵ = 1e-3 + method = DP._Hull(Hull(ϵ, Dict(x => (0., 100.))), Set([x])) + DP._disaggregate_variables(model, z, Set([x]), method) + x_z = variable_by_name(model, "x_z") + ref = reformulate_disjunct_constraint(model, constraint_object(con), zbin, method) + @test length(ref) == 1 + @test ref[1].func.head == :- + @test 5zbin in ref[1].func.args + arg2 = setdiff(ref[1].func.args, [5zbin])[1] + @test 0*zbin in arg2.args + arg3 = setdiff(arg2.args, [0*zbin])[1] + @test arg3.head == :/ + @test x_z^2 in arg3.args + @test (1-ϵ)*zbin+ϵ in arg3.args + @test ref[1].set isa moiset + @test DP._set_value(ref[1].set) == 0 +end +#nonpositives, nonnegatives, zeros +function test_vector_quadratic_hull_1sided(moiset) + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + @constraint(model, con, [x^2 - 5; x^2 - 5] in moiset(2), DisjunctConstraint(z)) + DP._reformulate_logical_variables(model) + zbin = variable_by_name(model, "z") + ϵ = 1e-3 + method = DP._Hull(Hull(ϵ, Dict(x => (0., 100.))), Set([x])) + DP._disaggregate_variables(model, z, Set([x]), method) + x_z = variable_by_name(model, "x_z") + ref = reformulate_disjunct_constraint(model, constraint_object(con), zbin, method) + @test length(ref) == 1 + @test length(ref[1].func) == 2 + for i in 1:2 + @test ref[1].func[i].head == :+ + @test -5zbin in ref[1].func[i].args + arg2 = setdiff(ref[1].func[i].args, [-5zbin])[1] + @test arg2.head == :/ + @test x_z^2 in arg2.args + @test (1-ϵ)*zbin+ϵ in arg2.args + end + @test ref[1].set == moiset(2) +end +#less than, greater than, equalto +function test_scalar_nonlinear_hull_1sided(moiset) + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + @constraint(model, con, x^3 in moiset(5), DisjunctConstraint(z)) + DP._reformulate_logical_variables(model) + zbin = variable_by_name(model, "z") + ϵ = 1e-3 + method = DP._Hull(Hull(ϵ, Dict(x => (0., 100.))), Set([x])) + DP._disaggregate_variables(model, z, Set([x]), method) + x_z = variable_by_name(model, "x_z") + ref = reformulate_disjunct_constraint(model, constraint_object(con), zbin, method) + @test length(ref) == 1 + @test ref[1].func.head == :- + @test 5zbin in ref[1].func.args + arg2 = setdiff(ref[1].func.args, [5zbin])[1] + @test 0*zbin in arg2.args + arg3 = setdiff(arg2.args, [0*zbin])[1] + @test arg3.head == :* + @test (1-ϵ)*zbin+ϵ in arg3.args + arg4 = setdiff(arg3.args, [(1-ϵ)*zbin+ϵ])[1] + @test arg4.head == :^ + @test arg4.args[2] == 3 + @test arg4.args[1].head == :/ + @test x_z in arg4.args[1].args + @test (1-ϵ)*zbin+ϵ in arg4.args[1].args + @test ref[1].set isa moiset + @test DP._set_value(ref[1].set) == 0 +end +#nonpositives, nonnegatives, zeros +function test_vector_nonlinear_hull_1sided(moiset) + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + @constraint(model, con, [x^3 - 5; x^3 - 5] in moiset(2), DisjunctConstraint(z)) + DP._reformulate_logical_variables(model) + zbin = variable_by_name(model, "z") + ϵ = 1e-3 + method = DP._Hull(Hull(ϵ, Dict(x => (0., 100.))), Set([x])) + DP._disaggregate_variables(model, z, Set([x]), method) + x_z = variable_by_name(model, "x_z") + ref = reformulate_disjunct_constraint(model, constraint_object(con), zbin, method) + @test length(ref) == 1 + @test length(ref[1].func) == 2 + for i in 1:2 + @test ref[1].func[i].head == :- + @test -5*ϵ*(1-zbin) in ref[1].func[i].args + arg2 = setdiff(ref[1].func[i].args, [-5*ϵ*(1-zbin)])[1] + @test arg2.head == :* + @test (1-ϵ)*zbin+ϵ in arg2.args + arg3 = setdiff(arg2.args, [(1-ϵ)*zbin+ϵ])[1] + @test arg3.head == :- + @test 5 in arg3.args + arg4 = setdiff(arg3.args, [5])[1] + @test arg4.head == :^ + @test arg4.args[2] == 3 + @test arg4.args[1].head == :/ + @test x_z in arg4.args[1].args + @test (1-ϵ)*zbin+ϵ in arg4.args[1].args + end + @test ref[1].set == moiset(2) +end +#interval +function test_scalar_var_hull_2sided() + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + @constraint(model, con, x in MOI.Interval(5,5), DisjunctConstraint(z)) + DP._reformulate_logical_variables(model) + zbin = variable_by_name(model, "z") + ϵ = 1e-3 + method = DP._Hull(Hull(ϵ, Dict(x => (0., 100.))), Set([x])) + DP._disaggregate_variables(model, z, Set([x]), method) + x_z = variable_by_name(model, "x_z") + ref = reformulate_disjunct_constraint(model, constraint_object(con), zbin, method) + @test length(ref) == 2 + sets = (MOI.GreaterThan, MOI.LessThan) + for i in 1:2 + @test ref[i].func == x_z - 5*zbin + @test ref[i].set isa sets[i] + @test DP._set_value(ref[1].set) == 0 + end +end +function test_scalar_affine_hull_2sided() + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + @constraint(model, con, 5 <= x <= 5, DisjunctConstraint(z)) + DP._reformulate_logical_variables(model) + zbin = variable_by_name(model, "z") + ϵ = 1e-3 + method = DP._Hull(Hull(ϵ, Dict(x => (0., 100.))), Set([x])) + DP._disaggregate_variables(model, z, Set([x]), method) + x_z = variable_by_name(model, "x_z") + ref = reformulate_disjunct_constraint(model, constraint_object(con), zbin, method) + @test length(ref) == 2 + sets = (MOI.GreaterThan, MOI.LessThan) + for i in 1:2 + @test ref[i].func == x_z - 5*zbin + @test ref[i].set isa sets[i] + @test DP._set_value(ref[1].set) == 0 + end +end +function test_scalar_quadratic_hull_2sided() + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + @constraint(model, con, 5 <= x^2 <= 5, DisjunctConstraint(z)) + DP._reformulate_logical_variables(model) + zbin = variable_by_name(model, "z") + ϵ = 1e-3 + method = DP._Hull(Hull(ϵ, Dict(x => (0., 100.))), Set([x])) + DP._disaggregate_variables(model, z, Set([x]), method) + x_z = variable_by_name(model, "x_z") + ref = reformulate_disjunct_constraint(model, constraint_object(con), zbin, method) + @test length(ref) == 2 + sets = (MOI.GreaterThan, MOI.LessThan) + for i in 1:2 + @test ref[i].func.head == :- + @test 5zbin in ref[i].func.args + arg2 = setdiff(ref[i].func.args, [5zbin])[1] + @test 0*zbin in arg2.args + arg3 = setdiff(arg2.args, [0*zbin])[1] + @test arg3.head == :/ + @test x_z^2 in arg3.args + @test (1-ϵ)*zbin+ϵ in arg3.args + @test ref[i].set isa sets[i] + @test DP._set_value(ref[i].set) == 0 + end +end +function test_scalar_nonlinear_hull_2sided() + model = GDPModel() + @variable(model, 10 <= x <= 100) + @variable(model, z, LogicalVariable) + @constraint(model, con, 5 <= x^3 <= 5, DisjunctConstraint(z)) + DP._reformulate_logical_variables(model) + zbin = variable_by_name(model, "z") + ϵ = 1e-3 + method = DP._Hull(Hull(ϵ, Dict(x => (0., 100.))), Set([x])) + DP._disaggregate_variables(model, z, Set([x]), method) + x_z = variable_by_name(model, "x_z") + ref = reformulate_disjunct_constraint(model, constraint_object(con), zbin, method) + @test length(ref) == 2 + sets = (MOI.GreaterThan, MOI.LessThan) + for i in 1:2 + @test ref[i].func.head == :- + @test 5zbin in ref[i].func.args + arg2 = setdiff(ref[i].func.args, [5zbin])[1] + @test 0*zbin in arg2.args + arg3 = setdiff(arg2.args, [0*zbin])[1] + @test arg3.head == :* + @test (1-ϵ)*zbin+ϵ in arg3.args + arg4 = setdiff(arg3.args, [(1-ϵ)*zbin+ϵ])[1] + @test arg4.head == :^ + @test arg4.args[2] == 3 + @test arg4.args[1].head == :/ + @test x_z in arg4.args[1].args + @test (1-ϵ)*zbin+ϵ in arg4.args[1].args + @test ref[i].set isa sets[i] + @test DP._set_value(ref[i].set) == 0 + end +end + +@testset "Hull Reformulation" begin + test_default_hull() + test_set_hull() + test_query_variable_bounds() + test_query_variable_bounds_error1() + test_query_variable_bounds_error2() + test_disaggregate_variables() + test_aggregate_variable() + test_disaggregate_expression_affine() + test_disaggregate_expression_quadratic() + test_disaggregate_nl_expression_c() + test_disaggregate_nl_expression_var() + test_disaggregate_nl_expression_aff() + test_disaggregate_nl_expression_quad() + test_disaggregate_nl_expession() + for s in (MOI.LessThan, MOI.GreaterThan, MOI.EqualTo) + test_scalar_var_hull_1sided(s) + test_scalar_affine_hull_1sided(s) + test_scalar_quadratic_hull_1sided(s) + test_scalar_nonlinear_hull_1sided(s) + end + for s in (MOI.Nonpositives, MOI.Nonnegatives, MOI.Zeros) + test_vector_var_hull_1sided(s) + test_vector_affine_hull_1sided(s) + test_vector_quadratic_hull_1sided(s) + test_vector_nonlinear_hull_1sided(s) + end + test_scalar_var_hull_2sided() + test_scalar_affine_hull_2sided() + test_scalar_quadratic_hull_2sided() + test_scalar_nonlinear_hull_2sided() +end \ No newline at end of file diff --git a/test/constraints/indicator.jl b/test/constraints/indicator.jl new file mode 100644 index 0000000..f4f7c0a --- /dev/null +++ b/test/constraints/indicator.jl @@ -0,0 +1,119 @@ +function test_indicator_scalar_constraints() + model = GDPModel() + @variable(model, x) + @variable(model, y[1:2], LogicalVariable) + @constraint(model, x == 5, DisjunctConstraint(y[1])) + @constraint(model, x <= 5, DisjunctConstraint(y[1])) + @constraint(model, x >= 5, DisjunctConstraint(y[1])) + @constraint(model, x == 10, DisjunctConstraint(y[2])) + @constraint(model, x <= 10, DisjunctConstraint(y[2])) + @constraint(model, x >= 10, DisjunctConstraint(y[2])) + @disjunction(model, y) + reformulate_model(model, Indicator()) + + ref_cons = DP._reformulation_constraints(model) + ref_cons_obj = constraint_object.(ref_cons) + @test length(ref_cons) == 6 + @test all(is_valid.(model, ref_cons)) + @test all(isa.(ref_cons_obj, VectorConstraint)) + @test all([cobj.set isa MOI.Indicator for cobj in ref_cons_obj]) +end + +function test_indicator_vector_constraints() + model = GDPModel() + A = [1 0; 0 1] + @variable(model, x) + @variable(model, y[1:2], LogicalVariable) + @constraint(model, A*[x,x] == [5,5], DisjunctConstraint(y[1])) + @constraint(model, A*[x,x] == [10,10], DisjunctConstraint(y[2])) + @disjunction(model, y) + reformulate_model(model, Indicator()) + + ref_cons = DP._reformulation_constraints(model) + ref_cons_obj = constraint_object.(ref_cons) + @test length(ref_cons) == 4 + @test all(is_valid.(model, ref_cons)) + @test all(isa.(ref_cons_obj, VectorConstraint)) + @test all([cobj.set isa MOI.Indicator for cobj in ref_cons_obj]) +end + +function test_indicator_array() + model = GDPModel() + @variable(model, x) + @variable(model, y[1:2], LogicalVariable) + @constraint(model, [1:3, 1:2], x <= 6, DisjunctConstraint(y[1])) + @constraint(model, [1:3, 1:2], x >= 6, DisjunctConstraint(y[2])) + @disjunction(model, y) + reformulate_model(model, Indicator()) + + ref_cons = DP._reformulation_constraints(model) + ref_cons_obj = constraint_object.(ref_cons) + @test length(ref_cons) == 12 + @test all(is_valid.(model, ref_cons)) + @test all(isa.(ref_cons_obj, VectorConstraint)) + @test all([cobj.set isa MOI.Indicator for cobj in ref_cons_obj]) +end + +function test_indicator_dense_axis() + model = GDPModel() + @variable(model, x) + @variable(model, y[1:2], LogicalVariable) + @constraint(model, [["a","b","c"],[1,2]], x <= 7, DisjunctConstraint(y[1])) + @constraint(model, [["a","b","c"],[1,2]], x >= 7, DisjunctConstraint(y[2])) + @disjunction(model, y) + reformulate_model(model, Indicator()) + + ref_cons = DP._reformulation_constraints(model) + ref_cons_obj = constraint_object.(ref_cons) + @test length(ref_cons) == 12 + @test all(is_valid.(model, ref_cons)) + @test all(isa.(ref_cons_obj, VectorConstraint)) + @test all([cobj.set isa MOI.Indicator for cobj in ref_cons_obj]) +end + +function test_indicator_sparse_axis() + model = GDPModel() + @variable(model, x) + @variable(model, y[1:2], LogicalVariable) + @constraint(model, [i = 1:3, j = 1:3; j > i], x <= 7, DisjunctConstraint(y[1])) + @constraint(model, [i = 1:3, j = 1:3; j > i], x >= 7, DisjunctConstraint(y[2])) + @disjunction(model, y) + reformulate_model(model, Indicator()) + + ref_cons = DP._reformulation_constraints(model) + ref_cons_obj = constraint_object.(ref_cons) + @test length(ref_cons) == 6 + @test all(is_valid.(model, ref_cons)) + @test all(isa.(ref_cons_obj, VectorConstraint)) + @test all([cobj.set isa MOI.Indicator for cobj in ref_cons_obj]) +end + +function test_indicator_nested() + model = GDPModel() + @variable(model, x) + @variable(model, y[1:2], LogicalVariable) + @variable(model, z[1:2], LogicalVariable) + @constraint(model, x <= 5, DisjunctConstraint(y[1])) + @constraint(model, x >= 5, DisjunctConstraint(y[2])) + @disjunction(model, y, DisjunctConstraint(z[1])) + @constraint(model, x <= 10, DisjunctConstraint(z[1])) + @constraint(model, x >= 10, DisjunctConstraint(z[2])) + @disjunction(model, z) + reformulate_model(model, Indicator()) + + ref_cons = DP._reformulation_constraints(model) + ref_cons_obj = constraint_object.(ref_cons) + @test length(ref_cons) == 4 + @test all(is_valid.(model, ref_cons)) + @test all(isa.(ref_cons_obj, VectorConstraint)) + @test all([cobj.set isa MOI.Indicator for cobj in ref_cons_obj]) +end + +@testset "Indicator" begin + test_indicator_scalar_constraints() + test_indicator_vector_constraints() + test_indicator_array() + test_indicator_dense_axis() + test_indicator_sparse_axis() + test_indicator_nested() +end \ No newline at end of file diff --git a/test/constraints/proposition.jl b/test/constraints/proposition.jl new file mode 100644 index 0000000..75cfb46 --- /dev/null +++ b/test/constraints/proposition.jl @@ -0,0 +1,531 @@ +function test_proposition_add_fail() + m = GDPModel() + @variable(m, y[1:3], LogicalVariable) + @test_throws ErrorException @constraint(Model(), logical_or(y...) in IsTrue()) + @test_throws ErrorException @constraint(m, logical_or(y...) == 2) + @test_throws ErrorException @constraint(m, logical_or(y...) <= 1) + @test_throws ErrorException @constraint(m, sum(y) in IsTrue()) + @test_throws ErrorException @constraint(m, prod(y) in IsTrue()) + @test_throws ErrorException @constraint(m, sin(y[1]) in IsTrue()) + @test_throws MethodError @constraint(m, logical_or(y...) == IsTrue()) + @test_throws AssertionError @constraint(GDPModel(), logical_or(y...) in IsTrue()) +end + +function test_negation_add_success() + model = GDPModel() + @variable(model, y, LogicalVariable) + c1 = @constraint(model, logical_not(y) in IsTrue()) + @constraint(model, c2, ¬y in IsTrue()) + @test is_valid(model, c1) + @test is_valid(model, c2) + @test owner_model(c1) == model + @test owner_model(c2) == model + @test name(c1) == "" + @test name(c2) == "c2" + @test index(c1) == LogicalConstraintIndex(1) + @test index(c2) == LogicalConstraintIndex(2) + @test haskey(DP._logical_constraints(model), index(c1)) + @test haskey(DP._logical_constraints(model), index(c2)) + @test DP._logical_constraints(model)[index(c1)] == DP._constraint_data(c1) + @test constraint_object(c1).func isa DP._LogicalExpr + @test constraint_object(c2).func isa DP._LogicalExpr + @test constraint_object(c1).func.head == + constraint_object(c2).func.head == :! + @test constraint_object(c1).func.args == + constraint_object(c2).func.args == Any[y] + @test constraint_object(c1).set == + constraint_object(c2).set == IsTrue() + @test c1 == copy(c1) +end + +function test_implication_add_success() + model = GDPModel() + @variable(model, y[1:2], LogicalVariable) + @constraint(model, c1, implies(y...) in IsTrue()) + @constraint(model, c2, (y[1] ⟹ y[2]) in IsTrue()) + @test_macro_throws ErrorException @constraint(model, y[1] ⟹ y[2] in IsTrue()) + @test constraint_object(c1).func.head == + constraint_object(c2).func.head == :(=>) + @test constraint_object(c1).func.args == + constraint_object(c2).func.args == Vector{Any}(y) + @test constraint_object(c1).set == + constraint_object(c2).set == IsTrue() +end + +function test_equivalence_add_success() + model = GDPModel() + @variable(model, y[1:2], LogicalVariable) + @constraint(model, c1, iff(y...) in IsTrue()) + @constraint(model, c2, (y[1] ⇔ y[2]) in IsTrue()) + @test_macro_throws ErrorException @constraint(model, y[1] ⇔ y[2] in IsTrue()) + @test constraint_object(c1).func.head == + constraint_object(c2).func.head == :(==) + @test constraint_object(c1).func.args == + constraint_object(c2).func.args == Vector{Any}(y) + @test constraint_object(c1).set == + constraint_object(c2).set == IsTrue() +end + +function test_intersection_and_flatten_add_success() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + @constraint(model, c1, logical_and(y...) in IsTrue()) + @constraint(model, c2, ∧(y...) in IsTrue()) + @constraint(model, c3, y[1] ∧ y[2] ∧ y[3] in IsTrue()) + @test is_valid(model, c1) + @test is_valid(model, c2) + @test is_valid(model, c3) + @test constraint_object(c1).func.head == + constraint_object(c2).func.head == + constraint_object(c3).func.head == :&& + @test Set(constraint_object(c1).func.args) == + Set(constraint_object(c2).func.args) == + Set(DP._flatten(constraint_object(c3).func).args) + @test constraint_object(c1).set == + constraint_object(c2).set == + constraint_object(c3).set == IsTrue() +end + +function test_union_and_flatten_add_success() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + @constraint(model, c1, logical_or(y...) in IsTrue()) + @constraint(model, c2, ∨(y...) in IsTrue()) + @constraint(model, c3, y[1] ∨ y[2] ∨ y[3] in IsTrue()) + @test is_valid(model, c1) + @test is_valid(model, c2) + @test is_valid(model, c3) + @test constraint_object(c1).func.head == + constraint_object(c2).func.head == + constraint_object(c3).func.head == :|| + @test Set(constraint_object(c1).func.args) == + Set(constraint_object(c2).func.args) == + Set(DP._flatten(constraint_object(c3).func).args) + @test constraint_object(c1).set == + constraint_object(c2).set == + constraint_object(c3).set == IsTrue() +end + +function test_proposition_add_array() + model = GDPModel() + @variable(model, y[1:2, 1:3, 1:4], LogicalVariable) + @constraint(model, con[i=1:2,j=1:3], ∨(y[i,j,:]...) in IsTrue()) + @test con isa Matrix{LogicalConstraintRef} + @test length(con) == 6 +end + +function test_proposition_add_dense_axis() + model = GDPModel() + I = ["a", "b", "c"] + J = [1, 2] + @variable(model, y[I, J, 1:4], LogicalVariable) + @constraint(model, con[i=I,j=J], ∨(y[i,j,:]...) in IsTrue()) + @test con isa Containers.DenseAxisArray + @test con.axes[1] == ["a","b","c"] + @test con.axes[2] == [1,2] + @test con.data isa Matrix{LogicalConstraintRef} +end + +function test_proposition_add_sparse_axis() + model = GDPModel() + @variable(model, y[1:3, 1:3, 1:4], LogicalVariable) + @constraint(model, con[i=1:3,j=1:3; j > i], ∨(y[i,j,:]...) in IsTrue()) + @test con isa Containers.SparseAxisArray + @test length(con) == 3 + @test con.names == (:i, :j) + @test Set(keys(con.data)) == Set([(1,2),(1,3),(2,3)]) +end + +function test_proposition_set_name() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + c1 = @constraint(model, logical_not(y...) in IsTrue()) + set_name(c1, "proposition") + @test name(c1) == "proposition" +end + +function test_proposition_delete() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + c1 = @constraint(model, logical_not(y...) in IsTrue()) + + @test_throws AssertionError delete(GDPModel(), c1) + delete(model, c1) + @test !haskey(gdp_data(model).logical_constraints, index(c1)) + @test !DP._ready_to_optimize(model) +end + +function test_negation_reformulation() + model = GDPModel() + @variable(model, y, LogicalVariable) + @constraint(model, ¬y in IsTrue()) + reformulate_model(model, DummyReformulation()) + ref_con = DP._reformulation_constraints(model)[1] + @test is_valid(model, ref_con) + ref_con_obj = constraint_object(ref_con) + @test ref_con_obj.set == MOI.GreaterThan(0.0) + @test ref_con_obj.func == -DP._indicator_to_binary(model)[y] +end + +function test_implication_reformulation() + model = GDPModel() + @variable(model, y[1:2], LogicalVariable) + @constraint(model, implies(y[1], y[2]) in IsTrue()) + reformulate_model(model, DummyReformulation()) + ref_con = DP._reformulation_constraints(model)[1] + @test is_valid(model, ref_con) + ref_con_obj = constraint_object(ref_con) + @test ref_con_obj.set == MOI.GreaterThan(0.0) + @test ref_con_obj.func == + -DP._indicator_to_binary(model)[y[1]] + + DP._indicator_to_binary(model)[y[2]] +end + +function test_implication_reformulation_fail() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + @constraint(model, implies(y...) in IsTrue()) + @test_throws ErrorException reformulate_model(model, DummyReformulation()) +end + +function test_equivalence_reformulation() + model = GDPModel() + @variable(model, y[1:2], LogicalVariable) + @constraint(model, iff(y[1], y[2]) in IsTrue()) + reformulate_model(model, DummyReformulation()) + ref_cons = DP._reformulation_constraints(model) + @test all(is_valid.(model, ref_cons)) + ref_con_objs = constraint_object.(ref_cons) + @test ref_con_objs[1].set == + ref_con_objs[2].set == MOI.GreaterThan(0.0) + @test ref_con_objs[1].func == -ref_con_objs[2].func + bvars = DP._indicator_to_binary(model) + for con in ref_cons + @test normalized_coefficient(con, bvars[y[1]]) == + -normalized_coefficient(con, bvars[y[2]]) + end +end + +function test_intersection_reformulation() + model = GDPModel() + @variable(model, y[1:2], LogicalVariable) + @constraint(model, ∧(y[1], y[2]) in IsTrue()) + reformulate_model(model, DummyReformulation()) + ref_cons = DP._reformulation_constraints(model) + @test all(is_valid.(model, ref_cons)) + ref_con_objs = constraint_object.(ref_cons) + @test ref_con_objs[1].set == + ref_con_objs[2].set == MOI.GreaterThan(1.0) + bvars = DP._indicator_to_binary(model) + funcs = [ref_con_objs[1].func, ref_con_objs[2].func] + @test 1bvars[y[1]] in funcs + @test 1bvars[y[2]] in funcs +end + +function test_implication_reformulation() + model = GDPModel() + @variable(model, y[1:2], LogicalVariable) + @constraint(model, ∨(y[1], y[2]) in IsTrue()) + reformulate_model(model, DummyReformulation()) + ref_con = DP._reformulation_constraints(model)[1] + @test is_valid(model, ref_con) + ref_con_obj = constraint_object(ref_con) + @test ref_con_obj.set == MOI.GreaterThan(1.0) + @test ref_con_obj.func == + DP._indicator_to_binary(model)[y[1]] + + DP._indicator_to_binary(model)[y[2]] +end + +function test_lvar_cnf_functions() + model = GDPModel() + @variable(model, y, LogicalVariable) + @test DP._eliminate_equivalence(y) == y + @test DP._eliminate_implication(y) == y + @test DP._move_negations_inward(y) == y + neg_y = DP._negate(y) + @test neg_y.head == :! + @test neg_y.args[1] == y + @test DP._distribute_and_over_or(y) == y + @test DP._flatten(y) == y +end + +function test_eliminate_equivalence() + model = GDPModel() + @variable(model, y[1:2], LogicalVariable) + ex = y[1] ⇔ y[2] + new_ex = DP._eliminate_equivalence(ex) + @test new_ex.head == :&& + @test length(new_ex.args) == 2 + @test new_ex.args[1].head == :(=>) + @test new_ex.args[2].head == :(=>) + @test Set(new_ex.args[1].args) == Set{Any}(y) + @test Set(new_ex.args[2].args) == Set{Any}(y) +end + +function test_eliminate_equivalence_flat() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + ex = iff(y...) + new_ex = DP._eliminate_equivalence(ex) + @test new_ex.head == :&& + @test new_ex.args[1].head == :(=>) + @test new_ex.args[1].args[1] == y[1] + @test new_ex.args[1].args[2].head == :&& + @test y[2] in new_ex.args[1].args[2].args[1].args + @test y[3] in new_ex.args[1].args[2].args[1].args + @test y[2] in new_ex.args[1].args[2].args[2].args + @test y[3] in new_ex.args[1].args[2].args[2].args + @test new_ex.args[1].args[1] == new_ex.args[2].args[2] + @test new_ex.args[1].args[2] == new_ex.args[2].args[1] +end + +function test_eliminate_equivalence_nested() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + ex = iff(y[1], iff(y[2],y[3])) + new_ex = DP._eliminate_equivalence(ex) + @test new_ex.head == :&& + @test new_ex.args[1].head == :(=>) + @test new_ex.args[1].args[1] == y[1] + @test new_ex.args[1].args[2].head == :&& + @test y[2] in new_ex.args[1].args[2].args[1].args + @test y[3] in new_ex.args[1].args[2].args[1].args + @test y[2] in new_ex.args[1].args[2].args[2].args + @test y[3] in new_ex.args[1].args[2].args[2].args + @test new_ex.args[1].args[1] == new_ex.args[2].args[2] + @test new_ex.args[1].args[2] == new_ex.args[2].args[1] +end + +function test_eliminate_implication() + model = GDPModel() + @variable(model, y[1:2], LogicalVariable) + ex = y[1] ⟹ y[2] + new_ex = DP._eliminate_implication(ex) + @test new_ex.head == :|| + @test new_ex.args[1].head == :! + @test new_ex.args[1].args[1] == y[1] + @test new_ex.args[2] == y[2] +end + +function test_eliminate_implication_error() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + ex = implies(y...) + @test_throws ErrorException DP._eliminate_implication(ex) +end + +function test_eliminate_implication_nested() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + ex = (y[1] ⟹ y[2]) ⟹ y[3] + new_ex = DP._eliminate_implication(ex) + @test new_ex.head == :|| + @test new_ex.args[1].head == :! + @test new_ex.args[1].args[1].head == :|| + @test new_ex.args[1].args[1].args[1].head == :! + @test new_ex.args[1].args[1].args[1].args[1] == y[1] + @test new_ex.args[1].args[1].args[2] == y[2] + @test new_ex.args[2] == y[3] +end + +function test_move_negation_inward_error() + model = GDPModel() + @variable(model, y, LogicalVariable) + ex = ¬(y, y) + @test_throws ErrorException DP._move_negations_inward(ex) +end + +function test_move_negation_inward() + model = GDPModel() + @variable(model, y, LogicalVariable) + ex = ¬y + new_ex = DP._move_negations_inward(ex) + @test new_ex.head == :! + @test new_ex.args[1] == y +end + +function test_move_negation_inward_nested() + model = GDPModel() + @variable(model, y, LogicalVariable) + ex = ¬¬y + @test DP._move_negations_inward(ex) == y +end + +function test_negate_error() + model = GDPModel() + @variable(model, y, LogicalVariable) + @test_throws ErrorException DP._negate(iff(y,y)) +end + +function test_negate_or() + model = GDPModel() + @variable(model, y[1:2], LogicalVariable) + ex = ∨(y...) + new_ex = DP._negate_or(ex) + @test new_ex.head == :&& + @test new_ex.args[1].head == :! + @test new_ex.args[1].args[1] == y[1] + @test new_ex.args[2].head == :! + @test new_ex.args[2].args[1] == y[2] +end + +function test_negate_or_error() + model = GDPModel() + @variable(model, y, LogicalVariable) + @test_throws ErrorException DP._negate_or(∨(y)) +end + +function test_negate_and() + model = GDPModel() + @variable(model, y[1:2], LogicalVariable) + ex = ∧(y...) + new_ex = DP._negate_and(ex) + @test new_ex.head == :|| + @test new_ex.args[1].head == :! + @test new_ex.args[1].args[1] == y[1] + @test new_ex.args[2].head == :! + @test new_ex.args[2].args[1] == y[2] +end + +function test_negate_and_error() + model = GDPModel() + @variable(model, y, LogicalVariable) + @test_throws ErrorException DP._negate_or(∧(y)) +end + +function test_negate_negation() + model = GDPModel() + @variable(model, y, LogicalVariable) + @test DP._negate_negation(¬y) == y +end + +function test_negate_negation_error() + model = GDPModel() + @variable(model, y, LogicalVariable) + @test_throws ErrorException DP._negate_negation(¬(y,y)) +end + +function test_distribute_and_over_or() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + ex = y[1] ∨ (y[2] ∧ y[3]) + new_ex = DP._distribute_and_over_or(ex) + @test new_ex.head == :&& + @test new_ex.args[1].head == + new_ex.args[2].head == :|| + @test y[1] in new_ex.args[1].args + @test y[1] in new_ex.args[2].args + @test y[2] in new_ex.args[1].args || y[2] in new_ex.args[2].args + @test y[3] in new_ex.args[1].args || y[3] in new_ex.args[2].args +end + +function test_distribute_and_over_or_nested() + model = GDPModel() + @variable(model, y[1:4], LogicalVariable) + ex = (y[1] ∧ y[2]) ∨ (y[3] ∧ y[4]) + new_ex = DP._flatten(DP._distribute_and_over_or(ex)) + for arg in new_ex.args + @test arg.head == :|| + end + @test (y[1] in new_ex.args[1].args && y[3] in new_ex.args[1].args) || + (y[1] in new_ex.args[2].args && y[3] in new_ex.args[2].args) || + (y[1] in new_ex.args[3].args && y[3] in new_ex.args[3].args) || + (y[1] in new_ex.args[4].args && y[3] in new_ex.args[4].args) + + @test (y[1] in new_ex.args[1].args && y[4] in new_ex.args[1].args) || + (y[1] in new_ex.args[2].args && y[4] in new_ex.args[2].args) || + (y[1] in new_ex.args[3].args && y[4] in new_ex.args[3].args) || + (y[1] in new_ex.args[4].args && y[4] in new_ex.args[4].args) + + @test (y[2] in new_ex.args[1].args && y[3] in new_ex.args[1].args) || + (y[2] in new_ex.args[2].args && y[3] in new_ex.args[2].args) || + (y[2] in new_ex.args[3].args && y[3] in new_ex.args[3].args) || + (y[2] in new_ex.args[4].args && y[3] in new_ex.args[4].args) + + @test (y[2] in new_ex.args[1].args && y[4] in new_ex.args[1].args) || + (y[2] in new_ex.args[2].args && y[4] in new_ex.args[2].args) || + (y[2] in new_ex.args[3].args && y[4] in new_ex.args[3].args) || + (y[2] in new_ex.args[4].args && y[4] in new_ex.args[4].args) +end + +function test_to_cnf() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + ex = iff(y...) + new_ex = DP._to_cnf(ex) + @test new_ex.head == :&& + for arg in new_ex.args + @test arg.head == :|| + end + @test (y[1] in new_ex.args[1].args && y[2] in new_ex.args[1].args && y[3] in new_ex.args[1].args) || + (y[1] in new_ex.args[2].args && y[2] in new_ex.args[2].args && y[3] in new_ex.args[2].args) || + (y[1] in new_ex.args[3].args && y[2] in new_ex.args[3].args && y[3] in new_ex.args[3].args) || + (y[1] in new_ex.args[4].args && y[2] in new_ex.args[4].args && y[3] in new_ex.args[4].args) || + (y[1] in new_ex.args[5].args && y[2] in new_ex.args[5].args && y[3] in new_ex.args[5].args) || + (y[1] in new_ex.args[6].args && y[2] in new_ex.args[6].args && y[3] in new_ex.args[6].args) + + @test (y[1] in new_ex.args[1].args && !(y[2] in new_ex.args[1].args) && !(y[3] in new_ex.args[1].args)) || + (y[1] in new_ex.args[2].args && !(y[2] in new_ex.args[2].args) && !(y[3] in new_ex.args[2].args)) || + (y[1] in new_ex.args[3].args && !(y[2] in new_ex.args[3].args) && !(y[3] in new_ex.args[3].args)) || + (y[1] in new_ex.args[4].args && !(y[2] in new_ex.args[4].args) && !(y[3] in new_ex.args[4].args)) || + (y[1] in new_ex.args[5].args && !(y[2] in new_ex.args[5].args) && !(y[3] in new_ex.args[5].args)) || + (y[1] in new_ex.args[6].args && !(y[2] in new_ex.args[6].args) && !(y[3] in new_ex.args[6].args)) + + @test (!(y[1] in new_ex.args[1].args) && y[2] in new_ex.args[1].args && !(y[3] in new_ex.args[1].args)) || + (!(y[1] in new_ex.args[2].args) && y[2] in new_ex.args[2].args && !(y[3] in new_ex.args[2].args)) || + (!(y[1] in new_ex.args[3].args) && y[2] in new_ex.args[3].args && !(y[3] in new_ex.args[3].args)) || + (!(y[1] in new_ex.args[4].args) && y[2] in new_ex.args[4].args && !(y[3] in new_ex.args[4].args)) || + (!(y[1] in new_ex.args[5].args) && y[2] in new_ex.args[5].args && !(y[3] in new_ex.args[5].args)) || + (!(y[1] in new_ex.args[6].args) && y[2] in new_ex.args[6].args && !(y[3] in new_ex.args[6].args)) + + @test (!(y[1] in new_ex.args[1].args) && !(y[2] in new_ex.args[1].args) && y[3] in new_ex.args[1].args) || + (!(y[1] in new_ex.args[2].args) && !(y[2] in new_ex.args[2].args) && y[3] in new_ex.args[2].args) || + (!(y[1] in new_ex.args[3].args) && !(y[2] in new_ex.args[3].args) && y[3] in new_ex.args[3].args) || + (!(y[1] in new_ex.args[4].args) && !(y[2] in new_ex.args[4].args) && y[3] in new_ex.args[4].args) || + (!(y[1] in new_ex.args[5].args) && !(y[2] in new_ex.args[5].args) && y[3] in new_ex.args[5].args) || + (!(y[1] in new_ex.args[6].args) && !(y[2] in new_ex.args[6].args) && y[3] in new_ex.args[6].args) +end + +@testset "Logical Proposition Constraints" begin + @testset "Add Proposition" begin + test_proposition_add_fail() + test_negation_add_success() + test_implication_add_success() + test_equivalence_add_success() + test_intersection_and_flatten_add_success() + test_union_and_flatten_add_success() + test_proposition_add_array() + test_proposition_add_dense_axis() + test_proposition_add_sparse_axis() + end + @testset "Reformulate Proposition" begin + test_negation_reformulation() + test_implication_reformulation() + test_implication_reformulation_fail() + test_equivalence_reformulation() + test_intersection_reformulation() + test_implication_reformulation() + end + @testset "Conjunctive Normal Form" begin + test_lvar_cnf_functions() + test_eliminate_equivalence() + test_eliminate_equivalence_flat() + test_eliminate_equivalence_nested() + test_eliminate_implication() + test_eliminate_implication_error() + test_eliminate_implication_nested() + test_move_negation_inward_error() + test_move_negation_inward() + test_move_negation_inward_nested() + test_negate_error() + test_negate_or() + test_negate_or_error() + test_negate_and() + test_negate_and_error() + test_negate_negation() + test_negate_negation_error() + test_distribute_and_over_or() + test_distribute_and_over_or_nested() + test_to_cnf() + end +end \ No newline at end of file diff --git a/test/constraints/selector.jl b/test/constraints/selector.jl new file mode 100644 index 0000000..ab7ae37 --- /dev/null +++ b/test/constraints/selector.jl @@ -0,0 +1,200 @@ +function test_selector_add_fail() + m = GDPModel() + @variable(m, y[1:3], LogicalVariable) + @test_throws ErrorException @constraint(Model(), y in AtMost(2)) + @test_throws ErrorException @constraint(m, logical_or(y...) in Exactly(1)) + @test_throws ErrorException @constraint(m, sin.(y) in Exactly(1)) + @test_throws AssertionError @constraint(GDPModel(), y in AtMost(2)) + @test_throws MethodError @constraint(m, y in AtMost(1.0)) + @test_throws MethodError @constraint(m, y[1:2] in AtMost(1y[3])) +end + +function test_selector_add_success() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + c1 = @constraint(model, y in Exactly(1)) + @constraint(model, c2, y in Exactly(1)) + @test owner_model(c1) == model + @test is_valid(model, c1) + @test index(c1) == LogicalConstraintIndex(1) + @test name(c1) == "" + @test name(c2) == "c2" + @test haskey(DP._logical_constraints(model), index(c1)) + @test haskey(DP._logical_constraints(model), index(c2)) + @test DP._logical_constraints(model)[index(c1)] == DP._constraint_data(c1) + @test 1 in constraint_object(c1).func + @test y[1] in constraint_object(c1).func + @test y[2] in constraint_object(c1).func + @test y[3] in constraint_object(c1).func + @test constraint_object(c1).set == DP._MOIExactly(4) + @test constraint_object(c1).func == constraint_object(c2).func + @test constraint_object(c1).set == constraint_object(c2).set + @test c1 == copy(c1) +end + +function test_nested_selector_add_success() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + c1 = @constraint(model, y[1:2] in Exactly(y[3])) + @test is_valid(model, c1) + @test length(constraint_object(c1).func) == 3 + @test y[1] in constraint_object(c1).func + @test y[2] in constraint_object(c1).func + @test y[3] in constraint_object(c1).func +end + +function test_selector_add_array() + model = GDPModel() + @variable(model, y[1:2, 1:3, 1:4], LogicalVariable) + @constraint(model, con[i=1:2, j=1:3], y[i,j,:] in Exactly(1)) + @test con isa Matrix{LogicalConstraintRef} + @test length(con) == 6 +end + +function test_selector_add_dense_axis() + model = GDPModel() + I = ["a", "b", "c"] + J = [1, 2] + @variable(model, y[I, J, 1:4], LogicalVariable) + @constraint(model, con[i=I, j=J], y[i,j,:] in Exactly(1)) + @test con isa Containers.DenseAxisArray + @test con.axes[1] == ["a","b","c"] + @test con.axes[2] == [1,2] + @test con.data isa Matrix{LogicalConstraintRef} +end + +function test_selector_add_sparse_axis() + model = GDPModel() + @variable(model, y[1:3, 1:3, 1:4], LogicalVariable) + @constraint(model, con[i=1:3, j=1:3; j > i], y[i,j,:] in Exactly(1)) + @test con isa Containers.SparseAxisArray + @test length(con) == 3 + @test con.names == (:i, :j) + @test Set(keys(con.data)) == Set([(1,2),(1,3),(2,3)]) +end + +function test_selector_set_name() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + c1 = @constraint(model, y in Exactly(1)) + set_name(c1, "selector") + @test name(c1) == "selector" +end + +function test_selector_delete() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + c1 = @constraint(model, y in Exactly(1)) + + @test_throws AssertionError delete(GDPModel(), c1) + + delete(model, c1) + @test !haskey(gdp_data(model).logical_constraints, index(c1)) + @test !DP._ready_to_optimize(model) +end + +function test_exactly_reformulation() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + @constraint(model, y in Exactly(1)) + reformulate_model(model, DummyReformulation()) + ref_con = DP._reformulation_constraints(model)[1] + @test is_valid(model, ref_con) + ref_con_obj = constraint_object(ref_con) + @test ref_con_obj.set == MOI.EqualTo(1.0) + @test ref_con_obj.func == sum(DP._reformulation_variables(model)) +end + +function test_atleast_reformulation() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + @constraint(model, y in AtLeast(1)) + reformulate_model(model, DummyReformulation()) + ref_con = DP._reformulation_constraints(model)[1] + @test is_valid(model, ref_con) + ref_con_obj = constraint_object(ref_con) + @test ref_con_obj.set == MOI.GreaterThan(1.0) + @test ref_con_obj.func == sum(DP._reformulation_variables(model)) +end + +function test_atmost_reformulation() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + @constraint(model, y in AtMost(1)) + reformulate_model(model, DummyReformulation()) + ref_con = DP._reformulation_constraints(model)[1] + @test is_valid(model, ref_con) + ref_con_obj = constraint_object(ref_con) + @test ref_con_obj.set == MOI.LessThan(1.0) + @test ref_con_obj.func == sum(DP._reformulation_variables(model)) +end + +function test_nested_exactly_reformulation() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + @constraint(model, y[1:2] in Exactly(y[3])) + reformulate_model(model, DummyReformulation()) + ref_con = DP._reformulation_constraints(model)[1] + @test is_valid(model, ref_con) + ref_con_obj = constraint_object(ref_con) + @test ref_con_obj.set == MOI.EqualTo(0.0) + @test ref_con_obj.func == + DP._indicator_to_binary(model)[y[1]] + + DP._indicator_to_binary(model)[y[2]] - + DP._indicator_to_binary(model)[y[3]] +end + +function test_nested_atleast_reformulation() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + @constraint(model, y[1:2] in AtLeast(y[3])) + reformulate_model(model, DummyReformulation()) + ref_con = DP._reformulation_constraints(model)[1] + @test is_valid(model, ref_con) + ref_con_obj = constraint_object(ref_con) + @test ref_con_obj.set == MOI.GreaterThan(0.0) + @test ref_con_obj.func == + DP._indicator_to_binary(model)[y[1]] + + DP._indicator_to_binary(model)[y[2]] - + DP._indicator_to_binary(model)[y[3]] +end + +function test_nested_atmost_reformulation() + model = GDPModel() + @variable(model, y[1:3], LogicalVariable) + @constraint(model, y[1:2] in AtMost(y[3])) + reformulate_model(model, DummyReformulation()) + ref_con = DP._reformulation_constraints(model)[1] + @test is_valid(model, ref_con) + ref_con_obj = constraint_object(ref_con) + @test ref_con_obj.set == MOI.LessThan(0.0) + @test ref_con_obj.func == + DP._indicator_to_binary(model)[y[1]] + + DP._indicator_to_binary(model)[y[2]] - + DP._indicator_to_binary(model)[y[3]] +end + +@testset "Logical Selector Constraints" begin + @testset "Add Selector" begin + test_selector_add_fail() + test_selector_add_success() + test_nested_selector_add_success() + test_selector_add_array() + test_selector_add_dense_axis() + test_selector_add_sparse_axis() + end + @testset "Selector Properties" begin + test_selector_set_name() + end + @testset "Delete Selector" begin + test_selector_delete() + end + @testset "Reformulate Selector" begin + test_exactly_reformulation() + test_atleast_reformulation() + test_atmost_reformulation() + test_nested_exactly_reformulation() + test_nested_atleast_reformulation() + test_nested_atmost_reformulation() + end +end \ No newline at end of file diff --git a/test/disjunction.jl b/test/disjunction.jl new file mode 100644 index 0000000..1032e6e --- /dev/null +++ b/test/disjunction.jl @@ -0,0 +1,216 @@ +function test_disjunction_add_fail() + model = GDPModel() + @variable(model, x) + @variable(model, y[1:2], LogicalVariable) + @constraint(model, x == 5, DisjunctConstraint(y[1])) + + @test_macro_throws ErrorException @disjunction(model) #not enough arguments + @test_macro_throws UndefVarError @disjunction(model, y) #unassociated indicator + @test_macro_throws UndefVarError @disjunction(GDPModel(), y) #wrong model + @test_macro_throws ErrorException @disjunction(Model(), y) #not a GDPModel + @test_macro_throws UndefVarError @disjunction(model, [y[1], y[1]]) #duplicate indicator + @test_macro_throws UndefVarError @disjunction(model, y[1]) #no disjunction expression + @test_macro_throws UndefVarError @disjunction(model, y, "random_arg") #unrecognized extra argument + @test_macro_throws ErrorException @disjunction(model, "ABC") #unrecognized structure + @test_macro_throws ErrorException @disjunction(model, begin y end) #@disjunctions (plural) + @test_macro_throws UndefVarError @disjunction(model, x, y) #name x already exists + + @constraint(model, x == 10, DisjunctConstraint(y[2])) + @disjunction(model, disj, y) + @test_macro_throws UndefVarError @disjunction(model, disj, y) #duplicate name + + @test_macro_throws ErrorException @disjunction(model, "bad"[i=1:2], y) #wrong expression for disjunction name + @test_macro_throws ErrorException @disjunction(model, [model=1:2], y) #index name can't be same as model name +end + +function test_disjunction_add_success() + model = GDPModel() + @variable(model, x) + @variable(model, y[1:2], LogicalVariable) + @constraint(model, x == 5, DisjunctConstraint(y[1])) + @constraint(model, x == 10, DisjunctConstraint(y[2])) + disj = @disjunction(model, y) + @disjunction(model, disj2, y) + @test owner_model(disj) == model + @test is_valid(model, disj) + @test index(disj) == DisjunctionIndex(1) + @test name(disj) == "" + @test name(disj2) == "disj2" + @test haskey(DP._disjunctions(model), index(disj)) + @test haskey(DP._disjunctions(model), index(disj2)) + @test DP._disjunctions(model)[index(disj)] == DP._constraint_data(disj) + @test !constraint_object(disj).nested + @test constraint_object(disj).indicators == y + @test disj == copy(disj) +end + +function test_disjunction_add_nested() + model = GDPModel() + @variable(model, x) + @variable(model, y[1:2], LogicalVariable) + @variable(model, z[1:2], LogicalVariable) + @constraint(model, x <= 5, DisjunctConstraint(y[1])) + @constraint(model, x >= 5, DisjunctConstraint(y[2])) + @disjunction(model, inner, y, DisjunctConstraint(z[1])) + @constraint(model, x <= 10, DisjunctConstraint(z[1])) + @constraint(model, x >= 10, DisjunctConstraint(z[2])) + @disjunction(model, outer, z) + + @test is_valid(model, inner) + @test is_valid(model, outer) + @test haskey(DP._disjunctions(model), index(inner)) + @test haskey(DP._disjunctions(model), index(outer)) + @test constraint_object(inner).nested + @test !constraint_object(outer).nested + @test haskey(DP._indicator_to_constraints(model), z[1]) + @test inner in DP._indicator_to_constraints(model)[z[1]] +end + +function test_disjunction_add_array() + model=GDPModel() + @variable(model, x) + @variable(model, y[1:2, 1:3, 1:4], LogicalVariable) + @constraint(model, con[i=1:2, j=1:3, k=1:4], x==i+j+k, DisjunctConstraint(y[i,j,k])) + @disjunction(model, disj[i=1:2, j=1:3], y[i,j,:]) + + @test disj isa Matrix{DisjunctionRef} + @test length(disj) == 6 + @test all(is_valid.(model, disj)) +end + +function test_disjunciton_add_dense_axis() + model = GDPModel() + @variable(model, x) + I = ["a", "b", "c"] + J = [1, 2] + @variable(model, y[I, J, 1:4], LogicalVariable) + @constraint(model, con[i=I, j=J, k=1:4], x==k, DisjunctConstraint(y[i,j,k])) + @disjunction(model, disj[i=I, j=J], y[i,j,:]) + + @test disj isa Containers.DenseAxisArray + @test disj.axes[1] == ["a","b","c"] + @test disj.axes[2] == [1,2] + @test disj.data isa Matrix{DisjunctionRef} +end + +function test_disjunction_add_sparse_axis() + model = GDPModel() + @variable(model, x) + @variable(model, y[1:3, 1:3, 1:4], LogicalVariable) + @constraint(model, con[i=1:3, j=1:3, k=1:4; j > i], x==i+j+k, DisjunctConstraint(y[i,j,k])) + @disjunction(model, disj[i=1:3, j=1:3; j > i], y[i,j,:]) + + @test disj isa Containers.SparseAxisArray + @test length(disj) == 3 + @test disj.names == (:i, :j) + @test Set(keys(disj.data)) == Set([(1,2),(1,3),(2,3)]) +end + +function test_disjunctions_add_success() + model = GDPModel() + @variable(model, x) + @variable(model, y[1:2], LogicalVariable) + @variable(model, z[1:2], LogicalVariable) + @constraint(model, x <= 5, DisjunctConstraint(y[1])) + @constraint(model, x >= 5, DisjunctConstraint(y[2])) + @constraint(model, x <= 10, DisjunctConstraint(z[1])) + @constraint(model, x >= 10, DisjunctConstraint(z[2])) + @disjunctions(model, begin + disj1, y + disj2, z + end) + @test is_valid(model, disj1) + @test is_valid(model, disj2) + @test haskey(DP._disjunctions(model), index(disj1)) + @test haskey(DP._disjunctions(model), index(disj2)) + + unamed = @disjunctions(model, begin + y + z + end) + @test all(is_valid.(model, unamed)) + @test haskey(DP._disjunctions(model), index(unamed[1])) + @test haskey(DP._disjunctions(model), index(unamed[2])) +end + +function test_disjunction_set_name() + model = GDPModel() + @variable(model, x) + @variable(model, y[1:2], LogicalVariable) + @constraint(model, x == 5, DisjunctConstraint(y[1])) + @constraint(model, x == 10, DisjunctConstraint(y[2])) + @disjunction(model, disj, y) + set_name(disj, "new_name") + @test name(disj) == "new_name" +end + +function test_disjunction_delete() + model = GDPModel() + @variable(model, x) + @variable(model, y[1:2], LogicalVariable) + @constraint(model, x == 5, DisjunctConstraint(y[1])) + @constraint(model, x == 10, DisjunctConstraint(y[2])) + @disjunction(model, disj, y) + + @test_throws AssertionError delete(GDPModel(), disj) + delete(model, disj) + @test !haskey(gdp_data(model).disjunctions, index(disj)) + @test !DP._ready_to_optimize(model) +end + +function test_disjunction_function() + model = GDPModel() + @variable(model, x) + @variable(model, y[1:2], LogicalVariable) + @constraint(model, x == 5, DisjunctConstraint(y[1])) + @constraint(model, x == 10, DisjunctConstraint(y[2])) + disj = disjunction(model, y, "name") + + @test is_valid(model, disj) + @test name(disj) == "name" + set_name(disj, "new_name") + @test name(disj) == "new_name" + @test haskey(DP._disjunctions(model), index(disj)) +end + +function test_disjunction_function_nested() + model = GDPModel() + @variable(model, x) + @variable(model, y[1:2], LogicalVariable) + @variable(model, z[1:2], LogicalVariable) + @constraint(model, x <= 5, DisjunctConstraint(y[1])) + @constraint(model, x >= 5, DisjunctConstraint(y[2])) + @constraint(model, x <= 10, DisjunctConstraint(z[1])) + @constraint(model, x >= 10, DisjunctConstraint(z[2])) + disj1 = disjunction(model, y, DisjunctConstraint(z[1]), "inner") + disj2 = disjunction(model, z, "outer") + + @test is_valid(model, disj1) + @test is_valid(model, disj2) + @test haskey(DP._disjunctions(model), index(disj1)) + @test haskey(DP._disjunctions(model), index(disj2)) + @test constraint_object(disj1).nested + @test !constraint_object(disj2).nested + @test haskey(DP._indicator_to_constraints(model), z[1]) + @test disj1 in DP._indicator_to_constraints(model)[z[1]] +end + +@testset "Disjunction" begin + @testset "Add Disjunction" begin + test_disjunction_add_fail() + test_disjunction_add_success() + test_disjunction_add_nested() + test_disjunction_add_array() + test_disjunciton_add_dense_axis() + test_disjunction_add_sparse_axis() + test_disjunctions_add_success() + test_disjunction_function() + test_disjunction_function_nested() + end + @testset "Disjunction Properties" begin + test_disjunction_set_name() + end + @testset "Delete Disjunction" begin + test_disjunction_delete() + end +end \ No newline at end of file diff --git a/test/model.jl b/test/model.jl new file mode 100644 index 0000000..83a2f4b --- /dev/null +++ b/test/model.jl @@ -0,0 +1,39 @@ +using HiGHS + +function test_empty_model() + model = GDPModel() + @test gdp_data(model) isa GDPData + @test isempty(DP._logical_variables(model)) + @test isempty(DP._logical_constraints(model)) + @test isempty(DP._disjunct_constraints(model)) + @test isempty(DP._disjunctions(model)) + @test isempty(DP._indicator_to_binary(model)) + @test isempty(DP._indicator_to_constraints(model)) + @test isempty(DP._reformulation_variables(model)) + @test isempty(DP._reformulation_constraints(model)) + @test isnothing(DP._solution_method(model)) + @test !DP._ready_to_optimize(model) +end + +function test_non_gdp_model() + model = Model() + @test_throws ErrorException gdp_data(model) +end + +function test_creation_optimizer() + model = GDPModel(HiGHS.Optimizer) + @test solver_name(model) == "HiGHS" +end + +function test_set_optimizer() + model = GDPModel() + set_optimizer(model, HiGHS.Optimizer) + @test solver_name(model) == "HiGHS" +end + +@testset "GDP Model" begin + test_empty_model() + test_non_gdp_model() + test_creation_optimizer() + test_set_optimizer() +end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index e69de29..e06b246 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -0,0 +1,40 @@ +using DisjunctiveProgramming +using JuMP +using Test + +const DP = DisjunctiveProgramming + +struct DummyReformulation <: AbstractReformulationMethod end + +# Utilities to test macro error exception +# Taken from https://github.com/jump-dev/JuMP.jl/blob/master/test/utilities.jl +function strip_line_from_error(err::ErrorException) + return ErrorException(replace(err.msg, r"^At.+\:[0-9]+\: `@" => "In `@")) +end +strip_line_from_error(err::LoadError) = strip_line_from_error(err.error) +strip_line_from_error(err) = err +macro test_macro_throws(errortype, m) + quote + @test_throws( + $(esc(strip_line_from_error(errortype))), + try + @eval $m + catch err + throw(strip_line_from_error(err)) + end + ) + end +end + +include("aqua.jl") +include("model.jl") +include("variables/query.jl") +include("variables/logical.jl") +include("constraints/selector.jl") +include("constraints/proposition.jl") +include("constraints/disjunct.jl") +include("constraints/indicator.jl") +include("constraints/bigm.jl") +include("constraints/hull.jl") +include("disjunction.jl") +include("solve.jl") \ No newline at end of file diff --git a/test/solve.jl b/test/solve.jl new file mode 100644 index 0000000..697ccde --- /dev/null +++ b/test/solve.jl @@ -0,0 +1,50 @@ +using HiGHS + +function test_linear_gdp_example() + m = GDPModel(HiGHS.Optimizer) + set_attribute(m, MOI.Silent(), true) + @variable(m, 1 ≤ x[1:2] ≤ 9) + @variable(m, Y[1:2], LogicalVariable) + @variable(m, W[1:2], LogicalVariable) + @objective(m, Max, sum(x)) + @constraint(m, y1[i=1:2], [1,4][i] ≤ x[i] ≤ [3,6][i], DisjunctConstraint(Y[1])) + @constraint(m, w1[i=1:2], [1,5][i] ≤ x[i] ≤ [2,6][i], DisjunctConstraint(W[1])) + @constraint(m, w2[i=1:2], [2,4][i] ≤ x[i] ≤ [3,5][i], DisjunctConstraint(W[2])) + @constraint(m, y2[i=1:2], [8,1][i] ≤ x[i] ≤ [9,2][i], DisjunctConstraint(Y[2])) + @disjunction(m, inner, [W[1], W[2]], DisjunctConstraint(Y[1])) + @disjunction(m, outer, [Y[1], Y[2]]) + @constraint(m, Y in Exactly(1)) + @constraint(m, W in Exactly(Y[1])) + + optimize!(m, method = BigM()) + @test termination_status(m) == MOI.OPTIMAL + @test objective_value(m) ≈ 11 + @test value.(x) ≈ [9,2] + bins = gdp_data(m).indicator_to_binary + @test value(bins[Y[1]]) ≈ 0 + @test value(bins[Y[2]]) ≈ 1 + @test value(bins[W[1]]) ≈ 0 + @test value(bins[W[2]]) ≈ 0 + + optimize!(m, method = Hull()) + @test termination_status(m) == MOI.OPTIMAL + @test objective_value(m) ≈ 11 + @test value.(x) ≈ [9,2] + bins = gdp_data(m).indicator_to_binary + @test value(bins[Y[1]]) ≈ 0 + @test value(bins[Y[2]]) ≈ 1 + @test value(bins[W[1]]) ≈ 0 + @test value(bins[W[2]]) ≈ 0 + @test value(variable_by_name(m, "x[1]_Y[1]")) ≈ 0 + @test value(variable_by_name(m, "x[1]_Y[2]")) ≈ 9 + @test value(variable_by_name(m, "x[1]_W[1]")) ≈ 0 + @test value(variable_by_name(m, "x[1]_W[2]")) ≈ 0 + @test value(variable_by_name(m, "x[2]_Y[1]")) ≈ 0 + @test value(variable_by_name(m, "x[2]_Y[2]")) ≈ 2 + @test value(variable_by_name(m, "x[2]_W[1]")) ≈ 0 + @test value(variable_by_name(m, "x[2]_W[2]")) ≈ 0 +end + +@testset "Solve Linear GDP" begin + test_linear_gdp_example() +end \ No newline at end of file diff --git a/test/variables/logical.jl b/test/variables/logical.jl new file mode 100644 index 0000000..489474f --- /dev/null +++ b/test/variables/logical.jl @@ -0,0 +1,168 @@ +# test creating, modifying, and reformulating logical variables +function test_lvar_add_fail() + model = Model() + @test_throws ErrorException @variable(model, y, LogicalVariable) +end + +function test_lvar_add_success() + model = GDPModel() + @variable(model, y, LogicalVariable) + @test typeof(y) == LogicalVariableRef + @test owner_model(y) == model + @test is_valid(model, y) + @test name(y) == "y" + @test index(y) == LogicalVariableIndex(1) + @test isnothing(start_value(y)) + @test isnothing(fix_value(y)) + @test isequal_canonical(y, copy(y)) + @test haskey(DP._logical_variables(model), index(y)) + @test DP._logical_variables(model)[index(y)].variable == LogicalVariable(nothing, nothing) + @test DP._logical_variables(model)[index(y)].name == "y" + #reformulate the variable + test_lvar_reformulation(model, y) +end + +function test_lvar_add_array() + model = GDPModel() + @variable(model, y[1:3, 1:2], LogicalVariable) + @test y isa Array{LogicalVariableRef, 2} + @test length(y) == 6 +end + +function test_lvar_add_dense_axis() + model = GDPModel() + @variable(model, y[["a","b","c"],[1,2]], LogicalVariable) + @test y isa Containers.DenseAxisArray + @test length(y) == 6 + @test y.axes[1] == ["a","b","c"] + @test y.axes[2] == [1,2] + @test y.data isa Array{LogicalVariableRef, 2} +end + +function test_lvar_add_sparse_axis() + model = GDPModel() + @variable(model, y[i = 1:3, j = 1:3; j > i], LogicalVariable) + @test y isa Containers.SparseAxisArray + @test length(y) == 3 + @test y.names == (:i, :j) + @test Set(keys(y.data)) == Set([(1,2),(1,3),(2,3)]) +end + +function test_lvar_set_name() + model = GDPModel() + @variable(model, y, LogicalVariable) + set_name(y, "z") + @test name(y) == "z" + #reformulate the variable + test_lvar_reformulation(model, y) +end + +function test_lvar_creation_start_value() + model = GDPModel() + @variable(model, y, LogicalVariable, start = true) + @test start_value(y) + #reformulate the variable + test_lvar_reformulation(model, y) +end + +function test_lvar_set_start_value() + model = GDPModel() + @variable(model, y, LogicalVariable) + @test isnothing(start_value(y)) + set_start_value(y, false) + @test !start_value(y) + #reformulate the variable + test_lvar_reformulation(model, y) +end + +function test_lvar_fix_value() + model = GDPModel() + @variable(model, y, LogicalVariable) + @test isnothing(fix_value(y)) + fix(y, true) + @test fix_value(y) + #reformulate the variable + test_lvar_reformulation(model, y) + #unfix the value + unfix(y) + @test isnothing(fix_value(y)) +end + +function test_lvar_delete() + model = GDPModel() + @variable(model, y, LogicalVariable) + @variable(model, z, LogicalVariable) + @variable(model, x) + @constraint(model, con, x <= 10, DisjunctConstraint(y)) + @constraint(model, con2, x >= 50, DisjunctConstraint(z)) + @disjunction(model, disj, [y, z]) + @constraint(model, lcon, y ∨ z in IsTrue()) + DP._reformulate_logical_variables(model) + + @test_throws AssertionError delete(GDPModel(), y) + + delete(model, y) + @test !haskey(gdp_data(model).logical_variables, index(y)) + @test haskey(gdp_data(model).logical_variables, index(z)) + @test !haskey(gdp_data(model).disjunct_constraints, index(con)) + @test !haskey(gdp_data(model).disjunctions, index(disj)) + @test !haskey(gdp_data(model).logical_constraints, index(lcon)) + @test !haskey(gdp_data(model).indicator_to_constraints, y) + @test !haskey(gdp_data(model).indicator_to_binary, y) + @test haskey(gdp_data(model).indicator_to_binary, z) + @test !DP._ready_to_optimize(model) +end + +function test_lvar_reformulation() + model = GDPModel() + @variable(model, y, LogicalVariable, start = false) + fix(y, true) + test_lvar_reformulation(model, y) +end + +function test_lvar_reformulation(model::Model, lvref::LogicalVariableRef) + model = owner_model(lvref) + DP._reformulate_logical_variables(model) + @test haskey(DP._indicator_to_binary(model), lvref) + bvref = DP._indicator_to_binary(model)[lvref] + @test bvref in DP._reformulation_variables(model) + @test name(bvref) == name(lvref) + @test is_valid(model, bvref) + @test is_binary(bvref) + if isnothing(start_value(lvref)) + @test isnothing(start_value(bvref)) + elseif start_value(lvref) + @test isone(start_value(bvref)) + else + @test iszero(start_value(bvref)) + end + if isnothing(fix_value(lvref)) + @test_throws Exception fix_value(bvref) + elseif fix_value(lvref) + @test isone(fix_value(bvref)) + else + @test iszero(fix_value(bvref)) + end +end + +@testset "Logical Variables" begin + @testset "Add Logical Variables" begin + test_lvar_add_fail() + test_lvar_add_success() + test_lvar_add_array() + test_lvar_add_dense_axis() + test_lvar_add_sparse_axis() + end + @testset "Logical Variable Properties" begin + test_lvar_set_name() + test_lvar_creation_start_value() + test_lvar_set_start_value() + test_lvar_fix_value() + end + @testset "Delete Logical Variables" begin + test_lvar_delete() + end + @testset "Reformulate Logical Variables" begin + test_lvar_reformulation() + end +end \ No newline at end of file diff --git a/test/variables/query.jl b/test/variables/query.jl new file mode 100644 index 0000000..8ed7015 --- /dev/null +++ b/test/variables/query.jl @@ -0,0 +1,168 @@ +function test_interrogate_non_variables() + vars = Set() + f = Base.Fix1(push!, vars) #interrogator + #numbers + DP._interrogate_variables(f, 1) + @test isempty(vars) + empty!(vars) + DP._interrogate_variables(f, 1.0) + @test isempty(vars) + empty!(vars) + #strings/symbols + @test_throws ErrorException DP._interrogate_variables(f, "a") + @test_throws ErrorException DP._interrogate_variables(f, :a) +end + +function test_interrogate_variables() + vars = Set() + f = Base.Fix1(push!, vars) #interrogator + m = GDPModel() + @variable(m, x) + @variable(m, y, LogicalVariable) + DP._interrogate_variables(f, [x, y]) + @test x in vars + @test y in vars + @test length(vars) == 2 +end + +function test_interrogate_affexpr() + vars = Set() + f = Base.Fix1(push!, vars) #interrogator + m = GDPModel() + @variable(m, x) + @variable(m, y, LogicalVariable) + @variable(m, z) + DP._interrogate_variables(f, x + y + z) + @test x in vars + @test y in vars + @test z in vars + @test length(vars) == 3 +end + +function test_interrogate_quadexpr() + vars = Set() + f = Base.Fix1(push!, vars) #interrogator + m = GDPModel() + @variable(m, x) + @variable(m, y, LogicalVariable) + @variable(m, z) + DP._interrogate_variables(f, x^2 + x*y + z + 1) + @test x in vars + @test y in vars + @test z in vars + @test length(vars) == 3 + empty!(vars) +end + +function test_interrogate_nonlinear_expr() + vars = Set() + f = Base.Fix1(push!, vars) #interrogator + m = GDPModel() + @variable(m, x) + @variable(m, y, LogicalVariable) + @variable(m, z) + DP._interrogate_variables(f, sin(exp(x^2 + 1)) + cos(x) + y + 2) + @test x in vars + @test y in vars + @test !(z in vars) + @test length(vars) == 2 +end + +function test_interrogate_logical_expr() + vars = Set() + f = Base.Fix1(push!, vars) #interrogator + m = GDPModel() + @variable(m, y, LogicalVariable) + @variable(m, w[1:5], LogicalVariable) + ex = (implies(w[1], w[2]) ∧ w[3]) ⇔ (¬w[4] ∨ y) + DP._interrogate_variables(f, ex) + @test w[1] in vars + @test w[2] in vars + @test w[3] in vars + @test w[4] in vars + @test !(w[5] in vars) + @test y in vars + @test length(vars) == 5 +end + +function test_interrogate_proposition_constraint() + m = GDPModel() + @variable(m, y, LogicalVariable) + @variable(m, w[1:5], LogicalVariable) + ex = (implies(w[1], w[2]) ∧ w[3]) ⇔ (¬w[4] ∨ y) + @constraint(m, con, ex in IsTrue()) + obj = constraint_object(con) + vars = DP._get_constraint_variables(m, obj) + @test w[1] in vars + @test w[2] in vars + @test w[3] in vars + @test w[4] in vars + @test !(w[5] in vars) + @test y in vars + @test length(vars) == 5 +end + +function test_interrogate_selector_constraint() + m = GDPModel() + @variable(m, y, LogicalVariable) + @variable(m, w[1:5], LogicalVariable) + @constraint(m, con, w[1:4] in AtMost(y)) + obj = constraint_object(con) + vars = DP._get_constraint_variables(m, obj) + @test w[1] in vars + @test w[2] in vars + @test w[3] in vars + @test w[4] in vars + @test !(w[5] in vars) + @test y in vars + @test length(vars) == 5 +end + +function test_interrogate_disjunction() + m = GDPModel() + @variable(m, -5 ≤ x[1:2] ≤ 10) + @variable(m, Y[1:2], LogicalVariable) + @constraint(m, [i = 1:2], 0 ≤ x[i] ≤ [3,4][i], DisjunctConstraint(Y[1])) + @constraint(m, [i = 1:2], [5,4][i] ≤ x[i] ≤ [9,6][i], DisjunctConstraint(Y[2])) + @disjunction(m, Y) + disj = DP._disjunctions(m)[DisjunctionIndex(1)].constraint + vars = DP._get_disjunction_variables(m, disj) + @test Set(x) == vars +end + +function test_interrogate_nested_disjunction() + m = GDPModel() + @variable(m, -5 <= x[1:3] <= 5) + + @variable(m, y[1:2], LogicalVariable) + @constraint(m, x[1] <= -2, DisjunctConstraint(y[1])) + @constraint(m, x[1] >= 2, DisjunctConstraint(y[2])) + @disjunction(m, y) + + @variable(m, w[1:2], LogicalVariable) + @constraint(m, x[2] <= -3, DisjunctConstraint(w[1])) + @constraint(m, x[2] >= 3, DisjunctConstraint(w[2])) + @disjunction(m, w, DisjunctConstraint(y[1])) + + @variable(m, z[1:2], LogicalVariable) + @constraint(m, x[3] <= -4, DisjunctConstraint(z[1])) + @constraint(m, x[3] >= 4, DisjunctConstraint(z[2])) + @disjunction(m, z, DisjunctConstraint(w[1])) + + disj = DP._disjunctions(m)[DisjunctionIndex(1)].constraint + vars = DP._get_disjunction_variables(m, disj) + @test Set(x) == vars +end + +@testset "Variable Interrogation" begin + test_interrogate_non_variables() + test_interrogate_variables() + test_interrogate_affexpr() + test_interrogate_quadexpr() + test_interrogate_nonlinear_expr() + test_interrogate_logical_expr() + test_interrogate_proposition_constraint() + test_interrogate_selector_constraint() + test_interrogate_disjunction() + test_interrogate_nested_disjunction() +end \ No newline at end of file