diff --git a/.github/workflows/containers.yml b/.github/workflows/containers.yml
index 90302994d..9b5906ea4 100644
--- a/.github/workflows/containers.yml
+++ b/.github/workflows/containers.yml
@@ -38,7 +38,7 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max
context: frontend/
- file: frontend/docker/production/react/Dockerfile
+ file: frontend/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.metadata.outputs.tags }}
labels: ${{ steps.metadata.outputs.labels }}
@@ -66,7 +66,7 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max
context: backend/
- file: backend/docker/production/django/Dockerfile
+ file: backend/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.metadata.outputs.tags }}
labels: ${{ steps.metadata.outputs.labels }}
diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml
index 72f41f214..02c20958e 100644
--- a/.github/workflows/frontend.yml
+++ b/.github/workflows/frontend.yml
@@ -12,11 +12,6 @@ defaults:
run:
working-directory: frontend
-env:
- REACT_APP_KEYCLOAK_REALM: esgf
- REACT_APP_KEYCLOAK_URL: https://esgf-login.ceda.ac.uk/
- REACT_APP_KEYCLOAK_CLIENT_ID: metagrid-localhost
-
jobs:
build:
runs-on: ubuntu-latest
@@ -46,13 +41,8 @@ jobs:
- name: Run Tests
env:
RELEASE: dev
- ENV_FILE: .envs/.react
HTML_PATH: public
- run: |
- # Replaces react-scripts substitution during build for index.html and generates runtime_env.js
- docker/production/react/entrypoint
-
- yarn test:coverage
+ run: yarn test:coverage
- name: Upload Coverage Report
uses: codecov/codecov-action@v3
diff --git a/.gitignore b/.gitignore
index 4b7a1a572..6343ae71a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,7 +23,6 @@ metagrid_configs/backups
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
-
### VisualStudioCode template
**/.vscode/*
@@ -80,8 +79,6 @@ crashlytics.properties
crashlytics-build.properties
fabric.properties
-
-
### Windows template
# Windows thumbnail cache files
Thumbs.db
@@ -106,7 +103,6 @@ $RECYCLE.BIN/
# Windows shortcuts
*.lnk
-
### macOS template
# General
*.DS_Store
@@ -135,7 +131,6 @@ Network Trash Folder
Temporary Items
.apdisk
-
### SublimeText template
# Cache files for Sublime Text
*.tmlanguage.cache
@@ -168,7 +163,6 @@ bh_unicode_properties.cache
# https://packagecontrol.io/packages/sublime-github
GitHub.sublime-settings
-
### Vim template
# Swap
[._]*.s[a-v][a-z]
@@ -189,4 +183,7 @@ tags
.env
.envs/*
!.envs/.local/
+
+# Documentation artifacts
+docs/site
frontend/public/runtime_env.js
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 2ad2432c3..f7f07886a 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -62,7 +62,14 @@
"eslint.workingDirectories": ["./frontend/"],
// Jest
// -----------------------------
- "jest.pathToJest": "yarn test:watch",
+ "jest.rootPath": "./frontend/src",
+ "jest.jestCommandLine": "yarn jest --runInBand",
+ "jest.monitorLongRun": "off",
+ "jest.enable": true,
+ "jest.runMode": {
+ "type": "on-demand",
+ "coverage": true
+ },
// HTML, CSS, JSON
// -----------------------------
"[html]": {
@@ -77,5 +84,7 @@
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
- "python.analysis.extraPaths": ["backend/venv/bin/python"]
+ "python.analysis.extraPaths": ["backend/venv/bin/python"],
+ "python.testing.pytestEnabled": true,
+ "python.testing.pytestArgs": ["backend"]
}
diff --git a/backend/.envs/.django b/backend/.envs/.django
deleted file mode 100644
index 9347db827..000000000
--- a/backend/.envs/.django
+++ /dev/null
@@ -1,42 +0,0 @@
-# General
-# ------------------------------------------------------------------------------
-DJANGO_SETTINGS_MODULE=config.settings.local
-DOMAIN_NAME=http://localhost:8000
-
-# Security
-# ------------------------------------------------------------------------------
-DJANGO_SECURE_SSL_REDIRECT=False
-
-# django-cors-headers
-# ------------------------------------------------------------------------------
-CORS_ORIGIN_WHITELIST=http://localhost:3000
-
-# django-all-auth
-# ------------------------------------------------------------------------------
-KEYCLOAK_URL=https://esgf-login.ceda.ac.uk/
-KEYCLOAK_REALM=esgf
-KEYCLOAK_CLIENT_ID=metagrid-localhost
-
-# ESGF wget API
-# https://github.com/ESGF/esgf-wget
-REACT_APP_WGET_API_URL=https://esgf-node.llnl.gov/esg-search/wget
-
-# ESGF Search API
-# https://esgf.github.io/esg-search/ESGF_Search_RESTful_API.html
-REACT_APP_SEARCH_URL=https://esgf-node.llnl.gov/esg-search/search
-
-# ESGF Node Status API
-# https://github.com/ESGF/esgf-utils/blob/master/node_status/query_prom.py
-REACT_APP_ESGF_NODE_STATUS_URL=https://aims2.llnl.gov/metagrid-backend/proxy/status
-
-# ESGF Solr URL
-REACT_APP_ESGF_SOLR_URL=http://esgf-node.llnl.gov/solr/files/select
-
-# https://docs.djangoproject.com/en/4.2/ref/settings/#login-redirect-url
-# https://docs.djangoproject.com/en/4.2/ref/settings/#logout-redirect-url
-DJANGO_LOGIN_REDIRECT_URL=http://localhost:3000/search
-DJANGO_LOGOUT_REDIRECT_URL=http://localhost:3000/search
-
-# https://app.globus.org/settings/developers/registration/confidential_client
-GLOBUS_CLIENT_KEY=12345
-GLOBUS_CLIENT_SECRET=12345
diff --git a/backend/.envs/.keycloak b/backend/.envs/.keycloak
deleted file mode 100644
index e5864f981..000000000
--- a/backend/.envs/.keycloak
+++ /dev/null
@@ -1,14 +0,0 @@
-# Database settings, make sure this matches .postgres
-# ------------------------------------------------------------------------------
-DB_VENDOR=POSTGRES
-DB_ADDR=postgres:5432
-DB_DATABASE=postgres
-DB_USER=postgres
-DB_SCHEMA=keycloak
-DB_PASSWORD=postgres
-
-# Other settings
-# ------------------------------------------------------------------------------
-KEYCLOAK_USER=admin
-KEYCLOAK_PASSWORD=admin
-KEYCLOAK_IMPORT=./keycloak_realm.json
diff --git a/backend/.envs/.postgres b/backend/.envs/.postgres
deleted file mode 100644
index c30487087..000000000
--- a/backend/.envs/.postgres
+++ /dev/null
@@ -1,5 +0,0 @@
-POSTGRES_HOST=postgres
-POSTGRES_PORT=5432
-POSTGRES_DB=postgres
-POSTGRES_USER=postgres
-POSTGRES_PASSWORD=postgres
diff --git a/backend/docker/production/django/Dockerfile b/backend/Dockerfile
similarity index 57%
rename from backend/docker/production/django/Dockerfile
rename to backend/Dockerfile
index 9b2f9c352..8e0b484eb 100644
--- a/backend/docker/production/django/Dockerfile
+++ b/backend/Dockerfile
@@ -17,23 +17,16 @@ RUN addgroup --system django \
&& adduser --system --ingroup django django
# Requirements are installed here to ensure they will be cached.
-COPY ./requirements /requirements
-RUN pip3 install --no-cache-dir -r /requirements/production.txt \
- && rm -rf /requirements
+COPY requirements /requirements
+RUN pip3 install --no-cache-dir -r /requirements/local.txt
-COPY ./docker/production/django/entrypoint /entrypoint
-RUN sed -i 's/\r$//g' /entrypoint
-RUN chmod +x /entrypoint
-RUN chown django /entrypoint
+COPY . /app
-COPY ./docker/production/django/start /start
-RUN sed -i 's/\r$//g' /start
-RUN chmod +x /start
-RUN chown django /start
-COPY --chown=django:django . /app
-
-USER django
+RUN python /app/manage.py collectstatic --noinput \
+ && mkdir -p /app/staticfiles/.well-known \
+ && cyclonedx-py requirements requirements/base.txt --output-format json --outfile /app/staticfiles/.well-known/bom
WORKDIR /app
-
-ENTRYPOINT ["/entrypoint"]
+USER django
+EXPOSE 5000
+CMD ["/usr/local/bin/gunicorn", "-c", "gunicorn_conf.py", "config.wsgi", "--chdir=/app"]
diff --git a/backend/config/settings/base.py b/backend/config/settings/base.py
index 0780686bc..9e88cdb18 100755
--- a/backend/config/settings/base.py
+++ b/backend/config/settings/base.py
@@ -22,7 +22,7 @@
# ------------------------------------------------------------------------------
# Set DEBUG to False as a default for safety
# https://docs.djangoproject.com/en/dev/ref/settings/#debug
-DEBUG = env.bool("DJANGO_DEBUG", default=False)
+DEBUG = env.bool("DJANGO_DEBUG", default=True)
APPEND_SLASH = False
TIME_ZONE = "UTC"
LANGUAGE_CODE = "en-us"
@@ -52,6 +52,8 @@
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
+ "whitenoise.runserver_nostatic",
+ "django_extensions",
# Third party apps
"rest_framework", # utilities for rest apis
"rest_framework.authtoken",
@@ -64,6 +66,7 @@
"dj_rest_auth",
"drf_yasg",
"social_django",
+ "gunicorn",
# Your apps
"metagrid.api_proxy",
"metagrid.users",
@@ -96,15 +99,24 @@
]
# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts
-ALLOWED_HOSTS = ["localhost", "0.0.0.0", "127.0.0.1"]
+ALLOWED_HOSTS = ["django", "localhost", "0.0.0.0", "127.0.0.1"]
ROOT_URLCONF = "config.urls"
+# https://docs.djangoproject.com/en/dev/ref/settings/#secret-key
+SECRET_KEY = env(
+ "DJANGO_SECRET_KEY",
+ default="7LynCTKfcjH6p2Nz77YM9XzSnTSvpPVUNz4bHEScGJ6flWcOslxGNMdAhsDioJFJ",
+)
+
WSGI_APPLICATION = "config.wsgi.application"
# EMAIL
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#email-backend
-EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
+EMAIL_BACKEND = env(
+ "DJANGO_EMAIL_BACKEND",
+ default="django.core.mail.backends.console.EmailBackend",
+)
# https://docs.djangoproject.com/en/2.2/ref/settings/#email-timeout
EMAIL_TIMEOUT = 5
@@ -113,15 +125,24 @@
# Django Admin URL.
ADMIN_URL = "admin/"
# https://docs.djangoproject.com/en/dev/ref/settings/#admins
-ADMINS = (("Author", "vo13@llnl.gov"), ("Author", "downie4@llnl.gov"))
+ADMINS = [("Author", "downie4@llnl.gov"), ("Author", "ames4@llnl.gov")]
# https://docs.djangoproject.com/en/dev/ref/settings/#managers
MANAGERS = ADMINS
+CORS_ORIGIN_ALLOW_ALL = True
+
# DATABASES
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#databases
-DATABASES = {"default": env.db("DATABASE_URL")}
-DATABASES["default"]["ATOMIC_REQUESTS"] = True
+# Default to allowing the standard Postgres variables to configure the default database
+# https://www.postgresql.org/docs/current/libpq-envars.html
+
+DATABASES = {
+ "default": {
+ "ATOMIC_REQUESTS": True,
+ **env.db("DATABASE_URL", default="pgsql:///postgres"),
+ }
+}
# STATIC
# ------------------------------------------------------------------------------
@@ -185,7 +206,7 @@
# https://docs.djangoproject.com/en/dev/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
- "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
+ "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"
},
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
{
@@ -251,7 +272,10 @@
# django-rest-framework - https://www.django-rest-framework.org/api-guide/settings/
# -------------------------------------------------------------------------------
-DEFAULT_RENDERER_CLASSES = ["rest_framework.renderers.JSONRenderer"]
+DEFAULT_RENDERER_CLASSES = [
+ "rest_framework.renderers.JSONRenderer",
+ "rest_framework.renderers.BrowsableAPIRenderer",
+]
REST_FRAMEWORK = {
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
"PAGE_SIZE": int(env("DJANGO_PAGINATION_LIMIT", default=10)),
@@ -282,15 +306,13 @@
SOCIALACCOUNT_PROVIDERS = {
"keycloak": {
"KEYCLOAK_URL": env(
- "KEYCLOAK_URL",
- ),
- "KEYCLOAK_REALM": env(
- "KEYCLOAK_REALM",
+ "KEYCLOAK_URL", default="https://esgf-login.ceda.ac.uk/"
),
+ "KEYCLOAK_REALM": env("KEYCLOAK_REALM", default="esgf"),
},
}
# Used in data migration to register Keycloak social app
-KEYCLOAK_CLIENT_ID = env("KEYCLOAK_CLIENT_ID")
+KEYCLOAK_CLIENT_ID = env("KEYCLOAK_CLIENT_ID", default="metagrid-localhost")
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
@@ -306,8 +328,12 @@
# https://docs.djangoproject.com/en/3.2/ref/settings/#login-url
LOGIN_URL = "/login/globus/"
-LOGIN_REDIRECT_URL = env("DJANGO_LOGIN_REDIRECT_URL")
-LOGOUT_REDIRECT_URL = env("DJANGO_LOGOUT_REDIRECT_URL")
+LOGIN_REDIRECT_URL = env(
+ "DJANGO_LOGIN_REDIRECT_URL", default="http://localhost:8080/search"
+)
+LOGOUT_REDIRECT_URL = env(
+ "DJANGO_LOGOUT_REDIRECT_URL", default="http://localhost:8080/search"
+)
# This dictates which scopes will be requested on each user login
SOCIAL_AUTH_GLOBUS_SCOPE = [
@@ -318,13 +344,14 @@
"urn:globus:auth:scope:transfer.api.globus.org:all",
]
-SOCIAL_AUTH_GLOBUS_KEY = env("GLOBUS_CLIENT_KEY")
-SOCIAL_AUTH_GLOBUS_SECRET = env("GLOBUS_CLIENT_SECRET")
+SOCIAL_AUTH_GLOBUS_KEY = env("GLOBUS_CLIENT_KEY", default="12345")
+SOCIAL_AUTH_GLOBUS_SECRET = env("GLOBUS_CLIENT_SECRET", default="12345")
SOCIAL_AUTH_GLOBUS_AUTH_EXTRA_ARGUMENTS = {
"requested_scopes": SOCIAL_AUTH_GLOBUS_SCOPE,
"prompt": None,
}
SOCIAL_AUTH_JSONFIELD_ENABLED = True
+SOCIAL_AUTH_REDIRECT_IS_HTTPS = False
# dj-rest-auth
# -------------------------------------------------------------------------------
@@ -335,13 +362,83 @@
# django-cors-headers
# -------------------------------------------------------------------------------
# https://github.com/adamchainz/django-cors-headers#setup
-CORS_ALLOWED_ORIGINS = env.list(
- "CORS_ALLOWED_ORIGINS", default=["http://localhost:5000"]
-)
+CORS_ALLOWED_ORIGINS = [
+ "http://localhost:8080",
+]
CORS_ALLOW_CREDENTIALS = True
-CORS_ORIGIN_WHITELIST = env.list("CORS_ORIGIN_WHITELIST", default=[])
+CORS_ORIGIN_WHITELIST = env.list(
+ "CORS_ORIGIN_WHITELIST", default="http://localhost:8080"
+)
+CSRF_TRUSTED_ORIGINS = ["http://localhost:8080"]
+
+SEARCH_URL = env(
+ "REACT_APP_SEARCH_URL",
+ default="https://esgf-node.llnl.gov/esg-search/search",
+)
+WGET_URL = env(
+ "REACT_APP_WGET_API_URL",
+ default="https://esgf-node.llnl.gov/esg-search/wget",
+)
+STATUS_URL = env(
+ "REACT_APP_ESGF_NODE_STATUS_URL",
+ default="https://esgf-node.llnl.gov/proxy/status",
+)
+SOLR_URL = env(
+ "REACT_APP_ESGF_SOLR_URL", default="https://esgf-node.llnl.gov/esg-search"
+)
+
+FRONTEND_SETTINGS = {
+ "REACT_APP_PREVIOUS_URL": env("REACT_APP_PREVIOUS_URL", default=""),
+ "REACT_APP_AUTHENTICATION_METHOD": env(
+ "REACT_APP_AUTHENTICATION_METHOD", default="keycloak"
+ ),
+ "REACT_APP_GLOBUS_REDIRECT": env(
+ "REACT_APP_GLOBUS_REDIRECT",
+ default="http://localhost:8080/cart/items",
+ ),
+ "REACT_APP_GLOBUS_CLIENT_ID": env(
+ "REACT_APP_GLOBUS_CLIENT_ID", default="frontend"
+ ),
+ "REACT_APP_GLOBUS_NODES": env.list(
+ "REACT_APP_GLOBUS_NODES",
+ default=[
+ "aims3.llnl.gov",
+ "esgf-data1.llnl.gov",
+ "esgf-data2.llnl.gov",
+ "esgf-node.ornl.gov",
+ ],
+ ),
+ "REACT_APP_ESGF_SOLR_URL": env(
+ "REACT_APP_ESGF_SOLR_URL", default="https://esgf-node.llnl.gov/solr"
+ ),
+ "REACT_APP_KEYCLOAK_REALM": env(
+ "REACT_APP_KEYCLOAK_REALM", default="esgf"
+ ),
+ "REACT_APP_KEYCLOAK_URL": env(
+ "REACT_APP_KEYCLOAK_URL", default="http://localhost:1337"
+ ),
+ "REACT_APP_KEYCLOAK_CLIENT_ID": env(
+ "REACT_APP_KEYCLOAK_CLIENT_ID", default="frontend"
+ ),
+ "REACT_APP_HOTJAR_ID": env("REACT_APP_HOTJAR_ID", default="1234"),
+ "REACT_APP_HOTJAR_SV": env("REACT_APP_HOTJAR_SV", default="1234"),
+ "REACT_APP_GOOGLE_ANALYTICS_TRACKING_ID": env(
+ "REACT_APP_GOOGLE_ANALYTICS_TRACKING_ID", default="GA-XXXXXX"
+ ),
+}
-SEARCH_URL = env("REACT_APP_SEARCH_URL")
-WGET_URL = env("REACT_APP_WGET_API_URL")
-STATUS_URL = env("REACT_APP_ESGF_NODE_STATUS_URL")
-SOLR_URL = env("REACT_APP_ESGF_SOLR_URL")
+if not isinstance(FRONTEND_SETTINGS["REACT_APP_GLOBUS_NODES"], list):
+ raise environ.ImproperlyConfigured(
+ f"REACT_APP_GLOBUS_NODES must be of type list, not "
+ f"{FRONTEND_SETTINGS['REACT_APP_GLOBUS_NODES']} of type "
+ f"{type(FRONTEND_SETTINGS['REACT_APP_GLOBUS_NODES'])}"
+ )
+
+if FRONTEND_SETTINGS["REACT_APP_AUTHENTICATION_METHOD"] not in (
+ "keycloak",
+ "globus",
+):
+ raise environ.ImproperlyConfigured(
+ f"REACT_APP_AUTHENTICATION_METHOD must be one of keycloak or globus, "
+ f"not {FRONTEND_SETTINGS['REACT_APP_AUTHENTICATION_METHOD']}"
+ )
diff --git a/backend/config/settings/local.py b/backend/config/settings/local.py
deleted file mode 100755
index 75a8b0401..000000000
--- a/backend/config/settings/local.py
+++ /dev/null
@@ -1,47 +0,0 @@
-from .base import * # noqa
-from .base import env
-
-# GENERAL
-# ------------------------------------------------------------------------------
-# https://docs.djangoproject.com/en/dev/ref/settings/#debug
-DEBUG = True
-# https://docs.djangoproject.com/en/dev/ref/settings/#secret-key
-SECRET_KEY = env(
- "DJANGO_SECRET_KEY",
- default="7LynCTKfcjH6p2Nz77YM9XzSnTSvpPVUNz4bHEScGJ6flWcOslxGNMdAhsDioJFJ",
-)
-
-# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts
-ALLOWED_HOSTS = ["localhost", "0.0.0.0", "127.0.0.1"]
-
-# EMAIL
-# ------------------------------------------------------------------------------
-# https://docs.djangoproject.com/en/dev/ref/settings/#email-backend
-EMAIL_BACKEND = env(
- "DJANGO_EMAIL_BACKEND",
- default="django.core.mail.backends.console.EmailBackend",
-)
-
-# django-rest-framework - https://www.django-rest-framework.org/api-guide/settings/
-
-# -------------------------------------------------------------------------------
-DEFAULT_RENDERER_CLASSES.append( # noqa F405
- "rest_framework.renderers.BrowsableAPIRenderer",
-)
-REST_FRAMEWORK["DEFAULT_RENDERER_CLASSES"] = ( # noqa F405
- DEFAULT_RENDERER_CLASSES # noqa F405
-)
-
-# WhiteNoise
-# ------------------------------------------------------------------------------
-# http://whitenoise.evans.io/en/latest/django.html#using-whitenoise-in-development
-INSTALLED_APPS = [
- "whitenoise.runserver_nostatic",
- "django_extensions",
-] + INSTALLED_APPS # noqa F405
-
-CORS_ORIGIN_ALLOW_ALL = True
-
-CSRF_TRUSTED_ORIGINS = ["http://localhost:3000"]
-
-SOCIAL_AUTH_REDIRECT_IS_HTTPS = False
diff --git a/backend/config/settings/production.py b/backend/config/settings/production.py
index b0c18e5ad..7194e41fe 100755
--- a/backend/config/settings/production.py
+++ b/backend/config/settings/production.py
@@ -4,18 +4,29 @@
# GENERAL
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#secret-key
+# Unset default to force user to set it for production deployments
+DEBUG = False
SECRET_KEY = env("DJANGO_SECRET_KEY")
-# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts
-ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=["example.com"])
# DATABASES
# ------------------------------------------------------------------------------
-DATABASES["default"] = env.db("DATABASE_URL") # noqa F405
-DATABASES["default"]["ATOMIC_REQUESTS"] = True # noqa F405
-DATABASES["default"]["CONN_MAX_AGE"] = env.int( # noqa F405
+DATABASES["default"]["CONN_MAX_AGE"] = env.int( # noqa: F405
"CONN_MAX_AGE", default=60
)
+# django-rest-framework - https://www.django-rest-framework.org/api-guide/settings/
+
+# -------------------------------------------------------------------------------
+DEFAULT_RENDERER_CLASSES = ["rest_framework.renderers.BrowsableAPIRenderer"]
+
+
+# EMAIL
+# ------------------------------------------------------------------------------
+# https://docs.djangoproject.com/en/dev/ref/settings/#email-backend
+EMAIL_BACKEND = env(
+ "DJANGO_EMAIL_BACKEND",
+ default="django.core.mail.backends.smtp.EmailBackend",
+)
# SECURITY
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-proxy-ssl-header
@@ -41,21 +52,12 @@
"DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True
)
+# social_django
+# -------------------------------------------------------------------------------
+# This is a general Django setting if views need to redirect to login
+# https://docs.djangoproject.com/en/3.2/ref/settings/#login-url
+SOCIAL_AUTH_REDIRECT_IS_HTTPS = True
+
# STATIC
# ------------------------
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
-
-# MEDIA
-# ------------------------------------------------------------------------------
-# No media is served in this project since it is a pure REST API backend
-
-# APPS
-# ------------------------------------------------------------------------------
-INSTALLED_APPS += ["gunicorn"] # noqa F405
-
-# ADMIN
-# ------------------------------------------------------------------------------
-# Django Admin URL regex.
-ADMIN_URL = env("DJANGO_ADMIN_URL")
-
-CORS_ORIGIN_ALLOW_ALL = False
diff --git a/backend/config/urls.py b/backend/config/urls.py
index 6f3c82b21..a603f1de6 100644
--- a/backend/config/urls.py
+++ b/backend/config/urls.py
@@ -22,6 +22,7 @@
do_search,
do_status,
do_wget,
+ get_frontend_config,
get_temp_storage,
set_temp_storage,
)
@@ -83,6 +84,7 @@ class KeycloakLogin(SocialLoginView):
path("tempStorage/set", set_temp_storage, name="temp_storage_set"),
path("globus/auth", get_access_token, name="globus_auth"),
path("globus/transfer", do_globus_transfer, name="globus_transfer"),
+ path("frontend-config.js", get_frontend_config, name="frontend_config"),
re_path(
r"^account-confirm-email/",
VerifyEmailView.as_view(),
diff --git a/backend/config/wsgi.py b/backend/config/wsgi.py
index 6a0a4cbe8..24e8c2c99 100755
--- a/backend/config/wsgi.py
+++ b/backend/config/wsgi.py
@@ -27,7 +27,7 @@
# if running multiple sites in the same mod_wsgi process. To fix this, use
# mod_wsgi daemon mode with each site in its own daemon process, or use
# os.environ["DJANGO_SETTINGS_MODULE"] = "config.settings.production"
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production")
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.base")
# This application object is used by any WSGI server configured to use this
# file. This includes Django's development server, if the WSGI_APPLICATION
diff --git a/backend/docker-compose.prod.yml b/backend/docker-compose.prod.yml
deleted file mode 100644
index daec9050f..000000000
--- a/backend/docker-compose.prod.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-volumes:
- production_postgres_data: {}
- production_postgres_data_backups: {}
- production_traefik: {}
-
-services:
- postgres:
- build:
- context: .
- dockerfile: ./docker/production/postgres/Dockerfile
- image: metagrid_production_postgres
- volumes:
- - production_postgres_data:/var/lib/postgresql/data
- - production_postgres_data_backups:/backups
- env_file:
- - ./.envs/.prod.env
-
- django:
- build:
- context: .
- dockerfile: ./docker/production/django/Dockerfile
- image: metagrid_production_django
- networks:
- - traefik_default
- - default
- depends_on:
- - postgres
- env_file:
- - ./.envs/.prod.env
- ports:
- - "5000:5000"
- command: /start
-
-networks:
- traefik_default:
- external: true
diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml
deleted file mode 100644
index 5a2edeeb1..000000000
--- a/backend/docker-compose.yml
+++ /dev/null
@@ -1,39 +0,0 @@
-volumes:
- local_postgres_data: {}
- local_postgres_data_backups: {}
-
-services:
- # This service uses the production Postgres Dockerfile as a base
- # Some tweaks are applied to support the Keycloak service, including the init.sql script
- postgres:
- build:
- context: .
- dockerfile: ./docker/production/postgres/Dockerfile
- image: metagrid_local_postgres
- container_name: postgres
- volumes:
- - local_postgres_data:/var/lib/postgresql/data
- - local_postgres_data_backups:/backups
- - ./docker/local/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
- env_file:
- - ./.envs/.postgres
- ports:
- - "5433:5432"
-
- django:
- build:
- context: .
- dockerfile: ./docker/local/django/Dockerfile
- image: metagrid_local_django
- container_name: django
- depends_on:
- - postgres
- volumes:
- - .:/app
- env_file:
- - ./.envs/.django
- - ./.envs/.postgres
- ports:
- - "8000:8000"
- restart: always
- command: /start
diff --git a/backend/docker/local/django/Dockerfile b/backend/docker/local/django/Dockerfile
deleted file mode 100644
index 6bc1f1bba..000000000
--- a/backend/docker/local/django/Dockerfile
+++ /dev/null
@@ -1,33 +0,0 @@
-FROM python:3.11-slim
-
-ENV DATABASE_URL postgres://postgres:postgres@postgres:5432/postgres
-ENV PYTHONUNBUFFERED 1
-ENV PYTHONDONTWRITEBYTECODE 1
-
-RUN apt-get update \
- # dependencies for building Python packages
- && apt-get install -y build-essential \
- # psycopg2 dependencies
- && apt-get install -y libpq-dev \
- # Translations dependencies
- && apt-get install -y gettext \
- # cleaning up unused files
- && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
- && rm -rf /var/lib/apt/lists/*
-
-# Requirements are installed here to ensure they will be cached.
-COPY ./requirements /requirements
-RUN pip3 install setuptools
-RUN pip3 install -r /requirements/local.txt
-
-COPY ./docker/production/django/entrypoint /entrypoint
-RUN sed -i 's/\r$//g' /entrypoint
-RUN chmod +x /entrypoint
-
-COPY ./docker/local/django/start /start
-RUN sed -i 's/\r$//g' /start
-RUN chmod +x /start
-
-WORKDIR /app
-
-ENTRYPOINT ["/entrypoint"]
diff --git a/backend/docker/local/django/start b/backend/docker/local/django/start
deleted file mode 100644
index df27b7174..000000000
--- a/backend/docker/local/django/start
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-set -o errexit
-set -o pipefail
-set -o nounset
-
-
-python manage.py migrate
-python manage.py runserver 0.0.0.0:8000
diff --git a/backend/docker/local/keycloak/realm-export.json b/backend/docker/local/keycloak/realm-export.json
deleted file mode 100644
index 2460855cf..000000000
--- a/backend/docker/local/keycloak/realm-export.json
+++ /dev/null
@@ -1,2067 +0,0 @@
-{
- "id": "MyDemo",
- "realm": "metagrid",
- "displayName": "MetaGrid",
- "notBefore": 0,
- "revokeRefreshToken": false,
- "refreshTokenMaxReuse": 0,
- "accessTokenLifespan": 300,
- "accessTokenLifespanForImplicitFlow": 900,
- "ssoSessionIdleTimeout": 1800,
- "ssoSessionMaxLifespan": 36000,
- "ssoSessionIdleTimeoutRememberMe": 0,
- "ssoSessionMaxLifespanRememberMe": 0,
- "offlineSessionIdleTimeout": 2592000,
- "offlineSessionMaxLifespanEnabled": false,
- "offlineSessionMaxLifespan": 5184000,
- "clientSessionIdleTimeout": 0,
- "clientSessionMaxLifespan": 0,
- "accessCodeLifespan": 60,
- "accessCodeLifespanUserAction": 300,
- "accessCodeLifespanLogin": 1800,
- "actionTokenGeneratedByAdminLifespan": 43200,
- "actionTokenGeneratedByUserLifespan": 300,
- "enabled": true,
- "sslRequired": "external",
- "registrationAllowed": false,
- "registrationEmailAsUsername": false,
- "rememberMe": false,
- "verifyEmail": false,
- "loginWithEmailAllowed": true,
- "duplicateEmailsAllowed": false,
- "resetPasswordAllowed": false,
- "editUsernameAllowed": false,
- "bruteForceProtected": false,
- "permanentLockout": false,
- "maxFailureWaitSeconds": 900,
- "minimumQuickLoginWaitSeconds": 60,
- "waitIncrementSeconds": 60,
- "quickLoginCheckMilliSeconds": 1000,
- "maxDeltaTimeSeconds": 43200,
- "failureFactor": 30,
- "roles": {
- "realm": [
- {
- "id": "7c723af0-c724-4eec-8fc6-0342606cdf3b",
- "name": "offline_access",
- "description": "${role_offline-access}",
- "composite": false,
- "clientRole": false,
- "containerId": "MyDemo",
- "attributes": {}
- },
- {
- "id": "9d7f509a-2e01-4f68-b49a-f6b84b29e4bd",
- "name": "uma_authorization",
- "description": "${role_uma_authorization}",
- "composite": false,
- "clientRole": false,
- "containerId": "MyDemo",
- "attributes": {}
- }
- ],
- "client": {
- "realm-management": [
- {
- "id": "9e929a6e-b2f9-4755-bf8f-ab9ca5f07892",
- "name": "view-events",
- "description": "${role_view-events}",
- "composite": false,
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "0efa7ac2-8b8e-4a2e-bdb1-7dacd1c87453",
- "name": "view-realm",
- "description": "${role_view-realm}",
- "composite": false,
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "662d4825-7799-4921-9cfb-911866e3f27b",
- "name": "query-users",
- "description": "${role_query-users}",
- "composite": false,
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "018dbd7d-3635-4a5d-9da9-1bbc9ffbaac6",
- "name": "realm-admin",
- "description": "${role_realm-admin}",
- "composite": true,
- "composites": {
- "client": {
- "realm-management": [
- "view-events",
- "view-realm",
- "query-users",
- "create-client",
- "manage-realm",
- "view-clients",
- "view-authorization",
- "manage-authorization",
- "query-realms",
- "manage-users",
- "query-clients",
- "view-identity-providers",
- "view-users",
- "manage-identity-providers",
- "impersonation",
- "manage-events",
- "manage-clients",
- "query-groups"
- ]
- }
- },
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "7a7e77d5-9c63-4d6c-9a78-4b882d6d1125",
- "name": "create-client",
- "description": "${role_create-client}",
- "composite": false,
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "97950b72-dab8-4639-867a-e71250974758",
- "name": "manage-realm",
- "description": "${role_manage-realm}",
- "composite": false,
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "951af848-7263-4c13-bd57-66460ba2682f",
- "name": "view-clients",
- "description": "${role_view-clients}",
- "composite": true,
- "composites": {
- "client": {
- "realm-management": ["query-clients"]
- }
- },
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "d0166563-eaea-4811-918d-4346f5651d10",
- "name": "view-authorization",
- "description": "${role_view-authorization}",
- "composite": false,
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "8046dcc1-c182-48ec-a10c-05bfcc6708b3",
- "name": "manage-authorization",
- "description": "${role_manage-authorization}",
- "composite": false,
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "85958fb8-5510-4271-9b68-0d05499e7f57",
- "name": "manage-users",
- "description": "${role_manage-users}",
- "composite": false,
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "4b2758a6-baf8-4b68-9517-0178d8b713ad",
- "name": "query-realms",
- "description": "${role_query-realms}",
- "composite": false,
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "90d4090f-a392-4c66-995e-a726dfe0338f",
- "name": "query-clients",
- "description": "${role_query-clients}",
- "composite": false,
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "61cc0b27-2261-4af1-b3b4-90a588374eb3",
- "name": "view-identity-providers",
- "description": "${role_view-identity-providers}",
- "composite": false,
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "e7f1185f-85fc-4ed8-ac45-57adc624851a",
- "name": "view-users",
- "description": "${role_view-users}",
- "composite": true,
- "composites": {
- "client": {
- "realm-management": ["query-users", "query-groups"]
- }
- },
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "f0771319-6627-4cd9-bdec-23384a635804",
- "name": "manage-identity-providers",
- "description": "${role_manage-identity-providers}",
- "composite": false,
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "38499a21-ed5a-4021-80bf-22853da02bff",
- "name": "impersonation",
- "description": "${role_impersonation}",
- "composite": false,
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "f7de7801-9785-4bb4-98fb-52f630133ebe",
- "name": "manage-clients",
- "description": "${role_manage-clients}",
- "composite": false,
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "ec206da7-b3ae-4751-b1e9-0bd564056ee1",
- "name": "manage-events",
- "description": "${role_manage-events}",
- "composite": false,
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- },
- {
- "id": "57721045-0d2f-4667-aa3e-9db2864f8935",
- "name": "query-groups",
- "description": "${role_query-groups}",
- "composite": false,
- "clientRole": true,
- "containerId": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "attributes": {}
- }
- ],
- "security-admin-console": [],
- "admin-cli": [],
- "backend": [],
- "account-console": [],
- "broker": [
- {
- "id": "452e4fb6-8bbe-4b87-bdc1-9b7cbe201eb8",
- "name": "read-token",
- "description": "${role_read-token}",
- "composite": false,
- "clientRole": true,
- "containerId": "155dca54-ed4e-4dfc-a9c3-ab3a603810fd",
- "attributes": {}
- }
- ],
- "account": [
- {
- "id": "2e315fd5-d859-469e-a149-76f47a306621",
- "name": "manage-consent",
- "description": "${role_manage-consent}",
- "composite": true,
- "composites": {
- "client": {
- "account": ["view-consent"]
- }
- },
- "clientRole": true,
- "containerId": "c4c68879-c3d2-4639-a86d-a9ff188018ee",
- "attributes": {}
- },
- {
- "id": "70fdd426-022e-4fa1-bf3e-ff3ed9320161",
- "name": "view-profile",
- "description": "${role_view-profile}",
- "composite": false,
- "clientRole": true,
- "containerId": "c4c68879-c3d2-4639-a86d-a9ff188018ee",
- "attributes": {}
- },
- {
- "id": "d3f130d3-68f0-4aff-9eb5-7290ee8448fd",
- "name": "view-applications",
- "description": "${role_view-applications}",
- "composite": false,
- "clientRole": true,
- "containerId": "c4c68879-c3d2-4639-a86d-a9ff188018ee",
- "attributes": {}
- },
- {
- "id": "33a92b0b-4dcf-4eb9-abf3-f0ca97361577",
- "name": "view-consent",
- "description": "${role_view-consent}",
- "composite": false,
- "clientRole": true,
- "containerId": "c4c68879-c3d2-4639-a86d-a9ff188018ee",
- "attributes": {}
- },
- {
- "id": "3cc40068-7967-4fc7-adf3-c4ae588b1418",
- "name": "manage-account-links",
- "description": "${role_manage-account-links}",
- "composite": false,
- "clientRole": true,
- "containerId": "c4c68879-c3d2-4639-a86d-a9ff188018ee",
- "attributes": {}
- },
- {
- "id": "b57c2337-dc7f-4d1d-b23c-18f9c27a1ff2",
- "name": "manage-account",
- "description": "${role_manage-account}",
- "composite": true,
- "composites": {
- "client": {
- "account": ["manage-account-links"]
- }
- },
- "clientRole": true,
- "containerId": "c4c68879-c3d2-4639-a86d-a9ff188018ee",
- "attributes": {}
- }
- ],
- "frontend": []
- }
- },
- "groups": [],
- "defaultRoles": ["offline_access", "uma_authorization"],
- "requiredCredentials": ["password"],
- "otpPolicyType": "totp",
- "otpPolicyAlgorithm": "HmacSHA1",
- "otpPolicyInitialCounter": 0,
- "otpPolicyDigits": 6,
- "otpPolicyLookAheadWindow": 1,
- "otpPolicyPeriod": 30,
- "otpSupportedApplications": ["FreeOTP", "Google Authenticator"],
- "webAuthnPolicyRpEntityName": "keycloak",
- "webAuthnPolicySignatureAlgorithms": ["ES256"],
- "webAuthnPolicyRpId": "",
- "webAuthnPolicyAttestationConveyancePreference": "not specified",
- "webAuthnPolicyAuthenticatorAttachment": "not specified",
- "webAuthnPolicyRequireResidentKey": "not specified",
- "webAuthnPolicyUserVerificationRequirement": "not specified",
- "webAuthnPolicyCreateTimeout": 0,
- "webAuthnPolicyAvoidSameAuthenticatorRegister": false,
- "webAuthnPolicyAcceptableAaguids": [],
- "webAuthnPolicyPasswordlessRpEntityName": "keycloak",
- "webAuthnPolicyPasswordlessSignatureAlgorithms": ["ES256"],
- "webAuthnPolicyPasswordlessRpId": "",
- "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified",
- "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified",
- "webAuthnPolicyPasswordlessRequireResidentKey": "not specified",
- "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified",
- "webAuthnPolicyPasswordlessCreateTimeout": 0,
- "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false,
- "webAuthnPolicyPasswordlessAcceptableAaguids": [],
- "scopeMappings": [
- {
- "clientScope": "offline_access",
- "roles": ["offline_access"]
- }
- ],
- "clientScopeMappings": {
- "account": [
- {
- "client": "account-console",
- "roles": ["manage-account"]
- }
- ]
- },
- "clients": [
- {
- "id": "c4c68879-c3d2-4639-a86d-a9ff188018ee",
- "clientId": "account",
- "name": "${client_account}",
- "rootUrl": "${authBaseUrl}",
- "baseUrl": "/realms/metagrid/account/",
- "surrogateAuthRequired": false,
- "enabled": true,
- "alwaysDisplayInConsole": false,
- "clientAuthenticatorType": "client-secret",
- "secret": "**********",
- "defaultRoles": ["view-profile", "manage-account"],
- "redirectUris": ["/realms/metagrid/account/*"],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": false,
- "frontchannelLogout": false,
- "protocol": "openid-connect",
- "attributes": {},
- "authenticationFlowBindingOverrides": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "defaultClientScopes": [
- "web-origins",
- "role_list",
- "roles",
- "profile",
- "email"
- ],
- "optionalClientScopes": [
- "address",
- "phone",
- "offline_access",
- "microprofile-jwt"
- ]
- },
- {
- "id": "3a2b0f1b-0015-4ca9-b818-d8f743c91e29",
- "clientId": "account-console",
- "name": "${client_account-console}",
- "rootUrl": "${authBaseUrl}",
- "baseUrl": "/realms/MyDemo/account/",
- "surrogateAuthRequired": false,
- "enabled": true,
- "alwaysDisplayInConsole": false,
- "clientAuthenticatorType": "client-secret",
- "secret": "**********",
- "redirectUris": ["/realms/MyDemo/account/*"],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": true,
- "frontchannelLogout": false,
- "protocol": "openid-connect",
- "attributes": {
- "pkce.code.challenge.method": "S256"
- },
- "authenticationFlowBindingOverrides": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "049033ef-bf17-4bb7-999a-8cba9b746166",
- "name": "audience resolve",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-audience-resolve-mapper",
- "consentRequired": false,
- "config": {}
- }
- ],
- "defaultClientScopes": [
- "web-origins",
- "role_list",
- "roles",
- "profile",
- "email"
- ],
- "optionalClientScopes": [
- "address",
- "phone",
- "offline_access",
- "microprofile-jwt"
- ]
- },
- {
- "id": "b04303dc-127b-4bc3-9b6b-b2efffb90e44",
- "clientId": "admin-cli",
- "name": "${client_admin-cli}",
- "surrogateAuthRequired": false,
- "enabled": true,
- "alwaysDisplayInConsole": false,
- "clientAuthenticatorType": "client-secret",
- "secret": "**********",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": false,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": true,
- "serviceAccountsEnabled": false,
- "publicClient": true,
- "frontchannelLogout": false,
- "protocol": "openid-connect",
- "attributes": {},
- "authenticationFlowBindingOverrides": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "defaultClientScopes": [
- "web-origins",
- "role_list",
- "roles",
- "profile",
- "email"
- ],
- "optionalClientScopes": [
- "address",
- "phone",
- "offline_access",
- "microprofile-jwt"
- ]
- },
- {
- "id": "4f6fb22f-0fe4-4ade-af10-70fde8207491",
- "clientId": "backend",
- "name": "Django (Backend)",
- "rootUrl": "http://localhost:8000",
- "adminUrl": "http://localhost:8000",
- "surrogateAuthRequired": false,
- "enabled": true,
- "alwaysDisplayInConsole": false,
- "clientAuthenticatorType": "client-secret",
- "secret": "**********",
- "redirectUris": ["http://localhost:8000/*"],
- "webOrigins": ["http://localhost:8000"],
- "notBefore": 0,
- "bearerOnly": true,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": true,
- "serviceAccountsEnabled": false,
- "publicClient": false,
- "frontchannelLogout": false,
- "protocol": "openid-connect",
- "attributes": {
- "saml.assertion.signature": "false",
- "saml.force.post.binding": "false",
- "saml.multivalued.roles": "false",
- "saml.encrypt": "false",
- "saml.server.signature": "false",
- "saml.server.signature.keyinfo.ext": "false",
- "exclude.session.state.from.auth.response": "false",
- "saml_force_name_id_format": "false",
- "saml.client.signature": "false",
- "tls.client.certificate.bound.access.tokens": "false",
- "saml.authnstatement": "false",
- "display.on.consent.screen": "false",
- "saml.onetimeuse.condition": "false"
- },
- "authenticationFlowBindingOverrides": {},
- "fullScopeAllowed": true,
- "nodeReRegistrationTimeout": -1,
- "defaultClientScopes": [
- "web-origins",
- "role_list",
- "roles",
- "profile",
- "email"
- ],
- "optionalClientScopes": [
- "address",
- "phone",
- "offline_access",
- "microprofile-jwt"
- ]
- },
- {
- "id": "155dca54-ed4e-4dfc-a9c3-ab3a603810fd",
- "clientId": "broker",
- "name": "${client_broker}",
- "surrogateAuthRequired": false,
- "enabled": true,
- "alwaysDisplayInConsole": false,
- "clientAuthenticatorType": "client-secret",
- "secret": "**********",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": false,
- "frontchannelLogout": false,
- "protocol": "openid-connect",
- "attributes": {},
- "authenticationFlowBindingOverrides": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "defaultClientScopes": [
- "web-origins",
- "role_list",
- "roles",
- "profile",
- "email"
- ],
- "optionalClientScopes": [
- "address",
- "phone",
- "offline_access",
- "microprofile-jwt"
- ]
- },
- {
- "id": "b7c6abcd-7d45-44af-bd98-3c3743b1d973",
- "clientId": "frontend",
- "name": "React (frontend)",
- "rootUrl": "http://localhost:3000",
- "adminUrl": "http://localhost:3000",
- "surrogateAuthRequired": false,
- "enabled": true,
- "alwaysDisplayInConsole": false,
- "clientAuthenticatorType": "client-secret",
- "secret": "**********",
- "redirectUris": ["http://localhost:3000/*"],
- "webOrigins": ["http://localhost:3000"],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": true,
- "directAccessGrantsEnabled": true,
- "serviceAccountsEnabled": false,
- "publicClient": true,
- "frontchannelLogout": false,
- "protocol": "openid-connect",
- "attributes": {
- "saml.assertion.signature": "false",
- "saml.force.post.binding": "false",
- "saml.multivalued.roles": "false",
- "saml.encrypt": "false",
- "saml.server.signature": "false",
- "saml.server.signature.keyinfo.ext": "false",
- "exclude.session.state.from.auth.response": "false",
- "saml_force_name_id_format": "false",
- "saml.client.signature": "false",
- "tls.client.certificate.bound.access.tokens": "false",
- "saml.authnstatement": "false",
- "display.on.consent.screen": "false",
- "saml.onetimeuse.condition": "false"
- },
- "authenticationFlowBindingOverrides": {},
- "fullScopeAllowed": true,
- "nodeReRegistrationTimeout": -1,
- "defaultClientScopes": [
- "web-origins",
- "role_list",
- "roles",
- "profile",
- "email"
- ],
- "optionalClientScopes": [
- "address",
- "phone",
- "offline_access",
- "microprofile-jwt"
- ]
- },
- {
- "id": "428ea6fa-d66c-4af4-bec5-483ac01c329c",
- "clientId": "realm-management",
- "name": "${client_realm-management}",
- "surrogateAuthRequired": false,
- "enabled": true,
- "alwaysDisplayInConsole": false,
- "clientAuthenticatorType": "client-secret",
- "secret": "**********",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": true,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": false,
- "frontchannelLogout": false,
- "protocol": "openid-connect",
- "attributes": {},
- "authenticationFlowBindingOverrides": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "defaultClientScopes": [
- "web-origins",
- "role_list",
- "roles",
- "profile",
- "email"
- ],
- "optionalClientScopes": [
- "address",
- "phone",
- "offline_access",
- "microprofile-jwt"
- ]
- },
- {
- "id": "48b280c4-0857-4624-b586-5866fcd29334",
- "clientId": "security-admin-console",
- "name": "${client_security-admin-console}",
- "rootUrl": "${authAdminUrl}",
- "baseUrl": "/admin/metagrid/console/",
- "surrogateAuthRequired": false,
- "enabled": true,
- "alwaysDisplayInConsole": false,
- "clientAuthenticatorType": "client-secret",
- "secret": "**********",
- "redirectUris": ["/admin/metagrid/console/*"],
- "webOrigins": ["+"],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": true,
- "frontchannelLogout": false,
- "protocol": "openid-connect",
- "attributes": {
- "pkce.code.challenge.method": "S256"
- },
- "authenticationFlowBindingOverrides": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "83638566-6c96-4e58-a575-5cbefe17fdff",
- "name": "locale",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "locale",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "locale",
- "jsonType.label": "String"
- }
- }
- ],
- "defaultClientScopes": [
- "web-origins",
- "role_list",
- "roles",
- "profile",
- "email"
- ],
- "optionalClientScopes": [
- "address",
- "phone",
- "offline_access",
- "microprofile-jwt"
- ]
- }
- ],
- "clientScopes": [
- {
- "id": "76c7c0b8-27b0-4407-bfe9-18b1755b4214",
- "name": "address",
- "description": "OpenID Connect built-in scope: address",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "true",
- "display.on.consent.screen": "true",
- "consent.screen.text": "${addressScopeConsentText}"
- },
- "protocolMappers": [
- {
- "id": "907e945d-4ba6-4ddf-9596-4d35f8097a79",
- "name": "address",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-address-mapper",
- "consentRequired": false,
- "config": {
- "user.attribute.formatted": "formatted",
- "user.attribute.country": "country",
- "user.attribute.postal_code": "postal_code",
- "userinfo.token.claim": "true",
- "user.attribute.street": "street",
- "id.token.claim": "true",
- "user.attribute.region": "region",
- "access.token.claim": "true",
- "user.attribute.locality": "locality"
- }
- }
- ]
- },
- {
- "id": "96e3edef-e63c-4b2f-bf55-4fb3e4792cc8",
- "name": "email",
- "description": "OpenID Connect built-in scope: email",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "true",
- "display.on.consent.screen": "true",
- "consent.screen.text": "${emailScopeConsentText}"
- },
- "protocolMappers": [
- {
- "id": "35db8c2f-848a-4824-b2da-452e1944cc73",
- "name": "email verified",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "emailVerified",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email_verified",
- "jsonType.label": "boolean"
- }
- },
- {
- "id": "300ed031-2d11-483c-96ba-1357be8158bb",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- }
- ]
- },
- {
- "id": "0fc68c88-6203-462a-9e3d-e9838d11be5a",
- "name": "microprofile-jwt",
- "description": "Microprofile - JWT built-in scope",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "true",
- "display.on.consent.screen": "false"
- },
- "protocolMappers": [
- {
- "id": "a5cb388e-7782-430f-8b83-280735093cee",
- "name": "upn",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "upn",
- "jsonType.label": "String"
- }
- },
- {
- "id": "1aeb8ecd-4bd9-48ef-9f8d-13ee41771254",
- "name": "groups",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-realm-role-mapper",
- "consentRequired": false,
- "config": {
- "multivalued": "true",
- "userinfo.token.claim": "true",
- "user.attribute": "foo",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "groups",
- "jsonType.label": "String"
- }
- }
- ]
- },
- {
- "id": "858bfdcd-7f43-4f7e-8650-2b59d1390b11",
- "name": "offline_access",
- "description": "OpenID Connect built-in scope: offline_access",
- "protocol": "openid-connect",
- "attributes": {
- "consent.screen.text": "${offlineAccessScopeConsentText}",
- "display.on.consent.screen": "true"
- }
- },
- {
- "id": "df2091b1-dd6e-4fc5-b44a-b0c990d44a27",
- "name": "phone",
- "description": "OpenID Connect built-in scope: phone",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "true",
- "display.on.consent.screen": "true",
- "consent.screen.text": "${phoneScopeConsentText}"
- },
- "protocolMappers": [
- {
- "id": "76def093-bdd7-4d7a-b4a1-291a67300550",
- "name": "phone number",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "phoneNumber",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "phone_number",
- "jsonType.label": "String"
- }
- },
- {
- "id": "1278e746-e27e-4ed3-ab19-d428bb7eddd9",
- "name": "phone number verified",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "phoneNumberVerified",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "phone_number_verified",
- "jsonType.label": "boolean"
- }
- }
- ]
- },
- {
- "id": "aa0b03ab-84ca-45a1-828c-f6b73bb57d29",
- "name": "profile",
- "description": "OpenID Connect built-in scope: profile",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "true",
- "display.on.consent.screen": "true",
- "consent.screen.text": "${profileScopeConsentText}"
- },
- "protocolMappers": [
- {
- "id": "4c410418-d3a2-4e24-953d-d2846eb54345",
- "name": "updated at",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "updatedAt",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "updated_at",
- "jsonType.label": "String"
- }
- },
- {
- "id": "060ced15-4a97-4d67-a6c9-d2eebd7a46f8",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "1121490d-01f6-4706-9686-af6c25ac293c",
- "name": "gender",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "gender",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "gender",
- "jsonType.label": "String"
- }
- },
- {
- "id": "557eb13c-8c26-4ac6-a3ef-7103c848325d",
- "name": "profile",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "profile",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "profile",
- "jsonType.label": "String"
- }
- },
- {
- "id": "f2fa81a4-0b4e-4728-b6c4-df54347def61",
- "name": "website",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "website",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "website",
- "jsonType.label": "String"
- }
- },
- {
- "id": "dbc3b7d1-9e16-4902-a175-e8053688ff43",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": false,
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true",
- "userinfo.token.claim": "true"
- }
- },
- {
- "id": "f0cf04fa-5cdf-4bf7-b044-96092a781b63",
- "name": "picture",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "picture",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "picture",
- "jsonType.label": "String"
- }
- },
- {
- "id": "ed4c200b-c9a8-48a1-9155-269590702663",
- "name": "birthdate",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "birthdate",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "birthdate",
- "jsonType.label": "String"
- }
- },
- {
- "id": "2176159e-5b10-42db-b7ef-8c34d63e2e28",
- "name": "zoneinfo",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "zoneinfo",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "zoneinfo",
- "jsonType.label": "String"
- }
- },
- {
- "id": "78c06922-66f9-4e68-814e-cef2338800d7",
- "name": "locale",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "locale",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "locale",
- "jsonType.label": "String"
- }
- },
- {
- "id": "26f82454-e2e3-496c-b82c-e66c89f51f58",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "8d4caf8b-bba0-4c31-b907-bfb7bba4e4d3",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "c3dcf67c-3d22-415d-aeb7-a049cdbf1a94",
- "name": "middle name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "middleName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "middle_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "94ef900e-9323-48b4-9fef-fa1285f0ab1e",
- "name": "nickname",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "nickname",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "nickname",
- "jsonType.label": "String"
- }
- }
- ]
- },
- {
- "id": "addd2620-6db2-41b2-95e2-5eadeb955bc5",
- "name": "role_list",
- "description": "SAML role list",
- "protocol": "saml",
- "attributes": {
- "consent.screen.text": "${samlRoleListScopeConsentText}",
- "display.on.consent.screen": "true"
- },
- "protocolMappers": [
- {
- "id": "9630e722-fd36-48a7-9df5-c979c77c301f",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- }
- ]
- },
- {
- "id": "8111b123-4cde-4c04-b851-3360e11a6652",
- "name": "roles",
- "description": "OpenID Connect scope for add user roles to the access token",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "false",
- "display.on.consent.screen": "true",
- "consent.screen.text": "${rolesScopeConsentText}"
- },
- "protocolMappers": [
- {
- "id": "e427db4e-bc2a-47f7-af7d-239b77843be3",
- "name": "client roles",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-client-role-mapper",
- "consentRequired": false,
- "config": {
- "user.attribute": "foo",
- "access.token.claim": "true",
- "claim.name": "resource_access.${client_id}.roles",
- "jsonType.label": "String",
- "multivalued": "true"
- }
- },
- {
- "id": "6a4047e1-83ba-476e-84f2-e6beda64c054",
- "name": "audience resolve",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-audience-resolve-mapper",
- "consentRequired": false,
- "config": {}
- },
- {
- "id": "518c936c-9302-4cc8-b9b3-ac61c4a09e3a",
- "name": "realm roles",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-realm-role-mapper",
- "consentRequired": false,
- "config": {
- "user.attribute": "foo",
- "access.token.claim": "true",
- "claim.name": "realm_access.roles",
- "jsonType.label": "String",
- "multivalued": "true"
- }
- }
- ]
- },
- {
- "id": "5cad739c-06f5-4236-ad7a-377c50f11ca4",
- "name": "web-origins",
- "description": "OpenID Connect scope for add allowed web origins to the access token",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "false",
- "display.on.consent.screen": "false",
- "consent.screen.text": ""
- },
- "protocolMappers": [
- {
- "id": "c34ff5ed-8dca-405f-84a1-06d3421976d0",
- "name": "allowed web origins",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-allowed-origins-mapper",
- "consentRequired": false,
- "config": {}
- }
- ]
- }
- ],
- "defaultDefaultClientScopes": [
- "web-origins",
- "roles",
- "email",
- "profile",
- "role_list"
- ],
- "defaultOptionalClientScopes": [
- "microprofile-jwt",
- "address",
- "offline_access",
- "phone"
- ],
- "browserSecurityHeaders": {
- "contentSecurityPolicyReportOnly": "",
- "xContentTypeOptions": "nosniff",
- "xRobotsTag": "none",
- "xFrameOptions": "SAMEORIGIN",
- "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
- "xXSSProtection": "1; mode=block",
- "strictTransportSecurity": "max-age=31536000; includeSubDomains"
- },
- "smtpServer": {},
- "eventsEnabled": false,
- "eventsListeners": ["jboss-logging"],
- "enabledEventTypes": [],
- "adminEventsEnabled": false,
- "adminEventsDetailsEnabled": false,
- "identityProviders": [
- {
- "alias": "github",
- "internalId": "71f0dd51-f77a-4418-abaf-b6c6a3572af3",
- "providerId": "github",
- "enabled": true,
- "updateProfileFirstLoginMode": "on",
- "trustEmail": false,
- "storeToken": false,
- "addReadTokenRoleOnCreate": false,
- "authenticateByDefault": false,
- "linkOnly": false,
- "firstBrokerLoginFlowAlias": "first broker login",
- "config": {
- "syncMode": "IMPORT",
- "clientSecret": "**********",
- "clientId": "07d06e6a0d804ad8f066",
- "useJwksUrl": "true"
- }
- }
- ],
- "components": {
- "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [
- {
- "id": "c545e641-0a0b-4cf3-8d94-612c41d720a3",
- "name": "Full Scope Disabled",
- "providerId": "scope",
- "subType": "anonymous",
- "subComponents": {},
- "config": {}
- },
- {
- "id": "3e0a8ae5-2272-498b-bb46-98df388ac0c7",
- "name": "Consent Required",
- "providerId": "consent-required",
- "subType": "anonymous",
- "subComponents": {},
- "config": {}
- },
- {
- "id": "55048aab-8bb4-4a09-80f8-b244dce19f49",
- "name": "Allowed Protocol Mapper Types",
- "providerId": "allowed-protocol-mappers",
- "subType": "authenticated",
- "subComponents": {},
- "config": {
- "allowed-protocol-mapper-types": [
- "saml-user-property-mapper",
- "oidc-sha256-pairwise-sub-mapper",
- "oidc-usermodel-property-mapper",
- "saml-role-list-mapper",
- "saml-user-attribute-mapper",
- "oidc-address-mapper",
- "oidc-usermodel-attribute-mapper",
- "oidc-full-name-mapper"
- ]
- }
- },
- {
- "id": "e1bc5a46-3396-4972-bff3-43b2ba177472",
- "name": "Trusted Hosts",
- "providerId": "trusted-hosts",
- "subType": "anonymous",
- "subComponents": {},
- "config": {
- "host-sending-registration-request-must-match": ["true"],
- "client-uris-must-match": ["true"]
- }
- },
- {
- "id": "757b0a76-097c-4866-b276-9cf18f32b643",
- "name": "Allowed Client Scopes",
- "providerId": "allowed-client-templates",
- "subType": "anonymous",
- "subComponents": {},
- "config": {
- "allow-default-scopes": ["true"]
- }
- },
- {
- "id": "174a67b9-6763-4570-b904-7971bc724305",
- "name": "Allowed Protocol Mapper Types",
- "providerId": "allowed-protocol-mappers",
- "subType": "anonymous",
- "subComponents": {},
- "config": {
- "allowed-protocol-mapper-types": [
- "oidc-address-mapper",
- "saml-user-property-mapper",
- "oidc-usermodel-property-mapper",
- "oidc-full-name-mapper",
- "saml-user-attribute-mapper",
- "oidc-usermodel-attribute-mapper",
- "saml-role-list-mapper",
- "oidc-sha256-pairwise-sub-mapper"
- ]
- }
- },
- {
- "id": "bb862f01-cbb5-4920-8cd7-f4b57ab90af6",
- "name": "Allowed Client Scopes",
- "providerId": "allowed-client-templates",
- "subType": "authenticated",
- "subComponents": {},
- "config": {
- "allow-default-scopes": ["true"]
- }
- },
- {
- "id": "ee875768-d1a7-4b76-aa2f-b3e23cb32341",
- "name": "Max Clients Limit",
- "providerId": "max-clients",
- "subType": "anonymous",
- "subComponents": {},
- "config": {
- "max-clients": ["200"]
- }
- }
- ],
- "org.keycloak.keys.KeyProvider": [
- {
- "id": "cecf73d7-ee34-400e-8685-4dc5b5b7b11f",
- "name": "rsa-generated",
- "providerId": "rsa-generated",
- "subComponents": {},
- "config": {
- "priority": ["100"]
- }
- },
- {
- "id": "21c1c104-8341-4b64-837e-6aa3097202c1",
- "name": "hmac-generated",
- "providerId": "hmac-generated",
- "subComponents": {},
- "config": {
- "priority": ["100"],
- "algorithm": ["HS256"]
- }
- },
- {
- "id": "0cd6c025-2384-4056-8d06-8f19eb3c5a22",
- "name": "aes-generated",
- "providerId": "aes-generated",
- "subComponents": {},
- "config": {
- "priority": ["100"]
- }
- }
- ]
- },
- "internationalizationEnabled": false,
- "supportedLocales": [],
- "authenticationFlows": [
- {
- "id": "c2b5a753-d1cb-4a93-8aab-547e0c0fe96f",
- "alias": "Account verification options",
- "description": "Method with which to verity the existing account",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "idp-email-verification",
- "requirement": "ALTERNATIVE",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "ALTERNATIVE",
- "priority": 20,
- "flowAlias": "Verify Existing Account by Re-authentication",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "06a97751-eff5-4e43-854e-02a09a4fe388",
- "alias": "Authentication Options",
- "description": "Authentication options.",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "basic-auth",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "basic-auth-otp",
- "requirement": "DISABLED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "auth-spnego",
- "requirement": "DISABLED",
- "priority": 30,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "05df331d-3276-4020-b8dc-b03c7298dc7b",
- "alias": "Browser - Conditional OTP",
- "description": "Flow to determine if the OTP is required for the authentication",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "conditional-user-configured",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "auth-otp-form",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "b768fec3-73c1-4049-a443-e12ceb3db309",
- "alias": "Direct Grant - Conditional OTP",
- "description": "Flow to determine if the OTP is required for the authentication",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "conditional-user-configured",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "direct-grant-validate-otp",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "3fa5889b-59f7-4eab-8c44-f6c1828f9ba9",
- "alias": "First broker login - Conditional OTP",
- "description": "Flow to determine if the OTP is required for the authentication",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "conditional-user-configured",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "auth-otp-form",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "38b0ff3a-8503-4cc1-811f-532c84e80745",
- "alias": "Handle Existing Account",
- "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "idp-confirm-link",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "REQUIRED",
- "priority": 20,
- "flowAlias": "Account verification options",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "718ffaaa-3f3a-40f3-bdbb-7f7a9b23772f",
- "alias": "Reset - Conditional OTP",
- "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "conditional-user-configured",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "reset-otp",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "e18ce8bf-ef28-4c69-b5e4-580792b0e42f",
- "alias": "User creation or linking",
- "description": "Flow for the existing/non-existing user alternatives",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticatorConfig": "create unique user config",
- "authenticator": "idp-create-user-if-unique",
- "requirement": "ALTERNATIVE",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "ALTERNATIVE",
- "priority": 20,
- "flowAlias": "Handle Existing Account",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "33609ab5-8bfe-4464-8229-c8bd68dad6ac",
- "alias": "Verify Existing Account by Re-authentication",
- "description": "Reauthentication of existing account",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "idp-username-password-form",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "CONDITIONAL",
- "priority": 20,
- "flowAlias": "First broker login - Conditional OTP",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "099c1c9e-de56-48a6-82b0-b717f2901910",
- "alias": "browser",
- "description": "browser based authentication",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "auth-cookie",
- "requirement": "ALTERNATIVE",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "auth-spnego",
- "requirement": "DISABLED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "identity-provider-redirector",
- "requirement": "ALTERNATIVE",
- "priority": 25,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "ALTERNATIVE",
- "priority": 30,
- "flowAlias": "forms",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "b627afac-3a2f-4512-8f77-d1bb39d4176e",
- "alias": "clients",
- "description": "Base authentication for clients",
- "providerId": "client-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "client-secret",
- "requirement": "ALTERNATIVE",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "client-jwt",
- "requirement": "ALTERNATIVE",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "client-secret-jwt",
- "requirement": "ALTERNATIVE",
- "priority": 30,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "client-x509",
- "requirement": "ALTERNATIVE",
- "priority": 40,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "dcbc1e3a-2c1e-40c7-ac93-df1d27a2dc31",
- "alias": "direct grant",
- "description": "OpenID Connect Resource Owner Grant",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "direct-grant-validate-username",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "direct-grant-validate-password",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "CONDITIONAL",
- "priority": 30,
- "flowAlias": "Direct Grant - Conditional OTP",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "56b960bc-ef7f-4840-9475-cf2071870e89",
- "alias": "docker auth",
- "description": "Used by Docker clients to authenticate against the IDP",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "docker-http-basic-authenticator",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "215fb81e-86f7-4cb4-b028-c51dc1fbda19",
- "alias": "first broker login",
- "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticatorConfig": "review profile config",
- "authenticator": "idp-review-profile",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "REQUIRED",
- "priority": 20,
- "flowAlias": "User creation or linking",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "268e9530-a8e9-436c-8125-fb5763ee3f63",
- "alias": "forms",
- "description": "Username, password, otp and other auth forms.",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "auth-username-password-form",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "CONDITIONAL",
- "priority": 20,
- "flowAlias": "Browser - Conditional OTP",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "7bfac5eb-bbc2-41e9-bd89-c14f54be18d7",
- "alias": "http challenge",
- "description": "An authentication flow based on challenge-response HTTP Authentication Schemes",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "no-cookie-redirect",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "REQUIRED",
- "priority": 20,
- "flowAlias": "Authentication Options",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "789c8b7a-ad9f-4a54-9248-9f53704bc6d7",
- "alias": "registration",
- "description": "registration flow",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "registration-page-form",
- "requirement": "REQUIRED",
- "priority": 10,
- "flowAlias": "registration form",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "4b0a5bb2-499a-4158-96b5-0e41b65bd8b3",
- "alias": "registration form",
- "description": "registration form",
- "providerId": "form-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "registration-user-creation",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "registration-profile-action",
- "requirement": "REQUIRED",
- "priority": 40,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "registration-password-action",
- "requirement": "REQUIRED",
- "priority": 50,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "registration-recaptcha-action",
- "requirement": "DISABLED",
- "priority": 60,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "31697df6-fc57-4476-b1d8-1dd916d88ee0",
- "alias": "reset credentials",
- "description": "Reset credentials for a user if they forgot their password or something",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "reset-credentials-choose-user",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "reset-credential-email",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "reset-password",
- "requirement": "REQUIRED",
- "priority": 30,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "CONDITIONAL",
- "priority": 40,
- "flowAlias": "Reset - Conditional OTP",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "f2221385-7665-4a9a-b919-774c61351b25",
- "alias": "saml ecp",
- "description": "SAML ECP Profile Authentication Flow",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "http-basic-authenticator",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- }
- ],
- "authenticatorConfig": [
- {
- "id": "7fe76bd0-dd7e-4904-b47d-939af63a907b",
- "alias": "create unique user config",
- "config": {
- "require.password.update.after.registration": "false"
- }
- },
- {
- "id": "55cf038e-f35f-4ae1-a693-766c4be105f8",
- "alias": "review profile config",
- "config": {
- "update.profile.on.first.login": "missing"
- }
- }
- ],
- "requiredActions": [
- {
- "alias": "CONFIGURE_TOTP",
- "name": "Configure OTP",
- "providerId": "CONFIGURE_TOTP",
- "enabled": true,
- "defaultAction": false,
- "priority": 10,
- "config": {}
- },
- {
- "alias": "terms_and_conditions",
- "name": "Terms and Conditions",
- "providerId": "terms_and_conditions",
- "enabled": false,
- "defaultAction": false,
- "priority": 20,
- "config": {}
- },
- {
- "alias": "UPDATE_PASSWORD",
- "name": "Update Password",
- "providerId": "UPDATE_PASSWORD",
- "enabled": true,
- "defaultAction": false,
- "priority": 30,
- "config": {}
- },
- {
- "alias": "UPDATE_PROFILE",
- "name": "Update Profile",
- "providerId": "UPDATE_PROFILE",
- "enabled": true,
- "defaultAction": false,
- "priority": 40,
- "config": {}
- },
- {
- "alias": "VERIFY_EMAIL",
- "name": "Verify Email",
- "providerId": "VERIFY_EMAIL",
- "enabled": true,
- "defaultAction": false,
- "priority": 50,
- "config": {}
- },
- {
- "alias": "update_user_locale",
- "name": "Update User Locale",
- "providerId": "update_user_locale",
- "enabled": true,
- "defaultAction": false,
- "priority": 1000,
- "config": {}
- }
- ],
- "browserFlow": "browser",
- "registrationFlow": "registration",
- "directGrantFlow": "direct grant",
- "resetCredentialsFlow": "reset credentials",
- "clientAuthenticationFlow": "clients",
- "dockerAuthenticationFlow": "docker auth",
- "attributes": {
- "clientSessionIdleTimeout": "0",
- "clientSessionMaxLifespan": "0"
- },
- "keycloakVersion": "10.0.2",
- "userManagedAccessAllowed": false
-}
diff --git a/backend/docker/local/postgres/init.sql b/backend/docker/local/postgres/init.sql
deleted file mode 100644
index 03bf0c281..000000000
--- a/backend/docker/local/postgres/init.sql
+++ /dev/null
@@ -1 +0,0 @@
-CREATE SCHEMA IF NOT EXISTS keycloak;
diff --git a/backend/docker/production/django/entrypoint b/backend/docker/production/django/entrypoint
deleted file mode 100644
index 2c5bec8ff..000000000
--- a/backend/docker/production/django/entrypoint
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash
-
-set -o errexit
-set -o pipefail
-set -o nounset
-
-
-
-
-if [ -z "${POSTGRES_USER}" ]; then
- base_postgres_image_default_user='postgres'
- export POSTGRES_USER="${base_postgres_image_default_user}"
-fi
-export DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}"
-
-postgres_ready() {
-python << END
-import sys
-
-import psycopg2
-
-try:
- psycopg2.connect(
- dbname="${POSTGRES_DB}",
- user="${POSTGRES_USER}",
- password="${POSTGRES_PASSWORD}",
- host="${POSTGRES_HOST}",
- port="${POSTGRES_PORT}",
- )
-except psycopg2.OperationalError:
- sys.exit(-1)
-sys.exit(0)
-
-END
-}
-until postgres_ready; do
- >&2 echo 'Waiting for PostgreSQL to become available...'
- sleep 1
-done
->&2 echo 'PostgreSQL is available'
-
-exec "$@"
diff --git a/backend/docker/production/django/start b/backend/docker/production/django/start
deleted file mode 100644
index e6ded0699..000000000
--- a/backend/docker/production/django/start
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-set -o errexit
-set -o pipefail
-set -o nounset
-
-
-python /app/manage.py collectstatic --noinput
-
-
-/usr/local/bin/gunicorn config.wsgi --bind 0.0.0.0:5000 --chdir=/app
diff --git a/backend/gunicorn_conf.py b/backend/gunicorn_conf.py
new file mode 100644
index 000000000..fb4605789
--- /dev/null
+++ b/backend/gunicorn_conf.py
@@ -0,0 +1,54 @@
+from multiprocessing import cpu_count
+from os import environ
+from tempfile import mkdtemp
+
+
+def calculate_workers() -> int:
+ """Calculate the number of workers for the Gunicorn server.
+
+ Returns:
+ - int: The final value for the 'workers' field after applying the validation logic.
+
+ The method first checks if a value has been provided for 'workers'. If not, it attempts to retrieve the value from the 'web_concurrency' or 'max_workers'.
+ If neither of these fields has a value, the method calculates the number of workers based on the number of CPU cores and rounds the result to the nearest integer, with a minimum value of 2.
+ """
+ return int(
+ environ.get("GUNICORN_WORKERS")
+ or environ.get("GUNICORN_WEB_CONCURRENCY")
+ or environ.get("GUNICORN_MAX_WORKERS")
+ or round(
+ max(
+ int(environ.get("GUNICORN_MAX_WORKERS_PER_CORE", 1))
+ * cpu_count(),
+ 2,
+ )
+ )
+ )
+
+
+def get_binding_addr() -> str:
+ """Determine the binding address for the Gunicorn server.
+
+ Returns:
+ - str: The final value for the `bind` field after applying the validation logic.
+
+ The method first checks if a value has been provided for `bind`. If not, it attempts to construct a binding address from `host` and `port`
+ """
+ return (
+ environ.get("GUNICORN_BIND_ADDRESS")
+ or f"{environ.get('GUNICORN_HOST', '0.0.0.0')}:{environ.get('GUNICORN_PORT', 5000)}"
+ )
+
+
+# Actual Gunicorn config variables
+workers: int = calculate_workers()
+worker_tmp_dir: str = mkdtemp(prefix="/dev/shm/")
+loglevel: str = "DEBUG"
+errorlog: str = "-"
+accesslog: str = "-"
+graceful_timeout: int = 120
+timeout: int = 120
+keepalive: int = 5
+bind: str = get_binding_addr()
+reload: bool = True
+default_proc_name: str = "Metagrid"
diff --git a/backend/manage.py b/backend/manage.py
index f1c84cace..c2454e58d 100755
--- a/backend/manage.py
+++ b/backend/manage.py
@@ -3,7 +3,7 @@
import sys
if __name__ == "__main__":
- os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.base")
try:
from django.core.management import execute_from_command_line
diff --git a/backend/metagrid/api_proxy/tests/test_views.py b/backend/metagrid/api_proxy/tests/test_views.py
index 365a1d12b..418969102 100644
--- a/backend/metagrid/api_proxy/tests/test_views.py
+++ b/backend/metagrid/api_proxy/tests/test_views.py
@@ -1,6 +1,12 @@
+import re
+
+import globus_sdk
+import responses
+from django.conf import settings
from django.contrib.auth import get_user_model
from django.test import override_settings
from django.urls import reverse
+from globus_sdk._testing import load_response
from rest_framework import status
from rest_framework.test import APITestCase
@@ -14,29 +20,51 @@ def test_globus_auth_unauthenticated(self):
assert response.data == {"is_authenticated": False}
assert response.status_code == status.HTTP_200_OK
+ @responses.activate
@override_settings(
SOCIAL_AUTH_GLOBUS_KEY="1", SOCIAL_AUTH_GLOBUS_SECRET="2"
)
def test_globus_auth_begin(self):
+ responses.get(
+ "https://auth.globus.org//.well-known/openid-configuration",
+ json={
+ "authorization_endpoint": "https://auth.globus.org/v2/oauth2/authorize",
+ },
+ )
response = self.client.get(
reverse("social:begin", kwargs={"backend": "globus"})
)
self.assertEqual(response.status_code, 302)
+ @responses.activate
def test_do_globus_get_endpoint(self):
url = reverse("globus-get-endpoint")
+ endpoint_id = "12345"
+ endpoint_url_pattern = re.compile(
+ f"https://transfer.api.globus.org/.*/endpoint/{endpoint_id}"
+ )
+ load_response(
+ globus_sdk.ConfidentialAppAuthClient.oauth2_client_credentials_tokens
+ )
- data = {"endpoint_id": "0247816e-cc0d-4e03-a509-10903f6dde11"}
- response = self.client.get(url, data)
- print(response.status_code)
+ responses.get(endpoint_url_pattern, json={"foo": "bar"})
+ response = self.client.get(url, {"endpoint_id": endpoint_id})
assert response.status_code == status.HTTP_200_OK
+ @responses.activate
def test_do_globus_search_endpoints(self):
url = reverse("globus-search-endpoints")
-
data = {"search_text": "0247816e-cc0d-4e03-a509-10903f6dde11"}
+ endpoint_url_pattern = re.compile(
+ "https://transfer.api.globus.org/.*/endpoint_search"
+ )
+
+ load_response(
+ globus_sdk.ConfidentialAppAuthClient.oauth2_client_credentials_tokens
+ )
+ responses.get(endpoint_url_pattern, json={"DATA": "dummy"})
+
response = self.client.get(url, data)
- print(response.status_code)
assert response.status_code == status.HTTP_200_OK
def test_globus_auth_complete(self):
@@ -64,8 +92,10 @@ def test_globus_auth_logout(self):
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_302_FOUND)
+ @responses.activate
def test_wget(self):
url = reverse("do-wget")
+ responses.get(settings.WGET_URL)
response = self.client.get(
url,
{
@@ -74,9 +104,11 @@ def test_wget(self):
)
assert response.status_code == status.HTTP_200_OK
+ @responses.activate
def test_search(self):
url = reverse("do-search")
postdata = {"project": "CMIP6", "limit": 0}
+ responses.get(settings.SEARCH_URL)
response = self.client.get(url, postdata)
assert response.status_code == status.HTTP_200_OK
@@ -85,12 +117,17 @@ def test_search(self):
# response = self.client.get(url)
# assert response.status_code == status.HTTP_200_OK
+ @responses.activate
def test_citation(self):
url = reverse("do-citation")
jo = {
"citurl": "https://cera-www.dkrz.de/WDCC/meta/CMIP6/CMIP6.CMIP.IPSL.IPSL-CM6A-LR.abrupt-4xCO2.r12i1p1f1.Amon.n2oglobal.gr.v20191003.json"
}
+ responses.get(
+ "https://cera-www.dkrz.de/WDCC/meta/CMIP6/CMIP6.CMIP.IPSL.IPSL-CM6A-LR.abrupt-4xCO2.r12i1p1f1.Amon.n2oglobal.gr.v20191003.json"
+ )
+
response = self.client.post(url, jo, format="json")
assert response.status_code == status.HTTP_200_OK
@@ -163,3 +200,11 @@ def test_temp_storage(self):
test_data = {"dataKey": "temp_storage", "dataValue": None}
response = self.client.post(setUrl, test_data, format="json")
assert response.status_code == status.HTTP_200_OK
+
+ @override_settings(FRONTEND_SETTINGS={"key1": "value1", "key2": "value2"})
+ def test_frontend_config_returns_frontend_settings_as_json(self) -> None:
+ url = reverse("frontend_config")
+ response = self.client.get(url)
+ assert response.status_code == status.HTTP_200_OK
+ assert response["content-type"] == "application/json"
+ assert response.json() == {"key1": "value1", "key2": "value2"}
diff --git a/backend/metagrid/api_proxy/views.py b/backend/metagrid/api_proxy/views.py
index 331d26396..932ddc864 100644
--- a/backend/metagrid/api_proxy/views.py
+++ b/backend/metagrid/api_proxy/views.py
@@ -9,6 +9,7 @@
HttpResponse,
HttpResponseBadRequest,
HttpResponseServerError,
+ JsonResponse,
)
from django.shortcuts import redirect
from django.views.decorators.csrf import csrf_exempt
@@ -325,3 +326,7 @@ def set_temp_storage(request):
)
return HttpResponse(json.dumps(response))
+
+
+def get_frontend_config(_) -> JsonResponse:
+ return JsonResponse(settings.FRONTEND_SETTINGS)
diff --git a/backend/requirements/base.txt b/backend/requirements/base.txt
index 8d87b5de4..0725a0146 100644
--- a/backend/requirements/base.txt
+++ b/backend/requirements/base.txt
@@ -24,6 +24,7 @@ django-allauth==0.54.0 # https://github.com/pennersr/django-allauth
dj-rest-auth==2.2.8 # https://github.com/jazzband/dj-rest-auth
djangorestframework-simplejwt==5.3.1 # https://github.com/SimpleJWT/django-rest-framework-simplejwt/
drf-yasg==1.21.7 # https://github.com/axnsan12/drf-yasg
+django-extensions==3.2.3 # https://github.com/django-extensions/django-extensions
# Code quality
# ------------------------------------------------------------------------------
@@ -34,3 +35,7 @@ pre-commit==3.7.1 # https://github.com/pre-commit/pre-commit
django-model-utils==4.5.1 # https://github.com/jazzband/django-model-utils
django_unique_upload==0.2.1 # https://github.com/agconti/django-unique-upload
globus-sdk==3.46.0
+
+# SBOM
+# ------------------------------------------------------------------------------
+cyclonedx-bom==4.5.0 # https://github.com/CycloneDX/cyclonedx-python/
diff --git a/backend/requirements/local.txt b/backend/requirements/local.txt
index 92e07dbac..a9c6e818a 100644
--- a/backend/requirements/local.txt
+++ b/backend/requirements/local.txt
@@ -17,6 +17,7 @@ pytest-django==4.8.0 # https://github.com/pytest-dev/pytest-django
pytest-sugar==1.0.0 # https://github.com/Frozenball/pytest-sugar
pytest-watch==4.2.0 # https://github.com/joeyespo/pytest-watch
factory-boy==3.3.0 # https://github.com/FactoryBoy/factory_boy
+responses==0.25.0 # https://github.com/getsentry/responses
# Developer Tools
# ------------------------------------------------------------------------------
diff --git a/backend/requirements/production.txt b/backend/requirements/production.txt
deleted file mode 100644
index e9b9b3ea0..000000000
--- a/backend/requirements/production.txt
+++ /dev/null
@@ -1,4 +0,0 @@
--r ./base.txt
-
-# Static and Media Tools
-# ------------------------------------------------------------------------------
diff --git a/docker-compose.prod-overlay.yml b/docker-compose.prod-overlay.yml
new file mode 100644
index 000000000..2bd6ee949
--- /dev/null
+++ b/docker-compose.prod-overlay.yml
@@ -0,0 +1,8 @@
+services:
+ keycloak:
+ command: start
+ volumes: []
+
+ react:
+ build:
+ target: prod
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 000000000..f126819d2
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,88 @@
+networks:
+ metagrid:
+ ipam:
+ config:
+ - subnet: 10.89.9.0/24
+
+volumes:
+ local_postgres_data: {}
+ local_postgres_data_backups: {}
+
+services:
+ postgres:
+ # This service uses the production Postgres Dockerfile as a base
+ # Some tweaks are applied to support the Keycloak service, including the init.sql script
+ build: postgres
+ image: metagrid_local_postgres
+ volumes:
+ - local_postgres_data:/var/lib/postgresql/data
+ - local_postgres_data_backups:/local_postgres_data_backups
+ env_file:
+ - ./metagrid_configs/.local_config
+ ports:
+ - 5432:5432
+ healthcheck:
+ test: [ "CMD", "pg_isready", "-U", "postgres", "-d", "postgres" ]
+ start_period: 5s
+ interval: 5s
+ timeout: 2s
+ retries: 6
+ networks:
+ metagrid:
+ ipv4_address: 10.89.9.81
+ aliases:
+ - postgres
+
+ django:
+ build: backend
+ image: metagrid_local_django
+ depends_on:
+ postgres:
+ condition: service_healthy
+ volumes:
+ - ./backend:/app
+ env_file:
+ - ./metagrid_configs/.local_config
+ ports:
+ - 5000:5000
+ networks:
+ metagrid:
+ ipv4_address: 10.89.9.82
+ aliases:
+ - django
+
+ react:
+ build:
+ context: frontend
+ target: build
+ image: metagrid_local_react
+ environment:
+ - PORT=8080
+ depends_on:
+ - django
+ networks:
+ metagrid:
+ ipv4_address: 10.89.9.83
+ ports:
+ - 8080:8080
+
+ keycloak:
+ image: quay.io/keycloak/keycloak:23.0.6
+ depends_on:
+ - react
+ command: start-dev --import-realm
+ volumes:
+ - ./keycloak/realm.json:/opt/keycloak/data/import/realm.json
+ ports:
+ - 1337:8080
+ networks:
+ metagrid:
+ ipv4_address: 10.89.9.84
+
+ docs:
+ build: docs
+ image: metagrid_local_docs
+ volumes:
+ - ./docs:/docs
+ ports:
+ - "8001:8001"
diff --git a/docs/Dockerfile b/docs/Dockerfile
index 14e6f28fc..64a1efcb8 100644
--- a/docs/Dockerfile
+++ b/docs/Dockerfile
@@ -1,4 +1,4 @@
-FROM python:3.9-slim-buster
+FROM python:3-slim
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
@@ -19,8 +19,8 @@ COPY requirements.txt requirements.txt
# All imports needed for autodoc.
RUN pip install -r requirements.txt
-COPY start /start-docs
-RUN sed -i 's/\r$//g' /start-docs
-RUN chmod +x /start-docs
+WORKDIR /docs
+COPY . .
+RUN mkdocs build --strict
-WORKDIR /docs
\ No newline at end of file
+CMD [ "mkdocs", "serve" ]
\ No newline at end of file
diff --git a/docs/docker-compose.yml b/docs/docker-compose.yml
deleted file mode 100644
index 7e9a80d70..000000000
--- a/docs/docker-compose.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-services:
- docs:
- build:
- context: .
- dockerfile: Dockerfile
- image: metagrid_local_docs
- volumes:
- - ./:/docs
- ports:
- - "8001:8001"
- command: /start-docs
diff --git a/docs/docs/contributors/document.md b/docs/docs/contributors/document.md
index f8b2a3bde..cb83c1ddd 100644
--- a/docs/docs/contributors/document.md
+++ b/docs/docs/contributors/document.md
@@ -2,7 +2,7 @@
This project uses [MkDocs](https://www.mkdocs.org/) documentation generator.
-If you set up your project by walking through [Getting Started For Local Development](../getting_started_local), run the following command:
+If you set up your project by walking through [Getting Started For Local Development](getting_started_local.md), run the following command:
cd docs
docker compose -p metagrid_docs_dev up
diff --git a/docs/docs/contributors/frontend_development.md b/docs/docs/contributors/frontend_development.md
index 358d86226..4ae0aba5b 100644
--- a/docs/docs/contributors/frontend_development.md
+++ b/docs/docs/contributors/frontend_development.md
@@ -124,7 +124,7 @@ frontend
- `assets/` - stores assets used when the app is compiled
- `common/` - stores common code used between components such as utility functions
- `components/` - contains React components and related files.
- Follow [React Components File Structure](#react-components-file-structure)
+ Follow [React Components File Structure](#file-structure)
- `contexts/` - stores React [Context](https://reactjs.org/docs/context.html) components, such as for authentication state
- `lib/` - stores initialized instances of third party library that are exported for use in the codebase (e.g. Axios, Keycloak)
- `test/` - contains related files and functions shared among tests
diff --git a/docs/docs/contributors/getting_started_production.md b/docs/docs/contributors/getting_started_production.md
index c44d09f33..55b67e6a1 100644
--- a/docs/docs/contributors/getting_started_production.md
+++ b/docs/docs/contributors/getting_started_production.md
@@ -80,7 +80,7 @@ DJANGO_SECURE_SSL_REDIRECT=False
# django-cors-headers
-CORS_ORIGIN_WHITELIST=https://localhost:3000,https://esgf-dev1.llnl.gov
+CORS_ORIGIN_WHITELIST=http://localhost:3000,https://esgf-dev1.llnl.gov
# django-all-auth - Configure your Keycloak here
@@ -111,7 +111,7 @@ REACT_APP_METAGRID_API_URL=https://esgf-dev1.llnl.gov/metagrid-backend
# Globus
REACT_APP_GLOBUS_REDIRECT=https://esgf-dev1.llnl.gov/cart/items
-REACT_APP_CLIENT_ID= # Generate a client ID at Globus for your Native App
+REACT_APP_GLOBUS_CLIENT_ID= # Generate a client ID at Globus for your Native App
REACT_APP_GLOBUS_NODES=aims3.llnl.gov,esgf-data1.llnl.gov,esgf-data2.llnl.gov
# ESGF wget API
diff --git a/docs/docs/contributors/project_standards.md b/docs/docs/contributors/project_standards.md
index ac8bed786..513b0a85a 100644
--- a/docs/docs/contributors/project_standards.md
+++ b/docs/docs/contributors/project_standards.md
@@ -11,7 +11,7 @@ GitHub Flow aligns with **continuous delivery** of modern web applications where
### How to Use GitHub Flow
-![GitHub Flow Diagram](https://i.stack.imgur.com/ChShh.png)
+![GitHub Flow Diagram](../images/gitflow.png)
1. Fork the repo and create a support branch
- Forking ensures the upstream repository can only be affected through a pull request (PR)
@@ -162,7 +162,7 @@ Source: [https://blog.carbonfive.com/always-squash-and-rebase-your-git-commits/]
##### Ways to Run Tools
-1. Using `pre-commit` - recommend in most cases, commands found [here](../getting_started_local#helpful-commands)
+1. Using `pre-commit` - recommend in most cases, commands found [here](getting_started_local.md#23-helpful-commands)
2. Using IDE/text editor - recommended alongside #1 for integrated linting and formatting, only VSCode `settings.json` file provided for configuration
3. Using terminal to run standalone tool - useful to test configs. Visit the tool's site for a list of commands
diff --git a/docs/docs/html/.buildinfo b/docs/docs/html/.buildinfo
deleted file mode 100644
index 2429ced35..000000000
--- a/docs/docs/html/.buildinfo
+++ /dev/null
@@ -1,4 +0,0 @@
-# Sphinx build info version 1
-# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
-config: 0d1c191be2e284dd0f4e95b8e803e0f1
-tags: 645f666f9bcd5a90fca523b33c5a78b7
diff --git a/docs/docs/html/.doctrees/api.doctree b/docs/docs/html/.doctrees/api.doctree
deleted file mode 100644
index cafc89c1d..000000000
Binary files a/docs/docs/html/.doctrees/api.doctree and /dev/null differ
diff --git a/docs/docs/html/.doctrees/dev/architecture_and_scaffolding.doctree b/docs/docs/html/.doctrees/dev/architecture_and_scaffolding.doctree
deleted file mode 100644
index e02d13d22..000000000
Binary files a/docs/docs/html/.doctrees/dev/architecture_and_scaffolding.doctree and /dev/null differ
diff --git a/docs/docs/html/.doctrees/dev/contributing.doctree b/docs/docs/html/.doctrees/dev/contributing.doctree
deleted file mode 100644
index 6716d2bda..000000000
Binary files a/docs/docs/html/.doctrees/dev/contributing.doctree and /dev/null differ
diff --git a/docs/docs/html/.doctrees/dev/how_to_document.doctree b/docs/docs/html/.doctrees/dev/how_to_document.doctree
deleted file mode 100644
index 6ef94ed04..000000000
Binary files a/docs/docs/html/.doctrees/dev/how_to_document.doctree and /dev/null differ
diff --git a/docs/docs/html/.doctrees/dev/howto.doctree b/docs/docs/html/.doctrees/dev/howto.doctree
deleted file mode 100644
index fa073900f..000000000
Binary files a/docs/docs/html/.doctrees/dev/howto.doctree and /dev/null differ
diff --git a/docs/docs/html/.doctrees/dev/howtodocument.doctree b/docs/docs/html/.doctrees/dev/howtodocument.doctree
deleted file mode 100644
index 50a5d6666..000000000
Binary files a/docs/docs/html/.doctrees/dev/howtodocument.doctree and /dev/null differ
diff --git a/docs/docs/html/.doctrees/dev/styling_and_linting.doctree b/docs/docs/html/.doctrees/dev/styling_and_linting.doctree
deleted file mode 100644
index 5d063b912..000000000
Binary files a/docs/docs/html/.doctrees/dev/styling_and_linting.doctree and /dev/null differ
diff --git a/docs/docs/html/.doctrees/environment.pickle b/docs/docs/html/.doctrees/environment.pickle
deleted file mode 100644
index ac4786b01..000000000
Binary files a/docs/docs/html/.doctrees/environment.pickle and /dev/null differ
diff --git a/docs/docs/html/.doctrees/howto.doctree b/docs/docs/html/.doctrees/howto.doctree
deleted file mode 100644
index d4d12a8d4..000000000
Binary files a/docs/docs/html/.doctrees/howto.doctree and /dev/null differ
diff --git a/docs/docs/html/.doctrees/index.doctree b/docs/docs/html/.doctrees/index.doctree
deleted file mode 100644
index 6c81ee151..000000000
Binary files a/docs/docs/html/.doctrees/index.doctree and /dev/null differ
diff --git a/docs/docs/html/.doctrees/user/api.doctree b/docs/docs/html/.doctrees/user/api.doctree
deleted file mode 100644
index f6e024f12..000000000
Binary files a/docs/docs/html/.doctrees/user/api.doctree and /dev/null differ
diff --git a/docs/docs/html/.doctrees/users.doctree b/docs/docs/html/.doctrees/users.doctree
deleted file mode 100644
index cab563c1b..000000000
Binary files a/docs/docs/html/.doctrees/users.doctree and /dev/null differ
diff --git a/docs/docs/html/_sources/api.rst.txt b/docs/docs/html/_sources/api.rst.txt
deleted file mode 100644
index 563aefe54..000000000
--- a/docs/docs/html/_sources/api.rst.txt
+++ /dev/null
@@ -1,15 +0,0 @@
- .. _api:
-
-Users
-======================================================================
-
-Starting a new project, it’s highly recommended to set up a custom user model,
-even if the default User model is sufficient for you.
-
-This model behaves identically to the default user model,
-but you’ll be able to customize it in the future if the need arises.
-
-.. automodule:: metagrid.users.models
- :members:
- :noindex:
-
diff --git a/docs/docs/html/_sources/dev/architecture_and_scaffolding.rst.txt b/docs/docs/html/_sources/dev/architecture_and_scaffolding.rst.txt
deleted file mode 100644
index 2dcbef9c9..000000000
--- a/docs/docs/html/_sources/dev/architecture_and_scaffolding.rst.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-.. _architecture_and_scaffolding:
-
-Architecture and Scaffolding
-======================================================================
-
-Repositories
-Link: https://github.com/aims-group/metagrid
-
-Project Stack
-
-- Python >= 3.8
-- Django > 3.x
-- Django REST Framework
-- PostgreSQL
-
-
-Architecture Diagram
-
-..
- _TODO: Add architecture diagram
-
-Django serves REST APIs, which send data and receive responses via REST API endpoints. Typically, the response is in the form of JSON.
-
-Django Project Scaffolding
\ No newline at end of file
diff --git a/docs/docs/html/_sources/dev/contributing.rst.txt b/docs/docs/html/_sources/dev/contributing.rst.txt
deleted file mode 100644
index 6560d29c6..000000000
--- a/docs/docs/html/_sources/dev/contributing.rst.txt
+++ /dev/null
@@ -1,208 +0,0 @@
-.. _contributing:
-
-Contributor's Guide
-===================
-
-If you're reading this, you're probably interested in contributing to Requests.
-Thank you very much! Open source projects live-and-die based on the support
-they receive from others, and the fact that you're even considering
-contributing to the Requests project is *very* generous of you.
-
-This document lays out guidelines and advice for contributing to this project.
-If you're thinking of contributing, please start by reading this document and
-getting a feel for how contributing to this project works. If you have any
-questions, feel free to reach out to either `Nate Prewitt`_, `Ian Cordasco`_,
-or `Seth Michael Larson`_, the primary maintainers.
-
-.. _Ian Cordasco: http://www.coglib.com/~icordasc/
-.. _Nate Prewitt: https://www.nateprewitt.com/
-.. _Seth Michael Larson: https://sethmlarson.dev/
-
-The guide is split into sections based on the type of contribution you're
-thinking of making, with a section that covers general guidelines for all
-contributors.
-
-Be Cordial
-----------
-
- **Be cordial or be on your way**. *—Kenneth Reitz*
-
-Requests has one very important rule governing all forms of contribution,
-including reporting bugs or requesting features. This golden rule is
-"`be cordial or be on your way`_".
-
-**All contributions are welcome**, as long as
-everyone involved is treated with respect.
-
-.. _be cordial or be on your way: https://www.kennethreitz.org/essays/be-cordial-or-be-on-your-way
-
-.. _early-feedback:
-
-Get Early Feedback
-------------------
-
-If you are contributing, do not feel the need to sit on your contribution until
-it is perfectly polished and complete. It helps everyone involved for you to
-seek feedback as early as you possibly can. Submitting an early, unfinished
-version of your contribution for feedback in no way prejudices your chances of
-getting that contribution accepted, and can save you from putting a lot of work
-into a contribution that is not suitable for the project.
-
-Contribution Suitability
-------------------------
-
-Our project maintainers have the last word on whether or not a contribution is
-suitable for Requests. All contributions will be considered carefully, but from
-time to time, contributions will be rejected because they do not suit the
-current goals or needs of the project.
-
-If your contribution is rejected, don't despair! As long as you followed these
-guidelines, you will have a much better chance of getting your next
-contribution accepted.
-
-
-Code Contributions
-------------------
-
-Steps for Submitting Code
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When contributing code, you'll want to follow this checklist:
-
-1. Fork the repository on GitHub.
-2. Run the tests to confirm they all pass on your system. If they don't, you'll
- need to investigate why they fail. If you're unable to diagnose this
- yourself, raise it as a bug report by following the guidelines in this
- document: :ref:`bug-reports`.
-3. Write tests that demonstrate your bug or feature. Ensure that they fail.
-4. Make your change.
-5. Run the entire test suite again, confirming that all tests pass *including
- the ones you just added*.
-6. Send a GitHub Pull Request to the main repository's ``master`` branch.
- GitHub Pull Requests are the expected method of code collaboration on this
- project.
-
-The following sub-sections go into more detail on some of the points above.
-
-Code Review
-~~~~~~~~~~~
-
-Contributions will not be merged until they've been code reviewed. You should
-implement any code review feedback unless you strongly object to it. In the
-event that you object to the code review feedback, you should make your case
-clearly and calmly. If, after doing so, the feedback is judged to still apply,
-you must either apply the feedback or withdraw your contribution.
-
-New Contributors
-~~~~~~~~~~~~~~~~
-
-If you are new or relatively new to Open Source, welcome! Requests aims to
-be a gentle introduction to the world of Open Source. If you're concerned about
-how best to contribute, please consider mailing a maintainer (listed above) and
-asking for help.
-
-Please also check the :ref:`early-feedback` section.
-
-Kenneth Reitz's Code Style™
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The Requests codebase uses the `PEP 8`_ code style.
-
-In addition to the standards outlined in PEP 8, we have a few guidelines:
-
-- Line-length can exceed 79 characters, to 100, when convenient.
-- Line-length can exceed 100 characters, when doing otherwise would be *terribly* inconvenient.
-- Always use single-quoted strings (e.g. ``'#flatearth'``), unless a single-quote occurs within the string.
-
-Additionally, one of the styles that PEP8 recommends for `line continuations`_
-completely lacks all sense of taste, and is not to be permitted within
-the Requests codebase::
-
- # Aligned with opening delimiter.
- foo = long_function_name(var_one, var_two,
- var_three, var_four)
-
-No. Just don't. Please. This is much better::
-
- foo = long_function_name(
- var_one,
- var_two,
- var_three,
- var_four,
- )
-
-Docstrings are to follow the following syntaxes::
-
- def the_earth_is_flat():
- """NASA divided up the seas into thirty-three degrees."""
- pass
-
-::
-
- def fibonacci_spiral_tool():
- """With my feet upon the ground I lose myself / between the sounds
- and open wide to suck it in. / I feel it move across my skin. / I'm
- reaching up and reaching out. / I'm reaching for the random or
- whatever will bewilder me. / Whatever will bewilder me. / And
- following our will and wind we may just go where no one's been. /
- We'll ride the spiral to the end and may just go where no one's
- been.
-
- Spiral out. Keep going...
- """
- pass
-
-All functions, methods, and classes are to contain docstrings. Object data
-model methods (e.g. ``__repr__``) are typically the exception to this rule.
-
-Thanks for helping to make the world a better place!
-
-.. _PEP 8: https://pep8.org/
-.. _line continuations: https://www.python.org/dev/peps/pep-0008/#indentation
-
-Documentation Contributions
----------------------------
-
-Documentation improvements are always welcome! The documentation files live in
-the ``docs/`` directory of the codebase. They're written in
-`reStructuredText`_, and use `Sphinx`_ to generate the full suite of
-documentation.
-
-When contributing documentation, please do your best to follow the style of the
-documentation files. This means a soft-limit of 79 characters wide in your text
-files and a semi-formal, yet friendly and approachable, prose style.
-
-When presenting Python code, use single-quoted strings (``'hello'`` instead of
-``"hello"``).
-
-.. _reStructuredText: http://docutils.sourceforge.net/rst.html
-.. _Sphinx: http://sphinx-doc.org/index.html
-
-
-.. _bug-reports:
-
-Bug Reports
------------
-
-Bug reports are hugely important! Before you raise one, though, please check
-through the `GitHub issues`_, **both open and closed**, to confirm that the bug
-hasn't been reported before. Duplicate bug reports are a huge drain on the time
-of other contributors, and should be avoided as much as possible.
-
-.. _GitHub issues: https://github.com/psf/requests/issues
-
-
-Feature Requests
-----------------
-
-Requests is in a perpetual feature freeze, only the BDFL can add or approve of
-new features. The maintainers believe that Requests is a feature-complete
-piece of software at this time.
-
-One of the most important skills to have while maintaining a largely-used
-open source project is learning the ability to say "no" to suggested changes,
-while keeping an open ear and mind.
-
-If you believe there is a feature missing, feel free to raise a feature
-request, but please do be aware that the overwhelming likelihood is that your
-feature request will not be accepted.
\ No newline at end of file
diff --git a/docs/docs/html/_sources/dev/how_to_document.rst.txt b/docs/docs/html/_sources/dev/how_to_document.rst.txt
deleted file mode 100644
index aadf59168..000000000
--- a/docs/docs/html/_sources/dev/how_to_document.rst.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-.. _how_to_document:
-
-How To - Project Documentation
-======================================================================
-
-Get Started
-----------------------------------------------------------------------
-
-Documentation can be written as rst files in the `metagrid/docs/_source`.
-
-
-To build and serve docs, use the commands:
- ::
-
- docker compose -f local.yml up docs
-
-
-Changes to files in `docs/_source` will be picked up and reloaded automatically.
-
-`Sphinx `_ is the tool used to build documentation.
-
-Docstrings to Documentation
-----------------------------------------------------------------------
-
-The sphinx extension `apidoc `_ is used to automatically document code using signatures and docstrings.
-
-Numpy or Google style docstrings will be picked up from project files and availble for documentation. See the `Napoleon `_ extension for details.
-
-For an in-use example, see the `page source <_sources/users.rst.txt>`_ for :ref:`users`.
-
-To compile all docstrings automatically into documentation source files, use the command:
- ::
-
- make apidocs
-
-
-This can be done in the docker container:
- ::
-
- docker run --rm docs make apidocs
diff --git a/docs/docs/html/_sources/dev/howto.rst.txt b/docs/docs/html/_sources/dev/howto.rst.txt
deleted file mode 100644
index 2a561f478..000000000
--- a/docs/docs/html/_sources/dev/howto.rst.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-How To - Project Documentation
-======================================================================
-
-Get Started
-----------------------------------------------------------------------
-
-Documentation can be written as rst files in the `metagrid/docs/_source`.
-
-
-To build and serve docs, use the commands:
- ::
-
- docker compose -f local.yml up docs
-
-
-Changes to files in `docs/_source` will be picked up and reloaded automatically.
-
-`Sphinx `_ is the tool used to build documentation.
-
-Docstrings to Documentation
-----------------------------------------------------------------------
-
-The sphinx extension `apidoc `_ is used to automatically document code using signatures and docstrings.
-
-Numpy or Google style docstrings will be picked up from project files and availble for documentation. See the `Napoleon `_ extension for details.
-
-For an in-use example, see the `page source <_sources/users.rst.txt>`_ for :ref:`users`.
-
-To compile all docstrings automatically into documentation source files, use the command:
- ::
-
- make apidocs
-
-
-This can be done in the docker container:
- ::
-
- docker run --rm docs make apidocs
diff --git a/docs/docs/html/_sources/dev/howtodocument.rst.txt b/docs/docs/html/_sources/dev/howtodocument.rst.txt
deleted file mode 100644
index 2a561f478..000000000
--- a/docs/docs/html/_sources/dev/howtodocument.rst.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-How To - Project Documentation
-======================================================================
-
-Get Started
-----------------------------------------------------------------------
-
-Documentation can be written as rst files in the `metagrid/docs/_source`.
-
-
-To build and serve docs, use the commands:
- ::
-
- docker compose -f local.yml up docs
-
-
-Changes to files in `docs/_source` will be picked up and reloaded automatically.
-
-`Sphinx `_ is the tool used to build documentation.
-
-Docstrings to Documentation
-----------------------------------------------------------------------
-
-The sphinx extension `apidoc `_ is used to automatically document code using signatures and docstrings.
-
-Numpy or Google style docstrings will be picked up from project files and availble for documentation. See the `Napoleon `_ extension for details.
-
-For an in-use example, see the `page source <_sources/users.rst.txt>`_ for :ref:`users`.
-
-To compile all docstrings automatically into documentation source files, use the command:
- ::
-
- make apidocs
-
-
-This can be done in the docker container:
- ::
-
- docker run --rm docs make apidocs
diff --git a/docs/docs/html/_sources/dev/styling_and_linting.rst.txt b/docs/docs/html/_sources/dev/styling_and_linting.rst.txt
deleted file mode 100644
index e3bba5871..000000000
--- a/docs/docs/html/_sources/dev/styling_and_linting.rst.txt
+++ /dev/null
@@ -1 +0,0 @@
-.. _styling_and_linting:
\ No newline at end of file
diff --git a/docs/docs/html/_sources/howto.rst.txt b/docs/docs/html/_sources/howto.rst.txt
deleted file mode 100644
index 2a561f478..000000000
--- a/docs/docs/html/_sources/howto.rst.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-How To - Project Documentation
-======================================================================
-
-Get Started
-----------------------------------------------------------------------
-
-Documentation can be written as rst files in the `metagrid/docs/_source`.
-
-
-To build and serve docs, use the commands:
- ::
-
- docker compose -f local.yml up docs
-
-
-Changes to files in `docs/_source` will be picked up and reloaded automatically.
-
-`Sphinx `_ is the tool used to build documentation.
-
-Docstrings to Documentation
-----------------------------------------------------------------------
-
-The sphinx extension `apidoc `_ is used to automatically document code using signatures and docstrings.
-
-Numpy or Google style docstrings will be picked up from project files and availble for documentation. See the `Napoleon `_ extension for details.
-
-For an in-use example, see the `page source <_sources/users.rst.txt>`_ for :ref:`users`.
-
-To compile all docstrings automatically into documentation source files, use the command:
- ::
-
- make apidocs
-
-
-This can be done in the docker container:
- ::
-
- docker run --rm docs make apidocs
diff --git a/docs/docs/html/_sources/index.rst.txt b/docs/docs/html/_sources/index.rst.txt
deleted file mode 100644
index c0aef8e11..000000000
--- a/docs/docs/html/_sources/index.rst.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-.. MetaGrid documentation master file, created by
- sphinx-quickstart on Thu Jan 7 11:03:02 2021.
- You can adapt this file completely to your liking, but it should at least
- contain the root `toctree` directive.
-
-Welcome to MetaGrid API's documentation!
-====================================
-
-API Documentation
---------------
-
-This project uses drf-yasg_ to generate OpenAPI Swagger documentation.
-Please visit the '/swagger' endpoint for more information on how to use the MetaGrid API.
-
-.. _drf-yasg: https://drf-yasg.readthedocs.io/en/stable/readme.html
-
-
-Contributor Guide
----------------------
-
-If you want to contribute to the project, this part of the documentation is for
-you.
-
-.. toctree::
- :maxdepth: 3
-
- dev/architecture_and_scaffolding
- dev/contributing
- dev/how_to_document
- dev/building_local
- dev/building_production
-
-Helpful Links
-- Django
-- Django REST Framework
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
diff --git a/docs/docs/html/_sources/user/api.rst.txt b/docs/docs/html/_sources/user/api.rst.txt
deleted file mode 100644
index e69de29bb..000000000
diff --git a/docs/docs/html/_sources/users.rst.txt b/docs/docs/html/_sources/users.rst.txt
deleted file mode 100644
index 3ecd1fc72..000000000
--- a/docs/docs/html/_sources/users.rst.txt
+++ /dev/null
@@ -1,15 +0,0 @@
- .. _users:
-
-Users
-======================================================================
-
-Starting a new project, it’s highly recommended to set up a custom user model,
-even if the default User model is sufficient for you.
-
-This model behaves identically to the default user model,
-but you’ll be able to customize it in the future if the need arises.
-
-.. automodule:: metagrid.users.models
- :members:
- :noindex:
-
diff --git a/docs/docs/html/_static/alabaster.css b/docs/docs/html/_static/alabaster.css
deleted file mode 100644
index 0eddaeb07..000000000
--- a/docs/docs/html/_static/alabaster.css
+++ /dev/null
@@ -1,701 +0,0 @@
-@import url("basic.css");
-
-/* -- page layout ----------------------------------------------------------- */
-
-body {
- font-family: Georgia, serif;
- font-size: 17px;
- background-color: #fff;
- color: #000;
- margin: 0;
- padding: 0;
-}
-
-
-div.document {
- width: 940px;
- margin: 30px auto 0 auto;
-}
-
-div.documentwrapper {
- float: left;
- width: 100%;
-}
-
-div.bodywrapper {
- margin: 0 0 0 220px;
-}
-
-div.sphinxsidebar {
- width: 220px;
- font-size: 14px;
- line-height: 1.5;
-}
-
-hr {
- border: 1px solid #B1B4B6;
-}
-
-div.body {
- background-color: #fff;
- color: #3E4349;
- padding: 0 30px 0 30px;
-}
-
-div.body > .section {
- text-align: left;
-}
-
-div.footer {
- width: 940px;
- margin: 20px auto 30px auto;
- font-size: 14px;
- color: #888;
- text-align: right;
-}
-
-div.footer a {
- color: #888;
-}
-
-p.caption {
- font-family: inherit;
- font-size: inherit;
-}
-
-
-div.relations {
- display: none;
-}
-
-
-div.sphinxsidebar a {
- color: #444;
- text-decoration: none;
- border-bottom: 1px dotted #999;
-}
-
-div.sphinxsidebar a:hover {
- border-bottom: 1px solid #999;
-}
-
-div.sphinxsidebarwrapper {
- padding: 18px 10px;
-}
-
-div.sphinxsidebarwrapper p.logo {
- padding: 0;
- margin: -10px 0 0 0px;
- text-align: center;
-}
-
-div.sphinxsidebarwrapper h1.logo {
- margin-top: -10px;
- text-align: center;
- margin-bottom: 5px;
- text-align: left;
-}
-
-div.sphinxsidebarwrapper h1.logo-name {
- margin-top: 0px;
-}
-
-div.sphinxsidebarwrapper p.blurb {
- margin-top: 0;
- font-style: normal;
-}
-
-div.sphinxsidebar h3,
-div.sphinxsidebar h4 {
- font-family: Georgia, serif;
- color: #444;
- font-size: 24px;
- font-weight: normal;
- margin: 0 0 5px 0;
- padding: 0;
-}
-
-div.sphinxsidebar h4 {
- font-size: 20px;
-}
-
-div.sphinxsidebar h3 a {
- color: #444;
-}
-
-div.sphinxsidebar p.logo a,
-div.sphinxsidebar h3 a,
-div.sphinxsidebar p.logo a:hover,
-div.sphinxsidebar h3 a:hover {
- border: none;
-}
-
-div.sphinxsidebar p {
- color: #555;
- margin: 10px 0;
-}
-
-div.sphinxsidebar ul {
- margin: 10px 0;
- padding: 0;
- color: #000;
-}
-
-div.sphinxsidebar ul li.toctree-l1 > a {
- font-size: 120%;
-}
-
-div.sphinxsidebar ul li.toctree-l2 > a {
- font-size: 110%;
-}
-
-div.sphinxsidebar input {
- border: 1px solid #CCC;
- font-family: Georgia, serif;
- font-size: 1em;
-}
-
-div.sphinxsidebar hr {
- border: none;
- height: 1px;
- color: #AAA;
- background: #AAA;
-
- text-align: left;
- margin-left: 0;
- width: 50%;
-}
-
-div.sphinxsidebar .badge {
- border-bottom: none;
-}
-
-div.sphinxsidebar .badge:hover {
- border-bottom: none;
-}
-
-/* To address an issue with donation coming after search */
-div.sphinxsidebar h3.donation {
- margin-top: 10px;
-}
-
-/* -- body styles ----------------------------------------------------------- */
-
-a {
- color: #004B6B;
- text-decoration: underline;
-}
-
-a:hover {
- color: #6D4100;
- text-decoration: underline;
-}
-
-div.body h1,
-div.body h2,
-div.body h3,
-div.body h4,
-div.body h5,
-div.body h6 {
- font-family: Georgia, serif;
- font-weight: normal;
- margin: 30px 0px 10px 0px;
- padding: 0;
-}
-
-div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
-div.body h2 { font-size: 180%; }
-div.body h3 { font-size: 150%; }
-div.body h4 { font-size: 130%; }
-div.body h5 { font-size: 100%; }
-div.body h6 { font-size: 100%; }
-
-a.headerlink {
- color: #DDD;
- padding: 0 4px;
- text-decoration: none;
-}
-
-a.headerlink:hover {
- color: #444;
- background: #EAEAEA;
-}
-
-div.body p, div.body dd, div.body li {
- line-height: 1.4em;
-}
-
-div.admonition {
- margin: 20px 0px;
- padding: 10px 30px;
- background-color: #EEE;
- border: 1px solid #CCC;
-}
-
-div.admonition tt.xref, div.admonition code.xref, div.admonition a tt {
- background-color: #FBFBFB;
- border-bottom: 1px solid #fafafa;
-}
-
-div.admonition p.admonition-title {
- font-family: Georgia, serif;
- font-weight: normal;
- font-size: 24px;
- margin: 0 0 10px 0;
- padding: 0;
- line-height: 1;
-}
-
-div.admonition p.last {
- margin-bottom: 0;
-}
-
-div.highlight {
- background-color: #fff;
-}
-
-dt:target, .highlight {
- background: #FAF3E8;
-}
-
-div.warning {
- background-color: #FCC;
- border: 1px solid #FAA;
-}
-
-div.danger {
- background-color: #FCC;
- border: 1px solid #FAA;
- -moz-box-shadow: 2px 2px 4px #D52C2C;
- -webkit-box-shadow: 2px 2px 4px #D52C2C;
- box-shadow: 2px 2px 4px #D52C2C;
-}
-
-div.error {
- background-color: #FCC;
- border: 1px solid #FAA;
- -moz-box-shadow: 2px 2px 4px #D52C2C;
- -webkit-box-shadow: 2px 2px 4px #D52C2C;
- box-shadow: 2px 2px 4px #D52C2C;
-}
-
-div.caution {
- background-color: #FCC;
- border: 1px solid #FAA;
-}
-
-div.attention {
- background-color: #FCC;
- border: 1px solid #FAA;
-}
-
-div.important {
- background-color: #EEE;
- border: 1px solid #CCC;
-}
-
-div.note {
- background-color: #EEE;
- border: 1px solid #CCC;
-}
-
-div.tip {
- background-color: #EEE;
- border: 1px solid #CCC;
-}
-
-div.hint {
- background-color: #EEE;
- border: 1px solid #CCC;
-}
-
-div.seealso {
- background-color: #EEE;
- border: 1px solid #CCC;
-}
-
-div.topic {
- background-color: #EEE;
-}
-
-p.admonition-title {
- display: inline;
-}
-
-p.admonition-title:after {
- content: ":";
-}
-
-pre, tt, code {
- font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
- font-size: 0.9em;
-}
-
-.hll {
- background-color: #FFC;
- margin: 0 -12px;
- padding: 0 12px;
- display: block;
-}
-
-img.screenshot {
-}
-
-tt.descname, tt.descclassname, code.descname, code.descclassname {
- font-size: 0.95em;
-}
-
-tt.descname, code.descname {
- padding-right: 0.08em;
-}
-
-img.screenshot {
- -moz-box-shadow: 2px 2px 4px #EEE;
- -webkit-box-shadow: 2px 2px 4px #EEE;
- box-shadow: 2px 2px 4px #EEE;
-}
-
-table.docutils {
- border: 1px solid #888;
- -moz-box-shadow: 2px 2px 4px #EEE;
- -webkit-box-shadow: 2px 2px 4px #EEE;
- box-shadow: 2px 2px 4px #EEE;
-}
-
-table.docutils td, table.docutils th {
- border: 1px solid #888;
- padding: 0.25em 0.7em;
-}
-
-table.field-list, table.footnote {
- border: none;
- -moz-box-shadow: none;
- -webkit-box-shadow: none;
- box-shadow: none;
-}
-
-table.footnote {
- margin: 15px 0;
- width: 100%;
- border: 1px solid #EEE;
- background: #FDFDFD;
- font-size: 0.9em;
-}
-
-table.footnote + table.footnote {
- margin-top: -15px;
- border-top: none;
-}
-
-table.field-list th {
- padding: 0 0.8em 0 0;
-}
-
-table.field-list td {
- padding: 0;
-}
-
-table.field-list p {
- margin-bottom: 0.8em;
-}
-
-/* Cloned from
- * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68
- */
-.field-name {
- -moz-hyphens: manual;
- -ms-hyphens: manual;
- -webkit-hyphens: manual;
- hyphens: manual;
-}
-
-table.footnote td.label {
- width: .1px;
- padding: 0.3em 0 0.3em 0.5em;
-}
-
-table.footnote td {
- padding: 0.3em 0.5em;
-}
-
-dl {
- margin: 0;
- padding: 0;
-}
-
-dl dd {
- margin-left: 30px;
-}
-
-blockquote {
- margin: 0 0 0 30px;
- padding: 0;
-}
-
-ul, ol {
- /* Matches the 30px from the narrow-screen "li > ul" selector below */
- margin: 10px 0 10px 30px;
- padding: 0;
-}
-
-pre {
- background: #EEE;
- padding: 7px 30px;
- margin: 15px 0px;
- line-height: 1.3em;
-}
-
-div.viewcode-block:target {
- background: #ffd;
-}
-
-dl pre, blockquote pre, li pre {
- margin-left: 0;
- padding-left: 30px;
-}
-
-tt, code {
- background-color: #ecf0f3;
- color: #222;
- /* padding: 1px 2px; */
-}
-
-tt.xref, code.xref, a tt {
- background-color: #FBFBFB;
- border-bottom: 1px solid #fff;
-}
-
-a.reference {
- text-decoration: none;
- border-bottom: 1px dotted #004B6B;
-}
-
-/* Don't put an underline on images */
-a.image-reference, a.image-reference:hover {
- border-bottom: none;
-}
-
-a.reference:hover {
- border-bottom: 1px solid #6D4100;
-}
-
-a.footnote-reference {
- text-decoration: none;
- font-size: 0.7em;
- vertical-align: top;
- border-bottom: 1px dotted #004B6B;
-}
-
-a.footnote-reference:hover {
- border-bottom: 1px solid #6D4100;
-}
-
-a:hover tt, a:hover code {
- background: #EEE;
-}
-
-
-@media screen and (max-width: 870px) {
-
- div.sphinxsidebar {
- display: none;
- }
-
- div.document {
- width: 100%;
-
- }
-
- div.documentwrapper {
- margin-left: 0;
- margin-top: 0;
- margin-right: 0;
- margin-bottom: 0;
- }
-
- div.bodywrapper {
- margin-top: 0;
- margin-right: 0;
- margin-bottom: 0;
- margin-left: 0;
- }
-
- ul {
- margin-left: 0;
- }
-
- li > ul {
- /* Matches the 30px from the "ul, ol" selector above */
- margin-left: 30px;
- }
-
- .document {
- width: auto;
- }
-
- .footer {
- width: auto;
- }
-
- .bodywrapper {
- margin: 0;
- }
-
- .footer {
- width: auto;
- }
-
- .github {
- display: none;
- }
-
-
-
-}
-
-
-
-@media screen and (max-width: 875px) {
-
- body {
- margin: 0;
- padding: 20px 30px;
- }
-
- div.documentwrapper {
- float: none;
- background: #fff;
- }
-
- div.sphinxsidebar {
- display: block;
- float: none;
- width: 102.5%;
- margin: 50px -30px -20px -30px;
- padding: 10px 20px;
- background: #333;
- color: #FFF;
- }
-
- div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
- div.sphinxsidebar h3 a {
- color: #fff;
- }
-
- div.sphinxsidebar a {
- color: #AAA;
- }
-
- div.sphinxsidebar p.logo {
- display: none;
- }
-
- div.document {
- width: 100%;
- margin: 0;
- }
-
- div.footer {
- display: none;
- }
-
- div.bodywrapper {
- margin: 0;
- }
-
- div.body {
- min-height: 0;
- padding: 0;
- }
-
- .rtd_doc_footer {
- display: none;
- }
-
- .document {
- width: auto;
- }
-
- .footer {
- width: auto;
- }
-
- .footer {
- width: auto;
- }
-
- .github {
- display: none;
- }
-}
-
-
-/* misc. */
-
-.revsys-inline {
- display: none!important;
-}
-
-/* Make nested-list/multi-paragraph items look better in Releases changelog
- * pages. Without this, docutils' magical list fuckery causes inconsistent
- * formatting between different release sub-lists.
- */
-div#changelog > div.section > ul > li > p:only-child {
- margin-bottom: 0;
-}
-
-/* Hide fugly table cell borders in ..bibliography:: directive output */
-table.docutils.citation, table.docutils.citation td, table.docutils.citation th {
- border: none;
- /* Below needed in some edge cases; if not applied, bottom shadows appear */
- -moz-box-shadow: none;
- -webkit-box-shadow: none;
- box-shadow: none;
-}
-
-
-/* relbar */
-
-.related {
- line-height: 30px;
- width: 100%;
- font-size: 0.9rem;
-}
-
-.related.top {
- border-bottom: 1px solid #EEE;
- margin-bottom: 20px;
-}
-
-.related.bottom {
- border-top: 1px solid #EEE;
-}
-
-.related ul {
- padding: 0;
- margin: 0;
- list-style: none;
-}
-
-.related li {
- display: inline;
-}
-
-nav#rellinks {
- float: right;
-}
-
-nav#rellinks li+li:before {
- content: "|";
-}
-
-nav#breadcrumbs li+li:before {
- content: "\00BB";
-}
-
-/* Hide certain items when printing */
-@media print {
- div.related {
- display: none;
- }
-}
\ No newline at end of file
diff --git a/docs/docs/html/_static/basic.css b/docs/docs/html/_static/basic.css
deleted file mode 100644
index be19270e4..000000000
--- a/docs/docs/html/_static/basic.css
+++ /dev/null
@@ -1,856 +0,0 @@
-/*
- * basic.css
- * ~~~~~~~~~
- *
- * Sphinx stylesheet -- basic theme.
- *
- * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-
-/* -- main layout ----------------------------------------------------------- */
-
-div.clearer {
- clear: both;
-}
-
-div.section::after {
- display: block;
- content: '';
- clear: left;
-}
-
-/* -- relbar ---------------------------------------------------------------- */
-
-div.related {
- width: 100%;
- font-size: 90%;
-}
-
-div.related h3 {
- display: none;
-}
-
-div.related ul {
- margin: 0;
- padding: 0 0 0 10px;
- list-style: none;
-}
-
-div.related li {
- display: inline;
-}
-
-div.related li.right {
- float: right;
- margin-right: 5px;
-}
-
-/* -- sidebar --------------------------------------------------------------- */
-
-div.sphinxsidebarwrapper {
- padding: 10px 5px 0 10px;
-}
-
-div.sphinxsidebar {
- float: left;
- width: 230px;
- margin-left: -100%;
- font-size: 90%;
- word-wrap: break-word;
- overflow-wrap : break-word;
-}
-
-div.sphinxsidebar ul {
- list-style: none;
-}
-
-div.sphinxsidebar ul ul,
-div.sphinxsidebar ul.want-points {
- margin-left: 20px;
- list-style: square;
-}
-
-div.sphinxsidebar ul ul {
- margin-top: 0;
- margin-bottom: 0;
-}
-
-div.sphinxsidebar form {
- margin-top: 10px;
-}
-
-div.sphinxsidebar input {
- border: 1px solid #98dbcc;
- font-family: sans-serif;
- font-size: 1em;
-}
-
-div.sphinxsidebar #searchbox form.search {
- overflow: hidden;
-}
-
-div.sphinxsidebar #searchbox input[type="text"] {
- float: left;
- width: 80%;
- padding: 0.25em;
- box-sizing: border-box;
-}
-
-div.sphinxsidebar #searchbox input[type="submit"] {
- float: left;
- width: 20%;
- border-left: none;
- padding: 0.25em;
- box-sizing: border-box;
-}
-
-
-img {
- border: 0;
- max-width: 100%;
-}
-
-/* -- search page ----------------------------------------------------------- */
-
-ul.search {
- margin: 10px 0 0 20px;
- padding: 0;
-}
-
-ul.search li {
- padding: 5px 0 5px 20px;
- background-image: url(file.png);
- background-repeat: no-repeat;
- background-position: 0 7px;
-}
-
-ul.search li a {
- font-weight: bold;
-}
-
-ul.search li div.context {
- color: #888;
- margin: 2px 0 0 30px;
- text-align: left;
-}
-
-ul.keywordmatches li.goodmatch a {
- font-weight: bold;
-}
-
-/* -- index page ------------------------------------------------------------ */
-
-table.contentstable {
- width: 90%;
- margin-left: auto;
- margin-right: auto;
-}
-
-table.contentstable p.biglink {
- line-height: 150%;
-}
-
-a.biglink {
- font-size: 1.3em;
-}
-
-span.linkdescr {
- font-style: italic;
- padding-top: 5px;
- font-size: 90%;
-}
-
-/* -- general index --------------------------------------------------------- */
-
-table.indextable {
- width: 100%;
-}
-
-table.indextable td {
- text-align: left;
- vertical-align: top;
-}
-
-table.indextable ul {
- margin-top: 0;
- margin-bottom: 0;
- list-style-type: none;
-}
-
-table.indextable > tbody > tr > td > ul {
- padding-left: 0em;
-}
-
-table.indextable tr.pcap {
- height: 10px;
-}
-
-table.indextable tr.cap {
- margin-top: 10px;
- background-color: #f2f2f2;
-}
-
-img.toggler {
- margin-right: 3px;
- margin-top: 3px;
- cursor: pointer;
-}
-
-div.modindex-jumpbox {
- border-top: 1px solid #ddd;
- border-bottom: 1px solid #ddd;
- margin: 1em 0 1em 0;
- padding: 0.4em;
-}
-
-div.genindex-jumpbox {
- border-top: 1px solid #ddd;
- border-bottom: 1px solid #ddd;
- margin: 1em 0 1em 0;
- padding: 0.4em;
-}
-
-/* -- domain module index --------------------------------------------------- */
-
-table.modindextable td {
- padding: 2px;
- border-collapse: collapse;
-}
-
-/* -- general body styles --------------------------------------------------- */
-
-div.body {
- min-width: 450px;
- max-width: 800px;
-}
-
-div.body p, div.body dd, div.body li, div.body blockquote {
- -moz-hyphens: auto;
- -ms-hyphens: auto;
- -webkit-hyphens: auto;
- hyphens: auto;
-}
-
-a.headerlink {
- visibility: hidden;
-}
-
-a.brackets:before,
-span.brackets > a:before{
- content: "[";
-}
-
-a.brackets:after,
-span.brackets > a:after {
- content: "]";
-}
-
-h1:hover > a.headerlink,
-h2:hover > a.headerlink,
-h3:hover > a.headerlink,
-h4:hover > a.headerlink,
-h5:hover > a.headerlink,
-h6:hover > a.headerlink,
-dt:hover > a.headerlink,
-caption:hover > a.headerlink,
-p.caption:hover > a.headerlink,
-div.code-block-caption:hover > a.headerlink {
- visibility: visible;
-}
-
-div.body p.caption {
- text-align: inherit;
-}
-
-div.body td {
- text-align: left;
-}
-
-.first {
- margin-top: 0 !important;
-}
-
-p.rubric {
- margin-top: 30px;
- font-weight: bold;
-}
-
-img.align-left, .figure.align-left, object.align-left {
- clear: left;
- float: left;
- margin-right: 1em;
-}
-
-img.align-right, .figure.align-right, object.align-right {
- clear: right;
- float: right;
- margin-left: 1em;
-}
-
-img.align-center, .figure.align-center, object.align-center {
- display: block;
- margin-left: auto;
- margin-right: auto;
-}
-
-img.align-default, .figure.align-default {
- display: block;
- margin-left: auto;
- margin-right: auto;
-}
-
-.align-left {
- text-align: left;
-}
-
-.align-center {
- text-align: center;
-}
-
-.align-default {
- text-align: center;
-}
-
-.align-right {
- text-align: right;
-}
-
-/* -- sidebars -------------------------------------------------------------- */
-
-div.sidebar {
- margin: 0 0 0.5em 1em;
- border: 1px solid #ddb;
- padding: 7px;
- background-color: #ffe;
- width: 40%;
- float: right;
- clear: right;
- overflow-x: auto;
-}
-
-p.sidebar-title {
- font-weight: bold;
-}
-
-div.admonition, div.topic, blockquote {
- clear: left;
-}
-
-/* -- topics ---------------------------------------------------------------- */
-
-div.topic {
- border: 1px solid #ccc;
- padding: 7px;
- margin: 10px 0 10px 0;
-}
-
-p.topic-title {
- font-size: 1.1em;
- font-weight: bold;
- margin-top: 10px;
-}
-
-/* -- admonitions ----------------------------------------------------------- */
-
-div.admonition {
- margin-top: 10px;
- margin-bottom: 10px;
- padding: 7px;
-}
-
-div.admonition dt {
- font-weight: bold;
-}
-
-p.admonition-title {
- margin: 0px 10px 5px 0px;
- font-weight: bold;
-}
-
-div.body p.centered {
- text-align: center;
- margin-top: 25px;
-}
-
-/* -- content of sidebars/topics/admonitions -------------------------------- */
-
-div.sidebar > :last-child,
-div.topic > :last-child,
-div.admonition > :last-child {
- margin-bottom: 0;
-}
-
-div.sidebar::after,
-div.topic::after,
-div.admonition::after,
-blockquote::after {
- display: block;
- content: '';
- clear: both;
-}
-
-/* -- tables ---------------------------------------------------------------- */
-
-table.docutils {
- margin-top: 10px;
- margin-bottom: 10px;
- border: 0;
- border-collapse: collapse;
-}
-
-table.align-center {
- margin-left: auto;
- margin-right: auto;
-}
-
-table.align-default {
- margin-left: auto;
- margin-right: auto;
-}
-
-table caption span.caption-number {
- font-style: italic;
-}
-
-table caption span.caption-text {
-}
-
-table.docutils td, table.docutils th {
- padding: 1px 8px 1px 5px;
- border-top: 0;
- border-left: 0;
- border-right: 0;
- border-bottom: 1px solid #aaa;
-}
-
-table.footnote td, table.footnote th {
- border: 0 !important;
-}
-
-th {
- text-align: left;
- padding-right: 5px;
-}
-
-table.citation {
- border-left: solid 1px gray;
- margin-left: 1px;
-}
-
-table.citation td {
- border-bottom: none;
-}
-
-th > :first-child,
-td > :first-child {
- margin-top: 0px;
-}
-
-th > :last-child,
-td > :last-child {
- margin-bottom: 0px;
-}
-
-/* -- figures --------------------------------------------------------------- */
-
-div.figure {
- margin: 0.5em;
- padding: 0.5em;
-}
-
-div.figure p.caption {
- padding: 0.3em;
-}
-
-div.figure p.caption span.caption-number {
- font-style: italic;
-}
-
-div.figure p.caption span.caption-text {
-}
-
-/* -- field list styles ----------------------------------------------------- */
-
-table.field-list td, table.field-list th {
- border: 0 !important;
-}
-
-.field-list ul {
- margin: 0;
- padding-left: 1em;
-}
-
-.field-list p {
- margin: 0;
-}
-
-.field-name {
- -moz-hyphens: manual;
- -ms-hyphens: manual;
- -webkit-hyphens: manual;
- hyphens: manual;
-}
-
-/* -- hlist styles ---------------------------------------------------------- */
-
-table.hlist {
- margin: 1em 0;
-}
-
-table.hlist td {
- vertical-align: top;
-}
-
-
-/* -- other body styles ----------------------------------------------------- */
-
-ol.arabic {
- list-style: decimal;
-}
-
-ol.loweralpha {
- list-style: lower-alpha;
-}
-
-ol.upperalpha {
- list-style: upper-alpha;
-}
-
-ol.lowerroman {
- list-style: lower-roman;
-}
-
-ol.upperroman {
- list-style: upper-roman;
-}
-
-:not(li) > ol > li:first-child > :first-child,
-:not(li) > ul > li:first-child > :first-child {
- margin-top: 0px;
-}
-
-:not(li) > ol > li:last-child > :last-child,
-:not(li) > ul > li:last-child > :last-child {
- margin-bottom: 0px;
-}
-
-ol.simple ol p,
-ol.simple ul p,
-ul.simple ol p,
-ul.simple ul p {
- margin-top: 0;
-}
-
-ol.simple > li:not(:first-child) > p,
-ul.simple > li:not(:first-child) > p {
- margin-top: 0;
-}
-
-ol.simple p,
-ul.simple p {
- margin-bottom: 0;
-}
-
-dl.footnote > dt,
-dl.citation > dt {
- float: left;
- margin-right: 0.5em;
-}
-
-dl.footnote > dd,
-dl.citation > dd {
- margin-bottom: 0em;
-}
-
-dl.footnote > dd:after,
-dl.citation > dd:after {
- content: "";
- clear: both;
-}
-
-dl.field-list {
- display: grid;
- grid-template-columns: fit-content(30%) auto;
-}
-
-dl.field-list > dt {
- font-weight: bold;
- word-break: break-word;
- padding-left: 0.5em;
- padding-right: 5px;
-}
-
-dl.field-list > dt:after {
- content: ":";
-}
-
-dl.field-list > dd {
- padding-left: 0.5em;
- margin-top: 0em;
- margin-left: 0em;
- margin-bottom: 0em;
-}
-
-dl {
- margin-bottom: 15px;
-}
-
-dd > :first-child {
- margin-top: 0px;
-}
-
-dd ul, dd table {
- margin-bottom: 10px;
-}
-
-dd {
- margin-top: 3px;
- margin-bottom: 10px;
- margin-left: 30px;
-}
-
-dl > dd:last-child,
-dl > dd:last-child > :last-child {
- margin-bottom: 0;
-}
-
-dt:target, span.highlighted {
- background-color: #fbe54e;
-}
-
-rect.highlighted {
- fill: #fbe54e;
-}
-
-dl.glossary dt {
- font-weight: bold;
- font-size: 1.1em;
-}
-
-.optional {
- font-size: 1.3em;
-}
-
-.sig-paren {
- font-size: larger;
-}
-
-.versionmodified {
- font-style: italic;
-}
-
-.system-message {
- background-color: #fda;
- padding: 5px;
- border: 3px solid red;
-}
-
-.footnote:target {
- background-color: #ffa;
-}
-
-.line-block {
- display: block;
- margin-top: 1em;
- margin-bottom: 1em;
-}
-
-.line-block .line-block {
- margin-top: 0;
- margin-bottom: 0;
- margin-left: 1.5em;
-}
-
-.guilabel, .menuselection {
- font-family: sans-serif;
-}
-
-.accelerator {
- text-decoration: underline;
-}
-
-.classifier {
- font-style: oblique;
-}
-
-.classifier:before {
- font-style: normal;
- margin: 0.5em;
- content: ":";
-}
-
-abbr, acronym {
- border-bottom: dotted 1px;
- cursor: help;
-}
-
-/* -- code displays --------------------------------------------------------- */
-
-pre {
- overflow: auto;
- overflow-y: hidden; /* fixes display issues on Chrome browsers */
-}
-
-pre, div[class*="highlight-"] {
- clear: both;
-}
-
-span.pre {
- -moz-hyphens: none;
- -ms-hyphens: none;
- -webkit-hyphens: none;
- hyphens: none;
-}
-
-div[class*="highlight-"] {
- margin: 1em 0;
-}
-
-td.linenos pre {
- border: 0;
- background-color: transparent;
- color: #aaa;
-}
-
-table.highlighttable {
- display: block;
-}
-
-table.highlighttable tbody {
- display: block;
-}
-
-table.highlighttable tr {
- display: flex;
-}
-
-table.highlighttable td {
- margin: 0;
- padding: 0;
-}
-
-table.highlighttable td.linenos {
- padding-right: 0.5em;
-}
-
-table.highlighttable td.code {
- flex: 1;
- overflow: hidden;
-}
-
-.highlight .hll {
- display: block;
-}
-
-div.highlight pre,
-table.highlighttable pre {
- margin: 0;
-}
-
-div.code-block-caption + div {
- margin-top: 0;
-}
-
-div.code-block-caption {
- margin-top: 1em;
- padding: 2px 5px;
- font-size: small;
-}
-
-div.code-block-caption code {
- background-color: transparent;
-}
-
-table.highlighttable td.linenos,
-span.linenos,
-div.doctest > div.highlight span.gp { /* gp: Generic.Prompt */
- user-select: none;
-}
-
-div.code-block-caption span.caption-number {
- padding: 0.1em 0.3em;
- font-style: italic;
-}
-
-div.code-block-caption span.caption-text {
-}
-
-div.literal-block-wrapper {
- margin: 1em 0;
-}
-
-code.descname {
- background-color: transparent;
- font-weight: bold;
- font-size: 1.2em;
-}
-
-code.descclassname {
- background-color: transparent;
-}
-
-code.xref, a code {
- background-color: transparent;
- font-weight: bold;
-}
-
-h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
- background-color: transparent;
-}
-
-.viewcode-link {
- float: right;
-}
-
-.viewcode-back {
- float: right;
- font-family: sans-serif;
-}
-
-div.viewcode-block:target {
- margin: -1px -10px;
- padding: 0 10px;
-}
-
-/* -- math display ---------------------------------------------------------- */
-
-img.math {
- vertical-align: middle;
-}
-
-div.body div.math p {
- text-align: center;
-}
-
-span.eqno {
- float: right;
-}
-
-span.eqno a.headerlink {
- position: absolute;
- z-index: 1;
-}
-
-div.math:hover a.headerlink {
- visibility: visible;
-}
-
-/* -- printout stylesheet --------------------------------------------------- */
-
-@media print {
- div.document,
- div.documentwrapper,
- div.bodywrapper {
- margin: 0 !important;
- width: 100%;
- }
-
- div.sphinxsidebar,
- div.related,
- div.footer,
- #top-link {
- display: none;
- }
-}
\ No newline at end of file
diff --git a/docs/docs/html/_static/css/badge_only.css b/docs/docs/html/_static/css/badge_only.css
deleted file mode 100644
index e380325bc..000000000
--- a/docs/docs/html/_static/css/badge_only.css
+++ /dev/null
@@ -1 +0,0 @@
-.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}
\ No newline at end of file
diff --git a/docs/docs/html/_static/css/fonts/Roboto-Slab-Bold.woff b/docs/docs/html/_static/css/fonts/Roboto-Slab-Bold.woff
deleted file mode 100644
index 6cb600001..000000000
Binary files a/docs/docs/html/_static/css/fonts/Roboto-Slab-Bold.woff and /dev/null differ
diff --git a/docs/docs/html/_static/css/fonts/Roboto-Slab-Bold.woff2 b/docs/docs/html/_static/css/fonts/Roboto-Slab-Bold.woff2
deleted file mode 100644
index 7059e2314..000000000
Binary files a/docs/docs/html/_static/css/fonts/Roboto-Slab-Bold.woff2 and /dev/null differ
diff --git a/docs/docs/html/_static/css/fonts/Roboto-Slab-Regular.woff b/docs/docs/html/_static/css/fonts/Roboto-Slab-Regular.woff
deleted file mode 100644
index f815f63f9..000000000
Binary files a/docs/docs/html/_static/css/fonts/Roboto-Slab-Regular.woff and /dev/null differ
diff --git a/docs/docs/html/_static/css/fonts/Roboto-Slab-Regular.woff2 b/docs/docs/html/_static/css/fonts/Roboto-Slab-Regular.woff2
deleted file mode 100644
index f2c76e5bd..000000000
Binary files a/docs/docs/html/_static/css/fonts/Roboto-Slab-Regular.woff2 and /dev/null differ
diff --git a/docs/docs/html/_static/css/fonts/fontawesome-webfont.eot b/docs/docs/html/_static/css/fonts/fontawesome-webfont.eot
deleted file mode 100644
index e9f60ca95..000000000
Binary files a/docs/docs/html/_static/css/fonts/fontawesome-webfont.eot and /dev/null differ
diff --git a/docs/docs/html/_static/css/fonts/fontawesome-webfont.svg b/docs/docs/html/_static/css/fonts/fontawesome-webfont.svg
deleted file mode 100644
index 855c845e5..000000000
--- a/docs/docs/html/_static/css/fonts/fontawesome-webfont.svg
+++ /dev/null
@@ -1,2671 +0,0 @@
-
-
-
diff --git a/docs/docs/html/_static/css/fonts/fontawesome-webfont.ttf b/docs/docs/html/_static/css/fonts/fontawesome-webfont.ttf
deleted file mode 100644
index 35acda2fa..000000000
Binary files a/docs/docs/html/_static/css/fonts/fontawesome-webfont.ttf and /dev/null differ
diff --git a/docs/docs/html/_static/css/fonts/fontawesome-webfont.woff b/docs/docs/html/_static/css/fonts/fontawesome-webfont.woff
deleted file mode 100644
index 400014a4b..000000000
Binary files a/docs/docs/html/_static/css/fonts/fontawesome-webfont.woff and /dev/null differ
diff --git a/docs/docs/html/_static/css/fonts/fontawesome-webfont.woff2 b/docs/docs/html/_static/css/fonts/fontawesome-webfont.woff2
deleted file mode 100644
index 4d13fc604..000000000
Binary files a/docs/docs/html/_static/css/fonts/fontawesome-webfont.woff2 and /dev/null differ
diff --git a/docs/docs/html/_static/css/fonts/lato-bold-italic.woff b/docs/docs/html/_static/css/fonts/lato-bold-italic.woff
deleted file mode 100644
index 88ad05b9f..000000000
Binary files a/docs/docs/html/_static/css/fonts/lato-bold-italic.woff and /dev/null differ
diff --git a/docs/docs/html/_static/css/fonts/lato-bold-italic.woff2 b/docs/docs/html/_static/css/fonts/lato-bold-italic.woff2
deleted file mode 100644
index c4e3d804b..000000000
Binary files a/docs/docs/html/_static/css/fonts/lato-bold-italic.woff2 and /dev/null differ
diff --git a/docs/docs/html/_static/css/fonts/lato-bold.woff b/docs/docs/html/_static/css/fonts/lato-bold.woff
deleted file mode 100644
index c6dff51f0..000000000
Binary files a/docs/docs/html/_static/css/fonts/lato-bold.woff and /dev/null differ
diff --git a/docs/docs/html/_static/css/fonts/lato-bold.woff2 b/docs/docs/html/_static/css/fonts/lato-bold.woff2
deleted file mode 100644
index bb195043c..000000000
Binary files a/docs/docs/html/_static/css/fonts/lato-bold.woff2 and /dev/null differ
diff --git a/docs/docs/html/_static/css/fonts/lato-normal-italic.woff b/docs/docs/html/_static/css/fonts/lato-normal-italic.woff
deleted file mode 100644
index 76114bc03..000000000
Binary files a/docs/docs/html/_static/css/fonts/lato-normal-italic.woff and /dev/null differ
diff --git a/docs/docs/html/_static/css/fonts/lato-normal-italic.woff2 b/docs/docs/html/_static/css/fonts/lato-normal-italic.woff2
deleted file mode 100644
index 3404f37e2..000000000
Binary files a/docs/docs/html/_static/css/fonts/lato-normal-italic.woff2 and /dev/null differ
diff --git a/docs/docs/html/_static/css/fonts/lato-normal.woff b/docs/docs/html/_static/css/fonts/lato-normal.woff
deleted file mode 100644
index ae1307ff5..000000000
Binary files a/docs/docs/html/_static/css/fonts/lato-normal.woff and /dev/null differ
diff --git a/docs/docs/html/_static/css/fonts/lato-normal.woff2 b/docs/docs/html/_static/css/fonts/lato-normal.woff2
deleted file mode 100644
index 3bf984332..000000000
Binary files a/docs/docs/html/_static/css/fonts/lato-normal.woff2 and /dev/null differ
diff --git a/docs/docs/html/_static/css/theme.css b/docs/docs/html/_static/css/theme.css
deleted file mode 100644
index 8cd4f101a..000000000
--- a/docs/docs/html/_static/css/theme.css
+++ /dev/null
@@ -1,4 +0,0 @@
-html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li span.toctree-expand:before,.wy-nav-top a,.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*!
- * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
- * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
- */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li span.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p.caption .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a span.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-left.toctree-expand,.wy-menu-vertical li span.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p.caption .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a span.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-right.toctree-expand,.wy-menu-vertical li span.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p.caption .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a span.pull-left.toctree-expand,.wy-menu-vertical li.on a span.pull-left.toctree-expand,.wy-menu-vertical li span.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p.caption .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a span.pull-right.toctree-expand,.wy-menu-vertical li.on a span.pull-right.toctree-expand,.wy-menu-vertical li span.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li span.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li span.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li span.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li a span.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li span.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p.caption .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a span.toctree-expand,.btn .wy-menu-vertical li.on a span.toctree-expand,.btn .wy-menu-vertical li span.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p.caption .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a span.toctree-expand,.nav .wy-menu-vertical li.on a span.toctree-expand,.nav .wy-menu-vertical li span.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p.caption .btn .headerlink,.rst-content p.caption .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn span.toctree-expand,.wy-menu-vertical li.current>a .btn span.toctree-expand,.wy-menu-vertical li.current>a .nav span.toctree-expand,.wy-menu-vertical li .nav span.toctree-expand,.wy-menu-vertical li.on a .btn span.toctree-expand,.wy-menu-vertical li.on a .nav span.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p.caption .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li span.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p.caption .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li span.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p.caption .btn .fa-large.headerlink,.rst-content p.caption .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn span.fa-large.toctree-expand,.wy-menu-vertical li .nav span.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p.caption .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li span.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p.caption .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li span.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p.caption .btn .fa-spin.headerlink,.rst-content p.caption .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn span.fa-spin.toctree-expand,.wy-menu-vertical li .nav span.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p.caption .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li span.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p.caption .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li span.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p.caption .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li span.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p.caption .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini span.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol li,.rst-content ol.arabic li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content ol.arabic li p:last-child,.rst-content ol.arabic li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.rst-content .wy-breadcrumbs li tt,.wy-breadcrumbs li .rst-content tt,.wy-breadcrumbs li code{padding:5px;border:none;background:none}.rst-content .wy-breadcrumbs li tt.literal,.wy-breadcrumbs li .rst-content tt.literal,.wy-breadcrumbs li code.literal{color:#404040}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li span.toctree-expand{display:block;float:left;margin-left:-1.2em;font-size:.8em;line-height:1.6em;color:#4d4d4d}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover span.toctree-expand,.wy-menu-vertical li.on a:hover span.toctree-expand{color:grey}.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand{display:block;font-size:.8em;line-height:1.6em;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover span.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 span.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 span.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover span.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active span.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p.caption .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p.caption .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content img{max-width:100%;height:auto}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure p.caption{font-style:italic}.rst-content div.figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp{user-select:none;pointer-events:none}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink{visibility:hidden;font-size:14px}.rst-content .code-block-caption .headerlink:after,.rst-content .toctree-wrapper>p.caption .headerlink:after,.rst-content dl dt .headerlink:after,.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content p.caption .headerlink:after,.rst-content table>caption .headerlink:after{content:"\f0c1";font-family:FontAwesome}.rst-content .code-block-caption:hover .headerlink:after,.rst-content .toctree-wrapper>p.caption:hover .headerlink:after,.rst-content dl dt:hover .headerlink:after,.rst-content h1:hover .headerlink:after,.rst-content h2:hover .headerlink:after,.rst-content h3:hover .headerlink:after,.rst-content h4:hover .headerlink:after,.rst-content h5:hover .headerlink:after,.rst-content h6:hover .headerlink:after,.rst-content p.caption:hover .headerlink:after,.rst-content table>caption:hover .headerlink:after{visibility:visible}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .hlist{width:100%}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl dt span.classifier:before{content:" : "}html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.field-list>dt:after,html.writer-html5 .rst-content dl.footnote>dt:after{content:":"}html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.footnote>dt>span.brackets{margin-right:.5rem}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{font-style:italic}html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.footnote>dd p,html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{font-size:inherit;line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code,html.writer-html4 .rst-content dl:not(.docutils) tt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel{border:1px solid #7fbbe3;background:#e7f2fa;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block}
\ No newline at end of file
diff --git a/docs/docs/html/_static/custom.css b/docs/docs/html/_static/custom.css
deleted file mode 100644
index 2a924f1d6..000000000
--- a/docs/docs/html/_static/custom.css
+++ /dev/null
@@ -1 +0,0 @@
-/* This file intentionally left blank. */
diff --git a/docs/docs/html/_static/doctools.js b/docs/docs/html/_static/doctools.js
deleted file mode 100644
index 144884ea6..000000000
--- a/docs/docs/html/_static/doctools.js
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * doctools.js
- * ~~~~~~~~~~~
- *
- * Sphinx JavaScript utilities for all documentation.
- *
- * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-
-/**
- * select a different prefix for underscore
- */
-$u = _.noConflict();
-
-/**
- * make the code below compatible with browsers without
- * an installed firebug like debugger
-if (!window.console || !console.firebug) {
- var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
- "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
- "profile", "profileEnd"];
- window.console = {};
- for (var i = 0; i < names.length; ++i)
- window.console[names[i]] = function() {};
-}
- */
-
-/**
- * small helper function to urldecode strings
- */
-jQuery.urldecode = function(x) {
- return decodeURIComponent(x).replace(/\+/g, ' ');
-};
-
-/**
- * small helper function to urlencode strings
- */
-jQuery.urlencode = encodeURIComponent;
-
-/**
- * This function returns the parsed url parameters of the
- * current request. Multiple values per key are supported,
- * it will always return arrays of strings for the value parts.
- */
-jQuery.getQueryParameters = function(s) {
- if (typeof s === 'undefined')
- s = document.location.search;
- var parts = s.substr(s.indexOf('?') + 1).split('&');
- var result = {};
- for (var i = 0; i < parts.length; i++) {
- var tmp = parts[i].split('=', 2);
- var key = jQuery.urldecode(tmp[0]);
- var value = jQuery.urldecode(tmp[1]);
- if (key in result)
- result[key].push(value);
- else
- result[key] = [value];
- }
- return result;
-};
-
-/**
- * highlight a given string on a jquery object by wrapping it in
- * span elements with the given class name.
- */
-jQuery.fn.highlightText = function(text, className) {
- function highlight(node, addItems) {
- if (node.nodeType === 3) {
- var val = node.nodeValue;
- var pos = val.toLowerCase().indexOf(text);
- if (pos >= 0 &&
- !jQuery(node.parentNode).hasClass(className) &&
- !jQuery(node.parentNode).hasClass("nohighlight")) {
- var span;
- var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
- if (isInSVG) {
- span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
- } else {
- span = document.createElement("span");
- span.className = className;
- }
- span.appendChild(document.createTextNode(val.substr(pos, text.length)));
- node.parentNode.insertBefore(span, node.parentNode.insertBefore(
- document.createTextNode(val.substr(pos + text.length)),
- node.nextSibling));
- node.nodeValue = val.substr(0, pos);
- if (isInSVG) {
- var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
- var bbox = node.parentElement.getBBox();
- rect.x.baseVal.value = bbox.x;
- rect.y.baseVal.value = bbox.y;
- rect.width.baseVal.value = bbox.width;
- rect.height.baseVal.value = bbox.height;
- rect.setAttribute('class', className);
- addItems.push({
- "parent": node.parentNode,
- "target": rect});
- }
- }
- }
- else if (!jQuery(node).is("button, select, textarea")) {
- jQuery.each(node.childNodes, function() {
- highlight(this, addItems);
- });
- }
- }
- var addItems = [];
- var result = this.each(function() {
- highlight(this, addItems);
- });
- for (var i = 0; i < addItems.length; ++i) {
- jQuery(addItems[i].parent).before(addItems[i].target);
- }
- return result;
-};
-
-/*
- * backward compatibility for jQuery.browser
- * This will be supported until firefox bug is fixed.
- */
-if (!jQuery.browser) {
- jQuery.uaMatch = function(ua) {
- ua = ua.toLowerCase();
-
- var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
- /(webkit)[ \/]([\w.]+)/.exec(ua) ||
- /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
- /(msie) ([\w.]+)/.exec(ua) ||
- ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
- [];
-
- return {
- browser: match[ 1 ] || "",
- version: match[ 2 ] || "0"
- };
- };
- jQuery.browser = {};
- jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
-}
-
-/**
- * Small JavaScript module for the documentation.
- */
-var Documentation = {
-
- init : function() {
- this.fixFirefoxAnchorBug();
- this.highlightSearchWords();
- this.initIndexTable();
- if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {
- this.initOnKeyListeners();
- }
- },
-
- /**
- * i18n support
- */
- TRANSLATIONS : {},
- PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },
- LOCALE : 'unknown',
-
- // gettext and ngettext don't access this so that the functions
- // can safely bound to a different name (_ = Documentation.gettext)
- gettext : function(string) {
- var translated = Documentation.TRANSLATIONS[string];
- if (typeof translated === 'undefined')
- return string;
- return (typeof translated === 'string') ? translated : translated[0];
- },
-
- ngettext : function(singular, plural, n) {
- var translated = Documentation.TRANSLATIONS[singular];
- if (typeof translated === 'undefined')
- return (n == 1) ? singular : plural;
- return translated[Documentation.PLURALEXPR(n)];
- },
-
- addTranslations : function(catalog) {
- for (var key in catalog.messages)
- this.TRANSLATIONS[key] = catalog.messages[key];
- this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
- this.LOCALE = catalog.locale;
- },
-
- /**
- * add context elements like header anchor links
- */
- addContextElements : function() {
- $('div[id] > :header:first').each(function() {
- $('').
- attr('href', '#' + this.id).
- attr('title', _('Permalink to this headline')).
- appendTo(this);
- });
- $('dt[id]').each(function() {
- $('').
- attr('href', '#' + this.id).
- attr('title', _('Permalink to this definition')).
- appendTo(this);
- });
- },
-
- /**
- * workaround a firefox stupidity
- * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
- */
- fixFirefoxAnchorBug : function() {
- if (document.location.hash && $.browser.mozilla)
- window.setTimeout(function() {
- document.location.href += '';
- }, 10);
- },
-
- /**
- * highlight the search words provided in the url in the text
- */
- highlightSearchWords : function() {
- var params = $.getQueryParameters();
- var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
- if (terms.length) {
- var body = $('div.body');
- if (!body.length) {
- body = $('body');
- }
- window.setTimeout(function() {
- $.each(terms, function() {
- body.highlightText(this.toLowerCase(), 'highlighted');
- });
- }, 10);
- $('
' + _('Hide Search Matches') + '
')
- .appendTo($('#searchbox'));
- }
- },
-
- /**
- * init the domain index toggle buttons
- */
- initIndexTable : function() {
- var togglers = $('img.toggler').click(function() {
- var src = $(this).attr('src');
- var idnum = $(this).attr('id').substr(7);
- $('tr.cg-' + idnum).toggle();
- if (src.substr(-9) === 'minus.png')
- $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
- else
- $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
- }).css('display', '');
- if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
- togglers.click();
- }
- },
-
- /**
- * helper function to hide the search marks again
- */
- hideSearchWords : function() {
- $('#searchbox .highlight-link').fadeOut(300);
- $('span.highlighted').removeClass('highlighted');
- },
-
- /**
- * make the url absolute
- */
- makeURL : function(relativeURL) {
- return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
- },
-
- /**
- * get the current relative url
- */
- getCurrentURL : function() {
- var path = document.location.pathname;
- var parts = path.split(/\//);
- $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
- if (this === '..')
- parts.pop();
- });
- var url = parts.join('/');
- return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
- },
-
- initOnKeyListeners: function() {
- $(document).keydown(function(event) {
- var activeElementType = document.activeElement.tagName;
- // don't navigate when in search box, textarea, dropdown or button
- if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT'
- && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey
- && !event.shiftKey) {
- switch (event.keyCode) {
- case 37: // left
- var prevHref = $('link[rel="prev"]').prop('href');
- if (prevHref) {
- window.location.href = prevHref;
- return false;
- }
- case 39: // right
- var nextHref = $('link[rel="next"]').prop('href');
- if (nextHref) {
- window.location.href = nextHref;
- return false;
- }
- }
- }
- });
- }
-};
-
-// quick alias for translations
-_ = Documentation.gettext;
-
-$(document).ready(function() {
- Documentation.init();
-});
diff --git a/docs/docs/html/_static/documentation_options.js b/docs/docs/html/_static/documentation_options.js
deleted file mode 100644
index 2fa8c97fe..000000000
--- a/docs/docs/html/_static/documentation_options.js
+++ /dev/null
@@ -1,12 +0,0 @@
-var DOCUMENTATION_OPTIONS = {
- URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
- VERSION: '',
- LANGUAGE: 'None',
- COLLAPSE_INDEX: false,
- BUILDER: 'html',
- FILE_SUFFIX: '.html',
- LINK_SUFFIX: '.html',
- HAS_SOURCE: true,
- SOURCELINK_SUFFIX: '.txt',
- NAVIGATION_WITH_KEYS: false
-};
\ No newline at end of file
diff --git a/docs/docs/html/_static/file.png b/docs/docs/html/_static/file.png
deleted file mode 100644
index a858a410e..000000000
Binary files a/docs/docs/html/_static/file.png and /dev/null differ
diff --git a/docs/docs/html/_static/jquery-3.5.1.js b/docs/docs/html/_static/jquery-3.5.1.js
deleted file mode 100644
index 50937333b..000000000
--- a/docs/docs/html/_static/jquery-3.5.1.js
+++ /dev/null
@@ -1,10872 +0,0 @@
-/*!
- * jQuery JavaScript Library v3.5.1
- * https://jquery.com/
- *
- * Includes Sizzle.js
- * https://sizzlejs.com/
- *
- * Copyright JS Foundation and other contributors
- * Released under the MIT license
- * https://jquery.org/license
- *
- * Date: 2020-05-04T22:49Z
- */
-( function( global, factory ) {
-
- "use strict";
-
- if ( typeof module === "object" && typeof module.exports === "object" ) {
-
- // For CommonJS and CommonJS-like environments where a proper `window`
- // is present, execute the factory and get jQuery.
- // For environments that do not have a `window` with a `document`
- // (such as Node.js), expose a factory as module.exports.
- // This accentuates the need for the creation of a real `window`.
- // e.g. var jQuery = require("jquery")(window);
- // See ticket #14549 for more info.
- module.exports = global.document ?
- factory( global, true ) :
- function( w ) {
- if ( !w.document ) {
- throw new Error( "jQuery requires a window with a document" );
- }
- return factory( w );
- };
- } else {
- factory( global );
- }
-
-// Pass this if window is not defined yet
-} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
-
-// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
-// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
-// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
-// enough that all such attempts are guarded in a try block.
-"use strict";
-
-var arr = [];
-
-var getProto = Object.getPrototypeOf;
-
-var slice = arr.slice;
-
-var flat = arr.flat ? function( array ) {
- return arr.flat.call( array );
-} : function( array ) {
- return arr.concat.apply( [], array );
-};
-
-
-var push = arr.push;
-
-var indexOf = arr.indexOf;
-
-var class2type = {};
-
-var toString = class2type.toString;
-
-var hasOwn = class2type.hasOwnProperty;
-
-var fnToString = hasOwn.toString;
-
-var ObjectFunctionString = fnToString.call( Object );
-
-var support = {};
-
-var isFunction = function isFunction( obj ) {
-
- // Support: Chrome <=57, Firefox <=52
- // In some browsers, typeof returns "function" for HTML