From 420e0594e03c56ef40db3492fbb4027d9dcb1b7d Mon Sep 17 00:00:00 2001 From: Paul Nation Date: Mon, 16 Aug 2021 11:55:54 -0400 Subject: [PATCH] Initial version --- .github/workflows/python-package-conda.yml | 34 + .gitignore | 134 + LICENSE => LICENSE.txt | 4 +- README.md | 98 + docs/Makefile | 28 + docs/_static/custom.css | 27 + docs/_static/gallery.css | 195 + docs/_static/style.css | 12 + docs/_static/theme.css | 12285 ++++++++++++++++++ docs/_templates/autosummary/class.rst | 32 + docs/_templates/layout.html | 322 + docs/_templates/theme_variables.jinja | 26 + docs/_templates/versions.html | 24 + docs/apidocs/main.rst | 6 + docs/conf.py | 131 + docs/images/truncation.png | Bin 0 -> 126320 bytes docs/index.rst | 35 + examples/30Q_GHZ_Manhattan.ipynb | 326 + examples/M3_paper_example1.ipynb | 626 + examples/correcting_for_probabilities.ipynb | 195 + examples/m3_x8_stabilizer_example.ipynb | 272 + mthree/__init__.py | 39 + mthree/classes.py | 108 + mthree/compute.pxd | 30 + mthree/compute.pyx | 137 + mthree/converters.pxd | 23 + mthree/converters.pyx | 68 + mthree/exceptions.py | 26 + mthree/expval.pyx | 63 + mthree/hamming.pyx | 64 + mthree/matrix.pyx | 183 + mthree/matvec.pyx | 184 + mthree/mitigation.py | 504 + mthree/norms.py | 179 + mthree/probability.pyx | 44 + mthree/test/__init__.py | 11 + mthree/test/column_testing.pyx | 46 + mthree/test/converters_testing.pyx | 71 + mthree/test/test_columns.py | 79 + mthree/test/test_converters.py | 63 + mthree/test/test_extra_cals.py | 87 + mthree/test/test_full.py | 373 + mthree/test/test_matvec.py | 57 + mthree/test/test_methods.py | 69 + mthree/test/test_probability.py | 29 + mthree/test/test_quasi_attr.py | 59 + mthree/test/test_reduced_matrix.py | 364 + mthree/test/test_sdd.py | 91 + mthree/test/test_sim.py | 37 + mthree/utils.py | 52 + requirements-dev.txt | 10 + requirements.txt | 6 + setup.py | 226 + 53 files changed, 18193 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/python-package-conda.yml create mode 100644 .gitignore rename LICENSE => LICENSE.txt (99%) create mode 100644 README.md create mode 100644 docs/Makefile create mode 100644 docs/_static/custom.css create mode 100644 docs/_static/gallery.css create mode 100644 docs/_static/style.css create mode 100644 docs/_static/theme.css create mode 100644 docs/_templates/autosummary/class.rst create mode 100644 docs/_templates/layout.html create mode 100644 docs/_templates/theme_variables.jinja create mode 100644 docs/_templates/versions.html create mode 100644 docs/apidocs/main.rst create mode 100644 docs/conf.py create mode 100644 docs/images/truncation.png create mode 100644 docs/index.rst create mode 100644 examples/30Q_GHZ_Manhattan.ipynb create mode 100644 examples/M3_paper_example1.ipynb create mode 100644 examples/correcting_for_probabilities.ipynb create mode 100644 examples/m3_x8_stabilizer_example.ipynb create mode 100644 mthree/__init__.py create mode 100644 mthree/classes.py create mode 100644 mthree/compute.pxd create mode 100644 mthree/compute.pyx create mode 100644 mthree/converters.pxd create mode 100644 mthree/converters.pyx create mode 100644 mthree/exceptions.py create mode 100644 mthree/expval.pyx create mode 100644 mthree/hamming.pyx create mode 100644 mthree/matrix.pyx create mode 100644 mthree/matvec.pyx create mode 100644 mthree/mitigation.py create mode 100644 mthree/norms.py create mode 100644 mthree/probability.pyx create mode 100644 mthree/test/__init__.py create mode 100644 mthree/test/column_testing.pyx create mode 100644 mthree/test/converters_testing.pyx create mode 100644 mthree/test/test_columns.py create mode 100644 mthree/test/test_converters.py create mode 100644 mthree/test/test_extra_cals.py create mode 100644 mthree/test/test_full.py create mode 100644 mthree/test/test_matvec.py create mode 100644 mthree/test/test_methods.py create mode 100644 mthree/test/test_probability.py create mode 100644 mthree/test/test_quasi_attr.py create mode 100644 mthree/test/test_reduced_matrix.py create mode 100644 mthree/test/test_sdd.py create mode 100644 mthree/test/test_sim.py create mode 100644 mthree/utils.py create mode 100644 requirements-dev.txt create mode 100644 requirements.txt create mode 100644 setup.py diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml new file mode 100644 index 00000000..67e8bdd3 --- /dev/null +++ b/.github/workflows/python-package-conda.yml @@ -0,0 +1,34 @@ +name: Mthree using Conda + +on: [push] + +jobs: + build-linux: + runs-on: ubuntu-latest + strategy: + max-parallel: 5 + + steps: + - uses: actions/checkout@v2 + - name: Set up Python 3.9 + uses: actions/setup-python@v2 + with: + python-version: 3.9 + - name: Add conda to system path + run: | + # $CONDA is an environment variable pointing to the root of the miniconda directory + echo $CONDA/bin >> $GITHUB_PATH + - name: Install dependencies + run: | + conda config --set always_yes yes --set changeps1 no + pip install -U -r requirements.txt + python setup.py install + - name: Lint with pylint and pycodestyle + run: | + pip install -U -r requirements-dev.txt + pylint -rn mthree + pycodestyle --max-line-length=100 mthree + - name: Test no-Qiskit with pytest + run: | + conda install pytest + pytest -p no:warnings --pyargs mthree/test diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..8e14e58a --- /dev/null +++ b/.gitignore @@ -0,0 +1,134 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ +.DS_Store +mthree/version.py +*.cpp + +docs/stubs/* diff --git a/LICENSE b/LICENSE.txt similarity index 99% rename from LICENSE rename to LICENSE.txt index 261eeb9e..5333c633 100644 --- a/LICENSE +++ b/LICENSE.txt @@ -1,3 +1,5 @@ + Copyright 2017 IBM and its contributors + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -186,7 +188,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2017 IBM and its contributors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md new file mode 100644 index 00000000..f62404a5 --- /dev/null +++ b/README.md @@ -0,0 +1,98 @@ +# mthree + +Matrix-free Measurement Mitigation (M3). + +M3 is a measurement mitigation technique that solves for corrected counts using a dimensionality reduction step followed by a simple iterative method that nominally converges in O(1) steps, and can be computed in parallel. For example, M3 can compute corrections on 30 qubit GHZ problems in under one second on a quad-core machine (depending on the number of unique bitstrings in the output). + +## Installation + +Currently M3 needs to be installed from source: + +```bash +python setup.py install +``` + +To enable openmp one must have an openmp enabled compiler and install with: + +```bash +python setup.py install --with-openmp +``` + +Optionally one can also set `-march=native` using: + +```bash +python setup.py install --with-native +``` + +The `openmp` and `native` flags can be used simultaneously using a comma. + +### OpenMP on OSX + +On OSX one must install LLVM using homebrew (You cannot use GCC): + +```bash +brew install llvm +``` + +after which the following (or the like) must be executed in the terminal: + +```bash +export PATH="/usr/local/opt/llvm/bin:$PATH" +``` + +and + +```bash +export LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib" +export CPPFLAGS="-I/usr/local/opt/llvm/include" +``` + +Then installation with openmp can be accomplished using: + +```bash +CC=clang CXX=clang python setup.py install --with-openmp +``` + +## Usage + +M3 is simple to use: + +```python +import mthree +# Specify a mitigator object targeting a given backend +mit = mthree.M3Mitigation(backend) + +# Compute the tensored 1Q calibration matrices for the given qubits and given number of shots +# By default it is over all backend qubits at 8192 shots. +mit.tensored_cals_from_system(qubits, shots) + +# Apply mitigation to a given dict of raw counts over the specified qubits +m3_quasi = mit.apply_correction(raw_counts, qubits) +``` +Note that here `qubits` is a list of which qubits are measured to yield the bits in the output. +For example the list `[4,3,1,2,0]` indicates that a measurement on physical qubit 4 was written to +classical bit zero in the output bit-strings, physical qubit 3 maps to classical bit 1, etc. +The fact that the zeroth bit is right-most in the bitstring is handled internally. + +The results of M3 mitigation are quasi-probabilities that contain small negative values. +This is suitable for use in computing corrected expectation values. However, if one needs +a true probability distribution then it is possible to convert from quasi-probabilites to +the closest true probability distribution in L2-norm using: + +```python +closest_probs = m3_quasi.nearest_probability_distribution() +``` + +An additional benefit of the way M3 works is that it is possible to compute the effect of mitigation when only +looking at errors that are up to a given Hamming distance away. This slightly increases the computational cost, but +allows for investigating if large weight errors have much impact on the output. This can be controlled by the `distance` keyword argument in `apply_correction`: + +```python +m3_quasi = mit.apply_correction(raw_counts, qubits, distance=DIST) +``` +By default, M3 computes errors out to the full distance. + +## License + +(C) Copyright IBM Quantum 2021. +This code is for internal IBM Quantum use only. diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000..308f755d --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,28 @@ +# This code is part of Kaleidoscope +# +# (C) Copyright IBM 2020. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/_static/custom.css b/docs/_static/custom.css new file mode 100644 index 00000000..3f981b65 --- /dev/null +++ b/docs/_static/custom.css @@ -0,0 +1,27 @@ +.toggle .header { + display: block; + clear: both; + background-color: #785EF0; + color: #f9f9f9; + height: 40px; + padding-top: 10px; + padding-left: 5px; + margin-bottom: 20px; +} + +.toggle .header:before { + float: left; + content: "▶ "; + font-size: 20px; + +} + +.toggle .header.open:before { + float: left; + content: "▼ "; + font-size: 20px; +} + +.toggle{ + background: #FBFBFB; +} diff --git a/docs/_static/gallery.css b/docs/_static/gallery.css new file mode 100644 index 00000000..a89b176b --- /dev/null +++ b/docs/_static/gallery.css @@ -0,0 +1,195 @@ +/* +Sphinx-Gallery has compatible CSS to fix default sphinx themes +Tested for Sphinx 1.3.1 for all themes: default, alabaster, sphinxdoc, +scrolls, agogo, traditional, nature, haiku, pyramid +Tested for Read the Docs theme 0.1.7 */ +.sphx-glr-thumbcontainer { + background: #fff; + border: solid #fff 1px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + box-shadow: none; + float: left; + margin: 5px; + min-height: 230px; + padding-top: 5px; + position: relative; +} +.sphx-glr-thumbcontainer:hover { + border: solid #fb8122 1px; + box-shadow: 0 0 15px rgba(163, 142, 202, 0.5); +} +.sphx-glr-thumbcontainer a.internal { + bottom: 0; + display: block; + left: 0; + padding: 150px 10px 0; + position: absolute; + right: 0; + top: 0; +} +/* Next one is to avoid Sphinx traditional theme to cover all the +thumbnail with its default link Background color */ +.sphx-glr-thumbcontainer a.internal:hover { + background-color: transparent; +} + +.sphx-glr-thumbcontainer p { + margin: 0 0 .1em 0; +} +.sphx-glr-thumbcontainer .figure { + margin: 10px; + width: 160px; +} +.sphx-glr-thumbcontainer img { + display: inline; + max-height: 112px; + max-width: 160px; +} +.sphx-glr-thumbcontainer[tooltip]:hover:after { + background: rgba(0, 0, 0, 0.8); + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + color: #fff; + content: attr(tooltip); + left: 95%; + padding: 5px 15px; + position: absolute; + z-index: 98; + width: 220px; + bottom: 52%; +} +.sphx-glr-thumbcontainer[tooltip]:hover:before { + border: solid; + border-color: #333 transparent; + border-width: 18px 0 0 20px; + bottom: 58%; + content: ''; + left: 85%; + position: absolute; + z-index: 99; +} + +.sphx-glr-script-out { + color: #888; + margin: 0; +} +p.sphx-glr-script-out { + padding-top: 0.7em; +} +.sphx-glr-script-out .highlight { + background-color: transparent; + margin-left: 2.5em; + margin-top: -2.1em; +} +.sphx-glr-script-out .highlight pre { + background-color: #fafae2; + border: 0; + max-height: 30em; + overflow: auto; + padding-left: 1ex; + margin: 0px; + word-break: break-word; +} +.sphx-glr-script-out + p { + margin-top: 1.8em; +} +blockquote.sphx-glr-script-out { + margin-left: 0pt; +} +.sphx-glr-script-out.highlight-pytb .highlight pre { + color: #000; + background-color: #ffe4e4; + border: 1px solid #f66; + margin-top: 10px; + padding: 7px; +} + +div.sphx-glr-footer { + text-align: center; +} + +div.sphx-glr-download { + margin: 1em auto; + vertical-align: middle; +} + +div.sphx-glr-download a { + background-color: #ffc; + background-image: linear-gradient(to bottom, #FFC, #d5d57e); + border-radius: 4px; + border: 1px solid #c2c22d; + color: #000; + display: inline-block; + font-weight: bold; + padding: 1ex; + text-align: center; +} + +div.sphx-glr-download code.download { + display: inline-block; + white-space: normal; + word-break: normal; + overflow-wrap: break-word; + /* border and background are given by the enclosing 'a' */ + border: none; + background: none; +} + +div.sphx-glr-download a:hover { + box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 5px rgba(0,0,0,.25); + text-decoration: none; + background-image: none; + background-color: #d5d57e; +} + +.sphx-glr-example-title > :target::before { + display: block; + content: ""; + margin-top: -50px; + height: 50px; + visibility: hidden; +} + +ul.sphx-glr-horizontal { + list-style: none; + padding: 0; +} +ul.sphx-glr-horizontal li { + display: inline; +} +ul.sphx-glr-horizontal img { + height: auto !important; +} + +.sphx-glr-single-img { + margin: auto; + display: block; + max-width: 100%; +} + +.sphx-glr-multi-img { + max-width: 42%; + height: auto; +} + +p.sphx-glr-signature a.reference.external { + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + padding: 3px; + font-size: 75%; + text-align: right; + margin-left: auto; + display: table; +} + +.sphx-glr-clear{ + clear: both; +} + +a.sphx-glr-backref-instance { + text-decoration: none; +} diff --git a/docs/_static/style.css b/docs/_static/style.css new file mode 100644 index 00000000..9817a3ef --- /dev/null +++ b/docs/_static/style.css @@ -0,0 +1,12 @@ +.wy-nav-content { + max-width: 90% !important; +} + +.wy-side-scroll { + background:#f1f2f1; +} + +.pre +{ +color:#BE8184; +} diff --git a/docs/_static/theme.css b/docs/_static/theme.css new file mode 100644 index 00000000..33a6ad3a --- /dev/null +++ b/docs/_static/theme.css @@ -0,0 +1,12285 @@ +@charset "UTF-8"; +/*! + * Bootstrap v4.0.0 (https://getbootstrap.com) + * Copyright 2011-2018 The Bootstrap Authors + * Copyright 2011-2018 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +:root { + --blue: #007bff; + --indigo: #6610f2; + --purple: #6f42c1; + --pink: #e83e8c; + --red: #dc3545; + --orange: #fb8122; + --yellow: #ffc107; + --green: #28a745; + --teal: #20c997; + --cyan: #17a2b8; + --white: #fff; + --gray: #6c757d; + --gray-dark: #343a40; + --primary: #007bff; + --secondary: #6c757d; + --success: #28a745; + --info: #17a2b8; + --warning: #ffc107; + --danger: #dc3545; + --light: #f8f9fa; + --dark: #343a40; + --breakpoint-xs: 0; + --breakpoint-sm: 576px; + --breakpoint-md: 768px; + --breakpoint-lg: 992px; + --breakpoint-xl: 1200px; + --font-family-sans-serif: "IBM Plex Sans", "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + --font-family-monospace: "IBM Plex Mono", SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +*, +*::before, +*::after { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +html { + font-family: "IBM Plex Sans", sans-serif; + line-height: 1.15; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + -ms-overflow-style: scrollbar; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +@-ms-viewport { + width: device-width; +} +article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section { + display: block; +} + +body { + margin: 0; + font-family: "IBM Plex Sans", "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: left; + background-color: #fff; +} + +[tabindex="-1"]:focus { + outline: 0 !important; +} + +hr { + -webkit-box-sizing: content-box; + box-sizing: content-box; + height: 0; + overflow: visible; +} + +h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: 0.5rem; +} + +p { + margin-top: 0; + margin-bottom: 1rem; +} + +abbr[title], +abbr[data-original-title] { + text-decoration: underline; + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + cursor: help; + border-bottom: 0; +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit; +} + +ol, +ul, +dl { + margin-top: 0; + margin-bottom: 1rem; +} + +ol ol, +ul ul, +ol ul, +ul ol { + margin-bottom: 0; +} + +dt { + font-weight: 700; +} + +dd { + margin-bottom: .5rem; + margin-left: 0; +} + +blockquote { + margin: 0 0 1rem; +} + +dfn { + font-style: italic; +} + +b, +strong { + font-weight: bolder; +} + +small { + font-size: 80%; +} + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} + +sub { + bottom: -.25em; +} + +sup { + top: -.5em; +} + +a { + color: #007bff; + text-decoration: none; + background-color: transparent; + -webkit-text-decoration-skip: objects; +} +a:hover { + color: #0056b3; + text-decoration: underline; +} + +a:not([href]):not([tabindex]) { + color: inherit; + text-decoration: none; +} +a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus { + color: inherit; + text-decoration: none; +} +a:not([href]):not([tabindex]):focus { + outline: 0; +} + +pre, +code, +kbd, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +pre { + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; + -ms-overflow-style: scrollbar; +} + +figure { + margin: 0 0 1rem; +} + +img { + vertical-align: middle; + border-style: none; +} + +svg:not(:root) { + overflow: hidden; +} + +table { + border-collapse: collapse; +} + +caption { + padding-top: 0.75rem; + padding-bottom: 0.75rem; + color: #6c757d; + text-align: left; + caption-side: bottom; +} + +th { + text-align: inherit; +} + +label { + display: inline-block; + margin-bottom: .5rem; +} + +button { + border-radius: 0; +} + +button:focus { + outline: 1px dotted; + outline: 5px auto -webkit-focus-ring-color; +} + +input, +button, +select, +optgroup, +textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +button, +input { + overflow: visible; +} + +button, +select { + text-transform: none; +} + +button, +html [type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + padding: 0; + border-style: none; +} + +input[type="radio"], +input[type="checkbox"] { + -webkit-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} + +input[type="date"], +input[type="time"], +input[type="datetime-local"], +input[type="month"] { + -webkit-appearance: listbox; +} + +textarea { + overflow: auto; + resize: vertical; +} + +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} + +legend { + display: block; + width: 100%; + max-width: 100%; + padding: 0; + margin-bottom: .5rem; + font-size: 1.5rem; + line-height: inherit; + color: inherit; + white-space: normal; +} + +progress { + vertical-align: baseline; +} + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +[type="search"] { + outline-offset: -2px; + -webkit-appearance: none; +} + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-file-upload-button { + font: inherit; + -webkit-appearance: button; +} + +output { + display: inline-block; +} + +summary { + display: list-item; + cursor: pointer; +} + +template { + display: none; +} + +[hidden] { + display: none !important; +} + +h1, h2, h3, h4, h5, h6, +.h1, .h2, .h3, .h4, .h5, .h6 { + margin-bottom: 0.5rem; + font-family: inherit; + font-weight: 500; + line-height: 1.2; + color: inherit; +} + +h1, .h1 { + font-size: 2.5rem; +} + +h2, .h2 { + font-size: 2rem; +} + +h3, .h3 { + font-size: 1.75rem; +} + +h4, .h4 { + font-size: 1.5rem; +} + +h5, .h5 { + font-size: 1.25rem; +} + +h6, .h6 { + font-size: 1rem; +} + +.lead { + font-size: 1.25rem; + font-weight: 300; +} + +.display-1 { + font-size: 6rem; + font-weight: 300; + line-height: 1.2; +} + +.display-2 { + font-size: 5.5rem; + font-weight: 300; + line-height: 1.2; +} + +.display-3 { + font-size: 4.5rem; + font-weight: 300; + line-height: 1.2; +} + +.display-4 { + font-size: 3.5rem; + font-weight: 300; + line-height: 1.2; +} + +hr { + margin-top: 1rem; + margin-bottom: 1rem; + border: 0; + border-top: 1px solid rgba(0, 0, 0, 0.1); +} + +small, +.small { + font-size: 80%; + font-weight: 400; +} + +mark, +.mark { + padding: 0.2em; + background-color: #fcf8e3; +} + +.list-unstyled { + padding-left: 0; + list-style: none; +} + +.list-inline { + padding-left: 0; + list-style: none; +} + +.list-inline-item { + display: inline-block; +} +.list-inline-item:not(:last-child) { + margin-right: 0.5rem; +} + +.initialism { + font-size: 90%; + text-transform: uppercase; +} + +.blockquote { + margin-bottom: 1rem; + font-size: 1.25rem; +} + +.blockquote-footer { + display: block; + font-size: 80%; + color: #6c757d; +} +.blockquote-footer::before { + content: "\2014 \00A0"; +} + +.img-fluid { + max-width: 100%; + height: auto; +} + +.img-thumbnail { + padding: 0.25rem; + background-color: #fff; + border: 1px solid #dee2e6; + border-radius: 0.25rem; + max-width: 100%; + height: auto; +} + +.figure { + display: inline-block; +} + +.figure-img { + margin-bottom: 0.5rem; + line-height: 1; +} + +.figure-caption { + font-size: 90%; + color: #6c757d; +} + +code, +kbd, +pre, +samp { + font-family: "IBM Plex Mono", SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +code { + font-size: 87.5%; + color: #e83e8c; + word-break: break-word; +} +a > code { + color: inherit; +} + +kbd { + padding: 0.2rem 0.4rem; + font-size: 87.5%; + color: #fff; + background-color: #212529; + border-radius: 0.2rem; +} +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: 700; +} + +pre { + display: block; + font-size: 87.5%; + color: #212529; +} +pre code { + font-size: inherit; + color: inherit; + word-break: normal; +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} + +.container { + width: 100%; + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +@media (min-width: 576px) { + .container { + max-width: 540px; + } +} +@media (min-width: 768px) { + .container { + max-width: 720px; + } +} +@media (min-width: 992px) { + .container { + max-width: 960px; + } +} +@media (min-width: 1200px) { + .container { + max-width: 1140px; + } +} + +.container-fluid { + width: 100%; + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} + +.row { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin-right: -15px; + margin-left: -15px; +} + +.no-gutters { + margin-right: 0; + margin-left: 0; +} +.no-gutters > .col, +.no-gutters > [class*="col-"] { + padding-right: 0; + padding-left: 0; +} + +.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col, +.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm, +.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md, +.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg, +.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl, +.col-xl-auto { + position: relative; + width: 100%; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} + +.col { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; +} + +.col-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; +} + +.col-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.3333333333%; + flex: 0 0 8.3333333333%; + max-width: 8.3333333333%; +} + +.col-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.6666666667%; + flex: 0 0 16.6666666667%; + max-width: 16.6666666667%; +} + +.col-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; +} + +.col-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.3333333333%; + flex: 0 0 33.3333333333%; + max-width: 33.3333333333%; +} + +.col-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.6666666667%; + flex: 0 0 41.6666666667%; + max-width: 41.6666666667%; +} + +.col-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; +} + +.col-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.3333333333%; + flex: 0 0 58.3333333333%; + max-width: 58.3333333333%; +} + +.col-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.6666666667%; + flex: 0 0 66.6666666667%; + max-width: 66.6666666667%; +} + +.col-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; +} + +.col-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.3333333333%; + flex: 0 0 83.3333333333%; + max-width: 83.3333333333%; +} + +.col-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.6666666667%; + flex: 0 0 91.6666666667%; + max-width: 91.6666666667%; +} + +.col-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; +} + +.order-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; +} + +.order-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; +} + +.order-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; +} + +.order-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; +} + +.order-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; +} + +.order-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; +} + +.order-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; +} + +.order-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; +} + +.order-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; +} + +.order-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; +} + +.order-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; +} + +.order-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; +} + +.order-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; +} + +.order-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; +} + +.order-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; +} + +.offset-1 { + margin-left: 8.3333333333%; +} + +.offset-2 { + margin-left: 16.6666666667%; +} + +.offset-3 { + margin-left: 25%; +} + +.offset-4 { + margin-left: 33.3333333333%; +} + +.offset-5 { + margin-left: 41.6666666667%; +} + +.offset-6 { + margin-left: 50%; +} + +.offset-7 { + margin-left: 58.3333333333%; +} + +.offset-8 { + margin-left: 66.6666666667%; +} + +.offset-9 { + margin-left: 75%; +} + +.offset-10 { + margin-left: 83.3333333333%; +} + +.offset-11 { + margin-left: 91.6666666667%; +} + +@media (min-width: 576px) { + .col-sm { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + + .col-sm-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + + .col-sm-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.3333333333%; + flex: 0 0 8.3333333333%; + max-width: 8.3333333333%; + } + + .col-sm-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.6666666667%; + flex: 0 0 16.6666666667%; + max-width: 16.6666666667%; + } + + .col-sm-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + + .col-sm-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.3333333333%; + flex: 0 0 33.3333333333%; + max-width: 33.3333333333%; + } + + .col-sm-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.6666666667%; + flex: 0 0 41.6666666667%; + max-width: 41.6666666667%; + } + + .col-sm-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + + .col-sm-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.3333333333%; + flex: 0 0 58.3333333333%; + max-width: 58.3333333333%; + } + + .col-sm-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.6666666667%; + flex: 0 0 66.6666666667%; + max-width: 66.6666666667%; + } + + .col-sm-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + + .col-sm-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.3333333333%; + flex: 0 0 83.3333333333%; + max-width: 83.3333333333%; + } + + .col-sm-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.6666666667%; + flex: 0 0 91.6666666667%; + max-width: 91.6666666667%; + } + + .col-sm-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + + .order-sm-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + } + + .order-sm-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; + } + + .order-sm-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; + } + + .order-sm-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } + + .order-sm-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + } + + .order-sm-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; + } + + .order-sm-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; + } + + .order-sm-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; + } + + .order-sm-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; + } + + .order-sm-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; + } + + .order-sm-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; + } + + .order-sm-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; + } + + .order-sm-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; + } + + .order-sm-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; + } + + .order-sm-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; + } + + .offset-sm-0 { + margin-left: 0; + } + + .offset-sm-1 { + margin-left: 8.3333333333%; + } + + .offset-sm-2 { + margin-left: 16.6666666667%; + } + + .offset-sm-3 { + margin-left: 25%; + } + + .offset-sm-4 { + margin-left: 33.3333333333%; + } + + .offset-sm-5 { + margin-left: 41.6666666667%; + } + + .offset-sm-6 { + margin-left: 50%; + } + + .offset-sm-7 { + margin-left: 58.3333333333%; + } + + .offset-sm-8 { + margin-left: 66.6666666667%; + } + + .offset-sm-9 { + margin-left: 75%; + } + + .offset-sm-10 { + margin-left: 83.3333333333%; + } + + .offset-sm-11 { + margin-left: 91.6666666667%; + } +} +@media (min-width: 768px) { + .col-md { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + + .col-md-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + + .col-md-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.3333333333%; + flex: 0 0 8.3333333333%; + max-width: 8.3333333333%; + } + + .col-md-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.6666666667%; + flex: 0 0 16.6666666667%; + max-width: 16.6666666667%; + } + + .col-md-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + + .col-md-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.3333333333%; + flex: 0 0 33.3333333333%; + max-width: 33.3333333333%; + } + + .col-md-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.6666666667%; + flex: 0 0 41.6666666667%; + max-width: 41.6666666667%; + } + + .col-md-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + + .col-md-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.3333333333%; + flex: 0 0 58.3333333333%; + max-width: 58.3333333333%; + } + + .col-md-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.6666666667%; + flex: 0 0 66.6666666667%; + max-width: 66.6666666667%; + } + + .col-md-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + + .col-md-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.3333333333%; + flex: 0 0 83.3333333333%; + max-width: 83.3333333333%; + } + + .col-md-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.6666666667%; + flex: 0 0 91.6666666667%; + max-width: 91.6666666667%; + } + + .col-md-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + + .order-md-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + } + + .order-md-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; + } + + .order-md-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; + } + + .order-md-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } + + .order-md-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + } + + .order-md-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; + } + + .order-md-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; + } + + .order-md-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; + } + + .order-md-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; + } + + .order-md-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; + } + + .order-md-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; + } + + .order-md-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; + } + + .order-md-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; + } + + .order-md-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; + } + + .order-md-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; + } + + .offset-md-0 { + margin-left: 0; + } + + .offset-md-1 { + margin-left: 8.3333333333%; + } + + .offset-md-2 { + margin-left: 16.6666666667%; + } + + .offset-md-3 { + margin-left: 25%; + } + + .offset-md-4 { + margin-left: 33.3333333333%; + } + + .offset-md-5 { + margin-left: 41.6666666667%; + } + + .offset-md-6 { + margin-left: 50%; + } + + .offset-md-7 { + margin-left: 58.3333333333%; + } + + .offset-md-8 { + margin-left: 66.6666666667%; + } + + .offset-md-9 { + margin-left: 75%; + } + + .offset-md-10 { + margin-left: 83.3333333333%; + } + + .offset-md-11 { + margin-left: 91.6666666667%; + } +} +@media (min-width: 992px) { + .col-lg { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + + .col-lg-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + + .col-lg-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.3333333333%; + flex: 0 0 8.3333333333%; + max-width: 8.3333333333%; + } + + .col-lg-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.6666666667%; + flex: 0 0 16.6666666667%; + max-width: 16.6666666667%; + } + + .col-lg-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + + .col-lg-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.3333333333%; + flex: 0 0 33.3333333333%; + max-width: 33.3333333333%; + } + + .col-lg-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.6666666667%; + flex: 0 0 41.6666666667%; + max-width: 41.6666666667%; + } + + .col-lg-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + + .col-lg-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.3333333333%; + flex: 0 0 58.3333333333%; + max-width: 58.3333333333%; + } + + .col-lg-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.6666666667%; + flex: 0 0 66.6666666667%; + max-width: 66.6666666667%; + } + + .col-lg-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + + .col-lg-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.3333333333%; + flex: 0 0 83.3333333333%; + max-width: 83.3333333333%; + } + + .col-lg-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.6666666667%; + flex: 0 0 91.6666666667%; + max-width: 91.6666666667%; + } + + .col-lg-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + + .order-lg-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + } + + .order-lg-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; + } + + .order-lg-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; + } + + .order-lg-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } + + .order-lg-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + } + + .order-lg-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; + } + + .order-lg-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; + } + + .order-lg-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; + } + + .order-lg-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; + } + + .order-lg-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; + } + + .order-lg-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; + } + + .order-lg-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; + } + + .order-lg-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; + } + + .order-lg-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; + } + + .order-lg-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; + } + + .offset-lg-0 { + margin-left: 0; + } + + .offset-lg-1 { + margin-left: 8.3333333333%; + } + + .offset-lg-2 { + margin-left: 16.6666666667%; + } + + .offset-lg-3 { + margin-left: 25%; + } + + .offset-lg-4 { + margin-left: 33.3333333333%; + } + + .offset-lg-5 { + margin-left: 41.6666666667%; + } + + .offset-lg-6 { + margin-left: 50%; + } + + .offset-lg-7 { + margin-left: 58.3333333333%; + } + + .offset-lg-8 { + margin-left: 66.6666666667%; + } + + .offset-lg-9 { + margin-left: 75%; + } + + .offset-lg-10 { + margin-left: 83.3333333333%; + } + + .offset-lg-11 { + margin-left: 91.6666666667%; + } +} +@media (min-width: 1200px) { + .col-xl { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + + .col-xl-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + + .col-xl-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.3333333333%; + flex: 0 0 8.3333333333%; + max-width: 8.3333333333%; + } + + .col-xl-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.6666666667%; + flex: 0 0 16.6666666667%; + max-width: 16.6666666667%; + } + + .col-xl-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + + .col-xl-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.3333333333%; + flex: 0 0 33.3333333333%; + max-width: 33.3333333333%; + } + + .col-xl-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.6666666667%; + flex: 0 0 41.6666666667%; + max-width: 41.6666666667%; + } + + .col-xl-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + + .col-xl-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.3333333333%; + flex: 0 0 58.3333333333%; + max-width: 58.3333333333%; + } + + .col-xl-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.6666666667%; + flex: 0 0 66.6666666667%; + max-width: 66.6666666667%; + } + + .col-xl-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + + .col-xl-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.3333333333%; + flex: 0 0 83.3333333333%; + max-width: 83.3333333333%; + } + + .col-xl-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.6666666667%; + flex: 0 0 91.6666666667%; + max-width: 91.6666666667%; + } + + .col-xl-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + + .order-xl-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + } + + .order-xl-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; + } + + .order-xl-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; + } + + .order-xl-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } + + .order-xl-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + } + + .order-xl-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; + } + + .order-xl-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; + } + + .order-xl-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; + } + + .order-xl-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; + } + + .order-xl-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; + } + + .order-xl-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; + } + + .order-xl-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; + } + + .order-xl-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; + } + + .order-xl-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; + } + + .order-xl-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; + } + + .offset-xl-0 { + margin-left: 0; + } + + .offset-xl-1 { + margin-left: 8.3333333333%; + } + + .offset-xl-2 { + margin-left: 16.6666666667%; + } + + .offset-xl-3 { + margin-left: 25%; + } + + .offset-xl-4 { + margin-left: 33.3333333333%; + } + + .offset-xl-5 { + margin-left: 41.6666666667%; + } + + .offset-xl-6 { + margin-left: 50%; + } + + .offset-xl-7 { + margin-left: 58.3333333333%; + } + + .offset-xl-8 { + margin-left: 66.6666666667%; + } + + .offset-xl-9 { + margin-left: 75%; + } + + .offset-xl-10 { + margin-left: 83.3333333333%; + } + + .offset-xl-11 { + margin-left: 91.6666666667%; + } +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 1rem; + background-color: transparent; +} +.table th, +.table td { + padding: 0.75rem; + vertical-align: top; + border-top: 1px solid #dee2e6; +} +.table thead th { + vertical-align: bottom; + border-bottom: 2px solid #dee2e6; +} +.table tbody + tbody { + border-top: 2px solid #dee2e6; +} +.table .table { + background-color: #fff; +} + +.table-sm th, +.table-sm td { + padding: 0.3rem; +} + +.table-bordered { + border: 1px solid #dee2e6; +} +.table-bordered th, +.table-bordered td { + border: 1px solid #dee2e6; +} +.table-bordered thead th, +.table-bordered thead td { + border-bottom-width: 2px; +} + +.table-striped tbody tr:nth-of-type(odd) { + background-color: rgba(0, 0, 0, 0.05); +} + +.table-hover tbody tr:hover { + background-color: rgba(0, 0, 0, 0.075); +} + +.table-primary, +.table-primary > th, +.table-primary > td { + background-color: #b8daff; +} + +.table-hover .table-primary:hover { + background-color: #9fcdff; +} +.table-hover .table-primary:hover > td, +.table-hover .table-primary:hover > th { + background-color: #9fcdff; +} + +.table-secondary, +.table-secondary > th, +.table-secondary > td { + background-color: #d6d8db; +} + +.table-hover .table-secondary:hover { + background-color: #c8cbcf; +} +.table-hover .table-secondary:hover > td, +.table-hover .table-secondary:hover > th { + background-color: #c8cbcf; +} + +.table-success, +.table-success > th, +.table-success > td { + background-color: #c3e6cb; +} + +.table-hover .table-success:hover { + background-color: #b1dfbb; +} +.table-hover .table-success:hover > td, +.table-hover .table-success:hover > th { + background-color: #b1dfbb; +} + +.table-info, +.table-info > th, +.table-info > td { + background-color: #bee5eb; +} + +.table-hover .table-info:hover { + background-color: #abdde5; +} +.table-hover .table-info:hover > td, +.table-hover .table-info:hover > th { + background-color: #abdde5; +} + +.table-warning, +.table-warning > th, +.table-warning > td { + background-color: #ffeeba; +} + +.table-hover .table-warning:hover { + background-color: #ffe8a1; +} +.table-hover .table-warning:hover > td, +.table-hover .table-warning:hover > th { + background-color: #ffe8a1; +} + +.table-danger, +.table-danger > th, +.table-danger > td { + background-color: #f5c6cb; +} + +.table-hover .table-danger:hover { + background-color: #f1b0b7; +} +.table-hover .table-danger:hover > td, +.table-hover .table-danger:hover > th { + background-color: #f1b0b7; +} + +.table-light, +.table-light > th, +.table-light > td { + background-color: #fdfdfe; +} + +.table-hover .table-light:hover { + background-color: #ececf6; +} +.table-hover .table-light:hover > td, +.table-hover .table-light:hover > th { + background-color: #ececf6; +} + +.table-dark, +.table-dark > th, +.table-dark > td { + background-color: #c6c8ca; +} + +.table-hover .table-dark:hover { + background-color: #b9bbbe; +} +.table-hover .table-dark:hover > td, +.table-hover .table-dark:hover > th { + background-color: #b9bbbe; +} + +.table-active, +.table-active > th, +.table-active > td { + background-color: rgba(0, 0, 0, 0.075); +} + +.table-hover .table-active:hover { + background-color: rgba(0, 0, 0, 0.075); +} +.table-hover .table-active:hover > td, +.table-hover .table-active:hover > th { + background-color: rgba(0, 0, 0, 0.075); +} + +.table .thead-dark th { + color: #fff; + background-color: #212529; + border-color: #32383e; +} +.table .thead-light th { + color: #495057; + background-color: #e9ecef; + border-color: #dee2e6; +} + +.table-dark { + color: #fff; + background-color: #212529; +} +.table-dark th, +.table-dark td, +.table-dark thead th { + border-color: #32383e; +} +.table-dark.table-bordered { + border: 0; +} +.table-dark.table-striped tbody tr:nth-of-type(odd) { + background-color: rgba(255, 255, 255, 0.05); +} +.table-dark.table-hover tbody tr:hover { + background-color: rgba(255, 255, 255, 0.075); +} + +@media (max-width: 575.98px) { + .table-responsive-sm { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } + .table-responsive-sm > .table-bordered { + border: 0; + } +} +@media (max-width: 767.98px) { + .table-responsive-md { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } + .table-responsive-md > .table-bordered { + border: 0; + } +} +@media (max-width: 991.98px) { + .table-responsive-lg { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } + .table-responsive-lg > .table-bordered { + border: 0; + } +} +@media (max-width: 1199.98px) { + .table-responsive-xl { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } + .table-responsive-xl > .table-bordered { + border: 0; + } +} +.table-responsive { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; +} +.table-responsive > .table-bordered { + border: 0; +} + +.form-control { + display: block; + width: 100%; + padding: 0.375rem 0.75rem; + font-size: 1rem; + line-height: 1.5; + color: #495057; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ced4da; + border-radius: 0.25rem; + -webkit-transition: border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out; + transition: border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out; +} +.form-control::-ms-expand { + background-color: transparent; + border: 0; +} +.form-control:focus { + color: #495057; + background-color: #fff; + border-color: #80bdff; + outline: 0; + -webkit-box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.form-control::-webkit-input-placeholder { + color: #6c757d; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #6c757d; + opacity: 1; +} +.form-control::-ms-input-placeholder { + color: #6c757d; + opacity: 1; +} +.form-control::placeholder { + color: #6c757d; + opacity: 1; +} +.form-control:disabled, .form-control[readonly] { + background-color: #e9ecef; + opacity: 1; +} + +select.form-control:not([size]):not([multiple]) { + height: calc(2.25rem + 2px); +} +select.form-control:focus::-ms-value { + color: #495057; + background-color: #fff; +} + +.form-control-file, +.form-control-range { + display: block; + width: 100%; +} + +.col-form-label { + padding-top: calc(0.375rem + 1px); + padding-bottom: calc(0.375rem + 1px); + margin-bottom: 0; + font-size: inherit; + line-height: 1.5; +} + +.col-form-label-lg { + padding-top: calc(0.5rem + 1px); + padding-bottom: calc(0.5rem + 1px); + font-size: 1.25rem; + line-height: 1.5; +} + +.col-form-label-sm { + padding-top: calc(0.25rem + 1px); + padding-bottom: calc(0.25rem + 1px); + font-size: 0.875rem; + line-height: 1.5; +} + +.form-control-plaintext { + display: block; + width: 100%; + padding-top: 0.375rem; + padding-bottom: 0.375rem; + margin-bottom: 0; + line-height: 1.5; + background-color: transparent; + border: solid transparent; + border-width: 1px 0; +} +.form-control-plaintext.form-control-sm, .input-group-sm > .form-control-plaintext.form-control, +.input-group-sm > .input-group-prepend > .form-control-plaintext.input-group-text, +.input-group-sm > .input-group-append > .form-control-plaintext.input-group-text, +.input-group-sm > .input-group-prepend > .form-control-plaintext.btn, +.input-group-sm > .input-group-append > .form-control-plaintext.btn, .form-control-plaintext.form-control-lg, .input-group-lg > .form-control-plaintext.form-control, +.input-group-lg > .input-group-prepend > .form-control-plaintext.input-group-text, +.input-group-lg > .input-group-append > .form-control-plaintext.input-group-text, +.input-group-lg > .input-group-prepend > .form-control-plaintext.btn, +.input-group-lg > .input-group-append > .form-control-plaintext.btn { + padding-right: 0; + padding-left: 0; +} + +.form-control-sm, .input-group-sm > .form-control, +.input-group-sm > .input-group-prepend > .input-group-text, +.input-group-sm > .input-group-append > .input-group-text, +.input-group-sm > .input-group-prepend > .btn, +.input-group-sm > .input-group-append > .btn { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.5; + border-radius: 0.2rem; +} + +select.form-control-sm:not([size]):not([multiple]), .input-group-sm > select.form-control:not([size]):not([multiple]), +.input-group-sm > .input-group-prepend > select.input-group-text:not([size]):not([multiple]), +.input-group-sm > .input-group-append > select.input-group-text:not([size]):not([multiple]), +.input-group-sm > .input-group-prepend > select.btn:not([size]):not([multiple]), +.input-group-sm > .input-group-append > select.btn:not([size]):not([multiple]) { + height: calc(1.8125rem + 2px); +} + +.form-control-lg, .input-group-lg > .form-control, +.input-group-lg > .input-group-prepend > .input-group-text, +.input-group-lg > .input-group-append > .input-group-text, +.input-group-lg > .input-group-prepend > .btn, +.input-group-lg > .input-group-append > .btn { + padding: 0.5rem 1rem; + font-size: 1.25rem; + line-height: 1.5; + border-radius: 0.3rem; +} + +select.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.form-control:not([size]):not([multiple]), +.input-group-lg > .input-group-prepend > select.input-group-text:not([size]):not([multiple]), +.input-group-lg > .input-group-append > select.input-group-text:not([size]):not([multiple]), +.input-group-lg > .input-group-prepend > select.btn:not([size]):not([multiple]), +.input-group-lg > .input-group-append > select.btn:not([size]):not([multiple]) { + height: calc(2.875rem + 2px); +} + +.form-group { + margin-bottom: 1rem; +} + +.form-text { + display: block; + margin-top: 0.25rem; +} + +.form-row { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin-right: -5px; + margin-left: -5px; +} +.form-row > .col, +.form-row > [class*="col-"] { + padding-right: 5px; + padding-left: 5px; +} + +.form-check { + position: relative; + display: block; + padding-left: 1.25rem; +} + +.form-check-input { + position: absolute; + margin-top: 0.3rem; + margin-left: -1.25rem; +} +.form-check-input:disabled ~ .form-check-label { + color: #6c757d; +} + +.form-check-label { + margin-bottom: 0; +} + +.form-check-inline { + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + padding-left: 0; + margin-right: 0.75rem; +} +.form-check-inline .form-check-input { + position: static; + margin-top: 0; + margin-right: 0.3125rem; + margin-left: 0; +} + +.valid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 80%; + color: #28a745; +} + +.valid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: .5rem; + margin-top: .1rem; + font-size: .875rem; + line-height: 1; + color: #fff; + background-color: rgba(40, 167, 69, 0.8); + border-radius: .2rem; +} + +.was-validated .form-control:valid, .form-control.is-valid, +.was-validated .custom-select:valid, +.custom-select.is-valid { + border-color: #28a745; +} +.was-validated .form-control:valid:focus, .form-control.is-valid:focus, +.was-validated .custom-select:valid:focus, +.custom-select.is-valid:focus { + border-color: #28a745; + -webkit-box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} +.was-validated .form-control:valid ~ .valid-feedback, +.was-validated .form-control:valid ~ .valid-tooltip, .form-control.is-valid ~ .valid-feedback, +.form-control.is-valid ~ .valid-tooltip, +.was-validated .custom-select:valid ~ .valid-feedback, +.was-validated .custom-select:valid ~ .valid-tooltip, +.custom-select.is-valid ~ .valid-feedback, +.custom-select.is-valid ~ .valid-tooltip { + display: block; +} + +.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label { + color: #28a745; +} +.was-validated .form-check-input:valid ~ .valid-feedback, +.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback, +.form-check-input.is-valid ~ .valid-tooltip { + display: block; +} + +.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label { + color: #28a745; +} +.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before { + background-color: #71dd8a; +} +.was-validated .custom-control-input:valid ~ .valid-feedback, +.was-validated .custom-control-input:valid ~ .valid-tooltip, .custom-control-input.is-valid ~ .valid-feedback, +.custom-control-input.is-valid ~ .valid-tooltip { + display: block; +} +.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before { + background-color: #34ce57; +} +.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before { + -webkit-box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(40, 167, 69, 0.25); + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} + +.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label { + border-color: #28a745; +} +.was-validated .custom-file-input:valid ~ .custom-file-label::before, .custom-file-input.is-valid ~ .custom-file-label::before { + border-color: inherit; +} +.was-validated .custom-file-input:valid ~ .valid-feedback, +.was-validated .custom-file-input:valid ~ .valid-tooltip, .custom-file-input.is-valid ~ .valid-feedback, +.custom-file-input.is-valid ~ .valid-tooltip { + display: block; +} +.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label { + -webkit-box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} + +.invalid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 80%; + color: #dc3545; +} + +.invalid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: .5rem; + margin-top: .1rem; + font-size: .875rem; + line-height: 1; + color: #fff; + background-color: rgba(220, 53, 69, 0.8); + border-radius: .2rem; +} + +.was-validated .form-control:invalid, .form-control.is-invalid, +.was-validated .custom-select:invalid, +.custom-select.is-invalid { + border-color: #dc3545; +} +.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus, +.was-validated .custom-select:invalid:focus, +.custom-select.is-invalid:focus { + border-color: #dc3545; + -webkit-box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} +.was-validated .form-control:invalid ~ .invalid-feedback, +.was-validated .form-control:invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback, +.form-control.is-invalid ~ .invalid-tooltip, +.was-validated .custom-select:invalid ~ .invalid-feedback, +.was-validated .custom-select:invalid ~ .invalid-tooltip, +.custom-select.is-invalid ~ .invalid-feedback, +.custom-select.is-invalid ~ .invalid-tooltip { + display: block; +} + +.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label { + color: #dc3545; +} +.was-validated .form-check-input:invalid ~ .invalid-feedback, +.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback, +.form-check-input.is-invalid ~ .invalid-tooltip { + display: block; +} + +.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label { + color: #dc3545; +} +.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before { + background-color: #efa2a9; +} +.was-validated .custom-control-input:invalid ~ .invalid-feedback, +.was-validated .custom-control-input:invalid ~ .invalid-tooltip, .custom-control-input.is-invalid ~ .invalid-feedback, +.custom-control-input.is-invalid ~ .invalid-tooltip { + display: block; +} +.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before { + background-color: #e4606d; +} +.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before { + -webkit-box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(220, 53, 69, 0.25); + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} + +.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label { + border-color: #dc3545; +} +.was-validated .custom-file-input:invalid ~ .custom-file-label::before, .custom-file-input.is-invalid ~ .custom-file-label::before { + border-color: inherit; +} +.was-validated .custom-file-input:invalid ~ .invalid-feedback, +.was-validated .custom-file-input:invalid ~ .invalid-tooltip, .custom-file-input.is-invalid ~ .invalid-feedback, +.custom-file-input.is-invalid ~ .invalid-tooltip { + display: block; +} +.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label { + -webkit-box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} + +.form-inline { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.form-inline .form-check { + width: 100%; +} +@media (min-width: 576px) { + .form-inline label { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + margin-bottom: 0; + } + .form-inline .form-group { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + margin-bottom: 0; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-plaintext { + display: inline-block; + } + .form-inline .input-group { + width: auto; + } + .form-inline .form-check { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + width: auto; + padding-left: 0; + } + .form-inline .form-check-input { + position: relative; + margin-top: 0; + margin-right: 0.25rem; + margin-left: 0; + } + .form-inline .custom-control { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + } + .form-inline .custom-control-label { + margin-bottom: 0; + } +} + +.btn { + display: inline-block; + font-weight: 400; + text-align: center; + white-space: nowrap; + vertical-align: middle; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + border: 1px solid transparent; + padding: 0.375rem 0.75rem; + font-size: 1rem; + line-height: 1.5; + border-radius: 0.25rem; + -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out; +} +.btn:hover, .btn:focus { + text-decoration: none; +} +.btn:focus, .btn.focus { + outline: 0; + -webkit-box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.btn.disabled, .btn:disabled { + opacity: 0.65; +} +.btn:not(:disabled):not(.disabled) { + cursor: pointer; +} +.btn:not(:disabled):not(.disabled):active, .btn:not(:disabled):not(.disabled).active { + background-image: none; +} + +a.btn.disabled, +fieldset:disabled a.btn { + pointer-events: none; +} + +.btn-primary { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} +.btn-primary:hover { + color: #fff; + background-color: #0069d9; + border-color: #0062cc; +} +.btn-primary:focus, .btn-primary.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} +.btn-primary.disabled, .btn-primary:disabled { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} +.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active, .show > .btn-primary.dropdown-toggle { + color: #fff; + background-color: #0062cc; + border-color: #005cbf; +} +.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus, .show > .btn-primary.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} + +.btn-secondary { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-secondary:hover { + color: #fff; + background-color: #5a6268; + border-color: #545b62; +} +.btn-secondary:focus, .btn-secondary.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} +.btn-secondary.disabled, .btn-secondary:disabled { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active, .show > .btn-secondary.dropdown-toggle { + color: #fff; + background-color: #545b62; + border-color: #4e555b; +} +.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus, .show > .btn-secondary.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} + +.btn-success { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} +.btn-success:hover { + color: #fff; + background-color: #218838; + border-color: #1e7e34; +} +.btn-success:focus, .btn-success.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} +.btn-success.disabled, .btn-success:disabled { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} +.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active, .show > .btn-success.dropdown-toggle { + color: #fff; + background-color: #1e7e34; + border-color: #1c7430; +} +.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus, .show > .btn-success.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} + +.btn-info { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} +.btn-info:hover { + color: #fff; + background-color: #138496; + border-color: #117a8b; +} +.btn-info:focus, .btn-info.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} +.btn-info.disabled, .btn-info:disabled { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} +.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active, .show > .btn-info.dropdown-toggle { + color: #fff; + background-color: #117a8b; + border-color: #10707f; +} +.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus, .show > .btn-info.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} + +.btn-warning { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-warning:hover { + color: #212529; + background-color: #e0a800; + border-color: #d39e00; +} +.btn-warning:focus, .btn-warning.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} +.btn-warning.disabled, .btn-warning:disabled { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active, .show > .btn-warning.dropdown-toggle { + color: #212529; + background-color: #d39e00; + border-color: #c69500; +} +.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus, .show > .btn-warning.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} + +.btn-danger { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-danger:hover { + color: #fff; + background-color: #c82333; + border-color: #bd2130; +} +.btn-danger:focus, .btn-danger.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} +.btn-danger.disabled, .btn-danger:disabled { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active, .show > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #bd2130; + border-color: #b21f2d; +} +.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus, .show > .btn-danger.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} + +.btn-light { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-light:hover { + color: #212529; + background-color: #e2e6ea; + border-color: #dae0e5; +} +.btn-light:focus, .btn-light.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} +.btn-light.disabled, .btn-light:disabled { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active, .show > .btn-light.dropdown-toggle { + color: #212529; + background-color: #dae0e5; + border-color: #d3d9df; +} +.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus, .show > .btn-light.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} + +.btn-dark { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} +.btn-dark:hover { + color: #fff; + background-color: #23272b; + border-color: #1d2124; +} +.btn-dark:focus, .btn-dark.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} +.btn-dark.disabled, .btn-dark:disabled { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} +.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active, .show > .btn-dark.dropdown-toggle { + color: #fff; + background-color: #1d2124; + border-color: #171a1d; +} +.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus, .show > .btn-dark.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} + +.btn-outline-primary { + color: #007bff; + background-color: transparent; + background-image: none; + border-color: #007bff; +} +.btn-outline-primary:hover { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} +.btn-outline-primary:focus, .btn-outline-primary.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} +.btn-outline-primary.disabled, .btn-outline-primary:disabled { + color: #007bff; + background-color: transparent; +} +.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active, .show > .btn-outline-primary.dropdown-toggle { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} +.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-primary.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} + +.btn-outline-secondary { + color: #6c757d; + background-color: transparent; + background-image: none; + border-color: #6c757d; +} +.btn-outline-secondary:hover { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-outline-secondary:focus, .btn-outline-secondary.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} +.btn-outline-secondary.disabled, .btn-outline-secondary:disabled { + color: #6c757d; + background-color: transparent; +} +.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active, .show > .btn-outline-secondary.dropdown-toggle { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-secondary.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} + +.btn-outline-success { + color: #28a745; + background-color: transparent; + background-image: none; + border-color: #28a745; +} +.btn-outline-success:hover { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} +.btn-outline-success:focus, .btn-outline-success.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} +.btn-outline-success.disabled, .btn-outline-success:disabled { + color: #28a745; + background-color: transparent; +} +.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active, .show > .btn-outline-success.dropdown-toggle { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} +.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-success.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} + +.btn-outline-info { + color: #17a2b8; + background-color: transparent; + background-image: none; + border-color: #17a2b8; +} +.btn-outline-info:hover { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} +.btn-outline-info:focus, .btn-outline-info.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} +.btn-outline-info.disabled, .btn-outline-info:disabled { + color: #17a2b8; + background-color: transparent; +} +.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active, .show > .btn-outline-info.dropdown-toggle { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} +.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-info.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} + +.btn-outline-warning { + color: #ffc107; + background-color: transparent; + background-image: none; + border-color: #ffc107; +} +.btn-outline-warning:hover { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-outline-warning:focus, .btn-outline-warning.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} +.btn-outline-warning.disabled, .btn-outline-warning:disabled { + color: #ffc107; + background-color: transparent; +} +.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active, .show > .btn-outline-warning.dropdown-toggle { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-warning.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} + +.btn-outline-danger { + color: #dc3545; + background-color: transparent; + background-image: none; + border-color: #dc3545; +} +.btn-outline-danger:hover { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-outline-danger:focus, .btn-outline-danger.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} +.btn-outline-danger.disabled, .btn-outline-danger:disabled { + color: #dc3545; + background-color: transparent; +} +.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active, .show > .btn-outline-danger.dropdown-toggle { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-danger.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} + +.btn-outline-light { + color: #f8f9fa; + background-color: transparent; + background-image: none; + border-color: #f8f9fa; +} +.btn-outline-light:hover { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-outline-light:focus, .btn-outline-light.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} +.btn-outline-light.disabled, .btn-outline-light:disabled { + color: #f8f9fa; + background-color: transparent; +} +.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active, .show > .btn-outline-light.dropdown-toggle { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-light.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} + +.btn-outline-dark { + color: #343a40; + background-color: transparent; + background-image: none; + border-color: #343a40; +} +.btn-outline-dark:hover { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} +.btn-outline-dark:focus, .btn-outline-dark.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} +.btn-outline-dark.disabled, .btn-outline-dark:disabled { + color: #343a40; + background-color: transparent; +} +.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active, .show > .btn-outline-dark.dropdown-toggle { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} +.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-dark.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} + +.btn-link { + font-weight: 400; + color: #007bff; + background-color: transparent; +} +.btn-link:hover { + color: #0056b3; + text-decoration: underline; + background-color: transparent; + border-color: transparent; +} +.btn-link:focus, .btn-link.focus { + text-decoration: underline; + border-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link:disabled, .btn-link.disabled { + color: #6c757d; +} + +.btn-lg, .btn-group-lg > .btn { + padding: 0.5rem 1rem; + font-size: 1.25rem; + line-height: 1.5; + border-radius: 0.3rem; +} + +.btn-sm, .btn-group-sm > .btn { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.5; + border-radius: 0.2rem; +} + +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 0.5rem; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} +.fade.show { + opacity: 1; +} + +.collapse { + display: none; +} +.collapse.show { + display: block; +} + +tr.collapse.show { + display: table-row; +} + +tbody.collapse.show { + display: table-row-group; +} + +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + transition: height 0.35s ease; +} + +.dropup, +.dropdown { + position: relative; +} + +.dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid; + border-right: 0.3em solid transparent; + border-bottom: 0; + border-left: 0.3em solid transparent; +} +.dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 10rem; + padding: 0.5rem 0; + margin: 0.125rem 0 0; + font-size: 1rem; + color: #212529; + text-align: left; + list-style: none; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; +} + +.dropup .dropdown-menu { + margin-top: 0; + margin-bottom: 0.125rem; +} +.dropup .dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0; + border-right: 0.3em solid transparent; + border-bottom: 0.3em solid; + border-left: 0.3em solid transparent; +} +.dropup .dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropright .dropdown-menu { + margin-top: 0; + margin-left: 0.125rem; +} +.dropright .dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-bottom: 0.3em solid transparent; + border-left: 0.3em solid; +} +.dropright .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropright .dropdown-toggle::after { + vertical-align: 0; +} + +.dropleft .dropdown-menu { + margin-top: 0; + margin-right: 0.125rem; +} +.dropleft .dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; +} +.dropleft .dropdown-toggle::after { + display: none; +} +.dropleft .dropdown-toggle::before { + display: inline-block; + width: 0; + height: 0; + margin-right: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-right: 0.3em solid; + border-bottom: 0.3em solid transparent; +} +.dropleft .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropleft .dropdown-toggle::before { + vertical-align: 0; +} + +.dropdown-divider { + height: 0; + margin: 0.5rem 0; + overflow: hidden; + border-top: 1px solid #e9ecef; +} + +.dropdown-item { + display: block; + width: 100%; + padding: 0.25rem 1.5rem; + clear: both; + font-weight: 400; + color: #212529; + text-align: inherit; + white-space: nowrap; + background-color: transparent; + border: 0; +} +.dropdown-item:hover, .dropdown-item:focus { + color: #16181b; + text-decoration: none; + background-color: #f8f9fa; +} +.dropdown-item.active, .dropdown-item:active { + color: #fff; + text-decoration: none; + background-color: #007bff; +} +.dropdown-item.disabled, .dropdown-item:disabled { + color: #6c757d; + background-color: transparent; +} + +.dropdown-menu.show { + display: block; +} + +.dropdown-header { + display: block; + padding: 0.5rem 1.5rem; + margin-bottom: 0; + font-size: 0.875rem; + color: #6c757d; + white-space: nowrap; +} + +.btn-group, +.btn-group-vertical { + position: relative; + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + -webkit-box-flex: 0; + -ms-flex: 0 1 auto; + flex: 0 1 auto; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover { + z-index: 1; +} +.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active, +.btn-group-vertical > .btn:focus, +.btn-group-vertical > .btn:active, +.btn-group-vertical > .btn.active { + z-index: 1; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group, +.btn-group-vertical .btn + .btn, +.btn-group-vertical .btn + .btn-group, +.btn-group-vertical .btn-group + .btn, +.btn-group-vertical .btn-group + .btn-group { + margin-left: -1px; +} + +.btn-toolbar { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; +} +.btn-toolbar .input-group { + width: auto; +} + +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:not(:first-child), +.btn-group > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.dropdown-toggle-split { + padding-right: 0.5625rem; + padding-left: 0.5625rem; +} +.dropdown-toggle-split::after { + margin-left: 0; +} + +.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split { + padding-right: 0.375rem; + padding-left: 0.375rem; +} + +.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split { + padding-right: 0.75rem; + padding-left: 0.75rem; +} + +.btn-group-vertical { + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-align: start; + -ms-flex-align: start; + align-items: flex-start; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.btn-group-vertical .btn, +.btn-group-vertical .btn-group { + width: 100%; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group-vertical > .btn-group:not(:last-child) > .btn { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:not(:first-child), +.btn-group-vertical > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.btn-group-toggle > .btn, +.btn-group-toggle > .btn-group > .btn { + margin-bottom: 0; +} +.btn-group-toggle > .btn input[type="radio"], +.btn-group-toggle > .btn input[type="checkbox"], +.btn-group-toggle > .btn-group > .btn input[type="radio"], +.btn-group-toggle > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} + +.input-group { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-align: stretch; + -ms-flex-align: stretch; + align-items: stretch; + width: 100%; +} +.input-group > .form-control, +.input-group > .custom-select, +.input-group > .custom-file { + position: relative; + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + width: 1%; + margin-bottom: 0; +} +.input-group > .form-control:focus, +.input-group > .custom-select:focus, +.input-group > .custom-file:focus { + z-index: 3; +} +.input-group > .form-control + .form-control, +.input-group > .form-control + .custom-select, +.input-group > .form-control + .custom-file, +.input-group > .custom-select + .form-control, +.input-group > .custom-select + .custom-select, +.input-group > .custom-select + .custom-file, +.input-group > .custom-file + .form-control, +.input-group > .custom-file + .custom-select, +.input-group > .custom-file + .custom-file { + margin-left: -1px; +} +.input-group > .form-control:not(:last-child), +.input-group > .custom-select:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group > .form-control:not(:first-child), +.input-group > .custom-select:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group > .custom-file { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.input-group > .custom-file:not(:last-child) .custom-file-label, .input-group > .custom-file:not(:last-child) .custom-file-label::before { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group > .custom-file:not(:first-child) .custom-file-label, .input-group > .custom-file:not(:first-child) .custom-file-label::before { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.input-group-prepend, +.input-group-append { + display: -webkit-box; + display: -ms-flexbox; + display: flex; +} +.input-group-prepend .btn, +.input-group-append .btn { + position: relative; + z-index: 2; +} +.input-group-prepend .btn + .btn, +.input-group-prepend .btn + .input-group-text, +.input-group-prepend .input-group-text + .input-group-text, +.input-group-prepend .input-group-text + .btn, +.input-group-append .btn + .btn, +.input-group-append .btn + .input-group-text, +.input-group-append .input-group-text + .input-group-text, +.input-group-append .input-group-text + .btn { + margin-left: -1px; +} + +.input-group-prepend { + margin-right: -1px; +} + +.input-group-append { + margin-left: -1px; +} + +.input-group-text { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + padding: 0.375rem 0.75rem; + margin-bottom: 0; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #495057; + text-align: center; + white-space: nowrap; + background-color: #e9ecef; + border: 1px solid #ced4da; + border-radius: 0.25rem; +} +.input-group-text input[type="radio"], +.input-group-text input[type="checkbox"] { + margin-top: 0; +} + +.input-group > .input-group-prepend > .btn, +.input-group > .input-group-prepend > .input-group-text, +.input-group > .input-group-append:not(:last-child) > .btn, +.input-group > .input-group-append:not(:last-child) > .input-group-text, +.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.input-group > .input-group-append > .btn, +.input-group > .input-group-append > .input-group-text, +.input-group > .input-group-prepend:not(:first-child) > .btn, +.input-group > .input-group-prepend:not(:first-child) > .input-group-text, +.input-group > .input-group-prepend:first-child > .btn:not(:first-child), +.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.custom-control { + position: relative; + display: block; + min-height: 1.5rem; + padding-left: 1.5rem; +} + +.custom-control-inline { + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + margin-right: 1rem; +} + +.custom-control-input { + position: absolute; + z-index: -1; + opacity: 0; +} +.custom-control-input:checked ~ .custom-control-label::before { + color: #fff; + background-color: #007bff; +} +.custom-control-input:focus ~ .custom-control-label::before { + -webkit-box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.custom-control-input:active ~ .custom-control-label::before { + color: #fff; + background-color: #b3d7ff; +} +.custom-control-input:disabled ~ .custom-control-label { + color: #6c757d; +} +.custom-control-input:disabled ~ .custom-control-label::before { + background-color: #e9ecef; +} + +.custom-control-label { + margin-bottom: 0; +} +.custom-control-label::before { + position: absolute; + top: 0.25rem; + left: 0; + display: block; + width: 1rem; + height: 1rem; + pointer-events: none; + content: ""; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-color: #dee2e6; +} +.custom-control-label::after { + position: absolute; + top: 0.25rem; + left: 0; + display: block; + width: 1rem; + height: 1rem; + content: ""; + background-repeat: no-repeat; + background-position: center center; + background-size: 50% 50%; +} + +.custom-checkbox .custom-control-label::before { + border-radius: 0.25rem; +} +.custom-checkbox .custom-control-input:checked ~ .custom-control-label::before { + background-color: #007bff; +} +.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E"); +} +.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before { + background-color: #007bff; +} +.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E"); +} +.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before { + background-color: rgba(0, 123, 255, 0.5); +} +.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before { + background-color: rgba(0, 123, 255, 0.5); +} + +.custom-radio .custom-control-label::before { + border-radius: 50%; +} +.custom-radio .custom-control-input:checked ~ .custom-control-label::before { + background-color: #007bff; +} +.custom-radio .custom-control-input:checked ~ .custom-control-label::after { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E"); +} +.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before { + background-color: rgba(0, 123, 255, 0.5); +} + +.custom-select { + display: inline-block; + width: 100%; + height: calc(2.25rem + 2px); + padding: 0.375rem 1.75rem 0.375rem 0.75rem; + line-height: 1.5; + color: #495057; + vertical-align: middle; + background: #fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center; + background-size: 8px 10px; + border: 1px solid #ced4da; + border-radius: 0.25rem; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} +.custom-select:focus { + border-color: #80bdff; + outline: 0; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075), 0 0 5px rgba(128, 189, 255, 0.5); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075), 0 0 5px rgba(128, 189, 255, 0.5); +} +.custom-select:focus::-ms-value { + color: #495057; + background-color: #fff; +} +.custom-select[multiple], .custom-select[size]:not([size="1"]) { + height: auto; + padding-right: 0.75rem; + background-image: none; +} +.custom-select:disabled { + color: #6c757d; + background-color: #e9ecef; +} +.custom-select::-ms-expand { + opacity: 0; +} + +.custom-select-sm { + height: calc(1.8125rem + 2px); + padding-top: 0.375rem; + padding-bottom: 0.375rem; + font-size: 75%; +} + +.custom-select-lg { + height: calc(2.875rem + 2px); + padding-top: 0.375rem; + padding-bottom: 0.375rem; + font-size: 125%; +} + +.custom-file { + position: relative; + display: inline-block; + width: 100%; + height: calc(2.25rem + 2px); + margin-bottom: 0; +} + +.custom-file-input { + position: relative; + z-index: 2; + width: 100%; + height: calc(2.25rem + 2px); + margin: 0; + opacity: 0; +} +.custom-file-input:focus ~ .custom-file-control { + border-color: #80bdff; + -webkit-box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.custom-file-input:focus ~ .custom-file-control::before { + border-color: #80bdff; +} +.custom-file-input:lang(en) ~ .custom-file-label::after { + content: "Browse"; +} + +.custom-file-label { + position: absolute; + top: 0; + right: 0; + left: 0; + z-index: 1; + height: calc(2.25rem + 2px); + padding: 0.375rem 0.75rem; + line-height: 1.5; + color: #495057; + background-color: #fff; + border: 1px solid #ced4da; + border-radius: 0.25rem; +} +.custom-file-label::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + z-index: 3; + display: block; + height: calc(calc(2.25rem + 2px) - 1px * 2); + padding: 0.375rem 0.75rem; + line-height: 1.5; + color: #495057; + content: "Browse"; + background-color: #e9ecef; + border-left: 1px solid #ced4da; + border-radius: 0 0.25rem 0.25rem 0; +} + +.nav { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} + +.nav-link { + display: block; + padding: 0.5rem 1rem; +} +.nav-link:hover, .nav-link:focus { + text-decoration: none; +} +.nav-link.disabled { + color: #6c757d; +} + +.nav-tabs { + border-bottom: 1px solid #dee2e6; +} +.nav-tabs .nav-item { + margin-bottom: -1px; +} +.nav-tabs .nav-link { + border: 1px solid transparent; + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} +.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus { + border-color: #e9ecef #e9ecef #dee2e6; +} +.nav-tabs .nav-link.disabled { + color: #6c757d; + background-color: transparent; + border-color: transparent; +} +.nav-tabs .nav-link.active, +.nav-tabs .nav-item.show .nav-link { + color: #495057; + background-color: #fff; + border-color: #dee2e6 #dee2e6 #fff; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.nav-pills .nav-link { + border-radius: 0.25rem; +} +.nav-pills .nav-link.active, +.nav-pills .show > .nav-link { + color: #fff; + background-color: #007bff; +} + +.nav-fill .nav-item { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + text-align: center; +} + +.nav-justified .nav-item { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + text-align: center; +} + +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} + +.navbar { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + padding: 0.5rem 1rem; +} +.navbar > .container, +.navbar > .container-fluid { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; +} + +.navbar-brand { + display: inline-block; + padding-top: 0.3125rem; + padding-bottom: 0.3125rem; + margin-right: 1rem; + font-size: 1.25rem; + line-height: inherit; + white-space: nowrap; +} +.navbar-brand:hover, .navbar-brand:focus { + text-decoration: none; +} + +.navbar-nav { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.navbar-nav .nav-link { + padding-right: 0; + padding-left: 0; +} +.navbar-nav .dropdown-menu { + position: static; + float: none; +} + +.navbar-text { + display: inline-block; + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.navbar-collapse { + -ms-flex-preferred-size: 100%; + flex-basis: 100%; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.navbar-toggler { + padding: 0.25rem 0.75rem; + font-size: 1.25rem; + line-height: 1; + background-color: transparent; + border: 1px solid transparent; + border-radius: 0.25rem; +} +.navbar-toggler:hover, .navbar-toggler:focus { + text-decoration: none; +} +.navbar-toggler:not(:disabled):not(.disabled) { + cursor: pointer; +} + +.navbar-toggler-icon { + display: inline-block; + width: 1.5em; + height: 1.5em; + vertical-align: middle; + content: ""; + background: no-repeat center center; + background-size: 100% 100%; +} + +@media (max-width: 575.98px) { + .navbar-expand-sm > .container, + .navbar-expand-sm > .container-fluid { + padding-right: 0; + padding-left: 0; + } +} +@media (min-width: 576px) { + .navbar-expand-sm { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + } + .navbar-expand-sm .navbar-nav { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + } + .navbar-expand-sm .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-sm .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; + } + .navbar-expand-sm .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-sm > .container, + .navbar-expand-sm > .container-fluid { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } + .navbar-expand-sm .navbar-collapse { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; + } + .navbar-expand-sm .navbar-toggler { + display: none; + } + .navbar-expand-sm .dropup .dropdown-menu { + top: auto; + bottom: 100%; + } +} +@media (max-width: 767.98px) { + .navbar-expand-md > .container, + .navbar-expand-md > .container-fluid { + padding-right: 0; + padding-left: 0; + } +} +@media (min-width: 768px) { + .navbar-expand-md { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + } + .navbar-expand-md .navbar-nav { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + } + .navbar-expand-md .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-md .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; + } + .navbar-expand-md .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-md > .container, + .navbar-expand-md > .container-fluid { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } + .navbar-expand-md .navbar-collapse { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; + } + .navbar-expand-md .navbar-toggler { + display: none; + } + .navbar-expand-md .dropup .dropdown-menu { + top: auto; + bottom: 100%; + } +} +@media (max-width: 991.98px) { + .navbar-expand-lg > .container, + .navbar-expand-lg > .container-fluid { + padding-right: 0; + padding-left: 0; + } +} +@media (min-width: 992px) { + .navbar-expand-lg { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + } + .navbar-expand-lg .navbar-nav { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + } + .navbar-expand-lg .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-lg .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; + } + .navbar-expand-lg .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-lg > .container, + .navbar-expand-lg > .container-fluid { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } + .navbar-expand-lg .navbar-collapse { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; + } + .navbar-expand-lg .navbar-toggler { + display: none; + } + .navbar-expand-lg .dropup .dropdown-menu { + top: auto; + bottom: 100%; + } +} +@media (max-width: 1199.98px) { + .navbar-expand-xl > .container, + .navbar-expand-xl > .container-fluid { + padding-right: 0; + padding-left: 0; + } +} +@media (min-width: 1200px) { + .navbar-expand-xl { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + } + .navbar-expand-xl .navbar-nav { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + } + .navbar-expand-xl .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-xl .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; + } + .navbar-expand-xl .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-xl > .container, + .navbar-expand-xl > .container-fluid { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } + .navbar-expand-xl .navbar-collapse { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; + } + .navbar-expand-xl .navbar-toggler { + display: none; + } + .navbar-expand-xl .dropup .dropdown-menu { + top: auto; + bottom: 100%; + } +} +.navbar-expand { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; +} +.navbar-expand > .container, +.navbar-expand > .container-fluid { + padding-right: 0; + padding-left: 0; +} +.navbar-expand .navbar-nav { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; +} +.navbar-expand .navbar-nav .dropdown-menu { + position: absolute; +} +.navbar-expand .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; +} +.navbar-expand .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; +} +.navbar-expand > .container, +.navbar-expand > .container-fluid { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; +} +.navbar-expand .navbar-collapse { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; +} +.navbar-expand .navbar-toggler { + display: none; +} +.navbar-expand .dropup .dropdown-menu { + top: auto; + bottom: 100%; +} + +.navbar-light .navbar-brand { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-nav .nav-link { + color: rgba(0, 0, 0, 0.5); +} +.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus { + color: rgba(0, 0, 0, 0.7); +} +.navbar-light .navbar-nav .nav-link.disabled { + color: rgba(0, 0, 0, 0.3); +} +.navbar-light .navbar-nav .show > .nav-link, +.navbar-light .navbar-nav .active > .nav-link, +.navbar-light .navbar-nav .nav-link.show, +.navbar-light .navbar-nav .nav-link.active { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-toggler { + color: rgba(0, 0, 0, 0.5); + border-color: rgba(0, 0, 0, 0.1); +} +.navbar-light .navbar-toggler-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"); +} +.navbar-light .navbar-text { + color: rgba(0, 0, 0, 0.5); +} +.navbar-light .navbar-text a { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus { + color: rgba(0, 0, 0, 0.9); +} + +.navbar-dark .navbar-brand { + color: #fff; +} +.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus { + color: #fff; +} +.navbar-dark .navbar-nav .nav-link { + color: rgba(255, 255, 255, 0.5); +} +.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus { + color: rgba(255, 255, 255, 0.75); +} +.navbar-dark .navbar-nav .nav-link.disabled { + color: rgba(255, 255, 255, 0.25); +} +.navbar-dark .navbar-nav .show > .nav-link, +.navbar-dark .navbar-nav .active > .nav-link, +.navbar-dark .navbar-nav .nav-link.show, +.navbar-dark .navbar-nav .nav-link.active { + color: #fff; +} +.navbar-dark .navbar-toggler { + color: rgba(255, 255, 255, 0.5); + border-color: rgba(255, 255, 255, 0.1); +} +.navbar-dark .navbar-toggler-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"); +} +.navbar-dark .navbar-text { + color: rgba(255, 255, 255, 0.5); +} +.navbar-dark .navbar-text a { + color: #fff; +} +.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus { + color: #fff; +} + +.card { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + min-width: 0; + word-wrap: break-word; + background-color: #fff; + background-clip: border-box; + border: 1px solid rgba(0, 0, 0, 0.125); + border-radius: 0.25rem; +} +.card > hr { + margin-right: 0; + margin-left: 0; +} +.card > .list-group:first-child .list-group-item:first-child { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} +.card > .list-group:last-child .list-group-item:last-child { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} + +.card-body { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + padding: 1.25rem; +} + +.card-title { + margin-bottom: 0.75rem; +} + +.card-subtitle { + margin-top: -0.375rem; + margin-bottom: 0; +} + +.card-text:last-child { + margin-bottom: 0; +} + +.card-link:hover { + text-decoration: none; +} +.card-link + .card-link { + margin-left: 1.25rem; +} + +.card-header { + padding: 0.75rem 1.25rem; + margin-bottom: 0; + background-color: rgba(0, 0, 0, 0.03); + border-bottom: 1px solid rgba(0, 0, 0, 0.125); +} +.card-header:first-child { + border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0; +} +.card-header + .list-group .list-group-item:first-child { + border-top: 0; +} + +.card-footer { + padding: 0.75rem 1.25rem; + background-color: rgba(0, 0, 0, 0.03); + border-top: 1px solid rgba(0, 0, 0, 0.125); +} +.card-footer:last-child { + border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px); +} + +.card-header-tabs { + margin-right: -0.625rem; + margin-bottom: -0.75rem; + margin-left: -0.625rem; + border-bottom: 0; +} + +.card-header-pills { + margin-right: -0.625rem; + margin-left: -0.625rem; +} + +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: 1.25rem; +} + +.card-img { + width: 100%; + border-radius: calc(0.25rem - 1px); +} + +.card-img-top { + width: 100%; + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} + +.card-img-bottom { + width: 100%; + border-bottom-right-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); +} + +.card-deck { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} +.card-deck .card { + margin-bottom: 15px; +} +@media (min-width: 576px) { + .card-deck { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + margin-right: -15px; + margin-left: -15px; + } + .card-deck .card { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-flex: 1; + -ms-flex: 1 0 0%; + flex: 1 0 0%; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + margin-right: 15px; + margin-bottom: 0; + margin-left: 15px; + } +} + +.card-group { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} +.card-group > .card { + margin-bottom: 15px; +} +@media (min-width: 576px) { + .card-group { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + } + .card-group > .card { + -webkit-box-flex: 1; + -ms-flex: 1 0 0%; + flex: 1 0 0%; + margin-bottom: 0; + } + .card-group > .card + .card { + margin-left: 0; + border-left: 0; + } + .card-group > .card:first-child { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .card-group > .card:first-child .card-img-top, + .card-group > .card:first-child .card-header { + border-top-right-radius: 0; + } + .card-group > .card:first-child .card-img-bottom, + .card-group > .card:first-child .card-footer { + border-bottom-right-radius: 0; + } + .card-group > .card:last-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .card-group > .card:last-child .card-img-top, + .card-group > .card:last-child .card-header { + border-top-left-radius: 0; + } + .card-group > .card:last-child .card-img-bottom, + .card-group > .card:last-child .card-footer { + border-bottom-left-radius: 0; + } + .card-group > .card:only-child { + border-radius: 0.25rem; + } + .card-group > .card:only-child .card-img-top, + .card-group > .card:only-child .card-header { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; + } + .card-group > .card:only-child .card-img-bottom, + .card-group > .card:only-child .card-footer { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; + } + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) { + border-radius: 0; + } + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-top, + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom, + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-header, + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-footer { + border-radius: 0; + } +} + +.card-columns .card { + margin-bottom: 0.75rem; +} +@media (min-width: 576px) { + .card-columns { + -webkit-column-count: 3; + column-count: 3; + -webkit-column-gap: 1.25rem; + column-gap: 1.25rem; + } + .card-columns .card { + display: inline-block; + width: 100%; + } +} + +.breadcrumb { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + padding: 0.75rem 1rem; + margin-bottom: 1rem; + list-style: none; + background-color: #e9ecef; + border-radius: 0.25rem; +} + +.breadcrumb-item + .breadcrumb-item::before { + display: inline-block; + padding-right: 0.5rem; + padding-left: 0.5rem; + color: #6c757d; + content: "/"; +} +.breadcrumb-item + .breadcrumb-item:hover::before { + text-decoration: underline; +} +.breadcrumb-item + .breadcrumb-item:hover::before { + text-decoration: none; +} +.breadcrumb-item.active { + color: #6c757d; +} + +.pagination { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + padding-left: 0; + list-style: none; + border-radius: 0.25rem; +} + +.page-link { + position: relative; + display: block; + padding: 0.5rem 0.75rem; + margin-left: -1px; + line-height: 1.25; + color: #007bff; + background-color: #fff; + border: 1px solid #dee2e6; +} +.page-link:hover { + color: #0056b3; + text-decoration: none; + background-color: #e9ecef; + border-color: #dee2e6; +} +.page-link:focus { + z-index: 2; + outline: 0; + -webkit-box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.page-link:not(:disabled):not(.disabled) { + cursor: pointer; +} + +.page-item:first-child .page-link { + margin-left: 0; + border-top-left-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} +.page-item:last-child .page-link { + border-top-right-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; +} +.page-item.active .page-link { + z-index: 1; + color: #fff; + background-color: #007bff; + border-color: #007bff; +} +.page-item.disabled .page-link { + color: #6c757d; + pointer-events: none; + cursor: auto; + background-color: #fff; + border-color: #dee2e6; +} + +.pagination-lg .page-link { + padding: 0.75rem 1.5rem; + font-size: 1.25rem; + line-height: 1.5; +} +.pagination-lg .page-item:first-child .page-link { + border-top-left-radius: 0.3rem; + border-bottom-left-radius: 0.3rem; +} +.pagination-lg .page-item:last-child .page-link { + border-top-right-radius: 0.3rem; + border-bottom-right-radius: 0.3rem; +} + +.pagination-sm .page-link { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.5; +} +.pagination-sm .page-item:first-child .page-link { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; +} +.pagination-sm .page-item:last-child .page-link { + border-top-right-radius: 0.2rem; + border-bottom-right-radius: 0.2rem; +} + +.badge { + display: inline-block; + padding: 0.25em 0.4em; + font-size: 75%; + font-weight: 700; + line-height: 1; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 0.25rem; +} +.badge:empty { + display: none; +} + +.btn .badge { + position: relative; + top: -1px; +} + +.badge-pill { + padding-right: 0.6em; + padding-left: 0.6em; + border-radius: 10rem; +} + +.badge-primary { + color: #fff; + background-color: #007bff; +} +.badge-primary[href]:hover, .badge-primary[href]:focus { + color: #fff; + text-decoration: none; + background-color: #0062cc; +} + +.badge-secondary { + color: #fff; + background-color: #6c757d; +} +.badge-secondary[href]:hover, .badge-secondary[href]:focus { + color: #fff; + text-decoration: none; + background-color: #545b62; +} + +.badge-success { + color: #fff; + background-color: #28a745; +} +.badge-success[href]:hover, .badge-success[href]:focus { + color: #fff; + text-decoration: none; + background-color: #1e7e34; +} + +.badge-info { + color: #fff; + background-color: #17a2b8; +} +.badge-info[href]:hover, .badge-info[href]:focus { + color: #fff; + text-decoration: none; + background-color: #117a8b; +} + +.badge-warning { + color: #212529; + background-color: #ffc107; +} +.badge-warning[href]:hover, .badge-warning[href]:focus { + color: #212529; + text-decoration: none; + background-color: #d39e00; +} + +.badge-danger { + color: #fff; + background-color: #dc3545; +} +.badge-danger[href]:hover, .badge-danger[href]:focus { + color: #fff; + text-decoration: none; + background-color: #bd2130; +} + +.badge-light { + color: #212529; + background-color: #f8f9fa; +} +.badge-light[href]:hover, .badge-light[href]:focus { + color: #212529; + text-decoration: none; + background-color: #dae0e5; +} + +.badge-dark { + color: #fff; + background-color: #343a40; +} +.badge-dark[href]:hover, .badge-dark[href]:focus { + color: #fff; + text-decoration: none; + background-color: #1d2124; +} + +.jumbotron { + padding: 2rem 1rem; + margin-bottom: 2rem; + background-color: #e9ecef; + border-radius: 0.3rem; +} +@media (min-width: 576px) { + .jumbotron { + padding: 4rem 2rem; + } +} + +.jumbotron-fluid { + padding-right: 0; + padding-left: 0; + border-radius: 0; +} + +.alert { + position: relative; + padding: 0.75rem 1.25rem; + margin-bottom: 1rem; + border: 1px solid transparent; + border-radius: 0.25rem; +} + +.alert-heading { + color: inherit; +} + +.alert-link { + font-weight: 700; +} + +.alert-dismissible { + padding-right: 4rem; +} +.alert-dismissible .close { + position: absolute; + top: 0; + right: 0; + padding: 0.75rem 1.25rem; + color: inherit; +} + +.alert-primary { + color: #004085; + background-color: #cce5ff; + border-color: #b8daff; +} +.alert-primary hr { + border-top-color: #9fcdff; +} +.alert-primary .alert-link { + color: #002752; +} + +.alert-secondary { + color: #383d41; + background-color: #e2e3e5; + border-color: #d6d8db; +} +.alert-secondary hr { + border-top-color: #c8cbcf; +} +.alert-secondary .alert-link { + color: #202326; +} + +.alert-success { + color: #155724; + background-color: #d4edda; + border-color: #c3e6cb; +} +.alert-success hr { + border-top-color: #b1dfbb; +} +.alert-success .alert-link { + color: #0b2e13; +} + +.alert-info { + color: #0c5460; + background-color: #d1ecf1; + border-color: #bee5eb; +} +.alert-info hr { + border-top-color: #abdde5; +} +.alert-info .alert-link { + color: #062c33; +} + +.alert-warning { + color: #856404; + background-color: #fff3cd; + border-color: #ffeeba; +} +.alert-warning hr { + border-top-color: #ffe8a1; +} +.alert-warning .alert-link { + color: #533f03; +} + +.alert-danger { + color: #721c24; + background-color: #f8d7da; + border-color: #f5c6cb; +} +.alert-danger hr { + border-top-color: #f1b0b7; +} +.alert-danger .alert-link { + color: #491217; +} + +.alert-light { + color: #818182; + background-color: #fefefe; + border-color: #fdfdfe; +} +.alert-light hr { + border-top-color: #ececf6; +} +.alert-light .alert-link { + color: #686868; +} + +.alert-dark { + color: #1b1e21; + background-color: #d6d8d9; + border-color: #c6c8ca; +} +.alert-dark hr { + border-top-color: #b9bbbe; +} +.alert-dark .alert-link { + color: #040505; +} + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 1rem 0; + } + to { + background-position: 0 0; + } +} + +@keyframes progress-bar-stripes { + from { + background-position: 1rem 0; + } + to { + background-position: 0 0; + } +} +.progress { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + height: 1rem; + overflow: hidden; + font-size: 0.75rem; + background-color: #e9ecef; + border-radius: 0.25rem; +} + +.progress-bar { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + color: #fff; + text-align: center; + background-color: #007bff; + -webkit-transition: width 0.6s ease; + transition: width 0.6s ease; +} + +.progress-bar-striped { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 1rem 1rem; +} + +.progress-bar-animated { + -webkit-animation: progress-bar-stripes 1s linear infinite; + animation: progress-bar-stripes 1s linear infinite; +} + +.media { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: start; + -ms-flex-align: start; + align-items: flex-start; +} + +.media-body { + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; +} + +.list-group { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; +} + +.list-group-item-action { + width: 100%; + color: #495057; + text-align: inherit; +} +.list-group-item-action:hover, .list-group-item-action:focus { + color: #495057; + text-decoration: none; + background-color: #f8f9fa; +} +.list-group-item-action:active { + color: #212529; + background-color: #e9ecef; +} + +.list-group-item { + position: relative; + display: block; + padding: 0.75rem 1.25rem; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid rgba(0, 0, 0, 0.125); +} +.list-group-item:first-child { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} +.list-group-item:hover, .list-group-item:focus { + z-index: 1; + text-decoration: none; +} +.list-group-item.disabled, .list-group-item:disabled { + color: #6c757d; + background-color: #fff; +} +.list-group-item.active { + z-index: 2; + color: #fff; + background-color: #007bff; + border-color: #007bff; +} + +.list-group-flush .list-group-item { + border-right: 0; + border-left: 0; + border-radius: 0; +} +.list-group-flush:first-child .list-group-item:first-child { + border-top: 0; +} +.list-group-flush:last-child .list-group-item:last-child { + border-bottom: 0; +} + +.list-group-item-primary { + color: #004085; + background-color: #b8daff; +} +.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus { + color: #004085; + background-color: #9fcdff; +} +.list-group-item-primary.list-group-item-action.active { + color: #fff; + background-color: #004085; + border-color: #004085; +} + +.list-group-item-secondary { + color: #383d41; + background-color: #d6d8db; +} +.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus { + color: #383d41; + background-color: #c8cbcf; +} +.list-group-item-secondary.list-group-item-action.active { + color: #fff; + background-color: #383d41; + border-color: #383d41; +} + +.list-group-item-success { + color: #155724; + background-color: #c3e6cb; +} +.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus { + color: #155724; + background-color: #b1dfbb; +} +.list-group-item-success.list-group-item-action.active { + color: #fff; + background-color: #155724; + border-color: #155724; +} + +.list-group-item-info { + color: #0c5460; + background-color: #bee5eb; +} +.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus { + color: #0c5460; + background-color: #abdde5; +} +.list-group-item-info.list-group-item-action.active { + color: #fff; + background-color: #0c5460; + border-color: #0c5460; +} + +.list-group-item-warning { + color: #856404; + background-color: #ffeeba; +} +.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus { + color: #856404; + background-color: #ffe8a1; +} +.list-group-item-warning.list-group-item-action.active { + color: #fff; + background-color: #856404; + border-color: #856404; +} + +.list-group-item-danger { + color: #721c24; + background-color: #f5c6cb; +} +.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus { + color: #721c24; + background-color: #f1b0b7; +} +.list-group-item-danger.list-group-item-action.active { + color: #fff; + background-color: #721c24; + border-color: #721c24; +} + +.list-group-item-light { + color: #818182; + background-color: #fdfdfe; +} +.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus { + color: #818182; + background-color: #ececf6; +} +.list-group-item-light.list-group-item-action.active { + color: #fff; + background-color: #818182; + border-color: #818182; +} + +.list-group-item-dark { + color: #1b1e21; + background-color: #c6c8ca; +} +.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus { + color: #1b1e21; + background-color: #b9bbbe; +} +.list-group-item-dark.list-group-item-action.active { + color: #fff; + background-color: #1b1e21; + border-color: #1b1e21; +} + +.close { + float: right; + font-size: 1.5rem; + font-weight: 700; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: .5; +} +.close:hover, .close:focus { + color: #000; + text-decoration: none; + opacity: .75; +} +.close:not(:disabled):not(.disabled) { + cursor: pointer; +} + +button.close { + padding: 0; + background-color: transparent; + border: 0; + -webkit-appearance: none; +} + +.modal-open { + overflow: hidden; +} + +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: hidden; + outline: 0; +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} + +.modal-dialog { + position: relative; + width: auto; + margin: 0.5rem; + pointer-events: none; +} +.modal.fade .modal-dialog { + -webkit-transition: -webkit-transform 0.3s ease-out; + transition: -webkit-transform 0.3s ease-out; + transition: transform 0.3s ease-out; + transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out; + -webkit-transform: translate(0, -25%); + transform: translate(0, -25%); +} +.modal.show .modal-dialog { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); +} + +.modal-dialog-centered { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + min-height: calc(100% - (0.5rem * 2)); +} + +.modal-content { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + width: 100%; + pointer-events: auto; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; + outline: 0; +} + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop.show { + opacity: 0.5; +} + +.modal-header { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: start; + -ms-flex-align: start; + align-items: flex-start; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + padding: 1rem; + border-bottom: 1px solid #e9ecef; + border-top-left-radius: 0.3rem; + border-top-right-radius: 0.3rem; +} +.modal-header .close { + padding: 1rem; + margin: -1rem -1rem -1rem auto; +} + +.modal-title { + margin-bottom: 0; + line-height: 1.5; +} + +.modal-body { + position: relative; + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + padding: 1rem; +} + +.modal-footer { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; + padding: 1rem; + border-top: 1px solid #e9ecef; +} +.modal-footer > :not(:first-child) { + margin-left: .25rem; +} +.modal-footer > :not(:last-child) { + margin-right: .25rem; +} + +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} + +@media (min-width: 576px) { + .modal-dialog { + max-width: 500px; + margin: 1.75rem auto; + } + + .modal-dialog-centered { + min-height: calc(100% - (1.75rem * 2)); + } + + .modal-sm { + max-width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + max-width: 800px; + } +} +.tooltip { + position: absolute; + z-index: 1070; + display: block; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: 0.875rem; + word-wrap: break-word; + opacity: 0; +} +.tooltip.show { + opacity: 0.9; +} +.tooltip .arrow { + position: absolute; + display: block; + width: 0.8rem; + height: 0.4rem; +} +.tooltip .arrow::before { + position: absolute; + content: ""; + border-color: transparent; + border-style: solid; +} + +.bs-tooltip-top, .bs-tooltip-auto[x-placement^="top"] { + padding: 0.4rem 0; +} +.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^="top"] .arrow { + bottom: 0; +} +.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^="top"] .arrow::before { + top: 0; + border-width: 0.4rem 0.4rem 0; + border-top-color: #000; +} + +.bs-tooltip-right, .bs-tooltip-auto[x-placement^="right"] { + padding: 0 0.4rem; +} +.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^="right"] .arrow { + left: 0; + width: 0.4rem; + height: 0.8rem; +} +.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^="right"] .arrow::before { + right: 0; + border-width: 0.4rem 0.4rem 0.4rem 0; + border-right-color: #000; +} + +.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^="bottom"] { + padding: 0.4rem 0; +} +.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^="bottom"] .arrow { + top: 0; +} +.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^="bottom"] .arrow::before { + bottom: 0; + border-width: 0 0.4rem 0.4rem; + border-bottom-color: #000; +} + +.bs-tooltip-left, .bs-tooltip-auto[x-placement^="left"] { + padding: 0 0.4rem; +} +.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^="left"] .arrow { + right: 0; + width: 0.4rem; + height: 0.8rem; +} +.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^="left"] .arrow::before { + left: 0; + border-width: 0.4rem 0 0.4rem 0.4rem; + border-left-color: #000; +} + +.tooltip-inner { + max-width: 200px; + padding: 0.25rem 0.5rem; + color: #fff; + text-align: center; + background-color: #000; + border-radius: 0.25rem; +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: block; + max-width: 276px; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: 0.875rem; + word-wrap: break-word; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; +} +.popover .arrow { + position: absolute; + display: block; + width: 1rem; + height: 0.5rem; + margin: 0 0.3rem; +} +.popover .arrow::before, .popover .arrow::after { + position: absolute; + display: block; + content: ""; + border-color: transparent; + border-style: solid; +} + +.bs-popover-top, .bs-popover-auto[x-placement^="top"] { + margin-bottom: 0.5rem; +} +.bs-popover-top .arrow, .bs-popover-auto[x-placement^="top"] .arrow { + bottom: calc((0.5rem + 1px) * -1); +} +.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^="top"] .arrow::before, +.bs-popover-top .arrow::after, +.bs-popover-auto[x-placement^="top"] .arrow::after { + border-width: 0.5rem 0.5rem 0; +} +.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^="top"] .arrow::before { + bottom: 0; + border-top-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-top .arrow::after, .bs-popover-auto[x-placement^="top"] .arrow::after { + bottom: 1px; + border-top-color: #fff; +} + +.bs-popover-right, .bs-popover-auto[x-placement^="right"] { + margin-left: 0.5rem; +} +.bs-popover-right .arrow, .bs-popover-auto[x-placement^="right"] .arrow { + left: calc((0.5rem + 1px) * -1); + width: 0.5rem; + height: 1rem; + margin: 0.3rem 0; +} +.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^="right"] .arrow::before, +.bs-popover-right .arrow::after, +.bs-popover-auto[x-placement^="right"] .arrow::after { + border-width: 0.5rem 0.5rem 0.5rem 0; +} +.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^="right"] .arrow::before { + left: 0; + border-right-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-right .arrow::after, .bs-popover-auto[x-placement^="right"] .arrow::after { + left: 1px; + border-right-color: #fff; +} + +.bs-popover-bottom, .bs-popover-auto[x-placement^="bottom"] { + margin-top: 0.5rem; +} +.bs-popover-bottom .arrow, .bs-popover-auto[x-placement^="bottom"] .arrow { + top: calc((0.5rem + 1px) * -1); +} +.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^="bottom"] .arrow::before, +.bs-popover-bottom .arrow::after, +.bs-popover-auto[x-placement^="bottom"] .arrow::after { + border-width: 0 0.5rem 0.5rem 0.5rem; +} +.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^="bottom"] .arrow::before { + top: 0; + border-bottom-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-bottom .arrow::after, .bs-popover-auto[x-placement^="bottom"] .arrow::after { + top: 1px; + border-bottom-color: #fff; +} +.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^="bottom"] .popover-header::before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: 1rem; + margin-left: -0.5rem; + content: ""; + border-bottom: 1px solid #f7f7f7; +} + +.bs-popover-left, .bs-popover-auto[x-placement^="left"] { + margin-right: 0.5rem; +} +.bs-popover-left .arrow, .bs-popover-auto[x-placement^="left"] .arrow { + right: calc((0.5rem + 1px) * -1); + width: 0.5rem; + height: 1rem; + margin: 0.3rem 0; +} +.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^="left"] .arrow::before, +.bs-popover-left .arrow::after, +.bs-popover-auto[x-placement^="left"] .arrow::after { + border-width: 0.5rem 0 0.5rem 0.5rem; +} +.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^="left"] .arrow::before { + right: 0; + border-left-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-left .arrow::after, .bs-popover-auto[x-placement^="left"] .arrow::after { + right: 1px; + border-left-color: #fff; +} + +.popover-header { + padding: 0.5rem 0.75rem; + margin-bottom: 0; + font-size: 1rem; + color: inherit; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-top-left-radius: calc(0.3rem - 1px); + border-top-right-radius: calc(0.3rem - 1px); +} +.popover-header:empty { + display: none; +} + +.popover-body { + padding: 0.5rem 0.75rem; + color: #212529; +} + +.carousel { + position: relative; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-item { + position: relative; + display: none; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + width: 100%; + -webkit-transition: -webkit-transform 0.6s ease; + transition: -webkit-transform 0.6s ease; + transition: transform 0.6s ease; + transition: transform 0.6s ease, -webkit-transform 0.6s ease; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000px; + perspective: 1000px; +} + +.carousel-item.active, +.carousel-item-next, +.carousel-item-prev { + display: block; +} + +.carousel-item-next, +.carousel-item-prev { + position: absolute; + top: 0; +} + +.carousel-item-next.carousel-item-left, +.carousel-item-prev.carousel-item-right { + -webkit-transform: translateX(0); + transform: translateX(0); +} +@supports ((-webkit-transform-style: preserve-3d) or (transform-style: preserve-3d)) { + .carousel-item-next.carousel-item-left, + .carousel-item-prev.carousel-item-right { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.carousel-item-next, +.active.carousel-item-right { + -webkit-transform: translateX(100%); + transform: translateX(100%); +} +@supports ((-webkit-transform-style: preserve-3d) or (transform-style: preserve-3d)) { + .carousel-item-next, + .active.carousel-item-right { + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } +} + +.carousel-item-prev, +.active.carousel-item-left { + -webkit-transform: translateX(-100%); + transform: translateX(-100%); +} +@supports ((-webkit-transform-style: preserve-3d) or (transform-style: preserve-3d)) { + .carousel-item-prev, + .active.carousel-item-left { + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} + +.carousel-control-prev, +.carousel-control-next { + position: absolute; + top: 0; + bottom: 0; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + width: 15%; + color: #fff; + text-align: center; + opacity: 0.5; +} +.carousel-control-prev:hover, .carousel-control-prev:focus, +.carousel-control-next:hover, +.carousel-control-next:focus { + color: #fff; + text-decoration: none; + outline: 0; + opacity: .9; +} + +.carousel-control-prev { + left: 0; +} + +.carousel-control-next { + right: 0; +} + +.carousel-control-prev-icon, +.carousel-control-next-icon { + display: inline-block; + width: 20px; + height: 20px; + background: transparent no-repeat center center; + background-size: 100% 100%; +} + +.carousel-control-prev-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E"); +} + +.carousel-control-next-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E"); +} + +.carousel-indicators { + position: absolute; + right: 0; + bottom: 10px; + left: 0; + z-index: 15; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + padding-left: 0; + margin-right: 15%; + margin-left: 15%; + list-style: none; +} +.carousel-indicators li { + position: relative; + -webkit-box-flex: 0; + -ms-flex: 0 1 auto; + flex: 0 1 auto; + width: 30px; + height: 3px; + margin-right: 3px; + margin-left: 3px; + text-indent: -999px; + background-color: rgba(255, 255, 255, 0.5); +} +.carousel-indicators li::before { + position: absolute; + top: -10px; + left: 0; + display: inline-block; + width: 100%; + height: 10px; + content: ""; +} +.carousel-indicators li::after { + position: absolute; + bottom: -10px; + left: 0; + display: inline-block; + width: 100%; + height: 10px; + content: ""; +} +.carousel-indicators .active { + background-color: #fff; +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; +} + +.align-baseline { + vertical-align: baseline !important; +} + +.align-top { + vertical-align: top !important; +} + +.align-middle { + vertical-align: middle !important; +} + +.align-bottom { + vertical-align: bottom !important; +} + +.align-text-bottom { + vertical-align: text-bottom !important; +} + +.align-text-top { + vertical-align: text-top !important; +} + +.bg-primary { + background-color: #007bff !important; +} + +a.bg-primary:hover, a.bg-primary:focus, +button.bg-primary:hover, +button.bg-primary:focus { + background-color: #0062cc !important; +} + +.bg-secondary { + background-color: #6c757d !important; +} + +a.bg-secondary:hover, a.bg-secondary:focus, +button.bg-secondary:hover, +button.bg-secondary:focus { + background-color: #545b62 !important; +} + +.bg-success { + background-color: #28a745 !important; +} + +a.bg-success:hover, a.bg-success:focus, +button.bg-success:hover, +button.bg-success:focus { + background-color: #1e7e34 !important; +} + +.bg-info { + background-color: #17a2b8 !important; +} + +a.bg-info:hover, a.bg-info:focus, +button.bg-info:hover, +button.bg-info:focus { + background-color: #117a8b !important; +} + +.bg-warning { + background-color: #ffc107 !important; +} + +a.bg-warning:hover, a.bg-warning:focus, +button.bg-warning:hover, +button.bg-warning:focus { + background-color: #d39e00 !important; +} + +.bg-danger { + background-color: #dc3545 !important; +} + +a.bg-danger:hover, a.bg-danger:focus, +button.bg-danger:hover, +button.bg-danger:focus { + background-color: #bd2130 !important; +} + +.bg-light { + background-color: #f8f9fa !important; +} + +a.bg-light:hover, a.bg-light:focus, +button.bg-light:hover, +button.bg-light:focus { + background-color: #dae0e5 !important; +} + +.bg-dark { + background-color: #343a40 !important; +} + +a.bg-dark:hover, a.bg-dark:focus, +button.bg-dark:hover, +button.bg-dark:focus { + background-color: #1d2124 !important; +} + +.bg-white { + background-color: #fff !important; +} + +.bg-transparent { + background-color: transparent !important; +} + +.border { + border: 1px solid #dee2e6 !important; +} + +.border-top { + border-top: 1px solid #dee2e6 !important; +} + +.border-right { + border-right: 1px solid #dee2e6 !important; +} + +.border-bottom { + border-bottom: 1px solid #dee2e6 !important; +} + +.border-left { + border-left: 1px solid #dee2e6 !important; +} + +.border-0 { + border: 0 !important; +} + +.border-top-0 { + border-top: 0 !important; +} + +.border-right-0 { + border-right: 0 !important; +} + +.border-bottom-0 { + border-bottom: 0 !important; +} + +.border-left-0 { + border-left: 0 !important; +} + +.border-primary { + border-color: #007bff !important; +} + +.border-secondary { + border-color: #6c757d !important; +} + +.border-success { + border-color: #28a745 !important; +} + +.border-info { + border-color: #17a2b8 !important; +} + +.border-warning { + border-color: #ffc107 !important; +} + +.border-danger { + border-color: #dc3545 !important; +} + +.border-light { + border-color: #f8f9fa !important; +} + +.border-dark { + border-color: #343a40 !important; +} + +.border-white { + border-color: #fff !important; +} + +.rounded { + border-radius: 0.25rem !important; +} + +.rounded-top { + border-top-left-radius: 0.25rem !important; + border-top-right-radius: 0.25rem !important; +} + +.rounded-right { + border-top-right-radius: 0.25rem !important; + border-bottom-right-radius: 0.25rem !important; +} + +.rounded-bottom { + border-bottom-right-radius: 0.25rem !important; + border-bottom-left-radius: 0.25rem !important; +} + +.rounded-left { + border-top-left-radius: 0.25rem !important; + border-bottom-left-radius: 0.25rem !important; +} + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-0 { + border-radius: 0 !important; +} + +.clearfix::after { + display: block; + clear: both; + content: ""; +} + +.d-none { + display: none !important; +} + +.d-inline { + display: inline !important; +} + +.d-inline-block { + display: inline-block !important; +} + +.d-block { + display: block !important; +} + +.d-table { + display: table !important; +} + +.d-table-row { + display: table-row !important; +} + +.d-table-cell { + display: table-cell !important; +} + +.d-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; +} + +.d-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; +} + +@media (min-width: 576px) { + .d-sm-none { + display: none !important; + } + + .d-sm-inline { + display: inline !important; + } + + .d-sm-inline-block { + display: inline-block !important; + } + + .d-sm-block { + display: block !important; + } + + .d-sm-table { + display: table !important; + } + + .d-sm-table-row { + display: table-row !important; + } + + .d-sm-table-cell { + display: table-cell !important; + } + + .d-sm-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + + .d-sm-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} +@media (min-width: 768px) { + .d-md-none { + display: none !important; + } + + .d-md-inline { + display: inline !important; + } + + .d-md-inline-block { + display: inline-block !important; + } + + .d-md-block { + display: block !important; + } + + .d-md-table { + display: table !important; + } + + .d-md-table-row { + display: table-row !important; + } + + .d-md-table-cell { + display: table-cell !important; + } + + .d-md-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + + .d-md-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} +@media (min-width: 992px) { + .d-lg-none { + display: none !important; + } + + .d-lg-inline { + display: inline !important; + } + + .d-lg-inline-block { + display: inline-block !important; + } + + .d-lg-block { + display: block !important; + } + + .d-lg-table { + display: table !important; + } + + .d-lg-table-row { + display: table-row !important; + } + + .d-lg-table-cell { + display: table-cell !important; + } + + .d-lg-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + + .d-lg-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} +@media (min-width: 1200px) { + .d-xl-none { + display: none !important; + } + + .d-xl-inline { + display: inline !important; + } + + .d-xl-inline-block { + display: inline-block !important; + } + + .d-xl-block { + display: block !important; + } + + .d-xl-table { + display: table !important; + } + + .d-xl-table-row { + display: table-row !important; + } + + .d-xl-table-cell { + display: table-cell !important; + } + + .d-xl-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + + .d-xl-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} +@media print { + .d-print-none { + display: none !important; + } + + .d-print-inline { + display: inline !important; + } + + .d-print-inline-block { + display: inline-block !important; + } + + .d-print-block { + display: block !important; + } + + .d-print-table { + display: table !important; + } + + .d-print-table-row { + display: table-row !important; + } + + .d-print-table-cell { + display: table-cell !important; + } + + .d-print-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + + .d-print-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} +.embed-responsive { + position: relative; + display: block; + width: 100%; + padding: 0; + overflow: hidden; +} +.embed-responsive::before { + display: block; + content: ""; +} +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object, +.embed-responsive video { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; +} + +.embed-responsive-21by9::before { + padding-top: 42.8571428571%; +} + +.embed-responsive-16by9::before { + padding-top: 56.25%; +} + +.embed-responsive-4by3::before { + padding-top: 75%; +} + +.embed-responsive-1by1::before { + padding-top: 100%; +} + +.flex-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; +} + +.flex-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; +} + +.flex-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; +} + +.flex-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; +} + +.flex-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; +} + +.flex-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; +} + +.flex-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; +} + +.justify-content-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; +} + +.justify-content-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; +} + +.justify-content-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; +} + +.justify-content-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; +} + +.justify-content-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; +} + +.align-items-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; +} + +.align-items-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; +} + +.align-items-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; +} + +.align-items-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; +} + +.align-items-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; +} + +.align-content-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; +} + +.align-content-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; +} + +.align-content-center { + -ms-flex-line-pack: center !important; + align-content: center !important; +} + +.align-content-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; +} + +.align-content-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; +} + +.align-content-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; +} + +.align-self-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; +} + +.align-self-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; +} + +.align-self-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; +} + +.align-self-center { + -ms-flex-item-align: center !important; + align-self: center !important; +} + +.align-self-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; +} + +.align-self-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; +} + +@media (min-width: 576px) { + .flex-sm-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; + } + + .flex-sm-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; + } + + .flex-sm-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + + .flex-sm-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + + .flex-sm-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + + .flex-sm-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + + .flex-sm-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + + .justify-content-sm-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + + .justify-content-sm-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + + .justify-content-sm-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; + } + + .justify-content-sm-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + + .justify-content-sm-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + + .align-items-sm-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; + } + + .align-items-sm-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; + } + + .align-items-sm-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; + } + + .align-items-sm-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + + .align-items-sm-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + + .align-content-sm-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + + .align-content-sm-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + + .align-content-sm-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + + .align-content-sm-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + + .align-content-sm-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + + .align-content-sm-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + + .align-self-sm-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + + .align-self-sm-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + + .align-self-sm-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + + .align-self-sm-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + + .align-self-sm-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + + .align-self-sm-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} +@media (min-width: 768px) { + .flex-md-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; + } + + .flex-md-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; + } + + .flex-md-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + + .flex-md-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + + .flex-md-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + + .flex-md-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + + .flex-md-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + + .justify-content-md-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + + .justify-content-md-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + + .justify-content-md-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; + } + + .justify-content-md-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + + .justify-content-md-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + + .align-items-md-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; + } + + .align-items-md-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; + } + + .align-items-md-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; + } + + .align-items-md-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + + .align-items-md-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + + .align-content-md-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + + .align-content-md-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + + .align-content-md-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + + .align-content-md-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + + .align-content-md-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + + .align-content-md-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + + .align-self-md-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + + .align-self-md-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + + .align-self-md-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + + .align-self-md-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + + .align-self-md-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + + .align-self-md-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} +@media (min-width: 992px) { + .flex-lg-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; + } + + .flex-lg-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; + } + + .flex-lg-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + + .flex-lg-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + + .flex-lg-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + + .flex-lg-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + + .flex-lg-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + + .justify-content-lg-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + + .justify-content-lg-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + + .justify-content-lg-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; + } + + .justify-content-lg-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + + .justify-content-lg-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + + .align-items-lg-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; + } + + .align-items-lg-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; + } + + .align-items-lg-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; + } + + .align-items-lg-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + + .align-items-lg-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + + .align-content-lg-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + + .align-content-lg-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + + .align-content-lg-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + + .align-content-lg-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + + .align-content-lg-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + + .align-content-lg-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + + .align-self-lg-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + + .align-self-lg-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + + .align-self-lg-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + + .align-self-lg-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + + .align-self-lg-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + + .align-self-lg-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} +@media (min-width: 1200px) { + .flex-xl-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; + } + + .flex-xl-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; + } + + .flex-xl-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + + .flex-xl-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + + .flex-xl-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + + .flex-xl-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + + .flex-xl-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + + .justify-content-xl-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + + .justify-content-xl-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + + .justify-content-xl-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; + } + + .justify-content-xl-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + + .justify-content-xl-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + + .align-items-xl-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; + } + + .align-items-xl-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; + } + + .align-items-xl-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; + } + + .align-items-xl-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + + .align-items-xl-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + + .align-content-xl-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + + .align-content-xl-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + + .align-content-xl-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + + .align-content-xl-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + + .align-content-xl-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + + .align-content-xl-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + + .align-self-xl-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + + .align-self-xl-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + + .align-self-xl-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + + .align-self-xl-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + + .align-self-xl-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + + .align-self-xl-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} +.float-left { + float: left !important; +} + +.float-right { + float: right !important; +} + +.float-none { + float: none !important; +} + +@media (min-width: 576px) { + .float-sm-left { + float: left !important; + } + + .float-sm-right { + float: right !important; + } + + .float-sm-none { + float: none !important; + } +} +@media (min-width: 768px) { + .float-md-left { + float: left !important; + } + + .float-md-right { + float: right !important; + } + + .float-md-none { + float: none !important; + } +} +@media (min-width: 992px) { + .float-lg-left { + float: left !important; + } + + .float-lg-right { + float: right !important; + } + + .float-lg-none { + float: none !important; + } +} +@media (min-width: 1200px) { + .float-xl-left { + float: left !important; + } + + .float-xl-right { + float: right !important; + } + + .float-xl-none { + float: none !important; + } +} +.position-static { + position: static !important; +} + +.position-relative { + position: relative !important; +} + +.position-absolute { + position: absolute !important; +} + +.position-fixed { + position: fixed !important; +} + +.position-sticky { + position: -webkit-sticky !important; + position: sticky !important; +} + +.fixed-top { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 1030; +} + +.fixed-bottom { + position: fixed; + right: 0; + bottom: 0; + left: 0; + z-index: 1030; +} + +@supports ((position: -webkit-sticky) or (position: sticky)) { + .sticky-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020; + } +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + -webkit-clip-path: inset(50%); + clip-path: inset(50%); + border: 0; +} + +.sr-only-focusable:active, .sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + overflow: visible; + clip: auto; + white-space: normal; + -webkit-clip-path: none; + clip-path: none; +} + +.w-25 { + width: 25% !important; +} + +.w-50 { + width: 50% !important; +} + +.w-75 { + width: 75% !important; +} + +.w-100 { + width: 100% !important; +} + +.h-25 { + height: 25% !important; +} + +.h-50 { + height: 50% !important; +} + +.h-75 { + height: 75% !important; +} + +.h-100 { + height: 100% !important; +} + +.mw-100 { + max-width: 100% !important; +} + +.mh-100 { + max-height: 100% !important; +} + +.m-0 { + margin: 0 !important; +} + +.mt-0, +.my-0 { + margin-top: 0 !important; +} + +.mr-0, +.mx-0 { + margin-right: 0 !important; +} + +.mb-0, +.my-0 { + margin-bottom: 0 !important; +} + +.ml-0, +.mx-0 { + margin-left: 0 !important; +} + +.m-1 { + margin: 0.25rem !important; +} + +.mt-1, +.my-1 { + margin-top: 0.25rem !important; +} + +.mr-1, +.mx-1 { + margin-right: 0.25rem !important; +} + +.mb-1, +.my-1 { + margin-bottom: 0.25rem !important; +} + +.ml-1, +.mx-1 { + margin-left: 0.25rem !important; +} + +.m-2 { + margin: 0.5rem !important; +} + +.mt-2, +.my-2 { + margin-top: 0.5rem !important; +} + +.mr-2, +.mx-2 { + margin-right: 0.5rem !important; +} + +.mb-2, +.my-2 { + margin-bottom: 0.5rem !important; +} + +.ml-2, +.mx-2 { + margin-left: 0.5rem !important; +} + +.m-3 { + margin: 1rem !important; +} + +.mt-3, +.my-3 { + margin-top: 1rem !important; +} + +.mr-3, +.mx-3 { + margin-right: 1rem !important; +} + +.mb-3, +.my-3 { + margin-bottom: 1rem !important; +} + +.ml-3, +.mx-3 { + margin-left: 1rem !important; +} + +.m-4 { + margin: 1.5rem !important; +} + +.mt-4, +.my-4 { + margin-top: 1.5rem !important; +} + +.mr-4, +.mx-4 { + margin-right: 1.5rem !important; +} + +.mb-4, +.my-4 { + margin-bottom: 1.5rem !important; +} + +.ml-4, +.mx-4 { + margin-left: 1.5rem !important; +} + +.m-5 { + margin: 3rem !important; +} + +.mt-5, +.my-5 { + margin-top: 3rem !important; +} + +.mr-5, +.mx-5 { + margin-right: 3rem !important; +} + +.mb-5, +.my-5 { + margin-bottom: 3rem !important; +} + +.ml-5, +.mx-5 { + margin-left: 3rem !important; +} + +.p-0 { + padding: 0 !important; +} + +.pt-0, +.py-0 { + padding-top: 0 !important; +} + +.pr-0, +.px-0 { + padding-right: 0 !important; +} + +.pb-0, +.py-0 { + padding-bottom: 0 !important; +} + +.pl-0, +.px-0 { + padding-left: 0 !important; +} + +.p-1 { + padding: 0.25rem !important; +} + +.pt-1, +.py-1 { + padding-top: 0.25rem !important; +} + +.pr-1, +.px-1 { + padding-right: 0.25rem !important; +} + +.pb-1, +.py-1 { + padding-bottom: 0.25rem !important; +} + +.pl-1, +.px-1 { + padding-left: 0.25rem !important; +} + +.p-2 { + padding: 0.5rem !important; +} + +.pt-2, +.py-2 { + padding-top: 0.5rem !important; +} + +.pr-2, +.px-2 { + padding-right: 0.5rem !important; +} + +.pb-2, +.py-2 { + padding-bottom: 0.5rem !important; +} + +.pl-2, +.px-2 { + padding-left: 0.5rem !important; +} + +.p-3 { + padding: 1rem !important; +} + +.pt-3, +.py-3 { + padding-top: 1rem !important; +} + +.pr-3, +.px-3 { + padding-right: 1rem !important; +} + +.pb-3, +.py-3 { + padding-bottom: 1rem !important; +} + +.pl-3, +.px-3 { + padding-left: 1rem !important; +} + +.p-4 { + padding: 1.5rem !important; +} + +.pt-4, +.py-4 { + padding-top: 1.5rem !important; +} + +.pr-4, +.px-4 { + padding-right: 1.5rem !important; +} + +.pb-4, +.py-4 { + padding-bottom: 1.5rem !important; +} + +.pl-4, +.px-4 { + padding-left: 1.5rem !important; +} + +.p-5 { + padding: 3rem !important; +} + +.pt-5, +.py-5 { + padding-top: 3rem !important; +} + +.pr-5, +.px-5 { + padding-right: 3rem !important; +} + +.pb-5, +.py-5 { + padding-bottom: 3rem !important; +} + +.pl-5, +.px-5 { + padding-left: 3rem !important; +} + +.m-auto { + margin: auto !important; +} + +.mt-auto, +.my-auto { + margin-top: auto !important; +} + +.mr-auto, +.mx-auto { + margin-right: auto !important; +} + +.mb-auto, +.my-auto { + margin-bottom: auto !important; +} + +.ml-auto, +.mx-auto { + margin-left: auto !important; +} + +@media (min-width: 576px) { + .m-sm-0 { + margin: 0 !important; + } + + .mt-sm-0, + .my-sm-0 { + margin-top: 0 !important; + } + + .mr-sm-0, + .mx-sm-0 { + margin-right: 0 !important; + } + + .mb-sm-0, + .my-sm-0 { + margin-bottom: 0 !important; + } + + .ml-sm-0, + .mx-sm-0 { + margin-left: 0 !important; + } + + .m-sm-1 { + margin: 0.25rem !important; + } + + .mt-sm-1, + .my-sm-1 { + margin-top: 0.25rem !important; + } + + .mr-sm-1, + .mx-sm-1 { + margin-right: 0.25rem !important; + } + + .mb-sm-1, + .my-sm-1 { + margin-bottom: 0.25rem !important; + } + + .ml-sm-1, + .mx-sm-1 { + margin-left: 0.25rem !important; + } + + .m-sm-2 { + margin: 0.5rem !important; + } + + .mt-sm-2, + .my-sm-2 { + margin-top: 0.5rem !important; + } + + .mr-sm-2, + .mx-sm-2 { + margin-right: 0.5rem !important; + } + + .mb-sm-2, + .my-sm-2 { + margin-bottom: 0.5rem !important; + } + + .ml-sm-2, + .mx-sm-2 { + margin-left: 0.5rem !important; + } + + .m-sm-3 { + margin: 1rem !important; + } + + .mt-sm-3, + .my-sm-3 { + margin-top: 1rem !important; + } + + .mr-sm-3, + .mx-sm-3 { + margin-right: 1rem !important; + } + + .mb-sm-3, + .my-sm-3 { + margin-bottom: 1rem !important; + } + + .ml-sm-3, + .mx-sm-3 { + margin-left: 1rem !important; + } + + .m-sm-4 { + margin: 1.5rem !important; + } + + .mt-sm-4, + .my-sm-4 { + margin-top: 1.5rem !important; + } + + .mr-sm-4, + .mx-sm-4 { + margin-right: 1.5rem !important; + } + + .mb-sm-4, + .my-sm-4 { + margin-bottom: 1.5rem !important; + } + + .ml-sm-4, + .mx-sm-4 { + margin-left: 1.5rem !important; + } + + .m-sm-5 { + margin: 3rem !important; + } + + .mt-sm-5, + .my-sm-5 { + margin-top: 3rem !important; + } + + .mr-sm-5, + .mx-sm-5 { + margin-right: 3rem !important; + } + + .mb-sm-5, + .my-sm-5 { + margin-bottom: 3rem !important; + } + + .ml-sm-5, + .mx-sm-5 { + margin-left: 3rem !important; + } + + .p-sm-0 { + padding: 0 !important; + } + + .pt-sm-0, + .py-sm-0 { + padding-top: 0 !important; + } + + .pr-sm-0, + .px-sm-0 { + padding-right: 0 !important; + } + + .pb-sm-0, + .py-sm-0 { + padding-bottom: 0 !important; + } + + .pl-sm-0, + .px-sm-0 { + padding-left: 0 !important; + } + + .p-sm-1 { + padding: 0.25rem !important; + } + + .pt-sm-1, + .py-sm-1 { + padding-top: 0.25rem !important; + } + + .pr-sm-1, + .px-sm-1 { + padding-right: 0.25rem !important; + } + + .pb-sm-1, + .py-sm-1 { + padding-bottom: 0.25rem !important; + } + + .pl-sm-1, + .px-sm-1 { + padding-left: 0.25rem !important; + } + + .p-sm-2 { + padding: 0.5rem !important; + } + + .pt-sm-2, + .py-sm-2 { + padding-top: 0.5rem !important; + } + + .pr-sm-2, + .px-sm-2 { + padding-right: 0.5rem !important; + } + + .pb-sm-2, + .py-sm-2 { + padding-bottom: 0.5rem !important; + } + + .pl-sm-2, + .px-sm-2 { + padding-left: 0.5rem !important; + } + + .p-sm-3 { + padding: 1rem !important; + } + + .pt-sm-3, + .py-sm-3 { + padding-top: 1rem !important; + } + + .pr-sm-3, + .px-sm-3 { + padding-right: 1rem !important; + } + + .pb-sm-3, + .py-sm-3 { + padding-bottom: 1rem !important; + } + + .pl-sm-3, + .px-sm-3 { + padding-left: 1rem !important; + } + + .p-sm-4 { + padding: 1.5rem !important; + } + + .pt-sm-4, + .py-sm-4 { + padding-top: 1.5rem !important; + } + + .pr-sm-4, + .px-sm-4 { + padding-right: 1.5rem !important; + } + + .pb-sm-4, + .py-sm-4 { + padding-bottom: 1.5rem !important; + } + + .pl-sm-4, + .px-sm-4 { + padding-left: 1.5rem !important; + } + + .p-sm-5 { + padding: 3rem !important; + } + + .pt-sm-5, + .py-sm-5 { + padding-top: 3rem !important; + } + + .pr-sm-5, + .px-sm-5 { + padding-right: 3rem !important; + } + + .pb-sm-5, + .py-sm-5 { + padding-bottom: 3rem !important; + } + + .pl-sm-5, + .px-sm-5 { + padding-left: 3rem !important; + } + + .m-sm-auto { + margin: auto !important; + } + + .mt-sm-auto, + .my-sm-auto { + margin-top: auto !important; + } + + .mr-sm-auto, + .mx-sm-auto { + margin-right: auto !important; + } + + .mb-sm-auto, + .my-sm-auto { + margin-bottom: auto !important; + } + + .ml-sm-auto, + .mx-sm-auto { + margin-left: auto !important; + } +} +@media (min-width: 768px) { + .m-md-0 { + margin: 0 !important; + } + + .mt-md-0, + .my-md-0 { + margin-top: 0 !important; + } + + .mr-md-0, + .mx-md-0 { + margin-right: 0 !important; + } + + .mb-md-0, + .my-md-0 { + margin-bottom: 0 !important; + } + + .ml-md-0, + .mx-md-0 { + margin-left: 0 !important; + } + + .m-md-1 { + margin: 0.25rem !important; + } + + .mt-md-1, + .my-md-1 { + margin-top: 0.25rem !important; + } + + .mr-md-1, + .mx-md-1 { + margin-right: 0.25rem !important; + } + + .mb-md-1, + .my-md-1 { + margin-bottom: 0.25rem !important; + } + + .ml-md-1, + .mx-md-1 { + margin-left: 0.25rem !important; + } + + .m-md-2 { + margin: 0.5rem !important; + } + + .mt-md-2, + .my-md-2 { + margin-top: 0.5rem !important; + } + + .mr-md-2, + .mx-md-2 { + margin-right: 0.5rem !important; + } + + .mb-md-2, + .my-md-2 { + margin-bottom: 0.5rem !important; + } + + .ml-md-2, + .mx-md-2 { + margin-left: 0.5rem !important; + } + + .m-md-3 { + margin: 1rem !important; + } + + .mt-md-3, + .my-md-3 { + margin-top: 1rem !important; + } + + .mr-md-3, + .mx-md-3 { + margin-right: 1rem !important; + } + + .mb-md-3, + .my-md-3 { + margin-bottom: 1rem !important; + } + + .ml-md-3, + .mx-md-3 { + margin-left: 1rem !important; + } + + .m-md-4 { + margin: 1.5rem !important; + } + + .mt-md-4, + .my-md-4 { + margin-top: 1.5rem !important; + } + + .mr-md-4, + .mx-md-4 { + margin-right: 1.5rem !important; + } + + .mb-md-4, + .my-md-4 { + margin-bottom: 1.5rem !important; + } + + .ml-md-4, + .mx-md-4 { + margin-left: 1.5rem !important; + } + + .m-md-5 { + margin: 3rem !important; + } + + .mt-md-5, + .my-md-5 { + margin-top: 3rem !important; + } + + .mr-md-5, + .mx-md-5 { + margin-right: 3rem !important; + } + + .mb-md-5, + .my-md-5 { + margin-bottom: 3rem !important; + } + + .ml-md-5, + .mx-md-5 { + margin-left: 3rem !important; + } + + .p-md-0 { + padding: 0 !important; + } + + .pt-md-0, + .py-md-0 { + padding-top: 0 !important; + } + + .pr-md-0, + .px-md-0 { + padding-right: 0 !important; + } + + .pb-md-0, + .py-md-0 { + padding-bottom: 0 !important; + } + + .pl-md-0, + .px-md-0 { + padding-left: 0 !important; + } + + .p-md-1 { + padding: 0.25rem !important; + } + + .pt-md-1, + .py-md-1 { + padding-top: 0.25rem !important; + } + + .pr-md-1, + .px-md-1 { + padding-right: 0.25rem !important; + } + + .pb-md-1, + .py-md-1 { + padding-bottom: 0.25rem !important; + } + + .pl-md-1, + .px-md-1 { + padding-left: 0.25rem !important; + } + + .p-md-2 { + padding: 0.5rem !important; + } + + .pt-md-2, + .py-md-2 { + padding-top: 0.5rem !important; + } + + .pr-md-2, + .px-md-2 { + padding-right: 0.5rem !important; + } + + .pb-md-2, + .py-md-2 { + padding-bottom: 0.5rem !important; + } + + .pl-md-2, + .px-md-2 { + padding-left: 0.5rem !important; + } + + .p-md-3 { + padding: 1rem !important; + } + + .pt-md-3, + .py-md-3 { + padding-top: 1rem !important; + } + + .pr-md-3, + .px-md-3 { + padding-right: 1rem !important; + } + + .pb-md-3, + .py-md-3 { + padding-bottom: 1rem !important; + } + + .pl-md-3, + .px-md-3 { + padding-left: 1rem !important; + } + + .p-md-4 { + padding: 1.5rem !important; + } + + .pt-md-4, + .py-md-4 { + padding-top: 1.5rem !important; + } + + .pr-md-4, + .px-md-4 { + padding-right: 1.5rem !important; + } + + .pb-md-4, + .py-md-4 { + padding-bottom: 1.5rem !important; + } + + .pl-md-4, + .px-md-4 { + padding-left: 1.5rem !important; + } + + .p-md-5 { + padding: 3rem !important; + } + + .pt-md-5, + .py-md-5 { + padding-top: 3rem !important; + } + + .pr-md-5, + .px-md-5 { + padding-right: 3rem !important; + } + + .pb-md-5, + .py-md-5 { + padding-bottom: 3rem !important; + } + + .pl-md-5, + .px-md-5 { + padding-left: 3rem !important; + } + + .m-md-auto { + margin: auto !important; + } + + .mt-md-auto, + .my-md-auto { + margin-top: auto !important; + } + + .mr-md-auto, + .mx-md-auto { + margin-right: auto !important; + } + + .mb-md-auto, + .my-md-auto { + margin-bottom: auto !important; + } + + .ml-md-auto, + .mx-md-auto { + margin-left: auto !important; + } +} +@media (min-width: 992px) { + .m-lg-0 { + margin: 0 !important; + } + + .mt-lg-0, + .my-lg-0 { + margin-top: 0 !important; + } + + .mr-lg-0, + .mx-lg-0 { + margin-right: 0 !important; + } + + .mb-lg-0, + .my-lg-0 { + margin-bottom: 0 !important; + } + + .ml-lg-0, + .mx-lg-0 { + margin-left: 0 !important; + } + + .m-lg-1 { + margin: 0.25rem !important; + } + + .mt-lg-1, + .my-lg-1 { + margin-top: 0.25rem !important; + } + + .mr-lg-1, + .mx-lg-1 { + margin-right: 0.25rem !important; + } + + .mb-lg-1, + .my-lg-1 { + margin-bottom: 0.25rem !important; + } + + .ml-lg-1, + .mx-lg-1 { + margin-left: 0.25rem !important; + } + + .m-lg-2 { + margin: 0.5rem !important; + } + + .mt-lg-2, + .my-lg-2 { + margin-top: 0.5rem !important; + } + + .mr-lg-2, + .mx-lg-2 { + margin-right: 0.5rem !important; + } + + .mb-lg-2, + .my-lg-2 { + margin-bottom: 0.5rem !important; + } + + .ml-lg-2, + .mx-lg-2 { + margin-left: 0.5rem !important; + } + + .m-lg-3 { + margin: 1rem !important; + } + + .mt-lg-3, + .my-lg-3 { + margin-top: 1rem !important; + } + + .mr-lg-3, + .mx-lg-3 { + margin-right: 1rem !important; + } + + .mb-lg-3, + .my-lg-3 { + margin-bottom: 1rem !important; + } + + .ml-lg-3, + .mx-lg-3 { + margin-left: 1rem !important; + } + + .m-lg-4 { + margin: 1.5rem !important; + } + + .mt-lg-4, + .my-lg-4 { + margin-top: 1.5rem !important; + } + + .mr-lg-4, + .mx-lg-4 { + margin-right: 1.5rem !important; + } + + .mb-lg-4, + .my-lg-4 { + margin-bottom: 1.5rem !important; + } + + .ml-lg-4, + .mx-lg-4 { + margin-left: 1.5rem !important; + } + + .m-lg-5 { + margin: 3rem !important; + } + + .mt-lg-5, + .my-lg-5 { + margin-top: 3rem !important; + } + + .mr-lg-5, + .mx-lg-5 { + margin-right: 3rem !important; + } + + .mb-lg-5, + .my-lg-5 { + margin-bottom: 3rem !important; + } + + .ml-lg-5, + .mx-lg-5 { + margin-left: 3rem !important; + } + + .p-lg-0 { + padding: 0 !important; + } + + .pt-lg-0, + .py-lg-0 { + padding-top: 0 !important; + } + + .pr-lg-0, + .px-lg-0 { + padding-right: 0 !important; + } + + .pb-lg-0, + .py-lg-0 { + padding-bottom: 0 !important; + } + + .pl-lg-0, + .px-lg-0 { + padding-left: 0 !important; + } + + .p-lg-1 { + padding: 0.25rem !important; + } + + .pt-lg-1, + .py-lg-1 { + padding-top: 0.25rem !important; + } + + .pr-lg-1, + .px-lg-1 { + padding-right: 0.25rem !important; + } + + .pb-lg-1, + .py-lg-1 { + padding-bottom: 0.25rem !important; + } + + .pl-lg-1, + .px-lg-1 { + padding-left: 0.25rem !important; + } + + .p-lg-2 { + padding: 0.5rem !important; + } + + .pt-lg-2, + .py-lg-2 { + padding-top: 0.5rem !important; + } + + .pr-lg-2, + .px-lg-2 { + padding-right: 0.5rem !important; + } + + .pb-lg-2, + .py-lg-2 { + padding-bottom: 0.5rem !important; + } + + .pl-lg-2, + .px-lg-2 { + padding-left: 0.5rem !important; + } + + .p-lg-3 { + padding: 1rem !important; + } + + .pt-lg-3, + .py-lg-3 { + padding-top: 1rem !important; + } + + .pr-lg-3, + .px-lg-3 { + padding-right: 1rem !important; + } + + .pb-lg-3, + .py-lg-3 { + padding-bottom: 1rem !important; + } + + .pl-lg-3, + .px-lg-3 { + padding-left: 1rem !important; + } + + .p-lg-4 { + padding: 1.5rem !important; + } + + .pt-lg-4, + .py-lg-4 { + padding-top: 1.5rem !important; + } + + .pr-lg-4, + .px-lg-4 { + padding-right: 1.5rem !important; + } + + .pb-lg-4, + .py-lg-4 { + padding-bottom: 1.5rem !important; + } + + .pl-lg-4, + .px-lg-4 { + padding-left: 1.5rem !important; + } + + .p-lg-5 { + padding: 3rem !important; + } + + .pt-lg-5, + .py-lg-5 { + padding-top: 3rem !important; + } + + .pr-lg-5, + .px-lg-5 { + padding-right: 3rem !important; + } + + .pb-lg-5, + .py-lg-5 { + padding-bottom: 3rem !important; + } + + .pl-lg-5, + .px-lg-5 { + padding-left: 3rem !important; + } + + .m-lg-auto { + margin: auto !important; + } + + .mt-lg-auto, + .my-lg-auto { + margin-top: auto !important; + } + + .mr-lg-auto, + .mx-lg-auto { + margin-right: auto !important; + } + + .mb-lg-auto, + .my-lg-auto { + margin-bottom: auto !important; + } + + .ml-lg-auto, + .mx-lg-auto { + margin-left: auto !important; + } +} +@media (min-width: 1200px) { + .m-xl-0 { + margin: 0 !important; + } + + .mt-xl-0, + .my-xl-0 { + margin-top: 0 !important; + } + + .mr-xl-0, + .mx-xl-0 { + margin-right: 0 !important; + } + + .mb-xl-0, + .my-xl-0 { + margin-bottom: 0 !important; + } + + .ml-xl-0, + .mx-xl-0 { + margin-left: 0 !important; + } + + .m-xl-1 { + margin: 0.25rem !important; + } + + .mt-xl-1, + .my-xl-1 { + margin-top: 0.25rem !important; + } + + .mr-xl-1, + .mx-xl-1 { + margin-right: 0.25rem !important; + } + + .mb-xl-1, + .my-xl-1 { + margin-bottom: 0.25rem !important; + } + + .ml-xl-1, + .mx-xl-1 { + margin-left: 0.25rem !important; + } + + .m-xl-2 { + margin: 0.5rem !important; + } + + .mt-xl-2, + .my-xl-2 { + margin-top: 0.5rem !important; + } + + .mr-xl-2, + .mx-xl-2 { + margin-right: 0.5rem !important; + } + + .mb-xl-2, + .my-xl-2 { + margin-bottom: 0.5rem !important; + } + + .ml-xl-2, + .mx-xl-2 { + margin-left: 0.5rem !important; + } + + .m-xl-3 { + margin: 1rem !important; + } + + .mt-xl-3, + .my-xl-3 { + margin-top: 1rem !important; + } + + .mr-xl-3, + .mx-xl-3 { + margin-right: 1rem !important; + } + + .mb-xl-3, + .my-xl-3 { + margin-bottom: 1rem !important; + } + + .ml-xl-3, + .mx-xl-3 { + margin-left: 1rem !important; + } + + .m-xl-4 { + margin: 1.5rem !important; + } + + .mt-xl-4, + .my-xl-4 { + margin-top: 1.5rem !important; + } + + .mr-xl-4, + .mx-xl-4 { + margin-right: 1.5rem !important; + } + + .mb-xl-4, + .my-xl-4 { + margin-bottom: 1.5rem !important; + } + + .ml-xl-4, + .mx-xl-4 { + margin-left: 1.5rem !important; + } + + .m-xl-5 { + margin: 3rem !important; + } + + .mt-xl-5, + .my-xl-5 { + margin-top: 3rem !important; + } + + .mr-xl-5, + .mx-xl-5 { + margin-right: 3rem !important; + } + + .mb-xl-5, + .my-xl-5 { + margin-bottom: 3rem !important; + } + + .ml-xl-5, + .mx-xl-5 { + margin-left: 3rem !important; + } + + .p-xl-0 { + padding: 0 !important; + } + + .pt-xl-0, + .py-xl-0 { + padding-top: 0 !important; + } + + .pr-xl-0, + .px-xl-0 { + padding-right: 0 !important; + } + + .pb-xl-0, + .py-xl-0 { + padding-bottom: 0 !important; + } + + .pl-xl-0, + .px-xl-0 { + padding-left: 0 !important; + } + + .p-xl-1 { + padding: 0.25rem !important; + } + + .pt-xl-1, + .py-xl-1 { + padding-top: 0.25rem !important; + } + + .pr-xl-1, + .px-xl-1 { + padding-right: 0.25rem !important; + } + + .pb-xl-1, + .py-xl-1 { + padding-bottom: 0.25rem !important; + } + + .pl-xl-1, + .px-xl-1 { + padding-left: 0.25rem !important; + } + + .p-xl-2 { + padding: 0.5rem !important; + } + + .pt-xl-2, + .py-xl-2 { + padding-top: 0.5rem !important; + } + + .pr-xl-2, + .px-xl-2 { + padding-right: 0.5rem !important; + } + + .pb-xl-2, + .py-xl-2 { + padding-bottom: 0.5rem !important; + } + + .pl-xl-2, + .px-xl-2 { + padding-left: 0.5rem !important; + } + + .p-xl-3 { + padding: 1rem !important; + } + + .pt-xl-3, + .py-xl-3 { + padding-top: 1rem !important; + } + + .pr-xl-3, + .px-xl-3 { + padding-right: 1rem !important; + } + + .pb-xl-3, + .py-xl-3 { + padding-bottom: 1rem !important; + } + + .pl-xl-3, + .px-xl-3 { + padding-left: 1rem !important; + } + + .p-xl-4 { + padding: 1.5rem !important; + } + + .pt-xl-4, + .py-xl-4 { + padding-top: 1.5rem !important; + } + + .pr-xl-4, + .px-xl-4 { + padding-right: 1.5rem !important; + } + + .pb-xl-4, + .py-xl-4 { + padding-bottom: 1.5rem !important; + } + + .pl-xl-4, + .px-xl-4 { + padding-left: 1.5rem !important; + } + + .p-xl-5 { + padding: 3rem !important; + } + + .pt-xl-5, + .py-xl-5 { + padding-top: 3rem !important; + } + + .pr-xl-5, + .px-xl-5 { + padding-right: 3rem !important; + } + + .pb-xl-5, + .py-xl-5 { + padding-bottom: 3rem !important; + } + + .pl-xl-5, + .px-xl-5 { + padding-left: 3rem !important; + } + + .m-xl-auto { + margin: auto !important; + } + + .mt-xl-auto, + .my-xl-auto { + margin-top: auto !important; + } + + .mr-xl-auto, + .mx-xl-auto { + margin-right: auto !important; + } + + .mb-xl-auto, + .my-xl-auto { + margin-bottom: auto !important; + } + + .ml-xl-auto, + .mx-xl-auto { + margin-left: auto !important; + } +} +.text-justify { + text-align: justify !important; +} + +.text-nowrap { + white-space: nowrap !important; +} + +.text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.text-left { + text-align: left !important; +} + +.text-right { + text-align: right !important; +} + +.text-center { + text-align: center !important; +} + +@media (min-width: 576px) { + .text-sm-left { + text-align: left !important; + } + + .text-sm-right { + text-align: right !important; + } + + .text-sm-center { + text-align: center !important; + } +} +@media (min-width: 768px) { + .text-md-left { + text-align: left !important; + } + + .text-md-right { + text-align: right !important; + } + + .text-md-center { + text-align: center !important; + } +} +@media (min-width: 992px) { + .text-lg-left { + text-align: left !important; + } + + .text-lg-right { + text-align: right !important; + } + + .text-lg-center { + text-align: center !important; + } +} +@media (min-width: 1200px) { + .text-xl-left { + text-align: left !important; + } + + .text-xl-right { + text-align: right !important; + } + + .text-xl-center { + text-align: center !important; + } +} +.text-lowercase { + text-transform: lowercase !important; +} + +.text-uppercase { + text-transform: uppercase !important; +} + +.text-capitalize { + text-transform: capitalize !important; +} + +.font-weight-light { + font-weight: 300 !important; +} + +.font-weight-normal { + font-weight: 400 !important; +} + +.font-weight-bold { + font-weight: 700 !important; +} + +.font-italic { + font-style: italic !important; +} + +.text-white { + color: #fff !important; +} + +.text-primary { + color: #007bff !important; +} + +a.text-primary:hover, a.text-primary:focus { + color: #0062cc !important; +} + +.text-secondary { + color: #6c757d !important; +} + +a.text-secondary:hover, a.text-secondary:focus { + color: #545b62 !important; +} + +.text-success { + color: #28a745 !important; +} + +a.text-success:hover, a.text-success:focus { + color: #1e7e34 !important; +} + +.text-info { + color: #17a2b8 !important; +} + +a.text-info:hover, a.text-info:focus { + color: #117a8b !important; +} + +.text-warning { + color: #ffc107 !important; +} + +a.text-warning:hover, a.text-warning:focus { + color: #d39e00 !important; +} + +.text-danger { + color: #dc3545 !important; +} + +a.text-danger:hover, a.text-danger:focus { + color: #bd2130 !important; +} + +.text-light { + color: #f8f9fa !important; +} + +a.text-light:hover, a.text-light:focus { + color: #dae0e5 !important; +} + +.text-dark { + color: #343a40 !important; +} + +a.text-dark:hover, a.text-dark:focus { + color: #1d2124 !important; +} + +.text-muted { + color: #6c757d !important; +} + +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.visible { + visibility: visible !important; +} + +.invisible { + visibility: hidden !important; +} + +@media print { + *, + *::before, + *::after { + text-shadow: none !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + } + + a:not(.btn) { + text-decoration: underline; + } + + abbr[title]::after { + content: " (" attr(title) ")"; + } + + pre { + white-space: pre-wrap !important; + } + + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + + thead { + display: table-header-group; + } + + tr, + img { + page-break-inside: avoid; + } + + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + + h2, + h3 { + page-break-after: avoid; + } + + @page { + size: a3; + } + body { + min-width: 992px !important; + } + + .container { + min-width: 992px !important; + } + + .navbar { + display: none; + } + + .badge { + border: 1px solid #000; + } + + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +/*Github syntax highlighting theme via Rouge*/ +.highlight table td { + padding: 5px; +} + +.highlight table pre { + margin: 0; +} + +.highlight .cm { + color: #999988; + font-style: italic; +} + +.highlight .cp { + color: #999999; + font-weight: bold; +} + +.highlight .c1 { + color: #999988; + font-style: italic; +} + +.highlight .cs { + color: #999999; + font-weight: bold; + font-style: italic; +} + +.highlight .c, .highlight .cd { + color: #999988; + font-style: italic; +} + +.highlight .err { + color: #a61717; + background-color: #e3d2d2; +} + +.highlight .gd { + color: #000000; + background-color: #ffdddd; +} + +.highlight .ge { + color: #000000; + font-style: italic; +} + +.highlight .gr { + color: #aa0000; +} + +.highlight .gh { + color: #999999; +} + +.highlight .gi { + color: #000000; + background-color: #ddffdd; +} + +.highlight .go { + color: #888888; +} + +.highlight .gp { + color: #555555; +} + +.highlight .gs { + font-weight: bold; +} + +.highlight .gu { + color: #aaaaaa; +} + +.highlight .gt { + color: #aa0000; +} + +.highlight .kc { + color: #000000; + font-weight: bold; +} + +.highlight .kd { + color: #000000; + font-weight: bold; +} + +.highlight .kn { + color: #000000; + font-weight: bold; +} + +.highlight .kp { + color: #000000; + font-weight: bold; +} + +.highlight .kr { + color: #000000; + font-weight: bold; +} + +.highlight .kt { + color: #445588; + font-weight: bold; +} + +.highlight .k, .highlight .kv { + color: #000000; + font-weight: bold; +} + +.highlight .mf { + color: #009999; +} + +.highlight .mh { + color: #009999; +} + +.highlight .il { + color: #009999; +} + +.highlight .mi { + color: #009999; +} + +.highlight .mo { + color: #009999; +} + +.highlight .m, .highlight .mb, .highlight .mx { + color: #009999; +} + +.highlight .sb { + color: #d14; +} + +.highlight .sc { + color: #d14; +} + +.highlight .sd { + color: #d14; +} + +.highlight .s2 { + color: #d14; +} + +.highlight .se { + color: #d14; +} + +.highlight .sh { + color: #d14; +} + +.highlight .si { + color: #d14; +} + +.highlight .sx { + color: #d14; +} + +.highlight .sr { + color: #009926; +} + +.highlight .s1 { + color: #d14; +} + +.highlight .ss { + color: #990073; +} + +.highlight .s { + color: #d14; +} + +.highlight .na { + color: #008080; +} + +.highlight .bp { + color: #999999; +} + +.highlight .nb { + color: #0086B3; +} + +.highlight .nc { + color: #445588; + font-weight: bold; +} + +.highlight .no { + color: #008080; +} + +.highlight .nd { + color: #3c5d5d; + font-weight: bold; +} + +.highlight .ni { + color: #800080; +} + +.highlight .ne { + color: #990000; + font-weight: bold; +} + +.highlight .nf { + color: #990000; + font-weight: bold; +} + +.highlight .nl { + color: #990000; + font-weight: bold; +} + +.highlight .nn { + color: #555555; +} + +.highlight .nt { + color: #000080; +} + +.highlight .vc { + color: #008080; +} + +.highlight .vg { + color: #008080; +} + +.highlight .vi { + color: #008080; +} + +.highlight .nv { + color: #008080; +} + +.highlight .ow { + color: #000000; + font-weight: bold; +} + +.highlight .o { + color: #000000; + font-weight: bold; +} + +.highlight .w { + color: #bbbbbb; +} + +.highlight { + background-color: #f8f8f8; +} + +@font-face { + font-family: FreightSans; + font-weight: 700; + font-style: normal; + src: url("../fonts/FreightSans/freight-sans-bold.woff2") format("woff2"), url("../fonts/FreightSans/freight-sans-bold.woff") format("woff"); +} +@font-face { + font-family: FreightSans; + font-weight: 700; + font-style: italic; + src: url("../fonts/FreightSans/freight-sans-bold-italic.woff2") format("woff2"), url("../fonts/FreightSans/freight-sans-bold-italic.woff") format("woff"); +} +@font-face { + font-family: FreightSans; + font-weight: 500; + font-style: normal; + src: url("../fonts/FreightSans/freight-sans-medium.woff2") format("woff2"), url("../fonts/FreightSans/freight-sans-medium.woff") format("woff"); +} +@font-face { + font-family: FreightSans; + font-weight: 500; + font-style: italic; + src: url("../fonts/FreightSans/freight-sans-medium-italic.woff2") format("woff2"), url("../fonts/FreightSans/freight-sans-medium-italic.woff") format("woff"); +} +@font-face { + font-family: FreightSans; + font-weight: 100; + font-style: normal; + src: url("../fonts/FreightSans/freight-sans-light.woff2") format("woff2"), url("../fonts/FreightSans/freight-sans-light.woff") format("woff"); +} +@font-face { + font-family: FreightSans; + font-weight: 100; + font-style: italic; + src: url("../fonts/FreightSans/freight-sans-light-italic.woff2") format("woff2"), url("../fonts/FreightSans/freight-sans-light-italic.woff") format("woff"); +} +@font-face { + font-family: FreightSans; + font-weight: 400; + font-style: italic; + src: url("../fonts/FreightSans/freight-sans-book-italic.woff2") format("woff2"), url("../fonts/FreightSans/freight-sans-book-italic.woff") format("woff"); +} +@font-face { + font-family: FreightSans; + font-weight: 400; + font-style: normal; + src: url("../fonts/FreightSans/freight-sans-book.woff2") format("woff2"), url("../fonts/FreightSans/freight-sans-book.woff") format("woff"); +} +@font-face { + font-family: IBMPlexMono; + font-weight: 600; + font-style: normal; + unicode-range: u+0020-007f; + src: local("IBMPlexMono-SemiBold"), url("../fonts/IBMPlexMono/IBMPlexMono-SemiBold.woff2") format("woff2"), url("../fonts/IBMPlexMono/IBMPlexMono-SemiBold.woff") format("woff"); +} +@font-face { + font-family: IBMPlexMono; + font-weight: 500; + font-style: normal; + unicode-range: u+0020-007f; + src: local("IBMPlexMono-Medium"), url("../fonts/IBMPlexMono/IBMPlexMono-Medium.woff2") format("woff2"), url("../fonts/IBMPlexMono/IBMPlexMono-Medium.woff") format("woff"); +} +@font-face { + font-family: IBMPlexMono; + font-weight: 400; + font-style: normal; + unicode-range: u+0020-007f; + src: local("IBMPlexMono-Regular"), url("../fonts/IBMPlexMono/IBMPlexMono-Regular.woff2") format("woff2"), url("../fonts/IBMPlexMono/IBMPlexMono-Regular.woff") format("woff"); +} +@font-face { + font-family: IBMPlexMono; + font-weight: 300; + font-style: normal; + unicode-range: u+0020-007f; + src: local("IBMPlexMono-Light"), url("../fonts/IBMPlexMono/IBMPlexMono-Light.woff2") format("woff2"), url("../fonts/IBMPlexMono/IBMPlexMono-Light.woff") format("woff"); +} +html { + position: relative; + min-height: 100%; + font-size: 12px; +} +@media screen and (min-width: 768px) { + html { + font-size: 16px; + } +} + +* { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +body { + font-family: FreightSans, Helvetica Neue, Helvetica, Arial, sans-serif; +} + +a:link, +a:visited, +a:hover { + text-decoration: none; + color: #e44c2c; +} + +a.with-right-arrow, .btn.with-right-arrow { + padding-right: 1.375rem; + position: relative; + background-image: url("../images/chevron-right-orange.svg"); + background-size: 6px 13px; + background-position: center right 5px; + background-repeat: no-repeat; +} +@media screen and (min-width: 768px) { + a.with-right-arrow, .btn.with-right-arrow { + background-size: 8px 14px; + background-position: center right 12px; + padding-right: 2rem; + } +} + +::-webkit-input-placeholder { + color: #e44c2c; +} + +::-moz-placeholder { + color: #e44c2c; +} + +:-ms-input-placeholder { + color: #e44c2c; +} + +:-moz-placeholder { + color: #e44c2c; +} + +.email-subscribe-form input.email { + color: #e44c2c; + border: none; + border-bottom: 1px solid #939393; + width: 100%; + background-color: transparent; + outline: none; + font-size: 1.125rem; + letter-spacing: 0.25px; + line-height: 2.25rem; +} +.email-subscribe-form input[type="submit"] { + position: absolute; + right: 0; + top: 10px; + height: 15px; + width: 15px; + background-image: url("../images/arrow-right-with-tail.svg"); + background-color: transparent; + background-repeat: no-repeat; + background-size: 15px 15px; + background-position: center center; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border: 0; +} + +.email-subscribe-form-fields-wrapper { + position: relative; +} + +.anchorjs-link { + color: #6c6c6d !important; +} +@media screen and (min-width: 768px) { + .anchorjs-link:hover { + color: inherit; + text-decoration: none !important; + } +} + +.pytorch-article #table-of-contents { + display: none; +} + +code, kbd, pre, samp { + font-family: IBMPlexMono,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; +} +code span, kbd span, pre span, samp span { + font-family: IBMPlexMono,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; +} + +pre { + padding: 1.125rem; + background-color: #f3f4f7; +} +pre code { + font-size: 0.875rem; +} +pre.highlight { + background-color: #f3f4f7; + line-height: 1.3125rem; +} + +code.highlighter-rouge { + color: #6c6c6d; + background-color: #f3f4f7; + padding: 2px 6px; +} + +a:link code.highlighter-rouge, +a:visited code.highlighter-rouge, +a:hover code.highlighter-rouge { + color: #4974D1; +} +a:link.has-code, +a:visited.has-code, +a:hover.has-code { + color: #4974D1; +} + +p code, +h1 code, +h2 code, +h3 code, +h4 code, +h5 code, +h6 code { + font-size: 78.5%; +} + +pre { + white-space: pre-wrap; + white-space: -moz-pre-wrap; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word; +} + +.header-holder { + height: 68px; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + left: 0; + margin-left: auto; + margin-right: auto; + position: fixed; + right: 0; + top: 0; + width: 100%; + z-index: 9999; + background-color: #ffffff; + border-bottom: 1px solid #e2e2e2; +} +@media screen and (min-width: 1100px) { + .header-holder { + height: 90px; + } +} + +.header-container { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.header-container:before, .header-container:after { + content: ""; + display: table; +} +.header-container:after { + clear: both; +} +.header-container { + *zoom: 1; +} +@media screen and (min-width: 1100px) { + .header-container { + display: block; + } +} + +.header-logo { + height: 23px; + width: 93px; + background-image: url("../images/logo.svg"); + background-repeat: no-repeat; + background-size: 93px 23px; + display: block; + float: left; + z-index: 10; +} +@media screen and (min-width: 1100px) { + .header-logo { + background-size: 108px 27px; + position: absolute; + height: 27px; + width: 108px; + top: 4px; + float: none; + } +} + +.main-menu-open-button { + background-image: url("../images/icon-menu-dots.svg"); + background-position: center center; + background-size: 25px 7px; + background-repeat: no-repeat; + width: 25px; + height: 17px; + position: absolute; + right: 0; + top: 4px; +} +@media screen and (min-width: 1100px) { + .main-menu-open-button { + display: none; + } +} + +.header-holder .main-menu { + display: none; +} +@media screen and (min-width: 1100px) { + .header-holder .main-menu { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; + } +} +.header-holder .main-menu ul { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + margin: 0; +} +.header-holder .main-menu ul li { + display: inline-block; + margin-right: 40px; + position: relative; +} +.header-holder .main-menu ul li.active:after { + content: "•"; + bottom: -24px; + color: #e44c2c; + font-size: 1.375rem; + left: 0; + position: absolute; + right: 0; + text-align: center; +} +.header-holder .main-menu ul li.active a { + color: #e44c2c; +} +.header-holder .main-menu ul li:last-of-type { + margin-right: 0; +} +.header-holder .main-menu ul li a { + color: #ffffff; + font-size: 1.125rem; + letter-spacing: 0; + line-height: 2.125rem; + text-align: center; + text-decoration: none; +} +@media screen and (min-width: 1100px) { + .header-holder .main-menu ul li a:hover { + color: #e44c2c; + } +} + +.mobile-main-menu { + display: none; +} +.mobile-main-menu.open { + background-color: #262626; + display: block; + height: 100%; + left: 0; + margin-left: auto; + margin-right: auto; + min-height: 100%; + position: fixed; + right: 0; + top: 0; + width: 100%; + z-index: 99999; +} + +.mobile-main-menu .container-fluid { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + height: 68px; + position: relative; +} +.mobile-main-menu .container-fluid:before, .mobile-main-menu .container-fluid:after { + content: ""; + display: table; +} +.mobile-main-menu .container-fluid:after { + clear: both; +} +.mobile-main-menu .container-fluid { + *zoom: 1; +} + +.mobile-main-menu.open ul { + list-style-type: none; + padding: 0; +} +.mobile-main-menu.open ul li a { + font-size: 2rem; + color: #ffffff; + letter-spacing: 0; + line-height: 4rem; + text-decoration: none; +} +.mobile-main-menu.open ul li.active a { + color: #e44c2c; +} + +.main-menu-close-button { + background-image: url("../images/icon-close.svg"); + background-position: center center; + background-repeat: no-repeat; + background-size: 24px 24px; + height: 24px; + position: absolute; + right: 0; + width: 24px; + top: -4px; +} + +.mobile-main-menu-header-container { + position: relative; +} + +.mobile-main-menu-links-container { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + padding-left: 2.8125rem; + height: 100%; + min-height: 100%; + margin-top: -68px; +} + +.site-footer { + padding: 2.5rem 0; + width: 100%; + background: #000000; + background-size: 100%; + margin-left: 0; + margin-right: 0; + position: relative; + z-index: 201; +} +@media screen and (min-width: 768px) { + .site-footer { + padding: 5rem 0; + } +} +.site-footer p { + color: #ffffff; +} +.site-footer ul { + list-style-type: none; + padding-left: 0; + margin-bottom: 0; +} +.site-footer ul li { + font-size: 1.125rem; + line-height: 2rem; + color: #A0A0A1; + padding-bottom: 0.375rem; +} +.site-footer ul li.list-title { + padding-bottom: 0.75rem; + color: #ffffff; +} +.site-footer a:link, +.site-footer a:visited { + color: inherit; +} +@media screen and (min-width: 768px) { + .site-footer a:hover { + color: #e44c2c; + } +} + +.docs-tutorials-resources { + background-color: #262626; + color: #ffffff; + padding-top: 2.5rem; + padding-bottom: 2.5rem; + position: relative; + z-index: 201; +} +@media screen and (min-width: 768px) { + .docs-tutorials-resources { + padding-top: 5rem; + padding-bottom: 5rem; + } +} +.docs-tutorials-resources p { + color: #929292; + font-size: 1.125rem; +} +.docs-tutorials-resources h2 { + font-size: 1.5rem; + letter-spacing: -0.25px; + text-transform: none; + margin-bottom: 0.25rem; +} +@media screen and (min-width: 768px) { + .docs-tutorials-resources h2 { + margin-bottom: 1.25rem; + } +} +.docs-tutorials-resources .col-md-4 { + margin-bottom: 2rem; + text-align: center; +} +@media screen and (min-width: 768px) { + .docs-tutorials-resources .col-md-4 { + margin-bottom: 0; + } +} +.docs-tutorials-resources .with-right-arrow { + margin-left: 12px; +} +.docs-tutorials-resources .with-right-arrow:hover { + background-image: url("../images/chevron-right-white.svg"); +} +.docs-tutorials-resources p { + font-size: 1rem; + line-height: 1.5rem; + letter-spacing: 0.22px; + color: #939393; + margin-bottom: 0; +} +@media screen and (min-width: 768px) { + .docs-tutorials-resources p { + margin-bottom: 1.25rem; + } +} +.docs-tutorials-resources a { + font-size: 1.125rem; + color: #e44c2c; +} +.docs-tutorials-resources a:hover { + color: #ffffff; +} + +.footer-container { + position: relative; +} + +@media screen and (min-width: 768px) { + .footer-logo-wrapper { + position: absolute; + top: 0; + left: 30px; + } +} + +.footer-logo { + background-image: url("../images/logo-icon.svg"); + background-position: center; + background-repeat: no-repeat; + background-size: 20px 24px; + display: block; + height: 24px; + margin-bottom: 2.8125rem; + width: 20px; +} +@media screen and (min-width: 768px) { + .footer-logo { + background-size: 29px 36px; + height: 36px; + margin-bottom: 0; + margin-bottom: 0; + width: 29px; + } +} + +.footer-links-wrapper { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} +@media screen and (min-width: 768px) { + .footer-links-wrapper { + -ms-flex-wrap: initial; + flex-wrap: initial; + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; + } +} + +.footer-links-col { + margin-bottom: 3.75rem; + width: 50%; +} +@media screen and (min-width: 768px) { + .footer-links-col { + margin-bottom: 0; + width: 14%; + margin-right: 23px; + } + .footer-links-col.follow-us-col { + width: 18%; + margin-right: 0; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + .footer-links-col { + width: 18%; + margin-right: 30px; + } +} + +.footer-social-icons { + margin: 8.5625rem 0 2.5rem 0; +} +.footer-social-icons a { + height: 32px; + width: 32px; + display: inline-block; + background-color: #CCCDD1; + border-radius: 50%; + margin-right: 5px; +} +.footer-social-icons a.facebook { + background-image: url("../images/logo-facebook-dark.svg"); + background-position: center center; + background-size: 9px 18px; + background-repeat: no-repeat; +} +.footer-social-icons a.twitter { + background-image: url("../images/logo-twitter-dark.svg"); + background-position: center center; + background-size: 17px 17px; + background-repeat: no-repeat; +} +.footer-social-icons a.youtube { + background-image: url("../images/logo-youtube-dark.svg"); + background-position: center center; + background-repeat: no-repeat; +} + +.site-footer .mc-field-group { + margin-top: -2px; +} + +article.pytorch-article { + max-width: 920px; + margin: 0 auto; +} +article.pytorch-article h2, +article.pytorch-article h3, +article.pytorch-article h4, +article.pytorch-article h5, +article.pytorch-article h6 { + margin: 1.375rem 0; + color: #262626; +} +article.pytorch-article h2 { + font-size: 1.625rem; + letter-spacing: 1.33px; + line-height: 2rem; + text-transform: none; +} +article.pytorch-article h3 { + font-size: 1.5rem; + letter-spacing: -0.25px; + line-height: 1.875rem; + text-transform: none; +} +article.pytorch-article h4, +article.pytorch-article h5, +article.pytorch-article h6 { + font-size: 1.125rem; + letter-spacing: -0.19px; + line-height: 1.875rem; +} +article.pytorch-article p { + margin-bottom: 1.125rem; +} +article.pytorch-article p, +article.pytorch-article ul li, +article.pytorch-article ol li, +article.pytorch-article dl dt, +article.pytorch-article dl dd, +article.pytorch-article blockquote { + font-size: 1rem; + line-height: 1.375rem; + color: #262626; + letter-spacing: 0.01px; + font-weight: 500; +} +article.pytorch-article table { + margin-bottom: 2.5rem; + width: 100%; +} +article.pytorch-article table thead { + border-bottom: 1px solid #cacaca; +} +article.pytorch-article table th { + padding: 0.625rem; + color: #262626; +} +article.pytorch-article table td { + padding: 0.3125rem; +} +article.pytorch-article table tr th:first-of-type, +article.pytorch-article table tr td:first-of-type { + padding-left: 0; +} +article.pytorch-article table.docutils.field-list th.field-name { + padding: 0.3125rem; + padding-left: 0; +} +article.pytorch-article table.docutils.field-list td.field-body { + padding: 0.3125rem; +} +article.pytorch-article table.docutils.field-list td.field-body p:last-of-type { + margin-bottom: 0; +} +article.pytorch-article ul, +article.pytorch-article ol { + margin: 1.5rem 0 3.125rem 0; +} +@media screen and (min-width: 768px) { + article.pytorch-article ul, + article.pytorch-article ol { + padding-left: 6.25rem; + } +} +article.pytorch-article ul li, +article.pytorch-article ol li { + margin-bottom: 0.625rem; +} +article.pytorch-article dl { + margin-bottom: 1.5rem; +} +article.pytorch-article dl dt { + margin-bottom: 0.75rem; +} +article.pytorch-article pre { + margin-bottom: 2.5rem; +} +article.pytorch-article hr { + margin-top: 4.6875rem; + margin-bottom: 4.6875rem; +} +article.pytorch-article blockquote { + margin: 0 auto; + margin-bottom: 2.5rem; + width: 65%; +} +article.pytorch-article img { + width: 100%; +} + +html { + height: 100%; +} +@media screen and (min-width: 768px) { + html { + font-size: 16px; + } +} + +body { + background: #ffffff; + height: 100%; + margin: 0; +} +body.no-scroll { + height: 100%; + overflow: hidden; +} + +p { + margin-top: 0; + margin-bottom: 1.125rem; +} +p a:link, +p a:visited, +p a:hover { + color: #e44c2c; + text-decoration: none; +} +@media screen and (min-width: 768px) { + p a:hover { + text-decoration: underline; + } +} +p a:link, +p a:visited, +p a:hover { + color: #ee4c2c; +} + +.wy-breadcrumbs li a { + color: #ee4c2c; +} + +.wy-nav-top{ + background: #808080; +} + +ul.pytorch-breadcrumbs { + padding-left: 0; + list-style-type: none; +} +ul.pytorch-breadcrumbs li { + display: inline-block; + font-size: 0.875rem; +} +ul.pytorch-breadcrumbs a { + color: #ee4c2c; + text-decoration: none; +} + +.table-of-contents-link-wrapper { + display: block; + margin-top: 0; + padding: 1.25rem 1.875rem; + background-color: #f3f4f7; + position: relative; + color: #262626; + font-size: 1.25rem; +} +.table-of-contents-link-wrapper.is-open .toggle-table-of-contents { + -webkit-transform: rotate(180deg); + transform: rotate(180deg); +} +@media screen and (min-width: 1100px) { + .table-of-contents-link-wrapper { + display: none; + } +} + +.toggle-table-of-contents { + background-image: url("../images/chevron-down-grey.svg"); + background-position: center center; + background-repeat: no-repeat; + background-size: 18px 18px; + height: 100%; + position: absolute; + right: 21px; + width: 30px; + top: 0; +} + +.tutorials-header .header-logo { + background-image: url("../images/logo-dark.svg"); +} +.tutorials-header .main-menu ul li a { + color: #262626; +} +.tutorials-header .main-menu-open-button { + background-image: url("../images/icon-menu-dots-dark.svg"); +} + +.rst-content footer .helpful-hr.hr-top { + margin-bottom: -0.0625rem; +} +.rst-content footer .helpful-hr.hr-bottom { + margin-top: -0.0625rem; +} +.rst-content footer .helpful-container { + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + font-size: 1.125rem; +} +.rst-content footer .helpful-container .helpful-question, .rst-content footer .helpful-container .was-helpful-thank-you { + padding: 0.625rem 1.25rem 0.625rem 1.25rem; +} +.rst-content footer .helpful-container .was-helpful-thank-you { + display: none; +} +.rst-content footer .helpful-container .helpful-question.yes-link, .rst-content footer .helpful-container .helpful-question.no-link { + color: #e44c2c; + cursor: pointer; +} +.rst-content footer .helpful-container .helpful-question.yes-link:hover, .rst-content footer .helpful-container .helpful-question.no-link:hover { + background-color: #e44c2c; + color: #ffffff; +} +.rst-content footer div[role="contentinfo"] { + padding-top: 2.5rem; +} +.rst-content footer div[role="contentinfo"] p { + margin-bottom: 0; +} + +h1 { + font-size: 2rem; + letter-spacing: 1.78px; + line-height: 2.5rem; + margin: 1.375rem 0; +} + +span.pre { + color: #6c6c6d; + background-color: #f3f4f7; + padding: 2px 6px; +} + +pre { + background-color: #f3f4f7; + padding: 1.375rem; +} + +.highlight .c1 { + color: #6c6c6d; +} + +.headerlink { + display: none !important; +} + +a:link.has-code, +a:hover.has-code, +a:visited.has-code { + color: #4974D1; +} +a:link.has-code span, +a:hover.has-code span, +a:visited.has-code span { + color: #4974D1; +} + +article.pytorch-article ul, +article.pytorch-article ol { + padding-left: 1.875rem; + margin: 0; +} +article.pytorch-article ul li, +article.pytorch-article ol li { + margin: 0; + line-height: 1.75rem; +} +article.pytorch-article ul p, +article.pytorch-article ol p { + line-height: 1.75rem; + margin-bottom: 0; +} +article.pytorch-article ul ul, +article.pytorch-article ul ol, +article.pytorch-article ol ul, +article.pytorch-article ol ol { + margin: 0; +} +article.pytorch-article h1, +article.pytorch-article h2, +article.pytorch-article h3, +article.pytorch-article h4, +article.pytorch-article h5, +article.pytorch-article h6 { + font-weight: normal; +} +article.pytorch-article h1 a, +article.pytorch-article h2 a, +article.pytorch-article h3 a, +article.pytorch-article h4 a, +article.pytorch-article h5 a, +article.pytorch-article h6 a { + color: #262626; +} +article.pytorch-article p.caption { + margin-top: 1.25rem; +} + +article.pytorch-article .section:first-of-type h1:first-of-type { + margin-top: 0; +} + +article.pytorch-article .sphx-glr-thumbcontainer { + margin: 0; + border: 1px solid #d6d7d8; + border-radius: 0; + width: 45%; + text-align: center; + margin-bottom: 5%; +} +@media screen and (max-width: 1100px) { + article.pytorch-article .sphx-glr-thumbcontainer:nth-child(odd) { + margin-left: 0; + margin-right: 2.5%; + } + article.pytorch-article .sphx-glr-thumbcontainer:nth-child(even) { + margin-right: 0; + margin-left: 2.5%; + } + article.pytorch-article .sphx-glr-thumbcontainer .figure { + width: 40%; + } +} +@media screen and (min-width: 1101px) { + article.pytorch-article .sphx-glr-thumbcontainer { + margin-right: 3%; + margin-bottom: 3%; + width: 30%; + } +} +article.pytorch-article .sphx-glr-thumbcontainer .caption-text a { + font-size: 1rem; + color: #262626; + letter-spacing: 0; + line-height: 1.5rem; + text-decoration: none; +} +article.pytorch-article .sphx-glr-thumbcontainer:hover { + -webkit-box-shadow: none; + box-shadow: none; + border-bottom-color: #ffffff; +} +article.pytorch-article .sphx-glr-thumbcontainer:hover .figure:before { + bottom: 100%; +} +article.pytorch-article .sphx-glr-thumbcontainer .figure { + width: 80%; +} +article.pytorch-article .sphx-glr-thumbcontainer .figure:before { + content: ""; + display: block; + position: absolute; + top: 0; + bottom: 35%; + left: 0; + right: 0; + background: #8A94B3; + opacity: 0.10; +} +article.pytorch-article .sphx-glr-thumbcontainer .figure a.reference.internal { + text-align: left; +} +@media screen and (min-width: 768px) { + article.pytorch-article .sphx-glr-thumbcontainer:after { + content: ""; + display: block; + width: 0; + height: 1px; + position: absolute; + bottom: 0; + left: 0; + background-color: #e44c2c; + -webkit-transition: width .250s ease-in-out; + transition: width .250s ease-in-out; + } + article.pytorch-article .sphx-glr-thumbcontainer:hover:after { + width: 100%; + } +} +@media screen and (min-width: 768px) { + article.pytorch-article .sphx-glr-thumbcontainer:after { + background-color: #ee4c2c; + } +} + +article.pytorch-article .section :not(dt) > code { + color: #262626; + border-top: solid 2px #f3f4f7; + background-color: #f3f4f7; + border-bottom: solid 2px #f3f4f7; + padding: 0px 3px; + -webkit-box-decoration-break: clone; + box-decoration-break: clone; +} +article.pytorch-article .section :not(dt) > code .pre { + outline: 0px; + padding: 0px; +} +article.pytorch-article .function dt, article.pytorch-article .attribute dt, article.pytorch-article .class .attribute dt, article.pytorch-article .class dt { + position: relative; + background: #f3f4f7; + padding: 0.5rem; + border-left: 3px solid #ee4c2c; + word-wrap: break-word; + padding-right: 100px; +} +article.pytorch-article .function dt em.property, article.pytorch-article .attribute dt em.property, article.pytorch-article .class dt em.property { + font-family: inherit; +} +article.pytorch-article .function dt em, article.pytorch-article .attribute dt em, article.pytorch-article .class .attribute dt em, article.pytorch-article .class dt em, article.pytorch-article .function dt .sig-paren, article.pytorch-article .attribute dt .sig-paren, article.pytorch-article .class dt .sig-paren { + font-family: IBMPlexMono,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; + font-size: 87.5%; +} +article.pytorch-article .function dt a, article.pytorch-article .attribute dt a, article.pytorch-article .class .attribute dt a, article.pytorch-article .class dt a { + position: absolute; + right: 30px; + padding-right: 0; + top: 50%; + -webkit-transform: perspective(1px) translateY(-50%); + transform: perspective(1px) translateY(-50%); +} +article.pytorch-article .function dt:hover .viewcode-link, article.pytorch-article .attribute dt:hover .viewcode-link, article.pytorch-article .class dt:hover .viewcode-link { + color: #ee4c2c; +} +article.pytorch-article .function .anchorjs-link, article.pytorch-article .attribute .anchorjs-link, article.pytorch-article .class .anchorjs-link { + display: inline; + position: absolute; + right: 8px; + font-size: 1.5625rem !important; + padding-left: 0; +} +article.pytorch-article .function dt > code, article.pytorch-article .attribute dt > code, article.pytorch-article .class .attribute dt > code, article.pytorch-article .class dt > code { + color: #262626; + border-top: solid 2px #f3f4f7; + background-color: #f3f4f7; + border-bottom: solid 2px #f3f4f7; + -webkit-box-decoration-break: clone; + box-decoration-break: clone; +} +article.pytorch-article .function .viewcode-link, article.pytorch-article .attribute .viewcode-link, article.pytorch-article .class .viewcode-link { + font-size: 0.875rem; + color: #979797; + letter-spacing: 0; + line-height: 1.5rem; + text-transform: uppercase; +} +article.pytorch-article .function dd, article.pytorch-article .attribute dd, article.pytorch-article .class .attribute dd, article.pytorch-article .class dd { + padding-left: 3.75rem; +} +article.pytorch-article .function dd p, article.pytorch-article .attribute dd p, article.pytorch-article .class .attribute dd p, article.pytorch-article .class dd p { + color: #262626; +} +article.pytorch-article .function table tbody tr th.field-name, article.pytorch-article .attribute table tbody tr th.field-name, article.pytorch-article .class table tbody tr th.field-name { + white-space: nowrap; + color: #262626; + width: 20%; +} +@media screen and (min-width: 768px) { + article.pytorch-article .function table tbody tr th.field-name, article.pytorch-article .attribute table tbody tr th.field-name, article.pytorch-article .class table tbody tr th.field-name { + width: 15%; + } +} +article.pytorch-article .function table tbody tr td.field-body, article.pytorch-article .attribute table tbody tr td.field-body, article.pytorch-article .class table tbody tr td.field-body { + padding: 0.625rem; + width: 80%; + color: #262626; +} +@media screen and (min-width: 768px) { + article.pytorch-article .function table tbody tr td.field-body, article.pytorch-article .attribute table tbody tr td.field-body, article.pytorch-article .class table tbody tr td.field-body { + width: 85%; + } +} +@media screen and (min-width: 1600px) { + article.pytorch-article .function table tbody tr td.field-body, article.pytorch-article .attribute table tbody tr td.field-body, article.pytorch-article .class table tbody tr td.field-body { + padding-left: 1.25rem; + } +} +article.pytorch-article .function table tbody tr td.field-body p, article.pytorch-article .attribute table tbody tr td.field-body p, article.pytorch-article .class table tbody tr td.field-body p { + padding-left: 0px; +} +article.pytorch-article .function table tbody tr td.field-body p:last-of-type, article.pytorch-article .attribute table tbody tr td.field-body p:last-of-type, article.pytorch-article .class table tbody tr td.field-body p:last-of-type { + margin-bottom: 0; +} +article.pytorch-article .function table tbody tr td.field-body ol, article.pytorch-article .attribute table tbody tr td.field-body ol, article.pytorch-article .class table tbody tr td.field-body ol, article.pytorch-article .function table tbody tr td.field-body ul, article.pytorch-article .attribute table tbody tr td.field-body ul, article.pytorch-article .class table tbody tr td.field-body ul { + padding-left: 1rem; + padding-bottom: 0; +} +article.pytorch-article .function table.docutils.field-list, article.pytorch-article .attribute table.docutils.field-list, article.pytorch-article .class table.docutils.field-list { + margin-bottom: 0.75rem; +} +article.pytorch-article .attribute .has-code { + float: none; +} +article.pytorch-article .class dt { + border-left: none; + border-top: 3px solid #ee4c2c; + padding-left: 4em; +} +article.pytorch-article .class dt em.property { + position: absolute; + left: 0.5rem; +} +article.pytorch-article .class dd .docutils dt { + padding-left: 0.5rem; +} +article.pytorch-article .class em.property { + text-transform: uppercase; + font-style: normal; + color: #ee4c2c; + font-size: 1rem; + letter-spacing: 0; + padding-right: 0.75rem; +} +article.pytorch-article .class dl dt em.property { + position: static; + left: 0; + padding-right: 0; +} +article.pytorch-article .class .method dt, +article.pytorch-article .class .staticmethod dt { + border-left: 3px solid #ee4c2c; + border-top: none; +} +article.pytorch-article .class .method dt, +article.pytorch-article .class .staticmethod dt { + padding-left: 0.5rem; +} +article.pytorch-article .class .attribute dt { + border-top: none; +} +article.pytorch-article .class .attribute dt em.property { + position: relative; + left: 0; +} +article.pytorch-article table { + table-layout: fixed; +} + +article.pytorch-article .note, +article.pytorch-article .warning, +article.pytorch-article .tip, +article.pytorch-article .hint, +article.pytorch-article .important, +article.pytorch-article .caution, +article.pytorch-article .danger, +article.pytorch-article .attention, +article.pytorch-article .error { + background: #f3f4f7; + margin-top: 1.875rem; + margin-bottom: 1.125rem; +} +article.pytorch-article .note .admonition-title, +article.pytorch-article .warning .admonition-title, +article.pytorch-article .tip .admonition-title, +article.pytorch-article .hint .admonition-title, +article.pytorch-article .important .admonition-title, +article.pytorch-article .caution .admonition-title, +article.pytorch-article .danger .admonition-title, +article.pytorch-article .attention .admonition-title, +article.pytorch-article .error .admonition-title { + color: #ffffff; + letter-spacing: 1px; + text-transform: uppercase; + margin-bottom: 1.125rem; + padding: 3px 0 3px 1.375rem; + position: relative; + font-size: 0.875rem; +} +article.pytorch-article .note .admonition-title:before, +article.pytorch-article .warning .admonition-title:before, +article.pytorch-article .tip .admonition-title:before, +article.pytorch-article .hint .admonition-title:before, +article.pytorch-article .important .admonition-title:before, +article.pytorch-article .caution .admonition-title:before, +article.pytorch-article .danger .admonition-title:before, +article.pytorch-article .attention .admonition-title:before, +article.pytorch-article .error .admonition-title:before { + content: "\2022"; + position: absolute; + left: 9px; + color: #ffffff; + top: 2px; +} +article.pytorch-article .note p:nth-child(n + 2), +article.pytorch-article .warning p:nth-child(n + 2), +article.pytorch-article .tip p:nth-child(n + 2), +article.pytorch-article .hint p:nth-child(n + 2), +article.pytorch-article .important p:nth-child(n + 2), +article.pytorch-article .caution p:nth-child(n + 2), +article.pytorch-article .danger p:nth-child(n + 2), +article.pytorch-article .attention p:nth-child(n + 2), +article.pytorch-article .error p:nth-child(n + 2) { + padding: 0 1.375rem; +} +article.pytorch-article .note table, +article.pytorch-article .warning table, +article.pytorch-article .tip table, +article.pytorch-article .hint table, +article.pytorch-article .important table, +article.pytorch-article .caution table, +article.pytorch-article .danger table, +article.pytorch-article .attention table, +article.pytorch-article .error table { + margin: 0 2rem; + width: auto; +} +article.pytorch-article .note .pre, +article.pytorch-article .note pre, +article.pytorch-article .warning .pre, +article.pytorch-article .warning pre, +article.pytorch-article .tip .pre, +article.pytorch-article .tip pre, +article.pytorch-article .hint .pre, +article.pytorch-article .hint pre, +article.pytorch-article .important .pre, +article.pytorch-article .important pre, +article.pytorch-article .caution .pre, +article.pytorch-article .caution pre, +article.pytorch-article .danger .pre, +article.pytorch-article .danger pre, +article.pytorch-article .attention .pre, +article.pytorch-article .attention pre, +article.pytorch-article .error .pre, +article.pytorch-article .error pre { + background: #ffffff; + outline: 1px solid #e9e9e9; +} +article.pytorch-article .note :not(dt) > code, +article.pytorch-article .warning :not(dt) > code, +article.pytorch-article .tip :not(dt) > code, +article.pytorch-article .hint :not(dt) > code, +article.pytorch-article .important :not(dt) > code, +article.pytorch-article .caution :not(dt) > code, +article.pytorch-article .danger :not(dt) > code, +article.pytorch-article .attention :not(dt) > code, +article.pytorch-article .error :not(dt) > code { + border-top: solid 2px #ffffff; + background-color: #ffffff; + border-bottom: solid 2px #ffffff; + padding: 0px 3px; + -webkit-box-decoration-break: clone; + box-decoration-break: clone; + outline: 1px solid #e9e9e9; +} +article.pytorch-article .note :not(dt) > code .pre, +article.pytorch-article .warning :not(dt) > code .pre, +article.pytorch-article .tip :not(dt) > code .pre, +article.pytorch-article .hint :not(dt) > code .pre, +article.pytorch-article .important :not(dt) > code .pre, +article.pytorch-article .caution :not(dt) > code .pre, +article.pytorch-article .danger :not(dt) > code .pre, +article.pytorch-article .attention :not(dt) > code .pre, +article.pytorch-article .error :not(dt) > code .pre { + outline: 0px; + padding: 0px; +} +article.pytorch-article .note pre, +article.pytorch-article .warning pre, +article.pytorch-article .tip pre, +article.pytorch-article .hint pre, +article.pytorch-article .important pre, +article.pytorch-article .caution pre, +article.pytorch-article .danger pre, +article.pytorch-article .attention pre, +article.pytorch-article .error pre { + margin-bottom: 0; +} +article.pytorch-article .note .highlight, +article.pytorch-article .warning .highlight, +article.pytorch-article .tip .highlight, +article.pytorch-article .hint .highlight, +article.pytorch-article .important .highlight, +article.pytorch-article .caution .highlight, +article.pytorch-article .danger .highlight, +article.pytorch-article .attention .highlight, +article.pytorch-article .error .highlight { + margin: 0 2rem 1.125rem 2rem; +} +article.pytorch-article .note ul, +article.pytorch-article .note ol, +article.pytorch-article .warning ul, +article.pytorch-article .warning ol, +article.pytorch-article .tip ul, +article.pytorch-article .tip ol, +article.pytorch-article .hint ul, +article.pytorch-article .hint ol, +article.pytorch-article .important ul, +article.pytorch-article .important ol, +article.pytorch-article .caution ul, +article.pytorch-article .caution ol, +article.pytorch-article .danger ul, +article.pytorch-article .danger ol, +article.pytorch-article .attention ul, +article.pytorch-article .attention ol, +article.pytorch-article .error ul, +article.pytorch-article .error ol { + padding-left: 3.25rem; +} +article.pytorch-article .note ul li, +article.pytorch-article .note ol li, +article.pytorch-article .warning ul li, +article.pytorch-article .warning ol li, +article.pytorch-article .tip ul li, +article.pytorch-article .tip ol li, +article.pytorch-article .hint ul li, +article.pytorch-article .hint ol li, +article.pytorch-article .important ul li, +article.pytorch-article .important ol li, +article.pytorch-article .caution ul li, +article.pytorch-article .caution ol li, +article.pytorch-article .danger ul li, +article.pytorch-article .danger ol li, +article.pytorch-article .attention ul li, +article.pytorch-article .attention ol li, +article.pytorch-article .error ul li, +article.pytorch-article .error ol li { + color: #262626; +} +article.pytorch-article .note p, +article.pytorch-article .warning p, +article.pytorch-article .tip p, +article.pytorch-article .hint p, +article.pytorch-article .important p, +article.pytorch-article .caution p, +article.pytorch-article .danger p, +article.pytorch-article .attention p, +article.pytorch-article .error p { + margin-top: 1.125rem; +} +article.pytorch-article .note .admonition-title { + background: #54c7ec; +} +article.pytorch-article .warning .admonition-title { + background: #e94f3b; +} +article.pytorch-article .tip .admonition-title { + background: #6bcebb; +} +article.pytorch-article .hint .admonition-title { + background: #a2cdde; +} +article.pytorch-article .important .admonition-title { + background: #5890ff; +} +article.pytorch-article .caution .admonition-title { + background: #f7923a; +} +article.pytorch-article .danger .admonition-title { + background: #db2c49; +} +article.pytorch-article .attention .admonition-title { + background: #f5a623; +} +article.pytorch-article .error .admonition-title { + background: #cc2f90; +} +article.pytorch-article .sphx-glr-download-link-note.admonition.note, +article.pytorch-article .reference.download.internal, article.pytorch-article .sphx-glr-signature { + display: none; +} +article.pytorch-article .admonition > p:last-of-type { + margin-bottom: 0; + padding-bottom: 1.125rem !important; +} + +.pytorch-article div.sphx-glr-download a { + background-color: #f3f4f7; + background-image: url("../images/arrow-down-orange.svg"); + background-repeat: no-repeat; + background-position: left 10px center; + background-size: 15px 15px; + border-radius: 0; + border: none; + display: block; + text-align: left; + padding: 0.9375rem 3.125rem; + position: relative; + margin: 1.25rem auto; +} +@media screen and (min-width: 768px) { + .pytorch-article div.sphx-glr-download a:after { + content: ""; + display: block; + width: 0; + height: 1px; + position: absolute; + bottom: 0; + left: 0; + background-color: #e44c2c; + -webkit-transition: width .250s ease-in-out; + transition: width .250s ease-in-out; + } + .pytorch-article div.sphx-glr-download a:hover:after { + width: 100%; + } +} +@media screen and (min-width: 768px) { + .pytorch-article div.sphx-glr-download a:after { + background-color: #ee4c2c; + } +} +@media screen and (min-width: 768px) { + .pytorch-article div.sphx-glr-download a { + background-position: left 20px center; + } +} +.pytorch-article div.sphx-glr-download a:hover { + -webkit-box-shadow: none; + box-shadow: none; + text-decoration: none; + background-image: url("../images/arrow-down-orange.svg"); + background-color: #f3f4f7; +} +.pytorch-article div.sphx-glr-download a span.pre { + background-color: transparent; + font-size: 1.125rem; + padding: 0; + color: #262626; +} +.pytorch-article div.sphx-glr-download a code, .pytorch-article div.sphx-glr-download a kbd, .pytorch-article div.sphx-glr-download a pre, .pytorch-article div.sphx-glr-download a samp, .pytorch-article div.sphx-glr-download a span.pre { + font-family: FreightSans, Helvetica Neue, Helvetica, Arial, sans-serif; +} + +.pytorch-article p.sphx-glr-script-out { + margin-bottom: 1.125rem; +} + +.pytorch-article div.sphx-glr-script-out { + margin-bottom: 2.5rem; +} +.pytorch-article div.sphx-glr-script-out .highlight { + margin-left: 0; + margin-top: 0; +} +.pytorch-article div.sphx-glr-script-out .highlight pre { + background-color: #fdede9; + padding: 1.5625rem; + color: #837b79; +} +.pytorch-article div.sphx-glr-script-out + p { + margin-top: unset; +} + +article.pytorch-article .wy-table-responsive table { + border: none; + border-color: #ffffff !important; + table-layout: fixed; +} +article.pytorch-article .wy-table-responsive table thead tr { + border-bottom: 2px solid #6c6c6d; +} +article.pytorch-article .wy-table-responsive table thead th { + line-height: 1.75rem; + padding-left: 0.9375rem; + padding-right: 0.9375rem; +} +article.pytorch-article .wy-table-responsive table tbody .row-odd { + background-color: #f3f4f7; +} +article.pytorch-article .wy-table-responsive table tbody td { + color: #6c6c6d; + white-space: normal; + padding: 0.9375rem; + font-size: 1rem; + line-height: 1.375rem; +} +article.pytorch-article .wy-table-responsive table tbody td .pre { + background: #ffffff; + outline: 1px solid #e9e9e9; + color: #ee4c2c; + font-size: 87.5%; +} +article.pytorch-article .wy-table-responsive table tbody td code { + font-size: 87.5%; +} + +a[rel~="prev"], a[rel~="next"] { + padding: 0.375rem 0 0 0; +} + +img.next-page, +img.previous-page { + width: 8px; + height: 10px; + position: relative; + top: -1px; +} + +img.previous-page { + -webkit-transform: scaleX(-1); + transform: scaleX(-1); +} + +.rst-footer-buttons { + margin-top: 1.875rem; + margin-bottom: 1.875rem; +} +.rst-footer-buttons .btn:focus, +.rst-footer-buttons .btn.focus { + -webkit-box-shadow: none; + box-shadow: none; +} + +article.pytorch-article blockquote { + margin-left: 3.75rem; + color: #6c6c6d; +} + +article.pytorch-article .caption { + color: #6c6c6d; + letter-spacing: 0.25px; + line-height: 2.125rem; +} + +article.pytorch-article .math { + color: #262626; + width: auto; + text-align: center; +} +article.pytorch-article .math img { + width: auto; +} + +.pytorch-breadcrumbs-wrapper { + width: 100%; +} +@media screen and (min-width: 1101px) { + .pytorch-breadcrumbs-wrapper { + float: left; + margin-left: 3%; + width: 75%; + } +} +@media screen and (min-width: 1600px) { + .pytorch-breadcrumbs-wrapper { + width: 850px; + margin-left: 1.875rem; + } +} +.pytorch-breadcrumbs-wrapper .pytorch-breadcrumbs-aside { + float: right; +} + +.pytorch-article .container { + padding-left: 0; + padding-right: 0; + max-width: none; +} + +a:link, +a:visited, +a:hover { + color: #ee4c2c; +} + +::-webkit-input-placeholder { + color: #ee4c2c; +} + +::-moz-placeholder { + color: #ee4c2c; +} + +:-ms-input-placeholder { + color: #ee4c2c; +} + +:-moz-placeholder { + color: #ee4c2c; +} + +@media screen and (min-width: 768px) { + .site-footer a:hover { + color: #ee4c2c; + } +} + +.docs-tutorials-resources a { + color: #ee4c2c; +} + +.header-holder { + position: relative; + z-index: 201; +} + +.header-holder .main-menu ul li.active:after { + color: #ee4c2c; +} +.header-holder .main-menu ul li.active a { + color: #ee4c2c; +} +@media screen and (min-width: 1100px) { + .header-holder .main-menu ul li a:hover { + color: #ee4c2c; + } +} + +.mobile-main-menu.open ul li.active a { + color: #ee4c2c; +} + +.version { + padding-bottom: 1rem; +} + +.pytorch-call-to-action-links { + padding-top: 0; + display: -webkit-box; + display: -ms-flexbox; + display: flex; +} +@media screen and (min-width: 768px) { + .pytorch-call-to-action-links { + padding-top: 2.5rem; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + .pytorch-call-to-action-links { + padding-top: 0; + } +} +@media (min-width: 1100px) and (max-width: 1239px) { + .pytorch-call-to-action-links { + padding-top: 2.5rem; + } +} +.pytorch-call-to-action-links #tutorial-type { + display: none; +} +.pytorch-call-to-action-links .call-to-action-img, .pytorch-call-to-action-links .call-to-action-notebook-img { + height: 1.375rem; + width: 1.375rem; + margin-right: 10px; +} +.pytorch-call-to-action-links .call-to-action-notebook-img { + height: 1rem; +} +.pytorch-call-to-action-links a { + padding-right: 1.25rem; + color: #000000; + cursor: pointer; +} +.pytorch-call-to-action-links a:hover { + color: #e44c2c; +} +.pytorch-call-to-action-links a .call-to-action-desktop-view { + display: none; +} +@media screen and (min-width: 768px) { + .pytorch-call-to-action-links a .call-to-action-desktop-view { + display: block; + } +} +.pytorch-call-to-action-links a .call-to-action-mobile-view { + display: block; +} +@media screen and (min-width: 768px) { + .pytorch-call-to-action-links a .call-to-action-mobile-view { + display: none; + } +} +.pytorch-call-to-action-links a #google-colab-link, .pytorch-call-to-action-links a #download-notebook-link, +.pytorch-call-to-action-links a #github-view-link { + padding-bottom: 0.625rem; + border-bottom: 1px solid #f3f4f7; + padding-right: 2.5rem; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.pytorch-call-to-action-links a #google-colab-link:hover, .pytorch-call-to-action-links a #download-notebook-link:hover, +.pytorch-call-to-action-links a #github-view-link:hover { + border-bottom-color: #e44c2c; + color: #e44c2c; +} + +#tutorial-cards-container #tutorial-cards { + width: 100%; +} +#tutorial-cards-container .tutorials-nav { + padding-left: 0; + padding-right: 0; + padding-bottom: 0; +} +#tutorial-cards-container .tutorials-hr { + margin-top: 1rem; + margin-bottom: 1rem; +} +#tutorial-cards-container .card.tutorials-card { + border-radius: 0; + border-color: #f3f4f7; + height: 98px; + margin-bottom: 1.25rem; + margin-bottom: 1.875rem; + overflow: scroll; + background-color: #f3f4f7; + cursor: pointer; +} +@media screen and (min-width: 1240px) { + #tutorial-cards-container .card.tutorials-card { + height: 200px; + overflow: inherit; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + #tutorial-cards-container .card.tutorials-card { + height: 200px; + overflow: scroll; + } +} +#tutorial-cards-container .card.tutorials-card .tutorials-image { + position: absolute; + top: 0px; + right: 0px; + height: 96px; + width: 96px; + opacity: 0.5; +} +#tutorial-cards-container .card.tutorials-card .tutorials-image img { + height: 100%; + width: 100%; +} +@media screen and (min-width: 768px) { + #tutorial-cards-container .card.tutorials-card .tutorials-image { + height: 100%; + width: 25%; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + #tutorial-cards-container .card.tutorials-card .tutorials-image { + height: 100%; + width: 198px; + } +} +#tutorial-cards-container .card.tutorials-card .tutorials-image:before { + content: ''; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + z-index: 1; + background: #000000; + opacity: .075; +} +#tutorial-cards-container .card.tutorials-card .card-title-container { + width: 70%; + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; +} +@media screen and (min-width: 768px) { + #tutorial-cards-container .card.tutorials-card .card-title-container { + width: 75%; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + #tutorial-cards-container .card.tutorials-card .card-title-container { + width: 70%; + } +} +#tutorial-cards-container .card.tutorials-card .card-title-container h4 { + margin-bottom: 1.125rem; + margin-top: 0; + font-size: 1.5rem; +} +#tutorial-cards-container .card.tutorials-card p.card-summary, #tutorial-cards-container .card.tutorials-card p.tags { + font-size: 0.9375rem; + line-height: 1.5rem; + margin-bottom: 0; + color: #6c6c6d; + font-weight: 400; + width: 70%; +} +@media screen and (min-width: 768px) { + #tutorial-cards-container .card.tutorials-card p.card-summary, #tutorial-cards-container .card.tutorials-card p.tags { + width: 75%; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + #tutorial-cards-container .card.tutorials-card p.card-summary, #tutorial-cards-container .card.tutorials-card p.tags { + width: 70%; + } +} +#tutorial-cards-container .card.tutorials-card p.tags { + margin-top: 30px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} +#tutorial-cards-container .card.tutorials-card h4 { + color: #262626; + margin-bottom: 1.125rem; +} +#tutorial-cards-container .card.tutorials-card a { + height: 100%; +} +@media screen and (min-width: 768px) { + #tutorial-cards-container .card.tutorials-card a { + min-height: 190px; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + #tutorial-cards-container .card.tutorials-card a { + min-height: 234px; + } +} +@media screen and (min-width: 768px) { + #tutorial-cards-container .card.tutorials-card:after { + content: ""; + display: block; + width: 0; + height: 1px; + position: absolute; + bottom: 0; + left: 0; + background-color: #e44c2c; + -webkit-transition: width .250s ease-in-out; + transition: width .250s ease-in-out; + } + #tutorial-cards-container .card.tutorials-card:hover:after { + width: 100%; + } +} +#tutorial-cards-container .card.tutorials-card:hover { + background-color: #ffffff; + border: 1px solid #e2e2e2; + border-bottom: none; +} +#tutorial-cards-container .card.tutorials-card:hover p.card-summary { + color: #262626; +} +#tutorial-cards-container .card.tutorials-card:hover .tutorials-image { + opacity: unset; +} +#tutorial-cards-container .tutorial-tags-container { + width: 75%; +} +#tutorial-cards-container .tutorial-tags-container.active { + width: 0; +} +#tutorial-cards-container .tutorial-filter-menu ul { + list-style-type: none; + padding-left: 1.25rem; +} +#tutorial-cards-container .tutorial-filter-menu ul li { + padding-right: 1.25rem; + word-break: break-all; +} +#tutorial-cards-container .tutorial-filter-menu ul li a { + color: #979797; +} +#tutorial-cards-container .tutorial-filter-menu ul li a:hover { + color: #e44c2c; +} +#tutorial-cards-container .tutorial-filter { + cursor: pointer; +} +#tutorial-cards-container .filter-btn { + color: #979797; + border: 1px solid #979797; + display: inline-block; + text-align: center; + white-space: nowrap; + vertical-align: middle; + padding: 0.375rem 0.75rem; + font-size: 1rem; + line-height: 1.5; + margin-bottom: 5px; +} +#tutorial-cards-container .filter-btn:hover { + border: 1px solid #e44c2c; + color: #e44c2c; +} +#tutorial-cards-container .filter-btn.selected { + background-color: #e44c2c; + border: 1px solid #e44c2c; + color: #ffffff; +} +#tutorial-cards-container .all-tag-selected { + background-color: #979797; + color: #ffffff; +} +#tutorial-cards-container .all-tag-selected:hover { + border-color: #979797; + color: #ffffff; +} +#tutorial-cards-container .pagination .page { + border: 1px solid #dee2e6; + padding: 0.5rem 0.75rem; +} +#tutorial-cards-container .pagination .active .page { + background-color: #dee2e6; +} + +article.pytorch-article .tutorials-callout-container { + padding-bottom: 50px; +} +article.pytorch-article .tutorials-callout-container .col-md-6 { + padding-bottom: 10px; +} +article.pytorch-article .tutorials-callout-container .text-container { + padding: 10px 0px 30px 0px; + padding-bottom: 10px; +} +article.pytorch-article .tutorials-callout-container .text-container .body-paragraph { + color: #666666; + font-weight: 300; + font-size: 1.125rem; + line-height: 1.875rem; +} +article.pytorch-article .tutorials-callout-container .btn.callout-button { + font-size: 1.125rem; + border-radius: 0; + border: none; + background-color: #f3f4f7; + color: #6c6c6d; + font-weight: 400; + position: relative; + letter-spacing: 0.25px; +} +@media screen and (min-width: 768px) { + article.pytorch-article .tutorials-callout-container .btn.callout-button:after { + content: ""; + display: block; + width: 0; + height: 1px; + position: absolute; + bottom: 0; + left: 0; + background-color: #e44c2c; + -webkit-transition: width .250s ease-in-out; + transition: width .250s ease-in-out; + } + article.pytorch-article .tutorials-callout-container .btn.callout-button:hover:after { + width: 100%; + } +} +article.pytorch-article .tutorials-callout-container .btn.callout-button a { + color: inherit; +} + +.pytorch-container { + margin: 0 auto; + padding: 0 1.875rem; + width: auto; + position: relative; +} +@media screen and (min-width: 1100px) { + .pytorch-container { + padding: 0; + } +} +@media screen and (min-width: 1101px) { + .pytorch-container { + margin-left: 25%; + } +} +@media screen and (min-width: 1600px) { + .pytorch-container { + margin-left: 350px; + } +} +.pytorch-container:before, .pytorch-container:after { + content: ""; + display: table; +} +.pytorch-container:after { + clear: both; +} +.pytorch-container { + *zoom: 1; +} + +.pytorch-content-wrap { + background-color: #ffffff; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + position: relative; + padding-top: 0; +} +.pytorch-content-wrap:before, .pytorch-content-wrap:after { + content: ""; + display: table; +} +.pytorch-content-wrap:after { + clear: both; +} +.pytorch-content-wrap { + *zoom: 1; +} +@media screen and (min-width: 1101px) { + .pytorch-content-wrap { + padding-top: 45px; + float: left; + width: 100%; + display: block; + } +} +@media screen and (min-width: 1600px) { + .pytorch-content-wrap { + width: 100%; + } +} + +.pytorch-content { + background: #ffffff; + width: 100%; + max-width: 700px; + position: relative; +} + +.pytorch-content-left { + margin-top: 2.5rem; + width: 100%; +} +@media screen and (min-width: 1101px) { + .pytorch-content-left { + margin-top: 0; + margin-left: 3%; + width: 75%; + float: left; + } +} +@media screen and (min-width: 1600px) { + .pytorch-content-left { + width: 850px; + margin-left: 30px; + } +} +.pytorch-content-left .main-content { + padding-top: 0.9375rem; +} +.pytorch-content-left .main-content ul.simple { + padding-bottom: 1.25rem; +} +.pytorch-content-left .main-content .note:nth-child(1), .pytorch-content-left .main-content .warning:nth-child(1) { + margin-top: 0; +} + +.pytorch-content-right { + display: none; + position: relative; + overflow-x: hidden; + overflow-y: hidden; +} +@media screen and (min-width: 1101px) { + .pytorch-content-right { + display: block; + margin-left: 0; + width: 19%; + float: left; + height: 100%; + } +} +@media screen and (min-width: 1600px) { + .pytorch-content-right { + width: 280px; + } +} + +@media screen and (min-width: 1101px) { + .pytorch-side-scroll { + position: relative; + overflow-x: hidden; + overflow-y: scroll; + height: 100%; + } +} + +.pytorch-menu-vertical { + padding: 1.25rem 1.875rem 2.5rem 1.875rem; +} +@media screen and (min-width: 1101px) { + .pytorch-menu-vertical { + display: block; + padding-top: 0; + padding-right: 13.5%; + padding-bottom: 5.625rem; + } +} +@media screen and (min-width: 1600px) { + .pytorch-menu-vertical { + padding-left: 0; + padding-right: 1.5625rem; + } +} + +.pytorch-left-menu { + display: none; + background-color: #f3f4f7; + color: #262626; + overflow: scroll; +} +@media screen and (min-width: 1101px) { + .pytorch-left-menu { + display: block; + overflow-x: hidden; + overflow-y: hidden; + padding-bottom: 110px; + padding: 0 1.875rem 0 0; + width: 25%; + z-index: 200; + float: left; + } + .pytorch-left-menu.make-fixed { + position: fixed; + top: 0; + bottom: 0; + left: 0; + float: none; + } +} +@media screen and (min-width: 1600px) { + .pytorch-left-menu { + padding: 0 0 0 1.875rem; + width: 350px; + } +} + +.expand-menu, .hide-menu { + color: #6c6c6d; + padding-left: 10px; + cursor: pointer; +} + +.hide-menu { + display: none; +} + +.left-nav-top-caption { + padding-top: 1rem; +} + +.pytorch-left-menu p.caption { + color: #262626; + display: block; + font-size: 1rem; + line-height: 1.375rem; + margin-bottom: 1rem; + text-transform: none; + white-space: nowrap; +} + +.pytorch-left-menu-search { + margin-bottom: 2.5rem; +} +@media screen and (min-width: 1101px) { + .pytorch-left-menu-search { + margin: 1.25rem 0.625rem 1.875rem 0; + } +} + +.pytorch-left-menu-search ::-webkit-input-placeholder { + color: #262626; +} +.pytorch-left-menu-search :-ms-input-placeholder { + color: #262626; +} +.pytorch-left-menu-search ::-ms-input-placeholder { + color: #262626; +} +.pytorch-left-menu-search ::placeholder { + color: #262626; +} + +.pytorch-left-menu-search input[type=text] { + border-radius: 0; + padding: 0.5rem 0.75rem; + border-color: #ffffff; + color: #262626; + border-style: solid; + font-size: 1rem; + width: 100%; + background-color: #f3f4f7; + background-image: url("../images/search-icon.svg"); + background-repeat: no-repeat; + background-size: 18px 18px; + background-position: 12px 10px; + padding-left: 40px; + background-color: #ffffff; +} +.pytorch-left-menu-search input[type=text]:focus { + outline: 0; +} + +@media screen and (min-width: 1101px) { + .pytorch-left-menu .pytorch-side-scroll { + width: 120%; + } +} +@media screen and (min-width: 1600px) { + .pytorch-left-menu .pytorch-side-scroll { + width: 340px; + } +} + +.pytorch-right-menu { + min-height: 100px; + overflow-x: hidden; + overflow-y: hidden; + left: 0; + z-index: 200; + padding-top: 0; + position: relative; +} +@media screen and (min-width: 1101px) { + .pytorch-right-menu { + width: 100%; + } + .pytorch-right-menu.scrolling-fixed { + position: fixed; + top: 45px; + left: 83.5%; + width: 14%; + } + .pytorch-right-menu.scrolling-absolute { + position: absolute; + left: 0; + } +} +@media screen and (min-width: 1600px) { + .pytorch-right-menu { + left: 0; + width: 380px; + } + .pytorch-right-menu.scrolling-fixed { + position: fixed; + top: 45px; + left: 1230px; + } + .pytorch-right-menu.scrolling-absolute { + position: absolute; + left: 0; + } +} + +.pytorch-left-menu ul, +.pytorch-right-menu ul { + list-style-type: none; + padding-left: 0; + margin-bottom: 2.5rem; +} +.pytorch-left-menu > ul, +.pytorch-right-menu > ul { + margin-bottom: 2.5rem; +} +.pytorch-left-menu a:link, +.pytorch-left-menu a:visited, +.pytorch-left-menu a:hover, +.pytorch-right-menu a:link, +.pytorch-right-menu a:visited, +.pytorch-right-menu a:hover { + color: #6c6c6d; + font-size: 0.875rem; + line-height: 1rem; + padding: 0; + text-decoration: none; +} +.pytorch-left-menu a:link.reference.internal, +.pytorch-left-menu a:visited.reference.internal, +.pytorch-left-menu a:hover.reference.internal, +.pytorch-right-menu a:link.reference.internal, +.pytorch-right-menu a:visited.reference.internal, +.pytorch-right-menu a:hover.reference.internal { + margin-bottom: 0.3125rem; + position: relative; +} +.pytorch-left-menu li code, +.pytorch-right-menu li code { + border: none; + background: inherit; + color: inherit; + padding-left: 0; + padding-right: 0; +} +.pytorch-left-menu li span.toctree-expand, +.pytorch-right-menu li span.toctree-expand { + display: block; + float: left; + margin-left: -1.2em; + font-size: 0.8em; + line-height: 1.6em; +} +.pytorch-left-menu li.on a, .pytorch-left-menu li.current > a, +.pytorch-right-menu li.on a, +.pytorch-right-menu li.current > a { + position: relative; + border: none; +} +.pytorch-left-menu li.on a span.toctree-expand, .pytorch-left-menu li.current > a span.toctree-expand, +.pytorch-right-menu li.on a span.toctree-expand, +.pytorch-right-menu li.current > a span.toctree-expand { + display: block; + font-size: 0.8em; + line-height: 1.6em; +} +.pytorch-left-menu li.toctree-l1.current > a, +.pytorch-right-menu li.toctree-l1.current > a { + color: #ee4c2c; +} +.pytorch-left-menu li.toctree-l1.current > a:before, +.pytorch-right-menu li.toctree-l1.current > a:before { + content: "\2022"; + display: inline-block; + position: absolute; + left: -15px; + top: 1px; + font-size: 1.375rem; + color: #ee4c2c; +} +@media screen and (min-width: 1101px) { + .pytorch-left-menu li.toctree-l1.current > a:before, + .pytorch-right-menu li.toctree-l1.current > a:before { + left: -20px; + } +} +.pytorch-left-menu li.toctree-l1.current li.toctree-l2 > ul, .pytorch-left-menu li.toctree-l2.current li.toctree-l3 > ul, +.pytorch-right-menu li.toctree-l1.current li.toctree-l2 > ul, +.pytorch-right-menu li.toctree-l2.current li.toctree-l3 > ul { + display: none; +} +.pytorch-left-menu li.toctree-l1.current li.toctree-l2.current > ul, .pytorch-left-menu li.toctree-l2.current li.toctree-l3.current > ul, +.pytorch-right-menu li.toctree-l1.current li.toctree-l2.current > ul, +.pytorch-right-menu li.toctree-l2.current li.toctree-l3.current > ul { + display: block; +} +.pytorch-left-menu li.toctree-l2.current li.toctree-l3 > a, +.pytorch-right-menu li.toctree-l2.current li.toctree-l3 > a { + display: block; +} +.pytorch-left-menu li.toctree-l3, +.pytorch-right-menu li.toctree-l3 { + font-size: 0.9em; +} +.pytorch-left-menu li.toctree-l3.current li.toctree-l4 > a, +.pytorch-right-menu li.toctree-l3.current li.toctree-l4 > a { + display: block; +} +.pytorch-left-menu li.toctree-l4, +.pytorch-right-menu li.toctree-l4 { + font-size: 0.9em; +} +.pytorch-left-menu li.current ul, +.pytorch-right-menu li.current ul { + display: block; +} +.pytorch-left-menu li ul, +.pytorch-right-menu li ul { + margin-bottom: 0; + display: none; +} +.pytorch-left-menu li ul li a, +.pytorch-right-menu li ul li a { + margin-bottom: 0; +} +.pytorch-left-menu a, +.pytorch-right-menu a { + display: inline-block; + position: relative; +} +.pytorch-left-menu a:hover, +.pytorch-right-menu a:hover { + cursor: pointer; +} +.pytorch-left-menu a:active, +.pytorch-right-menu a:active { + cursor: pointer; +} + +.pytorch-left-menu ul { + padding-left: 0; +} + +.pytorch-right-menu a:link, +.pytorch-right-menu a:visited, +.pytorch-right-menu a:hover { + color: #6c6c6d; +} +.pytorch-right-menu a:link span.pre, +.pytorch-right-menu a:visited span.pre, +.pytorch-right-menu a:hover span.pre { + color: #6c6c6d; +} +.pytorch-right-menu a.reference.internal.expanded:before { + content: "-"; + font-family: monospace; + position: absolute; + left: -12px; +} +.pytorch-right-menu a.reference.internal.not-expanded:before { + content: "+"; + font-family: monospace; + position: absolute; + left: -12px; +} +.pytorch-right-menu li.active > a { + color: #ee4c2c; +} +.pytorch-right-menu li.active > a span.pre, .pytorch-right-menu li.active > a:before { + color: #ee4c2c; +} +.pytorch-right-menu li.active > a:after { + content: "\2022"; + color: #e44c2c; + display: inline-block; + font-size: 1.375rem; + left: -17px; + position: absolute; + top: 1px; +} +.pytorch-right-menu .pytorch-side-scroll > ul > li > ul > li { + margin-bottom: 0; +} +.pytorch-right-menu ul ul { + padding-left: 0; +} +.pytorch-right-menu ul ul li { + padding-left: 0px; +} +.pytorch-right-menu ul ul li a.reference.internal { + padding-left: 0; +} +.pytorch-right-menu ul ul li ul { + display: none; + padding-left: 10px; +} +.pytorch-right-menu ul ul li li a.reference.internal { + padding-left: 0; +} +.pytorch-right-menu li ul { + display: block; +} + +.pytorch-right-menu .pytorch-side-scroll { + padding-top: 20px; +} +@media screen and (min-width: 1101px) { + .pytorch-right-menu .pytorch-side-scroll { + width: 120%; + } +} +@media screen and (min-width: 1600px) { + .pytorch-right-menu .pytorch-side-scroll { + width: 400px; + } +} +.pytorch-right-menu .pytorch-side-scroll > ul { + padding-left: 10%; + padding-right: 10%; + margin-bottom: 0; +} +@media screen and (min-width: 1600px) { + .pytorch-right-menu .pytorch-side-scroll > ul { + padding-left: 25px; + } +} +.pytorch-right-menu .pytorch-side-scroll > ul > li > a.reference.internal { + color: #262626; + font-weight: 500; +} +.pytorch-right-menu .pytorch-side-scroll ul li { + position: relative; +} + +.header-container { + max-width: none; + margin-top: 4px; +} +@media screen and (min-width: 1101px) { + .header-container { + margin-top: 0; + } +} +@media screen and (min-width: 1600px) { + .header-container { + margin-top: 0; + } +} + +.container-fluid.header-holder { + padding-right: 0; + padding-left: 0; +} + +.header-holder .container { + max-width: none; + padding-right: 1.875rem; + padding-left: 1.875rem; +} +@media screen and (min-width: 1101px) { + .header-holder .container { + padding-right: 1.875rem; + padding-left: 1.875rem; + } +} + +.header-holder .main-menu { + -webkit-box-pack: unset; + -ms-flex-pack: unset; + justify-content: unset; + position: relative; +} +@media screen and (min-width: 1101px) { + .header-holder .main-menu ul { + padding-left: 0; + margin-left: 26%; + } +} +@media screen and (min-width: 1600px) { + .header-holder .main-menu ul { + padding-left: 38px; + margin-left: 310px; + } +} + +.pytorch-page-level-bar { + display: none; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + background-color: #ffffff; + border-bottom: 1px solid #e2e2e2; + width: 100%; + z-index: 201; +} +@media screen and (min-width: 1101px) { + .pytorch-page-level-bar { + left: 0; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + height: 45px; + padding-left: 0; + width: 100%; + position: absolute; + z-index: 1; + } + .pytorch-page-level-bar.left-menu-is-fixed { + position: fixed; + top: 0; + left: 25%; + padding-left: 0; + right: 0; + width: 75%; + } +} +@media screen and (min-width: 1600px) { + .pytorch-page-level-bar { + left: 0; + right: 0; + width: auto; + z-index: 1; + } + .pytorch-page-level-bar.left-menu-is-fixed { + left: 350px; + right: 0; + width: auto; + } +} +.pytorch-page-level-bar ul, .pytorch-page-level-bar li { + margin: 0; +} + +.pytorch-shortcuts-wrapper { + display: none; +} +@media screen and (min-width: 1101px) { + .pytorch-shortcuts-wrapper { + font-size: 0.875rem; + float: left; + margin-left: 2%; + } +} +@media screen and (min-width: 1600px) { + .pytorch-shortcuts-wrapper { + margin-left: 1.875rem; + } +} + +.cookie-banner-wrapper { + display: none; +} +.cookie-banner-wrapper .container { + padding-left: 1.875rem; + padding-right: 1.875rem; + max-width: 1240px; +} +.cookie-banner-wrapper.is-visible { + display: block; + position: fixed; + bottom: 0; + background-color: #f3f4f7; + min-height: 100px; + width: 100%; + z-index: 401; + border-top: 3px solid #ededee; +} +.cookie-banner-wrapper .gdpr-notice { + color: #6c6c6d; + margin-top: 1.5625rem; + text-align: left; + max-width: 1440px; +} +@media screen and (min-width: 768px) { + .cookie-banner-wrapper .gdpr-notice { + width: 77%; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + .cookie-banner-wrapper .gdpr-notice { + width: inherit; + } +} +.cookie-banner-wrapper .gdpr-notice .cookie-policy-link { + color: #343434; +} +.cookie-banner-wrapper .close-button { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: transparent; + border: 1px solid #f3f4f7; + height: 1.3125rem; + position: absolute; + bottom: 42px; + right: 0; + top: 0; + cursor: pointer; + outline: none; +} +@media screen and (min-width: 768px) { + .cookie-banner-wrapper .close-button { + right: 20%; + top: inherit; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + .cookie-banner-wrapper .close-button { + right: 0; + top: 0; + } +} + +.main-menu ul li .ecosystem-dropdown, .main-menu ul li .resources-dropdown a { + cursor: pointer; +} +.main-menu ul li .dropdown-menu { + border-radius: 0; + padding: 0; +} +.main-menu ul li .dropdown-menu .dropdown-item { + color: #6c6c6d; + border-bottom: 1px solid #e2e2e2; +} +.main-menu ul li .dropdown-menu .dropdown-item:last-of-type { + border-bottom-color: transparent; +} +.main-menu ul li .dropdown-menu .dropdown-item:hover { + background-color: #e44c2c; +} +.main-menu ul li .dropdown-menu .dropdown-item p { + font-size: 1rem; + color: #979797; +} +.main-menu ul li .dropdown-menu a.dropdown-item:hover { + color: #ffffff; +} +.main-menu ul li .dropdown-menu a.dropdown-item:hover p { + color: #ffffff; +} + +.ecosystem-dropdown-menu, .resources-dropdown-menu { + left: -75px; + width: 226px; + display: none; + position: absolute; + top: 3.125rem; + z-index: 1000; + display: none; + float: left; + min-width: 10rem; + padding: 0.5rem 0; + margin: 0.125rem 0 0; + font-size: 1rem; + color: #212529; + text-align: left; + list-style: none; + background-color: #ffffff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; +} + +.ecosystem-dropdown-menu.show-menu, .resources-dropdown-menu.show-menu { + display: block; +} + +.main-menu ul li .ecosystem-dropdown-menu, .main-menu ul li .resources-dropdown-menu { + border-radius: 0; + padding: 0; +} + +.main-menu ul li .ecosystem-dropdown-menu .dropdown-item, .main-menu ul li .resources-dropdown-menu .dropdown-item { + color: #6c6c6d; + border-bottom: 1px solid #e2e2e2; +} + +.header-holder .main-menu ul li a.nav-dropdown-item { + display: block; + font-size: 1rem; + line-height: 1.3125rem; + width: 100%; + padding: 0.25rem 1.5rem; + clear: both; + font-weight: 400; + color: #979797; + text-align: center; + background-color: transparent; + border-bottom: 1px solid #e2e2e2; +} +.header-holder .main-menu ul li a.nav-dropdown-item:last-of-type { + border-bottom-color: transparent; +} +.header-holder .main-menu ul li a.nav-dropdown-item:hover { + background-color: #e44c2c; + color: white; +} +.header-holder .main-menu ul li a.nav-dropdown-item .dropdown-title { + font-size: 1.125rem; + color: #6c6c6d; + letter-spacing: 0; + line-height: 34px; +} + +.header-holder .main-menu ul li a.nav-dropdown-item:hover .dropdown-title { + background-color: #e44c2c; + color: white; +} + +/*# sourceMappingURL=theme.css.map */ \ No newline at end of file diff --git a/docs/_templates/autosummary/class.rst b/docs/_templates/autosummary/class.rst new file mode 100644 index 00000000..b4e0d666 --- /dev/null +++ b/docs/_templates/autosummary/class.rst @@ -0,0 +1,32 @@ +{{ fullname | escape | underline}} + +.. currentmodule:: {{ module }} + +.. autoclass:: {{ objname }} + :members: + {% block methods %} + + {% if methods %} + .. rubric:: {{ _('Methods') }} + + .. autosummary:: + {% for item in methods %} + {%- if item not in inherited_members %} + {%- if not item.startswith('_') or item in ['__call__', '__mul__', '__getitem__', '__len__'] %} + ~{{ name }}.{{ item }} + {% endif %} + {% endif %} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block attributes %} + {% if attributes %} + .. rubric:: {{ _('Attributes') }} + + .. autosummary:: + {% for item in attributes %} + ~{{ name }}.{{ item }} + {%- endfor %} + {% endif %} + {% endblock %} diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html new file mode 100644 index 00000000..37977beb --- /dev/null +++ b/docs/_templates/layout.html @@ -0,0 +1,322 @@ +{# TEMPLATE VAR SETTINGS #} +{%- set url_root = pathto('', 1) %} +{%- if url_root == '#' %}{% set url_root = '' %}{% endif %} +{%- if not embedded and docstitle %} + {%- set titlesuffix = " — "|safe + docstitle|e %} +{%- else %} + {%- set titlesuffix = "" %} +{%- endif %} +{%- set lang_attr = 'en' if language == None else (language | replace('_', '-')) %} +{% import 'theme_variables.jinja' as theme_variables %} + + + + + + + {{ metatags }} + + {% block htmltitle %} + {{ title|striptags|e }}{{ titlesuffix }} + {% endblock %} + + {# FAVICON #} + {% if favicon %} + + {% endif %} + {# CANONICAL URL #} + {% if theme_canonical_url %} + + {% endif %} + + {# CSS #} + + {# OPENSEARCH #} + {% if not embedded %} + {% if use_opensearch %} + + {% endif %} + + {% endif %} + + + + {%- for css in css_files %} + {%- if css|attr("rel") %} + + {%- else %} + + {%- endif %} + {%- endfor %} + {%- for cssfile in extra_css_files %} + + {%- endfor %} + + {%- block linktags %} + {%- if hasdoc('about') %} + + {%- endif %} + {%- if hasdoc('genindex') %} + + {%- endif %} + {%- if hasdoc('search') %} + + {%- endif %} + {%- if hasdoc('copyright') %} + + {%- endif %} + {%- if next %} + + {%- endif %} + {%- if prev %} + + {%- endif %} + {%- endblock %} + {%- block extrahead %} {% endblock %} + + {# Keep modernizr in head - http://modernizr.com/docs/#installing #} + + + + +
+
+
+ + + + + +
+ +
+
+ + + + + {% block extrabody %} {% endblock %} + + {# SIDE NAV, TOGGLES ON MOBILE #} + + {% include "versions.html" %} + + + + + +
+
+
+ {% include "breadcrumbs.html" %} +
+ +
+ Shortcuts +
+
+ +
+
+ + {%- block content %} + {% if theme_style_external_links|tobool %} + + +
+
+
+ {{ toc }} +
+
+
+
+
+ + {% if not embedded %} + + {% if sphinx_version >= "1.8.0" %} + + {%- for scriptfile in script_files %} + {{ js_tag(scriptfile) }} + {%- endfor %} + {% else %} + + {%- for scriptfile in script_files %} + + {%- endfor %} + {% endif %} + + {% endif %} + + + + + + + + +{%- block footer %} {% endblock %} + +
+
+
+ + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + diff --git a/docs/_templates/theme_variables.jinja b/docs/_templates/theme_variables.jinja new file mode 100644 index 00000000..e8ed7384 --- /dev/null +++ b/docs/_templates/theme_variables.jinja @@ -0,0 +1,26 @@ +{%- set external_urls = { + 'github': 'https://github.com/Qiskit-Partners/qiskit-runtime', + 'github_issues': 'https://github.com/Qiskit-Partners/qiskit-runtime/issues', + 'contributing': 'https://github.com/Qiskit/qiskit/blob/master/CONTRIBUTING.md', + 'docs': 'https://qiskit.org/documentation/', + 'api': 'https://runtime-us-east.quantum-computing.ibm.com/openapi/', + 'ml': 'https://qiskit.org/documentation/machine-learning/', + 'nature': 'https://qiskit.org/documentation/nature/', + 'finance': 'https://qiskit.org/documentation/finance/', + 'optim': 'https://qiskit.org/documentation/optimization/', + 'experiments': 'https://qiskit.org/documentation/experiments/', + 'partners': 'https://qiskit.org/documentation/partners/', + 'twitter': 'https://twitter.com/qiskit', + 'events': 'https://qiskit.org/events', + 'textbook': 'https://qiskit.org/textbook', + 'slack': 'https://qiskit.slack.com', + 'home': 'https://qiskit.org/', + 'blog': 'https://pytorch.org/blog/', + 'resources': 'https://qiskit.org/learn', + 'support': 'https://pytorch.org/support', + 'youtube': 'https://www.youtube.com/qiskit', + 'iqx': 'https://quantum-computing.ibm.com/', + 'iqx_systems': 'https://quantum-computing.ibm.com/docs/manage/backends/', + 'ibm': 'https://www.ibm.com/quantum-computing/', +} +-%} diff --git a/docs/_templates/versions.html b/docs/_templates/versions.html new file mode 100644 index 00000000..800a9581 --- /dev/null +++ b/docs/_templates/versions.html @@ -0,0 +1,24 @@ +
+ + {{ version_label }} + + +
+ {% if translations %} +
+
{{ _('Languages') }}
+ {% for code, language in translations_list %} +
{{ language }}
+ {% endfor %} +
+ {% endif %} +
+ +
diff --git a/docs/apidocs/main.rst b/docs/apidocs/main.rst new file mode 100644 index 00000000..27b9a3da --- /dev/null +++ b/docs/apidocs/main.rst @@ -0,0 +1,6 @@ +.. _mthree-main: + +.. automodule:: mthree + :no-members: + :no-inherited-members: + :no-special-members: diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 00000000..1fa47578 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- + +# (C) Copyright IBM 2020. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +# pylint: disable=invalid-name +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + +import mthree as m3 + +""" +Sphinx documentation builder +""" + +# The short X.Y version +version = m3.__version__ +# The full version, including alpha/beta/rc tags +release = m3.__version__ + + +rst_prolog = """ +.. |version| replace:: {0} +""".format(m3.version.short_version) + +# -- Project information ----------------------------------------------------- +project = 'Mthree {}'.format(version) +copyright = '2021, Mthree Team' # pylint: disable=redefined-builtin +author = 'Mthree Development Team' +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.napoleon', + 'sphinx.ext.autodoc', + 'sphinx.ext.autosummary', + 'sphinx.ext.mathjax', + 'sphinx.ext.viewcode', + 'sphinx.ext.extlinks', + 'jupyter_sphinx' +] +html_static_path = ['_static'] +templates_path = ['_templates'] +html_css_files = ['gallery.css'] + +exclude_patterns = ['_build', '**.ipynb_checkpoints'] + +# ----------------------------------------------------------------------------- +# Autosummary +# ----------------------------------------------------------------------------- +autosummary_generate = True + +# ----------------------------------------------------------------------------- +# Autodoc +# ----------------------------------------------------------------------------- + +autodoc_default_options = { + 'inherited-members': None, +} + +autoclass_content = 'init' + + +# If true, figures, tables and code-blocks are automatically numbered if they +# have a caption. +numfig = True + +# A dictionary mapping 'figure', 'table', 'code-block' and 'section' to +# strings that are used for format of figure numbers. As a special character, +# %s will be replaced to figure number. +numfig_format = { + 'table': 'Table %s' +} +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# A boolean that decides whether module names are prepended to all object names +# (for object types where a “module” of some kind is defined), e.g. for +# py:function directives. +add_module_names = False + +# A list of prefixes that are ignored for sorting the Python module index +# (e.g., if this is set to ['foo.'], then foo.bar is shown under B, not F). +# This can be handy if you document a project that consists of a single +# package. Works only for the HTML builder currently. +modindex_common_prefix = ['mthree.'] + +# -- Configuration for extlinks extension ------------------------------------ +# Refer to https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "qiskit_sphinx_theme" + + +#html_sidebars = {'**': ['globaltoc.html']} +html_last_updated_fmt = '%Y/%m/%d' diff --git a/docs/images/truncation.png b/docs/images/truncation.png new file mode 100644 index 0000000000000000000000000000000000000000..415c0584fc38211dd24ee3646e751497a44206b7 GIT binary patch literal 126320 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 a77*pfH{Ql6j-wk2#LURru=tqU<-Y;CnMJ?= literal 0 HcmV?d00001 diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 00000000..d5d855bc --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,35 @@ +################## +mthree (|version|) +################## + +mthree is a package for scalable quantum measurement error mitigation that need not +explicitly form the assignment matrix, or its inverse, as is thus a **m**\atrix-free +**m**\easurement **m**\itigation (M3) routine. + +M3 works in a reduced subspace defined by the noisy input bitstrings that are to be +corrected. Because the number of unique bitstrings can be much smaller than the +dimensionality of the full multi-qubit Hilbert space, the resulting linear system +of equations is nominally much easier to solve. + +.. figure:: images/truncation.png + :align: center + +It is often the case that this linear equation is trivial to solve using LU decomposition, +using only modest computing resources. However, if the number of unique bistrings is large, +and / or one has very tight memory constraints, then the problem can be solved in a matrix-free +manner using an preconditioned interative linear solution method, e.g. the Generalized minimal +residual (GMRES) or biconjugate gradient stabilized (BiCGSTAB) methods. + + +.. toctree:: + :maxdepth: 1 + :hidden: + + self + +.. toctree:: + :maxdepth: 1 + :caption: API Documentation + :hidden: + + Mitigation classes \ No newline at end of file diff --git a/examples/30Q_GHZ_Manhattan.ipynb b/examples/30Q_GHZ_Manhattan.ipynb new file mode 100644 index 00000000..4aa130a1 --- /dev/null +++ b/examples/30Q_GHZ_Manhattan.ipynb @@ -0,0 +1,326 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 30Q GHZ state trial on Manhattan\n", + "\n", + "This notebook requires: `Qiskit >= 0.24`, and of course `mthree >= 0.4.1`. The latter must be installed from source at the moment.\n", + "\n", + "This will attempt to execute a 30Q GHZ state using Manhattan. This is interesting as forming the full mitigation matrix would require $2^{60}$ elements.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import time\n", + "import numpy as np\n", + "from qiskit import *\n", + "from qiskit.ignis.mitigation import expectation_value" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "IBMQ.load_account()\n", + "provider = IBMQ.get_provider(group='deployed')\n", + "backend = provider.backend.ibmq_manhattan" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "================================================================================\n", + "# Matrix-free Measurement Mitigation (M3) version 0.4.1.dev1+1fabf99\n", + "# (C) Copyright IBM Quantum, 2021\n", + "# Paul Nation, Hwajung Kang, and Jay Gambetta\n", + "================================================================================\n" + ] + } + ], + "source": [ + "import mthree\n", + "mthree.about()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "30" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "layers = [[4], \n", + " [5], \n", + " [6,11], \n", + " [7,17,3], \n", + " [8,18,2], \n", + " [12,19,1], \n", + " [21,25,0],\n", + " [22,33,10],\n", + " [23,32,13],\n", + " [26,31,14],\n", + " [37,39,15],\n", + " [45,24]]\n", + "\n", + "qubits = sum(layers, [])\n", + "len(qubits)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Build 30 qubit GHZ circuit" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "qc = QuantumCircuit(65, len(qubits))\n", + "qc.h(4)\n", + "#branch 1\n", + "qc.cx(4,5)\n", + "qc.cx(5,6)\n", + "qc.cx(6,7)\n", + "qc.cx(7,8)\n", + "qc.cx(8,12)\n", + "qc.cx(12,21)\n", + "qc.cx(21,22)\n", + "qc.cx(22,23)\n", + "qc.cx(23,26)\n", + "qc.cx(26,37)\n", + "#branch 2\n", + "qc.cx(4,11)\n", + "qc.cx(11,17)\n", + "qc.cx(17,18)\n", + "qc.cx(18,19)\n", + "qc.cx(19,25)\n", + "qc.cx(25,33)\n", + "qc.cx(33,32)\n", + "qc.cx(32,31)\n", + "qc.cx(31,39)\n", + "qc.cx(39,45)\n", + "#branch 3\n", + "qc.cx(4,3)\n", + "qc.cx(3,2)\n", + "qc.cx(2,1)\n", + "qc.cx(1,0)\n", + "qc.cx(0,10)\n", + "qc.cx(10,13)\n", + "qc.cx(13,14)\n", + "qc.cx(14,15)\n", + "qc.cx(15,24)\n", + "qc.measure(qubits, range(len(qubits)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Instantiate M3 Instance" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "mit = mthree.M3Mitigation(backend)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Calibration" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "mit.tensored_cals_from_system(qubits)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Execute the circuit on the backend and compute the expectation value" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "ghz_job = execute(qc, backend, shots=8192, optimization_level=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3874" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "real_counts = ghz_job.result().get_counts()\n", + "len(real_counts)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0849609375" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "expectation_value(real_counts)[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Measurement mitigation by M3 and compute the expectation value" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'method': 'direct',\n", + " 'time': 0.7396790981292725,\n", + " 'dimension': 3874,\n", + " 'col_norms': array([0.9033827 , 0.42526317, 0.71993441, ..., 0.61167295, 0.52939782,\n", + " 0.78016068])}" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "quasi, details = mit.apply_correction(real_counts, qubits=qubits, details=True)\n", + "details" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.5027474694623298" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "expectation_value(quasi)[0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/M3_paper_example1.ipynb b/examples/M3_paper_example1.ipynb new file mode 100644 index 00000000..5cfddb7b --- /dev/null +++ b/examples/M3_paper_example1.ipynb @@ -0,0 +1,626 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# M3 paper example 1" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import time\n", + "import numpy as np\n", + "from qiskit import *\n", + "import mthree" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit.quantum_info import Statevector" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit.ignis.mitigation.expval import (expval_meas_mitigator_circuits ,\n", + " TensoredExpvalMeasMitigator,\n", + " ExpvalMeasMitigatorFitter, expectation_value)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "sns.set_theme()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "IBMQ.load_account()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "provider = IBMQ.get_provider(group='deployed')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Set backend and define circuit" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "backend = provider.backend.ibmq_mumbai" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "qubits= [1,4,7,10,12,13,14,11,8,5,3,2]" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
      ┌───┐┌───┐                         ┌───┐\n",
+       " q_0: ┤ X ├┤ H ├─────────────────────────┤ H ├\n",
+       "      ├───┤├───┤                    ┌───┐└─┬─┘\n",
+       " q_1: ┤ X ├┤ H ├────────────────────┤ H ├──■──\n",
+       "      ├───┤├───┤               ┌───┐└─┬─┘     \n",
+       " q_2: ┤ X ├┤ H ├───────────────┤ H ├──■───────\n",
+       "      ├───┤├───┤          ┌───┐└─┬─┘          \n",
+       " q_3: ┤ X ├┤ H ├──────────┤ H ├──■────────────\n",
+       "      ├───┤├───┤     ┌───┐└─┬─┘               \n",
+       " q_4: ┤ X ├┤ H ├─────┤ H ├──■─────────────────\n",
+       "      ├───┤├───┤┌───┐└─┬─┘                    \n",
+       " q_5: ┤ X ├┤ H ├┤ H ├──■──────────────────────\n",
+       "      ├───┤├───┤└─┬─┘                         \n",
+       " q_6: ┤ X ├┤ H ├──■────■──────────────────────\n",
+       "      ├───┤├───┤     ┌─┴─┐                    \n",
+       " q_7: ┤ X ├┤ H ├─────┤ H ├──■─────────────────\n",
+       "      ├───┤├───┤     └───┘┌─┴─┐               \n",
+       " q_8: ┤ X ├┤ H ├──────────┤ H ├──■────────────\n",
+       "      ├───┤├───┤          └───┘┌─┴─┐          \n",
+       " q_9: ┤ X ├┤ H ├───────────────┤ H ├──■───────\n",
+       "      ├───┤├───┤               └───┘┌─┴─┐     \n",
+       "q_10: ┤ X ├┤ H ├────────────────────┤ H ├──■──\n",
+       "      ├───┤├───┤                    └───┘┌─┴─┐\n",
+       "q_11: ┤ X ├┤ H ├─────────────────────────┤ H ├\n",
+       "      └───┘└───┘                         └───┘
" + ], + "text/plain": [ + " ┌───┐┌───┐ ┌───┐\n", + " q_0: ┤ X ├┤ H ├─────────────────────────┤ H ├\n", + " ├───┤├───┤ ┌───┐└─┬─┘\n", + " q_1: ┤ X ├┤ H ├────────────────────┤ H ├──■──\n", + " ├───┤├───┤ ┌───┐└─┬─┘ \n", + " q_2: ┤ X ├┤ H ├───────────────┤ H ├──■───────\n", + " ├───┤├───┤ ┌───┐└─┬─┘ \n", + " q_3: ┤ X ├┤ H ├──────────┤ H ├──■────────────\n", + " ├───┤├───┤ ┌───┐└─┬─┘ \n", + " q_4: ┤ X ├┤ H ├─────┤ H ├──■─────────────────\n", + " ├───┤├───┤┌───┐└─┬─┘ \n", + " q_5: ┤ X ├┤ H ├┤ H ├──■──────────────────────\n", + " ├───┤├───┤└─┬─┘ \n", + " q_6: ┤ X ├┤ H ├──■────■──────────────────────\n", + " ├───┤├───┤ ┌─┴─┐ \n", + " q_7: ┤ X ├┤ H ├─────┤ H ├──■─────────────────\n", + " ├───┤├───┤ └───┘┌─┴─┐ \n", + " q_8: ┤ X ├┤ H ├──────────┤ H ├──■────────────\n", + " ├───┤├───┤ └───┘┌─┴─┐ \n", + " q_9: ┤ X ├┤ H ├───────────────┤ H ├──■───────\n", + " ├───┤├───┤ └───┘┌─┴─┐ \n", + "q_10: ┤ X ├┤ H ├────────────────────┤ H ├──■──\n", + " ├───┤├───┤ └───┘┌─┴─┐\n", + "q_11: ┤ X ├┤ H ├─────────────────────────┤ H ├\n", + " └───┘└───┘ └───┘" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "N = 12\n", + "qc = QuantumCircuit(N)\n", + "\n", + "qc.x(range(0, N))\n", + "qc.h(range(0, N))\n", + "\n", + "for kk in range(N//2,0,-1):\n", + " qc.ch(kk, kk-1)\n", + "for kk in range(N//2, N-1):\n", + " qc.ch(kk, kk+1)\n", + "qc.draw(fold=-1)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.44628906249999983" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "state = Statevector.from_instruction(qc)\n", + "ideal_expval = expectation_value(state.probabilities_dict())[0]\n", + "ideal_expval" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "#add measurements to circuit" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "qc.measure_all()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Get raw data" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "raw_counts = execute([qc]*100, backend, shots=8192, initial_layout=qubits).result().get_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "raw_dist = []\n", + "for kk in range(100):\n", + " raw_dist.append(expectation_value(raw_counts[kk])[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Mitigate using Ignis tensored expval" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "circs, labels = expval_meas_mitigator_circuits(12, method='tensored')" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "job = execute(circs, backend, shots=8192, initial_layout=qubits)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "fitter = ExpvalMeasMitigatorFitter(job.result(), labels).fit()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "TN time: 3.37315623998642\n" + ] + } + ], + "source": [ + "tn_dist = []\n", + "st = time.time()\n", + "for kk in range(100):\n", + " tn_dist.append(expectation_value(raw_counts[kk], meas_mitigator=fitter)[0])\n", + "print('TN time:', (time.time()-st)/100)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Mitigate using M3 and same calibration matrices as Ignis tensored" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "mit = mthree.M3Mitigation(None)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "mats = [None]*16\n", + "\n", + "for kk, mat in enumerate(fitter._assignment_mats):\n", + " mats[qubits[kk]] = mat" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "mit.single_qubit_cals = mats" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "M3 time: 0.013745360374450684\n" + ] + } + ], + "source": [ + "m3_dist = []\n", + "st = time.time()\n", + "for kk in range(100):\n", + " m3_counts = mit.apply_correction(raw_counts[kk], qubits)\n", + " m3_dist.append(expectation_value(m3_counts)[0])\n", + "print('M3 time:', (time.time()-st)/100)" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [], + "source": [ + "num_counts = []\n", + "for cnt in raw_counts:\n", + " num_counts.append(len(cnt))" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "697.1" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.mean(num_counts)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Take a look at one of the subspace A-matrices used" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "A3, _ = mit.reduced_cal_matrix(raw_counts[-1], qubits)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from matplotlib.colors import LogNorm\n", + "fig, ax = plt.subplots(figsize=(10,8))\n", + "mat = ax.matshow(A3, cmap='plasma', norm=LogNorm(vmin=A3[A3>1e-3].min(), vmax=1))\n", + "cbar = plt.colorbar(mat);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Simulation with no measurement error (gate errors only)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit.providers.aer.noise import NoiseModel\n", + "sim = Aer.get_backend('qasm_simulator')" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "nm = NoiseModel.from_backend(backend)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "for key, val in nm._local_readout_errors.items():\n", + " nm._local_readout_errors[key]._probabilities = np.identity(2)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "nm_meas_counts = execute([qc]*100, sim, noise_model=nm, shots=8192).result().get_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "no_meas_dist = []\n", + "st = time.time()\n", + "for kk in range(100):\n", + " no_meas_dist.append(expectation_value(nm_meas_counts[kk])[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Generate plot" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "image/png": "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TU2Fv78/dDodnnzySWzdutWwfl5eHs6fP49mzZpVe/by+Pn5ISUlxfD66tWruHLlCvz9/c0V18BcucUe84rkzs7Oxvvvv49atWph1apVcHNzM1puqeP9sNyWPN6rV6/GV199ZdR24sQJQy4xx9uc2S11zNu2bYsdO3Zg48aNhi83NzeEh4dj1KhRAMQfc7Op7ummYoqNjRV69+4tpKenC7/88ovQrl07YevWrYIgCML169eFgoICQRCKpyB37NhRmDhxovDff/8JU6ZMETp16mS4HicqKkp4+umnhYMHDwr//POPMHToUKF3796CVqut9uz3+/7770tcMnDkyBHD9V0ZGRnCu+++KwwaNMjic4s95qbm/vzzz4V27doJf//9t9G1WTk5OYIgWO54l5fbUsf7yJEjQsuWLYVVq1YJZ8+eFb788kvB399fuHr1qmG5mONtzuyWOuYPevLJJ40udaiOMTcHSRW//Px8YezYsYK/v7/QpUsXYdmyZYZlpV242bdvX8HX11d49dVXhWPHjhmW5eXlCV988YXQpUsXwc/PTxg6dKhw+fJli8l+T2lFRBAEYcOGDUL37t0Ff39/Yfjw4UJWVpbF5xZ7zE3NHRwcLDRv3rzE1/3XPVnieJeX21LHWxAEYceOHcLzzz9v+Nm8d53cPWKOtzmzW/KY3+/B4icI4o+5OfCRRkREJDmSOedHRER0D4sfERFJDosfERFJDosfERFJDosfERFJDosfERFJDosfSUaPHj1KPCX73tcLL7xQ3fEAFN9NaOPGjRV6EvapU6fw22+/GV736NEDCxcurIJ05vHEE09g06ZN1R2DJE4yN7YmAoDBgwfjvffeK9Fe0dvEVZUjR44gMjISu3btMvk9w4cPx4svvoju3bsDAJKTky3+psJE1c0yfuKJROLo6GjRN9ytzD0nHnxP3bp1zRWHqMbiYU+i+yxduhS+vr6Gu+8XFhbihRdewJAhQwAAUVFRiIyMRGxsLAICAtC1a1fMnz/fqAD9+++/+OCDD+Dn54du3brh888/R05OjmG5VqtFfHw8QkJC4O/vjzfffBNpaWm4dOkS3n77bQDA008/jXnz5gEAfv75Z7z66qto27Yt/Pz88Oabb+Lo0aMAip/IfuHCBcyfPx89evQAUPKw565duxAaGgo/Pz90794d8+bNMzyt+6+//kKbNm3w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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = plt.figure(figsize=(7,7))\n", + "gs = fig.add_gridspec(4, hspace=0.1)\n", + "axs = gs.subplots(sharex=True, sharey=True)\n", + "axs[0].hist(raw_dist, bins=5, color='#009d9a')\n", + "axs[0].legend(['Raw counts'], fontsize=12)\n", + "\n", + "axs[1].hist(tn_dist, bins=10, color='#002d9c')\n", + "axs[1].legend(['Full tensored mitigation'], fontsize=12)\n", + "\n", + "axs[2].hist(m3_dist, bins=10, color='#a56eff')\n", + "axs[2].legend(['M3 tensored mitigation'], fontsize=12)\n", + "axs[2].set_ylabel(' Occurrences', fontsize=15)\n", + "\n", + "axs[3].hist(no_meas_dist, bins=5, color='#9f1853')\n", + "axs[3].legend(['Gate errors only simulation'], fontsize=12)\n", + "axs[3].set_xlabel('Expectation value', fontsize=15)\n", + "for ax in axs:\n", + " ax.label_outer()\n", + " ax.tick_params(labelsize=14);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Look at how mitigation performs verses max Hamming distance" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [], + "source": [ + "m3_weighted_dist = []\n", + "for dist in range(13):\n", + " _temp = []\n", + " for kk in range(100):\n", + " m3_counts = mit.apply_correction(raw_counts[kk], qubits, distance=dist)\n", + " _temp.append(expectation_value(m3_counts)[0])\n", + " m3_weighted_dist.append(_temp)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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jh07AmhoPwB06tTJlKGZRGBgID799FNUV1fD3t4eQMPfw6CgINMGZiSNj7mWlZXhyy+/NEiyBtiHfd/utVxoa3fmzBl88cUXmDNnDgICAiCTyTQ/lsDLywve3t6an7Zt28LW1hbe3t6mDs0ounbtiuHDh2PevHk4f/48Tp06hRUrVmDixIkW8YU1KCgIfn5+mDdvHnJycnDmzBnEx8fjr3/9K5ydnU0dntH169cPnp6emDt3Li5duoT169fj7NmzePbZZ00dmlH885//xM8//4zExETY2dlp/haWl5frtZ7W/5tlQPPmzcPixYsRFRUFBwcHvPrqqxg7dqypwzKKAwcOAABWrlyJlStXau37+eefLeKPtqVLTk7G0qVLERUVBbFYjIiICIsZdCgWi/Hpp5/i/fffR1RUFCQSCUaPHo233nrL1KGZhLW1NdauXYsFCxYgMjISXbp0wZo1ayzmbsP+/fuhVCrxwgsvaJUHBwdj69atequHy2sSERGZAd4SJyIiMgNM2ERERGaACZuIiMgMMGETERGZASZsIiIiM8CETUREZAaYsIlaoWHDhsHX11fzExAQgOHDh2PZsmWaOZ9PnDgBX19fQSsqqdVq7Nq1CyUlJYYOnYiaweewiVqhYcOGYezYsYiKigLQsJrS+fPnkZSUBE9PT2zatAkAcPv2bbi4uNxzsY7Tp0/jueeew6FDhyxmMgyihw2noyJqpezt7bUWX+jSpQu8vb0xYcIE/Otf/8KUKVMEL87A7/VEpsdb4kQWxN/fHyEhIUhPT9e5Jf79998jIiICffr0weDBg7FkyRLU1tbi+vXrmDp1KgBg+PDhWL16NYCG6WknTJiAPn36IDAwEJMnT0ZWVpamLl9fX3z11VeYOnUq+vTpg9GjR2P79u1a8ezatQvjx4/X7P/mm280+3755RfMmTMHwcHBCAsLQ2xsLG7dumXot4joocWETWRhevbsidzcXK2y0tJSzJ49G5MnT8a+ffuwfPlypKenY8OGDejYsSPWrl0LANi5cyeio6ORlZWFv//974iMjER6ejo2b94MAIiPj9c674oVKzB16lR88803ePTRR7F48WLcuHEDAJCeno4FCxbgmWeewe7duzFjxgy88847+PHHH1FdXY1p06ZBKpVi27Zt+Pzzz1FXV4eoqCiddeiJLAVviRNZmLZt22oGnjUqKipCXV0dOnToAC8vL3h5eeGzzz6Dvb09rK2tNWu8Ozs7w8HBARKJBIsWLcLkyZMBNCwp+eyzz+Kdd97ROu+ECRM0C+LExcVh586dyMrKgpeXF7744guMHz9e08/u7e2NqqoqqFQq7N27FzU1NUhKSoK1tTUA4IMPPkD//v3x3XffITw83KDvEdHDiAmbyMJUVVXB0dFRq8zPzw9jxozBSy+9hA4dOmDQoEEYOXJks+uc+/n5wdHREZ9++iny8vJQUFCA7OxsqFQqreO6du2q+Xfbtm0BAHV1dQCA3NxcPPXUU1rHN652lJCQgNLSUjz66KNa+2tqajTrThNZGiZsIgvz888/w9/fX6tMJBLhww8/xOzZs3HkyBH8+OOPePXVVzFx4kQsXrxY5xzHjx/HzJkzMXz4cAQHB2PChAm4evUqFi1apHWcjY2NzmsbB7DdbQlWiUQCHx8frFmzRmffn79sEFkK9mETWZCcnBxkZmbq3FI+d+4cEhMT4ePjgxkzZiA1NRWxsbGaQWAikUjr+C1btmDQoEH48MMPMX36dAwYMEDTNy10RHmPHj1w/vx5rbK4uDi89957eOSRR3D9+nW0a9cO3t7e8Pb2houLCxITE3X634ksBRM2UStVXV0NmUwGmUyGa9euYdeuXZg5cyZCQ0N1bkU7Ojriyy+/xAcffIDCwkJkZ2fj//7v/9CnTx8AgIODAwAgOzsblZWVcHZ2xsWLF3HmzBlcu3YNmzdvxhdffAEAggeFxcTEYPfu3di6dSsKCwuxY8cO7N27F8OGDcP48ePRvn17/P3vf8e5c+eQm5uLN998E2fPnsUjjzyix3eJyHzwljhRK7VhwwZs2LABQEPC9fLywnPPPYcXXnhBM5CrUdeuXfHxxx9j1apV2LRpEyQSCR577DHMmzcPAODj44Mnn3wSsbGxmDJlCubMmYNff/0VM2bMgLW1NXx9fZGUlITY2FicO3dOp++5KSNGjMDChQvx+eef4/3330eXLl2QnJyMsLAwAEBqaiqSkpIQFRUFkUiEoKAgfPHFF3BxcdHzO0VkHjjTGRERkRngLXEiIiIzwIRNRERkBpiwiYiIzAATNhERkRlgwiYiIjIDTNhERERmgAmbiIjIDDBhExERmQEmbCIiIjPw/z46yahSxqm+AAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "out = np.array([np.mean(m3_weighted_dist[kk]) for kk in range(13)])\n", + "fig = plt.figure(figsize=(7,4))\n", + "plt.axhline(np.mean(m3_dist), color='0.3', linestyle='dashed')\n", + "plt.axhline(np.mean(raw_dist), color='0.3', linestyle='dashed')\n", + "plt.plot(range(13), out, 'o-', ms=10, color='#6929c4')\n", + "plt.ylim([0.05,0.25])\n", + "for ax in fig.get_axes():\n", + " ax.label_outer()\n", + " ax.tick_params(labelsize=14)\n", + " \n", + "plt.xlabel('Distance', fontsize=15);\n", + "plt.ylabel('Expectation value', fontsize=15);\n", + "fig.tight_layout()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/correcting_for_probabilities.ipynb b/examples/correcting_for_probabilities.ipynb new file mode 100644 index 00000000..3de8c9d4 --- /dev/null +++ b/examples/correcting_for_probabilities.ipynb @@ -0,0 +1,195 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "intimate-cookbook", + "metadata": {}, + "source": [ + "# Correcting GHZ probabilities on Melbourne\n", + "\n", + "Shows how to correct for really bad readout errors and transforming to true probability distribution." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "dietary-business", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from qiskit import *" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "composed-thumb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "================================================================================\n", + "# Matrix-free Measurement Mitigation (M3) version 0.4.1.dev1+1fabf99\n", + "# (C) Copyright IBM Quantum, 2021\n", + "# Paul Nation, Hwajung Kang, and Jay Gambetta\n", + "================================================================================\n" + ] + } + ], + "source": [ + "import mthree\n", + "mthree.about()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "natural-hunter", + "metadata": {}, + "outputs": [], + "source": [ + "IBMQ.load_account()\n", + "provider = IBMQ.get_provider(group='deployed')\n", + "backend = provider.backend.ibmq_16_melbourne" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "featured-translator", + "metadata": {}, + "outputs": [], + "source": [ + "qc = QuantumCircuit(5)\n", + "qc.h(2)\n", + "qc.cx(2,1)\n", + "qc.cx(1,0)\n", + "qc.cx(2,3)\n", + "qc.cx(3,4)\n", + "qc.measure_all()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "nominated-dominican", + "metadata": {}, + "outputs": [], + "source": [ + "trans_qc = transpile(qc, backend)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "computational-fabric", + "metadata": {}, + "outputs": [], + "source": [ + "raw_counts = backend.run(trans_qc, shots=2048).result().get_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "expanded-ability", + "metadata": {}, + "outputs": [], + "source": [ + "mit = mthree.M3Mitigation(backend)\n", + "mit.tensored_cals_from_system(range(qc.num_qubits))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "fitted-median", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'method': 'direct',\n", + " 'time': 0.002025127410888672,\n", + " 'dimension': 32,\n", + " 'col_norms': array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "quasi, details = mit.apply_correction(raw_counts, range(qc.num_qubits), details=True)\n", + "details" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "physical-suite", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit.visualization import plot_histogram" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "completed-accommodation", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAvcAAAFTCAYAAAC9GiPeAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAABtj0lEQVR4nO3dd3gVVf7H8ffJvWkkoXcSSmihSQsighQRUdzFuogNEVEQG7qouBbE8lNc17KCou6uWQugq+vCigUUaUoLKEiR3nuHkJ6c3x9zczflBhLSbz6v55mH3LnznTlnZrj3O3PPnGOstYiIiIiISMUXUNYFEBERERGR4qHkXkRERETETyi5FxERERHxE0ruRURERET8hJJ7ERERERE/oeReRERERMRPuMu6AGWpdu3atmnTpmVdDBEREZFzWrly5RFrbR0f8+u63e6/Ae3RjVt/lwmsTU9PH9m1a9dDvhao1Ml906ZNiY+PL+tiiIiIiJyTMWanr/lut/tv9evXb1OnTp3jAQEBGsDIj2VmZprDhw+3PXDgwN+Awb6W0dWdiIiISMXWvk6dOqeU2Pu/gIAAW6dOnZM4v9L4XqYUyyMiIiIixS9AiX3l4TnW+ebwSu5FRERERPyEknsRERERET9RqR+oFREREfFHd71O15Jc/3tjWVmS65fzpzv3IiIiIlLi0tLSyroIlYKSexEREREpEY0aNerwxBNP1G/VqlXbsLCwLo8++miDqKio9mFhYZ2bN2/e7oMPPqietWzDhg07LFq0qArAW2+9VdMY03XlypUhAK+++mrtyy67rHkZVaNCUXIvIiIiIiXm888/r/nVV19tPnbs2M8xMTHJixYt2njq1Kmfx48fv2/UqFHNdu7cGQjQvXv30999910EwKJFiyIiIyNTsr0Ov+SSS06XZT0qCiX3IiIiIlJiRo8efbBFixZp4eHhdsSIEcebNm2a5nK5uOuuu443adIkZdGiRWEAvXv3Tli0aFEEwLJly8IfeuihA9leR/Tv3z+hLOtRUSi5FxEREZES06RJE29j+8mTJ9eKiYlpGxER0SkiIqLTli1bQg8fPuwGGDBgwOn4+PjwXbt2uTMzM80dd9xxLD4+Pnzjxo1Bp0+fdvXo0SOx7GpRcai3HBEREREpMcYYC7Bp06aghx9+uMl///vfTf37909wu93ExMS0tdYZf6t9+/YpISEhmS+//HK97t27n65Ro0Zm7dq109588806sbGxCS6Xq0zrUVHozr2IiIiIlLjTp08HGGOoX79+GsAbb7xRa8uWLaHZl+nevfvpuLi4ur179z4N0LNnz9NxcXF1e/Xqpfb2BaQ79yIiIiJ+pjz2Q9+1a9fku++++2Dv3r3bBAQE2Ouvv/5o586dc7Sj79279+kvv/yy5oABAxIA+vbte/rdd9+t169fP7W3LyCT9VNIZRQbG2vj4+PLuhgiIiIi52SMWWmtjc09f/Xq1Ts6dux4pCzKJGVj9erVtTt27NjU13tqliMiIiIi4ieU3IuIiIiI+Akl9yIiIiIifkLJvYiIiIiIn1ByLyIiIiLiJ5Tci4iIiIj4CSX3IiIiIiJ+Qsm9iIiIiIifUHIvIiIiAnzzzTe0bt2aFi1a8NJLL+W73IoVK3C5XHz22WfeeSdOnOCGG24gJiaGNm3asGTJEgBWr15Njx496NChA7///e85depUiddD8nr77bdr9uzZs2V+73/zzTfhTZs2bV+aZcrPX//611pdu3Ztfb7x7uIsjIiIiEhFlJGRwb333svcuXOJjIykW7duDB48mLZt2+ZZ7rHHHmPgwIE55j/44INcccUVfPbZZ6SmppKYmAjAyJEjeeWVV+jTpw//+Mc/+POf/8xzzz1X4vXZ2vqZriW5/uYbn1lZnOvbv3+/+6qrrmqxbdu2kIyMDJo3b5788ssv77788svPFMf677nnnmP33HPPsazXxpiuv/7669r27dunAFxxxRUJO3bsWFsc27rwwgtbDx069OjDDz9cJqMG6869iIiIVHrLly+nRYsWREdHExQUxNChQ5k5c2ae5d58802uv/566tat65136tQpFi5cyJ133glAUFAQ1atXB2Djxo307t0bgAEDBvD555+XfGUqoGrVqmW8//77248ePfrLyZMnf/njH/944A9/+EPLtLS0si5ahaPkXkRERCq9vXv3EhUV5X0dGRnJ3r178yzzxRdfMHr06Bzzt23bRp06dbjjjjvo3LkzI0eO5MwZ54Zz+/btmTVrFgD/+te/2L17dwnXpHxp1KhRh6eeeqpeq1at2oaGhnYeMmRIk927d7t79+7dMiwsrPPFF1/c6vDhw64qVarYjh07prhcLqy1uFwue+rUKdehQ4d8tjLZuHFjkDGm6xtvvFGrfv36F1StWrXTyy+/XGfBggVVWrVq1TYiIqLTsGHDGmctn72pS2xsbGuAbt26ta1SpUrn9957r8aXX34ZUa9evQuyll+8eHGVNm3atA0LC+t85ZVXRl911VXRDzzwQEOAw4cPu/r169eiRo0aHatWrdqpX79+LbZu3RoIcP/99zdauXJl+OOPP964SpUqnbPK8PPPP4dcfPHFLatVq9apadOm7f/2t7/VyNrWgQMHXJdeemmL8PDwzh06dGizdevW4KLscyX3IiIiUulZa/PMM8bkeD127FgmTZqEy+XKMT89PZ1Vq1Zxzz338PPPPxMWFuZts/+Pf/yDKVOm0LVrV06fPk1QUFDJVaKcmjVrVo3vv/9+0/r169d+99131QcOHNjyxRdf3HPkyJFfMjMzeemll7w/g7Rq1aptSEhIl1tuuaXFjTfeeKRRo0bpZ1v3smXLwrZt2/ZrXFzctqeeeirqueeea/DDDz9sWrNmzbovv/yyxuzZs8Nzx8THx28EWLFixfrExMSf77rrruPZ309OTjZDhgxpfvPNNx85duzYL0OHDj02Z86c6lnvZ2RkcPvttx/ZtWvXrzt37lwTEhKSOWrUqMYAb7755t6uXbsmvPjii7sSExN//uCDD3adOnUq4Morr2x14403Hjty5MgvH3300bZHHnmkcXx8fAjAyJEjm4SEhGTu27dv9T/+8Y/t06dPr12U/a029yIiIlLpRUZG5rirvmfPHho2bJhjmfj4eIYOHQrAkSNH+Oqrr3C73Vx00UVERkbSvXt3AG644QZvch8TE8OcOXMA2LRpE7Nnzy6N6pQro0ePPhQVFZUO0K1bt4TatWun9ezZMwng97///YkffvghImvZTZs2rU9MTDQffvhhjdTUVJPfOrO88MIL+6tUqWKvu+66U6GhoZk33njjsawLgm7duiWsXLmyylVXXZVQmPL+8MMPYenp6eaJJ544FBAQwO23337ir3/9q7ftf/369TOGDx9+Iuv1U089tf+KK67I9wHYTz75pFqjRo1SHnzwwaMAvXr1SrzyyitPTJ8+vUanTp32f/PNN9VXrFixvmrVqpndunVLHjJkyNElS5bkuSgpKCX3IiIiUul169aNzZs3s337dho1asSMGTOYNm1ajmW2b9/u/Xv48OH87ne/45prrgEgKiqKjRs30rp1a77//nvvg7iHDh2i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ERERXHjhhVx99dWsX7+er776itDQUD766CNq1qxJcHAw9913X46HZI8cOcKePXt45plnSryuIr4UpVma2+0mJCSE0NBQwsLCvPM//fRTIiIiCAkJoV69euzZs6dU6iIiOSm5F5FKx1p7XssEBASQkpLCmTNn+POf/4y1lo4dO5KZmQnAvHnzSE5O5vTp09SrVw9rLWlpaSQnJzNs2DDvemrXrk1mZiaNGzfOd/vp6em0bt36PGoncnZFbZYGsHr1apKSkjhz5ox33h133MHzzz9PcnIygwYN4qabbiqV+ohITkruRaTSiYmJ8baVB9i+fbu3zXyWWrVqsWHDBu/rrDbznTp1wuVyceeddwIwcuRI72BT7du3JygoCLfbzaRJk9i1a1cp1EakcIqrK9fcEhMTuf/++wEYPXo0y5cvL6kqiMhZKLkXkUpn2LBhnDx5koULF5KQkMDChQsL3Gb+ggsuICwsjK+//hqAzz77jCZNmgDkSH5eeeUV6tatW2p1Eimoonblaoyhc+fOVKlShVtvvTXHMk8++STgPDCemppaktUQkXy4y7oAIiKlLSQkhCeffJLLLrsMay19+/bl6quv5uabbwZg2rRpPP3003z++ecEBwfjcrl49913vfHvvvsuN9xwA5mZmVSvXp2ffvoJgOuuu459+/ZhjKFatWp888033PV63u2/N7YUKimSj6I0SwNnFOUuXbqwbt06YmNj6d69O/fffz+ffPIJt912G6+//jrdu3fHGFPsZReRc1NyLyKV0oQJE7x9zGeZNm2a9++AgAB+/fVXn7E33ngjN954Y57527Zty7vw/CIVU6TYxcTE8MEHH3hfF6ZZGkCXLl0AaNeuHd27d+fbb7/l/vvvZ9CgQd7mbt9++y0rVqwo6aqIiA9qliMiIlKJFKVZ2qFDh9i3bx8Ahw4dYuXKlVx00UUArFu3DnAeBh8zZgx/+MMfSrdiIgIouRcREalUsjdLq1GjBr169fI2S8tqmvb0009Tv379PF25rl+/nubNmxMaGkrjxo256KKLvO3sn3rqKYKCgqhSpQp16tTh73//e5nVUaQyU7McEZGzUJt58Ufn2yytb9++JCUl+Vznv//97+ItpIicF925FxERERHxE0ruRURERET8hJJ7OW/nO3z5iRMnCA8PJzQ0lJCQEPr06eONady4MaGhoYSGhuJ2uwkNDS21+oiISE53ve57EpHyS8m9nJeiDF9etWpVtmzZQlJSEseOHWPlypX87W9/A2DXrl0kJSWRlJREp06d6NGjR6nXTURERKSiUnIv56Uow5cHBARQv359wBmuPDMzM89gJ5mZmfzyyy88/vjjpVYnERERkYpOyb2cl6IOX56amkpoaCh16tShQ4cO3HnnnTlip0yZQnBwMAMGDCjBWoiISJZvvvmG1q1b06JFC1566aU871tr+enfD/DpCy244IILWLVqFQDJyclceOGFdOzYkXbt2uXoheeRRx4hJiaGCy64gGuvvZYTJ06UVnVEKi0l93Jeijp8eVBQEElJSezYsYNNmzbxxRdf5Fhu6tSpXHrppcVTWBEROauMjAzuvfdevv76a9avX8/06dNZv359jmX2bPiaU4c384c/bebdd9/lnnvuASA4OJh58+YxadIk0tLSmDRpkndQrAEDBrB27VrWrFlDy5Yt6d+/Py1a5Lw42L17N/369aNNmza0a9eON954w7vN1atX06NHDzp06MDvf/97Tp06VUp7RKTiUnIv5yUmJsY7zDgUfvjyLE2aNKFTp045BjtJTk5mw4YNPP300yVUehERyW758uW0aNGC6OhogoKCGDp0KDNnzsyxzM61M2nZbRjGGC666CJOnDjB/v37McYQGhrKvffeyxdffEFMTAxz585l/fr1XH755bjdzpA6QUFB7N+/n82bN9OjRw9iY2MJDAxk2LBh/OUvf2HDhg0sXbqUKVOmsHbtWjp27EinTp1YtWoV48eP59prr2Xs2LHUqFGD4OBgQkJCuO6667zl++STT7ydNYSFhfH++++X6j4UKS+U3Mt5Kcrw5Rs2bGDnzp2A03Rn1apVdOnSxRv3yiuvULVqVbp161aqdRIRqaz27t1LVFSU93VkZCR79+7NscyZk3sJq+57mSVLlnDo0CG6d+/OwIEDGTFiRJ6Lgw8//JBrr72WtLQ0/vGPfxAZGelN6Pfs2QNAREQEbdq04eWXX2bfvn1EREQwefJkRo0axYABA5g/fz6TJ08mJSWFbdu28eWXX3o7cxgzZgyPPvooSUlJPProozz00EMlsq9Eyjsl93JeijJ8+bp162jTpg2hoaE0bNiQrl278uyzz3rXHRcXx6BBg8qkXiIilZGvZpS5OzrgLMscOHCAG2+8kT179rB8+XKA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AjY4ONh+9NFHdt++fbZVq1b2ueees4GBgdbtdntjs1x//fU2MDDQBgcH227dupVI/d955x1bq1Yt7+vLL7+8UOffO++8Y6tWrWqDg4PzxCclJVljjG3atOlZz9+s/Zd9H2RfJvv5GxISYj/66CNvbH77LyoqyntOu1wuGxISUoS95PD1/7c0431JSUmxbrfb/vDDD/b06dM2JCTEzpw5M8cyzzzzjK1du7bNyMiw7733ng0LC8sRe8cdd9jAwEAL2M6dO1trra1Zs6adOHGitdbap59+2gYEBPjc/xdffHGOYzdq1CjboUMHa+3/zl/ANm7c2BtTo0YN72eQtc7nR9b540vdunXt6NGji7inSkZR97/L5bIul8vOnj3bBgcH28DAQDtz5swc+79Pnz7WGJPv8Tvbtq21tmvXrrZfv35Frquv83fka9b73ZV9KoyCxue3/dJSUvU/X0C8LQf5k6byPenOfRnZlnqUGq4q3teRgdUL3SxixIgRBAcH5xhEylrL119/DUCXLl0wxvhss/jQQw/RsmVLb5vF2NhY3G43DRo0ICMjA2stYWFheUaKrVmzZo6BToA8A51ER0eTnp5Onz59vA9SZWne5WZ2rPkcKPqdR193vi655BLv3ZiaNWvSqlUrn/Fbt25l06ZN3m1v376d8PBwVq9e7Y1PTEz09iIEzi8R6enpREVFee9cG2OYN2+e985169atMcbgdruJiYkhNTWVatWqeYdPb9CgAYcOHcq3ScOrr77KvHnzOHLkCMnJyfneOS2qovysDc4vH9m7S83erOeVV16hatWqJCYm5nv+5nfnPy0tzbuN//73vwB57vxnNQm59dZbMcbw7bff0qVLFyDnA70XXHABLperUHc+S/OB6KKc/3/4wx9IT09nwIAB3HDDDd4759nP/2effZZLL700z53zuLg4qlatyocffsicOXO49NJLWb16NbNmzcoxwmfW54iv/b9kyRIiIyO9x27Hjh1AzvO3Tp063HbbbTnqVNA2zOX9gcai/HIRFxdHcHAw1atXZ9CgQfTp04eIiAimTJmSY/+vXr2asLAwn/Hn2nZ5eubF1533kuwxLXvTypdeeinPdke+ZmnX23enELljs5TXTiFE8qPkvozYfHobyP7hcubMmTzvG2O8vdXcfvvtOdp8Z43Sl/uD6YJLH6F6vRhqNryAphdc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\n", + "text/plain": [ + "
" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "plot_histogram([raw_counts, quasi.nearest_probability_distribution()], figsize=(10,5),\n", + " legend=['raw', 'm3-mitigated'])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dangerous-entity", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/m3_x8_stabilizer_example.ipynb b/examples/m3_x8_stabilizer_example.ipynb new file mode 100644 index 00000000..f090bcfc --- /dev/null +++ b/examples/m3_x8_stabilizer_example.ipynb @@ -0,0 +1,272 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# $\\langle XXXXXXXX\\rangle$ Stabilizer example\n", + " \n", + "Adapted from Ignis example by Chris Wood" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from qiskit import *\n", + "from qiskit.providers.aer import QasmSimulator, noise\n", + "\n", + "from qiskit.ignis.mitigation import (expectation_value, \n", + " expval_meas_mitigator_circuits,\n", + " ExpvalMeasMitigatorFitter)\n", + "\n", + "import mthree" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load systems and simulators" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "IBMQ.load_account()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "pro= IBMQ.get_provider(project='internal-test')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + ":2: DeprecationWarning: The `backends` provider attribute is deprecated. Please use `provider.backend` (singular) instead. You can continue to use `provider.backends()` to retrieve all backends.\n", + " backend = pro.backends.ibmq_dublin\n" + ] + } + ], + "source": [ + "sim = QasmSimulator()\n", + "backend = pro.backends.ibmq_dublin" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Test Circuit Measure stabilizer\n", + "# Eight qubit stabilizer\n", + "qubits=[1, 4, 7, 10, 12, 2, 3, 5]\n", + "\n", + "qc = QuantumCircuit(8, 8)\n", + "qc.h(0)\n", + "qc.cx(0, 1)\n", + "qc.cx(1, 2)\n", + "qc.cx(2, 3)\n", + "qc.cx(3, 4)\n", + "qc.cx(0, 5)\n", + "qc.cx(5, 6)\n", + "qc.cx(6, 7)\n", + "qc.h(range(8))\n", + "qc.measure(range(8), range(8))\n", + "\n", + "shots = 8192\n", + "#Get ideal result and raw counts from backend\n", + "result_target = execute(qc, sim, shots=shots, initial_layout=qubits).result()\n", + "result_noise = execute(qc, backend, shots=shots, initial_layout=qubits).result()\n", + "counts_target = result_target.get_counts(0)\n", + "counts_noise = result_noise.get_counts(0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Apply M3 correction" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "mit = mthree.M3Mitigation(backend)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "mit.tensored_cals_from_system(qubits)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'method': 'direct',\n", + " 'time': 0.004311084747314453,\n", + " 'dimension': 256,\n", + " 'col_norms': array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1.])}" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mit_counts, details = mit.apply_correction(counts_noise, qubits=qubits, details=True)\n", + "details" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Apply CTMP correction" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "circuits1, metadata1 = expval_meas_mitigator_circuits(len(qubits), method='tensored')" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "job_cal1 = execute(circuits1, backend, shots=8192, initial_layout=qubits)\n", + "result_cal1 = job_cal1.result()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "ctmp_mitigator = ExpvalMeasMitigatorFitter(result_cal1, metadata1).fit()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Tally all results" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ideal: 1.0\n", + "Raw: 0.497802734375\n", + "CTMP mitigated: 1.3377458081929379\n", + "M3 mitigated: 0.9543008693805328\n" + ] + } + ], + "source": [ + "print('Ideal:', expectation_value(counts_target)[0])\n", + "print('Raw:', expectation_value(counts_noise)[0])\n", + "print('CTMP mitigated:', expectation_value(counts_noise, meas_mitigator=ctmp_mitigator)[0])\n", + "print('M3 mitigated:', expectation_value(mit_counts)[0])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/mthree/__init__.py b/mthree/__init__.py new file mode 100644 index 00000000..285a01ef --- /dev/null +++ b/mthree/__init__.py @@ -0,0 +1,39 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +""" +Mitigation classes +------------------ + +.. autosummary:: + :toctree: ../stubs/ + + M3Mitigation + +""" + +try: + from .version import version as __version__ +except ImportError: + __version__ = '0.0.0' + +from .mitigation import M3Mitigation + + +def about(): + """The M3 version info function. + """ + print('='*80) + print('# Matrix-free Measurement Mitigation (M3) version {}'.format(__version__)) + print('# (C) Copyright IBM Quantum, 2021') + print('# Paul Nation, Hwajung Kang, and Jay Gambetta') + print('='*80) diff --git a/mthree/classes.py b/mthree/classes.py new file mode 100644 index 00000000..db716c38 --- /dev/null +++ b/mthree/classes.py @@ -0,0 +1,108 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module +"""mthree classes""" + +import math +from mthree.probability import quasi_to_probs +from mthree.expval import exp_val, exp_val_and_stddev +from mthree.exceptions import M3Error + + +class ProbDistribution(dict): + """A generic dict-like class for probability distributions. + """ + def __init__(self, data, shots=None): + """Initialize a probability distribution. + + Parameters: + data (dict): Input data. + shots (int): Number shots taken to form distribution. + """ + self.shots = shots + super().__init__(data) + + def expval(self): + """Compute expectation value from distribution. + + Returns: + float: Expectation value. + """ + return exp_val(self) + + def expval_and_stddev(self): + """Compute expectation value and standard deviation from distribution. + + Returns: + float: Expectation value. + float: Standard deviation. + """ + return exp_val_and_stddev(self) + + +class QuasiDistribution(dict): + """A dict-like class for representing quasi-probabilities. + """ + def __init__(self, data, shots=None, mitigation_overhead=None): + """Initialize a quasi-distribution. + + Parameters: + data (dict): Input data. + shots (int): Number shots taken to form quasi-distribution. + mitigation_overhead (float): Overhead from performing mitigation. + """ + self.shots = shots + self.mitigation_overhead = mitigation_overhead + super().__init__(data) + + def expval(self): + """Compute expectation value from distribution. + + Returns: + float: Expectation value. + """ + return exp_val(self) + + def expval_and_stddev(self): + """Compute expectation value and standard deviation estimate from distribution. + + Returns: + float: Expectation value. + float: Estimate of standard deviation upper-bound. + + Raises: + M3Error: Missing shots or mitigation_overhead information. + """ + if self.shots is None: + raise M3Error('Quasi-dist is missing shots information.') + if self.mitigation_overhead is None: + raise M3Error('Quasi-dist is missing mitigation overhead.') + return exp_val(self), math.sqrt(self.mitigation_overhead / self.shots) + + def nearest_probability_distribution(self, return_distance=False): + """Takes a quasiprobability distribution and maps + it to the closest probability distribution as defined by + the L2-norm. + + Parameters: + return_distance (bool): Return the L2 distance between distributions. + + Returns: + ProbDistribution: Nearest probability distribution. + float: Euclidean (L2) distance of distributions. + Notes: + Method from Smolin et al., Phys. Rev. Lett. 108, 070502 (2012). + """ + probs, dist = quasi_to_probs(self) + if return_distance: + return ProbDistribution(probs, self.shots), dist + return ProbDistribution(probs, self.shots) diff --git a/mthree/compute.pxd b/mthree/compute.pxd new file mode 100644 index 00000000..8db290cc --- /dev/null +++ b/mthree/compute.pxd @@ -0,0 +1,30 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +cdef unsigned int within_distance(unsigned int row, + unsigned int col, + const unsigned char * bitstrings, + unsigned int num_bits, + unsigned int distance) nogil + +cdef double compute_element(unsigned int row, + unsigned int col, + const unsigned char * bitstrings, + const double * cals, + unsigned int num_bits) nogil + +cdef void compute_col_norms(double * col_norms, + const unsigned char * bitstrings, + const double * cals, + unsigned int num_bits, + unsigned int num_elems, + unsigned int distance) nogil diff --git a/mthree/compute.pyx b/mthree/compute.pyx new file mode 100644 index 00000000..045df6ef --- /dev/null +++ b/mthree/compute.pyx @@ -0,0 +1,137 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +cimport cython +from cython.parallel cimport prange + +@cython.boundscheck(False) +@cython.cdivision(True) +cdef inline unsigned int within_distance(unsigned int row, + unsigned int col, + const unsigned char * bitstrings, + unsigned int num_bits, + unsigned int distance) nogil: + """Computes the Hamming distance between two bitstrings. + + Parameters: + row (unsigned int): The row index. + col (unsigned int): The col index. + bitstrings (unsigned char *): Pointer to array of all bitstrings. + num_bits (unsigned int): The number of bits in a bitstring. + distance (unsigned int): The distance to calculate out to. + + Returns: + unsigned int: Are the bitstrings within given distance. + """ + + cdef size_t kk + cdef unsigned int temp_dist = 0 + cdef unsigned int row_start = row*num_bits + cdef unsigned int col_start = col*num_bits + + for kk in range(num_bits): + temp_dist += bitstrings[row_start+kk] != bitstrings[col_start+kk] + return temp_dist <= distance + +@cython.boundscheck(False) +@cython.cdivision(True) +cdef inline double compute_element(unsigned int row, + unsigned int col, + const unsigned char * bitstrings, + const double * cals, + unsigned int num_bits) nogil: + """Computes the matrix element specified by the input + bit strings from the supplied tensored cals data. + + Parameters: + row_arr (unsigned char *): Basis element giving row index. + col_arr (unsigned char *): Basis element giving col index. + cals (const double *): Tensored calibration data. + num_qubits (unsigned int): Number of qubits in arrays + + Returns: + double: Matrix element value. + """ + cdef double res = 1 + cdef size_t kk + cdef unsigned int offset + cdef unsigned int row_start = num_bits*row + cdef unsigned int col_start = num_bits*col + + for kk in range(num_bits): + offset = 2*bitstrings[row_start+kk]+bitstrings[col_start+kk] + res *= cals[4*kk+offset] + return res + +@cython.boundscheck(False) +@cython.cdivision(True) +cdef void compute_col_norms(double * col_norms, + const unsigned char * bitstrings, + const double * cals, + unsigned int num_bits, + unsigned int num_elems, + unsigned int distance) nogil: + """Compute the matrix column norms for each bitstring. + + Parameters: + col_norms (double *): Pointer to double array in which to poulate norms. + bitstrings (unsigned char *): Pointer to array of all bitstrings. + num_bits (unsigned int): The number of bits in a bitstring. + num_elems (unsigned int): The number of bitstring elements. + distance (unsigned int): The distance to calculate out to. + """ + cdef size_t col, row + cdef double col_norm + cdef unsigned int MAX_DIST = 0 + + if distance == num_bits: + MAX_DIST = 1 + # Compute the column norm for each element + with nogil: + for col in prange(num_elems, schedule='static'): + col_norm = _inner_col_norm_loop(col, + bitstrings, + cals, + num_bits, + num_elems, + distance, + MAX_DIST) + col_norms[col] = col_norm + + +cdef double _inner_col_norm_loop(unsigned int col, + const unsigned char * bitstrings, + const double * cals, + unsigned int num_bits, + unsigned int num_elems, + unsigned int distance, + unsigned int MAX_DIST) nogil: + """An inner-loop function for computing col_norms in parallel. + + This is needed to get around an issue with how Cython tries to do + OMP reductions. + + Parameters: + col (int): The column of interest. + col_norms (double *): Pointer to double array in which to poulate norms. + bitstrings (unsigned char *): Pointer to array of all bitstrings. + num_bits (unsigned int): The number of bits in a bitstring. + num_elems (unsigned int): The number of bitstring elements. + distance (unsigned int): The distance to calculate out to. + MAX_DIST (unsigned int): Are we doing max distance. + """ + cdef size_t row + cdef double col_norm = 0 + + for row in range(num_elems): + if MAX_DIST or within_distance(row, col, bitstrings, num_bits, distance): + col_norm += compute_element(row, col, bitstrings, cals, num_bits) + return col_norm diff --git a/mthree/converters.pxd b/mthree/converters.pxd new file mode 100644 index 00000000..2f20b1c5 --- /dev/null +++ b/mthree/converters.pxd @@ -0,0 +1,23 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# cython: c_string_type=unicode, c_string_encoding=UTF-8 +from libcpp.map cimport map +from libcpp.string cimport string + +cdef void counts_to_internal(map[string, double] * counts, + unsigned char * vec, + double * probs, + unsigned int num_bits, + double shots) + +cdef void internal_to_probs(map[string, double] * counts, + double * probs) diff --git a/mthree/converters.pyx b/mthree/converters.pyx new file mode 100644 index 00000000..5405ee67 --- /dev/null +++ b/mthree/converters.pyx @@ -0,0 +1,68 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# cython: c_string_type=unicode, c_string_encoding=UTF-8 +cimport cython +from libcpp.map cimport map +from libcpp.string cimport string +from cython.operator cimport dereference, postincrement + +@cython.boundscheck(False) +@cython.cdivision(True) +cdef void counts_to_internal(map[string, double] * counts_map, + unsigned char * vec, + double * probs, + unsigned int num_bits, + double shots): + """Converts a Qiskit counts object (or Python dict) into an array + of bitstrings and probabilities. + + Parameters: + counts (object): A Qiskit counts object or Python dict. + vec (unsigned char *): Pointer to array of bitstrings to populate. + probs (double *): Pointer to array of probabilities to populate. + num_bits (unsigned int): Number of bits in the bitstrings. + """ + cdef unsigned int idx, letter, start + cdef map[string, double].iterator end = counts_map.end() + cdef map[string, double].iterator it = counts_map.begin() + cdef string temp + idx = 0 + while it != end: + start = num_bits*idx + probs[idx] = dereference(it).second / shots + temp = dereference(it).first + for letter in range(num_bits): + vec[start+letter] = temp[letter]-48 + idx += 1 + postincrement(it) + + +@cython.boundscheck(False) +@cython.cdivision(True) +cdef void internal_to_probs(map[string, double] * counts_map, + double * probs): + """Converts internal arrays back into a Python dict. + + Parameters: + vec (unsigned char *): Pointer to array of bitstrings. + vec (dobule *): Pointer to array of probabilities. + num_elems (unsigned int): Number of elements. + num_bits (unsigned int): Number of bits in the bitstrings. + """ + cdef size_t idx = 0 + cdef map[string, double].iterator end = counts_map.end() + cdef map[string, double].iterator it = counts_map.begin() + + while it != end: + dereference(it).second = probs[idx] + idx += 1 + postincrement(it) diff --git a/mthree/exceptions.py b/mthree/exceptions.py new file mode 100644 index 00000000..4c9bf8c9 --- /dev/null +++ b/mthree/exceptions.py @@ -0,0 +1,26 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module +"""mthree exceptions""" + + +class M3Error(Exception): + """Base class for errors raised by M3.""" + + def __init__(self, *message): + """Set the error message.""" + super().__init__(' '.join(message)) + self.message = ' '.join(message) + + def __str__(self): + """Return the message.""" + return repr(self.message) diff --git a/mthree/expval.pyx b/mthree/expval.pyx new file mode 100644 index 00000000..852ebaa5 --- /dev/null +++ b/mthree/expval.pyx @@ -0,0 +1,63 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module +"""mthree expectation value""" +cimport cython +from libc.math cimport sqrt + + +@cython.boundscheck(False) +def exp_val(object quasi): + """Computes expectation value in computational basis. + + Parameters: + quasi (dict): Input quasi-probability distribution. + + Returns: + float: Expectation value. + """ + # Find normalization to probs + cdef double exp_val = 0 + cdef str key + cdef double val + cdef unsigned int one_count + for key, val in quasi.items(): + one_count = key.count('1') % 2 + exp_val += val * (-1 if one_count else 1) + return exp_val + +@cython.boundscheck(False) +def exp_val_and_stddev(object probs): + """Computes expectation value and standard deviation in computational basis + for a given probability distribution (not quasi-probs). + + Parameters: + probs (dict): Input probability distribution. + + Returns: + float: Expectation value. + float: Standard deviation. + """ + # Find normalization to probs + cdef double exp_val = 0 + cdef double stddev, exp2 = 0 + cdef str key + cdef double val + cdef unsigned int one_count + for key, val in probs.items(): + one_count = key.count('1') % 2 + exp_val += val * (-1 if one_count else 1) + exp2 += val + + stddev = sqrt((exp2 - exp_val*exp_val) / probs.shots) + + return exp_val, stddev diff --git a/mthree/hamming.pyx b/mthree/hamming.pyx new file mode 100644 index 00000000..2c5965ae --- /dev/null +++ b/mthree/hamming.pyx @@ -0,0 +1,64 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +cimport cython +import numpy as np + + +def hamming_ball(unsigned char[::1] arr, unsigned int pos, int distance): + """Compute all bitstrings up to a given Hamming distance + away from a target bitstring. + + Parameters: + arr (char array): Input bitstring. + pos (int): Index position. + distance (int): Maximum Hamming distance to consider + + Returns: + list: List of all bitstrings as arrays. + """ + cdef list out = [] + _hamming_core(arr, pos, distance, out) + return out + +@cython.boundscheck(False) +@cython.wraparound(False) +cdef void _hamming_core(unsigned char[::1] arr, unsigned int pos, int distance, list out): + """Compute all bitstrings up to a given Hamming distance + away from a target bitstring. + + Parameters: + arr (char array): Input bitstring. + pos (int): Index position. + distance (int): Maximum Hamming distance to consider + out (list): A empty list to store bitstrings to. + """ + cdef unsigned int length = arr.shape[0] + cdef int dist_offset + cdef unsigned char temp + cdef size_t kk + + if pos == length: + # Here is where you do things for each bitstring + out.append(np.asarray(arr.copy(), dtype=np.uint8)) + return + + if distance > 0: + temp = arr[pos] + for kk in range(2): + arr[pos] = kk + dist_offset = 0 + if temp != arr[pos]: + dist_offset = -1 + _hamming_core(arr, pos+1, distance + dist_offset, out) + arr[pos] = temp + else: + _hamming_core(arr, pos+1, distance, out) diff --git a/mthree/matrix.pyx b/mthree/matrix.pyx new file mode 100644 index 00000000..6e4740df --- /dev/null +++ b/mthree/matrix.pyx @@ -0,0 +1,183 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# cython: c_string_type=unicode, c_string_encoding=UTF-8 +cimport cython +from cython.parallel cimport prange +import numpy as np +cimport numpy as np +from libc.stdlib cimport malloc, free +from libcpp.map cimport map +from libcpp.string cimport string +from libcpp cimport bool + +from .converters cimport counts_to_internal +from .compute cimport compute_element, compute_col_norms, within_distance + +@cython.boundscheck(False) +cdef double matrix_element(unsigned int row, + unsigned int col, + const unsigned char * bitstrings, + const double * cals, + unsigned int num_bits, + unsigned int distance, + unsigned int MAX_DIST) nogil: + + cdef size_t kk + cdef double out = 0 + + if MAX_DIST or within_distance(row, col, bitstrings, num_bits, distance): + out = compute_element(row, col, bitstrings, cals, num_bits) + return out + +def bitstring_int(str string): + return int(string, 2) + +@cython.boundscheck(False) +@cython.cdivision(True) +def _reduced_cal_matrix(object counts, double[::1] cals, + unsigned int num_bits, unsigned int distance): + + cdef double shots = sum(counts.values()) + cdef map[string, double] counts_map = counts + cdef unsigned int num_elems = counts_map.size() + cdef unsigned int MAX_DIST + + MAX_DIST = distance == num_bits + cdef double[::1,:] W = np.zeros((num_elems, num_elems), order='F', dtype=float) + + cdef double[::1] col_norms = np.zeros(num_elems, dtype=float) + + cdef unsigned char * bitstrings = malloc(num_bits*num_elems*sizeof(unsigned char)) + cdef double * input_probs = malloc(num_elems*sizeof(double)) + counts_to_internal(&counts_map, bitstrings, input_probs, num_bits, shots) + + cdef size_t ii, jj + cdef double col_norm, _temp + cdef dict out_dict = counts_map + + with nogil: + for jj in prange(num_elems, schedule='static'): + omp_element_compute(jj, bitstrings, &cals[0], num_elems, num_bits, distance, + &W[0,0], &col_norms[0], MAX_DIST) + + free(bitstrings) + free(input_probs) + return np.asarray(W), out_dict, np.asarray(col_norms) + +@cython.boundscheck(False) +@cython.cdivision(True) +cdef void omp_element_compute(size_t jj, const unsigned char * bitstrings, + const double * cals_ptr, + unsigned int num_elems, + unsigned int num_bits, + unsigned int distance, + double * W_ptr, + double * col_norms_ptr, + unsigned int MAX_DIST) nogil: + """Computes the matrix elements for a single column + """ + cdef double _temp, col_norm = 0 + cdef size_t ii, col_idx + col_idx = jj*num_elems + for ii in range(num_elems): + _temp = matrix_element(ii, jj, bitstrings, cals_ptr, + num_bits, distance, MAX_DIST) + W_ptr[col_idx+ii] = _temp + col_norm += _temp + col_norms_ptr[jj] = col_norm + for ii in range(num_elems): + W_ptr[col_idx+ii] /= col_norm + +@cython.boundscheck(False) +def sdd_check(dict counts, double[::1] cals, + unsigned int num_bits, unsigned int distance): + """Determines if the sub-space A matrix is strictly + diagonally dominant or not. + + Parameters: + counts (dict): Input dict of counts. + cals (double ndarray): Calibrations. + num_bits (unsigned int): Number of bits in bit-strings. + distance (unsigned int): Distance to go out to. + + Returns: + int: Is matrix SDD or not. + """ + cdef double shots = sum(counts.values()) + cdef map[string, double] counts_map = counts + cdef unsigned int num_elems = counts_map.size() + cdef unsigned int MAX_DIST + + cdef size_t row + cdef unsigned int is_sdd = 1 + + if distance > num_bits: + raise ValueError('Distance ({}) cannot be larger than' + 'the number of bits ({}).'.format(distance, num_bits)) + + MAX_DIST = distance == num_bits + + # Assign memeory for bitstrings and input probabilities + cdef unsigned char * bitstrings = malloc(num_bits*num_elems*sizeof(unsigned char)) + cdef double * input_probs = malloc(num_elems*sizeof(double)) + # Assign memeory for column norms + cdef double * col_norms = malloc(num_elems*sizeof(double)) + + # Assign memeory sdd checks + cdef bool * row_sdd = malloc(num_elems*sizeof(bool)) + # Convert sorted counts dict into bistrings and input probability arrays + counts_to_internal(&counts_map, bitstrings, input_probs, num_bits, shots) + # Compute column norms + compute_col_norms(col_norms, bitstrings, &cals[0], num_bits, num_elems, distance) + + with nogil: + for row in prange(num_elems, schedule='static'): + omp_sdd_compute(row, bitstrings, &cals[0], col_norms, + row_sdd, num_bits, num_elems, distance, MAX_DIST) + + for row in range(num_elems): + if not row_sdd[row]: + is_sdd = 0 + break + + # Free stuff here + # --------------- + free(bitstrings) + free(input_probs) + free(col_norms) + free(row_sdd) + + return is_sdd + +@cython.boundscheck(False) +@cython.cdivision(True) +cdef void omp_sdd_compute(size_t row, + const unsigned char * bitstrings, + const double * cals, + const double * col_norms, + bool * row_sdd, + unsigned int num_bits, + unsigned int num_elems, + unsigned int distance, + unsigned int MAX_DIST) nogil: + + cdef size_t col + cdef double diag_elem, mat_elem, row_sum = 0 + + diag_elem = matrix_element(row, row, bitstrings, cals, num_bits, distance, MAX_DIST) + diag_elem /= col_norms[row] + for col in range(num_elems): + if col != row: + mat_elem = matrix_element(row, col, bitstrings, cals, num_bits, distance, MAX_DIST) + mat_elem /= col_norms[col] + row_sum += mat_elem + row_sdd[row] = row_sum < diag_elem diff --git a/mthree/matvec.pyx b/mthree/matvec.pyx new file mode 100644 index 00000000..bf31d7fe --- /dev/null +++ b/mthree/matvec.pyx @@ -0,0 +1,184 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# cython: c_string_type=unicode, c_string_encoding=UTF-8 +cimport cython +from cython.parallel cimport prange +import numpy as np +cimport numpy as np +from libc.stdlib cimport malloc, free +from libcpp cimport bool +from libcpp.map cimport map +from libcpp.string cimport string +from cython.operator cimport dereference, postincrement + +from mthree.compute cimport within_distance, compute_element, compute_col_norms + + +cdef class M3MatVec(): + cdef unsigned char * bitstrings + cdef double * col_norms + cdef bool MAX_DIST + cdef unsigned int distance + cdef public unsigned int num_elems + cdef public unsigned int num_bits + cdef double * cals + cdef public dict sorted_counts + + def __cinit__(self, object counts, double[::1] cals, int distance=-1): + + cdef double shots = sum(counts.values()) + cdef map[string, double] counts_map = counts + self.num_elems = counts_map.size() + self.num_bits = len(next(iter(counts))) + self.cals = &cals[0] + self.sorted_counts = counts_map + + if distance == -1: + distance = self.num_bits + + self.distance = distance + self.MAX_DIST = self.distance == self.num_bits + + self.bitstrings = malloc(self.num_bits*self.num_elems*sizeof(unsigned char)) + self.col_norms = malloc(self.num_elems*sizeof(double)) + + counts_to_bitstrings(&counts_map, self.bitstrings, self.num_bits) + + compute_col_norms(self.col_norms, self.bitstrings, self.cals, + self.num_bits, self.num_elems, distance) + + @cython.boundscheck(False) + def get_col_norms(self): + """ + Get the internally used column norms. + + Returns: + ndarray: Column norms. + """ + cdef size_t kk + cdef double[::1] out = np.empty(self.num_elems, dtype=float) + for kk in range(self.num_elems): + out[kk] = self.col_norms[kk] + return np.asarray(out, dtype=float) + + @cython.boundscheck(False) + @cython.cdivision(True) + def get_diagonal(self): + cdef size_t kk + cdef double temp_elem + cdef double[::1] out = np.empty(self.num_elems, dtype=float) + for kk in range(self.num_elems): + temp_elem = compute_element(kk, kk, self.bitstrings, + self.cals, self.num_bits) + temp_elem /= self.col_norms[kk] + out[kk] = temp_elem + return np.asarray(out, dtype=float) + + @cython.boundscheck(False) + def matvec(self, const double[::1] x): + cdef size_t row + if x.shape[0] != self.num_elems: + raise Exception('Incorrect length of input vector.') + cdef double[::1] out = np.empty(self.num_elems, dtype=float) + with nogil: + for row in prange(self.num_elems, schedule='static'): + omp_matvec(row, &x[0], &out[0], + self.bitstrings, self.col_norms, self.cals, + self.num_elems, self.num_bits, self.distance, + self.MAX_DIST) + return np.asarray(out, dtype=float) + + @cython.boundscheck(False) + def rmatvec(self, const double[::1] x): + cdef size_t col + if x.shape[0] != self.num_elems: + raise Exception('Incorrect length of input vector.') + cdef double[::1] out = np.empty(self.num_elems, dtype=float) + with nogil: + for col in prange(self.num_elems, schedule='static'): + omp_rmatvec(col, &x[0], &out[0], + self.bitstrings, self.col_norms, self.cals, + self.num_elems, self.num_bits, self.distance, + self.MAX_DIST) + return np.asarray(out, dtype=float) + + def __dealloc__(self): + if self.bitstrings is not NULL: + free(self.bitstrings) + if self.col_norms is not NULL: + free(self.col_norms) + +@cython.boundscheck(False) +@cython.cdivision(True) +cdef void omp_matvec(size_t row, + const double * x, + double * out, + const unsigned char * bitstrings, + const double * col_norms, + const double * cals, + unsigned int num_elems, + unsigned int num_bits, + unsigned int distance, + bool MAX_DIST) nogil: + cdef double temp_elem, row_sum = 0 + cdef size_t col + for col in range(num_elems): + if MAX_DIST or within_distance(row, col, bitstrings, + num_bits, distance): + temp_elem = compute_element(row, col, bitstrings, + cals, num_bits) + temp_elem /= col_norms[col] + row_sum += temp_elem * x[col] + out[row] = row_sum + +@cython.boundscheck(False) +@cython.cdivision(True) +cdef void omp_rmatvec(size_t col, + const double * x, + double * out, + const unsigned char * bitstrings, + const double * col_norms, + const double * cals, + unsigned int num_elems, + unsigned int num_bits, + unsigned int distance, + bool MAX_DIST) nogil: + cdef double temp_elem, row_sum = 0 + cdef size_t row + for row in range(num_elems): + if MAX_DIST or within_distance(row, col, bitstrings, + num_bits, distance): + temp_elem = compute_element(row, col, bitstrings, + cals, num_bits) + temp_elem /= col_norms[col] + row_sum += temp_elem * x[row] + out[col] = row_sum + + +@cython.boundscheck(False) +@cython.cdivision(True) +cdef void counts_to_bitstrings(map[string, double] * counts_map, + unsigned char * bitstrings, + unsigned int num_bits): + + cdef unsigned int idx, letter, start + cdef map[string, double].iterator end = counts_map.end() + cdef map[string, double].iterator it = counts_map.begin() + cdef string temp + idx = 0 + while it != end: + start = num_bits*idx + temp = dereference(it).first + for letter in range(num_bits): + bitstrings[start+letter] = temp[letter]-48 + idx += 1 + postincrement(it) diff --git a/mthree/mitigation.py b/mthree/mitigation.py new file mode 100644 index 00000000..4da87415 --- /dev/null +++ b/mthree/mitigation.py @@ -0,0 +1,504 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module +"""Calibration data""" + +import warnings +from time import perf_counter + +import psutil +import numpy as np +import scipy.linalg as la +import scipy.sparse.linalg as spla +import orjson +from qiskit import QuantumCircuit, transpile + +from mthree.matrix import _reduced_cal_matrix, sdd_check +from mthree.utils import counts_to_vector, vector_to_quasiprobs +from mthree.norms import ainv_onenorm_est_lu, ainv_onenorm_est_iter +from mthree.matvec import M3MatVec +from mthree.exceptions import M3Error + + +def _tensor_meas_states(qubit, num_qubits): + """Construct |0> and |1> states + for marginal 1Q cals. + """ + qc0 = QuantumCircuit(num_qubits, 1) + qc0.measure(qubit, 0) + qc1 = QuantumCircuit(num_qubits, 1) + qc1.x(qubit) + qc1.measure(qubit, 0) + return [qc0, qc1] + + +def _marg_meas_states(num_qubits): + """Construct all zeros and all ones states + for marginal 1Q cals. + """ + qc0 = QuantumCircuit(num_qubits) + qc0.measure_all() + qc1 = QuantumCircuit(num_qubits) + qc1.x(range(num_qubits)) + qc1.measure_all() + return [qc0, qc1] + + +class M3Mitigation(): + """Main M3 calibration class.""" + def __init__(self, system, iter_threshold=4096): + """Main M3 calibration class. + + Parameters: + system (BaseBackend): Target backend. + iter_threshold (int): Sets the bitstring count at which iterative mode + is turned on (assuming reasonable error rates). + + Attributes: + system (BaseBackend): The target system. + single_qubit_cals (list): 1Q calibration matrices + """ + self.system = system + self.single_qubit_cals = None + self.num_qubits = system.configuration().num_qubits if system else None + self.iter_threshold = iter_threshold + self.cal_shots = None + self.cal_method = 'marginal' + self.rep_delay = None + + def _form_cals(self, qubits): + """Form the 1D cals array from tensored cals data + + Parameters: + qubits (array_like): The qubits to calibrate over. + + Returns: + ndarray: 1D Array of float cals data. + """ + qubits = np.asarray(qubits, dtype=int) + cals = np.zeros(4*qubits.shape[0], dtype=float) + + # Reverse index qubits for easier indexing later + for kk, qubit in enumerate(qubits[::-1]): + cals[4*kk:4*kk+4] = self.single_qubit_cals[qubit].ravel() + return cals + + def _check_sdd(self, counts, qubits, distance=None): + """Checks if reduced A-matrix is SDD or not + + Parameters: + counts (dict): Dictionary of counts. + qubits (array_like): List of qubits. + distance (int): Distance to compute over. + + Returns: + bool: True if A-matrix is SDD, else False + + Raises: + M3Error: Number of qubits supplied does not match bit-string length. + """ + # If distance is None, then assume max distance. + num_bits = len(qubits) + if distance is None: + distance = num_bits + + # check if len of bitstrings does not equal number of qubits passed. + bitstring_len = len(next(iter(counts))) + if bitstring_len != num_bits: + raise M3Error('Bitstring length ({}) does not match'.format(bitstring_len) + + ' number of qubits ({})'.format(num_bits)) + cals = self._form_cals(qubits) + return sdd_check(counts, cals, num_bits, distance) + + def tensored_cals_from_system(self, qubits=None, method='marginal', + shots=8192, rep_delay=None, counts_file=None): + """Grab calibration data from system. + + Parameters: + qubits (array_like): Qubits over which to correct calibration data. Default is all. + method (str): Type of calibration, 'marginal' (default) or 'independent'. + shots (int): Number of shots per circuit. Default is 8192. + rep_delay (float): Delay between circuits on IBM Quantum backends. + counts_file (str): Output path to write JSON calibration data to. + """ + warnings.warn("This method is deprecated, use 'cals_from_system' instead.") + self.cals_from_system(qubits=qubits, method=method, + shots=shots, rep_delay=rep_delay, + counts_file=counts_file) + + def cals_from_system(self, qubits=None, method='marginal', + shots=8192, rep_delay=None, counts_file=None): + """Grab calibration data from system. + + Parameters: + qubits (array_like): Qubits over which to correct calibration data. Default is all. + method (str): Type of calibration, 'marginal' (default) or 'independent'. + shots (int): Number of shots per circuit. Default is 8192. + rep_delay (float): Delay between circuits on IBM Quantum backends. + counts_file (str): Output path to write JSON calibration data to. + """ + if qubits is None: + qubits = range(self.num_qubits) + self.cal_method = method + self.rep_delay = rep_delay + self._grab_additional_cals(qubits, method, shots) + if counts_file: + with open(counts_file, 'wb') as fd: + fd.write(orjson.dumps(self.single_qubit_cals, + option=orjson.OPT_SERIALIZE_NUMPY)) + + def cals_from_file(self, counts_file): + """Generated the calibration data from a previous runs output + + counts_file (str): A string path to the saved counts file from an + earlier run. + """ + with open(counts_file, 'r') as fd: + self.single_qubit_cals = np.array(orjson.loads(fd.read())) + + def tensored_cals_from_file(self, counts_file): + """Generated the tensored calibration data from a previous runs output + + counts_file (str): A string path to the saved counts file from an + earlier run. + """ + warnings.warn("This method is deprecated, use 'cals_from_file' instead.") + self.cals_from_file(counts_file) + + def _grab_additional_cals(self, qubits, method='marginal', shots=8192, rep_delay=None): + """Grab missing calibration data from backend. + + Parameters: + qubits (array_like): List of measured qubits. + method (str): Type of calibration, 'marginal' (default) or 'independent'. + shots (int): Number of shots to take. + rep_delay (float): Delay between circuits on IBM Quantum backends. + + Raises: + M3Error: Faulty qubits found. + """ + if self.single_qubit_cals is None: + self.single_qubit_cals = [None]*self.num_qubits + if self.cal_shots is None: + self.cal_shots = shots + if self.rep_delay is None: + self.rep_delay = rep_delay + + if method not in ['marginal', 'independent']: + raise M3Error('Invalid calibration method.') + + num_cal_qubits = len(qubits) + if method == 'marginal': + circs = _marg_meas_states(num_cal_qubits) + trans_qcs = transpile(circs, self.system, + initial_layout=qubits, optimization_level=0) + job = self.system.run(trans_qcs, shots=self.cal_shots, rep_delay=self.rep_delay) + else: + circs = [] + for kk in qubits: + circs.extend(_tensor_meas_states(kk, self.num_qubits)) + + trans_qcs = transpile(circs, self.system, + initial_layout=qubits, optimization_level=0) + job = self.system.run(trans_qcs, shots=self.cal_shots, rep_delay=self.rep_delay) + counts = job.result().get_counts() + + # A list of qubits with bad meas cals + bad_list = [] + if method == 'independent': + for idx, qubit in enumerate(qubits): + self.single_qubit_cals[qubit] = np.zeros((2, 2), dtype=float) + # Counts 0 has all P00, P10 data, so do that here + prep0_counts = counts[2*idx] + P10 = prep0_counts.get('1', 0) / shots + P00 = 1-P10 + self.single_qubit_cals[qubit][:, 0] = [P00, P10] + # plus 1 here since zeros data at pos=0 + prep1_counts = counts[2*idx+1] + P01 = prep1_counts.get('0', 0) / shots + P11 = 1-P01 + self.single_qubit_cals[qubit][:, 1] = [P01, P11] + if P01 >= P00: + bad_list.append(qubit) + else: + prep0_counts = counts[0] + prep1_counts = counts[1] + for idx, qubit in enumerate(qubits): + self.single_qubit_cals[qubit] = np.zeros((2, 2), dtype=float) + count_vals = 0 + index = num_cal_qubits-idx-1 + for key, val in prep0_counts.items(): + if key[index] == '0': + count_vals += val + P00 = count_vals / shots + P10 = 1-P00 + self.single_qubit_cals[qubit][:, 0] = [P00, P10] + count_vals = 0 + for key, val in prep1_counts.items(): + if key[index] == '1': + count_vals += val + P11 = count_vals / shots + P01 = 1-P11 + self.single_qubit_cals[qubit][:, 1] = [P01, P11] + if P01 >= P00: + bad_list.append(qubit) + + if any(bad_list): + raise M3Error('Faulty qubits detected: {}'.format(bad_list)) + + def apply_correction(self, counts, qubits, distance=None, + method='auto', + max_iter=25, tol=1e-5, + return_mitigation_overhead=False, + details=False): + """Applies correction to given counts. + + Parameters: + counts (dict): Input counts dict. + qubits (array_like): Qubits on which measurements applied. + distance (int): Distance to correct for. Default=num_bits + method (str): Solution method: 'auto', 'iterative', 'direct'. + max_iter (int): Max. number of iterations, Default=25. + tol (float): Convergence tolerance of iterative method, Default=1e-5. + return_mitigation_overhead (bool): Returns the mitigation overhead, default=False. + details (bool): Return extra info, default=False. + + Returns: + QuasiDistribution: Dictionary of mitigated counts as probabilities. + + Raises: + M3Error: Bitstring length does not match number of qubits given. + """ + # This is needed because counts is a Counts object in Qiskit not a dict. + counts = dict(counts) + shots = sum(counts.values()) + + # If distance is None, then assume max distance. + num_bits = len(qubits) + num_elems = len(counts) + if distance is None: + distance = num_bits + + # check if len of bitstrings does not equal number of qubits passed. + bitstring_len = len(next(iter(counts))) + if bitstring_len != num_bits: + raise M3Error('Bitstring length ({}) does not match'.format(bitstring_len) + + ' number of qubits ({})'.format(num_bits)) + + # Check if no cals done yet + if self.single_qubit_cals is None: + warnings.warn('No calibration data. Calibrating: {}'.format(qubits)) + self._grab_additional_cals(qubits, method=self.cal_method) + + # Check if one or more new qubits need to be calibrated. + missing_qubits = [qq for qq in qubits if self.single_qubit_cals[qq] is None] + if any(missing_qubits): + warnings.warn('Computing missing calibrations for qubits: {}'.format(missing_qubits)) + self._grab_additional_cals(missing_qubits, method=self.cal_method) + + if method == 'auto': + current_free_mem = psutil.virtual_memory().available + # First check if direct method can be run + if num_elems <= self.iter_threshold \ + and ((num_elems**2+num_elems)*8/1024**3 < current_free_mem/1.5): + method = 'direct' + # If readout is not so good try direct if memory allows + elif np.min(self.readout_fidelity(qubits)) < 0.85 \ + and ((num_elems**2+num_elems)*8/1024**3 < current_free_mem/1.5): + method = 'direct' + else: + method = 'iterative' + + if method == 'direct': + st = perf_counter() + mit_counts, col_norms, gamma = self._direct_solver(counts, qubits, distance, + return_mitigation_overhead) + dur = perf_counter()-st + mit_counts.shots = shots + if gamma is not None: + mit_counts.mitigation_overhead = gamma * gamma + if details: + info = {'method': 'direct', 'time': dur, 'dimension': num_elems} + info['col_norms'] = col_norms + return mit_counts, info + return mit_counts + + elif method == 'iterative': + iter_count = np.zeros(1, dtype=int) + + def callback(_): + iter_count[0] += 1 + + if details: + st = perf_counter() + mit_counts, col_norms, gamma = self._matvec_solver(counts, + qubits, + distance, + tol, + max_iter, + 1, + callback, + return_mitigation_overhead) + dur = perf_counter()-st + mit_counts.shots = shots + if gamma is not None: + mit_counts.mitigation_overhead = gamma * gamma + info = {'method': 'iterative', 'time': dur, 'dimension': num_elems} + info['iterations'] = iter_count[0] + info['col_norms'] = col_norms + return mit_counts, info + # pylint: disable=unbalanced-tuple-unpacking + mit_counts, gamma = self._matvec_solver(counts, qubits, distance, tol, + max_iter, 0, None, + return_mitigation_overhead) + mit_counts.shots = shots + if gamma is not None: + mit_counts.mitigation_overhead = gamma * gamma + return mit_counts + + else: + raise M3Error('Invalid method: {}'.format(method)) + + def reduced_cal_matrix(self, counts, qubits, distance=None): + """Return the reduced calibration matrix used in the solution. + + Parameters: + counts (dict): Input counts dict. + qubits (array_like): Qubits on which measurements applied. + distance (int): Distance to correct for. Default=num_bits + + Returns: + ndarray: 2D array of reduced calibrations. + dict: Counts in order they are displayed in matrix. + + Raises: + M3Error: If bit-string length does not match passed number + of qubits. + """ + counts = dict(counts) + # If distance is None, then assume max distance. + num_bits = len(qubits) + if distance is None: + distance = num_bits + + # check if len of bitstrings does not equal number of qubits passed. + bitstring_len = len(next(iter(counts))) + if bitstring_len != num_bits: + raise M3Error('Bitstring length ({}) does not match'.format(bitstring_len) + + ' number of qubits ({})'.format(num_bits)) + + cals = self._form_cals(qubits) + A, counts, _ = _reduced_cal_matrix(counts, cals, num_bits, distance) + return A, counts + + def _direct_solver(self, counts, qubits, distance=None, + return_mitigation_overhead=False): + """Apply the mitigation using direct LU factorization. + + Parameters: + counts (dict): Input counts dict. + qubits (int): Qubits over which to calibrate. + distance (int): Distance to correct for. Default=num_bits + return_mitigation_overhead (bool): Returns the mitigation overhead, default=False. + + Returns: + QuasiDistribution: dict of Quasiprobabilites + """ + cals = self._form_cals(qubits) + num_bits = len(qubits) + A, sorted_counts, col_norms = _reduced_cal_matrix(counts, cals, num_bits, distance) + vec = counts_to_vector(sorted_counts) + LU = la.lu_factor(A, check_finite=False) + x = la.lu_solve(LU, vec, check_finite=False) + gamma = None + if return_mitigation_overhead: + gamma = ainv_onenorm_est_lu(A, LU) + out = vector_to_quasiprobs(x, sorted_counts) + return out, col_norms, gamma + + def _matvec_solver(self, counts, qubits, distance, tol=1e-5, max_iter=25, + details=0, callback=None, + return_mitigation_overhead=False): + """Compute solution using GMRES and Jacobi preconditioning. + + Parameters: + counts (dict): Input counts dict. + qubits (int): Qubits over which to calibrate. + tol (float): Tolerance to use. + max_iter (int): Maximum number of iterations to perform. + distance (int): Distance to correct for. Default=num_bits + details (bool): Return col norms. + callback (callable): Callback function to record iteration count. + return_mitigation_overhead (bool): Returns the mitigation overhead, default=False. + + Returns: + QuasiDistribution: dict of Quasiprobabilites + + Raises: + M3Error: Solver did not converge. + """ + cals = self._form_cals(qubits) + M = M3MatVec(dict(counts), cals, distance) + L = spla.LinearOperator((M.num_elems, M.num_elems), + matvec=M.matvec, rmatvec=M.rmatvec) + diags = M.get_diagonal() + + def precond_matvec(x): + out = x / diags + return out + + P = spla.LinearOperator((M.num_elems, M.num_elems), precond_matvec) + vec = counts_to_vector(M.sorted_counts) + out, error = spla.gmres(L, vec, tol=tol, atol=tol, maxiter=max_iter, + M=P, callback=callback) + if error: + raise M3Error('GMRES did not converge: {}'.format(error)) + + gamma = None + if return_mitigation_overhead: + gamma = ainv_onenorm_est_iter(M, tol=tol, max_iter=max_iter) + + quasi = vector_to_quasiprobs(out, M.sorted_counts) + if details: + return quasi, M.get_col_norms(), gamma + return quasi, gamma + + def readout_fidelity(self, qubits=None): + """Compute readout fidelity for calibrated qubits. + + Parameters: + qubits (array_like): Qubits to compute over, default is all. + + Returns: + list: List of qubit fidelities. + + Raises: + M3Error: Mitigator is not calibrated. + M3Error: Qubit indices out of range. + """ + if self.single_qubit_cals is None: + raise M3Error('Mitigator is not calibrated') + + if qubits is None: + qubits = range(self.num_qubits) + else: + outliers = [kk for kk in qubits if kk >= self.num_qubits] + if any(outliers): + raise M3Error('One or more qubit indices out of range: {}'.format(outliers)) + fids = [] + for kk in qubits: + qubit = self.single_qubit_cals[kk] + if qubit is not None: + fids.append(np.mean(qubit.diagonal())) + else: + fids.append(None) + return fids diff --git a/mthree/norms.py b/mthree/norms.py new file mode 100644 index 00000000..3c59f5b5 --- /dev/null +++ b/mthree/norms.py @@ -0,0 +1,179 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module +"""mthree one-norm estimators""" + +import numpy as np +import scipy.linalg as la +import scipy.sparse.linalg as spla +from mthree.exceptions import M3Error + + +def ainv_onenorm_est_lu(A, LU=None): + """ + Estimates the one-norm of the inverse A**-1 of the input + matrix A using direct LU factorization. + + Parameters: + A (ndarray): Input square matrix. + LU (ndarray): Perfactored LU of A, if any. + + Returns: + float: Estimate of one-norm for A**-1. + + Notes: + This uses the modified Hager's method (Alg. 4.1) from + N. J. Higham, ACM Trans. Math. Software, Vol. 14, 381 (1988). + """ + dims = A.shape[0] + + # Starting vec + v = (1.0/dims)*np.ones(dims, dtype=float) + + # Factor A and A.T + if LU is None: + LU = la.lu_factor(A, check_finite=False) + LU_T = la.lu_factor(A.T, check_finite=False) + + # Initial solve + v = la.lu_solve(LU, v, check_finite=False) + gamma = la.norm(v, 1) + eta = np.sign(v) + x = la.lu_solve(LU_T, eta, check_finite=False) + + # loop over reasonable number of trials + k = 2 + while k < 6: + x_nrm = la.norm(x, np.inf) + idx = np.where(np.abs(x) == x_nrm)[0][0] + v = np.zeros(dims, dtype=float) + v[idx] = 1 + v = la.lu_solve(LU, v, check_finite=False) + + gamma_prime = gamma + gamma = la.norm(v, 1) + + if gamma <= gamma_prime or np.allclose(np.sign(v), eta): + break + + eta = np.sign(v) + x = la.lu_solve(LU_T, eta, check_finite=False) + if la.norm(x, np.inf) == x[idx]: + break + k += 1 + + # After loop do Higham's check for cancellations. + x = np.arange(1, dims+1) + x = (-1)**(x+1)*(1+(x-1)/(dims-1)) + + x = la.lu_solve(LU, x, check_finite=False) + + temp = 2*la.norm(x, 1)/(3*dims) + + if temp > gamma: + gamma = temp + + return gamma + + +def ainv_onenorm_est_iter(M, tol=1e-5, max_iter=25): + """ + Estimates the one-norm of the inverse A**-1 of the input + matrix A using itertive GMRES. + + Parameters: + M (M3MatVec): M3 matrix-vector multiplication container. + tol (float): Tolerance of iterative solver. + max_iter (int): Number of max iterations to perform. + + Returns: + float: Estimate of one-norm for A**-1. + + Notes: + This uses the modified Hager's method (Alg. 4.1) from + N. J. Higham, ACM Trans. Math. Software, Vol. 14, 381 (1988). + + Raises: + M3Error: Error in iterative solver. + """ + # Setup linear operator interfaces + L = spla.LinearOperator((M.num_elems, M.num_elems), + matvec=M.matvec) + + LT = spla.LinearOperator((M.num_elems, M.num_elems), + matvec=M.rmatvec) + + diags = M.get_diagonal() + + def precond_matvec(x): + out = x / diags + return out + + P = spla.LinearOperator((M.num_elems, M.num_elems), precond_matvec) + + dims = M.num_elems + + # Starting vec + v = (1.0/dims)*np.ones(dims, dtype=float) + + # Initial solve + v, error = spla.gmres(L, v, tol=tol, atol=tol, maxiter=max_iter, + M=P) + if error: + raise M3Error('Iterative solver error {}'.format(error)) + gamma = la.norm(v, 1) + eta = np.sign(v) + x, error = spla.gmres(LT, eta, tol=tol, atol=tol, maxiter=max_iter, + M=P) + if error: + raise M3Error('Iterative solver error {}'.format(error)) + # loop over reasonable number of trials + k = 2 + while k < 6: + x_nrm = la.norm(x, np.inf) + idx = np.where(np.abs(x) == x_nrm)[0][0] + v = np.zeros(dims, dtype=float) + v[idx] = 1 + v, error = spla.gmres(L, v, tol=tol, atol=tol, maxiter=max_iter, + M=P) + if error: + raise M3Error('Iterative solver error {}'.format(error)) + gamma_prime = gamma + gamma = la.norm(v, 1) + + if gamma <= gamma_prime or np.allclose(np.sign(v), eta, atol=tol): + break + + eta = np.sign(v) + x, error = spla.gmres(LT, eta, tol=tol, atol=tol, maxiter=max_iter, + M=P) + if error: + raise M3Error('Iterative solver error {}'.format(error)) + if la.norm(x, np.inf) == x[idx]: + break + k += 1 + + # After loop do Higham's check for cancellations. + x = np.arange(1, dims+1) + x = (-1)**(x+1)*(1+(x-1)/(dims-1)) + + x, error = spla.gmres(L, x, tol=tol, atol=tol, maxiter=max_iter, + M=P) + if error: + raise M3Error('Iterative solver error {}'.format(error)) + + temp = 2*la.norm(x, 1)/(3*dims) + + if temp > gamma: + gamma = temp + + return gamma diff --git a/mthree/probability.pyx b/mthree/probability.pyx new file mode 100644 index 00000000..9c8bd8c8 --- /dev/null +++ b/mthree/probability.pyx @@ -0,0 +1,44 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +cimport cython +from libc.math cimport sqrt + +@cython.boundscheck(False) +@cython.cdivision(True) +def quasi_to_probs(object quasiprobs): + """Takes a quasiprobability distribution and maps + it to the closest probability distribution as defined by + the L2-norm. + Parameters: + quasiprobs (QuasiDistribution): Input quasiprobabilities. + Returns: + dict: Nearest probability distribution + float: Distance between distributions + Notes: + Method from Smolin et al., Phys. Rev. Lett. 108, 070502 (2012). + """ + cdef dict sorted_probs = dict(sorted(quasiprobs.items(), key=lambda item: item[1])) + cdef unsigned int num_elems = len(sorted_probs) + cdef dict new_probs = {} + cdef double beta = 0 + cdef object key + cdef double val, temp, diff = 0 + for key, val in sorted_probs.items(): + temp = val+beta/num_elems + if temp < 0: + beta += val + num_elems -= 1 + diff += val*val + else: + diff += (beta/num_elems)*(beta/num_elems) + new_probs[key] = sorted_probs[key] + beta/num_elems + return new_probs, sqrt(diff) diff --git a/mthree/test/__init__.py b/mthree/test/__init__.py new file mode 100644 index 00000000..67cf3852 --- /dev/null +++ b/mthree/test/__init__.py @@ -0,0 +1,11 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. diff --git a/mthree/test/column_testing.pyx b/mthree/test/column_testing.pyx new file mode 100644 index 00000000..3bcd46ac --- /dev/null +++ b/mthree/test/column_testing.pyx @@ -0,0 +1,46 @@ +# This code is part of mthree. +# +# (C) Copyright IBM Quantum 2021. +# +# This code is for internal IBM Quantum use only. +# cython: c_string_type=unicode, c_string_encoding=UTF-8 +cimport cython +import numpy as np +cimport numpy as np +from libc.stdlib cimport malloc, free +from libcpp.map cimport map +from libcpp.string cimport string + +from mthree.compute cimport compute_col_norms +from mthree.converters cimport counts_to_internal + + +def _test_vector_column_norm(object counts, + double[::1] cals, + int distance): + """Test computing the column norm on a full vector + + Parameters: + col (unsigned char memoryview): Bitstring for column + cals (double memoryview): Input calibration data. + distance (int): Distance (weight) of errors to consider. + """ + cdef unsigned int num_bits = len(next(iter(counts))) + cdef double shots = sum(counts.values()) + cdef map[string, double] counts_map = counts + cdef unsigned int num_elems = counts_map.size() + + # Assign memeory for bitstrings and input probabilities + cdef unsigned char * bitstrings = malloc(num_bits*num_elems*sizeof(unsigned char)) + cdef double * input_probs = malloc(num_elems*sizeof(double)) + # Assign memeory for column norms + cdef double[::1] col_norms = np.zeros(num_elems, dtype=float) + + # Convert sorted counts dict into bistrings and input probability arrays + counts_to_internal(&counts_map, bitstrings, input_probs, num_bits, shots) + # Compute column norms + compute_col_norms(&col_norms[0], bitstrings, &cals[0], num_bits, num_elems, distance) + + free(bitstrings) + free(input_probs) + return np.asarray(col_norms) \ No newline at end of file diff --git a/mthree/test/converters_testing.pyx b/mthree/test/converters_testing.pyx new file mode 100644 index 00000000..802ed9df --- /dev/null +++ b/mthree/test/converters_testing.pyx @@ -0,0 +1,71 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# cython: c_string_type=unicode, c_string_encoding=UTF-8 +cimport cython +import numpy as np +from libc.stdlib cimport malloc, free +from libcpp.map cimport map +from libcpp.string cimport string + +from mthree.converters cimport counts_to_internal, internal_to_probs + + +def _test_counts_to_array(object counts): + + cdef double shots = sum(counts.values()) + cdef unsigned int num_bits = len(next(iter(counts))) + cdef map[string, double] counts_map = counts + cdef unsigned int num_elems = counts_map.size() + cdef size_t kk, ll + cdef list out + + # Assign memeory for bitstrings and input probabilities + cdef unsigned char * bitstrings = malloc(num_bits*num_elems*sizeof(unsigned char)) + cdef double * input_probs = malloc(num_elems*sizeof(double)) + + # Convert sorted counts dict into bistrings and input probability arrays + counts_to_internal(&counts_map, bitstrings, input_probs, num_bits, shots) + + out = ['']*num_elems + + for kk in range(num_elems): + for ll in range(num_bits): + out[kk] += str(bitstrings[kk*num_bits+ll]) + + #free data + free(bitstrings) + free(input_probs) + return out + + +def _test_counts_roundtrip(object counts): + + cdef double shots = sum(counts.values()) + cdef unsigned int num_bits = len(next(iter(counts))) + cdef map[string, double] counts_map = counts + cdef unsigned int num_elems = counts_map.size() + cdef size_t kk, ll + + # Assign memeory for bitstrings and input probabilities + cdef unsigned char * bitstrings = malloc(num_bits*num_elems*sizeof(unsigned char)) + cdef double * input_probs = malloc(num_elems*sizeof(double)) + + # Convert sorted counts dict into bistrings and input probability arrays + counts_to_internal(&counts_map, bitstrings, input_probs, num_bits, shots) + internal_to_probs(&counts_map, input_probs) + cdef dict out = counts_map + + #free data + free(bitstrings) + free(input_probs) + + return out diff --git a/mthree/test/test_columns.py b/mthree/test/test_columns.py new file mode 100644 index 00000000..de3c2233 --- /dev/null +++ b/mthree/test/test_columns.py @@ -0,0 +1,79 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module + +"""Test the converters""" +import numpy as np +from mthree.hamming import hamming_ball +from .column_testing import _test_vector_column_norm + + +mats = [np.array([[0.9954, 0.0682], + [0.0046, 0.9318]]), + np.array([[0.9494, 0.1236], + [0.0506, 0.8764]]), + np.array([[0.9778, 0.04], + [0.0222, 0.96]]), + np.array([[0.9718, 0.0726], + [0.0282, 0.9274]]), + np.array([[0.9832, 0.0568], + [0.0168, 0.9432]])] + +cals = np.array([0.9832, 0.0568, 0.0168, 0.9432, 0.9718, 0.0726, 0.0282, 0.9274, + 0.9778, 0.04, 0.0222, 0.96, 0.9494, 0.1236, 0.0506, 0.8764, + 0.9954, 0.0682, 0.0046, 0.9318]) + +FULL_MAT = np.kron(mats[1], mats[0]) +for ll in range(2, len(mats)): + FULL_MAT = np.kron(mats[ll], FULL_MAT) + + +def test_vector_colnorm_d0(): + """Distance 0 vector col_norm gives diagonal elements""" + + counts = {} + for kk in range(32): + counts[bin(kk)[2:].zfill(5)] = 1/32 + + out = _test_vector_column_norm(counts, cals, 0) + + for kk in range(32): + assert abs(out[kk] - FULL_MAT[kk, kk]) < 1e-15 + + +def test_vector_colnorm_d3(): + """Distance 3 vector col_norm verification""" + + counts = {} + for kk in range(32): + counts[bin(kk)[2:].zfill(5)] = 1/32 + + out = _test_vector_column_norm(counts, cals, 3) + + for kk in range(32): + arr = np.fromiter(bin(kk)[2:].zfill(5), np.uint8) + elems = hamming_ball(arr, 0, 3) + rows = np.asarray([np.sum(bits*2**np.arange(5)[::-1]) for bits in elems]) + assert abs(out[kk] - np.sum(FULL_MAT[rows, kk])) < 1e-15 + + +def test_vector_colnorm_d5(): + """Distance 5 vector col_norm gives unit norm for 5Q matrix""" + + counts = {} + for kk in range(32): + counts[bin(kk)[2:].zfill(5)] = 1/32 + + out = _test_vector_column_norm(counts, cals, 5) + + for kk in range(32): + assert abs(out[kk] - 1) < 1e-15 diff --git a/mthree/test/test_converters.py b/mthree/test/test_converters.py new file mode 100644 index 00000000..be9997fa --- /dev/null +++ b/mthree/test/test_converters.py @@ -0,0 +1,63 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module + +"""Test the converters""" +from mthree.matrix import bitstring_int +from .converters_testing import _test_counts_roundtrip, _test_counts_to_array + +COUNTS = {'00000': 520, + '00001': 10, + '10000': 21, + '10011': 1, + '10100': 3, + '10101': 4, + '10110': 2, + '10111': 23, + '11000': 3, + '11001': 4, + '11010': 1, + '11011': 17, + '11100': 8, + '11101': 64, + '11110': 36, + '11111': 374, + '00010': 33, + '00011': 4, + '00100': 4, + '00101': 2, + '00111': 5, + '01000': 11, + '01010': 2, + '01011': 1, + '01101': 4, + '01110': 4, + '01111': 31} + + +def test_counts_converted_properly(): + """Tests counts strings are converted properly""" + # The counts need to be sorted by int value as that is what + # the cpp_map is doing internally. + sorted_counts = dict(sorted(COUNTS.items(), + key=lambda item: bitstring_int(item[0]))) + ans_list = list(sorted_counts.keys()) + out_list = _test_counts_to_array(COUNTS) + assert ans_list == out_list + + +def test_roundtrip_convert(): + """Tests converts work roundtrip""" + shots = sum(COUNTS.values()) + out = _test_counts_roundtrip(COUNTS) + for key, val in COUNTS.items(): + assert abs(val/shots - out[key]) <= 1e-15 diff --git a/mthree/test/test_extra_cals.py b/mthree/test/test_extra_cals.py new file mode 100644 index 00000000..3a408cc9 --- /dev/null +++ b/mthree/test/test_extra_cals.py @@ -0,0 +1,87 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module + +"""Test is various methods agree""" + +import numpy as np +import orjson +from qiskit import QuantumCircuit, execute +from qiskit.test.mock import FakeAthens + +import mthree + + +def test_missing_qubit_cal(): + """Test if missing calibration is retrived at apply_correcton.""" + + qc = QuantumCircuit(5) + qc.h(2) + qc.cx(2, 1) + qc.cx(1, 0) + qc.cx(2, 3) + qc.cx(3, 4) + qc.measure_all() + + backend = FakeAthens() + raw_counts = execute(qc, backend, shots=2048).result().get_counts() + + mit = mthree.M3Mitigation(backend) + mit.cals_from_system(range(4)) + + assert mit.single_qubit_cals[4] is None + + _ = mit.apply_correction(raw_counts, range(5)) + + assert not any(mit.single_qubit_cals[kk] is None for kk in range(5)) + + +def test_missing_all_cals(): + """Test if calibrations get added if none set before.""" + + qc = QuantumCircuit(5) + qc.h(2) + qc.cx(2, 1) + qc.cx(1, 0) + qc.cx(2, 3) + qc.cx(3, 4) + qc.measure_all() + + backend = FakeAthens() + raw_counts = execute(qc, backend, shots=2048).result().get_counts() + + mit = mthree.M3Mitigation(backend) + _ = mit.apply_correction(raw_counts, range(5)) + + assert not any(mit.single_qubit_cals[kk] is None for kk in range(5)) + + +def test_save_cals(tmp_path): + """Test if passing a calibration file saves the correct JSON.""" + backend = FakeAthens() + cal_file = tmp_path / "cal.json" + mit = mthree.M3Mitigation(backend) + mit.cals_from_system(counts_file=cal_file) + with open(cal_file, 'r') as fd: + cals = np.array(orjson.loads(fd.read())) + assert np.array_equal(mit.single_qubit_cals, cals) + + +def test_load_cals(tmp_path): + """Test if loading a calibration JSON file correctly loads the cals.""" + cal_file = tmp_path / "cal.json" + backend = FakeAthens() + mit = mthree.M3Mitigation(backend) + mit.cals_from_system(counts_file=cal_file) + new_mit = mthree.M3Mitigation(backend) + new_mit.cals_from_file(cal_file) + assert np.array_equal(mit.single_qubit_cals, new_mit.single_qubit_cals) diff --git a/mthree/test/test_full.py b/mthree/test/test_full.py new file mode 100644 index 00000000..991859e3 --- /dev/null +++ b/mthree/test/test_full.py @@ -0,0 +1,373 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module + +"""Test matrix elements""" +import numpy as np +import scipy.linalg as la + +from mthree import M3Mitigation +from mthree.matrix import bitstring_int + + +def test_full_problem(): + """Tests if matrix elements can be computed properly from the data""" + + # Compute using M3 + qubits = [1, 4, 7, 10, 12, 2, 3, 5] + mit = M3Mitigation(None) + mit.single_qubit_cals = CALS + mit_counts = mit.apply_correction(COUNTS, qubits, tol=1e-10, method='iterative') + + # Compute using LU solver + sorted_counts = dict(sorted(COUNTS.items(), key=lambda item: bitstring_int(item[0]))) + vec = counts_to_vector(sorted_counts) + + A = np.kron(mit.single_qubit_cals[qubits[1]], mit.single_qubit_cals[qubits[0]]) + for kk in range(2, len(qubits)): + A = np.kron(mit.single_qubit_cals[qubits[kk]], A) + + x = la.solve(A, vec) + lu_counts = vector_to_probs(x, sorted_counts) + + for key, val in lu_counts.items(): + assert abs(val - mit_counts[key]) < 1e-9 + + +def counts_to_vector(counts): + """ Return probability vector from counts dict. + + Parameters: + counts (dict): Input dict of counts. + + Returns: + ndarray: 1D array of probabilities. + """ + shots = sum(counts.values()) + vec = np.zeros(len(counts), dtype=float) + idx = 0 + for val in counts.values(): + vec[idx] = val / shots + idx += 1 + return vec + + +def vector_to_probs(vec, counts): + """ Return dict of probabilities. + + Parameters: + vec (ndarray): 1d vector of probabilites. + counts (dict): Dict of counts + + Returns: + dict: dict of probabilities + """ + out_counts = {} + idx = 0 + for key in counts: + out_counts[key] = vec[idx] + idx += 1 + return out_counts + + +COUNTS = {'00000000': 70, + '00000001': 33, + '00010000': 34, + '00000010': 30, + '00100000': 36, + '00000100': 20, + '01000000': 28, + '00001000': 31, + '10000000': 30, + '00010001': 34, + '00010010': 45, + '00010100': 56, + '00011000': 75, + '00100001': 50, + '00100010': 48, + '00100100': 30, + '00101000': 28, + '00000011': 46, + '00110000': 42, + '01000001': 59, + '01000010': 54, + '01000100': 42, + '01001000': 42, + '00000101': 30, + '01010000': 43, + '00000110': 47, + '01100000': 60, + '10000001': 48, + '10000010': 57, + '10000100': 30, + '10001000': 38, + '00001001': 33, + '10010000': 38, + '00001010': 33, + '10100000': 37, + '00001100': 36, + '11000000': 58, + '00010011': 22, + '00010101': 37, + '00010110': 35, + '00011001': 50, + '00011010': 38, + '00011100': 21, + '00100011': 37, + '00100101': 25, + '00100110': 34, + '00101001': 23, + '00101010': 38, + '00101100': 21, + '00110001': 34, + '00110010': 17, + '00110100': 23, + '00111000': 41, + '01000011': 28, + '01000101': 21, + '01000110': 23, + '01001001': 19, + '01001010': 13, + '01001100': 25, + '01010001': 29, + '01010010': 33, + '01010100': 26, + '01011000': 36, + '01100001': 40, + '01100010': 38, + '01100100': 37, + '01101000': 36, + '00000111': 26, + '01110000': 30, + '10000011': 24, + '10000101': 20, + '10000110': 20, + '10001001': 22, + '10001010': 18, + '10001100': 24, + '10010001': 23, + '10010010': 15, + '10010100': 17, + '10011000': 21, + '10100001': 32, + '10100010': 34, + '10100100': 23, + '10101000': 16, + '00001011': 23, + '10110000': 19, + '11000001': 24, + '11000010': 23, + '11000100': 30, + '11001000': 23, + '00001101': 31, + '11010000': 21, + '00001110': 30, + '11100000': 28, + '00010111': 47, + '00011011': 43, + '00011101': 53, + '00011110': 37, + '00100111': 40, + '00101011': 48, + '00101101': 39, + '00101110': 32, + '00110011': 32, + '00110101': 51, + '00110110': 44, + '00111001': 66, + '00111010': 49, + '00111100': 40, + '01000111': 47, + '01001011': 31, + '01001101': 33, + '01001110': 40, + '01010011': 38, + '01010101': 47, + '01010110': 40, + '01011001': 56, + '01011010': 38, + '01011100': 47, + '01100011': 45, + '01100101': 38, + '01100110': 31, + '01101001': 32, + '01101010': 38, + '01101100': 36, + '01110001': 35, + '01110010': 28, + '01110100': 49, + '01111000': 50, + '10000111': 36, + '10001011': 38, + '10001101': 37, + '10001110': 33, + '10010011': 25, + '10010101': 34, + '10010110': 35, + '10011001': 52, + '10011010': 41, + '10011100': 34, + '10100011': 45, + '10100101': 25, + '10100110': 34, + '10101001': 26, + '10101010': 19, + '10101100': 39, + '10110001': 21, + '10110010': 25, + '10110100': 31, + '10111000': 45, + '11000011': 41, + '11000101': 26, + '11000110': 39, + '11001001': 31, + '11001010': 29, + '11001100': 36, + '11010001': 25, + '11010010': 36, + '11010100': 39, + '11011000': 47, + '11100001': 53, + '11100010': 39, + '11100100': 35, + '11101000': 28, + '00001111': 45, + '11110000': 23, + '00011111': 36, + '00101111': 26, + '00110111': 26, + '00111011': 37, + '00111101': 23, + '00111110': 29, + '01001111': 16, + '01010111': 26, + '01011011': 31, + '01011101': 17, + '01011110': 23, + '01100111': 25, + '01101011': 25, + '01101101': 32, + '01101110': 26, + '01110011': 30, + '01110101': 26, + '01110110': 28, + '01111001': 30, + '01111010': 30, + '01111100': 31, + '10001111': 23, + '10010111': 22, + '10011011': 24, + '10011101': 21, + '10011110': 19, + '10100111': 18, + '10101011': 12, + '10101101': 14, + '10101110': 18, + '10110011': 26, + '10110101': 17, + '10110110': 20, + '10111001': 28, + '10111010': 19, + '10111100': 19, + '11000111': 16, + '11001011': 13, + '11001101': 20, + '11001110': 28, + '11010011': 14, + '11010101': 24, + '11010110': 24, + '11011001': 33, + '11011010': 28, + '11011100': 18, + '11100011': 36, + '11100101': 15, + '11100110': 15, + '11101001': 24, + '11101010': 26, + '11101100': 20, + '11110001': 28, + '11110010': 25, + '11110100': 27, + '11111000': 24, + '00111111': 40, + '01011111': 38, + '01101111': 30, + '01110111': 30, + '01111011': 50, + '01111101': 35, + '01111110': 32, + '10011111': 26, + '10101111': 27, + '10110111': 33, + '10111011': 46, + '10111101': 32, + '10111110': 29, + '11001111': 31, + '11010111': 35, + '11011011': 43, + '11011101': 36, + '11011110': 35, + '11100111': 30, + '11101011': 23, + '11101101': 38, + '11101110': 37, + '11110011': 30, + '11110101': 30, + '11110110': 38, + '11111001': 36, + '11111010': 44, + '11111100': 24, + '01111111': 27, + '10111111': 15, + '11011111': 17, + '11101111': 16, + '11110111': 24, + '11111011': 23, + '11111101': 17, + '11111110': 10, + '11111111': 19} + +CALS = [None, + np.array([[0.98299193, 0.01979335], + [0.01700807, 0.98020665]]), + np.array([[0.96917076, 0.03369085], + [0.03082924, 0.96630915]]), + np.array([[0.9858876, 0.02348826], + [0.0141124, 0.97651174]]), + np.array([[0.99496994, 0.02733885], + [0.00503006, 0.97266115]]), + np.array([[0.96395599, 0.18330204], + [0.03604401, 0.81669796]]), + None, + np.array([[0.98876682, 0.03722461], + [0.01123318, 0.96277539]]), + None, + None, + np.array([[0.99187792, 0.06334372], + [0.00812208, 0.93665628]]), + None, + np.array([[0.94568855, 0.07140989], + [0.05431145, 0.92859011]]), + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None] diff --git a/mthree/test/test_matvec.py b/mthree/test/test_matvec.py new file mode 100644 index 00000000..44efda42 --- /dev/null +++ b/mthree/test/test_matvec.py @@ -0,0 +1,57 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module +"""Test matrix elements""" +import numpy as np +import scipy.sparse.linalg as spla +from qiskit import QuantumCircuit, execute +from qiskit.test.mock import FakeAthens +import mthree +from mthree.matvec import M3MatVec + + +def test_matvec(): + """Check that matvec and rmatvec values are returned as expected""" + backend = FakeAthens() + + qc = QuantumCircuit(5) + qc.h(2) + qc.cx(2, 1) + qc.cx(2, 3) + qc.cx(1, 0) + qc.cx(3, 4) + qc.measure_all() + + raw_counts = execute(qc, backend).result().get_counts() + mit = mthree.M3Mitigation(backend) + mit.cals_from_system(range(5)) + + cals = mit._form_cals(range(5)) + M = M3MatVec(dict(raw_counts), cals, 5) + L = spla.LinearOperator((M.num_elems, M.num_elems), + matvec=M.matvec) + + LT = spla.LinearOperator((M.num_elems, M.num_elems), + matvec=M.rmatvec) + + A = mit.reduced_cal_matrix(raw_counts, range(5))[0] + vec = (-1)**np.arange(M.num_elems)*np.ones(M.num_elems, dtype=float) / M.num_elems + + v1 = L.dot(vec) + v2 = A.dot(vec) + + assert np.allclose(v1, v2, atol=1e-14) + + v3 = LT.dot(vec) + v4 = (A.T).dot(vec) + + assert np.allclose(v3, v4, atol=1e-14) diff --git a/mthree/test/test_methods.py b/mthree/test/test_methods.py new file mode 100644 index 00000000..4e392f08 --- /dev/null +++ b/mthree/test/test_methods.py @@ -0,0 +1,69 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module + +"""Test is various methods agree""" + +import numpy as np +from qiskit import QuantumCircuit, execute +from qiskit.test.mock import FakeAthens +import mthree + + +def test_methods_equality(): + """Make sure direct and iterative solvers agree with each other.""" + qc = QuantumCircuit(5) + qc.h(2) + qc.cx(2, 1) + qc.cx(1, 0) + qc.cx(2, 3) + qc.cx(3, 4) + qc.measure_all() + + backend = FakeAthens() + raw_counts = execute(qc, backend, shots=2048).result().get_counts() + + mit = mthree.M3Mitigation(backend) + mit.cals_from_system() + + iter_q = mit.apply_correction(raw_counts, range(5), method='iterative') + direct_q = mit.apply_correction(raw_counts, range(5), method='direct') + + for key, val in direct_q.items(): + assert key in iter_q.keys() + assert np.abs(val-iter_q[key]) < 1e-5 + + +def test_set_iterative(): + """Make sure can overload auto setting""" + qc = QuantumCircuit(5) + qc.h(2) + qc.cx(2, 1) + qc.cx(1, 0) + qc.cx(2, 3) + qc.cx(3, 4) + qc.measure_all() + + backend = FakeAthens() + raw_counts = execute(qc, backend, shots=4096).result().get_counts() + + mit = mthree.M3Mitigation(backend) + mit.cals_from_system(shots=4096) + + _, details = mit.apply_correction(raw_counts, range(5), + method='iterative', + details=True) + assert details['method'] == 'iterative' + + _, details = mit.apply_correction(raw_counts, range(5), + details=True) + assert details['method'] == 'direct' diff --git a/mthree/test/test_probability.py b/mthree/test/test_probability.py new file mode 100644 index 00000000..a7c70c78 --- /dev/null +++ b/mthree/test/test_probability.py @@ -0,0 +1,29 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module + +"""Test conversion to probability distribution""" +import numpy as np +from mthree.classes import QuasiDistribution + + +def test_known_conversion(): + """Reproduce conversion from Smolin PRL""" + qprobs = {'0': 3/5, '1': 1/2, '2': 7/20, '3': 1/10, '4': -11/20} + closest, dist = QuasiDistribution(qprobs).nearest_probability_distribution( + return_distance=True) + ans = {'0': 9/20, '1': 7/20, '2': 1/5} + + for key, val in closest.items(): + assert abs(ans[key] - val) < 1e-14 + + assert abs(dist-np.sqrt(0.38)) < 1e-14 diff --git a/mthree/test/test_quasi_attr.py b/mthree/test/test_quasi_attr.py new file mode 100644 index 00000000..612b3dfa --- /dev/null +++ b/mthree/test/test_quasi_attr.py @@ -0,0 +1,59 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module +"""Test matrix elements""" +from qiskit import QuantumCircuit, execute +from qiskit.test.mock import FakeMontreal +import mthree + + +def test_quasi_attr_set(): + """Test quasi-probs attributes are set""" + backend = FakeMontreal() + + N = 6 + qc = QuantumCircuit(N) + qc.x(range(0, N)) + qc.h(range(0, N)) + for kk in range(N//2, 0, -1): + qc.ch(kk, kk-1) + for kk in range(N//2, N-1): + qc.ch(kk, kk+1) + qc.measure_all() + + qubits = [1, 4, 7, 10, 12, 13] + + mit = mthree.M3Mitigation(backend) + mit.cals_from_system(qubits) + + raw_counts = execute(qc, backend, shots=1024, + initial_layout=qubits).result().get_counts() + quasi1 = mit.apply_correction(raw_counts, qubits, + return_mitigation_overhead=True, method='direct') + quasi2 = mit.apply_correction(raw_counts, qubits, + return_mitigation_overhead=True, method='iterative') + + quasi3 = mit.apply_correction(raw_counts, qubits, + return_mitigation_overhead=False, method='direct') + quasi4 = mit.apply_correction(raw_counts, qubits, + return_mitigation_overhead=False, method='iterative') + + shots = 1024 + assert quasi1.shots == shots + assert quasi2.shots == shots + assert quasi3.shots == shots + assert quasi4.shots == shots + + assert quasi1.mitigation_overhead is not None + assert quasi2.mitigation_overhead is not None + assert quasi3.mitigation_overhead is None + assert quasi4.mitigation_overhead is None diff --git a/mthree/test/test_reduced_matrix.py b/mthree/test/test_reduced_matrix.py new file mode 100644 index 00000000..1aa0afaa --- /dev/null +++ b/mthree/test/test_reduced_matrix.py @@ -0,0 +1,364 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module + +"""Test matrix elements""" +import numpy as np + +from mthree import M3Mitigation + + +def test_reduced_matrix(): + """Tests if matrix elements can be computed properly from the data""" + + # Compute using M3 + qubits = [1, 4, 7, 10, 12, 2, 3, 5] + mit = M3Mitigation(None) + mit.single_qubit_cals = CALS + M = mit.reduced_cal_matrix(COUNTS, qubits)[0] + # Compute using LU solver + A = np.kron(mit.single_qubit_cals[qubits[1]], mit.single_qubit_cals[qubits[0]]) + for kk in range(2, len(qubits)): + A = np.kron(mit.single_qubit_cals[qubits[kk]], A) + + assert np.linalg.norm(A-M, np.inf) < 1e-14 + + +def counts_to_vector(counts): + """ Return probability vector from counts dict. + + Parameters: + counts (dict): Input dict of counts. + + Returns: + ndarray: 1D array of probabilities. + """ + shots = sum(counts.values()) + num_bits = len(next(iter(counts))) + vec = np.zeros(2**num_bits, dtype=float) + idx = 0 + for val in counts.values(): + vec[idx] = val / shots + idx += 1 + return vec + + +def vector_to_probs(vec, counts): + """ Return dict of probabilities. + + Parameters: + vec (ndarray): 1d vector of probabilites. + counts (dict): Dict of counts + + Returns: + dict: dict of probabilities + """ + out_counts = {} + idx = 0 + for key in counts: + out_counts[key] = vec[idx] + idx += 1 + return out_counts + + +COUNTS = {'00000000': 70, + '00000001': 33, + '00010000': 34, + '00000010': 30, + '00100000': 36, + '00000100': 20, + '01000000': 28, + '00001000': 31, + '10000000': 30, + '00010001': 34, + '00010010': 45, + '00010100': 56, + '00011000': 75, + '00100001': 50, + '00100010': 48, + '00100100': 30, + '00101000': 28, + '00000011': 46, + '00110000': 42, + '01000001': 59, + '01000010': 54, + '01000100': 42, + '01001000': 42, + '00000101': 30, + '01010000': 43, + '00000110': 47, + '01100000': 60, + '10000001': 48, + '10000010': 57, + '10000100': 30, + '10001000': 38, + '00001001': 33, + '10010000': 38, + '00001010': 33, + '10100000': 37, + '00001100': 36, + '11000000': 58, + '00010011': 22, + '00010101': 37, + '00010110': 35, + '00011001': 50, + '00011010': 38, + '00011100': 21, + '00100011': 37, + '00100101': 25, + '00100110': 34, + '00101001': 23, + '00101010': 38, + '00101100': 21, + '00110001': 34, + '00110010': 17, + '00110100': 23, + '00111000': 41, + '01000011': 28, + '01000101': 21, + '01000110': 23, + '01001001': 19, + '01001010': 13, + '01001100': 25, + '01010001': 29, + '01010010': 33, + '01010100': 26, + '01011000': 36, + '01100001': 40, + '01100010': 38, + '01100100': 37, + '01101000': 36, + '00000111': 26, + '01110000': 30, + '10000011': 24, + '10000101': 20, + '10000110': 20, + '10001001': 22, + '10001010': 18, + '10001100': 24, + '10010001': 23, + '10010010': 15, + '10010100': 17, + '10011000': 21, + '10100001': 32, + '10100010': 34, + '10100100': 23, + '10101000': 16, + '00001011': 23, + '10110000': 19, + '11000001': 24, + '11000010': 23, + '11000100': 30, + '11001000': 23, + '00001101': 31, + '11010000': 21, + '00001110': 30, + '11100000': 28, + '00010111': 47, + '00011011': 43, + '00011101': 53, + '00011110': 37, + '00100111': 40, + '00101011': 48, + '00101101': 39, + '00101110': 32, + '00110011': 32, + '00110101': 51, + '00110110': 44, + '00111001': 66, + '00111010': 49, + '00111100': 40, + '01000111': 47, + '01001011': 31, + '01001101': 33, + '01001110': 40, + '01010011': 38, + '01010101': 47, + '01010110': 40, + '01011001': 56, + '01011010': 38, + '01011100': 47, + '01100011': 45, + '01100101': 38, + '01100110': 31, + '01101001': 32, + '01101010': 38, + '01101100': 36, + '01110001': 35, + '01110010': 28, + '01110100': 49, + '01111000': 50, + '10000111': 36, + '10001011': 38, + '10001101': 37, + '10001110': 33, + '10010011': 25, + '10010101': 34, + '10010110': 35, + '10011001': 52, + '10011010': 41, + '10011100': 34, + '10100011': 45, + '10100101': 25, + '10100110': 34, + '10101001': 26, + '10101010': 19, + '10101100': 39, + '10110001': 21, + '10110010': 25, + '10110100': 31, + '10111000': 45, + '11000011': 41, + '11000101': 26, + '11000110': 39, + '11001001': 31, + '11001010': 29, + '11001100': 36, + '11010001': 25, + '11010010': 36, + '11010100': 39, + '11011000': 47, + '11100001': 53, + '11100010': 39, + '11100100': 35, + '11101000': 28, + '00001111': 45, + '11110000': 23, + '00011111': 36, + '00101111': 26, + '00110111': 26, + '00111011': 37, + '00111101': 23, + '00111110': 29, + '01001111': 16, + '01010111': 26, + '01011011': 31, + '01011101': 17, + '01011110': 23, + '01100111': 25, + '01101011': 25, + '01101101': 32, + '01101110': 26, + '01110011': 30, + '01110101': 26, + '01110110': 28, + '01111001': 30, + '01111010': 30, + '01111100': 31, + '10001111': 23, + '10010111': 22, + '10011011': 24, + '10011101': 21, + '10011110': 19, + '10100111': 18, + '10101011': 12, + '10101101': 14, + '10101110': 18, + '10110011': 26, + '10110101': 17, + '10110110': 20, + '10111001': 28, + '10111010': 19, + '10111100': 19, + '11000111': 16, + '11001011': 13, + '11001101': 20, + '11001110': 28, + '11010011': 14, + '11010101': 24, + '11010110': 24, + '11011001': 33, + '11011010': 28, + '11011100': 18, + '11100011': 36, + '11100101': 15, + '11100110': 15, + '11101001': 24, + '11101010': 26, + '11101100': 20, + '11110001': 28, + '11110010': 25, + '11110100': 27, + '11111000': 24, + '00111111': 40, + '01011111': 38, + '01101111': 30, + '01110111': 30, + '01111011': 50, + '01111101': 35, + '01111110': 32, + '10011111': 26, + '10101111': 27, + '10110111': 33, + '10111011': 46, + '10111101': 32, + '10111110': 29, + '11001111': 31, + '11010111': 35, + '11011011': 43, + '11011101': 36, + '11011110': 35, + '11100111': 30, + '11101011': 23, + '11101101': 38, + '11101110': 37, + '11110011': 30, + '11110101': 30, + '11110110': 38, + '11111001': 36, + '11111010': 44, + '11111100': 24, + '01111111': 27, + '10111111': 15, + '11011111': 17, + '11101111': 16, + '11110111': 24, + '11111011': 23, + '11111101': 17, + '11111110': 10, + '11111111': 19} + +CALS = [None, + np.array([[0.98299193, 0.01979335], + [0.01700807, 0.98020665]]), + np.array([[0.96917076, 0.03369085], + [0.03082924, 0.96630915]]), + np.array([[0.9858876, 0.02348826], + [0.0141124, 0.97651174]]), + np.array([[0.99496994, 0.02733885], + [0.00503006, 0.97266115]]), + np.array([[0.96395599, 0.18330204], + [0.03604401, 0.81669796]]), + None, + np.array([[0.98876682, 0.03722461], + [0.01123318, 0.96277539]]), + None, + None, + np.array([[0.99187792, 0.06334372], + [0.00812208, 0.93665628]]), + None, + np.array([[0.94568855, 0.07140989], + [0.05431145, 0.92859011]]), + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None] diff --git a/mthree/test/test_sdd.py b/mthree/test/test_sdd.py new file mode 100644 index 00000000..1ad2b6d8 --- /dev/null +++ b/mthree/test/test_sdd.py @@ -0,0 +1,91 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module + +"""Test is various methods agree""" + +import numpy as np +import mthree + + +def test_bad_A_matrix_sdd(): + """Test a bad A-matrix for SDD""" + + mit = mthree.M3Mitigation(None) + mit.single_qubit_cals = BAD_CALS + is_sdd = mit._check_sdd(COUNTS, range(5)) + assert not is_sdd + + +def test_goood_A_matrix_sdd(): + """Test a bad A-matrix for SDD""" + + mit = mthree.M3Mitigation(None) + mit.single_qubit_cals = GOOD_CALS + is_sdd = mit._check_sdd(COUNTS, range(5)) + assert is_sdd + + +BAD_CALS = [np.array([[0.99, 0.08288574], + [0.01, 0.91711426]]), + np.array([[0.91967773, 0.14404297], + [0.08032227, 0.85595703]]), + np.array([[0.9, 0.13195801], + [0.1, 0.86804199]]), + np.array([[0.85, 0.0703125], + [0.15, 0.9296875]]), + np.array([[0.9, 0.23425293], + [0.1, 0.76574707]])] + +GOOD_CALS = [np.array([[1, 0.05419922], + [0, 0.94580078]]), + np.array([[0.95532227, 0.06750488], + [0.04467773, 0.93249512]]), + np.array([[0.99047852, 0.03967285], + [0.00952148, 0.96032715]]), + np.array([[0.96643066, 0.09606934], + [0.03356934, 0.90393066]]), + np.array([[0.99255371, 0.06066895], + [0.00744629, 0.93933105]])] + +COUNTS = {'00000': 3591, + '00001': 7, + '10000': 77, + '10001': 2, + '10010': 2, + '10011': 14, + '10100': 5, + '10101': 22, + '10110': 29, + '10111': 305, + '11000': 17, + '11001': 10, + '11010': 8, + '11011': 128, + '11100': 69, + '11101': 196, + '11110': 199, + '11111': 2734, + '00010': 153, + '00011': 40, + '00100': 46, + '00101': 6, + '00110': 6, + '00111': 72, + '01000': 152, + '01001': 1, + '01010': 14, + '01011': 12, + '01100': 5, + '01101': 22, + '01110': 8, + '01111': 240} diff --git a/mthree/test/test_sim.py b/mthree/test/test_sim.py new file mode 100644 index 00000000..5bbb9dee --- /dev/null +++ b/mthree/test/test_sim.py @@ -0,0 +1,37 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module + +"""Test matrix elements""" +from qiskit import QuantumCircuit, execute +from qiskit.test.mock import FakeAthens +import mthree + + +def test_athens_sim(): + """A simple check that the full pipeline does not break""" + backend = FakeAthens() + + qc = QuantumCircuit(5) + qc.h(2) + qc.cx(2, 1) + qc.cx(2, 3) + qc.cx(1, 0) + qc.cx(3, 4) + qc.measure_all() + + raw_counts = execute(qc, backend).result().get_counts() + mit = mthree.M3Mitigation(backend) + mit.cals_from_system() + mit_counts = mit.apply_correction(raw_counts, qubits=range(5)) + + assert mit_counts is not None diff --git a/mthree/utils.py b/mthree/utils.py new file mode 100644 index 00000000..26e952bf --- /dev/null +++ b/mthree/utils.py @@ -0,0 +1,52 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +# pylint: disable=no-name-in-module +"""Utility functions""" +import numpy as np +from mthree.classes import QuasiDistribution + + +def counts_to_vector(counts): + """ Return probability vector from counts dict. + + Parameters: + counts (dict): Input dict of counts. + + Returns: + ndarray: 1D array of probabilities. + """ + num_bitstrings = len(counts) + shots = sum(counts.values()) + vec = np.zeros(num_bitstrings, dtype=float) + idx = 0 + for val in counts.values(): + vec[idx] = val / shots + idx += 1 + return vec + + +def vector_to_quasiprobs(vec, counts): + """ Return dict of quasi-probabilities. + + Parameters: + vec (ndarray): 1d vector of quasi-probabilites. + counts (dict): Dict of counts + + Returns: + QuasiDistribution: dict of quasi-probabilities + """ + out_counts = {} + idx = 0 + for key in counts: + out_counts[key] = vec[idx] + idx += 1 + return QuasiDistribution(out_counts) diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 00000000..514df4b9 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,10 @@ +scipy>=1.3 +qiskit>=0.24 +pytest +pylint +pycodestyle +Sphinx==3.3 +qiskit_sphinx_theme +jupyter-sphinx +nbsphinx +psutil \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..52494518 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +numpy>=1.17 +scipy>=1.3 +cython>=0.29 +qiskit==0.24.1 +psutil +orjson>=3.5 diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..84d0d30f --- /dev/null +++ b/setup.py @@ -0,0 +1,226 @@ +# This code is part of Mthree. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +"""mthree + +Matrix-free measurement mitigation +""" + +import os +import sys +import subprocess +import setuptools + +try: + import numpy as np +except ImportError: + subprocess.call([sys.executable, '-m', 'pip', 'install', 'numpy>=1.17']) + import numpy as np +try: + from Cython.Build import cythonize +except ImportError: + subprocess.call([sys.executable, '-m', 'pip', 'install', 'cython>=0.29']) + from Cython.Build import cythonize + + +MAJOR = 0 +MINOR = 9 +MICRO = 0 + +ISRELEASED = False +VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO) + +REQUIREMENTS = ['numpy>=1.17', + 'scipy>=1.3', + 'cython>=0.29', + 'qiskit-terra>=0.16', + 'qiskit-ibmq-provider>=0.11', + 'psutil' + ] + +PACKAGES = setuptools.find_packages() +PACKAGE_DATA = {'mthree': ['*.pxd'], +} +DOCLINES = __doc__.split('\n') +DESCRIPTION = DOCLINES[0] +LONG_DESCRIPTION = "\n".join(DOCLINES[2:]) + +CYTHON_EXTS = ['compute', 'converters', 'hamming', 'matrix', 'probability', 'matvec'] + \ + ['expval', 'column_testing', 'converters_testing'] +CYTHON_MODULES = ['mthree']*7 + \ + ['mthree.test']*2 +CYTHON_SOURCE_DIRS = ['mthree']*7 + \ + ['mthree/test']*2 + +# Add openmp flags +OPTIONAL_FLAGS = [] +OPTIONAL_ARGS = [] +for _arg in sys.argv: + if _arg.startswith("--with-"): + _options = _arg.split("--with-")[1].split(",") + sys.argv.remove(_arg) + if "openmp" in _options: + if sys.platform == 'win32': + OPTIONAL_FLAGS = ['/openmp'] + else: + OPTIONAL_FLAGS = ['-fopenmp'] + OPTIONAL_ARGS = OPTIONAL_FLAGS + if "native" in _options: + OPTIONAL_FLAGS.append('-march=native') + +INCLUDE_DIRS = [np.get_include()] +# Extra link args +LINK_FLAGS = [] +# If on Win and not in MSYS2 (i.e. Visual studio compile) +if (sys.platform == 'win32' and os.environ.get('MSYSTEM') is None): + COMPILER_FLAGS = ['/O3'] +# Everything else +else: + COMPILER_FLAGS = ['-O3', '-ffast-math', '-std=c++17'] + if sys.platform == 'darwin': + # These are needed for compiling on OSX 10.14+ + COMPILER_FLAGS.append('-mmacosx-version-min=10.14') + LINK_FLAGS.append('-mmacosx-version-min=10.14') + + +EXT_MODULES = [] +# Add Cython Extensions +for idx, ext in enumerate(CYTHON_EXTS): + mod = setuptools.Extension(CYTHON_MODULES[idx] + '.' + ext, + sources=[CYTHON_SOURCE_DIRS[idx] + '/' + ext + '.pyx'], + include_dirs=INCLUDE_DIRS, + extra_compile_args=COMPILER_FLAGS+OPTIONAL_FLAGS, + extra_link_args=LINK_FLAGS+OPTIONAL_ARGS, + language='c++', + define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")]) + EXT_MODULES.append(mod) + + +def git_short_hash(): + try: + git_str = "+" + os.popen('git log -1 --format="%h"').read().strip() + except: # pylint: disable=bare-except + git_str = "" + else: + if git_str == '+': #fixes setuptools PEP issues with versioning + git_str = '' + return git_str + +FULLVERSION = VERSION +if not ISRELEASED: + FULLVERSION += '.dev'+str(MICRO)+git_short_hash() + +def write_version_py(filename='mthree/version.py'): + cnt = """\ +# THIS FILE IS GENERATED FROM MTHREE SETUP.PY +# pylint: disable=missing-module-docstring +short_version = '%(version)s' +version = '%(fullversion)s' +release = %(isrelease)s +""" + a = open(filename, 'w') + try: + a.write(cnt % {'version': VERSION, 'fullversion': + FULLVERSION, 'isrelease': str(ISRELEASED)}) + finally: + a.close() + +local_path = os.path.dirname(os.path.abspath(sys.argv[0])) +os.chdir(local_path) +sys.path.insert(0, local_path) +sys.path.insert(0, os.path.join(local_path, 'mthree')) # to retrive _version + +# always rewrite _version +if os.path.exists('mthree/version.py'): + os.remove('mthree/version.py') + +write_version_py() + + +# Add command for running pylint from setup.py +class PylintCommand(setuptools.Command): + """Run Pylint on all mthree Python source files.""" + description = 'Run Pylint on mthree Python source files' + user_options = [ + # The format is (long option, short option, description). + ('pylint-rcfile=', None, 'path to Pylint config file')] + + def initialize_options(self): + """Set default values for options.""" + # Each user option must be listed here with their default value. + self.pylint_rcfile = '' # pylint: disable=attribute-defined-outside-init + + def finalize_options(self): + """Post-process options.""" + if self.pylint_rcfile: + assert os.path.exists(self.pylint_rcfile), ( + 'Pylint config file %s does not exist.' % self.pylint_rcfile) + + def run(self): + """Run command.""" + command = ['pylint'] + if self.pylint_rcfile: + command.append('--rcfile=%s' % self.pylint_rcfile) + command.append(os.getcwd()+"/mthree") + subprocess.run(command, stderr=subprocess.STDOUT, check=False) + + +# Add command for running PEP8 tests from setup.py +class StyleCommand(setuptools.Command): + """Run pep8 from setup.""" + description = 'Run style from setup' + user_options = [ + # The format is (long option, short option, description). + ('abc', None, 'abc')] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + """Run command.""" + command = 'pycodestyle --max-line-length=100 mthree' + subprocess.run(command, shell=True, check=False, stderr=subprocess.STDOUT) + + +setuptools.setup( + name='mthree', + version=VERSION, + packages=PACKAGES, + description=DESCRIPTION, + long_description=LONG_DESCRIPTION, + url="", + author="Paul Nation", + author_email="paul.nation@ibm.com", + license="For internal IBM Quantum use only.", + classifiers=[ + "Environment :: Web Environment", + "License :: Other/Proprietary License", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "Operating System :: Microsoft :: Windows", + "Operating System :: MacOS", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Topic :: Scientific/Engineering", + ], + cmdclass={'lint': PylintCommand, 'style': StyleCommand}, + install_requires=REQUIREMENTS, + package_data=PACKAGE_DATA, + ext_modules=cythonize(EXT_MODULES, language_level=3), + include_package_data=True, + zip_safe=False +)