From 03250cef003b18e9da37079d9fb183f862bb2bd8 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sat, 18 Feb 2023 19:07:05 +0100
Subject: [PATCH 01/46] Switch from pipenv to poetry
---
 Pipfile        |   33 -
 Pipfile.lock   |  617 -----------------
 poetry.lock    | 1738 ++++++++++++++++++++++++++++++++++++++++++++++++
 pyproject.toml |   43 ++
 4 files changed, 1781 insertions(+), 650 deletions(-)
 delete mode 100644 Pipfile
 delete mode 100644 Pipfile.lock
 create mode 100644 poetry.lock
 create mode 100644 pyproject.toml
diff --git a/Pipfile b/Pipfile
deleted file mode 100644
index 0c6343e..0000000
--- a/Pipfile
+++ /dev/null
@@ -1,33 +0,0 @@
-[[source]]
-url = "https://pypi.org/simple"
-verify_ssl = true
-name = "pypi"
-
-[[source]]
-url = "https://pypi.gnuviech-server.de/simple"
-verify_ssl = true
-name = "gnuviech"
-
-[packages]
-"psycopg2" = "*"
-Django = "<3"
-celery = "*"
-django-allauth = "*"
-django-braces = "*"
-django-crispy-forms = "*"
-django-model-utils = "*"
-gvacommon = {version = "*",index = "gnuviech"}
-passlib = "*"
-redis = "*"
-requests-oauthlib = "*"
-
-[dev-packages]
-coverage = "*"
-django-debug-toolbar = "*"
-sphinx = "*"
-releases = "*"
-sphinxcontrib-blockdiag = "*"
-pylama = "*"
-
-[requires]
-python_version = "3.7"
diff --git a/Pipfile.lock b/Pipfile.lock
deleted file mode 100644
index 50db093..0000000
--- a/Pipfile.lock
+++ /dev/null
@@ -1,617 +0,0 @@
-{
-    "_meta": {
-        "hash": {
-            "sha256": "1c0b7bdab385f10279c852fa7fe7ae2c022dc1c4495d0e55fd407aea947bc976"
-        },
-        "pipfile-spec": 6,
-        "requires": {
-            "python_version": "3.7"
-        },
-        "sources": [
-            {
-                "name": "pypi",
-                "url": "https://pypi.org/simple",
-                "verify_ssl": true
-            },
-            {
-                "name": "gnuviech",
-                "url": "https://pypi.gnuviech-server.de/simple",
-                "verify_ssl": true
-            }
-        ]
-    },
-    "default": {
-        "amqp": {
-            "hashes": [
-                "sha256:6e649ca13a7df3faacdc8bbb280aa9a6602d22fd9d545336077e573a1f4ff3b8",
-                "sha256:77f1aef9410698d20eaeac5b73a87817365f457a507d82edf292e12cbb83b08d"
-            ],
-            "version": "==2.5.2"
-        },
-        "billiard": {
-            "hashes": [
-                "sha256:bff575450859a6e0fbc2f9877d9b715b0bbc07c3565bb7ed2280526a0cdf5ede",
-                "sha256:d91725ce6425f33a97dfa72fb6bfef0e47d4652acd98a032bd1a7fbf06d5fa6a"
-            ],
-            "version": "==3.6.3.0"
-        },
-        "celery": {
-            "hashes": [
-                "sha256:108a0bf9018a871620936c33a3ee9f6336a89f8ef0a0f567a9001f4aa361415f",
-                "sha256:5b4b37e276033fe47575107a2775469f0b721646a08c96ec2c61531e4fe45f2a"
-            ],
-            "index": "pypi",
-            "version": "==4.4.2"
-        },
-        "certifi": {
-            "hashes": [
-                "sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304",
-                "sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519"
-            ],
-            "version": "==2020.4.5.1"
-        },
-        "chardet": {
-            "hashes": [
-                "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
-                "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
-            ],
-            "version": "==3.0.4"
-        },
-        "defusedxml": {
-            "hashes": [
-                "sha256:6687150770438374ab581bb7a1b327a847dd9c5749e396102de3fad4e8a3ef93",
-                "sha256:f684034d135af4c6cbb949b8a4d2ed61634515257a67299e5f940fbaa34377f5"
-            ],
-            "version": "==0.6.0"
-        },
-        "django": {
-            "hashes": [
-                "sha256:69897097095f336d5aeef45b4103dceae51c00afa6d3ae198a2a18e519791b7a",
-                "sha256:6ecd229e1815d4fc5240fc98f1cca78c41e7a8cd3e3f2eefadc4735031077916"
-            ],
-            "index": "pypi",
-            "version": "==2.2.12"
-        },
-        "django-allauth": {
-            "hashes": [
-                "sha256:7ab91485b80d231da191d5c7999ba93170ef1bf14ab6487d886598a1ad03e1d8"
-            ],
-            "index": "pypi",
-            "version": "==0.41.0"
-        },
-        "django-braces": {
-            "hashes": [
-                "sha256:83705b78948de00804bfacf40c315d001bb39630f35bbdd8588211c2d5b4d43f",
-                "sha256:a6d9b34cf3e4949635e54884097c30410d7964fc7bec7231445ea7079b8c5722"
-            ],
-            "index": "pypi",
-            "version": "==1.14.0"
-        },
-        "django-crispy-forms": {
-            "hashes": [
-                "sha256:50032184708ce351e3c9f0008ac35d659d9d5973fa2db218066f2e0a76eb41d9",
-                "sha256:67e73ac863d3159500029fbbcdcb788f287a3fd357becebc1a0b51f73896dce3"
-            ],
-            "index": "pypi",
-            "version": "==1.9.0"
-        },
-        "django-model-utils": {
-            "hashes": [
-                "sha256:9cf882e5b604421b62dbe57ad2b18464dc9c8f963fc3f9831badccae66c1139c",
-                "sha256:adf09e5be15122a7f4e372cb5a6dd512bbf8d78a23a90770ad0983ee9d909061"
-            ],
-            "index": "pypi",
-            "version": "==4.0.0"
-        },
-        "gvacommon": {
-            "hashes": [
-                "sha256:adf1ebc824433196d112764c61d9ca869481d33f612818c2840069f57ab42c25"
-            ],
-            "index": "gnuviech",
-            "version": "==0.5.0"
-        },
-        "idna": {
-            "hashes": [
-                "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb",
-                "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"
-            ],
-            "version": "==2.9"
-        },
-        "importlib-metadata": {
-            "hashes": [
-                "sha256:2a688cbaa90e0cc587f1df48bdc97a6eadccdcd9c35fb3f976a09e3b5016d90f",
-                "sha256:34513a8a0c4962bc66d35b359558fd8a5e10cd472d37aec5f66858addef32c1e"
-            ],
-            "markers": "python_version < '3.8'",
-            "version": "==1.6.0"
-        },
-        "kombu": {
-            "hashes": [
-                "sha256:2d1cda774126a044d91a7ff5fa6d09edf99f46924ab332a810760fe6740e9b76",
-                "sha256:598e7e749d6ab54f646b74b2d2df67755dee13894f73ab02a2a9feb8870c7cb2"
-            ],
-            "version": "==4.6.8"
-        },
-        "oauthlib": {
-            "hashes": [
-                "sha256:bee41cc35fcca6e988463cacc3bcb8a96224f470ca547e697b604cc697b2f889",
-                "sha256:df884cd6cbe20e32633f1db1072e9356f53638e4361bef4e8b03c9127c9328ea"
-            ],
-            "version": "==3.1.0"
-        },
-        "passlib": {
-            "hashes": [
-                "sha256:68c35c98a7968850e17f1b6892720764cc7eed0ef2b7cb3116a89a28e43fe177",
-                "sha256:8d666cef936198bc2ab47ee9b0410c94adf2ba798e5a84bf220be079ae7ab6a8"
-            ],
-            "index": "pypi",
-            "version": "==1.7.2"
-        },
-        "psycopg2": {
-            "hashes": [
-                "sha256:132efc7ee46a763e68a815f4d26223d9c679953cd190f1f218187cb60decf535",
-                "sha256:2327bf42c1744a434ed8ed0bbaa9168cac7ee5a22a9001f6fc85c33b8a4a14b7",
-                "sha256:27c633f2d5db0fc27b51f1b08f410715b59fa3802987aec91aeb8f562724e95c",
-                "sha256:2c0afb40cfb4d53487ee2ebe128649028c9a78d2476d14a67781e45dc287f080",
-                "sha256:2df2bf1b87305bd95eb3ac666ee1f00a9c83d10927b8144e8e39644218f4cf81",
-                "sha256:440a3ea2c955e89321a138eb7582aa1d22fe286c7d65e26a2c5411af0a88ae72",
-                "sha256:6a471d4d2a6f14c97a882e8d3124869bc623f3df6177eefe02994ea41fd45b52",
-                "sha256:6b306dae53ec7f4f67a10942cf8ac85de930ea90e9903e2df4001f69b7833f7e",
-                "sha256:a0984ff49e176062fcdc8a5a2a670c9bb1704a2f69548bce8f8a7bad41c661bf",
-                "sha256:ac5b23d0199c012ad91ed1bbb971b7666da651c6371529b1be8cbe2a7bf3c3a9",
-                "sha256:acf56d564e443e3dea152efe972b1434058244298a94348fc518d6dd6a9fb0bb",
-                "sha256:d3b29d717d39d3580efd760a9a46a7418408acebbb784717c90d708c9ed5f055",
-                "sha256:f7d46240f7a1ae1dd95aab38bd74f7428d46531f69219954266d669da60c0818"
-            ],
-            "index": "pypi",
-            "version": "==2.8.5"
-        },
-        "python3-openid": {
-            "hashes": [
-                "sha256:0086da6b6ef3161cfe50fb1ee5cceaf2cda1700019fda03c2c5c440ca6abe4fa",
-                "sha256:628d365d687e12da12d02c6691170f4451db28d6d68d050007e4a40065868502"
-            ],
-            "version": "==3.1.0"
-        },
-        "pytz": {
-            "hashes": [
-                "sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d",
-                "sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be"
-            ],
-            "version": "==2019.3"
-        },
-        "redis": {
-            "hashes": [
-                "sha256:0dcfb335921b88a850d461dc255ff4708294943322bd55de6cfd68972490ca1f",
-                "sha256:b205cffd05ebfd0a468db74f0eedbff8df1a7bfc47521516ade4692991bb0833"
-            ],
-            "index": "pypi",
-            "version": "==3.4.1"
-        },
-        "requests": {
-            "hashes": [
-                "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee",
-                "sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6"
-            ],
-            "version": "==2.23.0"
-        },
-        "requests-oauthlib": {
-            "hashes": [
-                "sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d",
-                "sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a"
-            ],
-            "index": "pypi",
-            "version": "==1.3.0"
-        },
-        "six": {
-            "hashes": [
-                "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a",
-                "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"
-            ],
-            "version": "==1.14.0"
-        },
-        "sqlparse": {
-            "hashes": [
-                "sha256:022fb9c87b524d1f7862b3037e541f68597a730a8843245c349fc93e1643dc4e",
-                "sha256:e162203737712307dfe78860cc56c8da8a852ab2ee33750e33aeadf38d12c548"
-            ],
-            "version": "==0.3.1"
-        },
-        "urllib3": {
-            "hashes": [
-                "sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc",
-                "sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc"
-            ],
-            "version": "==1.25.8"
-        },
-        "vine": {
-            "hashes": [
-                "sha256:133ee6d7a9016f177ddeaf191c1f58421a1dcc6ee9a42c58b34bed40e1d2cd87",
-                "sha256:ea4947cc56d1fd6f2095c8d543ee25dad966f78692528e68b4fada11ba3f98af"
-            ],
-            "version": "==1.3.0"
-        },
-        "zipp": {
-            "hashes": [
-                "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b",
-                "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96"
-            ],
-            "version": "==3.1.0"
-        }
-    },
-    "develop": {
-        "alabaster": {
-            "hashes": [
-                "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359",
-                "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"
-            ],
-            "version": "==0.7.12"
-        },
-        "asgiref": {
-            "hashes": [
-                "sha256:8036f90603c54e93521e5777b2b9a39ba1bad05773fcf2d208f0299d1df58ce5",
-                "sha256:9ca8b952a0a9afa61d30aa6d3d9b570bb3fd6bafcf7ec9e6bed43b936133db1c"
-            ],
-            "version": "==3.2.7"
-        },
-        "babel": {
-            "hashes": [
-                "sha256:1aac2ae2d0d8ea368fa90906567f5c08463d98ade155c0c4bfedd6a0f7160e38",
-                "sha256:d670ea0b10f8b723672d3a6abeb87b565b244da220d76b4dba1b66269ec152d4"
-            ],
-            "version": "==2.8.0"
-        },
-        "blockdiag": {
-            "hashes": [
-                "sha256:16a69dd9f3b44c9e0869999ce82aa968586698febc86ece9ca0c902dba772397",
-                "sha256:fa0b47cf25bfc4d546b7fc284c70c3bac875a066e744b4a6b1d9ba457e4ed077"
-            ],
-            "version": "==2.0.1"
-        },
-        "certifi": {
-            "hashes": [
-                "sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304",
-                "sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519"
-            ],
-            "version": "==2020.4.5.1"
-        },
-        "chardet": {
-            "hashes": [
-                "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
-                "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
-            ],
-            "version": "==3.0.4"
-        },
-        "coverage": {
-            "hashes": [
-                "sha256:03f630aba2b9b0d69871c2e8d23a69b7fe94a1e2f5f10df5049c0df99db639a0",
-                "sha256:046a1a742e66d065d16fb564a26c2a15867f17695e7f3d358d7b1ad8a61bca30",
-                "sha256:0a907199566269e1cfa304325cc3b45c72ae341fbb3253ddde19fa820ded7a8b",
-                "sha256:165a48268bfb5a77e2d9dbb80de7ea917332a79c7adb747bd005b3a07ff8caf0",
-                "sha256:1b60a95fc995649464e0cd48cecc8288bac5f4198f21d04b8229dc4097d76823",
-                "sha256:1f66cf263ec77af5b8fe14ef14c5e46e2eb4a795ac495ad7c03adc72ae43fafe",
-                "sha256:2e08c32cbede4a29e2a701822291ae2bc9b5220a971bba9d1e7615312efd3037",
-                "sha256:3844c3dab800ca8536f75ae89f3cf566848a3eb2af4d9f7b1103b4f4f7a5dad6",
-                "sha256:408ce64078398b2ee2ec08199ea3fcf382828d2f8a19c5a5ba2946fe5ddc6c31",
-                "sha256:443be7602c790960b9514567917af538cac7807a7c0c0727c4d2bbd4014920fd",
-                "sha256:4482f69e0701139d0f2c44f3c395d1d1d37abd81bfafbf9b6efbe2542679d892",
-                "sha256:4a8a259bf990044351baf69d3b23e575699dd60b18460c71e81dc565f5819ac1",
-                "sha256:513e6526e0082c59a984448f4104c9bf346c2da9961779ede1fc458e8e8a1f78",
-                "sha256:5f587dfd83cb669933186661a351ad6fc7166273bc3e3a1531ec5c783d997aac",
-                "sha256:62061e87071497951155cbccee487980524d7abea647a1b2a6eb6b9647df9006",
-                "sha256:641e329e7f2c01531c45c687efcec8aeca2a78a4ff26d49184dce3d53fc35014",
-                "sha256:65a7e00c00472cd0f59ae09d2fb8a8aaae7f4a0cf54b2b74f3138d9f9ceb9cb2",
-                "sha256:6ad6ca45e9e92c05295f638e78cd42bfaaf8ee07878c9ed73e93190b26c125f7",
-                "sha256:73aa6e86034dad9f00f4bbf5a666a889d17d79db73bc5af04abd6c20a014d9c8",
-                "sha256:7c9762f80a25d8d0e4ab3cb1af5d9dffbddb3ee5d21c43e3474c84bf5ff941f7",
-                "sha256:85596aa5d9aac1bf39fe39d9fa1051b0f00823982a1de5766e35d495b4a36ca9",
-                "sha256:86a0ea78fd851b313b2e712266f663e13b6bc78c2fb260b079e8b67d970474b1",
-                "sha256:8a620767b8209f3446197c0e29ba895d75a1e272a36af0786ec70fe7834e4307",
-                "sha256:922fb9ef2c67c3ab20e22948dcfd783397e4c043a5c5fa5ff5e9df5529074b0a",
-                "sha256:9fad78c13e71546a76c2f8789623eec8e499f8d2d799f4b4547162ce0a4df435",
-                "sha256:a37c6233b28e5bc340054cf6170e7090a4e85069513320275a4dc929144dccf0",
-                "sha256:c3fc325ce4cbf902d05a80daa47b645d07e796a80682c1c5800d6ac5045193e5",
-                "sha256:cda33311cb9fb9323958a69499a667bd728a39a7aa4718d7622597a44c4f1441",
-                "sha256:db1d4e38c9b15be1521722e946ee24f6db95b189d1447fa9ff18dd16ba89f732",
-                "sha256:eda55e6e9ea258f5e4add23bcf33dc53b2c319e70806e180aecbff8d90ea24de",
-                "sha256:f372cdbb240e09ee855735b9d85e7f50730dcfb6296b74b95a3e5dea0615c4c1"
-            ],
-            "index": "pypi",
-            "version": "==5.0.4"
-        },
-        "django": {
-            "hashes": [
-                "sha256:69897097095f336d5aeef45b4103dceae51c00afa6d3ae198a2a18e519791b7a",
-                "sha256:6ecd229e1815d4fc5240fc98f1cca78c41e7a8cd3e3f2eefadc4735031077916"
-            ],
-            "index": "pypi",
-            "version": "==2.2.12"
-        },
-        "django-debug-toolbar": {
-            "hashes": [
-                "sha256:eabbefe89881bbe4ca7c980ff102e3c35c8e8ad6eb725041f538988f2f39a943",
-                "sha256:ff94725e7aae74b133d0599b9bf89bd4eb8f5d2c964106e61d11750228c8774c"
-            ],
-            "index": "pypi",
-            "version": "==2.2"
-        },
-        "docutils": {
-            "hashes": [
-                "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af",
-                "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"
-            ],
-            "version": "==0.16"
-        },
-        "funcparserlib": {
-            "hashes": [
-                "sha256:b7992eac1a3eb97b3d91faa342bfda0729e990bd8a43774c1592c091e563c91d"
-            ],
-            "version": "==0.3.6"
-        },
-        "idna": {
-            "hashes": [
-                "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb",
-                "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"
-            ],
-            "version": "==2.9"
-        },
-        "imagesize": {
-            "hashes": [
-                "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1",
-                "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"
-            ],
-            "version": "==1.2.0"
-        },
-        "jinja2": {
-            "hashes": [
-                "sha256:93187ffbc7808079673ef52771baa950426fd664d3aad1d0fa3e95644360e250",
-                "sha256:b0eaf100007721b5c16c1fc1eecb87409464edc10469ddc9a22a27a99123be49"
-            ],
-            "version": "==2.11.1"
-        },
-        "markupsafe": {
-            "hashes": [
-                "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
-                "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161",
-                "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235",
-                "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5",
-                "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42",
-                "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff",
-                "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b",
-                "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1",
-                "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e",
-                "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183",
-                "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66",
-                "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b",
-                "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1",
-                "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15",
-                "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1",
-                "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
-                "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b",
-                "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905",
-                "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735",
-                "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d",
-                "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e",
-                "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d",
-                "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c",
-                "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21",
-                "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2",
-                "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5",
-                "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b",
-                "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6",
-                "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f",
-                "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f",
-                "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2",
-                "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7",
-                "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"
-            ],
-            "version": "==1.1.1"
-        },
-        "mccabe": {
-            "hashes": [
-                "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
-                "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
-            ],
-            "version": "==0.6.1"
-        },
-        "packaging": {
-            "hashes": [
-                "sha256:3c292b474fda1671ec57d46d739d072bfd495a4f51ad01a055121d81e952b7a3",
-                "sha256:82f77b9bee21c1bafbf35a84905d604d5d1223801d639cf3ed140bd651c08752"
-            ],
-            "version": "==20.3"
-        },
-        "pillow": {
-            "hashes": [
-                "sha256:04a10558320eba9137d6a78ca6fc8f4a5801f1b971152938851dc4629d903579",
-                "sha256:0f89ddc77cf421b8cd34ae852309501458942bf370831b4a9b406156b599a14e",
-                "sha256:251e5618125ec12ac800265d7048f5857a8f8f1979db9ea3e11382e159d17f68",
-                "sha256:291bad7097b06d648222b769bbfcd61e40d0abdfe10df686d20ede36eb8162b6",
-                "sha256:2f0b52a08d175f10c8ea36685115681a484c55d24d0933f9fd911e4111c04144",
-                "sha256:3713386d1e9e79cea1c5e6aaac042841d7eef838cc577a3ca153c8bedf570287",
-                "sha256:433bbc2469a2351bea53666d97bb1eb30f0d56461735be02ea6b27654569f80f",
-                "sha256:4510c6b33277970b1af83c987277f9a08ec2b02cc20ac0f9234e4026136bb137",
-                "sha256:50a10b048f4dd81c092adad99fa5f7ba941edaf2f9590510109ac2a15e706695",
-                "sha256:670e58d3643971f4afd79191abd21623761c2ebe61db1c2cb4797d817c4ba1a7",
-                "sha256:6c1924ed7dbc6ad0636907693bbbdd3fdae1d73072963e71f5644b864bb10b4d",
-                "sha256:721c04d3c77c38086f1f95d1cd8df87f2f9a505a780acf8575912b3206479da1",
-                "sha256:8d5799243050c2833c2662b824dfb16aa98e408d2092805edea4300a408490e7",
-                "sha256:90cd441a1638ae176eab4d8b6b94ab4ec24b212ed4c3fbee2a6e74672481d4f8",
-                "sha256:a5dc9f28c0239ec2742d4273bd85b2aa84655be2564db7ad1eb8f64b1efcdc4c",
-                "sha256:b2f3e8cc52ecd259b94ca880fea0d15f4ebc6da2cd3db515389bb878d800270f",
-                "sha256:b7453750cf911785009423789d2e4e5393aae9cbb8b3f471dab854b85a26cb89",
-                "sha256:b99b2607b6cd58396f363b448cbe71d3c35e28f03e442ab00806463439629c2c",
-                "sha256:cd47793f7bc9285a88c2b5551d3f16a2ddd005789614a34c5f4a598c2a162383",
-                "sha256:d6bf085f6f9ec6a1724c187083b37b58a8048f86036d42d21802ed5d1fae4853",
-                "sha256:da737ab273f4d60ae552f82ad83f7cbd0e173ca30ca20b160f708c92742ee212",
-                "sha256:eb84e7e5b07ff3725ab05977ac56d5eeb0c510795aeb48e8b691491be3c5745b"
-            ],
-            "version": "==7.1.1"
-        },
-        "pycodestyle": {
-            "hashes": [
-                "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56",
-                "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c"
-            ],
-            "version": "==2.5.0"
-        },
-        "pydocstyle": {
-            "hashes": [
-                "sha256:da7831660b7355307b32778c4a0dbfb137d89254ef31a2b2978f50fc0b4d7586",
-                "sha256:f4f5d210610c2d153fae39093d44224c17429e2ad7da12a8b419aba5c2f614b5"
-            ],
-            "version": "==5.0.2"
-        },
-        "pyflakes": {
-            "hashes": [
-                "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92",
-                "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"
-            ],
-            "version": "==2.2.0"
-        },
-        "pygments": {
-            "hashes": [
-                "sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44",
-                "sha256:ff7a40b4860b727ab48fad6360eb351cc1b33cbf9b15a0f689ca5353e9463324"
-            ],
-            "version": "==2.6.1"
-        },
-        "pylama": {
-            "hashes": [
-                "sha256:9bae53ef9c1a431371d6a8dca406816a60d547147b60a4934721898f553b7d8f",
-                "sha256:fd61c11872d6256b019ef1235be37b77c922ef37ac9797df6bd489996dddeb15"
-            ],
-            "index": "pypi",
-            "version": "==7.7.1"
-        },
-        "pyparsing": {
-            "hashes": [
-                "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1",
-                "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"
-            ],
-            "version": "==2.4.7"
-        },
-        "pytz": {
-            "hashes": [
-                "sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d",
-                "sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be"
-            ],
-            "version": "==2019.3"
-        },
-        "releases": {
-            "hashes": [
-                "sha256:555ae4c97a671a420281c1c782e9236be25157b449fdf20b4c4b293fe93db2f1",
-                "sha256:cb3435ba372a6807433800fbe473760cfa781171513f670f3c4b76983ac80f18"
-            ],
-            "index": "pypi",
-            "version": "==1.6.3"
-        },
-        "requests": {
-            "hashes": [
-                "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee",
-                "sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6"
-            ],
-            "version": "==2.23.0"
-        },
-        "semantic-version": {
-            "hashes": [
-                "sha256:2a4328680073e9b243667b201119772aefc5fc63ae32398d6afafff07c4f54c0",
-                "sha256:2d06ab7372034bcb8b54f2205370f4aa0643c133b7e6dbd129c5200b83ab394b"
-            ],
-            "version": "==2.6.0"
-        },
-        "six": {
-            "hashes": [
-                "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a",
-                "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"
-            ],
-            "version": "==1.14.0"
-        },
-        "snowballstemmer": {
-            "hashes": [
-                "sha256:209f257d7533fdb3cb73bdbd24f436239ca3b2fa67d56f6ff88e86be08cc5ef0",
-                "sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52"
-            ],
-            "version": "==2.0.0"
-        },
-        "sphinx": {
-            "hashes": [
-                "sha256:6a099e6faffdc3ceba99ca8c2d09982d43022245e409249375edf111caf79ed3",
-                "sha256:b63a0c879c4ff9a4dffcb05217fa55672ce07abdeb81e33c73303a563f8d8901"
-            ],
-            "index": "pypi",
-            "version": "==3.0.0"
-        },
-        "sphinxcontrib-applehelp": {
-            "hashes": [
-                "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a",
-                "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"
-            ],
-            "version": "==1.0.2"
-        },
-        "sphinxcontrib-blockdiag": {
-            "hashes": [
-                "sha256:51ce7cff8d25dfd4c8a753d5aa5491e6dbf280004719c49e8001e583ecda7d91",
-                "sha256:91fd35b64f1f25db59d80b8a5196ed4ffadf57a81f63ee207e34d53ec36d8f97"
-            ],
-            "index": "pypi",
-            "version": "==2.0.0"
-        },
-        "sphinxcontrib-devhelp": {
-            "hashes": [
-                "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e",
-                "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"
-            ],
-            "version": "==1.0.2"
-        },
-        "sphinxcontrib-htmlhelp": {
-            "hashes": [
-                "sha256:3c0bc24a2c41e340ac37c85ced6dafc879ab485c095b1d65d2461ac2f7cca86f",
-                "sha256:e8f5bb7e31b2dbb25b9cc435c8ab7a79787ebf7f906155729338f3156d93659b"
-            ],
-            "version": "==1.0.3"
-        },
-        "sphinxcontrib-jsmath": {
-            "hashes": [
-                "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178",
-                "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"
-            ],
-            "version": "==1.0.1"
-        },
-        "sphinxcontrib-qthelp": {
-            "hashes": [
-                "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72",
-                "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"
-            ],
-            "version": "==1.0.3"
-        },
-        "sphinxcontrib-serializinghtml": {
-            "hashes": [
-                "sha256:eaa0eccc86e982a9b939b2b82d12cc5d013385ba5eadcc7e4fed23f4405f77bc",
-                "sha256:f242a81d423f59617a8e5cf16f5d4d74e28ee9a66f9e5b637a18082991db5a9a"
-            ],
-            "version": "==1.1.4"
-        },
-        "sqlparse": {
-            "hashes": [
-                "sha256:022fb9c87b524d1f7862b3037e541f68597a730a8843245c349fc93e1643dc4e",
-                "sha256:e162203737712307dfe78860cc56c8da8a852ab2ee33750e33aeadf38d12c548"
-            ],
-            "version": "==0.3.1"
-        },
-        "urllib3": {
-            "hashes": [
-                "sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc",
-                "sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc"
-            ],
-            "version": "==1.25.8"
-        },
-        "webcolors": {
-            "hashes": [
-                "sha256:76f360636957d1c976db7466bc71dcb713bb95ac8911944dffc55c01cb516de6",
-                "sha256:b8cd5d865a25c51ff1218f0c90d0c0781fc64312a49b746b320cf50de1648f6e"
-            ],
-            "version": "==1.11.1"
-        }
-    }
-}
diff --git a/poetry.lock b/poetry.lock
new file mode 100644
index 0000000..d96f1cb
--- /dev/null
+++ b/poetry.lock
@@ -0,0 +1,1738 @@
+# This file is automatically @generated by Poetry and should not be changed by hand.
+
+[[package]]
+name = "alabaster"
+version = "0.7.13"
+description = "A configurable sidebar-enabled Sphinx theme"
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"},
+    {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"},
+]
+
+[[package]]
+name = "amqp"
+version = "5.1.1"
+description = "Low-level AMQP client for Python (fork of amqplib)."
+category = "main"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "amqp-5.1.1-py3-none-any.whl", hash = "sha256:6f0956d2c23d8fa6e7691934d8c3930eadb44972cbbd1a7ae3a520f735d43359"},
+    {file = "amqp-5.1.1.tar.gz", hash = "sha256:2c1b13fecc0893e946c65cbd5f36427861cffa4ea2201d8f6fca22e2a373b5e2"},
+]
+
+[package.dependencies]
+vine = ">=5.0.0"
+
+[[package]]
+name = "async-timeout"
+version = "4.0.2"
+description = "Timeout context manager for asyncio programs"
+category = "main"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"},
+    {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"},
+]
+
+[package.dependencies]
+typing-extensions = {version = ">=3.6.5", markers = "python_version < \"3.8\""}
+
+[[package]]
+name = "babel"
+version = "2.11.0"
+description = "Internationalization utilities"
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "Babel-2.11.0-py3-none-any.whl", hash = "sha256:1ad3eca1c885218f6dce2ab67291178944f810a10a9b5f3cb8382a5a232b64fe"},
+    {file = "Babel-2.11.0.tar.gz", hash = "sha256:5ef4b3226b0180dedded4229651c8b0e1a3a6a2837d45a073272f313e4cf97f6"},
+]
+
+[package.dependencies]
+pytz = ">=2015.7"
+
+[[package]]
+name = "billiard"
+version = "3.6.4.0"
+description = "Python multiprocessing fork with improvements and bugfixes"
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+    {file = "billiard-3.6.4.0-py3-none-any.whl", hash = "sha256:87103ea78fa6ab4d5c751c4909bcff74617d985de7fa8b672cf8618afd5a875b"},
+    {file = "billiard-3.6.4.0.tar.gz", hash = "sha256:299de5a8da28a783d51b197d496bef4f1595dd023a93a4f59dde1886ae905547"},
+]
+
+[[package]]
+name = "black"
+version = "23.1.0"
+description = "The uncompromising code formatter."
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "black-23.1.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:b6a92a41ee34b883b359998f0c8e6eb8e99803aa8bf3123bf2b2e6fec505a221"},
+    {file = "black-23.1.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:57c18c5165c1dbe291d5306e53fb3988122890e57bd9b3dcb75f967f13411a26"},
+    {file = "black-23.1.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:9880d7d419bb7e709b37e28deb5e68a49227713b623c72b2b931028ea65f619b"},
+    {file = "black-23.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6663f91b6feca5d06f2ccd49a10f254f9298cc1f7f49c46e498a0771b507104"},
+    {file = "black-23.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:9afd3f493666a0cd8f8df9a0200c6359ac53940cbde049dcb1a7eb6ee2dd7074"},
+    {file = "black-23.1.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:bfffba28dc52a58f04492181392ee380e95262af14ee01d4bc7bb1b1c6ca8d27"},
+    {file = "black-23.1.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c1c476bc7b7d021321e7d93dc2cbd78ce103b84d5a4cf97ed535fbc0d6660648"},
+    {file = "black-23.1.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:382998821f58e5c8238d3166c492139573325287820963d2f7de4d518bd76958"},
+    {file = "black-23.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bf649fda611c8550ca9d7592b69f0637218c2369b7744694c5e4902873b2f3a"},
+    {file = "black-23.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:121ca7f10b4a01fd99951234abdbd97728e1240be89fde18480ffac16503d481"},
+    {file = "black-23.1.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:a8471939da5e824b891b25751955be52ee7f8a30a916d570a5ba8e0f2eb2ecad"},
+    {file = "black-23.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8178318cb74f98bc571eef19068f6ab5613b3e59d4f47771582f04e175570ed8"},
+    {file = "black-23.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a436e7881d33acaf2536c46a454bb964a50eff59b21b51c6ccf5a40601fbef24"},
+    {file = "black-23.1.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:a59db0a2094d2259c554676403fa2fac3473ccf1354c1c63eccf7ae65aac8ab6"},
+    {file = "black-23.1.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:0052dba51dec07ed029ed61b18183942043e00008ec65d5028814afaab9a22fd"},
+    {file = "black-23.1.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:49f7b39e30f326a34b5c9a4213213a6b221d7ae9d58ec70df1c4a307cf2a1580"},
+    {file = "black-23.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:162e37d49e93bd6eb6f1afc3e17a3d23a823042530c37c3c42eeeaf026f38468"},
+    {file = "black-23.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b70eb40a78dfac24842458476135f9b99ab952dd3f2dab738c1881a9b38b753"},
+    {file = "black-23.1.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:a29650759a6a0944e7cca036674655c2f0f63806ddecc45ed40b7b8aa314b651"},
+    {file = "black-23.1.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:bb460c8561c8c1bec7824ecbc3ce085eb50005883a6203dcfb0122e95797ee06"},
+    {file = "black-23.1.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:c91dfc2c2a4e50df0026f88d2215e166616e0c80e86004d0003ece0488db2739"},
+    {file = "black-23.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a951cc83ab535d248c89f300eccbd625e80ab880fbcfb5ac8afb5f01a258ac9"},
+    {file = "black-23.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:0680d4380db3719ebcfb2613f34e86c8e6d15ffeabcf8ec59355c5e7b85bb555"},
+    {file = "black-23.1.0-py3-none-any.whl", hash = "sha256:7a0f701d314cfa0896b9001df70a530eb2472babb76086344e688829efd97d32"},
+    {file = "black-23.1.0.tar.gz", hash = "sha256:b0bd97bea8903f5a2ba7219257a44e3f1f9d00073d6cc1add68f0beec69692ac"},
+]
+
+[package.dependencies]
+click = ">=8.0.0"
+mypy-extensions = ">=0.4.3"
+packaging = ">=22.0"
+pathspec = ">=0.9.0"
+platformdirs = ">=2"
+tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
+typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""}
+typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}
+
+[package.extras]
+colorama = ["colorama (>=0.4.3)"]
+d = ["aiohttp (>=3.7.4)"]
+jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
+uvloop = ["uvloop (>=0.15.2)"]
+
+[[package]]
+name = "blockdiag"
+version = "3.0.0"
+description = "blockdiag generates block-diagram image from text"
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "blockdiag-3.0.0-py3-none-any.whl", hash = "sha256:4031bfae6a7f36071d733dec639987346e10f7871356ee2c7a221961c64961d8"},
+    {file = "blockdiag-3.0.0.tar.gz", hash = "sha256:dee4195bb87d23654546ba2bf5091480dbf253b409891fce2cd527c91d00a3e2"},
+]
+
+[package.dependencies]
+funcparserlib = ">=1.0.0a0"
+Pillow = ">3.0"
+setuptools = "*"
+webcolors = "*"
+
+[package.extras]
+pdf = ["reportlab"]
+rst = ["docutils"]
+testing = ["docutils", "flake8", "flake8-coding", "flake8-copyright", "flake8-isort", "nose", "reportlab"]
+
+[[package]]
+name = "cached-property"
+version = "1.5.2"
+description = "A decorator for caching properties in classes."
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+    {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"},
+    {file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"},
+]
+
+[[package]]
+name = "celery"
+version = "5.2.7"
+description = "Distributed Task Queue."
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "celery-5.2.7-py3-none-any.whl", hash = "sha256:138420c020cd58d6707e6257b6beda91fd39af7afde5d36c6334d175302c0e14"},
+    {file = "celery-5.2.7.tar.gz", hash = "sha256:fafbd82934d30f8a004f81e8f7a062e31413a23d444be8ee3326553915958c6d"},
+]
+
+[package.dependencies]
+billiard = ">=3.6.4.0,<4.0"
+click = ">=8.0.3,<9.0"
+click-didyoumean = ">=0.0.3"
+click-plugins = ">=1.1.1"
+click-repl = ">=0.2.0"
+importlib-metadata = {version = ">=1.4.0", markers = "python_version < \"3.8\""}
+kombu = ">=5.2.3,<6.0"
+pytz = ">=2021.3"
+vine = ">=5.0.0,<6.0"
+
+[package.extras]
+arangodb = ["pyArango (>=1.3.2)"]
+auth = ["cryptography"]
+azureblockblob = ["azure-storage-blob (==12.9.0)"]
+brotli = ["brotli (>=1.0.0)", "brotlipy (>=0.7.0)"]
+cassandra = ["cassandra-driver (<3.21.0)"]
+consul = ["python-consul2"]
+cosmosdbsql = ["pydocumentdb (==2.3.2)"]
+couchbase = ["couchbase (>=3.0.0)"]
+couchdb = ["pycouchdb"]
+django = ["Django (>=1.11)"]
+dynamodb = ["boto3 (>=1.9.178)"]
+elasticsearch = ["elasticsearch"]
+eventlet = ["eventlet (>=0.32.0)"]
+gevent = ["gevent (>=1.5.0)"]
+librabbitmq = ["librabbitmq (>=1.5.0)"]
+memcache = ["pylibmc"]
+mongodb = ["pymongo[srv] (>=3.11.1)"]
+msgpack = ["msgpack"]
+pymemcache = ["python-memcached"]
+pyro = ["pyro4"]
+pytest = ["pytest-celery"]
+redis = ["redis (>=3.4.1,!=4.0.0,!=4.0.1)"]
+s3 = ["boto3 (>=1.9.125)"]
+slmq = ["softlayer-messaging (>=1.0.3)"]
+solar = ["ephem"]
+sqlalchemy = ["sqlalchemy"]
+sqs = ["kombu[sqs]"]
+tblib = ["tblib (>=1.3.0)", "tblib (>=1.5.0)"]
+yaml = ["PyYAML (>=3.10)"]
+zookeeper = ["kazoo (>=1.3.1)"]
+zstd = ["zstandard"]
+
+[[package]]
+name = "certifi"
+version = "2022.12.7"
+description = "Python package for providing Mozilla's CA Bundle."
+category = "main"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"},
+    {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"},
+]
+
+[[package]]
+name = "cffi"
+version = "1.15.1"
+description = "Foreign Function Interface for Python calling C code."
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+    {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"},
+    {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"},
+    {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"},
+    {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"},
+    {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"},
+    {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"},
+    {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"},
+    {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"},
+    {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"},
+    {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"},
+    {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"},
+    {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"},
+    {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"},
+    {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"},
+    {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"},
+    {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"},
+    {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"},
+    {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"},
+    {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"},
+    {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"},
+    {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"},
+    {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"},
+    {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"},
+    {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"},
+    {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"},
+    {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"},
+    {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"},
+    {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"},
+    {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"},
+    {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"},
+    {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"},
+    {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"},
+    {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"},
+    {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"},
+    {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"},
+    {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"},
+    {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"},
+    {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"},
+    {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"},
+    {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"},
+    {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"},
+    {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"},
+    {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"},
+    {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"},
+    {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"},
+    {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"},
+    {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"},
+    {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"},
+    {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"},
+    {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"},
+    {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"},
+    {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"},
+    {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"},
+    {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"},
+    {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"},
+    {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"},
+    {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"},
+    {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"},
+    {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"},
+    {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"},
+    {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"},
+    {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"},
+    {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"},
+    {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"},
+]
+
+[package.dependencies]
+pycparser = "*"
+
+[[package]]
+name = "charset-normalizer"
+version = "3.0.1"
+description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+    {file = "charset-normalizer-3.0.1.tar.gz", hash = "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f"},
+    {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6"},
+    {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db"},
+    {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539"},
+    {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d"},
+    {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8"},
+    {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e"},
+    {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d"},
+    {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783"},
+    {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555"},
+    {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639"},
+    {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76"},
+    {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6"},
+    {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e"},
+    {file = "charset_normalizer-3.0.1-cp310-cp310-win32.whl", hash = "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b"},
+    {file = "charset_normalizer-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59"},
+    {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d"},
+    {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3"},
+    {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c"},
+    {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b"},
+    {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1"},
+    {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317"},
+    {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603"},
+    {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18"},
+    {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a"},
+    {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7"},
+    {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc"},
+    {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b"},
+    {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6"},
+    {file = "charset_normalizer-3.0.1-cp311-cp311-win32.whl", hash = "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3"},
+    {file = "charset_normalizer-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c"},
+    {file = "charset_normalizer-3.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a"},
+    {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea"},
+    {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72"},
+    {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478"},
+    {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d"},
+    {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837"},
+    {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6"},
+    {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc"},
+    {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a"},
+    {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c"},
+    {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a"},
+    {file = "charset_normalizer-3.0.1-cp36-cp36m-win32.whl", hash = "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41"},
+    {file = "charset_normalizer-3.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602"},
+    {file = "charset_normalizer-3.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14"},
+    {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d"},
+    {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc"},
+    {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3"},
+    {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866"},
+    {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b"},
+    {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087"},
+    {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8"},
+    {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b"},
+    {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918"},
+    {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d"},
+    {file = "charset_normalizer-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154"},
+    {file = "charset_normalizer-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5"},
+    {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42"},
+    {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c"},
+    {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e"},
+    {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58"},
+    {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174"},
+    {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753"},
+    {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b"},
+    {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1"},
+    {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a"},
+    {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed"},
+    {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479"},
+    {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291"},
+    {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820"},
+    {file = "charset_normalizer-3.0.1-cp38-cp38-win32.whl", hash = "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e"},
+    {file = "charset_normalizer-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af"},
+    {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f"},
+    {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678"},
+    {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be"},
+    {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b"},
+    {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca"},
+    {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e"},
+    {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3"},
+    {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541"},
+    {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d"},
+    {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579"},
+    {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4"},
+    {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c"},
+    {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786"},
+    {file = "charset_normalizer-3.0.1-cp39-cp39-win32.whl", hash = "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8"},
+    {file = "charset_normalizer-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59"},
+    {file = "charset_normalizer-3.0.1-py3-none-any.whl", hash = "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24"},
+]
+
+[[package]]
+name = "click"
+version = "8.1.3"
+description = "Composable command line interface toolkit"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
+    {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "platform_system == \"Windows\""}
+importlib-metadata = {version = "*", markers = "python_version < \"3.8\""}
+
+[[package]]
+name = "click-didyoumean"
+version = "0.3.0"
+description = "Enables git-like *did-you-mean* feature in click"
+category = "main"
+optional = false
+python-versions = ">=3.6.2,<4.0.0"
+files = [
+    {file = "click-didyoumean-0.3.0.tar.gz", hash = "sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035"},
+    {file = "click_didyoumean-0.3.0-py3-none-any.whl", hash = "sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667"},
+]
+
+[package.dependencies]
+click = ">=7"
+
+[[package]]
+name = "click-plugins"
+version = "1.1.1"
+description = "An extension module for click to enable registering CLI commands via setuptools entry-points."
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+    {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"},
+    {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"},
+]
+
+[package.dependencies]
+click = ">=4.0"
+
+[package.extras]
+dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"]
+
+[[package]]
+name = "click-repl"
+version = "0.2.0"
+description = "REPL plugin for Click"
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+    {file = "click-repl-0.2.0.tar.gz", hash = "sha256:cd12f68d745bf6151210790540b4cb064c7b13e571bc64b6957d98d120dacfd8"},
+    {file = "click_repl-0.2.0-py3-none-any.whl", hash = "sha256:94b3fbbc9406a236f176e0506524b2937e4b23b6f4c0c0b2a0a83f8a64e9194b"},
+]
+
+[package.dependencies]
+click = "*"
+prompt-toolkit = "*"
+six = "*"
+
+[[package]]
+name = "colorama"
+version = "0.4.6"
+description = "Cross-platform colored terminal text."
+category = "main"
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+files = [
+    {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
+    {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
+]
+
+[[package]]
+name = "coverage"
+version = "7.1.0"
+description = "Code coverage measurement for Python"
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "coverage-7.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3b946bbcd5a8231383450b195cfb58cb01cbe7f8949f5758566b881df4b33baf"},
+    {file = "coverage-7.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec8e767f13be637d056f7e07e61d089e555f719b387a7070154ad80a0ff31801"},
+    {file = "coverage-7.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4a5a5879a939cb84959d86869132b00176197ca561c664fc21478c1eee60d75"},
+    {file = "coverage-7.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b643cb30821e7570c0aaf54feaf0bfb630b79059f85741843e9dc23f33aaca2c"},
+    {file = "coverage-7.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32df215215f3af2c1617a55dbdfb403b772d463d54d219985ac7cd3bf124cada"},
+    {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:33d1ae9d4079e05ac4cc1ef9e20c648f5afabf1a92adfaf2ccf509c50b85717f"},
+    {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:29571503c37f2ef2138a306d23e7270687c0efb9cab4bd8038d609b5c2393a3a"},
+    {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:63ffd21aa133ff48c4dff7adcc46b7ec8b565491bfc371212122dd999812ea1c"},
+    {file = "coverage-7.1.0-cp310-cp310-win32.whl", hash = "sha256:4b14d5e09c656de5038a3f9bfe5228f53439282abcab87317c9f7f1acb280352"},
+    {file = "coverage-7.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:8361be1c2c073919500b6601220a6f2f98ea0b6d2fec5014c1d9cfa23dd07038"},
+    {file = "coverage-7.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:da9b41d4539eefd408c46725fb76ecba3a50a3367cafb7dea5f250d0653c1040"},
+    {file = "coverage-7.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5b15ed7644ae4bee0ecf74fee95808dcc34ba6ace87e8dfbf5cb0dc20eab45a"},
+    {file = "coverage-7.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d12d076582507ea460ea2a89a8c85cb558f83406c8a41dd641d7be9a32e1274f"},
+    {file = "coverage-7.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2617759031dae1bf183c16cef8fcfb3de7617f394c813fa5e8e46e9b82d4222"},
+    {file = "coverage-7.1.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4e4881fa9e9667afcc742f0c244d9364d197490fbc91d12ac3b5de0bf2df146"},
+    {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9d58885215094ab4a86a6aef044e42994a2bd76a446dc59b352622655ba6621b"},
+    {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ffeeb38ee4a80a30a6877c5c4c359e5498eec095878f1581453202bfacc8fbc2"},
+    {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3baf5f126f30781b5e93dbefcc8271cb2491647f8283f20ac54d12161dff080e"},
+    {file = "coverage-7.1.0-cp311-cp311-win32.whl", hash = "sha256:ded59300d6330be27bc6cf0b74b89ada58069ced87c48eaf9344e5e84b0072f7"},
+    {file = "coverage-7.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:6a43c7823cd7427b4ed763aa7fb63901ca8288591323b58c9cd6ec31ad910f3c"},
+    {file = "coverage-7.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7a726d742816cb3a8973c8c9a97539c734b3a309345236cd533c4883dda05b8d"},
+    {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc7c85a150501286f8b56bd8ed3aa4093f4b88fb68c0843d21ff9656f0009d6a"},
+    {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b4198d85a3755d27e64c52f8c95d6333119e49fd001ae5798dac872c95e0f8"},
+    {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddb726cb861c3117a553f940372a495fe1078249ff5f8a5478c0576c7be12050"},
+    {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:51b236e764840a6df0661b67e50697aaa0e7d4124ca95e5058fa3d7cbc240b7c"},
+    {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7ee5c9bb51695f80878faaa5598040dd6c9e172ddcf490382e8aedb8ec3fec8d"},
+    {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c31b75ae466c053a98bf26843563b3b3517b8f37da4d47b1c582fdc703112bc3"},
+    {file = "coverage-7.1.0-cp37-cp37m-win32.whl", hash = "sha256:3b155caf3760408d1cb903b21e6a97ad4e2bdad43cbc265e3ce0afb8e0057e73"},
+    {file = "coverage-7.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2a60d6513781e87047c3e630b33b4d1e89f39836dac6e069ffee28c4786715f5"},
+    {file = "coverage-7.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2cba5c6db29ce991029b5e4ac51eb36774458f0a3b8d3137241b32d1bb91f06"},
+    {file = "coverage-7.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beeb129cacea34490ffd4d6153af70509aa3cda20fdda2ea1a2be870dfec8d52"},
+    {file = "coverage-7.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c45948f613d5d18c9ec5eaa203ce06a653334cf1bd47c783a12d0dd4fd9c851"},
+    {file = "coverage-7.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef382417db92ba23dfb5864a3fc9be27ea4894e86620d342a116b243ade5d35d"},
+    {file = "coverage-7.1.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c7c0d0827e853315c9bbd43c1162c006dd808dbbe297db7ae66cd17b07830f0"},
+    {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e5cdbb5cafcedea04924568d990e20ce7f1945a1dd54b560f879ee2d57226912"},
+    {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9817733f0d3ea91bea80de0f79ef971ae94f81ca52f9b66500c6a2fea8e4b4f8"},
+    {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:218fe982371ac7387304153ecd51205f14e9d731b34fb0568181abaf7b443ba0"},
+    {file = "coverage-7.1.0-cp38-cp38-win32.whl", hash = "sha256:04481245ef966fbd24ae9b9e537ce899ae584d521dfbe78f89cad003c38ca2ab"},
+    {file = "coverage-7.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:8ae125d1134bf236acba8b83e74c603d1b30e207266121e76484562bc816344c"},
+    {file = "coverage-7.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2bf1d5f2084c3932b56b962a683074a3692bce7cabd3aa023c987a2a8e7612f6"},
+    {file = "coverage-7.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:98b85dd86514d889a2e3dd22ab3c18c9d0019e696478391d86708b805f4ea0fa"},
+    {file = "coverage-7.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38da2db80cc505a611938d8624801158e409928b136c8916cd2e203970dde4dc"},
+    {file = "coverage-7.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3164d31078fa9efe406e198aecd2a02d32a62fecbdef74f76dad6a46c7e48311"},
+    {file = "coverage-7.1.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db61a79c07331e88b9a9974815c075fbd812bc9dbc4dc44b366b5368a2936063"},
+    {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ccb092c9ede70b2517a57382a601619d20981f56f440eae7e4d7eaafd1d1d09"},
+    {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:33ff26d0f6cc3ca8de13d14fde1ff8efe1456b53e3f0273e63cc8b3c84a063d8"},
+    {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d47dd659a4ee952e90dc56c97d78132573dc5c7b09d61b416a9deef4ebe01a0c"},
+    {file = "coverage-7.1.0-cp39-cp39-win32.whl", hash = "sha256:d248cd4a92065a4d4543b8331660121b31c4148dd00a691bfb7a5cdc7483cfa4"},
+    {file = "coverage-7.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:7ed681b0f8e8bcbbffa58ba26fcf5dbc8f79e7997595bf071ed5430d8c08d6f3"},
+    {file = "coverage-7.1.0-pp37.pp38.pp39-none-any.whl", hash = "sha256:755e89e32376c850f826c425ece2c35a4fc266c081490eb0a841e7c1cb0d3bda"},
+    {file = "coverage-7.1.0.tar.gz", hash = "sha256:10188fe543560ec4874f974b5305cd1a8bdcfa885ee00ea3a03733464c4ca265"},
+]
+
+[package.extras]
+toml = ["tomli"]
+
+[[package]]
+name = "cryptography"
+version = "39.0.1"
+description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
+category = "main"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "cryptography-39.0.1-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:6687ef6d0a6497e2b58e7c5b852b53f62142cfa7cd1555795758934da363a965"},
+    {file = "cryptography-39.0.1-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:706843b48f9a3f9b9911979761c91541e3d90db1ca905fd63fee540a217698bc"},
+    {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:5d2d8b87a490bfcd407ed9d49093793d0f75198a35e6eb1a923ce1ee86c62b41"},
+    {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83e17b26de248c33f3acffb922748151d71827d6021d98c70e6c1a25ddd78505"},
+    {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e124352fd3db36a9d4a21c1aa27fd5d051e621845cb87fb851c08f4f75ce8be6"},
+    {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:5aa67414fcdfa22cf052e640cb5ddc461924a045cacf325cd164e65312d99502"},
+    {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:35f7c7d015d474f4011e859e93e789c87d21f6f4880ebdc29896a60403328f1f"},
+    {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f24077a3b5298a5a06a8e0536e3ea9ec60e4c7ac486755e5fb6e6ea9b3500106"},
+    {file = "cryptography-39.0.1-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:f0c64d1bd842ca2633e74a1a28033d139368ad959872533b1bab8c80e8240a0c"},
+    {file = "cryptography-39.0.1-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:0f8da300b5c8af9f98111ffd512910bc792b4c77392a9523624680f7956a99d4"},
+    {file = "cryptography-39.0.1-cp36-abi3-win32.whl", hash = "sha256:fe913f20024eb2cb2f323e42a64bdf2911bb9738a15dba7d3cce48151034e3a8"},
+    {file = "cryptography-39.0.1-cp36-abi3-win_amd64.whl", hash = "sha256:ced4e447ae29ca194449a3f1ce132ded8fcab06971ef5f618605aacaa612beac"},
+    {file = "cryptography-39.0.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:807ce09d4434881ca3a7594733669bd834f5b2c6d5c7e36f8c00f691887042ad"},
+    {file = "cryptography-39.0.1-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c5caeb8188c24888c90b5108a441c106f7faa4c4c075a2bcae438c6e8ca73cef"},
+    {file = "cryptography-39.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4789d1e3e257965e960232345002262ede4d094d1a19f4d3b52e48d4d8f3b885"},
+    {file = "cryptography-39.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:96f1157a7c08b5b189b16b47bc9db2332269d6680a196341bf30046330d15388"},
+    {file = "cryptography-39.0.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e422abdec8b5fa8462aa016786680720d78bdce7a30c652b7fadf83a4ba35336"},
+    {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:b0afd054cd42f3d213bf82c629efb1ee5f22eba35bf0eec88ea9ea7304f511a2"},
+    {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:6f8ba7f0328b79f08bdacc3e4e66fb4d7aab0c3584e0bd41328dce5262e26b2e"},
+    {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:ef8b72fa70b348724ff1218267e7f7375b8de4e8194d1636ee60510aae104cd0"},
+    {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:aec5a6c9864be7df2240c382740fcf3b96928c46604eaa7f3091f58b878c0bb6"},
+    {file = "cryptography-39.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fdd188c8a6ef8769f148f88f859884507b954cc64db6b52f66ef199bb9ad660a"},
+    {file = "cryptography-39.0.1.tar.gz", hash = "sha256:d1f6198ee6d9148405e49887803907fe8962a23e6c6f83ea7d98f1c0de375695"},
+]
+
+[package.dependencies]
+cffi = ">=1.12"
+
+[package.extras]
+docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"]
+docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"]
+pep8test = ["black", "check-manifest", "mypy", "ruff", "types-pytz", "types-requests"]
+sdist = ["setuptools-rust (>=0.11.4)"]
+ssh = ["bcrypt (>=3.1.5)"]
+test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist", "pytz"]
+test-randomorder = ["pytest-randomly"]
+tox = ["tox"]
+
+[[package]]
+name = "defusedxml"
+version = "0.7.1"
+description = "XML bomb protection for Python stdlib modules"
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+files = [
+    {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"},
+    {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"},
+]
+
+[[package]]
+name = "django"
+version = "2.2.28"
+description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design."
+category = "main"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "Django-2.2.28-py3-none-any.whl", hash = "sha256:365429d07c1336eb42ba15aa79f45e1c13a0b04d5c21569e7d596696418a6a45"},
+    {file = "Django-2.2.28.tar.gz", hash = "sha256:0200b657afbf1bc08003845ddda053c7641b9b24951e52acd51f6abda33a7413"},
+]
+
+[package.dependencies]
+pytz = "*"
+sqlparse = ">=0.2.2"
+
+[package.extras]
+argon2 = ["argon2-cffi (>=16.1.0)"]
+bcrypt = ["bcrypt"]
+
+[[package]]
+name = "django-allauth"
+version = "0.52.0"
+description = "Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication."
+category = "main"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "django-allauth-0.52.0.tar.gz", hash = "sha256:e380661ceafe55734c40102819ae720403027036f28e9f9827f0faeddc24ed5f"},
+]
+
+[package.dependencies]
+Django = ">=2.0"
+pyjwt = {version = ">=1.7", extras = ["crypto"]}
+python3-openid = ">=3.0.8"
+requests = "*"
+requests-oauthlib = ">=0.3.0"
+
+[[package]]
+name = "django-braces"
+version = "1.15.0"
+description = "Reusable, generic mixins for Django"
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+    {file = "django-braces-1.15.0.tar.gz", hash = "sha256:f451d08ffc1078d81209a2e17f2219bce20196928853c82405451b18a46875e0"},
+    {file = "django_braces-1.15.0-py2.py3-none-any.whl", hash = "sha256:28f00b0f98368c9a37f30cce6087fc57127f0a24c5b8b449f9e1245bded6405d"},
+]
+
+[package.dependencies]
+Django = ">=2.2"
+
+[[package]]
+name = "django-crispy-forms"
+version = "1.14.0"
+description = "Best way to have Django DRY forms"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "django-crispy-forms-1.14.0.tar.gz", hash = "sha256:35887b8851a931374dd697207a8f56c57a9c5cb9dbf0b9fa54314da5666cea5b"},
+    {file = "django_crispy_forms-1.14.0-py3-none-any.whl", hash = "sha256:bc4d2037f6de602d39c0bc452ac3029d1f5d65e88458872cc4dbc01c3a400604"},
+]
+
+[[package]]
+name = "django-debug-toolbar"
+version = "3.2.4"
+description = "A configurable set of panels that display various debug information about the current request/response."
+category = "main"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "django-debug-toolbar-3.2.4.tar.gz", hash = "sha256:644bbd5c428d3283aa9115722471769cac1bec189edf3a0c855fd8ff870375a9"},
+    {file = "django_debug_toolbar-3.2.4-py3-none-any.whl", hash = "sha256:6b633b6cfee24f232d73569870f19aa86c819d750e7f3e833f2344a9eb4b4409"},
+]
+
+[package.dependencies]
+Django = ">=2.2"
+sqlparse = ">=0.2.0"
+
+[[package]]
+name = "django-model-utils"
+version = "4.0.0"
+description = "Django model mixins and utilities"
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+    {file = "django-model-utils-4.0.0.tar.gz", hash = "sha256:adf09e5be15122a7f4e372cb5a6dd512bbf8d78a23a90770ad0983ee9d909061"},
+    {file = "django_model_utils-4.0.0-py2.py3-none-any.whl", hash = "sha256:9cf882e5b604421b62dbe57ad2b18464dc9c8f963fc3f9831badccae66c1139c"},
+]
+
+[package.dependencies]
+Django = ">=2.0.1"
+
+[[package]]
+name = "docutils"
+version = "0.19"
+description = "Docutils -- Python Documentation Utilities"
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc"},
+    {file = "docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6"},
+]
+
+[[package]]
+name = "funcparserlib"
+version = "1.0.1"
+description = "Recursive descent parsing library based on functional combinators"
+category = "dev"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*"
+files = [
+    {file = "funcparserlib-1.0.1-py2.py3-none-any.whl", hash = "sha256:95da15d3f0d00b9b6f4bf04005c708af3faa115f7b45692ace064ebe758c68e8"},
+    {file = "funcparserlib-1.0.1.tar.gz", hash = "sha256:a2c4a0d7942f7a0e7635c369d921066c8d4cae7f8b5bf7914466bec3c69837f4"},
+]
+
+[[package]]
+name = "gvacommon"
+version = "0.5.0"
+description = "common utility code for gnuviechadmin applications"
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+    {file = "gvacommon-0.5.0-py3-none-any.whl", hash = "sha256:adf1ebc824433196d112764c61d9ca869481d33f612818c2840069f57ab42c25"},
+]
+
+[package.dependencies]
+Django = "*"
+
+[package.source]
+type = "legacy"
+url = "https://pypi.gnuviech-server.de/simple"
+reference = "gnuviech"
+
+[[package]]
+name = "idna"
+version = "3.4"
+description = "Internationalized Domain Names in Applications (IDNA)"
+category = "main"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
+    {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
+]
+
+[[package]]
+name = "imagesize"
+version = "1.4.1"
+description = "Getting image size from png/jpeg/jpeg2000/gif file"
+category = "dev"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+    {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"},
+    {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"},
+]
+
+[[package]]
+name = "importlib-metadata"
+version = "4.13.0"
+description = "Read metadata from Python packages"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "importlib_metadata-4.13.0-py3-none-any.whl", hash = "sha256:8a8a81bcf996e74fee46f0d16bd3eaa382a7eb20fd82445c3ad11f4090334116"},
+    {file = "importlib_metadata-4.13.0.tar.gz", hash = "sha256:dd0173e8f150d6815e098fd354f6414b0f079af4644ddfe90c71e2fc6174346d"},
+]
+
+[package.dependencies]
+typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""}
+zipp = ">=0.5"
+
+[package.extras]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"]
+perf = ["ipython"]
+testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"]
+
+[[package]]
+name = "isort"
+version = "4.3.21"
+description = "A Python utility / library to sort Python imports."
+category = "dev"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+    {file = "isort-4.3.21-py2.py3-none-any.whl", hash = "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"},
+    {file = "isort-4.3.21.tar.gz", hash = "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1"},
+]
+
+[package.extras]
+pipfile = ["pipreqs", "requirementslib"]
+pyproject = ["toml"]
+requirements = ["pip-api", "pipreqs"]
+xdg-home = ["appdirs (>=1.4.0)"]
+
+[[package]]
+name = "jinja2"
+version = "3.1.2"
+description = "A very fast and expressive template engine."
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
+    {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
+]
+
+[package.dependencies]
+MarkupSafe = ">=2.0"
+
+[package.extras]
+i18n = ["Babel (>=2.7)"]
+
+[[package]]
+name = "kombu"
+version = "5.2.4"
+description = "Messaging library for Python."
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "kombu-5.2.4-py3-none-any.whl", hash = "sha256:8b213b24293d3417bcf0d2f5537b7f756079e3ea232a8386dcc89a59fd2361a4"},
+    {file = "kombu-5.2.4.tar.gz", hash = "sha256:37cee3ee725f94ea8bb173eaab7c1760203ea53bbebae226328600f9d2799610"},
+]
+
+[package.dependencies]
+amqp = ">=5.0.9,<6.0.0"
+cached-property = {version = "*", markers = "python_version < \"3.8\""}
+importlib-metadata = {version = ">=0.18", markers = "python_version < \"3.8\""}
+vine = "*"
+
+[package.extras]
+azureservicebus = ["azure-servicebus (>=7.0.0)"]
+azurestoragequeues = ["azure-storage-queue"]
+consul = ["python-consul (>=0.6.0)"]
+librabbitmq = ["librabbitmq (>=2.0.0)"]
+mongodb = ["pymongo (>=3.3.0,<3.12.1)"]
+msgpack = ["msgpack"]
+pyro = ["pyro4"]
+qpid = ["qpid-python (>=0.26)", "qpid-tools (>=0.26)"]
+redis = ["redis (>=3.4.1,!=4.0.0,!=4.0.1)"]
+slmq = ["softlayer-messaging (>=1.0.3)"]
+sqlalchemy = ["sqlalchemy"]
+sqs = ["boto3 (>=1.9.12)", "pycurl (>=7.44.1,<7.45.0)", "urllib3 (>=1.26.7)"]
+yaml = ["PyYAML (>=3.10)"]
+zookeeper = ["kazoo (>=1.3.1)"]
+
+[[package]]
+name = "markupsafe"
+version = "2.1.2"
+description = "Safely add untrusted strings to HTML/XML markup."
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"},
+    {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"},
+    {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"},
+    {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"},
+    {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"},
+    {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"},
+    {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"},
+]
+
+[[package]]
+name = "mccabe"
+version = "0.7.0"
+description = "McCabe checker, plugin for flake8"
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
+    {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
+]
+
+[[package]]
+name = "mypy-extensions"
+version = "1.0.0"
+description = "Type system extensions for programs checked with the mypy type checker."
+category = "dev"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
+    {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
+]
+
+[[package]]
+name = "oauthlib"
+version = "3.2.2"
+description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic"
+category = "main"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"},
+    {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"},
+]
+
+[package.extras]
+rsa = ["cryptography (>=3.0.0)"]
+signals = ["blinker (>=1.4.0)"]
+signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"]
+
+[[package]]
+name = "packaging"
+version = "23.0"
+description = "Core utilities for Python packages"
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"},
+    {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"},
+]
+
+[[package]]
+name = "passlib"
+version = "1.7.4"
+description = "comprehensive password hashing framework supporting over 30 schemes"
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+    {file = "passlib-1.7.4-py2.py3-none-any.whl", hash = "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1"},
+    {file = "passlib-1.7.4.tar.gz", hash = "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04"},
+]
+
+[package.extras]
+argon2 = ["argon2-cffi (>=18.2.0)"]
+bcrypt = ["bcrypt (>=3.1.0)"]
+build-docs = ["cloud-sptheme (>=1.10.1)", "sphinx (>=1.6)", "sphinxcontrib-fulltoc (>=1.2.0)"]
+totp = ["cryptography"]
+
+[[package]]
+name = "pathspec"
+version = "0.11.0"
+description = "Utility library for gitignore style pattern matching of file paths."
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "pathspec-0.11.0-py3-none-any.whl", hash = "sha256:3a66eb970cbac598f9e5ccb5b2cf58930cd8e3ed86d393d541eaf2d8b1705229"},
+    {file = "pathspec-0.11.0.tar.gz", hash = "sha256:64d338d4e0914e91c1792321e6907b5a593f1ab1851de7fc269557a21b30ebbc"},
+]
+
+[[package]]
+name = "pillow"
+version = "9.4.0"
+description = "Python Imaging Library (Fork)"
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "Pillow-9.4.0-1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b4b4e9dda4f4e4c4e6896f93e84a8f0bcca3b059de9ddf67dac3c334b1195e1"},
+    {file = "Pillow-9.4.0-1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:fb5c1ad6bad98c57482236a21bf985ab0ef42bd51f7ad4e4538e89a997624e12"},
+    {file = "Pillow-9.4.0-1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:f0caf4a5dcf610d96c3bd32932bfac8aee61c96e60481c2a0ea58da435e25acd"},
+    {file = "Pillow-9.4.0-1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:3f4cc516e0b264c8d4ccd6b6cbc69a07c6d582d8337df79be1e15a5056b258c9"},
+    {file = "Pillow-9.4.0-1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:b8c2f6eb0df979ee99433d8b3f6d193d9590f735cf12274c108bd954e30ca858"},
+    {file = "Pillow-9.4.0-1-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b70756ec9417c34e097f987b4d8c510975216ad26ba6e57ccb53bc758f490dab"},
+    {file = "Pillow-9.4.0-1-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:43521ce2c4b865d385e78579a082b6ad1166ebed2b1a2293c3be1d68dd7ca3b9"},
+    {file = "Pillow-9.4.0-2-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:9d9a62576b68cd90f7075876f4e8444487db5eeea0e4df3ba298ee38a8d067b0"},
+    {file = "Pillow-9.4.0-2-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:87708d78a14d56a990fbf4f9cb350b7d89ee8988705e58e39bdf4d82c149210f"},
+    {file = "Pillow-9.4.0-2-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:8a2b5874d17e72dfb80d917213abd55d7e1ed2479f38f001f264f7ce7bae757c"},
+    {file = "Pillow-9.4.0-2-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:83125753a60cfc8c412de5896d10a0a405e0bd88d0470ad82e0869ddf0cb3848"},
+    {file = "Pillow-9.4.0-2-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9e5f94742033898bfe84c93c831a6f552bb629448d4072dd312306bab3bd96f1"},
+    {file = "Pillow-9.4.0-2-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:013016af6b3a12a2f40b704677f8b51f72cb007dac785a9933d5c86a72a7fe33"},
+    {file = "Pillow-9.4.0-2-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:99d92d148dd03fd19d16175b6d355cc1b01faf80dae93c6c3eb4163709edc0a9"},
+    {file = "Pillow-9.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:2968c58feca624bb6c8502f9564dd187d0e1389964898f5e9e1fbc8533169157"},
+    {file = "Pillow-9.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c5c1362c14aee73f50143d74389b2c158707b4abce2cb055b7ad37ce60738d47"},
+    {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd752c5ff1b4a870b7661234694f24b1d2b9076b8bf337321a814c612665f343"},
+    {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a3049a10261d7f2b6514d35bbb7a4dfc3ece4c4de14ef5876c4b7a23a0e566d"},
+    {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16a8df99701f9095bea8a6c4b3197da105df6f74e6176c5b410bc2df2fd29a57"},
+    {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:94cdff45173b1919350601f82d61365e792895e3c3a3443cf99819e6fbf717a5"},
+    {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:ed3e4b4e1e6de75fdc16d3259098de7c6571b1a6cc863b1a49e7d3d53e036070"},
+    {file = "Pillow-9.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5b2f8a31bd43e0f18172d8ac82347c8f37ef3e0b414431157718aa234991b28"},
+    {file = "Pillow-9.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:09b89ddc95c248ee788328528e6a2996e09eaccddeeb82a5356e92645733be35"},
+    {file = "Pillow-9.4.0-cp310-cp310-win32.whl", hash = "sha256:f09598b416ba39a8f489c124447b007fe865f786a89dbfa48bb5cf395693132a"},
+    {file = "Pillow-9.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:f6e78171be3fb7941f9910ea15b4b14ec27725865a73c15277bc39f5ca4f8391"},
+    {file = "Pillow-9.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:3fa1284762aacca6dc97474ee9c16f83990b8eeb6697f2ba17140d54b453e133"},
+    {file = "Pillow-9.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:eaef5d2de3c7e9b21f1e762f289d17b726c2239a42b11e25446abf82b26ac132"},
+    {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4dfdae195335abb4e89cc9762b2edc524f3c6e80d647a9a81bf81e17e3fb6f0"},
+    {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6abfb51a82e919e3933eb137e17c4ae9c0475a25508ea88993bb59faf82f3b35"},
+    {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:451f10ef963918e65b8869e17d67db5e2f4ab40e716ee6ce7129b0cde2876eab"},
+    {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:6663977496d616b618b6cfa43ec86e479ee62b942e1da76a2c3daa1c75933ef4"},
+    {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:60e7da3a3ad1812c128750fc1bc14a7ceeb8d29f77e0a2356a8fb2aa8925287d"},
+    {file = "Pillow-9.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:19005a8e58b7c1796bc0167862b1f54a64d3b44ee5d48152b06bb861458bc0f8"},
+    {file = "Pillow-9.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f715c32e774a60a337b2bb8ad9839b4abf75b267a0f18806f6f4f5f1688c4b5a"},
+    {file = "Pillow-9.4.0-cp311-cp311-win32.whl", hash = "sha256:b222090c455d6d1a64e6b7bb5f4035c4dff479e22455c9eaa1bdd4c75b52c80c"},
+    {file = "Pillow-9.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:ba6612b6548220ff5e9df85261bddc811a057b0b465a1226b39bfb8550616aee"},
+    {file = "Pillow-9.4.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5f532a2ad4d174eb73494e7397988e22bf427f91acc8e6ebf5bb10597b49c493"},
+    {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dd5a9c3091a0f414a963d427f920368e2b6a4c2f7527fdd82cde8ef0bc7a327"},
+    {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef21af928e807f10bf4141cad4746eee692a0dd3ff56cfb25fce076ec3cc8abe"},
+    {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:847b114580c5cc9ebaf216dd8c8dbc6b00a3b7ab0131e173d7120e6deade1f57"},
+    {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:653d7fb2df65efefbcbf81ef5fe5e5be931f1ee4332c2893ca638c9b11a409c4"},
+    {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:46f39cab8bbf4a384ba7cb0bc8bae7b7062b6a11cfac1ca4bc144dea90d4a9f5"},
+    {file = "Pillow-9.4.0-cp37-cp37m-win32.whl", hash = "sha256:7ac7594397698f77bce84382929747130765f66406dc2cd8b4ab4da68ade4c6e"},
+    {file = "Pillow-9.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:46c259e87199041583658457372a183636ae8cd56dbf3f0755e0f376a7f9d0e6"},
+    {file = "Pillow-9.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:0e51f608da093e5d9038c592b5b575cadc12fd748af1479b5e858045fff955a9"},
+    {file = "Pillow-9.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:765cb54c0b8724a7c12c55146ae4647e0274a839fb6de7bcba841e04298e1011"},
+    {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:519e14e2c49fcf7616d6d2cfc5c70adae95682ae20f0395e9280db85e8d6c4df"},
+    {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d197df5489004db87d90b918033edbeee0bd6df3848a204bca3ff0a903bef837"},
+    {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0845adc64fe9886db00f5ab68c4a8cd933ab749a87747555cec1c95acea64b0b"},
+    {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:e1339790c083c5a4de48f688b4841f18df839eb3c9584a770cbd818b33e26d5d"},
+    {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:a96e6e23f2b79433390273eaf8cc94fec9c6370842e577ab10dabdcc7ea0a66b"},
+    {file = "Pillow-9.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7cfc287da09f9d2a7ec146ee4d72d6ea1342e770d975e49a8621bf54eaa8f30f"},
+    {file = "Pillow-9.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d7081c084ceb58278dd3cf81f836bc818978c0ccc770cbbb202125ddabec6628"},
+    {file = "Pillow-9.4.0-cp38-cp38-win32.whl", hash = "sha256:df41112ccce5d47770a0c13651479fbcd8793f34232a2dd9faeccb75eb5d0d0d"},
+    {file = "Pillow-9.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:7a21222644ab69ddd9967cfe6f2bb420b460dae4289c9d40ff9a4896e7c35c9a"},
+    {file = "Pillow-9.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0f3269304c1a7ce82f1759c12ce731ef9b6e95b6df829dccd9fe42912cc48569"},
+    {file = "Pillow-9.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cb362e3b0976dc994857391b776ddaa8c13c28a16f80ac6522c23d5257156bed"},
+    {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2e0f87144fcbbe54297cae708c5e7f9da21a4646523456b00cc956bd4c65815"},
+    {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:28676836c7796805914b76b1837a40f76827ee0d5398f72f7dcc634bae7c6264"},
+    {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0884ba7b515163a1a05440a138adeb722b8a6ae2c2b33aea93ea3118dd3a899e"},
+    {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:53dcb50fbdc3fb2c55431a9b30caeb2f7027fcd2aeb501459464f0214200a503"},
+    {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:e8c5cf126889a4de385c02a2c3d3aba4b00f70234bfddae82a5eaa3ee6d5e3e6"},
+    {file = "Pillow-9.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6c6b1389ed66cdd174d040105123a5a1bc91d0aa7059c7261d20e583b6d8cbd2"},
+    {file = "Pillow-9.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0dd4c681b82214b36273c18ca7ee87065a50e013112eea7d78c7a1b89a739153"},
+    {file = "Pillow-9.4.0-cp39-cp39-win32.whl", hash = "sha256:6d9dfb9959a3b0039ee06c1a1a90dc23bac3b430842dcb97908ddde05870601c"},
+    {file = "Pillow-9.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:54614444887e0d3043557d9dbc697dbb16cfb5a35d672b7a0fcc1ed0cf1c600b"},
+    {file = "Pillow-9.4.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b9b752ab91e78234941e44abdecc07f1f0d8f51fb62941d32995b8161f68cfe5"},
+    {file = "Pillow-9.4.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3b56206244dc8711f7e8b7d6cad4663917cd5b2d950799425076681e8766286"},
+    {file = "Pillow-9.4.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aabdab8ec1e7ca7f1434d042bf8b1e92056245fb179790dc97ed040361f16bfd"},
+    {file = "Pillow-9.4.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:db74f5562c09953b2c5f8ec4b7dfd3f5421f31811e97d1dbc0a7c93d6e3a24df"},
+    {file = "Pillow-9.4.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e9d7747847c53a16a729b6ee5e737cf170f7a16611c143d95aa60a109a59c336"},
+    {file = "Pillow-9.4.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b52ff4f4e002f828ea6483faf4c4e8deea8d743cf801b74910243c58acc6eda3"},
+    {file = "Pillow-9.4.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:575d8912dca808edd9acd6f7795199332696d3469665ef26163cd090fa1f8bfa"},
+    {file = "Pillow-9.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3c4ed2ff6760e98d262e0cc9c9a7f7b8a9f61aa4d47c58835cdaf7b0b8811bb"},
+    {file = "Pillow-9.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e621b0246192d3b9cb1dc62c78cfa4c6f6d2ddc0ec207d43c0dedecb914f152a"},
+    {file = "Pillow-9.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:8f127e7b028900421cad64f51f75c051b628db17fb00e099eb148761eed598c9"},
+    {file = "Pillow-9.4.0.tar.gz", hash = "sha256:a1c2d7780448eb93fbcc3789bf3916aa5720d942e37945f4056680317f1cd23e"},
+]
+
+[package.extras]
+docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-issues (>=3.0.1)", "sphinx-removed-in", "sphinxext-opengraph"]
+tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"]
+
+[[package]]
+name = "platformdirs"
+version = "3.0.0"
+description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "platformdirs-3.0.0-py3-none-any.whl", hash = "sha256:b1d5eb14f221506f50d6604a561f4c5786d9e80355219694a1b244bcd96f4567"},
+    {file = "platformdirs-3.0.0.tar.gz", hash = "sha256:8a1228abb1ef82d788f74139988b137e78692984ec7b08eaa6c65f1723af28f9"},
+]
+
+[package.dependencies]
+typing-extensions = {version = ">=4.4", markers = "python_version < \"3.8\""}
+
+[package.extras]
+docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
+
+[[package]]
+name = "prompt-toolkit"
+version = "3.0.36"
+description = "Library for building powerful interactive command lines in Python"
+category = "main"
+optional = false
+python-versions = ">=3.6.2"
+files = [
+    {file = "prompt_toolkit-3.0.36-py3-none-any.whl", hash = "sha256:aa64ad242a462c5ff0363a7b9cfe696c20d55d9fc60c11fd8e632d064804d305"},
+    {file = "prompt_toolkit-3.0.36.tar.gz", hash = "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63"},
+]
+
+[package.dependencies]
+wcwidth = "*"
+
+[[package]]
+name = "psycopg2-binary"
+version = "2.8.6"
+description = "psycopg2 - Python-PostgreSQL Database Adapter"
+category = "main"
+optional = false
+python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
+files = [
+    {file = "psycopg2-binary-2.8.6.tar.gz", hash = "sha256:11b9c0ebce097180129e422379b824ae21c8f2a6596b159c7659e2e5a00e1aa0"},
+    {file = "psycopg2_binary-2.8.6-cp27-cp27m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:d14b140a4439d816e3b1229a4a525df917d6ea22a0771a2a78332273fd9528a4"},
+    {file = "psycopg2_binary-2.8.6-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1fabed9ea2acc4efe4671b92c669a213db744d2af8a9fc5d69a8e9bc14b7a9db"},
+    {file = "psycopg2_binary-2.8.6-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:f5ab93a2cb2d8338b1674be43b442a7f544a0971da062a5da774ed40587f18f5"},
+    {file = "psycopg2_binary-2.8.6-cp27-cp27m-win32.whl", hash = "sha256:b4afc542c0ac0db720cf516dd20c0846f71c248d2b3d21013aa0d4ef9c71ca25"},
+    {file = "psycopg2_binary-2.8.6-cp27-cp27m-win_amd64.whl", hash = "sha256:e74a55f6bad0e7d3968399deb50f61f4db1926acf4a6d83beaaa7df986f48b1c"},
+    {file = "psycopg2_binary-2.8.6-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:0deac2af1a587ae12836aa07970f5cb91964f05a7c6cdb69d8425ff4c15d4e2c"},
+    {file = "psycopg2_binary-2.8.6-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ad20d2eb875aaa1ea6d0f2916949f5c08a19c74d05b16ce6ebf6d24f2c9f75d1"},
+    {file = "psycopg2_binary-2.8.6-cp34-cp34m-win32.whl", hash = "sha256:950bc22bb56ee6ff142a2cb9ee980b571dd0912b0334aa3fe0fe3788d860bea2"},
+    {file = "psycopg2_binary-2.8.6-cp34-cp34m-win_amd64.whl", hash = "sha256:b8a3715b3c4e604bcc94c90a825cd7f5635417453b253499664f784fc4da0152"},
+    {file = "psycopg2_binary-2.8.6-cp35-cp35m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:d1b4ab59e02d9008efe10ceabd0b31e79519da6fb67f7d8e8977118832d0f449"},
+    {file = "psycopg2_binary-2.8.6-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:ac0c682111fbf404525dfc0f18a8b5f11be52657d4f96e9fcb75daf4f3984859"},
+    {file = "psycopg2_binary-2.8.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7d92a09b788cbb1aec325af5fcba9fed7203897bbd9269d5691bb1e3bce29550"},
+    {file = "psycopg2_binary-2.8.6-cp35-cp35m-win32.whl", hash = "sha256:aaa4213c862f0ef00022751161df35804127b78adf4a2755b9f991a507e425fd"},
+    {file = "psycopg2_binary-2.8.6-cp35-cp35m-win_amd64.whl", hash = "sha256:c2507d796fca339c8fb03216364cca68d87e037c1f774977c8fc377627d01c71"},
+    {file = "psycopg2_binary-2.8.6-cp36-cp36m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:ee69dad2c7155756ad114c02db06002f4cded41132cc51378e57aad79cc8e4f4"},
+    {file = "psycopg2_binary-2.8.6-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:e82aba2188b9ba309fd8e271702bd0d0fc9148ae3150532bbb474f4590039ffb"},
+    {file = "psycopg2_binary-2.8.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d5227b229005a696cc67676e24c214740efd90b148de5733419ac9aaba3773da"},
+    {file = "psycopg2_binary-2.8.6-cp36-cp36m-win32.whl", hash = "sha256:a0eb43a07386c3f1f1ebb4dc7aafb13f67188eab896e7397aa1ee95a9c884eb2"},
+    {file = "psycopg2_binary-2.8.6-cp36-cp36m-win_amd64.whl", hash = "sha256:e1f57aa70d3f7cc6947fd88636a481638263ba04a742b4a37dd25c373e41491a"},
+    {file = "psycopg2_binary-2.8.6-cp37-cp37m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:833709a5c66ca52f1d21d41865a637223b368c0ee76ea54ca5bad6f2526c7679"},
+    {file = "psycopg2_binary-2.8.6-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ba28584e6bca48c59eecbf7efb1576ca214b47f05194646b081717fa628dfddf"},
+    {file = "psycopg2_binary-2.8.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:6a32f3a4cb2f6e1a0b15215f448e8ce2da192fd4ff35084d80d5e39da683e79b"},
+    {file = "psycopg2_binary-2.8.6-cp37-cp37m-win32.whl", hash = "sha256:0e4dc3d5996760104746e6cfcdb519d9d2cd27c738296525d5867ea695774e67"},
+    {file = "psycopg2_binary-2.8.6-cp37-cp37m-win_amd64.whl", hash = "sha256:cec7e622ebc545dbb4564e483dd20e4e404da17ae07e06f3e780b2dacd5cee66"},
+    {file = "psycopg2_binary-2.8.6-cp38-cp38-macosx_10_9_x86_64.macosx_10_9_intel.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:ba381aec3a5dc29634f20692349d73f2d21f17653bda1decf0b52b11d694541f"},
+    {file = "psycopg2_binary-2.8.6-cp38-cp38-manylinux1_i686.whl", hash = "sha256:a0c50db33c32594305b0ef9abc0cb7db13de7621d2cadf8392a1d9b3c437ef77"},
+    {file = "psycopg2_binary-2.8.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2dac98e85565d5688e8ab7bdea5446674a83a3945a8f416ad0110018d1501b94"},
+    {file = "psycopg2_binary-2.8.6-cp38-cp38-win32.whl", hash = "sha256:bd1be66dde2b82f80afb9459fc618216753f67109b859a361cf7def5c7968729"},
+    {file = "psycopg2_binary-2.8.6-cp38-cp38-win_amd64.whl", hash = "sha256:8cd0fb36c7412996859cb4606a35969dd01f4ea34d9812a141cd920c3b18be77"},
+    {file = "psycopg2_binary-2.8.6-cp39-cp39-macosx_10_9_x86_64.macosx_10_9_intel.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:89705f45ce07b2dfa806ee84439ec67c5d9a0ef20154e0e475e2b2ed392a5b83"},
+    {file = "psycopg2_binary-2.8.6-cp39-cp39-manylinux1_i686.whl", hash = "sha256:42ec1035841b389e8cc3692277a0bd81cdfe0b65d575a2c8862cec7a80e62e52"},
+    {file = "psycopg2_binary-2.8.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7312e931b90fe14f925729cde58022f5d034241918a5c4f9797cac62f6b3a9dd"},
+    {file = "psycopg2_binary-2.8.6-cp39-cp39-win32.whl", hash = "sha256:6422f2ff0919fd720195f64ffd8f924c1395d30f9a495f31e2392c2efafb5056"},
+    {file = "psycopg2_binary-2.8.6-cp39-cp39-win_amd64.whl", hash = "sha256:15978a1fbd225583dd8cdaf37e67ccc278b5abecb4caf6b2d6b8e2b948e953f6"},
+]
+
+[[package]]
+name = "pycodestyle"
+version = "2.10.0"
+description = "Python style guide checker"
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "pycodestyle-2.10.0-py2.py3-none-any.whl", hash = "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"},
+    {file = "pycodestyle-2.10.0.tar.gz", hash = "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053"},
+]
+
+[[package]]
+name = "pycparser"
+version = "2.21"
+description = "C parser in Python"
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+    {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
+    {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
+]
+
+[[package]]
+name = "pydocstyle"
+version = "6.3.0"
+description = "Python docstring style checker"
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"},
+    {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"},
+]
+
+[package.dependencies]
+importlib-metadata = {version = ">=2.0.0,<5.0.0", markers = "python_version < \"3.8\""}
+snowballstemmer = ">=2.2.0"
+
+[package.extras]
+toml = ["tomli (>=1.2.3)"]
+
+[[package]]
+name = "pyflakes"
+version = "3.0.1"
+description = "passive checker of Python programs"
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "pyflakes-3.0.1-py2.py3-none-any.whl", hash = "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf"},
+    {file = "pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"},
+]
+
+[[package]]
+name = "pygments"
+version = "2.14.0"
+description = "Pygments is a syntax highlighting package written in Python."
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "Pygments-2.14.0-py3-none-any.whl", hash = "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"},
+    {file = "Pygments-2.14.0.tar.gz", hash = "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297"},
+]
+
+[package.extras]
+plugins = ["importlib-metadata"]
+
+[[package]]
+name = "pyjwt"
+version = "2.6.0"
+description = "JSON Web Token implementation in Python"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "PyJWT-2.6.0-py3-none-any.whl", hash = "sha256:d83c3d892a77bbb74d3e1a2cfa90afaadb60945205d1095d9221f04466f64c14"},
+    {file = "PyJWT-2.6.0.tar.gz", hash = "sha256:69285c7e31fc44f68a1feb309e948e0df53259d579295e6cfe2b1792329f05fd"},
+]
+
+[package.dependencies]
+cryptography = {version = ">=3.4.0", optional = true, markers = "extra == \"crypto\""}
+
+[package.extras]
+crypto = ["cryptography (>=3.4.0)"]
+dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"]
+docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"]
+tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"]
+
+[[package]]
+name = "pylama"
+version = "8.4.1"
+description = "Code audit tool for python"
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "pylama-8.4.1-py3-none-any.whl", hash = "sha256:5bbdbf5b620aba7206d688ed9fc917ecd3d73e15ec1a89647037a09fa3a86e60"},
+    {file = "pylama-8.4.1.tar.gz", hash = "sha256:2d4f7aecfb5b7466216d48610c7d6bad1c3990c29cdd392ad08259b161e486f6"},
+]
+
+[package.dependencies]
+mccabe = ">=0.7.0"
+pycodestyle = ">=2.9.1"
+pydocstyle = ">=6.1.1"
+pyflakes = ">=2.5.0"
+
+[package.extras]
+all = ["eradicate", "mypy", "pylint", "radon", "vulture"]
+eradicate = ["eradicate"]
+mypy = ["mypy"]
+pylint = ["pylint"]
+radon = ["radon"]
+tests = ["eradicate (>=2.0.0)", "mypy", "pylama-quotes", "pylint (>=2.11.1)", "pytest (>=7.1.2)", "pytest-mypy", "radon (>=5.1.0)", "toml", "types-setuptools", "types-toml", "vulture"]
+toml = ["toml (>=0.10.2)"]
+vulture = ["vulture"]
+
+[[package]]
+name = "python3-openid"
+version = "3.2.0"
+description = "OpenID support for modern servers and consumers."
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+    {file = "python3-openid-3.2.0.tar.gz", hash = "sha256:33fbf6928f401e0b790151ed2b5290b02545e8775f982485205a066f874aaeaf"},
+    {file = "python3_openid-3.2.0-py3-none-any.whl", hash = "sha256:6626f771e0417486701e0b4daff762e7212e820ca5b29fcc0d05f6f8736dfa6b"},
+]
+
+[package.dependencies]
+defusedxml = "*"
+
+[package.extras]
+mysql = ["mysql-connector-python"]
+postgresql = ["psycopg2"]
+
+[[package]]
+name = "pytz"
+version = "2022.7.1"
+description = "World timezone definitions, modern and historical"
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+    {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"},
+    {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"},
+]
+
+[[package]]
+name = "redis"
+version = "4.5.1"
+description = "Python client for Redis database and key-value store"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "redis-4.5.1-py3-none-any.whl", hash = "sha256:5deb072d26e67d2be1712603bfb7947ec3431fb0eec9c578994052e33035af6d"},
+    {file = "redis-4.5.1.tar.gz", hash = "sha256:1eec3741cda408d3a5f84b78d089c8b8d895f21b3b050988351e925faf202864"},
+]
+
+[package.dependencies]
+async-timeout = ">=4.0.2"
+importlib-metadata = {version = ">=1.0", markers = "python_version < \"3.8\""}
+typing-extensions = {version = "*", markers = "python_version < \"3.8\""}
+
+[package.extras]
+hiredis = ["hiredis (>=1.0.0)"]
+ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"]
+
+[[package]]
+name = "releases"
+version = "2.0.0"
+description = "A Sphinx extension for changelog manipulation"
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "releases-2.0.0-py3-none-any.whl", hash = "sha256:ea6470d8d2ecb4161845a4e169527aecb8b9a8a628c590ae0855dd11fd6e8864"},
+    {file = "releases-2.0.0.tar.gz", hash = "sha256:99296a3acab3838e27e96ec5c3713450982f385b6b6fd54fc9e2425393972e8c"},
+]
+
+[package.dependencies]
+semantic-version = "<2.7"
+sphinx = ">=4"
+
+[[package]]
+name = "requests"
+version = "2.28.2"
+description = "Python HTTP for Humans."
+category = "main"
+optional = false
+python-versions = ">=3.7, <4"
+files = [
+    {file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"},
+    {file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"},
+]
+
+[package.dependencies]
+certifi = ">=2017.4.17"
+charset-normalizer = ">=2,<4"
+idna = ">=2.5,<4"
+urllib3 = ">=1.21.1,<1.27"
+
+[package.extras]
+socks = ["PySocks (>=1.5.6,!=1.5.7)"]
+use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
+
+[[package]]
+name = "requests-oauthlib"
+version = "1.3.1"
+description = "OAuthlib authentication support for Requests."
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+    {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"},
+    {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"},
+]
+
+[package.dependencies]
+oauthlib = ">=3.0.0"
+requests = ">=2.0.0"
+
+[package.extras]
+rsa = ["oauthlib[signedtoken] (>=3.0.0)"]
+
+[[package]]
+name = "semantic-version"
+version = "2.6.0"
+description = "A library implementing the 'SemVer' scheme."
+category = "dev"
+optional = false
+python-versions = "*"
+files = [
+    {file = "semantic_version-2.6.0-py3-none-any.whl", hash = "sha256:2d06ab7372034bcb8b54f2205370f4aa0643c133b7e6dbd129c5200b83ab394b"},
+    {file = "semantic_version-2.6.0.tar.gz", hash = "sha256:2a4328680073e9b243667b201119772aefc5fc63ae32398d6afafff07c4f54c0"},
+]
+
+[[package]]
+name = "setuptools"
+version = "67.3.2"
+description = "Easily download, build, install, upgrade, and uninstall Python packages"
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "setuptools-67.3.2-py3-none-any.whl", hash = "sha256:bb6d8e508de562768f2027902929f8523932fcd1fb784e6d573d2cafac995a48"},
+    {file = "setuptools-67.3.2.tar.gz", hash = "sha256:95f00380ef2ffa41d9bba85d95b27689d923c93dfbafed4aecd7cf988a25e012"},
+]
+
+[package.extras]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
+testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
+testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
+
+[[package]]
+name = "six"
+version = "1.16.0"
+description = "Python 2 and 3 compatibility utilities"
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
+files = [
+    {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
+    {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
+]
+
+[[package]]
+name = "snowballstemmer"
+version = "2.2.0"
+description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
+category = "dev"
+optional = false
+python-versions = "*"
+files = [
+    {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
+    {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
+]
+
+[[package]]
+name = "sphinx"
+version = "5.3.0"
+description = "Python documentation generator"
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "Sphinx-5.3.0.tar.gz", hash = "sha256:51026de0a9ff9fc13c05d74913ad66047e104f56a129ff73e174eb5c3ee794b5"},
+    {file = "sphinx-5.3.0-py3-none-any.whl", hash = "sha256:060ca5c9f7ba57a08a1219e547b269fadf125ae25b06b9fa7f66768efb652d6d"},
+]
+
+[package.dependencies]
+alabaster = ">=0.7,<0.8"
+babel = ">=2.9"
+colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
+docutils = ">=0.14,<0.20"
+imagesize = ">=1.3"
+importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""}
+Jinja2 = ">=3.0"
+packaging = ">=21.0"
+Pygments = ">=2.12"
+requests = ">=2.5.0"
+snowballstemmer = ">=2.0"
+sphinxcontrib-applehelp = "*"
+sphinxcontrib-devhelp = "*"
+sphinxcontrib-htmlhelp = ">=2.0.0"
+sphinxcontrib-jsmath = "*"
+sphinxcontrib-qthelp = "*"
+sphinxcontrib-serializinghtml = ">=1.1.5"
+
+[package.extras]
+docs = ["sphinxcontrib-websupport"]
+lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-bugbear", "flake8-comprehensions", "flake8-simplify", "isort", "mypy (>=0.981)", "sphinx-lint", "types-requests", "types-typed-ast"]
+test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"]
+
+[[package]]
+name = "sphinxcontrib-applehelp"
+version = "1.0.2"
+description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books"
+category = "dev"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"},
+    {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["pytest"]
+
+[[package]]
+name = "sphinxcontrib-blockdiag"
+version = "3.0.0"
+description = "Sphinx \"blockdiag\" extension"
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "sphinxcontrib-blockdiag-3.0.0.tar.gz", hash = "sha256:aa49bf924516f5de8a479994c7be81e077df5599c9da2a082003d5b388e1d450"},
+    {file = "sphinxcontrib_blockdiag-3.0.0-py2.py3-none-any.whl", hash = "sha256:fc296bfb8569d5b1a6673732cd2063868c13f6f11d5b1c7cfee666297632bc06"},
+]
+
+[package.dependencies]
+blockdiag = ">=1.5.0"
+Sphinx = ">=2.0"
+
+[[package]]
+name = "sphinxcontrib-devhelp"
+version = "1.0.2"
+description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document."
+category = "dev"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"},
+    {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["pytest"]
+
+[[package]]
+name = "sphinxcontrib-htmlhelp"
+version = "2.0.0"
+description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"},
+    {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["html5lib", "pytest"]
+
+[[package]]
+name = "sphinxcontrib-jsmath"
+version = "1.0.1"
+description = "A sphinx extension which renders display math in HTML via JavaScript"
+category = "dev"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"},
+    {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"},
+]
+
+[package.extras]
+test = ["flake8", "mypy", "pytest"]
+
+[[package]]
+name = "sphinxcontrib-qthelp"
+version = "1.0.3"
+description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document."
+category = "dev"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"},
+    {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["pytest"]
+
+[[package]]
+name = "sphinxcontrib-serializinghtml"
+version = "1.1.5"
+description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)."
+category = "dev"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"},
+    {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["pytest"]
+
+[[package]]
+name = "sqlparse"
+version = "0.4.3"
+description = "A non-validating SQL parser."
+category = "main"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "sqlparse-0.4.3-py3-none-any.whl", hash = "sha256:0323c0ec29cd52bceabc1b4d9d579e311f3e4961b98d174201d5622a23b85e34"},
+    {file = "sqlparse-0.4.3.tar.gz", hash = "sha256:69ca804846bb114d2ec380e4360a8a340db83f0ccf3afceeb1404df028f57268"},
+]
+
+[[package]]
+name = "tomli"
+version = "2.0.1"
+description = "A lil' TOML parser"
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
+    {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
+]
+
+[[package]]
+name = "typed-ast"
+version = "1.5.4"
+description = "a fork of Python 2 and 3 ast modules with type comment support"
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"},
+    {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"},
+    {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"},
+    {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"},
+    {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"},
+    {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"},
+    {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"},
+    {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"},
+    {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"},
+    {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"},
+    {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"},
+    {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"},
+    {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"},
+    {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"},
+    {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"},
+    {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"},
+    {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"},
+    {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"},
+    {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"},
+    {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"},
+    {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"},
+    {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"},
+    {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"},
+    {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"},
+]
+
+[[package]]
+name = "typing-extensions"
+version = "4.5.0"
+description = "Backported and Experimental Type Hints for Python 3.7+"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"},
+    {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"},
+]
+
+[[package]]
+name = "urllib3"
+version = "1.26.14"
+description = "HTTP library with thread-safe connection pooling, file post, and more."
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
+files = [
+    {file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"},
+    {file = "urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"},
+]
+
+[package.extras]
+brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"]
+secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"]
+socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
+
+[[package]]
+name = "vine"
+version = "5.0.0"
+description = "Promises, promises, promises."
+category = "main"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "vine-5.0.0-py2.py3-none-any.whl", hash = "sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30"},
+    {file = "vine-5.0.0.tar.gz", hash = "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e"},
+]
+
+[[package]]
+name = "wcwidth"
+version = "0.2.6"
+description = "Measures the displayed width of unicode strings in a terminal"
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+    {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"},
+    {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"},
+]
+
+[[package]]
+name = "webcolors"
+version = "1.12"
+description = "A library for working with color names and color values formats defined by HTML and CSS."
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "webcolors-1.12-py3-none-any.whl", hash = "sha256:d98743d81d498a2d3eaf165196e65481f0d2ea85281463d856b1e51b09f62dce"},
+    {file = "webcolors-1.12.tar.gz", hash = "sha256:16d043d3a08fd6a1b1b7e3e9e62640d09790dce80d2bdd4792a175b35fe794a9"},
+]
+
+[[package]]
+name = "zipp"
+version = "3.14.0"
+description = "Backport of pathlib-compatible object wrapper for zip files"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "zipp-3.14.0-py3-none-any.whl", hash = "sha256:188834565033387710d046e3fe96acfc9b5e86cbca7f39ff69cf21a4128198b7"},
+    {file = "zipp-3.14.0.tar.gz", hash = "sha256:9e5421e176ef5ab4c0ad896624e87a7b2f07aca746c9b2aa305952800cb8eecb"},
+]
+
+[package.extras]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
+testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"]
+
+[metadata]
+lock-version = "2.0"
+python-versions = "^3.7"
+content-hash = "45edcf8e776501a35fd1621b430bb434206d3429455c8637a71ea652445bda6a"
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..56704ca
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,43 @@
+[tool.poetry]
+name = "gva"
+version = "0.12.1"
+description = "gnuviechadmin web interface"
+authors = ["Jan Dittberner "]
+license = "AGPL-3+"
+readme = "README.md"
+
+[tool.poetry.dependencies]
+python = "^3.7"
+django = "<3"
+psycopg2-binary = "<2.9"
+celery = "^5.2.7"
+django-allauth = "^0.52.0"
+django-braces = "^1.15.0"
+django-crispy-forms = "<2"
+django-debug-toolbar = "<3.8"
+django-model-utils = "<4.1"
+gvacommon = {version = "^0.5.0", source = "gnuviech"}
+passlib = "^1.7.4"
+redis = "^4.5.1"
+requests-oauthlib = "^1.3.1"
+
+
+[tool.poetry.group.dev.dependencies]
+coverage = "^7.1.0"
+sphinx = "<6"
+releases = "^2.0.0"
+sphinxcontrib-blockdiag = "^3.0.0"
+pylama = "^8.4.1"
+black = "^23.1.0"
+isort = "<5"
+
+
+[[tool.poetry.source]]
+name = "gnuviech"
+url = "https://pypi.gnuviech-server.de/simple"
+default = false
+secondary = false
+
+[build-system]
+requires = ["poetry-core"]
+build-backend = "poetry.core.masonry.api"
From b3588b5e6c3e93f85adeeb2e627e5f596a831a17 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sat, 18 Feb 2023 19:07:21 +0100
Subject: [PATCH 02/46] Ignore direnv .envrc
---
 .gitignore | 1 +
 1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index e90e027..fcab49b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,6 +50,7 @@ coverage-report/
 .idea/
 
 .env
+.envrc
 
 /docker/django_media
 /docker/django_static
From 0f18e59d671cdc07aa55e1cb382fa6a6d1eb92c6 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sat, 18 Feb 2023 19:07:33 +0100
Subject: [PATCH 03/46] Fix deprecation warnings
---
 gnuviechadmin/gnuviechadmin/settings.py | 34 +++++------
 gnuviechadmin/gnuviechadmin/urls.py     | 14 ++---
 gnuviechadmin/managemails/models.py     | 77 +++++++++++++------------
 gnuviechadmin/osusers/models.py         | 13 ++---
 gnuviechadmin/templates/base.html       |  2 +-
 gnuviechadmin/webtasks/tasks.py         |  2 +-
 6 files changed, 67 insertions(+), 75 deletions(-)
diff --git a/gnuviechadmin/gnuviechadmin/settings.py b/gnuviechadmin/gnuviechadmin/settings.py
index 0d9ee46..2d8e3e5 100644
--- a/gnuviechadmin/gnuviechadmin/settings.py
+++ b/gnuviechadmin/gnuviechadmin/settings.py
@@ -24,10 +24,11 @@ SITE_NAME = basename(DJANGO_ROOT)
 
 # ######### END PATH CONFIGURATION
 
+GVA_ENVIRONMENT = get_env_variable("GVA_ENVIRONMENT", default="prod")
 
 # ######### DEBUG CONFIGURATION
 # See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
-DEBUG = False
+DEBUG = (GVA_ENVIRONMENT == "local")
 # ######### END DEBUG CONFIGURATION
 
 
@@ -351,8 +352,6 @@ GVA_LINK_PHPPGADMIN = get_env_variable(
 )
 # ######### END CUSTOM APP CONFIGURATION
 
-GVA_ENVIRONMENT = get_env_variable("GVA_ENVIRONMENT", default="prod")
-
 # ######### STATIC FILE CONFIGURATION
 # See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root
 STATIC_ROOT = "/srv/gva/static/"
@@ -362,11 +361,19 @@ def show_debug_toolbar(request):
     return DEBUG and GVA_ENVIRONMENT == "local"
 
 
-if GVA_ENVIRONMENT == "local":
-    # ######### DEBUG CONFIGURATION
-    # See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
-    DEBUG = True
+# ######### TOOLBAR CONFIGURATION
+# See: http://django-debug-toolbar.readthedocs.org/en/latest/installation.html#explicit-setup # noqa
+INSTALLED_APPS += ("debug_toolbar",)
 
+MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"]
+
+DEBUG_TOOLBAR_CONFIG = {
+    "SHOW_TOOLBAR_CALLBACK": "gnuviechadmin.settings.show_debug_toolbar"
+}
+# ######### END TOOLBAR CONFIGURATION
+
+
+if GVA_ENVIRONMENT == "local":
     # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug
     TEMPLATES[0]["OPTIONS"]["debug"] = DEBUG
     # ######### END DEBUG CONFIGURATION
@@ -381,12 +388,6 @@ if GVA_ENVIRONMENT == "local":
     CACHES = {"default": {"BACKEND": "django.core.cache.backends.locmem.LocMemCache"}}
     # ######### END CACHE CONFIGURATION
 
-    # ######### TOOLBAR CONFIGURATION
-    # See: http://django-debug-toolbar.readthedocs.org/en/latest/installation.html#explicit-setup # noqa
-    INSTALLED_APPS += ("debug_toolbar",)
-
-    MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"]
-
     LOGGING["handlers"].update(
         {
             "console": {
@@ -419,13 +420,6 @@ if GVA_ENVIRONMENT == "local":
             ]
         )
     )
-
-    DEBUG_TOOLBAR_PATCH_SETTINGS = False
-    DEBUG_TOOLBAR_CONFIG = {
-        "SHOW_TOOLBAR_CALLBACK": "gnuviechadmin.settings.show_debug_toolbar"
-    }
-
-    # ######### END TOOLBAR CONFIGURATION
 elif GVA_ENVIRONMENT == "test":
     ALLOWED_HOSTS = ["localhost"]
     PASSWORD_HASHERS = ("django.contrib.auth.hashers.MD5PasswordHasher",)
diff --git a/gnuviechadmin/gnuviechadmin/urls.py b/gnuviechadmin/gnuviechadmin/urls.py
index 2b6d0b1..506c09b 100644
--- a/gnuviechadmin/gnuviechadmin/urls.py
+++ b/gnuviechadmin/gnuviechadmin/urls.py
@@ -1,11 +1,11 @@
 from __future__ import absolute_import
 
+import debug_toolbar
 from django.conf.urls import include, url
-from django.conf import settings
-
 from django.contrib import admin
 from django.contrib.flatpages import views
 from django.contrib.staticfiles.urls import staticfiles_urlpatterns
+from django.urls import path
 
 admin.autodiscover()
 
@@ -28,9 +28,7 @@ urlpatterns = [
 # Uncomment the next line to serve media files in dev.
 # urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
 
-if settings.DEBUG:  # pragma: no cover
-    import debug_toolbar
-
-    urlpatterns = [
-        url(r'^__debug__/', include(debug_toolbar.urls)),
-    ] + staticfiles_urlpatterns() + urlpatterns
+urlpatterns += staticfiles_urlpatterns()
+urlpatterns += [
+    path('__debug__/', include(debug_toolbar.urls)),
+]
diff --git a/gnuviechadmin/managemails/models.py b/gnuviechadmin/managemails/models.py
index 5d30164..6eef059 100644
--- a/gnuviechadmin/managemails/models.py
+++ b/gnuviechadmin/managemails/models.py
@@ -7,24 +7,20 @@ from __future__ import unicode_literals
 from django.db import models
 from django.utils.encoding import python_2_unicode_compatible
 from django.utils.translation import ugettext as _
-
-from passlib.hash import sha512_crypt
 from model_utils.models import TimeStampedModel
+from passlib.hash import sha512_crypt
 
 from domains.models import MailDomain
+from fileservertasks.tasks import create_file_mailbox, delete_file_mailbox
 from osusers.models import User as OsUser
 
-from fileservertasks.tasks import (
-    create_file_mailbox,
-    delete_file_mailbox,
-)
-
 
 class ActivateAbleMixin(models.Model):
     """
     Mixin for model classes that can be active or inactive.
 
     """
+
     active = models.BooleanField(default=True)
 
     class Meta:
@@ -51,10 +47,8 @@ class MailboxManager(models.Manager):
         mailboxformat = "{0}p{1:02d}"
         mailboxname = mailboxformat.format(osuser.username, count)
 
-        for box in self.values('username').filter(osuser=osuser).order_by(
-            'username'
-        ):
-            if box['username'] == mailboxname:
+        for box in self.values("username").filter(osuser=osuser).order_by("username"):
+            if box["username"] == mailboxname:
                 count += 1
                 mailboxname = mailboxformat.format(osuser.username, count)
             else:
@@ -69,9 +63,10 @@ class MailboxManager(models.Manager):
 
         """
         return self.filter(
-            models.Q(mailaddressmailbox__isnull=True) |
-            models.Q(mailaddressmailbox__mailaddress=mailaddress),
-            active=True, osuser=osuser,
+            models.Q(mailaddressmailbox__isnull=True)
+            | models.Q(mailaddressmailbox__mailaddress=mailaddress),
+            active=True,
+            osuser=osuser,
         )
 
     def unused(self, osuser):
@@ -82,7 +77,8 @@ class MailboxManager(models.Manager):
         """
         return self.filter(
             mailaddressmailbox__isnull=True,
-            active=True, osuser=osuser,
+            active=True,
+            osuser=osuser,
         )
 
     def create_mailbox(self, osuser, password=None, commit=True):
@@ -97,7 +93,8 @@ class MailboxManager(models.Manager):
 
         """
         mailbox = self.create(
-            osuser=osuser, username=self.get_next_mailbox_name(osuser))
+            osuser=osuser, username=self.get_next_mailbox_name(osuser)
+        )
         if password is not None:
             mailbox.set_password(password)
         return mailbox
@@ -109,6 +106,7 @@ class Mailbox(ActivateAbleMixin, TimeStampedModel):
     This is the model class for a mailbox.
 
     """
+
     osuser = models.ForeignKey(OsUser, on_delete=models.CASCADE)
     username = models.CharField(max_length=128, unique=True)
     password = models.CharField(max_length=255)
@@ -116,9 +114,9 @@ class Mailbox(ActivateAbleMixin, TimeStampedModel):
     objects = MailboxManager()
 
     class Meta:
-        ordering = ['osuser', 'username']
-        verbose_name = _('Mailbox')
-        verbose_name_plural = _('Mailboxes')
+        ordering = ["osuser", "username"]
+        verbose_name = _("Mailbox")
+        verbose_name_plural = _("Mailboxes")
 
     def set_password(self, password):
         """
@@ -127,7 +125,7 @@ class Mailbox(ActivateAbleMixin, TimeStampedModel):
         :param str password: the clear text password
 
         """
-        self.password = sha512_crypt.encrypt(password)
+        self.password = sha512_crypt.hash(password)
 
     def save(self, *args, **kwargs):
         # TODO: refactor to use signals
@@ -144,11 +142,9 @@ class Mailbox(ActivateAbleMixin, TimeStampedModel):
         Get a list of mail addresses assigned to this mailbox.
 
         """
-        addrs = [
-            mbadr.mailaddress for mbadr in
-            self.mailaddressmailbox_set.all()
-        ]
+        addrs = [mbadr.mailaddress for mbadr in self.mailaddressmailbox_set.all()]
         return addrs
+
     mailaddresses = property(get_mailaddresses)
 
     def __str__(self):
@@ -161,15 +157,17 @@ class MailAddress(ActivateAbleMixin, TimeStampedModel, models.Model):
     This is the model class for a mail address.
 
     """
-    localpart = models.CharField(_('local part'), max_length=128)
+
+    localpart = models.CharField(_("local part"), max_length=128)
     domain = models.ForeignKey(
-        MailDomain, verbose_name=_('domain'), on_delete=models.CASCADE)
+        MailDomain, verbose_name=_("domain"), on_delete=models.CASCADE
+    )
 
     class Meta:
-        ordering = ['domain', 'localpart']
-        unique_together = ('localpart', 'domain')
-        verbose_name = _('Mail address')
-        verbose_name_plural = _('Mail addresses')
+        ordering = ["domain", "localpart"]
+        unique_together = ("localpart", "domain")
+        verbose_name = _("Mail address")
+        verbose_name_plural = _("Mail addresses")
 
     def __str__(self):
         return "{0}@{1}".format(self.localpart, self.domain)
@@ -220,8 +218,7 @@ class MailAddress(ActivateAbleMixin, TimeStampedModel, models.Model):
             if MailAddressMailbox.objects.filter(mailaddress=self).exists():
                 mabox = MailAddressMailbox.objects.get(mailaddress=self)
                 mabox.delete()
-            forwards = MailAddressForward.objects.filter(
-                mailaddress=self).all()
+            forwards = MailAddressForward.objects.filter(mailaddress=self).all()
             for item in forwards:
                 if item.target not in addresses:
                     item.delete()
@@ -250,14 +247,19 @@ class MailAddressMailbox(TimeStampedModel, models.Model):
     This is the model class to assign a mail address to a mailbox.
 
     """
+
     mailaddress = models.OneToOneField(
-        MailAddress, verbose_name=_('mailaddress'), primary_key=True,
-        on_delete=models.CASCADE)
+        MailAddress,
+        verbose_name=_("mailaddress"),
+        primary_key=True,
+        on_delete=models.CASCADE,
+    )
     mailbox = models.ForeignKey(
-        Mailbox, verbose_name=_('mailbox'), on_delete=models.CASCADE)
+        Mailbox, verbose_name=_("mailbox"), on_delete=models.CASCADE
+    )
 
     class Meta:
-        unique_together = ('mailaddress', 'mailbox')
+        unique_together = ("mailaddress", "mailbox")
 
     def __str__(self):
         return self.mailbox.username
@@ -268,8 +270,9 @@ class MailAddressForward(TimeStampedModel, models.Model):
     This is a model class to map mail addresses to forwarding addresses.
 
     """
+
     mailaddress = models.ForeignKey(MailAddress, on_delete=models.CASCADE)
     target = models.EmailField(max_length=254)
 
     class Meta:
-        unique_together = ('mailaddress', 'target')
+        unique_together = ("mailaddress", "target")
diff --git a/gnuviechadmin/osusers/models.py b/gnuviechadmin/osusers/models.py
index 14d36ff..7772d97 100644
--- a/gnuviechadmin/osusers/models.py
+++ b/gnuviechadmin/osusers/models.py
@@ -3,22 +3,19 @@ This module defines the database models of operating system users.
 
 """
 import base64
-from datetime import date
 import logging
 import os
+from datetime import date
 
-from django.db import models, transaction
 from django.conf import settings
 from django.core.exceptions import ValidationError
+from django.db import models, transaction
 from django.dispatch import Signal
 from django.utils import timezone
 from django.utils.translation import ugettext as _
-
 from model_utils.models import TimeStampedModel
-
 from passlib.hash import sha512_crypt
-from passlib.utils import generate_password
-
+from passlib.pwd import genword
 
 _LOGGER = logging.getLogger(__name__)
 
@@ -150,7 +147,7 @@ class UserManager(models.Manager):
 
         If username is None the result of :py:meth:`get_next_username` is used.
         If password is None a new password will be generated using passlib's
-        :py:func:`generate_password`.
+        :py:func:`genword`.
 
         :param customer: Django User instance this user is associated to
         :param str username: the username or None
@@ -166,7 +163,7 @@ class UserManager(models.Manager):
         if username is None:
             username = self.get_next_username()
         if password is None:
-            password = generate_password()
+            password = genword(entropy=128)
         homedir = os.path.join(settings.OSUSER_HOME_BASEPATH, username)
         group = Group.objects.create(groupname=username, gid=gid)
         user = self.create(
diff --git a/gnuviechadmin/templates/base.html b/gnuviechadmin/templates/base.html
index b6c10fb..8040f63 100644
--- a/gnuviechadmin/templates/base.html
+++ b/gnuviechadmin/templates/base.html
@@ -1,4 +1,4 @@
-{% load staticfiles i18n account %}
+{% load static i18n account %}
 
   
     
Date: Sat, 18 Feb 2023 22:46:48 +0100
Subject: [PATCH 04/46] Upgrade to Django 3.2
- update dependencies
- fix deprecation warnings
- fix tests
- skip some tests that need more work
- reformat changed code with isort and black
---
 .isort.cfg                                    |   7 +
 gnuviechadmin/contact_form/forms.py           |  48 +-
 gnuviechadmin/contact_form/urls.py            |  14 +-
 gnuviechadmin/contact_form/views.py           |  22 +-
 gnuviechadmin/dashboard/urls.py               |  19 +-
 gnuviechadmin/dashboard/views.py              |  20 +-
 gnuviechadmin/domains/__init__.py             |   1 -
 gnuviechadmin/domains/apps.py                 |   8 +-
 gnuviechadmin/domains/forms.py                |  40 +-
 .../domains/migrations/0001_initial.py        |  44 +-
 .../migrations/0002_auto_20150124_1909.py     | 111 +--
 .../migrations/0003_auto_20151105_2133.py     | 340 +++++----
 .../migrations/0004_auto_20151107_1708.py     |  83 ++-
 gnuviechadmin/domains/models.py               | 218 +++---
 gnuviechadmin/domains/tests/test_forms.py     |   4 +-
 gnuviechadmin/domains/urls.py                 |  12 +-
 gnuviechadmin/domains/views.py                |   5 +-
 .../gnuviechadmin/context_processors.py       |  52 +-
 gnuviechadmin/gnuviechadmin/settings.py       |   6 +-
 gnuviechadmin/gnuviechadmin/urls.py           |  30 +-
 gnuviechadmin/gvawebcore/forms.py             |  16 +-
 gnuviechadmin/gvawebcore/views.py             |  10 +-
 gnuviechadmin/hostingpackages/__init__.py     |   1 -
 gnuviechadmin/hostingpackages/admin.py        |  42 +-
 gnuviechadmin/hostingpackages/apps.py         |   8 +-
 gnuviechadmin/hostingpackages/forms.py        | 113 ++-
 .../migrations/0001_initial.py                | 582 ++++++++++------
 .../0001_squashed_0005_auto_20150118_1303.py  | 655 +++++++++++-------
 .../migrations/0002_auto_20150118_1149.py     |  64 +-
 .../migrations/0002_auto_20150118_1319.py     |   9 +-
 .../migrations/0003_auto_20150118_1221.py     |  17 +-
 .../migrations/0003_auto_20150118_1407.py     |  19 +-
 .../0004_customerhostingpackage_osuser.py     |  18 +-
 .../0004_customerhostingpackagedomain.py      |  68 +-
 .../migrations/0005_auto_20150118_1303.py     |  16 +-
 .../migrations/0005_auto_20150125_1508.py     |  11 +-
 .../migrations/0006_auto_20150125_1510.py     |  11 +-
 gnuviechadmin/hostingpackages/models.py       |  27 +-
 gnuviechadmin/hostingpackages/urls.py         |  48 +-
 gnuviechadmin/hostingpackages/views.py        | 209 +++---
 gnuviechadmin/managemails/__init__.py         |   1 -
 gnuviechadmin/managemails/admin.py            |  79 +--
 gnuviechadmin/managemails/apps.py             |   8 +-
 gnuviechadmin/managemails/forms.py            | 193 +++---
 .../managemails/migrations/0001_initial.py    | 215 ++++--
 .../migrations/0002_auto_20150117_1238.py     |  23 +-
 .../migrations/0003_auto_20150124_2029.py     |  26 +-
 .../migrations/0004_auto_20150125_1825.py     |  18 +-
 gnuviechadmin/managemails/models.py           |  10 +-
 gnuviechadmin/managemails/tests/test_admin.py |  16 +-
 gnuviechadmin/managemails/tests/test_forms.py | 332 ++++-----
 .../managemails/tests/test_models.py          |  20 +-
 gnuviechadmin/managemails/urls.py             |  41 +-
 gnuviechadmin/managemails/views.py            | 140 ++--
 gnuviechadmin/osusers/__init__.py             |   1 -
 gnuviechadmin/osusers/admin.py                |   3 +-
 gnuviechadmin/osusers/apps.py                 |   9 +-
 gnuviechadmin/osusers/forms.py                |   9 +-
 .../osusers/migrations/0001_initial.py        | 471 ++++++++-----
 .../migrations/0002_auto_20141226_1456.py     |  21 +-
 .../osusers/migrations/0003_user_customer.py  |  14 +-
 .../migrations/0004_auto_20150104_1751.py     |  20 +-
 .../migrations/0005_auto_20150131_2009.py     |  75 +-
 gnuviechadmin/osusers/models.py               |   6 +-
 gnuviechadmin/osusers/signals.py              | 126 ++--
 gnuviechadmin/osusers/tests/test_models.py    |   4 +-
 gnuviechadmin/osusers/tests/test_views.py     |  11 +-
 gnuviechadmin/osusers/urls.py                 |  40 +-
 gnuviechadmin/osusers/views.py                | 129 ++--
 .../management/commands/fetch_taskresults.py  |   2 -
 .../taskresults/migrations/0001_initial.py    |  37 +-
 .../migrations/0002_auto_20151011_2248.py     |  27 +-
 .../migrations/0003_auto_20160109_1524.py     |  35 +-
 gnuviechadmin/taskresults/models.py           |  35 +-
 gnuviechadmin/userdbs/__init__.py             |   1 -
 gnuviechadmin/userdbs/admin.py                |  68 +-
 gnuviechadmin/userdbs/apps.py                 |   9 +-
 gnuviechadmin/userdbs/forms.py                |  62 +-
 .../userdbs/migrations/0001_initial.py        | 128 ++--
 gnuviechadmin/userdbs/models.py               |  74 +-
 gnuviechadmin/userdbs/signals.py              | 187 +++--
 .../userdbs/tests/templatetags/test_userdb.py |  22 +-
 gnuviechadmin/userdbs/urls.py                 |  29 +-
 gnuviechadmin/userdbs/views.py                |  94 ++-
 gnuviechadmin/websites/__init__.py            |   1 -
 gnuviechadmin/websites/apps.py                |   8 +-
 gnuviechadmin/websites/forms.py               |  57 +-
 .../websites/migrations/0001_initial.py       |  62 +-
 gnuviechadmin/websites/models.py              |  37 +-
 gnuviechadmin/websites/urls.py                |  24 +-
 gnuviechadmin/websites/views.py               |  63 +-
 poetry.lock                                   | 163 +++--
 pyproject.toml                                |   9 +-
 93 files changed, 3598 insertions(+), 2725 deletions(-)
 create mode 100644 .isort.cfg
diff --git a/.isort.cfg b/.isort.cfg
new file mode 100644
index 0000000..b1316d4
--- /dev/null
+++ b/.isort.cfg
@@ -0,0 +1,7 @@
+[tool.isort]
+multi_line_output = 3
+include_trailing_comma = True
+force_grid_wrap = 0
+use_parentheses = True
+ensure_newline_before_comments = True
+line_length = 88
diff --git a/gnuviechadmin/contact_form/forms.py b/gnuviechadmin/contact_form/forms.py
index 4427eb6..8961c90 100644
--- a/gnuviechadmin/contact_form/forms.py
+++ b/gnuviechadmin/contact_form/forms.py
@@ -4,19 +4,16 @@ This module contains the form class for the contact_form app.
 """
 from __future__ import absolute_import, unicode_literals
 
-from django import forms
-from django.conf import settings
-from django.core.mail import send_mail
-from django.template import RequestContext
-from django.template import loader
-from django.urls import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from django.contrib.sites.models import Site
-from django.contrib.sites.requests import RequestSite
-
 from crispy_forms.helper import FormHelper
 from crispy_forms.layout import Submit
+from django import forms
+from django.conf import settings
+from django.contrib.sites.models import Site
+from django.contrib.sites.requests import RequestSite
+from django.core.mail import send_mail
+from django.template import RequestContext, loader
+from django.urls import reverse
+from django.utils.translation import gettext_lazy as _
 
 
 class ContactForm(forms.Form):
@@ -24,45 +21,42 @@ class ContactForm(forms.Form):
     This is the contact form class.
 
     """
-    name = forms.CharField(max_length=100, label=_('Your name'))
-    email = forms.EmailField(max_length=200, label=_('Your email address'))
-    body = forms.CharField(widget=forms.Textarea, label=_('Your message'))
+
+    name = forms.CharField(max_length=100, label=_("Your name"))
+    email = forms.EmailField(max_length=200, label=_("Your email address"))
+    body = forms.CharField(widget=forms.Textarea, label=_("Your message"))
 
     subject_template_name = "contact_form/contact_form_subject.txt"
-    template_name = 'contact_form/contact_form.txt'
+    template_name = "contact_form/contact_form.txt"
     from_email = settings.DEFAULT_FROM_EMAIL
     recipient_list = [mail_tuple[1] for mail_tuple in settings.MANAGERS]
 
     def __init__(self, **kwargs):
-        self.request = kwargs.pop('request')
+        self.request = kwargs.pop("request")
         super(ContactForm, self).__init__(**kwargs)
         self.helper = FormHelper()
-        self.helper.form_action = reverse('contact_form')
-        self.helper.add_input(Submit('submit', _('Send message')))
+        self.helper.form_action = reverse("contact_form")
+        self.helper.add_input(Submit("submit", _("Send message")))
 
     def get_context(self):
         if not self.is_valid():
-            raise ValueError(
-                'Cannot generate context from invalid contact form')
+            raise ValueError("Cannot generate context from invalid contact form")
         if Site._meta.installed:
             site = Site.objects.get_current()
         else:
             site = RequestSite(self.request)
-        return RequestContext(
-            self.request, dict(self.cleaned_data, site=site))
+        return RequestContext(self.request, dict(self.cleaned_data, site=site))
 
     def message(self):
         context = self.get_context()
         template_context = context.flatten()
-        template_context.update({
-            'remote_ip': context.request.META['REMOTE_ADDR']
-        })
+        template_context.update({"remote_ip": context.request.META["REMOTE_ADDR"]})
         return loader.render_to_string(self.template_name, template_context)
 
     def subject(self):
         context = self.get_context().flatten()
         subject = loader.render_to_string(self.subject_template_name, context)
-        return ''.join(subject.splitlines())
+        return "".join(subject.splitlines())
 
     def save(self, fail_silently=False):
         """
@@ -74,5 +68,5 @@ class ContactForm(forms.Form):
             from_email=self.from_email,
             recipient_list=self.recipient_list,
             subject=self.subject(),
-            message=self.message()
+            message=self.message(),
         )
diff --git a/gnuviechadmin/contact_form/urls.py b/gnuviechadmin/contact_form/urls.py
index e3f01ca..a77b1aa 100644
--- a/gnuviechadmin/contact_form/urls.py
+++ b/gnuviechadmin/contact_form/urls.py
@@ -2,17 +2,13 @@
 URL patterns for the contact_form views.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
-from django.conf.urls import url
-
-from .views import (
-    ContactFormView,
-    ContactSuccessView,
-)
+from django.urls import re_path
 
+from .views import ContactFormView, ContactSuccessView
 
 urlpatterns = [
-    url(r'^$', ContactFormView.as_view(), name='contact_form'),
-    url(r'^success/$', ContactSuccessView.as_view(), name='contact_success'),
+    re_path(r"^$", ContactFormView.as_view(), name="contact_form"),
+    re_path(r"^success/$", ContactSuccessView.as_view(), name="contact_success"),
 ]
diff --git a/gnuviechadmin/contact_form/views.py b/gnuviechadmin/contact_form/views.py
index a1f3aba..a0a4e05 100644
--- a/gnuviechadmin/contact_form/views.py
+++ b/gnuviechadmin/contact_form/views.py
@@ -2,14 +2,11 @@
 This module defines the views of the contact_form app.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
 from django.shortcuts import redirect
 from django.urls import reverse_lazy
-from django.views.generic import (
-    FormView,
-    TemplateView,
-)
+from django.views.generic import FormView, TemplateView
 
 from .forms import ContactForm
 
@@ -19,22 +16,22 @@ class ContactFormView(FormView):
     This is the contact form view.
 
     """
+
     form_class = ContactForm
-    template_name = 'contact_form/contact_form.html'
-    success_url = reverse_lazy('contact_success')
+    template_name = "contact_form/contact_form.html"
+    success_url = reverse_lazy("contact_success")
 
     def get_form_kwargs(self, **kwargs):
         kwargs = super(ContactFormView, self).get_form_kwargs(**kwargs)
-        kwargs['request'] = self.request
+        kwargs["request"] = self.request
         return kwargs
 
     def get_initial(self):
         initial = super(ContactFormView, self).get_initial()
         currentuser = self.request.user
         if currentuser.is_authenticated:
-            initial['name'] = (
-                currentuser.get_full_name() or currentuser.username)
-            initial['email'] = currentuser.email
+            initial["name"] = currentuser.get_full_name() or currentuser.username
+            initial["email"] = currentuser.email
         return initial
 
     def form_valid(self, form):
@@ -47,4 +44,5 @@ class ContactSuccessView(TemplateView):
     This view is shown after successful contact form sending.
 
     """
-    template_name = 'contact_form/contact_success.html'
+
+    template_name = "contact_form/contact_success.html"
diff --git a/gnuviechadmin/dashboard/urls.py b/gnuviechadmin/dashboard/urls.py
index ffa741b..59e98d4 100644
--- a/gnuviechadmin/dashboard/urls.py
+++ b/gnuviechadmin/dashboard/urls.py
@@ -1,15 +1,14 @@
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
-from django.conf.urls import url
-
-from .views import (
-    IndexView,
-    UserDashboardView,
-)
+from django.urls import re_path
 
+from .views import IndexView, UserDashboardView
 
 urlpatterns = [
-    url(r'^$', IndexView.as_view(), name='dashboard'),
-    url(r'^user/(?P[\w0-9@.+-_]+)/$',
-        UserDashboardView.as_view(), name='customer_dashboard'),
+    re_path(r"^$", IndexView.as_view(), name="dashboard"),
+    re_path(
+        r"^user/(?P[\w0-9@.+-_]+)/$",
+        UserDashboardView.as_view(),
+        name="customer_dashboard",
+    ),
 ]
diff --git a/gnuviechadmin/dashboard/views.py b/gnuviechadmin/dashboard/views.py
index 1542e45..af9d7e0 100644
--- a/gnuviechadmin/dashboard/views.py
+++ b/gnuviechadmin/dashboard/views.py
@@ -2,14 +2,8 @@
 This module defines the views for the gnuviechadmin customer dashboard.
 
 """
-from __future__ import unicode_literals
-
-from django.views.generic import (
-    DetailView,
-    TemplateView,
-)
 from django.contrib.auth import get_user_model
-
+from django.views.generic import DetailView, TemplateView
 from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin
 
 from hostingpackages.models import CustomerHostingPackage
@@ -20,7 +14,8 @@ class IndexView(TemplateView):
     This is the dashboard view.
 
     """
-    template_name = 'dashboard/index.html'
+
+    template_name = "dashboard/index.html"
 
 
 class UserDashboardView(StaffOrSelfLoginRequiredMixin, DetailView):
@@ -28,14 +23,15 @@ class UserDashboardView(StaffOrSelfLoginRequiredMixin, DetailView):
     This is the user dashboard view.
 
     """
+
     model = get_user_model()
-    context_object_name = 'dashboard_user'
-    slug_field = 'username'
-    template_name = 'dashboard/user_dashboard.html'
+    context_object_name = "dashboard_user"
+    slug_field = "username"
+    template_name = "dashboard/user_dashboard.html"
 
     def get_context_data(self, **kwargs):
         context = super(UserDashboardView, self).get_context_data(**kwargs)
-        context['hosting_packages'] = CustomerHostingPackage.objects.filter(
+        context["hosting_packages"] = CustomerHostingPackage.objects.filter(
             customer=self.object
         )
         return context
diff --git a/gnuviechadmin/domains/__init__.py b/gnuviechadmin/domains/__init__.py
index 77d3acd..f6b1dc5 100644
--- a/gnuviechadmin/domains/__init__.py
+++ b/gnuviechadmin/domains/__init__.py
@@ -2,4 +2,3 @@
 This app takes care of domains.
 
 """
-default_app_config = 'domains.apps.DomainAppConfig'
diff --git a/gnuviechadmin/domains/apps.py b/gnuviechadmin/domains/apps.py
index 12311cc..9e903e6 100644
--- a/gnuviechadmin/domains/apps.py
+++ b/gnuviechadmin/domains/apps.py
@@ -3,9 +3,8 @@ This module contains the :py:class:`django.apps.AppConfig` instance for the
 :py:mod:`domains` app.
 
 """
-from __future__ import unicode_literals
 from django.apps import AppConfig
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 
 
 class DomainAppConfig(AppConfig):
@@ -13,5 +12,6 @@ class DomainAppConfig(AppConfig):
     AppConfig for the :py:mod:`domains` app.
 
     """
-    name = 'domains'
-    verbose_name = _('Domains')
+
+    name = "domains"
+    verbose_name = _("Domains")
diff --git a/gnuviechadmin/domains/forms.py b/gnuviechadmin/domains/forms.py
index 451e108..bd5565e 100644
--- a/gnuviechadmin/domains/forms.py
+++ b/gnuviechadmin/domains/forms.py
@@ -2,19 +2,15 @@
 This module defines form classes for domain editing.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
 import re
 
+from crispy_forms.helper import FormHelper
+from crispy_forms.layout import Layout, Submit
 from django import forms
 from django.urls import reverse
-from django.utils.translation import ugettext as _
-
-from crispy_forms.helper import FormHelper
-from crispy_forms.layout import (
-    Layout,
-    Submit,
-)
+from django.utils.translation import gettext as _
 
 from .models import HostingDomain
 
@@ -26,11 +22,10 @@ def relative_domain_validator(value):
 
     """
     if len(value) > 254:
-        raise forms.ValidationError(
-            _('host name too long'), code='too-long')
+        raise forms.ValidationError(_("host name too long"), code="too-long")
     allowed = re.compile(r"(?!-)[a-z\d-]{1,63}(?\d+)/create$', CreateHostingDomain.as_view(),
-        name='create_hosting_domain'),
+    re_path(
+        r"^(?P\d+)/create$",
+        CreateHostingDomain.as_view(),
+        name="create_hosting_domain",
+    ),
 ]
diff --git a/gnuviechadmin/domains/views.py b/gnuviechadmin/domains/views.py
index 41ca975..c81e3b4 100644
--- a/gnuviechadmin/domains/views.py
+++ b/gnuviechadmin/domains/views.py
@@ -2,15 +2,16 @@
 This module defines views related to domains.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
 from braces.views import StaffuserRequiredMixin
 from django.contrib import messages
 from django.shortcuts import get_object_or_404, redirect
-from django.utils.translation import ugettext as _
+from django.utils.translation import gettext as _
 from django.views.generic.edit import CreateView
 
 from hostingpackages.models import CustomerHostingPackage
+
 from .forms import CreateHostingDomainForm
 from .models import HostingDomain
 
diff --git a/gnuviechadmin/gnuviechadmin/context_processors.py b/gnuviechadmin/gnuviechadmin/context_processors.py
index 09f1226..4f17f19 100644
--- a/gnuviechadmin/gnuviechadmin/context_processors.py
+++ b/gnuviechadmin/gnuviechadmin/context_processors.py
@@ -2,7 +2,7 @@
 This module provides context processor implementations for gnuviechadmin.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
 import logging
 
@@ -22,38 +22,42 @@ def navigation(request):
     :rtype: dict
 
     """
-    if request.is_ajax():
+    if request.headers.get("x-requested-with") == "XMLHttpRequest":
         return {}
     context = {
-        'webmail_url': settings.GVA_LINK_WEBMAIL,
-        'phpmyadmin_url': settings.GVA_LINK_PHPMYADMIN,
-        'phppgadmin_url': settings.GVA_LINK_PHPPGADMIN,
-        'active_item': 'dashboard',
+        "webmail_url": settings.GVA_LINK_WEBMAIL,
+        "phpmyadmin_url": settings.GVA_LINK_PHPMYADMIN,
+        "phppgadmin_url": settings.GVA_LINK_PHPPGADMIN,
+        "active_item": "dashboard",
     }
     if request.resolver_match:
         viewfunc = request.resolver_match.func
         viewmodule = viewfunc.__module__
-        if viewmodule == 'contact_form.views':
-            context['active_item'] = 'contact'
+        if viewmodule == "contact_form.views":
+            context["active_item"] = "contact"
         elif viewmodule in (
-            'hostingpackages.views', 'osusers.views', 'userdbs.views',
-            'managemails.views', 'websites.views', 'domains.views',
+            "hostingpackages.views",
+            "osusers.views",
+            "userdbs.views",
+            "managemails.views",
+            "websites.views",
+            "domains.views",
         ):
-            context['active_item'] = 'hostingpackage'
-        elif viewmodule in (
-            'allauth.account.views', 'allauth.socialaccount.views'
+            context["active_item"] = "hostingpackage"
+        elif viewmodule in ("allauth.account.views", "allauth.socialaccount.views"):
+            context["active_item"] = "account"
+        elif viewmodule == "django.contrib.flatpages.views" and request.path.endswith(
+            "/impressum/"
         ):
-            context['active_item'] = 'account'
-        elif (
-            viewmodule == 'django.contrib.flatpages.views' and
-            request.path.endswith('/impressum/')
-        ):
-            context['active_item'] = 'imprint'
-        elif not viewmodule.startswith('django.contrib.admin'):
+            context["active_item"] = "imprint"
+        elif not viewmodule.startswith("django.contrib.admin"):
             _LOGGER.debug(
-                'no special handling for view %s in module %s, fallback to '
-                'default active menu item %s',
-                viewfunc.__name__, viewmodule, context['active_item'])
+                "no special handling for view %s in module %s, fallback to "
+                "default active menu item %s",
+                viewfunc.__name__,
+                viewmodule,
+                context["active_item"],
+            )
     return context
 
 
@@ -64,6 +68,6 @@ def version_info(request):
 
     """
     context = {
-        'gnuviechadmin_version': gvaversion,
+        "gnuviechadmin_version": gvaversion,
     }
     return context
diff --git a/gnuviechadmin/gnuviechadmin/settings.py b/gnuviechadmin/gnuviechadmin/settings.py
index 2d8e3e5..5e3e890 100644
--- a/gnuviechadmin/gnuviechadmin/settings.py
+++ b/gnuviechadmin/gnuviechadmin/settings.py
@@ -8,10 +8,8 @@ Common settings and globals.
 from os.path import abspath, basename, dirname, join, normpath
 
 from django.contrib.messages import constants as messages
-
 from gvacommon.settings_utils import get_env_variable
 
-
 # ######### PATH CONFIGURATION
 # Absolute filesystem path to the Django project directory:
 DJANGO_ROOT = dirname(dirname(abspath(__file__)))
@@ -28,7 +26,7 @@ GVA_ENVIRONMENT = get_env_variable("GVA_ENVIRONMENT", default="prod")
 
 # ######### DEBUG CONFIGURATION
 # See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
-DEBUG = (GVA_ENVIRONMENT == "local")
+DEBUG = GVA_ENVIRONMENT == "local"
 # ######### END DEBUG CONFIGURATION
 
 
@@ -58,6 +56,8 @@ DATABASES = {
         "PORT": get_env_variable("GVA_PGSQL_PORT", int, default=5432),
     }
 }
+
+DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
 # ######### END DATABASE CONFIGURATION
 
 
diff --git a/gnuviechadmin/gnuviechadmin/urls.py b/gnuviechadmin/gnuviechadmin/urls.py
index 506c09b..8be802e 100644
--- a/gnuviechadmin/gnuviechadmin/urls.py
+++ b/gnuviechadmin/gnuviechadmin/urls.py
@@ -1,28 +1,26 @@
 from __future__ import absolute_import
 
 import debug_toolbar
-from django.conf.urls import include, url
+from django.conf.urls import include
 from django.contrib import admin
 from django.contrib.flatpages import views
 from django.contrib.staticfiles.urls import staticfiles_urlpatterns
-from django.urls import path
+from django.urls import path, re_path
 
 admin.autodiscover()
 
 urlpatterns = [
-    url(r'', include('dashboard.urls')),
-    url(r'^accounts/', include('allauth.urls')),
-    url(r'^database/', include('userdbs.urls')),
-    url(r'^domains/', include('domains.urls')),
-    url(r'^hosting/', include('hostingpackages.urls')),
-    url(r'^website/', include('websites.urls')),
-    url(r'^mail/', include('managemails.urls')),
-    url(r'^osuser/', include('osusers.urls')),
-    url(r'^admin/', admin.site.urls),
-    url(r'^contact/', include('contact_form.urls')),
-    url(r'^impressum/$', views.flatpage, {
-        'url': '/impressum/'
-    }, name='imprint'),
+    re_path(r"", include("dashboard.urls")),
+    re_path(r"^accounts/", include("allauth.urls")),
+    re_path(r"^database/", include("userdbs.urls")),
+    re_path(r"^domains/", include("domains.urls")),
+    re_path(r"^hosting/", include("hostingpackages.urls")),
+    re_path(r"^website/", include("websites.urls")),
+    re_path(r"^mail/", include("managemails.urls")),
+    re_path(r"^osuser/", include("osusers.urls")),
+    re_path(r"^admin/", admin.site.urls),
+    re_path(r"^contact/", include("contact_form.urls")),
+    re_path(r"^impressum/$", views.flatpage, {"url": "/impressum/"}, name="imprint"),
 ]
 
 # Uncomment the next line to serve media files in dev.
@@ -30,5 +28,5 @@ urlpatterns = [
 
 urlpatterns += staticfiles_urlpatterns()
 urlpatterns += [
-    path('__debug__/', include(debug_toolbar.urls)),
+    path("__debug__/", include(debug_toolbar.urls)),
 ]
diff --git a/gnuviechadmin/gvawebcore/forms.py b/gnuviechadmin/gvawebcore/forms.py
index 7a72d83..cdf5426 100644
--- a/gnuviechadmin/gvawebcore/forms.py
+++ b/gnuviechadmin/gvawebcore/forms.py
@@ -3,11 +3,10 @@ This module defines form classes that can be extended by other gnuviechadmin
 apps' forms.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
 from django import forms
-from django.utils.translation import ugettext_lazy as _
-
+from django.utils.translation import gettext_lazy as _
 
 PASSWORD_MISMATCH_ERROR = _("Passwords don't match")
 """
@@ -21,11 +20,14 @@ class PasswordModelFormMixin(forms.Form):
     whether both fields contain the same string.
 
     """
+
     password1 = forms.CharField(
-        label=_('Password'), widget=forms.PasswordInput,
+        label=_("Password"),
+        widget=forms.PasswordInput,
     )
     password2 = forms.CharField(
-        label=_('Password (again)'), widget=forms.PasswordInput,
+        label=_("Password (again)"),
+        widget=forms.PasswordInput,
     )
 
     def clean_password2(self):
@@ -36,8 +38,8 @@ class PasswordModelFormMixin(forms.Form):
         :rtype: str or None
 
         """
-        password1 = self.cleaned_data.get('password1')
-        password2 = self.cleaned_data.get('password2')
+        password1 = self.cleaned_data.get("password1")
+        password2 = self.cleaned_data.get("password2")
         if password1 and password2 and password1 != password2:
             raise forms.ValidationError(PASSWORD_MISMATCH_ERROR)
         return password2
diff --git a/gnuviechadmin/gvawebcore/views.py b/gnuviechadmin/gvawebcore/views.py
index f6079bb..d62f697 100644
--- a/gnuviechadmin/gvawebcore/views.py
+++ b/gnuviechadmin/gvawebcore/views.py
@@ -2,9 +2,10 @@
 This module defines common view code to be used by multiple gnuviechadmin apps.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
 from django.shortcuts import get_object_or_404
+
 from hostingpackages.models import CustomerHostingPackage
 
 
@@ -14,7 +15,8 @@ class HostingPackageAndCustomerMixin(object):
     keyword argument 'package'.
 
     """
-    hosting_package_kwarg = 'package'
+
+    hosting_package_kwarg = "package"
     """Keyword argument used to find the hosting package in the URL."""
 
     hostingpackage = None
@@ -22,8 +24,8 @@ class HostingPackageAndCustomerMixin(object):
     def get_hosting_package(self):
         if self.hostingpackage is None:
             self.hostingpackage = get_object_or_404(
-                CustomerHostingPackage,
-                pk=int(self.kwargs[self.hosting_package_kwarg]))
+                CustomerHostingPackage, pk=int(self.kwargs[self.hosting_package_kwarg])
+            )
         return self.hostingpackage
 
     def get_customer_object(self):
diff --git a/gnuviechadmin/hostingpackages/__init__.py b/gnuviechadmin/hostingpackages/__init__.py
index e32bbf1..18a34db 100644
--- a/gnuviechadmin/hostingpackages/__init__.py
+++ b/gnuviechadmin/hostingpackages/__init__.py
@@ -2,4 +2,3 @@
 This app takes care of hosting packages.
 
 """
-default_app_config = 'hostingpackages.apps.HostingPackagesAppConfig'
diff --git a/gnuviechadmin/hostingpackages/admin.py b/gnuviechadmin/hostingpackages/admin.py
index 4d11867..ae22212 100644
--- a/gnuviechadmin/hostingpackages/admin.py
+++ b/gnuviechadmin/hostingpackages/admin.py
@@ -2,7 +2,7 @@
 This module contains the admin site interface for hosting packages.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
 from django import forms
 from django.contrib import admin
@@ -25,9 +25,10 @@ class CustomerHostingPackageCreateForm(forms.ModelForm):
     This is the form class for creating new customer hosting packages.
 
     """
+
     class Meta:
         model = CustomerHostingPackage
-        fields = ['customer', 'template', 'name']
+        fields = ["customer", "template", "name"]
 
     def save(self, **kwargs):
         """
@@ -39,10 +40,11 @@ class CustomerHostingPackageCreateForm(forms.ModelForm):
 
         """
         hostinpackages = CustomerHostingPackage.objects.create_from_template(
-            customer=self.cleaned_data['customer'],
-            template=self.cleaned_data['template'],
-            name=self.cleaned_data['name'],
-            **kwargs)
+            customer=self.cleaned_data["customer"],
+            template=self.cleaned_data["template"],
+            name=self.cleaned_data["name"],
+            **kwargs
+        )
         return hostinpackages
 
     def save_m2m(self):
@@ -55,6 +57,7 @@ class CustomerDiskSpaceOptionInline(admin.TabularInline):
     space options.
 
     """
+
     model = CustomerDiskSpaceOption
     extra = 0
 
@@ -65,6 +68,7 @@ class CustomerMailboxOptionInline(admin.TabularInline):
     mailbox options.
 
     """
+
     model = CustomerMailboxOption
     extra = 0
 
@@ -75,6 +79,7 @@ class CustomerUserDatabaseOptionInline(admin.TabularInline):
     database options.
 
     """
+
     model = CustomerUserDatabaseOption
     extra = 0
 
@@ -85,6 +90,7 @@ class CustomerHostingPackageDomainInline(admin.TabularInline):
     hosting packages.
 
     """
+
     model = CustomerHostingPackageDomain
     extra = 0
 
@@ -95,12 +101,9 @@ class CustomerHostingPackageAdmin(admin.ModelAdmin):
     :py:class:`CustomerHostingPackage`.
 
     """
+
     add_form = CustomerHostingPackageCreateForm
-    add_fieldsets = (
-        (None, {
-            'fields': ('customer', 'template', 'name')
-        }),
-    )
+    add_fieldsets = ((None, {"fields": ("customer", "template", "name")}),)
 
     inlines = [
         CustomerDiskSpaceOptionInline,
@@ -108,7 +111,7 @@ class CustomerHostingPackageAdmin(admin.ModelAdmin):
         CustomerUserDatabaseOptionInline,
         CustomerHostingPackageDomainInline,
     ]
-    list_display = ['name', 'customer', 'osuser']
+    list_display = ["name", "customer", "osuser"]
 
     def get_form(self, request, obj=None, **kwargs):
         """
@@ -125,13 +128,16 @@ class CustomerHostingPackageAdmin(admin.ModelAdmin):
         """
         defaults = {}
         if obj is None:
-            defaults.update({
-                'form': self.add_form,
-                'fields': admin.options.flatten_fieldsets(self.add_fieldsets),
-            })
+            defaults.update(
+                {
+                    "form": self.add_form,
+                    "fields": admin.options.flatten_fieldsets(self.add_fieldsets),
+                }
+            )
         defaults.update(kwargs)
         return super(CustomerHostingPackageAdmin, self).get_form(
-            request, obj, **defaults)
+            request, obj, **defaults
+        )
 
     def get_readonly_fields(self, request, obj=None):
         """
@@ -147,7 +153,7 @@ class CustomerHostingPackageAdmin(admin.ModelAdmin):
 
         """
         if obj:
-            return ['customer', 'template']
+            return ["customer", "template"]
         return []
 
 
diff --git a/gnuviechadmin/hostingpackages/apps.py b/gnuviechadmin/hostingpackages/apps.py
index e1fb021..aee9773 100644
--- a/gnuviechadmin/hostingpackages/apps.py
+++ b/gnuviechadmin/hostingpackages/apps.py
@@ -3,9 +3,8 @@ This module contains the :py:class:`django.apps.AppConfig` instance for the
 :py:mod:`hostingpackages` app.
 
 """
-from __future__ import unicode_literals
 from django.apps import AppConfig
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 
 
 class HostingPackagesAppConfig(AppConfig):
@@ -13,5 +12,6 @@ class HostingPackagesAppConfig(AppConfig):
     AppConfig for the :py:mod:`hostingpackages` app.
 
     """
-    name = 'hostingpackages'
-    verbose_name = _('Hosting Packages and Options')
+
+    name = "hostingpackages"
+    verbose_name = _("Hosting Packages and Options")
diff --git a/gnuviechadmin/hostingpackages/forms.py b/gnuviechadmin/hostingpackages/forms.py
index ddf5f6b..16e7baf 100644
--- a/gnuviechadmin/hostingpackages/forms.py
+++ b/gnuviechadmin/hostingpackages/forms.py
@@ -2,17 +2,13 @@
 This module contains the form classes related to hosting packages.
 
 """
-from __future__ import absolute_import, unicode_literals
-
-from django import forms
-from django.urls import reverse
-from django.utils.translation import ugettext as _
+from __future__ import absolute_import
 
 from crispy_forms.helper import FormHelper
-from crispy_forms.layout import (
-    Layout,
-    Submit,
-)
+from crispy_forms.layout import Layout, Submit
+from django import forms
+from django.urls import reverse
+from django.utils.translation import gettext as _
 
 from .models import (
     CustomerDiskSpaceOption,
@@ -28,25 +24,24 @@ class CreateCustomerHostingPackageForm(forms.ModelForm):
     a preselected customer.
 
     """
+
     class Meta:
         model = CustomerHostingPackage
-        fields = ['template', 'name', 'description']
+        fields = ["template", "name", "description"]
 
     def __init__(self, instance, *args, **kwargs):
-        username = kwargs.pop('user')
-        super(CreateCustomerHostingPackageForm, self).__init__(
-            *args, **kwargs
-        )
-        self.fields['description'].widget.attrs['rows'] = 2
+        username = kwargs.pop("user")
+        super(CreateCustomerHostingPackageForm, self).__init__(*args, **kwargs)
+        self.fields["description"].widget.attrs["rows"] = 2
         self.helper = FormHelper()
         self.helper.form_action = reverse(
-            'create_customer_hosting_package', kwargs={'user': username}
+            "create_customer_hosting_package", kwargs={"user": username}
         )
         self.helper.layout = Layout(
-            'template',
-            'name',
-            'description',
-            Submit('submit', _('Add Hosting Package')),
+            "template",
+            "name",
+            "description",
+            Submit("submit", _("Add Hosting Package")),
         )
 
 
@@ -55,44 +50,44 @@ class CreateHostingPackageForm(forms.ModelForm):
     This form class is used for creating new customer hosting packages.
 
     """
+
     class Meta:
         model = CustomerHostingPackage
-        fields = ['customer', 'template', 'name', 'description']
+        fields = ["customer", "template", "name", "description"]
 
     def __init__(self, instance, *args, **kwargs):
-        super(CreateHostingPackageForm, self).__init__(
-            *args, **kwargs
-        )
-        self.fields['description'].widget.attrs['rows'] = 2
+        super(CreateHostingPackageForm, self).__init__(*args, **kwargs)
+        self.fields["description"].widget.attrs["rows"] = 2
         self.helper = FormHelper()
-        self.helper.form_action = reverse('create_hosting_package')
+        self.helper.form_action = reverse("create_hosting_package")
         self.helper.layout = Layout(
-            'customer',
-            'template',
-            'name',
-            'description',
-            Submit('submit', _('Add Hosting Package')),
+            "customer",
+            "template",
+            "name",
+            "description",
+            Submit("submit", _("Add Hosting Package")),
         )
 
 
 class AddDiskspaceOptionForm(forms.ModelForm):
     class Meta:
         model = CustomerDiskSpaceOption
-        fields = ['diskspace', 'diskspace_unit']
+        fields = ["diskspace", "diskspace_unit"]
 
     def __init__(self, *args, **kwargs):
-        self.hostingpackage = kwargs.pop('hostingpackage')
-        self.option_template = kwargs.pop('option_template')
+        self.hostingpackage = kwargs.pop("hostingpackage")
+        self.option_template = kwargs.pop("option_template")
         super(AddDiskspaceOptionForm, self).__init__(*args, **kwargs)
         self.helper = FormHelper()
         self.helper.form_action = reverse(
-            'add_hosting_option',
+            "add_hosting_option",
             kwargs={
-                'package': self.hostingpackage.id,
-                'type': 'diskspace',
-                'optionid': self.option_template.id,
-            })
-        self.helper.add_input(Submit('submit', _('Add disk space option')))
+                "package": self.hostingpackage.id,
+                "type": "diskspace",
+                "optionid": self.option_template.id,
+            },
+        )
+        self.helper.add_input(Submit("submit", _("Add disk space option")))
 
     def save(self, commit=True):
         self.instance.hosting_package = self.hostingpackage
@@ -103,21 +98,22 @@ class AddDiskspaceOptionForm(forms.ModelForm):
 class AddMailboxOptionForm(forms.ModelForm):
     class Meta:
         model = CustomerMailboxOption
-        fields = ['number']
+        fields = ["number"]
 
     def __init__(self, *args, **kwargs):
-        self.hostingpackage = kwargs.pop('hostingpackage')
-        self.option_template = kwargs.pop('option_template')
+        self.hostingpackage = kwargs.pop("hostingpackage")
+        self.option_template = kwargs.pop("option_template")
         super(AddMailboxOptionForm, self).__init__(*args, **kwargs)
         self.helper = FormHelper()
         self.helper.form_action = reverse(
-            'add_hosting_option',
+            "add_hosting_option",
             kwargs={
-                'package': self.hostingpackage.id,
-                'type': 'mailboxes',
-                'optionid': self.option_template.id,
-            })
-        self.helper.add_input(Submit('submit', _('Add mailbox option')))
+                "package": self.hostingpackage.id,
+                "type": "mailboxes",
+                "optionid": self.option_template.id,
+            },
+        )
+        self.helper.add_input(Submit("submit", _("Add mailbox option")))
 
     def save(self, commit=True):
         self.instance.hosting_package = self.hostingpackage
@@ -128,21 +124,22 @@ class AddMailboxOptionForm(forms.ModelForm):
 class AddUserDatabaseOptionForm(forms.ModelForm):
     class Meta:
         model = CustomerUserDatabaseOption
-        fields = ['number']
+        fields = ["number"]
 
     def __init__(self, *args, **kwargs):
-        self.hostingpackage = kwargs.pop('hostingpackage')
-        self.option_template = kwargs.pop('option_template')
+        self.hostingpackage = kwargs.pop("hostingpackage")
+        self.option_template = kwargs.pop("option_template")
         super(AddUserDatabaseOptionForm, self).__init__(*args, **kwargs)
         self.helper = FormHelper()
         self.helper.form_action = reverse(
-            'add_hosting_option',
+            "add_hosting_option",
             kwargs={
-                'package': self.hostingpackage.id,
-                'type': 'databases',
-                'optionid': self.option_template.id,
-            })
-        self.helper.add_input(Submit('submit', _('Add database option')))
+                "package": self.hostingpackage.id,
+                "type": "databases",
+                "optionid": self.option_template.id,
+            },
+        )
+        self.helper.add_input(Submit("submit", _("Add database option")))
 
     def save(self, commit=True):
         self.instance.hosting_package = self.hostingpackage
diff --git a/gnuviechadmin/hostingpackages/migrations/0001_initial.py b/gnuviechadmin/hostingpackages/migrations/0001_initial.py
index 51ec210..bc234dd 100644
--- a/gnuviechadmin/hostingpackages/migrations/0001_initial.py
+++ b/gnuviechadmin/hostingpackages/migrations/0001_initial.py
@@ -1,6 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 import django.utils.timezone
 import model_utils.fields
 from django.conf import settings
@@ -14,301 +12,469 @@ class Migration(migrations.Migration):
 
     operations = [
         migrations.CreateModel(
-            name='CustomerHostingPackage',
+            name="CustomerHostingPackage",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('name', models.CharField(
-                    unique=True, max_length=128, verbose_name='name')),
-                ('description', models.TextField(
-                    verbose_name='description', blank=True)),
-                ('mailboxcount', models.PositiveIntegerField(
-                    verbose_name='mailbox count')),
-                ('diskspace', models.PositiveIntegerField(
-                    help_text='disk space for the hosting package',
-                    verbose_name='disk space')),
-                ('diskspace_unit', models.PositiveSmallIntegerField(
-                    verbose_name='unit of disk space',
-                    choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])),
-                ('customer', models.ForeignKey(
-                    verbose_name='customer', to=settings.AUTH_USER_MODEL,
-                    on_delete=models.CASCADE)),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "name",
+                    models.CharField(unique=True, max_length=128, verbose_name="name"),
+                ),
+                (
+                    "description",
+                    models.TextField(verbose_name="description", blank=True),
+                ),
+                (
+                    "mailboxcount",
+                    models.PositiveIntegerField(verbose_name="mailbox count"),
+                ),
+                (
+                    "diskspace",
+                    models.PositiveIntegerField(
+                        help_text="disk space for the hosting package",
+                        verbose_name="disk space",
+                    ),
+                ),
+                (
+                    "diskspace_unit",
+                    models.PositiveSmallIntegerField(
+                        verbose_name="unit of disk space",
+                        choices=[(0, "MiB"), (1, "GiB"), (2, "TiB")],
+                    ),
+                ),
+                (
+                    "customer",
+                    models.ForeignKey(
+                        verbose_name="customer",
+                        to=settings.AUTH_USER_MODEL,
+                        on_delete=models.CASCADE,
+                    ),
+                ),
             ],
             options={
-                'verbose_name': 'customer hosting package',
-                'verbose_name_plural': 'customer hosting packages',
+                "verbose_name": "customer hosting package",
+                "verbose_name_plural": "customer hosting packages",
             },
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='CustomerHostingPackageOption',
+            name="CustomerHostingPackageOption",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
             ],
             options={
-                'verbose_name': 'customer hosting option',
-                'verbose_name_plural': 'customer hosting options',
+                "verbose_name": "customer hosting option",
+                "verbose_name_plural": "customer hosting options",
             },
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='CustomerDiskSpaceOption',
+            name="CustomerDiskSpaceOption",
             fields=[
-                ('customerhostingpackageoption_ptr', models.OneToOneField(
-                    parent_link=True, auto_created=True, primary_key=True,
-                    serialize=False,
-                    to='hostingpackages.CustomerHostingPackageOption',
-                    on_delete=models.CASCADE)),
-                ('diskspace', models.PositiveIntegerField(
-                    verbose_name='disk space')),
-                ('diskspace_unit', models.PositiveSmallIntegerField(
-                    verbose_name='unit of disk space',
-                    choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])),
+                (
+                    "customerhostingpackageoption_ptr",
+                    models.OneToOneField(
+                        parent_link=True,
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="hostingpackages.CustomerHostingPackageOption",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
+                ("diskspace", models.PositiveIntegerField(verbose_name="disk space")),
+                (
+                    "diskspace_unit",
+                    models.PositiveSmallIntegerField(
+                        verbose_name="unit of disk space",
+                        choices=[(0, "MiB"), (1, "GiB"), (2, "TiB")],
+                    ),
+                ),
             ],
             options={
-                'ordering': ['diskspace_unit', 'diskspace'],
-                'abstract': False,
-                'verbose_name': 'Disk space option',
-                'verbose_name_plural': 'Disk space options',
+                "ordering": ["diskspace_unit", "diskspace"],
+                "abstract": False,
+                "verbose_name": "Disk space option",
+                "verbose_name_plural": "Disk space options",
             },
-            bases=(
-                'hostingpackages.customerhostingpackageoption', models.Model),
+            bases=("hostingpackages.customerhostingpackageoption", models.Model),
         ),
         migrations.CreateModel(
-            name='CustomerMailboxOption',
+            name="CustomerMailboxOption",
             fields=[
-                ('customerhostingpackageoption_ptr', models.OneToOneField(
-                    parent_link=True, auto_created=True, primary_key=True,
-                    serialize=False,
-                    to='hostingpackages.CustomerHostingPackageOption',
-                    on_delete=models.CASCADE)),
-                ('number', models.PositiveIntegerField(
-                    unique=True, verbose_name='number of mailboxes')),
+                (
+                    "customerhostingpackageoption_ptr",
+                    models.OneToOneField(
+                        parent_link=True,
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="hostingpackages.CustomerHostingPackageOption",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
+                (
+                    "number",
+                    models.PositiveIntegerField(
+                        unique=True, verbose_name="number of mailboxes"
+                    ),
+                ),
             ],
             options={
-                'ordering': ['number'],
-                'abstract': False,
-                'verbose_name': 'Mailbox option',
-                'verbose_name_plural': 'Mailbox options',
+                "ordering": ["number"],
+                "abstract": False,
+                "verbose_name": "Mailbox option",
+                "verbose_name_plural": "Mailbox options",
             },
-            bases=(
-                'hostingpackages.customerhostingpackageoption', models.Model),
+            bases=("hostingpackages.customerhostingpackageoption", models.Model),
         ),
         migrations.CreateModel(
-            name='CustomerUserDatabaseOption',
+            name="CustomerUserDatabaseOption",
             fields=[
-                ('customerhostingpackageoption_ptr', models.OneToOneField(
-                    parent_link=True, auto_created=True, primary_key=True,
-                    serialize=False,
-                    to='hostingpackages.CustomerHostingPackageOption',
-                    on_delete=models.CASCADE)),
-                ('number', models.PositiveIntegerField(
-                    default=1, verbose_name='number of databases')),
-                ('db_type', models.PositiveSmallIntegerField(
-                    verbose_name='database type',
-                    choices=[(0, 'PostgreSQL'), (1, 'MySQL')])),
+                (
+                    "customerhostingpackageoption_ptr",
+                    models.OneToOneField(
+                        parent_link=True,
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="hostingpackages.CustomerHostingPackageOption",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
+                (
+                    "number",
+                    models.PositiveIntegerField(
+                        default=1, verbose_name="number of databases"
+                    ),
+                ),
+                (
+                    "db_type",
+                    models.PositiveSmallIntegerField(
+                        verbose_name="database type",
+                        choices=[(0, "PostgreSQL"), (1, "MySQL")],
+                    ),
+                ),
             ],
             options={
-                'ordering': ['db_type', 'number'],
-                'abstract': False,
-                'verbose_name': 'Database option',
-                'verbose_name_plural': 'Database options',
+                "ordering": ["db_type", "number"],
+                "abstract": False,
+                "verbose_name": "Database option",
+                "verbose_name_plural": "Database options",
             },
-            bases=(
-                'hostingpackages.customerhostingpackageoption', models.Model),
+            bases=("hostingpackages.customerhostingpackageoption", models.Model),
         ),
         migrations.CreateModel(
-            name='HostingOption',
+            name="HostingOption",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
             ],
             options={
-                'verbose_name': 'Hosting option',
-                'verbose_name_plural': 'Hosting options',
+                "verbose_name": "Hosting option",
+                "verbose_name_plural": "Hosting options",
             },
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='DiskSpaceOption',
+            name="DiskSpaceOption",
             fields=[
-                ('hostingoption_ptr', models.OneToOneField(
-                    parent_link=True, auto_created=True, primary_key=True,
-                    serialize=False, to='hostingpackages.HostingOption',
-                    on_delete=models.CASCADE)),
-                ('diskspace', models.PositiveIntegerField(
-                    verbose_name='disk space')),
-                ('diskspace_unit', models.PositiveSmallIntegerField(
-                    verbose_name='unit of disk space',
-                    choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])),
+                (
+                    "hostingoption_ptr",
+                    models.OneToOneField(
+                        parent_link=True,
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="hostingpackages.HostingOption",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
+                ("diskspace", models.PositiveIntegerField(verbose_name="disk space")),
+                (
+                    "diskspace_unit",
+                    models.PositiveSmallIntegerField(
+                        verbose_name="unit of disk space",
+                        choices=[(0, "MiB"), (1, "GiB"), (2, "TiB")],
+                    ),
+                ),
             ],
             options={
-                'ordering': ['diskspace_unit', 'diskspace'],
-                'abstract': False,
-                'verbose_name': 'Disk space option',
-                'verbose_name_plural': 'Disk space options',
+                "ordering": ["diskspace_unit", "diskspace"],
+                "abstract": False,
+                "verbose_name": "Disk space option",
+                "verbose_name_plural": "Disk space options",
             },
-            bases=('hostingpackages.hostingoption', models.Model),
+            bases=("hostingpackages.hostingoption", models.Model),
         ),
         migrations.CreateModel(
-            name='HostingPackageTemplate',
+            name="HostingPackageTemplate",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('name', models.CharField(
-                    unique=True, max_length=128, verbose_name='name')),
-                ('description', models.TextField(
-                    verbose_name='description', blank=True)),
-                ('mailboxcount', models.PositiveIntegerField(
-                    verbose_name='mailbox count')),
-                ('diskspace', models.PositiveIntegerField(
-                    help_text='disk space for the hosting package',
-                    verbose_name='disk space')),
-                ('diskspace_unit', models.PositiveSmallIntegerField(
-                    verbose_name='unit of disk space',
-                    choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "name",
+                    models.CharField(unique=True, max_length=128, verbose_name="name"),
+                ),
+                (
+                    "description",
+                    models.TextField(verbose_name="description", blank=True),
+                ),
+                (
+                    "mailboxcount",
+                    models.PositiveIntegerField(verbose_name="mailbox count"),
+                ),
+                (
+                    "diskspace",
+                    models.PositiveIntegerField(
+                        help_text="disk space for the hosting package",
+                        verbose_name="disk space",
+                    ),
+                ),
+                (
+                    "diskspace_unit",
+                    models.PositiveSmallIntegerField(
+                        verbose_name="unit of disk space",
+                        choices=[(0, "MiB"), (1, "GiB"), (2, "TiB")],
+                    ),
+                ),
             ],
             options={
-                'verbose_name': 'Hosting package',
-                'verbose_name_plural': 'Hosting packages',
+                "verbose_name": "Hosting package",
+                "verbose_name_plural": "Hosting packages",
             },
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='MailboxOption',
+            name="MailboxOption",
             fields=[
-                ('hostingoption_ptr', models.OneToOneField(
-                    parent_link=True, auto_created=True, primary_key=True,
-                    serialize=False, to='hostingpackages.HostingOption',
-                    on_delete=models.CASCADE)),
-                ('number', models.PositiveIntegerField(
-                    unique=True, verbose_name='number of mailboxes')),
+                (
+                    "hostingoption_ptr",
+                    models.OneToOneField(
+                        parent_link=True,
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="hostingpackages.HostingOption",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
+                (
+                    "number",
+                    models.PositiveIntegerField(
+                        unique=True, verbose_name="number of mailboxes"
+                    ),
+                ),
             ],
             options={
-                'ordering': ['number'],
-                'abstract': False,
-                'verbose_name': 'Mailbox option',
-                'verbose_name_plural': 'Mailbox options',
+                "ordering": ["number"],
+                "abstract": False,
+                "verbose_name": "Mailbox option",
+                "verbose_name_plural": "Mailbox options",
             },
-            bases=('hostingpackages.hostingoption', models.Model),
+            bases=("hostingpackages.hostingoption", models.Model),
         ),
         migrations.CreateModel(
-            name='UserDatabaseOption',
+            name="UserDatabaseOption",
             fields=[
-                ('hostingoption_ptr', models.OneToOneField(
-                    parent_link=True, auto_created=True, primary_key=True,
-                    serialize=False, to='hostingpackages.HostingOption',
-                    on_delete=models.CASCADE)),
-                ('number', models.PositiveIntegerField(
-                    default=1, verbose_name='number of databases')),
-                ('db_type', models.PositiveSmallIntegerField(
-                    verbose_name='database type',
-                    choices=[(0, 'PostgreSQL'), (1, 'MySQL')])),
+                (
+                    "hostingoption_ptr",
+                    models.OneToOneField(
+                        parent_link=True,
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="hostingpackages.HostingOption",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
+                (
+                    "number",
+                    models.PositiveIntegerField(
+                        default=1, verbose_name="number of databases"
+                    ),
+                ),
+                (
+                    "db_type",
+                    models.PositiveSmallIntegerField(
+                        verbose_name="database type",
+                        choices=[(0, "PostgreSQL"), (1, "MySQL")],
+                    ),
+                ),
             ],
             options={
-                'ordering': ['db_type', 'number'],
-                'abstract': False,
-                'verbose_name': 'Database option',
-                'verbose_name_plural': 'Database options',
+                "ordering": ["db_type", "number"],
+                "abstract": False,
+                "verbose_name": "Database option",
+                "verbose_name_plural": "Database options",
             },
-            bases=('hostingpackages.hostingoption', models.Model),
+            bases=("hostingpackages.hostingoption", models.Model),
         ),
         migrations.AlterUniqueTogether(
-            name='userdatabaseoption',
-            unique_together={('number', 'db_type')},
+            name="userdatabaseoption",
+            unique_together={("number", "db_type")},
         ),
         migrations.AlterUniqueTogether(
-            name='diskspaceoption',
-            unique_together={('diskspace', 'diskspace_unit')},
+            name="diskspaceoption",
+            unique_together={("diskspace", "diskspace_unit")},
         ),
         migrations.AddField(
-            model_name='customeruserdatabaseoption',
-            name='template',
+            model_name="customeruserdatabaseoption",
+            name="template",
             field=models.ForeignKey(
-                verbose_name='user database option template',
-                to='hostingpackages.UserDatabaseOption',
-                help_text='The user database option template that this '
-                          'hosting option is based on',
-                on_delete=models.CASCADE),
+                verbose_name="user database option template",
+                to="hostingpackages.UserDatabaseOption",
+                help_text="The user database option template that this "
+                "hosting option is based on",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
         migrations.AlterUniqueTogether(
-            name='customeruserdatabaseoption',
-            unique_together={('number', 'db_type')},
+            name="customeruserdatabaseoption",
+            unique_together={("number", "db_type")},
         ),
         migrations.AddField(
-            model_name='customermailboxoption',
-            name='template',
+            model_name="customermailboxoption",
+            name="template",
             field=models.ForeignKey(
-                verbose_name='mailbox option template',
-                to='hostingpackages.UserDatabaseOption',
-                help_text='The mailbox option template that this hosting '
-                          'option is based on',
-                on_delete=models.CASCADE),
+                verbose_name="mailbox option template",
+                to="hostingpackages.UserDatabaseOption",
+                help_text="The mailbox option template that this hosting "
+                "option is based on",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
         migrations.AddField(
-            model_name='customerhostingpackageoption',
-            name='hosting_package',
+            model_name="customerhostingpackageoption",
+            name="hosting_package",
             field=models.ForeignKey(
-                verbose_name='hosting package',
-                to='hostingpackages.CustomerHostingPackage',
-                on_delete=models.CASCADE),
+                verbose_name="hosting package",
+                to="hostingpackages.CustomerHostingPackage",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
         migrations.AddField(
-            model_name='customerhostingpackage',
-            name='template',
+            model_name="customerhostingpackage",
+            name="template",
             field=models.ForeignKey(
-                verbose_name='hosting package template',
-                to='hostingpackages.HostingPackageTemplate',
-                help_text='The hosting package template that this hosting '
-                          'package is based on.',
-                on_delete=models.CASCADE),
+                verbose_name="hosting package template",
+                to="hostingpackages.HostingPackageTemplate",
+                help_text="The hosting package template that this hosting "
+                "package is based on.",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
         migrations.AddField(
-            model_name='customerdiskspaceoption',
-            name='template',
+            model_name="customerdiskspaceoption",
+            name="template",
             field=models.ForeignKey(
-                verbose_name='disk space option template',
-                to='hostingpackages.DiskSpaceOption',
-                help_text='The disk space option template that this hosting '
-                          'option is based on',
-                on_delete=models.CASCADE),
+                verbose_name="disk space option template",
+                to="hostingpackages.DiskSpaceOption",
+                help_text="The disk space option template that this hosting "
+                "option is based on",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
         migrations.AlterUniqueTogether(
-            name='customerdiskspaceoption',
-            unique_together={('diskspace', 'diskspace_unit')},
+            name="customerdiskspaceoption",
+            unique_together={("diskspace", "diskspace_unit")},
         ),
     ]
diff --git a/gnuviechadmin/hostingpackages/migrations/0001_squashed_0005_auto_20150118_1303.py b/gnuviechadmin/hostingpackages/migrations/0001_squashed_0005_auto_20150118_1303.py
index 1bf5616..9a4f3a7 100644
--- a/gnuviechadmin/hostingpackages/migrations/0001_squashed_0005_auto_20150118_1303.py
+++ b/gnuviechadmin/hostingpackages/migrations/0001_squashed_0005_auto_20150118_1303.py
@@ -1,6 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 import django.utils.timezone
 import model_utils.fields
 from django.conf import settings
@@ -8,361 +6,530 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-    replaces = [('hostingpackages', '0001_initial'),
-                ('hostingpackages', '0002_auto_20150118_1149'),
-                ('hostingpackages', '0003_auto_20150118_1221'),
-                ('hostingpackages', '0004_customerhostingpackage_osuser'),
-                ('hostingpackages', '0005_auto_20150118_1303')]
+    replaces = [
+        ("hostingpackages", "0001_initial"),
+        ("hostingpackages", "0002_auto_20150118_1149"),
+        ("hostingpackages", "0003_auto_20150118_1221"),
+        ("hostingpackages", "0004_customerhostingpackage_osuser"),
+        ("hostingpackages", "0005_auto_20150118_1303"),
+    ]
 
     dependencies = [
         migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-        ('osusers', '0004_auto_20150104_1751'),
+        ("osusers", "0004_auto_20150104_1751"),
     ]
 
     operations = [
         migrations.CreateModel(
-            name='CustomerHostingPackage',
+            name="CustomerHostingPackage",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('name', models.CharField(
-                    unique=True, max_length=128, verbose_name='name')),
-                ('description', models.TextField(
-                    verbose_name='description', blank=True)),
-                ('mailboxcount', models.PositiveIntegerField(
-                    verbose_name='mailbox count')),
-                ('diskspace', models.PositiveIntegerField(
-                    help_text='disk space for the hosting package',
-                    verbose_name='disk space')),
-                ('diskspace_unit', models.PositiveSmallIntegerField(
-                    verbose_name='unit of disk space',
-                    choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])),
-                ('customer', models.ForeignKey(
-                    verbose_name='customer',
-                    to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "name",
+                    models.CharField(unique=True, max_length=128, verbose_name="name"),
+                ),
+                (
+                    "description",
+                    models.TextField(verbose_name="description", blank=True),
+                ),
+                (
+                    "mailboxcount",
+                    models.PositiveIntegerField(verbose_name="mailbox count"),
+                ),
+                (
+                    "diskspace",
+                    models.PositiveIntegerField(
+                        help_text="disk space for the hosting package",
+                        verbose_name="disk space",
+                    ),
+                ),
+                (
+                    "diskspace_unit",
+                    models.PositiveSmallIntegerField(
+                        verbose_name="unit of disk space",
+                        choices=[(0, "MiB"), (1, "GiB"), (2, "TiB")],
+                    ),
+                ),
+                (
+                    "customer",
+                    models.ForeignKey(
+                        verbose_name="customer",
+                        to=settings.AUTH_USER_MODEL,
+                        on_delete=models.CASCADE,
+                    ),
+                ),
             ],
             options={
-                'verbose_name': 'customer hosting package',
-                'verbose_name_plural': 'customer hosting packages',
+                "verbose_name": "customer hosting package",
+                "verbose_name_plural": "customer hosting packages",
             },
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='CustomerHostingPackageOption',
+            name="CustomerHostingPackageOption",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
             ],
             options={
-                'verbose_name': 'customer hosting option',
-                'verbose_name_plural': 'customer hosting options',
+                "verbose_name": "customer hosting option",
+                "verbose_name_plural": "customer hosting options",
             },
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='CustomerDiskSpaceOption',
+            name="CustomerDiskSpaceOption",
             fields=[
-                ('customerhostingpackageoption_ptr',
-                 models.OneToOneField(
-                     parent_link=True, auto_created=True, primary_key=True,
-                     serialize=False,
-                     to='hostingpackages.CustomerHostingPackageOption',
-                     on_delete=models.CASCADE)),
-                ('diskspace', models.PositiveIntegerField(
-                    verbose_name='disk space')),
-                ('diskspace_unit', models.PositiveSmallIntegerField(
-                    verbose_name='unit of disk space',
-                    choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])),
+                (
+                    "customerhostingpackageoption_ptr",
+                    models.OneToOneField(
+                        parent_link=True,
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="hostingpackages.CustomerHostingPackageOption",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
+                ("diskspace", models.PositiveIntegerField(verbose_name="disk space")),
+                (
+                    "diskspace_unit",
+                    models.PositiveSmallIntegerField(
+                        verbose_name="unit of disk space",
+                        choices=[(0, "MiB"), (1, "GiB"), (2, "TiB")],
+                    ),
+                ),
             ],
             options={
-                'ordering': ['diskspace_unit', 'diskspace'],
-                'abstract': False,
-                'verbose_name': 'Disk space option',
-                'verbose_name_plural': 'Disk space options',
+                "ordering": ["diskspace_unit", "diskspace"],
+                "abstract": False,
+                "verbose_name": "Disk space option",
+                "verbose_name_plural": "Disk space options",
             },
-            bases=(
-                'hostingpackages.customerhostingpackageoption', models.Model),
+            bases=("hostingpackages.customerhostingpackageoption", models.Model),
         ),
         migrations.CreateModel(
-            name='CustomerMailboxOption',
+            name="CustomerMailboxOption",
             fields=[
-                ('customerhostingpackageoption_ptr',
-                 models.OneToOneField(
-                     parent_link=True, auto_created=True, primary_key=True,
-                     serialize=False,
-                     to='hostingpackages.CustomerHostingPackageOption',
-                     on_delete=models.CASCADE)),
-                ('number', models.PositiveIntegerField(
-                    unique=True, verbose_name='number of mailboxes')),
+                (
+                    "customerhostingpackageoption_ptr",
+                    models.OneToOneField(
+                        parent_link=True,
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="hostingpackages.CustomerHostingPackageOption",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
+                (
+                    "number",
+                    models.PositiveIntegerField(
+                        unique=True, verbose_name="number of mailboxes"
+                    ),
+                ),
             ],
             options={
-                'ordering': ['number'],
-                'abstract': False,
-                'verbose_name': 'Mailbox option',
-                'verbose_name_plural': 'Mailbox options',
+                "ordering": ["number"],
+                "abstract": False,
+                "verbose_name": "Mailbox option",
+                "verbose_name_plural": "Mailbox options",
             },
-            bases=(
-                'hostingpackages.customerhostingpackageoption', models.Model),
+            bases=("hostingpackages.customerhostingpackageoption", models.Model),
         ),
         migrations.CreateModel(
-            name='CustomerUserDatabaseOption',
+            name="CustomerUserDatabaseOption",
             fields=[
-                ('customerhostingpackageoption_ptr',
-                 models.OneToOneField(
-                     parent_link=True, auto_created=True, primary_key=True,
-                     serialize=False,
-                     to='hostingpackages.CustomerHostingPackageOption',
-                     on_delete=models.CASCADE)),
-                ('number', models.PositiveIntegerField(
-                    default=1, verbose_name='number of databases')),
-                ('db_type', models.PositiveSmallIntegerField(
-                    verbose_name='database type',
-                    choices=[(0, 'PostgreSQL'), (1, 'MySQL')])),
+                (
+                    "customerhostingpackageoption_ptr",
+                    models.OneToOneField(
+                        parent_link=True,
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="hostingpackages.CustomerHostingPackageOption",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
+                (
+                    "number",
+                    models.PositiveIntegerField(
+                        default=1, verbose_name="number of databases"
+                    ),
+                ),
+                (
+                    "db_type",
+                    models.PositiveSmallIntegerField(
+                        verbose_name="database type",
+                        choices=[(0, "PostgreSQL"), (1, "MySQL")],
+                    ),
+                ),
             ],
             options={
-                'ordering': ['db_type', 'number'],
-                'abstract': False,
-                'verbose_name': 'Database option',
-                'verbose_name_plural': 'Database options',
+                "ordering": ["db_type", "number"],
+                "abstract": False,
+                "verbose_name": "Database option",
+                "verbose_name_plural": "Database options",
             },
-            bases=(
-                'hostingpackages.customerhostingpackageoption', models.Model),
+            bases=("hostingpackages.customerhostingpackageoption", models.Model),
         ),
         migrations.CreateModel(
-            name='HostingOption',
+            name="HostingOption",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
             ],
             options={
-                'verbose_name': 'Hosting option',
-                'verbose_name_plural': 'Hosting options',
+                "verbose_name": "Hosting option",
+                "verbose_name_plural": "Hosting options",
             },
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='DiskSpaceOption',
+            name="DiskSpaceOption",
             fields=[
-                ('hostingoption_ptr',
-                 models.OneToOneField(
-                     parent_link=True, auto_created=True, primary_key=True,
-                     serialize=False, to='hostingpackages.HostingOption',
-                     on_delete=models.CASCADE)),
-                ('diskspace', models.PositiveIntegerField(
-                    verbose_name='disk space')),
-                ('diskspace_unit', models.PositiveSmallIntegerField(
-                    verbose_name='unit of disk space',
-                    choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])),
+                (
+                    "hostingoption_ptr",
+                    models.OneToOneField(
+                        parent_link=True,
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="hostingpackages.HostingOption",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
+                ("diskspace", models.PositiveIntegerField(verbose_name="disk space")),
+                (
+                    "diskspace_unit",
+                    models.PositiveSmallIntegerField(
+                        verbose_name="unit of disk space",
+                        choices=[(0, "MiB"), (1, "GiB"), (2, "TiB")],
+                    ),
+                ),
             ],
             options={
-                'ordering': ['diskspace_unit', 'diskspace'],
-                'abstract': False,
-                'verbose_name': 'Disk space option',
-                'verbose_name_plural': 'Disk space options',
+                "ordering": ["diskspace_unit", "diskspace"],
+                "abstract": False,
+                "verbose_name": "Disk space option",
+                "verbose_name_plural": "Disk space options",
             },
-            bases=('hostingpackages.hostingoption', models.Model),
+            bases=("hostingpackages.hostingoption", models.Model),
         ),
         migrations.CreateModel(
-            name='HostingPackageTemplate',
+            name="HostingPackageTemplate",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('name', models.CharField(
-                    unique=True, max_length=128, verbose_name='name')),
-                ('description', models.TextField(
-                    verbose_name='description', blank=True)),
-                ('mailboxcount', models.PositiveIntegerField(
-                    verbose_name='mailbox count')),
-                ('diskspace', models.PositiveIntegerField(
-                    help_text='disk space for the hosting package',
-                    verbose_name='disk space')),
-                ('diskspace_unit', models.PositiveSmallIntegerField(
-                    verbose_name='unit of disk space',
-                    choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "name",
+                    models.CharField(unique=True, max_length=128, verbose_name="name"),
+                ),
+                (
+                    "description",
+                    models.TextField(verbose_name="description", blank=True),
+                ),
+                (
+                    "mailboxcount",
+                    models.PositiveIntegerField(verbose_name="mailbox count"),
+                ),
+                (
+                    "diskspace",
+                    models.PositiveIntegerField(
+                        help_text="disk space for the hosting package",
+                        verbose_name="disk space",
+                    ),
+                ),
+                (
+                    "diskspace_unit",
+                    models.PositiveSmallIntegerField(
+                        verbose_name="unit of disk space",
+                        choices=[(0, "MiB"), (1, "GiB"), (2, "TiB")],
+                    ),
+                ),
             ],
             options={
-                'verbose_name': 'Hosting package',
-                'verbose_name_plural': 'Hosting packages',
+                "verbose_name": "Hosting package",
+                "verbose_name_plural": "Hosting packages",
             },
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='MailboxOption',
+            name="MailboxOption",
             fields=[
-                ('hostingoption_ptr',
-                 models.OneToOneField(
-                     parent_link=True, auto_created=True, primary_key=True,
-                     serialize=False, to='hostingpackages.HostingOption',
-                     on_delete=models.CASCADE)),
-                ('number', models.PositiveIntegerField(
-                    unique=True, verbose_name='number of mailboxes')),
+                (
+                    "hostingoption_ptr",
+                    models.OneToOneField(
+                        parent_link=True,
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="hostingpackages.HostingOption",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
+                (
+                    "number",
+                    models.PositiveIntegerField(
+                        unique=True, verbose_name="number of mailboxes"
+                    ),
+                ),
             ],
             options={
-                'ordering': ['number'],
-                'abstract': False,
-                'verbose_name': 'Mailbox option',
-                'verbose_name_plural': 'Mailbox options',
+                "ordering": ["number"],
+                "abstract": False,
+                "verbose_name": "Mailbox option",
+                "verbose_name_plural": "Mailbox options",
             },
-            bases=('hostingpackages.hostingoption', models.Model),
+            bases=("hostingpackages.hostingoption", models.Model),
         ),
         migrations.CreateModel(
-            name='UserDatabaseOption',
+            name="UserDatabaseOption",
             fields=[
-                ('hostingoption_ptr',
-                 models.OneToOneField(
-                     parent_link=True, auto_created=True, primary_key=True,
-                     serialize=False, to='hostingpackages.HostingOption',
-                     on_delete=models.CASCADE)),
-                ('number', models.PositiveIntegerField(
-                    default=1, verbose_name='number of databases')),
-                ('db_type',
-                 models.PositiveSmallIntegerField(
-                     verbose_name='database type',
-                     choices=[(0, 'PostgreSQL'), (1, 'MySQL')])),
+                (
+                    "hostingoption_ptr",
+                    models.OneToOneField(
+                        parent_link=True,
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="hostingpackages.HostingOption",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
+                (
+                    "number",
+                    models.PositiveIntegerField(
+                        default=1, verbose_name="number of databases"
+                    ),
+                ),
+                (
+                    "db_type",
+                    models.PositiveSmallIntegerField(
+                        verbose_name="database type",
+                        choices=[(0, "PostgreSQL"), (1, "MySQL")],
+                    ),
+                ),
             ],
             options={
-                'ordering': ['db_type', 'number'],
-                'abstract': False,
-                'verbose_name': 'Database option',
-                'verbose_name_plural': 'Database options',
+                "ordering": ["db_type", "number"],
+                "abstract": False,
+                "verbose_name": "Database option",
+                "verbose_name_plural": "Database options",
             },
-            bases=('hostingpackages.hostingoption', models.Model),
+            bases=("hostingpackages.hostingoption", models.Model),
         ),
         migrations.AlterUniqueTogether(
-            name='userdatabaseoption',
-            unique_together={('number', 'db_type')},
+            name="userdatabaseoption",
+            unique_together={("number", "db_type")},
         ),
         migrations.AlterUniqueTogether(
-            name='diskspaceoption',
-            unique_together={('diskspace', 'diskspace_unit')},
+            name="diskspaceoption",
+            unique_together={("diskspace", "diskspace_unit")},
         ),
         migrations.AddField(
-            model_name='customeruserdatabaseoption',
-            name='template',
+            model_name="customeruserdatabaseoption",
+            name="template",
             field=models.ForeignKey(
-                verbose_name='user database option template',
-                to='hostingpackages.UserDatabaseOption',
-                help_text='The user database option template that this '
-                          'hosting option is based on',
-                on_delete=models.CASCADE),
+                verbose_name="user database option template",
+                to="hostingpackages.UserDatabaseOption",
+                help_text="The user database option template that this "
+                "hosting option is based on",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
         migrations.AlterUniqueTogether(
-            name='customeruserdatabaseoption',
-            unique_together={('number', 'db_type')},
+            name="customeruserdatabaseoption",
+            unique_together={("number", "db_type")},
         ),
         migrations.AddField(
-            model_name='customermailboxoption',
-            name='template',
+            model_name="customermailboxoption",
+            name="template",
             field=models.ForeignKey(
-                verbose_name='mailbox option template',
-                to='hostingpackages.UserDatabaseOption',
-                help_text='The mailbox option template that this mailbox '
-                          'option is based on',
-                on_delete=models.CASCADE),
+                verbose_name="mailbox option template",
+                to="hostingpackages.UserDatabaseOption",
+                help_text="The mailbox option template that this mailbox "
+                "option is based on",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
         migrations.AddField(
-            model_name='customerhostingpackageoption',
-            name='hosting_package',
+            model_name="customerhostingpackageoption",
+            name="hosting_package",
             field=models.ForeignKey(
-                verbose_name='hosting package',
-                to='hostingpackages.CustomerHostingPackage',
-                on_delete=models.CASCADE),
+                verbose_name="hosting package",
+                to="hostingpackages.CustomerHostingPackage",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
         migrations.AddField(
-            model_name='customerhostingpackage',
-            name='template',
+            model_name="customerhostingpackage",
+            name="template",
             field=models.ForeignKey(
-                verbose_name='hosting package template',
-                to='hostingpackages.HostingPackageTemplate',
-                help_text='The hosting package template that this hosting '
-                          'package is based on',
-                on_delete=models.CASCADE),
+                verbose_name="hosting package template",
+                to="hostingpackages.HostingPackageTemplate",
+                help_text="The hosting package template that this hosting "
+                "package is based on",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
         migrations.AddField(
-            model_name='customerdiskspaceoption',
-            name='template',
+            model_name="customerdiskspaceoption",
+            name="template",
             field=models.ForeignKey(
-                verbose_name='disk space option template',
-                to='hostingpackages.DiskSpaceOption',
-                help_text='The disk space option template that this hosting '
-                          'option is based on',
-                on_delete=models.CASCADE),
+                verbose_name="disk space option template",
+                to="hostingpackages.DiskSpaceOption",
+                help_text="The disk space option template that this hosting "
+                "option is based on",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
         migrations.AlterUniqueTogether(
-            name='customerdiskspaceoption',
-            unique_together={('diskspace', 'diskspace_unit')},
+            name="customerdiskspaceoption",
+            unique_together={("diskspace", "diskspace_unit")},
         ),
         migrations.AlterField(
-            model_name='customerdiskspaceoption',
-            name='template',
+            model_name="customerdiskspaceoption",
+            name="template",
             field=models.ForeignKey(
-                verbose_name='disk space option template',
-                to='hostingpackages.DiskSpaceOption',
-                help_text='The disk space option template that this disk '
-                          'space option is based on',
-                on_delete=models.CASCADE),
+                verbose_name="disk space option template",
+                to="hostingpackages.DiskSpaceOption",
+                help_text="The disk space option template that this disk "
+                "space option is based on",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
         migrations.AlterField(
-            model_name='customeruserdatabaseoption',
-            name='template',
+            model_name="customeruserdatabaseoption",
+            name="template",
             field=models.ForeignKey(
-                verbose_name='user database option template',
-                to='hostingpackages.UserDatabaseOption',
-                help_text='The user database option template that this '
-                          'database option is based on',
-                on_delete=models.CASCADE),
+                verbose_name="user database option template",
+                to="hostingpackages.UserDatabaseOption",
+                help_text="The user database option template that this "
+                "database option is based on",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
         migrations.AlterField(
-            model_name='customerhostingpackage',
-            name='name',
-            field=models.CharField(max_length=128, verbose_name='name'),
+            model_name="customerhostingpackage",
+            name="name",
+            field=models.CharField(max_length=128, verbose_name="name"),
             preserve_default=True,
         ),
         migrations.AlterUniqueTogether(
-            name='customerhostingpackage',
-            unique_together={('customer', 'name')},
+            name="customerhostingpackage",
+            unique_together={("customer", "name")},
         ),
         migrations.AddField(
-            model_name='customerhostingpackage',
-            name='osuser',
+            model_name="customerhostingpackage",
+            name="osuser",
             field=models.OneToOneField(
-                null=True, blank=True, to='osusers.User',
-                verbose_name='Operating system user', on_delete=models.CASCADE),
+                null=True,
+                blank=True,
+                to="osusers.User",
+                verbose_name="Operating system user",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
     ]
diff --git a/gnuviechadmin/hostingpackages/migrations/0002_auto_20150118_1149.py b/gnuviechadmin/hostingpackages/migrations/0002_auto_20150118_1149.py
index 515829f..732605c 100644
--- a/gnuviechadmin/hostingpackages/migrations/0002_auto_20150118_1149.py
+++ b/gnuviechadmin/hostingpackages/migrations/0002_auto_20150118_1149.py
@@ -1,57 +1,59 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
     dependencies = [
-        ('hostingpackages', '0001_initial'),
+        ("hostingpackages", "0001_initial"),
     ]
 
     operations = [
         migrations.AlterField(
-            model_name='customerdiskspaceoption',
-            name='template',
+            model_name="customerdiskspaceoption",
+            name="template",
             field=models.ForeignKey(
-                verbose_name='disk space option template',
-                to='hostingpackages.DiskSpaceOption',
-                help_text='The disk space option template that this disk '
-                          'space option is based on',
-                on_delete=models.CASCADE),
+                verbose_name="disk space option template",
+                to="hostingpackages.DiskSpaceOption",
+                help_text="The disk space option template that this disk "
+                "space option is based on",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
         migrations.AlterField(
-            model_name='customerhostingpackage',
-            name='template',
+            model_name="customerhostingpackage",
+            name="template",
             field=models.ForeignKey(
-                verbose_name='hosting package template',
-                to='hostingpackages.HostingPackageTemplate',
-                help_text='The hosting package template that this hosting '
-                          'package is based on',
-                on_delete=models.CASCADE),
+                verbose_name="hosting package template",
+                to="hostingpackages.HostingPackageTemplate",
+                help_text="The hosting package template that this hosting "
+                "package is based on",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
         migrations.AlterField(
-            model_name='customermailboxoption',
-            name='template',
+            model_name="customermailboxoption",
+            name="template",
             field=models.ForeignKey(
-                verbose_name='mailbox option template',
-                to='hostingpackages.UserDatabaseOption',
-                help_text='The mailbox option template that this mailbox '
-                          'option is based on',
-                on_delete=models.CASCADE),
+                verbose_name="mailbox option template",
+                to="hostingpackages.UserDatabaseOption",
+                help_text="The mailbox option template that this mailbox "
+                "option is based on",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
         migrations.AlterField(
-            model_name='customeruserdatabaseoption',
-            name='template',
+            model_name="customeruserdatabaseoption",
+            name="template",
             field=models.ForeignKey(
-                verbose_name='user database option template',
-                to='hostingpackages.UserDatabaseOption',
-                help_text='The user database option template that this '
-                          'database option is based on',
-                on_delete=models.CASCADE),
+                verbose_name="user database option template",
+                to="hostingpackages.UserDatabaseOption",
+                help_text="The user database option template that this "
+                "database option is based on",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
     ]
diff --git a/gnuviechadmin/hostingpackages/migrations/0002_auto_20150118_1319.py b/gnuviechadmin/hostingpackages/migrations/0002_auto_20150118_1319.py
index 80bf125..420c58e 100644
--- a/gnuviechadmin/hostingpackages/migrations/0002_auto_20150118_1319.py
+++ b/gnuviechadmin/hostingpackages/migrations/0002_auto_20150118_1319.py
@@ -1,18 +1,15 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
+from django.db import migrations
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
-        ('hostingpackages', '0001_squashed_0005_auto_20150118_1303'),
+        ("hostingpackages", "0001_squashed_0005_auto_20150118_1303"),
     ]
 
     operations = [
         migrations.AlterModelOptions(
-            name='hostingoption',
+            name="hostingoption",
             options={},
         ),
     ]
diff --git a/gnuviechadmin/hostingpackages/migrations/0003_auto_20150118_1221.py b/gnuviechadmin/hostingpackages/migrations/0003_auto_20150118_1221.py
index c77662e..2a0ff5e 100644
--- a/gnuviechadmin/hostingpackages/migrations/0003_auto_20150118_1221.py
+++ b/gnuviechadmin/hostingpackages/migrations/0003_auto_20150118_1221.py
@@ -1,24 +1,21 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
-        ('hostingpackages', '0002_auto_20150118_1149'),
+        ("hostingpackages", "0002_auto_20150118_1149"),
     ]
 
     operations = [
         migrations.AlterField(
-            model_name='customerhostingpackage',
-            name='name',
-            field=models.CharField(max_length=128, verbose_name='name'),
+            model_name="customerhostingpackage",
+            name="name",
+            field=models.CharField(max_length=128, verbose_name="name"),
             preserve_default=True,
         ),
         migrations.AlterUniqueTogether(
-            name='customerhostingpackage',
-            unique_together=set([('customer', 'name')]),
+            name="customerhostingpackage",
+            unique_together=set([("customer", "name")]),
         ),
     ]
diff --git a/gnuviechadmin/hostingpackages/migrations/0003_auto_20150118_1407.py b/gnuviechadmin/hostingpackages/migrations/0003_auto_20150118_1407.py
index 98979c5..a6cbd8a 100644
--- a/gnuviechadmin/hostingpackages/migrations/0003_auto_20150118_1407.py
+++ b/gnuviechadmin/hostingpackages/migrations/0003_auto_20150118_1407.py
@@ -1,24 +1,23 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
     dependencies = [
-        ('hostingpackages', '0002_auto_20150118_1319'),
+        ("hostingpackages", "0002_auto_20150118_1319"),
     ]
 
     operations = [
         migrations.AlterField(
-            model_name='customermailboxoption',
-            name='template',
+            model_name="customermailboxoption",
+            name="template",
             field=models.ForeignKey(
-                verbose_name='mailbox option template',
-                to='hostingpackages.MailboxOption',
-                help_text='The mailbox option template that this mailbox '
-                          'option is based on',
-                on_delete=models.CASCADE),
+                verbose_name="mailbox option template",
+                to="hostingpackages.MailboxOption",
+                help_text="The mailbox option template that this mailbox "
+                "option is based on",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
     ]
diff --git a/gnuviechadmin/hostingpackages/migrations/0004_customerhostingpackage_osuser.py b/gnuviechadmin/hostingpackages/migrations/0004_customerhostingpackage_osuser.py
index 616d13f..812ac68 100644
--- a/gnuviechadmin/hostingpackages/migrations/0004_customerhostingpackage_osuser.py
+++ b/gnuviechadmin/hostingpackages/migrations/0004_customerhostingpackage_osuser.py
@@ -1,22 +1,24 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
     dependencies = [
-        ('osusers', '0004_auto_20150104_1751'),
-        ('hostingpackages', '0003_auto_20150118_1221'),
+        ("osusers", "0004_auto_20150104_1751"),
+        ("hostingpackages", "0003_auto_20150118_1221"),
     ]
 
     operations = [
         migrations.AddField(
-            model_name='customerhostingpackage',
-            name='osuser',
+            model_name="customerhostingpackage",
+            name="osuser",
             field=models.ForeignKey(
-                verbose_name='Operating system user', blank=True,
-                to='osusers.User', null=True, on_delete=models.CASCADE),
+                verbose_name="Operating system user",
+                blank=True,
+                to="osusers.User",
+                null=True,
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
     ]
diff --git a/gnuviechadmin/hostingpackages/migrations/0004_customerhostingpackagedomain.py b/gnuviechadmin/hostingpackages/migrations/0004_customerhostingpackagedomain.py
index 446c730..82fdbdb 100644
--- a/gnuviechadmin/hostingpackages/migrations/0004_customerhostingpackagedomain.py
+++ b/gnuviechadmin/hostingpackages/migrations/0004_customerhostingpackagedomain.py
@@ -1,6 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 import django.utils.timezone
 import model_utils.fields
 from django.db import migrations, models
@@ -8,33 +6,59 @@ from django.db import migrations, models
 
 class Migration(migrations.Migration):
     dependencies = [
-        ('domains', '0002_auto_20150124_1909'),
-        ('hostingpackages', '0003_auto_20150118_1407'),
+        ("domains", "0002_auto_20150124_1909"),
+        ("hostingpackages", "0003_auto_20150118_1407"),
     ]
 
     operations = [
         migrations.CreateModel(
-            name='CustomerHostingPackageDomain',
+            name="CustomerHostingPackageDomain",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('domain', models.OneToOneField(
-                    verbose_name='hosting domain', to='domains.HostingDomain',
-                    on_delete=models.CASCADE)),
-                ('hosting_package', models.ForeignKey(
-                    related_name='domains', verbose_name='hosting package',
-                    to='hostingpackages.CustomerHostingPackage',
-                    on_delete=models.CASCADE)),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "domain",
+                    models.OneToOneField(
+                        verbose_name="hosting domain",
+                        to="domains.HostingDomain",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
+                (
+                    "hosting_package",
+                    models.ForeignKey(
+                        related_name="domains",
+                        verbose_name="hosting package",
+                        to="hostingpackages.CustomerHostingPackage",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
             ],
             options={
-                'abstract': False,
+                "abstract": False,
             },
             bases=(models.Model,),
         ),
diff --git a/gnuviechadmin/hostingpackages/migrations/0005_auto_20150118_1303.py b/gnuviechadmin/hostingpackages/migrations/0005_auto_20150118_1303.py
index 9034ae0..88bacc4 100644
--- a/gnuviechadmin/hostingpackages/migrations/0005_auto_20150118_1303.py
+++ b/gnuviechadmin/hostingpackages/migrations/0005_auto_20150118_1303.py
@@ -1,21 +1,23 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
     dependencies = [
-        ('hostingpackages', '0004_customerhostingpackage_osuser'),
+        ("hostingpackages", "0004_customerhostingpackage_osuser"),
     ]
 
     operations = [
         migrations.AlterField(
-            model_name='customerhostingpackage',
-            name='osuser',
+            model_name="customerhostingpackage",
+            name="osuser",
             field=models.OneToOneField(
-                null=True, blank=True, to='osusers.User',
-                verbose_name='Operating system user', on_delete=models.CASCADE),
+                null=True,
+                blank=True,
+                to="osusers.User",
+                verbose_name="Operating system user",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
     ]
diff --git a/gnuviechadmin/hostingpackages/migrations/0005_auto_20150125_1508.py b/gnuviechadmin/hostingpackages/migrations/0005_auto_20150125_1508.py
index 8bade76..fcf42bd 100644
--- a/gnuviechadmin/hostingpackages/migrations/0005_auto_20150125_1508.py
+++ b/gnuviechadmin/hostingpackages/migrations/0005_auto_20150125_1508.py
@@ -1,22 +1,19 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
+from django.db import migrations
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
-        ('hostingpackages', '0004_customerhostingpackagedomain'),
+        ("hostingpackages", "0004_customerhostingpackagedomain"),
     ]
 
     operations = [
         migrations.AlterModelOptions(
-            name='diskspaceoption',
+            name="diskspaceoption",
             options={},
         ),
         migrations.AlterUniqueTogether(
-            name='customerdiskspaceoption',
+            name="customerdiskspaceoption",
             unique_together=set([]),
         ),
     ]
diff --git a/gnuviechadmin/hostingpackages/migrations/0006_auto_20150125_1510.py b/gnuviechadmin/hostingpackages/migrations/0006_auto_20150125_1510.py
index 17f24c9..8777347 100644
--- a/gnuviechadmin/hostingpackages/migrations/0006_auto_20150125_1510.py
+++ b/gnuviechadmin/hostingpackages/migrations/0006_auto_20150125_1510.py
@@ -1,22 +1,19 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
+from django.db import migrations
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
-        ('hostingpackages', '0005_auto_20150125_1508'),
+        ("hostingpackages", "0005_auto_20150125_1508"),
     ]
 
     operations = [
         migrations.AlterModelOptions(
-            name='userdatabaseoption',
+            name="userdatabaseoption",
             options={},
         ),
         migrations.AlterUniqueTogether(
-            name='customeruserdatabaseoption',
+            name="customeruserdatabaseoption",
             unique_together=set([]),
         ),
     ]
diff --git a/gnuviechadmin/hostingpackages/models.py b/gnuviechadmin/hostingpackages/models.py
index c1a5267..6f04bf5 100644
--- a/gnuviechadmin/hostingpackages/models.py
+++ b/gnuviechadmin/hostingpackages/models.py
@@ -2,21 +2,20 @@
 This module contains the hosting package models.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
 from django.conf import settings
-from django.db import transaction
-from django.db import models
+from django.db import models, transaction
 from django.urls import reverse
-from django.utils.encoding import python_2_unicode_compatible
-from django.utils.translation import ugettext_lazy as _, ungettext
-
+from django.utils.translation import gettext_lazy as _
+from django.utils.translation import ngettext
 from model_utils import Choices
 from model_utils.models import TimeStampedModel
 
 from domains.models import HostingDomain
 from managemails.models import Mailbox
-from osusers.models import AdditionalGroup, Group, User as OsUser
+from osusers.models import AdditionalGroup, Group
+from osusers.models import User as OsUser
 from userdbs.models import DB_TYPES, UserDatabase
 
 DISK_SPACE_UNITS = Choices((0, "M", _("MiB")), (1, "G", _("GiB")), (2, "T", _("TiB")))
@@ -24,7 +23,6 @@ DISK_SPACE_UNITS = Choices((0, "M", _("MiB")), (1, "G", _("GiB")), (2, "T", _("T
 DISK_SPACE_FACTORS = ((1, None, None), (1024, 1, None), (1024 * 1024, 1024, 1))
 
 
-@python_2_unicode_compatible
 class HostingPackageBase(TimeStampedModel):
     description = models.TextField(_("description"), blank=True)
     mailboxcount = models.PositiveIntegerField(_("mailbox count"))
@@ -57,7 +55,6 @@ class HostingOption(TimeStampedModel):
     """
 
 
-@python_2_unicode_compatible
 class DiskSpaceOptionBase(models.Model):
     diskspace = models.PositiveIntegerField(_("disk space"))
     diskspace_unit = models.PositiveSmallIntegerField(
@@ -87,7 +84,6 @@ class DiskSpaceOption(DiskSpaceOptionBase, HostingOption):
         unique_together = ["diskspace", "diskspace_unit"]
 
 
-@python_2_unicode_compatible
 class UserDatabaseOptionBase(models.Model):
     number = models.PositiveIntegerField(_("number of databases"), default=1)
     db_type = models.PositiveSmallIntegerField(_("database type"), choices=DB_TYPES)
@@ -99,7 +95,7 @@ class UserDatabaseOptionBase(models.Model):
         verbose_name_plural = _("Database options")
 
     def __str__(self):
-        return ungettext(
+        return ngettext(
             "{type} database", "{count} {type} databases", self.number
         ).format(type=self.get_db_type_display(), count=self.number)
 
@@ -115,7 +111,6 @@ class UserDatabaseOption(UserDatabaseOptionBase, HostingOption):
         unique_together = ["number", "db_type"]
 
 
-@python_2_unicode_compatible
 class MailboxOptionBase(models.Model):
     """
     Base class for mailbox options.
@@ -131,7 +126,7 @@ class MailboxOptionBase(models.Model):
         verbose_name_plural = _("Mailbox options")
 
     def __str__(self):
-        return ungettext(
+        return ngettext(
             "{count} additional mailbox", "{count} additional mailboxes", self.number
         ).format(count=self.number)
 
@@ -177,7 +172,6 @@ class CustomerHostingPackageManager(models.Manager):
         return package
 
 
-@python_2_unicode_compatible
 class CustomerHostingPackage(HostingPackageBase):
     """
     This class defines customer specific hosting packages.
@@ -269,7 +263,7 @@ class CustomerHostingPackage(HostingPackageBase):
                 ) + option.diskspace
                 min_unit = option.diskspace_unit
         if unit is None:
-            return DISK_SPACE_FACTORS[min_unit][0] * diskspace * 1024 ** 2
+            return DISK_SPACE_FACTORS[min_unit][0] * diskspace * 1024**2
         if unit > min_unit:
             return DISK_SPACE_FACTORS[unit][min_unit] * diskspace
         return DISK_SPACE_FACTORS[min_unit][unit] * diskspace
@@ -287,7 +281,7 @@ class CustomerHostingPackage(HostingPackageBase):
         """
         if unit is None:
             return (
-                DISK_SPACE_FACTORS[self.diskspace_unit][0] * self.diskspace * 1024 ** 2
+                DISK_SPACE_FACTORS[self.diskspace_unit][0] * self.diskspace * 1024**2
             )
         if unit > self.diskspace_unit:
             return DISK_SPACE_FACTORS[unit][self.diskspace_unit] * self.diskspace
@@ -382,7 +376,6 @@ class CustomerHostingPackage(HostingPackageBase):
         return super(CustomerHostingPackage, self).save(*args, **kwargs)
 
 
-@python_2_unicode_compatible
 class CustomerHostingPackageDomain(TimeStampedModel):
     """
     This class defines the relationship from a hosting package to a hosting
diff --git a/gnuviechadmin/hostingpackages/urls.py b/gnuviechadmin/hostingpackages/urls.py
index 4d0201b..9f1dfb7 100644
--- a/gnuviechadmin/hostingpackages/urls.py
+++ b/gnuviechadmin/hostingpackages/urls.py
@@ -2,9 +2,9 @@
 This module defines the URL patterns for hosting package related views.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
-from django.conf.urls import url
+from django.urls import re_path
 
 from .views import (
     AddHostingOption,
@@ -16,22 +16,36 @@ from .views import (
     HostingOptionChoices,
 )
 
-
 urlpatterns = [
-    url(r'^create$', CreateHostingPackage.as_view(),
-        name='create_hosting_package'),
-    url(r'^allpackages/',
-        AllCustomerHostingPackageList.as_view(), name='all_hosting_packages'),
-    url(r'^(?P[-\w0-9@.+_]+)/$',
-        CustomerHostingPackageList.as_view(), name='hosting_packages'),
-    url(r'^(?P[-\w0-9@.+_]+)/create$',
+    re_path(r"^create$", CreateHostingPackage.as_view(), name="create_hosting_package"),
+    re_path(
+        r"^allpackages/",
+        AllCustomerHostingPackageList.as_view(),
+        name="all_hosting_packages",
+    ),
+    re_path(
+        r"^(?P[-\w0-9@.+_]+)/$",
+        CustomerHostingPackageList.as_view(),
+        name="hosting_packages",
+    ),
+    re_path(
+        r"^(?P[-\w0-9@.+_]+)/create$",
         CreateCustomerHostingPackage.as_view(),
-        name='create_customer_hosting_package'),
-    url(r'^(?P[-\w0-9@.+_]+)/(?P\d+)/$',
+        name="create_customer_hosting_package",
+    ),
+    re_path(
+        r"^(?P[-\w0-9@.+_]+)/(?P\d+)/$",
         CustomerHostingPackageDetails.as_view(),
-        name='hosting_package_details'),
-    url(r'^(?P\d+)/option-choices$',
-        HostingOptionChoices.as_view(), name='hosting_option_choices'),
-    url(r'^(?P\d+)/add-option/(?P\w+)/(?P\d+)$',
-        AddHostingOption.as_view(), name='add_hosting_option'),
+        name="hosting_package_details",
+    ),
+    re_path(
+        r"^(?P\d+)/option-choices$",
+        HostingOptionChoices.as_view(),
+        name="hosting_option_choices",
+    ),
+    re_path(
+        r"^(?P\d+)/add-option/(?P\w+)/(?P\d+)$",
+        AddHostingOption.as_view(),
+        name="add_hosting_option",
+    ),
 ]
diff --git a/gnuviechadmin/hostingpackages/views.py b/gnuviechadmin/hostingpackages/views.py
index d07f4cc..82dffac 100644
--- a/gnuviechadmin/hostingpackages/views.py
+++ b/gnuviechadmin/hostingpackages/views.py
@@ -2,28 +2,17 @@
 This module defines views related to hosting packages.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
+from braces.views import LoginRequiredMixin, StaffuserRequiredMixin
 from django.conf import settings
-from django.http import Http404
-from django.shortcuts import redirect, get_object_or_404
-from django.utils.translation import ugettext as _
-from django.views.generic import (
-    DetailView,
-    ListView,
-)
-from django.views.generic.edit import (
-    CreateView,
-    FormView,
-)
 from django.contrib import messages
 from django.contrib.auth import get_user_model
-
-from braces.views import (
-    LoginRequiredMixin,
-    StaffuserRequiredMixin,
-)
-
+from django.http import Http404
+from django.shortcuts import get_object_or_404, redirect
+from django.utils.translation import gettext as _
+from django.views.generic import DetailView, ListView
+from django.views.generic.edit import CreateView, FormView
 from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin
 
 from .forms import (
@@ -41,24 +30,24 @@ from .models import (
 )
 
 
-class CreateHostingPackage(
-    LoginRequiredMixin, StaffuserRequiredMixin, CreateView
-):
+class CreateHostingPackage(LoginRequiredMixin, StaffuserRequiredMixin, CreateView):
     """
     Create a hosting package.
 
     """
+
     model = CustomerHostingPackage
     raise_exception = True
-    template_name_suffix = '_create'
+    template_name_suffix = "_create"
     form_class = CreateHostingPackageForm
 
     def form_valid(self, form):
         hostingpackage = form.save()
         messages.success(
             self.request,
-            _('Started setup of new hosting package {name}.').format(
-                name=hostingpackage.name)
+            _("Started setup of new hosting package {name}.").format(
+                name=hostingpackage.name
+            ),
         )
         return redirect(hostingpackage)
 
@@ -68,6 +57,7 @@ class CreateCustomerHostingPackage(CreateHostingPackage):
     Create a hosting package for a selected customer.
 
     """
+
     form_class = CreateCustomerHostingPackageForm
 
     def get_form_kwargs(self):
@@ -76,13 +66,11 @@ class CreateCustomerHostingPackage(CreateHostingPackage):
         return kwargs
 
     def get_customer_object(self):
-        return get_object_or_404(
-            get_user_model(), username=self.kwargs['user'])
+        return get_object_or_404(get_user_model(), username=self.kwargs["user"])
 
     def get_context_data(self, **kwargs):
-        context = super(
-            CreateCustomerHostingPackage, self).get_context_data(**kwargs)
-        context['customer'] = self.get_customer_object()
+        context = super(CreateCustomerHostingPackage, self).get_context_data(**kwargs)
+        context["customer"] = self.get_customer_object()
         return context
 
     def form_valid(self, form):
@@ -91,8 +79,9 @@ class CreateCustomerHostingPackage(CreateHostingPackage):
         hostingpackage.save()
         messages.success(
             self.request,
-            _('Started setup of new hosting package {name}.').format(
-                name=hostingpackage.name)
+            _("Started setup of new hosting package {name}.").format(
+                name=hostingpackage.name
+            ),
         )
         return redirect(hostingpackage)
 
@@ -102,30 +91,32 @@ class CustomerHostingPackageDetails(StaffOrSelfLoginRequiredMixin, DetailView):
     This view is for showing details of a customer hosting package.
 
     """
+
     model = CustomerHostingPackage
-    context_object_name = 'hostingpackage'
+    context_object_name = "hostingpackage"
     customer = None
 
     def get_customer_object(self):
         if self.customer is None:
             self.customer = get_object_or_404(
-                get_user_model(), username=self.kwargs['user'])
+                get_user_model(), username=self.kwargs["user"]
+            )
         return self.customer
 
     def get_context_data(self, **kwargs):
-        context = super(CustomerHostingPackageDetails, self).get_context_data(
-            **kwargs)
-        context.update({
-            'customer': self.get_customer_object(),
-            'uploadserver': settings.OSUSER_UPLOAD_SERVER,
-            'databases': context['hostingpackage'].databases,
-            'osuser': context['hostingpackage'].osuser,
-            'hostingoptions':
-                context['hostingpackage'].get_hostingoptions(),
-            'domains': context['hostingpackage'].domains.all(),
-            'mailboxes': context['hostingpackage'].mailboxes,
-        })
-        context['sshkeys'] = context['osuser'].sshpublickey_set.all()
+        context = super(CustomerHostingPackageDetails, self).get_context_data(**kwargs)
+        context.update(
+            {
+                "customer": self.get_customer_object(),
+                "uploadserver": settings.OSUSER_UPLOAD_SERVER,
+                "databases": context["hostingpackage"].databases,
+                "osuser": context["hostingpackage"].osuser,
+                "hostingoptions": context["hostingpackage"].get_hostingoptions(),
+                "domains": context["hostingpackage"].domains.all(),
+                "mailboxes": context["hostingpackage"].mailboxes,
+            }
+        )
+        context["sshkeys"] = context["osuser"].sshpublickey_set.all()
         return context
 
 
@@ -136,8 +127,9 @@ class AllCustomerHostingPackageList(
     This view is used for showing a list of all hosting packages.
 
     """
+
     model = CustomerHostingPackage
-    template_name_suffix = '_admin_list'
+    template_name_suffix = "_admin_list"
 
 
 class CustomerHostingPackageList(StaffOrSelfLoginRequiredMixin, ListView):
@@ -145,113 +137,128 @@ class CustomerHostingPackageList(StaffOrSelfLoginRequiredMixin, ListView):
     This view is used for showing a list of a customer's hosting packages.
 
     """
+
     model = CustomerHostingPackage
     customer = None
 
     def get_customer_object(self):
         if self.customer is None:
             self.customer = get_object_or_404(
-                get_user_model(), username=self.kwargs['user'])
+                get_user_model(), username=self.kwargs["user"]
+            )
         return self.customer
 
     def get_context_data(self, **kwargs):
-        context = super(CustomerHostingPackageList, self).get_context_data(
-            **kwargs)
-        context['customer'] = self.get_customer_object()
+        context = super(CustomerHostingPackageList, self).get_context_data(**kwargs)
+        context["customer"] = self.get_customer_object()
         return context
 
     def get_queryset(self):
-        return super(CustomerHostingPackageList, self).get_queryset().filter(
-            customer__username=self.kwargs['user'])
+        return (
+            super(CustomerHostingPackageList, self)
+            .get_queryset()
+            .filter(customer__username=self.kwargs["user"])
+        )
 
 
-class HostingOptionChoices(
-    LoginRequiredMixin, StaffuserRequiredMixin, DetailView
-):
+class HostingOptionChoices(LoginRequiredMixin, StaffuserRequiredMixin, DetailView):
     """
     This view displays choices of hosting options for a customer hosting
     package.
 
     """
+
     model = CustomerHostingPackage
-    context_object_name = 'hostingpackage'
-    template_name_suffix = '_option_choices'
+    context_object_name = "hostingpackage"
+    template_name_suffix = "_option_choices"
 
     def get_context_data(self, **kwargs):
-        context = super(HostingOptionChoices, self).get_context_data(
-            **kwargs)
-        context.update({
-            'customer': self.get_object().customer,
-            'hosting_options': (
-                (_('Disk space'),
-                 [(option, 'diskspace') for option in
-                  DiskSpaceOption.objects.all()]),
-                (_('Mailboxes'),
-                 [(option, 'mailboxes') for option in
-                  MailboxOption.objects.all()]),
-                (_('Databases'),
-                 [(option, 'databases') for option in
-                  UserDatabaseOption.objects.all()]),
-            ),
-        })
+        context = super(HostingOptionChoices, self).get_context_data(**kwargs)
+        context.update(
+            {
+                "customer": self.get_object().customer,
+                "hosting_options": (
+                    (
+                        _("Disk space"),
+                        [
+                            (option, "diskspace")
+                            for option in DiskSpaceOption.objects.all()
+                        ],
+                    ),
+                    (
+                        _("Mailboxes"),
+                        [
+                            (option, "mailboxes")
+                            for option in MailboxOption.objects.all()
+                        ],
+                    ),
+                    (
+                        _("Databases"),
+                        [
+                            (option, "databases")
+                            for option in UserDatabaseOption.objects.all()
+                        ],
+                    ),
+                ),
+            }
+        )
         return context
 
 
-class AddHostingOption(
-    LoginRequiredMixin, StaffuserRequiredMixin, FormView
-):
-    template_name = 'hostingpackages/add_hosting_option.html'
+class AddHostingOption(LoginRequiredMixin, StaffuserRequiredMixin, FormView):
+    template_name = "hostingpackages/add_hosting_option.html"
 
     def get_form_class(self):
-        optiontype = self.kwargs['type']
-        if optiontype == 'diskspace':
+        optiontype = self.kwargs["type"]
+        if optiontype == "diskspace":
             return AddDiskspaceOptionForm
-        elif optiontype == 'mailboxes':
+        elif optiontype == "mailboxes":
             return AddMailboxOptionForm
-        elif optiontype == 'databases':
+        elif optiontype == "databases":
             return AddUserDatabaseOptionForm
         raise Http404()
 
     def get_hosting_package(self):
-        return get_object_or_404(
-            CustomerHostingPackage, pk=int(self.kwargs['package']))
+        return get_object_or_404(CustomerHostingPackage, pk=int(self.kwargs["package"]))
 
     def get_option_template(self):
-        optiontype = self.kwargs['type']
-        optionid = int(self.kwargs['optionid'])
-        if optiontype == 'diskspace':
+        optiontype = self.kwargs["type"]
+        optionid = int(self.kwargs["optionid"])
+        if optiontype == "diskspace":
             return get_object_or_404(DiskSpaceOption, pk=optionid)
-        elif optiontype == 'mailboxes':
+        elif optiontype == "mailboxes":
             return get_object_or_404(MailboxOption, pk=optionid)
-        elif optiontype == 'databases':
+        elif optiontype == "databases":
             return get_object_or_404(UserDatabaseOption, pk=optionid)
         raise Http404()
 
     def get_form_kwargs(self):
         kwargs = super(AddHostingOption, self).get_form_kwargs()
-        kwargs['hostingpackage'] = self.get_hosting_package()
-        kwargs['option_template'] = self.get_option_template()
+        kwargs["hostingpackage"] = self.get_hosting_package()
+        kwargs["option_template"] = self.get_option_template()
         return kwargs
 
     def get_initial(self):
         initial = super(AddHostingOption, self).get_initial()
         template = self.get_option_template()
         if type(template) == DiskSpaceOption:
-            initial.update({
-                'diskspace': template.diskspace,
-                'diskspace_unit': template.diskspace_unit,
-            })
+            initial.update(
+                {
+                    "diskspace": template.diskspace,
+                    "diskspace_unit": template.diskspace_unit,
+                }
+            )
         elif type(template) == MailboxOption:
-            initial['number'] = template.number
+            initial["number"] = template.number
         elif type(template) == UserDatabaseOption:
-            initial['number'] = template.number
+            initial["number"] = template.number
         else:
             raise Http404()
         return initial
 
     def get_context_data(self, **kwargs):
         context = super(AddHostingOption, self).get_context_data(**kwargs)
-        context['option_template'] = self.get_option_template()
+        context["option_template"] = self.get_option_template()
         return context
 
     def form_valid(self, form):
@@ -259,8 +266,8 @@ class AddHostingOption(
         hosting_package = self.get_hosting_package()
         messages.success(
             self.request,
-            _("Successfully added option {option} to hosting package "
-              "{package}.").format(
-                  option=option, package=hosting_package.name)
+            _(
+                "Successfully added option {option} to hosting package " "{package}."
+            ).format(option=option, package=hosting_package.name),
         )
         return redirect(hosting_package)
diff --git a/gnuviechadmin/managemails/__init__.py b/gnuviechadmin/managemails/__init__.py
index 75d9f0a..c16c60e 100644
--- a/gnuviechadmin/managemails/__init__.py
+++ b/gnuviechadmin/managemails/__init__.py
@@ -2,4 +2,3 @@
 This app takes care of mailboxes and mail addresses.
 
 """
-default_app_config = 'managemails.apps.ManageMailsAppConfig'
diff --git a/gnuviechadmin/managemails/admin.py b/gnuviechadmin/managemails/admin.py
index 8bb386f..68a3c12 100644
--- a/gnuviechadmin/managemails/admin.py
+++ b/gnuviechadmin/managemails/admin.py
@@ -1,15 +1,10 @@
-from django.utils.html import format_html
-from django.contrib import admin
 from django import forms
+from django.contrib import admin
 from django.forms.utils import flatatt
-from django.utils.translation import ugettext as _
+from django.utils.html import format_html
+from django.utils.translation import gettext as _
 
-from .models import (
-    MailAddress,
-    MailAddressForward,
-    MailAddressMailbox,
-    Mailbox,
-)
+from .models import MailAddress, MailAddressForward, MailAddressMailbox, Mailbox
 
 PASSWORD_MISMATCH_ERROR = _("Passwords don't match")
 
@@ -17,8 +12,7 @@ PASSWORD_MISMATCH_ERROR = _("Passwords don't match")
 class ReadOnlyPasswordHashWidget(forms.Widget):
     def render(self, name, value, attrs):
         final_attrs = self.build_attrs(attrs)
-        summary = format_html("{0} : {1} ",
-                              _('Hash'), value)
+        summary = format_html("{0} : {1} ", _("Hash"), value)
         return format_html("{1}
", flatatt(final_attrs), summary)
 
 
@@ -41,22 +35,21 @@ class MailboxCreationForm(forms.ModelForm):
     A form for creating mailboxes.
 
     """
-    password1 = forms.CharField(label=_('Password'),
-                                widget=forms.PasswordInput)
-    password2 = forms.CharField(label=_('Password (again)'),
-                                widget=forms.PasswordInput)
+
+    password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
+    password2 = forms.CharField(label=_("Password (again)"), widget=forms.PasswordInput)
 
     class Meta:
         model = Mailbox
-        fields = ('osuser',)
+        fields = ("osuser",)
 
     def clean_password2(self):
         """
         Check that the two password entries match.
 
         """
-        password1 = self.cleaned_data.get('password1')
-        password2 = self.cleaned_data.get('password2')
+        password1 = self.cleaned_data.get("password1")
+        password2 = self.cleaned_data.get("password2")
         if password1 and password2 and password1 != password2:
             raise forms.ValidationError(PASSWORD_MISMATCH_ERROR)
         return password2
@@ -67,9 +60,8 @@ class MailboxCreationForm(forms.ModelForm):
 
         """
         mailbox = super(MailboxCreationForm, self).save(commit=False)
-        mailbox.username = Mailbox.objects.get_next_mailbox_name(
-            mailbox.osuser)
-        mailbox.set_password(self.cleaned_data['password1'])
+        mailbox.username = Mailbox.objects.get_next_mailbox_name(mailbox.osuser)
+        mailbox.set_password(self.cleaned_data["password1"])
         if commit:
             mailbox.save()
         return mailbox
@@ -80,14 +72,15 @@ class MailboxChangeForm(forms.ModelForm):
     A form for updating mailboxes.
 
     """
+
     password = ReadOnlyPasswordHashField()
 
     class Meta:
         model = Mailbox
-        fields = ('username', 'password', 'osuser', 'active')
+        fields = ("username", "password", "osuser", "active")
 
     def clean_password(self):
-        return self.initial['password']
+        return self.initial["password"]
 
 
 class ActivationChangeMixin(object):
@@ -97,8 +90,8 @@ class ActivationChangeMixin(object):
     def deactivate(self, request, queryset):
         queryset.update(active=False)
 
-    activate.short_description = _('Activate')
-    deactivate.short_description = _('Deactivate')
+    activate.short_description = _("Activate")
+    deactivate.short_description = _("Deactivate")
 
 
 class MailboxAdmin(ActivationChangeMixin, admin.ModelAdmin):
@@ -106,24 +99,20 @@ class MailboxAdmin(ActivationChangeMixin, admin.ModelAdmin):
     Custom admin page for mailboxes.
 
     """
+
     form = MailboxChangeForm
     add_form = MailboxCreationForm
 
-    actions = ['activate', 'deactivate']
+    actions = ["activate", "deactivate"]
 
-    list_display = ('username', 'osuser', 'active')
-    list_filter = ('active', 'osuser')
-    fieldsets = (
-        (None, {
-            'fields': ('osuser', 'username', 'password', 'active')}),
-    )
+    list_display = ("username", "osuser", "active")
+    list_filter = ("active", "osuser")
+    fieldsets = ((None, {"fields": ("osuser", "username", "password", "active")}),)
     add_fieldsets = (
-        (None, {
-            'classes': ('wide',),
-            'fields': ('osuser', 'password1', 'password2')}),
+        (None, {"classes": ("wide",), "fields": ("osuser", "password1", "password2")}),
     )
-    search_fields = ('username',)
-    ordering = ('username',)
+    search_fields = ("username",)
+    ordering = ("username",)
     filter_horizontal = ()
 
     def get_fieldsets(self, request, obj=None):
@@ -138,10 +127,12 @@ class MailboxAdmin(ActivationChangeMixin, admin.ModelAdmin):
         """
         defaults = {}
         if obj is None:
-            defaults.update({
-                'form': self.add_form,
-                'fields': admin.options.flatten_fieldsets(self.add_fieldsets),
-            })
+            defaults.update(
+                {
+                    "form": self.add_form,
+                    "fields": admin.options.flatten_fieldsets(self.add_fieldsets),
+                }
+            )
         defaults.update(kwargs)
         return super(MailboxAdmin, self).get_form(request, obj, **defaults)
 
@@ -155,10 +146,10 @@ class MailAddressForwardInline(admin.TabularInline):
 
 
 class MailAddressAdmin(ActivationChangeMixin, admin.ModelAdmin):
-    actions = ['activate', 'deactivate']
+    actions = ["activate", "deactivate"]
 
-    list_display = ('__str__', 'mailaddressmailbox', 'active')
-    list_filter = ('active', 'domain')
+    list_display = ("__str__", "mailaddressmailbox", "active")
+    list_filter = ("active", "domain")
 
     inlines = [MailAddressMailboxInline, MailAddressForwardInline]
 
diff --git a/gnuviechadmin/managemails/apps.py b/gnuviechadmin/managemails/apps.py
index 7a5067b..1cf2135 100644
--- a/gnuviechadmin/managemails/apps.py
+++ b/gnuviechadmin/managemails/apps.py
@@ -3,9 +3,8 @@ This module contains the :py:class:`django.apps.AppConfig` instance for the
 :py:mod:`managemails` app.
 
 """
-from __future__ import unicode_literals
 from django.apps import AppConfig
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 
 
 class ManageMailsAppConfig(AppConfig):
@@ -13,5 +12,6 @@ class ManageMailsAppConfig(AppConfig):
     AppConfig for the :py:mod:`managemails` app.
 
     """
-    name = 'managemails'
-    verbose_name = _('Mailboxes and Mail Addresses')
+
+    name = "managemails"
+    verbose_name = _("Mailboxes and Mail Addresses")
diff --git a/gnuviechadmin/managemails/forms.py b/gnuviechadmin/managemails/forms.py
index dc1032a..27b6786 100644
--- a/gnuviechadmin/managemails/forms.py
+++ b/gnuviechadmin/managemails/forms.py
@@ -2,32 +2,24 @@
 This module defines form classes for mailbox and mail address editing.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
+from crispy_forms.bootstrap import AppendedText
+from crispy_forms.helper import FormHelper
+from crispy_forms.layout import Div, Layout, Submit
 from django import forms
 from django.core.validators import validate_email
 from django.urls import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from crispy_forms.helper import FormHelper
-from crispy_forms.bootstrap import AppendedText
-from crispy_forms.layout import (
-    Div,
-    Layout,
-    Submit,
-)
-
-from .models import (
-    MailAddress,
-    Mailbox,
-)
-from gvawebcore.forms import PasswordModelFormMixin
-
+from django.utils.translation import gettext_lazy as _
 from model_utils import Choices
 
+from gvawebcore.forms import PasswordModelFormMixin
+
+from .models import MailAddress, Mailbox
+
 MAILBOX_OR_FORWARDS = Choices(
-    (0, 'mailbox', _('Mailbox')),
-    (1, 'forwards', _('Forwards')),
+    (0, "mailbox", _("Mailbox")),
+    (1, "forwards", _("Forwards")),
 )
 
 
@@ -36,17 +28,19 @@ class CreateMailboxForm(PasswordModelFormMixin, forms.ModelForm):
     This form is used to create new Mailbox instances.
 
     """
+
     class Meta:
         model = Mailbox
         fields = []
 
     def __init__(self, *args, **kwargs):
-        self.hosting_package = kwargs.pop('hostingpackage')
+        self.hosting_package = kwargs.pop("hostingpackage")
         super(CreateMailboxForm, self).__init__(*args, **kwargs)
         self.helper = FormHelper()
         self.helper.form_action = reverse(
-            'create_mailbox', kwargs={'package': self.hosting_package.id})
-        self.helper.add_input(Submit('submit', _('Create mailbox')))
+            "create_mailbox", kwargs={"package": self.hosting_package.id}
+        )
+        self.helper.add_input(Submit("submit", _("Create mailbox")))
 
     def save(self, commit=True):
         """
@@ -60,7 +54,7 @@ class CreateMailboxForm(PasswordModelFormMixin, forms.ModelForm):
         osuser = self.hosting_package.osuser
         self.instance.osuser = osuser
         self.instance.username = Mailbox.objects.get_next_mailbox_name(osuser)
-        self.instance.set_password(self.cleaned_data['password1'])
+        self.instance.set_password(self.cleaned_data["password1"])
         return super(CreateMailboxForm, self).save(commit=commit)
 
 
@@ -69,20 +63,23 @@ class ChangeMailboxPasswordForm(PasswordModelFormMixin, forms.ModelForm):
     This form is used to set a new password for an existing mailbox.
 
     """
+
     class Meta:
         model = Mailbox
         fields = []
 
     def __init__(self, *args, **kwargs):
-        self.hosting_package = kwargs.pop('hostingpackage')
+        self.hosting_package = kwargs.pop("hostingpackage")
         super(ChangeMailboxPasswordForm, self).__init__(*args, **kwargs)
         self.helper = FormHelper()
         self.helper.form_action = reverse(
-            'change_mailbox_password', kwargs={
-                'package': self.hosting_package.id,
-                'slug': self.instance.username,
-            })
-        self.helper.add_input(Submit('submit', _('Set password')))
+            "change_mailbox_password",
+            kwargs={
+                "package": self.hosting_package.id,
+                "slug": self.instance.username,
+            },
+        )
+        self.helper.add_input(Submit("submit", _("Set password")))
 
     def save(self, commit=True):
         """
@@ -93,13 +90,13 @@ class ChangeMailboxPasswordForm(PasswordModelFormMixin, forms.ModelForm):
         :rtype: :py:class:`managemails.models.Mailbox`
 
         """
-        self.instance.set_password(self.cleaned_data['password1'])
+        self.instance.set_password(self.cleaned_data["password1"])
         return super(ChangeMailboxPasswordForm, self).save(commit=commit)
 
 
 def multiple_email_validator(value):
     if value:
-        for email in [part.strip() for part in value.split(',')]:
+        for email in [part.strip() for part in value.split(",")]:
             validate_email(email)
     return value
 
@@ -109,25 +106,26 @@ class MailAddressFieldMixin(forms.Form):
     This mixin defines form fields common to mail address forms.
 
     """
+
     mailbox_or_forwards = forms.TypedChoiceField(
-        label=_('Mailbox or Forwards'),
+        label=_("Mailbox or Forwards"),
         choices=MAILBOX_OR_FORWARDS,
         widget=forms.RadioSelect,
         coerce=int,
     )
     mailbox = forms.ModelChoiceField(
         Mailbox.objects,
-        label=_('Mailbox'),
+        label=_("Mailbox"),
         required=False,
     )
     # TODO: refactor as separate field class returning a list
     forwards = forms.CharField(
-        label=_('Forwards'),
+        label=_("Forwards"),
         required=False,
         error_messages={
-            'invalid': _(
-                'Please enter one or more email addresses separated by '
-                'commas.'),
+            "invalid": _(
+                "Please enter one or more email addresses separated by " "commas."
+            ),
         },
         validators=[multiple_email_validator],
     )
@@ -138,68 +136,71 @@ class AddMailAddressForm(forms.ModelForm, MailAddressFieldMixin):
     This form is used to add a new mail address.
 
     """
+
     class Meta:
         model = MailAddress
-        fields = ['localpart']
+        fields = ["localpart"]
 
     def __init__(self, *args, **kwargs):
-        self.maildomain = kwargs.pop('maildomain')
-        self.hosting_package = kwargs.pop('hostingpackage')
+        self.maildomain = kwargs.pop("maildomain")
+        self.hosting_package = kwargs.pop("hostingpackage")
         super(AddMailAddressForm, self).__init__(*args, **kwargs)
-        self.fields['mailbox'].queryset = Mailbox.objects.unused(
+        self.fields["mailbox"].queryset = Mailbox.objects.unused(
             osuser=self.hosting_package.osuser,
         )
 
         self.helper = FormHelper()
         self.helper.form_action = reverse(
-            'add_mailaddress', kwargs={
-                'package': self.hosting_package.id,
-                'domain': self.maildomain.domain,
-            })
+            "add_mailaddress",
+            kwargs={
+                "package": self.hosting_package.id,
+                "domain": self.maildomain.domain,
+            },
+        )
         self.helper.layout = Layout(
             Div(
                 Div(
-                    AppendedText('localpart', '@' + self.maildomain.domain),
-                    css_class='col-lg-4 col-md-4 col-xs-12',
+                    AppendedText("localpart", "@" + self.maildomain.domain),
+                    css_class="col-lg-4 col-md-4 col-xs-12",
                 ),
                 Div(
-                    'mailbox_or_forwards',
-                    css_class='col-lg-2 col-md-2 col-xs-12',
+                    "mailbox_or_forwards",
+                    css_class="col-lg-2 col-md-2 col-xs-12",
                 ),
                 Div(
-                    'mailbox',
-                    'forwards',
-                    css_class='col-lg-6 col-md-6 col-xs-12',
+                    "mailbox",
+                    "forwards",
+                    css_class="col-lg-6 col-md-6 col-xs-12",
                 ),
-                css_class='row',
+                css_class="row",
             ),
-            Submit('submit', _('Add mail address')),
+            Submit("submit", _("Add mail address")),
         )
 
     def clean_localpart(self):
-        localpart = self.cleaned_data['localpart']
+        localpart = self.cleaned_data["localpart"]
         if MailAddress.objects.filter(
             domain=self.maildomain,
             localpart=localpart,
         ).exists():
-            raise forms.ValidationError(
-                _('This mail address is already in use.'))
-        validate_email('{0}@{1}'.format(localpart, self.maildomain.domain))
+            raise forms.ValidationError(_("This mail address is already in use."))
+        validate_email("{0}@{1}".format(localpart, self.maildomain.domain))
         return localpart
 
     def clean(self):
         super(AddMailAddressForm, self).clean()
         data = self.cleaned_data
-        if data['mailbox_or_forwards'] == MAILBOX_OR_FORWARDS.mailbox:
-            if not data['mailbox']:
-                self.add_error('mailbox', _('No mailbox selected'))
-        elif data['mailbox_or_forwards'] == MAILBOX_OR_FORWARDS.forwards:
-            if 'forwards' not in data or not data['forwards']:
-                self.add_error('forwards', _('No forward addresses selected'))
+        if data["mailbox_or_forwards"] == MAILBOX_OR_FORWARDS.mailbox:
+            if "mailbox" not in data or not data["mailbox"]:
+                self.add_error("mailbox", _("No mailbox selected"))
+        elif data["mailbox_or_forwards"] == MAILBOX_OR_FORWARDS.forwards:
+            if "forwards" not in data or not data["forwards"]:
+                self.add_error("forwards", _("No forward addresses selected"))
         else:  # pragma: no cover
             # should not happen because of the field's validation
             raise forms.ValidationError(
-                _('Illegal choice for target of the mail address'))
+                _("Illegal choice for target of the mail address")
+            )
 
     def save(self, commit=True):
         """
@@ -212,11 +213,11 @@ class AddMailAddressForm(forms.ModelForm, MailAddressFieldMixin):
         """
         self.instance.domain = self.maildomain
         data = self.cleaned_data
-        target_choice = data['mailbox_or_forwards']
+        target_choice = data["mailbox_or_forwards"]
         if target_choice == MAILBOX_OR_FORWARDS.mailbox:
-            mabox = self.instance.set_mailbox(data['mailbox'], commit=False)
+            mabox = self.instance.set_mailbox(data["mailbox"], commit=False)
         elif target_choice == MAILBOX_OR_FORWARDS.forwards:
-            targets = [part.strip() for part in data['forwards'].split(',')]
+            targets = [part.strip() for part in data["forwards"].split(",")]
             fwds = self.instance.set_forward_addresses(targets, commit=False)
         mailaddress = super(AddMailAddressForm, self).save(commit)
         if commit:
@@ -235,53 +236,57 @@ class EditMailAddressForm(forms.ModelForm, MailAddressFieldMixin):
     This form is used to edit the targets for a mail address.
 
     """
+
     class Meta:
         model = MailAddress
         fields = []
 
     def __init__(self, *args, **kwargs):
-        self.hosting_package = kwargs.pop('hostingpackage')
-        self.maildomain = kwargs.pop('maildomain')
+        self.hosting_package = kwargs.pop("hostingpackage")
+        self.maildomain = kwargs.pop("maildomain")
         super(EditMailAddressForm, self).__init__(*args, **kwargs)
-        self.fields['mailbox'].queryset = Mailbox.objects.unused_or_own(
+        self.fields["mailbox"].queryset = Mailbox.objects.unused_or_own(
             self.instance, self.hosting_package.osuser
         )
 
         self.helper = FormHelper()
         self.helper.form_action = reverse(
-            'edit_mailaddress', kwargs={
-                'package': self.hosting_package.id,
-                'domain': self.maildomain.domain,
-                'pk': self.instance.id,
-            })
+            "edit_mailaddress",
+            kwargs={
+                "package": self.hosting_package.id,
+                "domain": self.maildomain.domain,
+                "pk": self.instance.id,
+            },
+        )
         self.helper.layout = Layout(
             Div(
                 Div(
-                    'mailbox_or_forwards',
-                    css_class='col-log-2 col-md-2 col-xs-12',
+                    "mailbox_or_forwards",
+                    css_class="col-log-2 col-md-2 col-xs-12",
                 ),
                 Div(
-                    'mailbox',
-                    'forwards',
-                    css_class='col-lg-10 col-md-10 col-xs-12',
+                    "mailbox",
+                    "forwards",
+                    css_class="col-lg-10 col-md-10 col-xs-12",
                 ),
-                css_class='row',
+                css_class="row",
             ),
-            Submit('submit', _('Change mail address targets')),
+            Submit("submit", _("Change mail address targets")),
         )
 
     def clean(self):
         data = self.cleaned_data
-        if data['mailbox_or_forwards'] == MAILBOX_OR_FORWARDS.mailbox:
-            if not data['mailbox']:
-                self.add_error('mailbox', _('No mailbox selected'))
-        elif data['mailbox_or_forwards'] == MAILBOX_OR_FORWARDS.forwards:
-            if 'forwards' not in data or not data['forwards']:
-                self.add_error('forwards', _('No forward addresses selected'))
+        if data["mailbox_or_forwards"] == MAILBOX_OR_FORWARDS.mailbox:
+            if not data["mailbox"]:
+                self.add_error("mailbox", _("No mailbox selected"))
+        elif data["mailbox_or_forwards"] == MAILBOX_OR_FORWARDS.forwards:
+            if "forwards" not in data or not data["forwards"]:
+                self.add_error("forwards", _("No forward addresses selected"))
         else:  # pragma: no cover
             # should not happen because of the field's validation
             raise forms.ValidationError(
-                _('Illegal choice for target of the mail address'))
+                _("Illegal choice for target of the mail address")
+            )
 
     def save(self, commit=True):
         """
@@ -290,9 +295,9 @@ class EditMailAddressForm(forms.ModelForm, MailAddressFieldMixin):
         :param boolean commit:
         """
         data = self.cleaned_data
-        if data['mailbox_or_forwards'] == MAILBOX_OR_FORWARDS.mailbox:
-            self.instance.set_mailbox(data['mailbox'], commit)
-        elif data['mailbox_or_forwards'] == MAILBOX_OR_FORWARDS.forwards:
-            targets = [part.strip() for part in data['forwards'].split(',')]
+        if data["mailbox_or_forwards"] == MAILBOX_OR_FORWARDS.mailbox:
+            self.instance.set_mailbox(data["mailbox"], commit)
+        elif data["mailbox_or_forwards"] == MAILBOX_OR_FORWARDS.forwards:
+            targets = [part.strip() for part in data["forwards"].split(",")]
             self.instance.set_forward_addresses(targets, commit)
         return super(EditMailAddressForm, self).save(commit)
diff --git a/gnuviechadmin/managemails/migrations/0001_initial.py b/gnuviechadmin/managemails/migrations/0001_initial.py
index 7b7b71f..383071a 100644
--- a/gnuviechadmin/managemails/migrations/0001_initial.py
+++ b/gnuviechadmin/managemails/migrations/0001_initial.py
@@ -1,6 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 import django.utils.timezone
 import model_utils.fields
 from django.db import migrations, models
@@ -8,122 +6,185 @@ from django.db import migrations, models
 
 class Migration(migrations.Migration):
     dependencies = [
-        ('domains', '0001_initial'),
-        ('osusers', '0001_initial'),
+        ("domains", "0001_initial"),
+        ("osusers", "0001_initial"),
     ]
 
     operations = [
         migrations.CreateModel(
-            name='MailAddress',
+            name="MailAddress",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('active', models.BooleanField(default=True)),
-                ('localpart', models.CharField(max_length=128)),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                ("active", models.BooleanField(default=True)),
+                ("localpart", models.CharField(max_length=128)),
             ],
             options={
-                'verbose_name': 'Mail address',
-                'verbose_name_plural': 'Mail addresses',
+                "verbose_name": "Mail address",
+                "verbose_name_plural": "Mail addresses",
             },
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='MailAddressForward',
+            name="MailAddressForward",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('target', models.EmailField(max_length=254)),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                ("target", models.EmailField(max_length=254)),
             ],
-            options={
-            },
+            options={},
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='MailAddressMailbox',
+            name="MailAddressMailbox",
             fields=[
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('mailaddress', models.OneToOneField(
-                    primary_key=True, serialize=False,
-                    to='managemails.MailAddress', on_delete=models.CASCADE)),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "mailaddress",
+                    models.OneToOneField(
+                        primary_key=True,
+                        serialize=False,
+                        to="managemails.MailAddress",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
             ],
-            options={
-            },
+            options={},
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='Mailbox',
+            name="Mailbox",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('active', models.BooleanField(default=True)),
-                ('username', models.CharField(unique=True, max_length=128)),
-                ('password', models.CharField(max_length=255)),
-                ('osuser', models.ForeignKey(
-                    to='osusers.User', on_delete=models.CASCADE)),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                ("active", models.BooleanField(default=True)),
+                ("username", models.CharField(unique=True, max_length=128)),
+                ("password", models.CharField(max_length=255)),
+                (
+                    "osuser",
+                    models.ForeignKey(to="osusers.User", on_delete=models.CASCADE),
+                ),
             ],
             options={
-                'verbose_name': 'Mailbox',
-                'verbose_name_plural': 'Mailboxes',
+                "verbose_name": "Mailbox",
+                "verbose_name_plural": "Mailboxes",
             },
             bases=(models.Model,),
         ),
         migrations.AddField(
-            model_name='mailaddressmailbox',
-            name='mailbox',
-            field=models.ForeignKey(
-                to='managemails.Mailbox', on_delete=models.CASCADE),
+            model_name="mailaddressmailbox",
+            name="mailbox",
+            field=models.ForeignKey(to="managemails.Mailbox", on_delete=models.CASCADE),
             preserve_default=True,
         ),
         migrations.AlterUniqueTogether(
-            name='mailaddressmailbox',
-            unique_together={('mailaddress', 'mailbox')},
+            name="mailaddressmailbox",
+            unique_together={("mailaddress", "mailbox")},
         ),
         migrations.AddField(
-            model_name='mailaddressforward',
-            name='mailaddress',
+            model_name="mailaddressforward",
+            name="mailaddress",
             field=models.ForeignKey(
-                to='managemails.MailAddress', on_delete=models.CASCADE),
+                to="managemails.MailAddress", on_delete=models.CASCADE
+            ),
             preserve_default=True,
         ),
         migrations.AlterUniqueTogether(
-            name='mailaddressforward',
-            unique_together={('mailaddress', 'target')},
+            name="mailaddressforward",
+            unique_together={("mailaddress", "target")},
         ),
         migrations.AddField(
-            model_name='mailaddress',
-            name='domain',
-            field=models.ForeignKey(
-                to='domains.MailDomain', on_delete=models.CASCADE),
+            model_name="mailaddress",
+            name="domain",
+            field=models.ForeignKey(to="domains.MailDomain", on_delete=models.CASCADE),
             preserve_default=True,
         ),
         migrations.AlterUniqueTogether(
-            name='mailaddress',
-            unique_together={('localpart', 'domain')},
+            name="mailaddress",
+            unique_together={("localpart", "domain")},
         ),
     ]
diff --git a/gnuviechadmin/managemails/migrations/0002_auto_20150117_1238.py b/gnuviechadmin/managemails/migrations/0002_auto_20150117_1238.py
index 5c6d070..a9ada6a 100644
--- a/gnuviechadmin/managemails/migrations/0002_auto_20150117_1238.py
+++ b/gnuviechadmin/managemails/migrations/0002_auto_20150117_1238.py
@@ -1,22 +1,27 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
+from django.db import migrations
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
-        ('managemails', '0001_initial'),
+        ("managemails", "0001_initial"),
     ]
 
     operations = [
         migrations.AlterModelOptions(
-            name='mailaddress',
-            options={'ordering': ['domain', 'localpart'], 'verbose_name': 'Mail address', 'verbose_name_plural': 'Mail addresses'},
+            name="mailaddress",
+            options={
+                "ordering": ["domain", "localpart"],
+                "verbose_name": "Mail address",
+                "verbose_name_plural": "Mail addresses",
+            },
         ),
         migrations.AlterModelOptions(
-            name='mailbox',
-            options={'ordering': ['osuser', 'username'], 'verbose_name': 'Mailbox', 'verbose_name_plural': 'Mailboxes'},
+            name="mailbox",
+            options={
+                "ordering": ["osuser", "username"],
+                "verbose_name": "Mailbox",
+                "verbose_name_plural": "Mailboxes",
+            },
         ),
     ]
diff --git a/gnuviechadmin/managemails/migrations/0003_auto_20150124_2029.py b/gnuviechadmin/managemails/migrations/0003_auto_20150124_2029.py
index 7863dbb..6812429 100644
--- a/gnuviechadmin/managemails/migrations/0003_auto_20150124_2029.py
+++ b/gnuviechadmin/managemails/migrations/0003_auto_20150124_2029.py
@@ -1,29 +1,33 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
     dependencies = [
-        ('managemails', '0002_auto_20150117_1238'),
+        ("managemails", "0002_auto_20150117_1238"),
     ]
 
     operations = [
         migrations.AlterField(
-            model_name='mailaddressmailbox',
-            name='mailaddress',
+            model_name="mailaddressmailbox",
+            name="mailaddress",
             field=models.OneToOneField(
-                primary_key=True, serialize=False, to='managemails.MailAddress',
-                verbose_name='mailaddress', on_delete=models.CASCADE),
+                primary_key=True,
+                serialize=False,
+                to="managemails.MailAddress",
+                verbose_name="mailaddress",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
         migrations.AlterField(
-            model_name='mailaddressmailbox',
-            name='mailbox',
+            model_name="mailaddressmailbox",
+            name="mailbox",
             field=models.ForeignKey(
-                verbose_name='mailbox', to='managemails.Mailbox',
-                on_delete=models.CASCADE),
+                verbose_name="mailbox",
+                to="managemails.Mailbox",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
     ]
diff --git a/gnuviechadmin/managemails/migrations/0004_auto_20150125_1825.py b/gnuviechadmin/managemails/migrations/0004_auto_20150125_1825.py
index d1afccf..97bd009 100644
--- a/gnuviechadmin/managemails/migrations/0004_auto_20150125_1825.py
+++ b/gnuviechadmin/managemails/migrations/0004_auto_20150125_1825.py
@@ -1,27 +1,25 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
     dependencies = [
-        ('managemails', '0003_auto_20150124_2029'),
+        ("managemails", "0003_auto_20150124_2029"),
     ]
 
     operations = [
         migrations.AlterField(
-            model_name='mailaddress',
-            name='domain',
+            model_name="mailaddress",
+            name="domain",
             field=models.ForeignKey(
-                verbose_name='domain', to='domains.MailDomain',
-                on_delete=models.CASCADE),
+                verbose_name="domain", to="domains.MailDomain", on_delete=models.CASCADE
+            ),
             preserve_default=True,
         ),
         migrations.AlterField(
-            model_name='mailaddress',
-            name='localpart',
-            field=models.CharField(max_length=128, verbose_name='local part'),
+            model_name="mailaddress",
+            name="localpart",
+            field=models.CharField(max_length=128, verbose_name="local part"),
             preserve_default=True,
         ),
     ]
diff --git a/gnuviechadmin/managemails/models.py b/gnuviechadmin/managemails/models.py
index 6eef059..9b303f1 100644
--- a/gnuviechadmin/managemails/models.py
+++ b/gnuviechadmin/managemails/models.py
@@ -2,13 +2,10 @@
 This module defines the database models for mail handling.
 
 """
-from __future__ import unicode_literals
-
 from django.db import models
-from django.utils.encoding import python_2_unicode_compatible
-from django.utils.translation import ugettext as _
+from django.utils.translation import gettext as _
 from model_utils.models import TimeStampedModel
-from passlib.hash import sha512_crypt
+from passlib.handlers.sha2_crypt import sha512_crypt
 
 from domains.models import MailDomain
 from fileservertasks.tasks import create_file_mailbox, delete_file_mailbox
@@ -100,7 +97,6 @@ class MailboxManager(models.Manager):
         return mailbox
 
 
-@python_2_unicode_compatible
 class Mailbox(ActivateAbleMixin, TimeStampedModel):
     """
     This is the model class for a mailbox.
@@ -151,7 +147,6 @@ class Mailbox(ActivateAbleMixin, TimeStampedModel):
         return self.username
 
 
-@python_2_unicode_compatible
 class MailAddress(ActivateAbleMixin, TimeStampedModel, models.Model):
     """
     This is the model class for a mail address.
@@ -241,7 +236,6 @@ class MailAddress(ActivateAbleMixin, TimeStampedModel, models.Model):
         return retval
 
 
-@python_2_unicode_compatible
 class MailAddressMailbox(TimeStampedModel, models.Model):
     """
     This is the model class to assign a mail address to a mailbox.
diff --git a/gnuviechadmin/managemails/tests/test_admin.py b/gnuviechadmin/managemails/tests/test_admin.py
index ddacf4b..332b363 100644
--- a/gnuviechadmin/managemails/tests/test_admin.py
+++ b/gnuviechadmin/managemails/tests/test_admin.py
@@ -1,27 +1,25 @@
+from unittest.mock import Mock
+
 from django import forms
+from django.contrib.admin import AdminSite
+from django.contrib.auth import get_user_model
 from django.test import TestCase
 from django.test.utils import override_settings
 from django.urls import reverse
 from django.utils.html import format_html
-from django.utils.translation import ugettext as _
-
-from django.contrib.admin import AdminSite
-from django.contrib.auth import get_user_model
-
-from unittest.mock import Mock
-
-from osusers.models import User
+from django.utils.translation import gettext as _
 
 from managemails.admin import (
+    PASSWORD_MISMATCH_ERROR,
     ActivationChangeMixin,
     MailboxAdmin,
     MailboxChangeForm,
     MailboxCreationForm,
-    PASSWORD_MISMATCH_ERROR,
     ReadOnlyPasswordHashField,
     ReadOnlyPasswordHashWidget,
 )
 from managemails.models import Mailbox
+from osusers.models import User
 
 Customer = get_user_model()
 
diff --git a/gnuviechadmin/managemails/tests/test_forms.py b/gnuviechadmin/managemails/tests/test_forms.py
index be72a61..d0beb59 100644
--- a/gnuviechadmin/managemails/tests/test_forms.py
+++ b/gnuviechadmin/managemails/tests/test_forms.py
@@ -2,21 +2,25 @@
 This module provides tests for :py:mod:`managemails.forms`.
 
 """
-from unittest.mock import MagicMock, Mock, patch, ANY
+from unittest import skip
+from unittest.mock import ANY, MagicMock, Mock, patch
 
 from django.forms import ValidationError
 from django.test import TestCase
 from django.urls import reverse
 
+import osusers.models
+from domains.models import MailDomain
 from managemails.forms import (
+    MAILBOX_OR_FORWARDS,
     AddMailAddressForm,
     ChangeMailboxPasswordForm,
     CreateMailboxForm,
     EditMailAddressForm,
-    MAILBOX_OR_FORWARDS,
     MailAddressFieldMixin,
     multiple_email_validator,
 )
+from managemails.models import MailAddress, Mailbox
 
 
 class CreateMailboxFormTest(TestCase):
@@ -131,20 +135,10 @@ class MailAddressFieldMixinTest(TestCase):
 
 
 class AddMailAddressFormTest(TestCase):
-    def setUp(self):
-        self.patcher1 = patch("managemails.forms.Mailbox.objects")
-        self.patcher2 = patch("managemails.forms.MailAddress.objects")
-        self.mailbox_objects = self.patcher1.start()
-        self.mailaddress_objects = self.patcher2.start()
-
-    def tearDown(self):
-        self.patcher2.stop()
-        self.patcher1.stop()
-
     def test_constructor_needs_hostingpackage(self):
-        instance = MagicMock()
+        instance = MailAddress()
         with self.assertRaises(KeyError):
-            AddMailAddressForm(instance=instance, maildomain=MagicMock())
+            AddMailAddressForm(instance=instance, maildomain=None)
 
     def test_constructor_needs_maildomain(self):
         instance = MagicMock()
@@ -152,21 +146,20 @@ class AddMailAddressFormTest(TestCase):
             AddMailAddressForm(instance=instance, hostingpackage=MagicMock())
 
     def test_constructor(self):
-        instance = MagicMock()
-        osuser = Mock(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
+        instance = MailAddress()
+        os_user = osusers.models.User(username="testuser")
+        hosting_package = MagicMock(id=42, osuser=os_user)
+        mail_domain = MailDomain(domain="example.org")
         form = AddMailAddressForm(
-            instance=instance, hostingpackage=hostingpackage, maildomain=maildomain
+            instance=instance, hostingpackage=hosting_package, maildomain=mail_domain
         )
-        self.mailbox_objects.unused.assert_called_with(osuser=osuser)
         self.assertIn("mailbox_or_forwards", form.fields)
         self.assertIn("mailbox", form.fields)
         self.assertIn("forwards", form.fields)
         self.assertTrue(hasattr(form, "hosting_package"))
-        self.assertEqual(form.hosting_package, hostingpackage)
+        self.assertEqual(form.hosting_package, hosting_package)
         self.assertTrue(hasattr(form, "maildomain"))
-        self.assertEqual(form.maildomain, maildomain)
+        self.assertEqual(form.maildomain, mail_domain)
         self.assertTrue(hasattr(form, "helper"))
         self.assertEqual(
             form.helper.form_action,
@@ -176,52 +169,50 @@ class AddMailAddressFormTest(TestCase):
         self.assertEqual(form.helper.layout[1].name, "submit")
 
     def test_clean_localpart_valid(self):
-        instance = MagicMock()
-        osuser = Mock(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
+        mail_domain = MailDomain.objects.create(domain="example.org")
+
+        instance = MailAddress()
+        os_user = osusers.models.User(username="testuser")
+        hosting_package = MagicMock(id=42, osuser=os_user)
         form = AddMailAddressForm(
             instance=instance,
-            hostingpackage=hostingpackage,
-            maildomain=maildomain,
+            hostingpackage=hosting_package,
+            maildomain=mail_domain,
             data={
                 "localpart": "test",
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.forwards,
                 "forwards": "test2@example.org",
             },
         )
-        self.mailaddress_objects.filter(
-            domain=maildomain, localpart="test"
-        ).exists.return_value = False
         self.assertTrue(form.is_valid())
         self.assertEqual("test", form.clean_localpart())
 
     def test_clean_localpart_duplicate(self):
-        instance = MagicMock()
-        osuser = Mock(username="testuser")
+        mail_domain = MailDomain.objects.create(domain="example.org")
+
+        MailAddress.objects.create(localpart="test", domain=mail_domain)
+
+        instance = MailAddress()
+        osuser = osusers.models.User(username="testuser")
         hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
         form = AddMailAddressForm(
             instance=instance,
             hostingpackage=hostingpackage,
-            maildomain=maildomain,
+            maildomain=mail_domain,
             data={
                 "localpart": "test",
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.forwards,
                 "forwards": "test2@example.org",
             },
         )
-        self.mailaddress_objects.filter(
-            domain=maildomain, localpart="test"
-        ).exists.return_value = True
         self.assertFalse(form.is_valid())
         self.assertIn("localpart", form.errors)
 
     def test_clean_no_mailbox_choice(self):
-        instance = MagicMock()
-        osuser = Mock(username="testuser")
+        instance = MailAddress()
+        osuser = osusers.models.User(username="testuser")
         hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
+        maildomain = MailDomain(domain="example.org")
         form = AddMailAddressForm(
             instance=instance,
             hostingpackage=hostingpackage,
@@ -231,68 +222,52 @@ class AddMailAddressFormTest(TestCase):
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.mailbox,
             },
         )
-        self.mailaddress_objects.filter(
-            domain=maildomain, localpart="test"
-        ).exists.return_value = False
         self.assertFalse(form.is_valid())
         self.assertIn("mailbox", form.errors)
 
     def test_clean_no_forward_address_choice(self):
-        instance = MagicMock()
-        osuser = Mock(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
+        instance = MailAddress()
+        os_user = osusers.models.User(username="testuser")
+        hosting_package = MagicMock(id=42, osuser=os_user)
+        mail_domain = MailDomain(domain="example.org")
         form = AddMailAddressForm(
             instance=instance,
-            hostingpackage=hostingpackage,
-            maildomain=maildomain,
+            hostingpackage=hosting_package,
+            maildomain=mail_domain,
             data={
                 "localpart": "test",
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.forwards,
             },
         )
-        self.mailaddress_objects.filter(
-            domain=maildomain, localpart="test"
-        ).exists.return_value = False
         self.assertFalse(form.is_valid())
         self.assertIn("forwards", form.errors)
 
     def test_save_with_forwards_no_commit(self):
-        instance = MagicMock()
-        osuser = Mock(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
+        mail_domain = MailDomain.objects.create(domain="example.org")
+
+        instance = MailAddress()
+        os_user = osusers.models.User(username="testuser")
+        hosting_package = MagicMock(id=42, osuser=os_user)
         form = AddMailAddressForm(
             instance=instance,
-            hostingpackage=hostingpackage,
-            maildomain=maildomain,
+            hostingpackage=hosting_package,
+            maildomain=mail_domain,
             data={
                 "localpart": "test",
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.forwards,
                 "forwards": "test2@example.org,test3@example.org",
             },
         )
-        self.mailaddress_objects.filter(
-            domain=maildomain, localpart="test"
-        ).exists.return_value = False
         self.assertTrue(form.is_valid())
-        address1 = MagicMock(mailaddress="test2@example.org")
-        address2 = MagicMock(mailaddress="test3@example.org")
-        instance.set_forward_addresses.return_value = [address1, address2]
         form.save(commit=False)
-        self.assertEqual(maildomain, instance.domain)
-        instance.set_forward_addresses.assert_called_with(
-            ["test2@example.org", "test3@example.org"], commit=False
-        )
-        address1.save.assert_not_called()
-        address2.save.assert_not_called()
-        instance.save.assert_not_called()
+        self.assertEqual(mail_domain, instance.domain)
 
     def test_save_with_forwards_commit(self):
-        instance = MagicMock()
-        osuser = Mock(username="testuser")
+        maildomain = MailDomain.objects.create(domain="example.org")
+
+        instance = MailAddress()
+        osuser = osusers.models.User(username="testuser")
         hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
         form = AddMailAddressForm(
             instance=instance,
             hostingpackage=hostingpackage,
@@ -303,122 +278,95 @@ class AddMailAddressFormTest(TestCase):
                 "forwards": "test2@example.org,test3@example.org",
             },
         )
-        self.mailaddress_objects.filter(
-            domain=maildomain, localpart="test"
-        ).exists.return_value = False
         self.assertTrue(form.is_valid())
-        address1 = MagicMock(mailaddress="test2@example.org")
-        address2 = MagicMock(mailaddress="test3@example.org")
-        instance.set_forward_addresses.return_value = [address1, address2]
         form.save(commit=True)
         self.assertEqual(maildomain, instance.domain)
-        instance.set_forward_addresses.assert_called_with(
-            ["test2@example.org", "test3@example.org"], commit=False
+        forwards = list(
+            instance.mailaddressforward_set.values_list("target", flat=True).order_by(
+                "target"
+            )
         )
-        address1.save.assert_called_with()
-        address2.save.assert_called_with()
-        instance.save.assert_called_with()
+        self.assertEqual(len(forwards), 2)
+        self.assertEqual(forwards, ["test2@example.org", "test3@example.org"])
 
+    @skip("does not work because it will create a real mailbox")
     def test_save_with_mailbox_no_commit(self):
-        instance = MagicMock()
-        osuser = Mock(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
+        instance = MailAddress()
+
+        os_user = osusers.models.User(username="testuser")
+        hosting_package = MagicMock(id=42, osuser=os_user)
+
+        mail_domain = MailDomain.objects.create(domain="example.org")
+        mail_box = Mailbox.objects.create(osuser=os_user, username="mailbox23")
+        mail_box.set_password("test")
+
         form = AddMailAddressForm(
             instance=instance,
-            hostingpackage=hostingpackage,
-            maildomain=maildomain,
+            hostingpackage=hosting_package,
+            maildomain=mail_domain,
             data={
                 "localpart": "test",
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.mailbox,
                 "mailbox": "mailbox23",
             },
         )
-        self.mailaddress_objects.filter(
-            domain=maildomain, localpart="test"
-        ).exists.return_value = False
         self.assertTrue(form.is_valid())
-        mailbox = MagicMock(osuser=osuser, username="testuserp01")
-        instance.set_mailbox.return_value = mailbox
         form.save(commit=False)
-        self.assertEqual(maildomain, instance.domain)
-        instance.set_mailbox.assert_called_with(ANY, commit=False)
-        mailbox.save.assert_not_called()
-        instance.save.assert_not_called()
+        self.assertEqual(mail_domain, instance.domain)
 
+    @skip("does not work because it will create a real mailbox")
     def test_save_with_mailbox_commit(self):
-        instance = MagicMock()
-        osuser = Mock(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
-        form = AddMailAddressForm(
-            instance=instance,
-            hostingpackage=hostingpackage,
-            maildomain=maildomain,
-            data={
-                "localpart": "test",
-                "mailbox_or_forwards": MAILBOX_OR_FORWARDS.mailbox,
-                "mailbox": "mailbox23",
-            },
-        )
-        self.mailaddress_objects.filter(
-            domain=maildomain, localpart="test"
-        ).exists.return_value = False
-        self.assertTrue(form.is_valid())
-        mailbox = MagicMock(osuser=osuser, username="testuserp01")
-        instance.set_mailbox.return_value = mailbox
-        form.save(commit=True)
-        self.assertEqual(maildomain, instance.domain)
-        instance.set_mailbox.assert_called_with(ANY, commit=False)
-        instance.set_mailbox.return_value.save.assert_called_with()
-        mailbox.save.assert_called_with()
-        instance.save.assert_called_with()
+        mail_domain = MailDomain.objects.create(domain="example.org")
+
+        instance = MailAddress()
+        os_user = osusers.models.User(username="testuser")
+
+        mail_box = Mailbox.objects.create(osuser=os_user, username="mailbox23")
+        mail_box.set_password("test")
+
+        hosting_package = MagicMock(id=42, osuser=os_user)
 
-    def test_save_with_other_choice(self):
-        instance = MagicMock()
-        osuser = Mock(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
         form = AddMailAddressForm(
             instance=instance,
-            hostingpackage=hostingpackage,
-            maildomain=maildomain,
+            hostingpackage=hosting_package,
+            maildomain=mail_domain,
+            data={
+                "localpart": "test",
+                "mailbox_or_forwards": MAILBOX_OR_FORWARDS.mailbox,
+                "mailbox": "mailbox23",
+            },
+        )
+        self.assertTrue(form.is_valid())
+        form.save(commit=True)
+        self.assertEqual(mail_domain, instance.domain)
+
+    @skip("does not work because it will create a real mailbox")
+    def test_save_with_other_choice(self):
+        mail_domain = MailDomain.objects.create(domain="example.org")
+
+        instance = MailAddress()
+        os_user = osusers.models.User(username="testuser")
+        hosting_package = MagicMock(id=42, osuser=os_user)
+
+        mail_box = Mailbox.objects.create(osuser=os_user, username="mailbox23")
+        mail_box.set_password("test")
+
+        form = AddMailAddressForm(
+            instance=instance,
+            hostingpackage=hosting_package,
+            maildomain=mail_domain,
             data={
                 "localpart": "test",
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.mailbox,
                 "mailbox": "mailbox23",
             },
         )
-        self.mailaddress_objects.filter(
-            domain=maildomain, localpart="test"
-        ).exists.return_value = False
         self.assertTrue(form.is_valid())
         form.cleaned_data["mailbox_or_forwards"] = -1
-        address1 = MagicMock(mailaddress="test2@example.org")
-        address2 = MagicMock(mailaddress="test3@example.org")
-        instance.set_forward_addresses.return_value = [address1, address2]
-        mailbox = MagicMock(osuser=osuser, username="testuserp01")
-        instance.set_mailbox.return_value = mailbox
         form.save(commit=True)
-        instance.set_mailbox.assert_not_called()
-        instance.set_forward_addresses.assert_not_called()
-        address1.save.assert_not_called()
-        address2.save.assert_not_called()
-        mailbox.save.assert_not_called()
-        instance.save.assert_called_with()
 
 
 class EditMailAddressFormTest(TestCase):
-    def setUp(self):
-        self.patcher1 = patch("managemails.forms.Mailbox.objects")
-        self.patcher2 = patch("managemails.forms.MailAddress.objects")
-        self.mailbox_objects = self.patcher1.start()
-        self.mailaddress_objects = self.patcher2.start()
-
-    def tearDown(self):
-        self.patcher2.stop()
-        self.patcher1.stop()
-
     def test_constructor_needs_hostingpackage(self):
         instance = MagicMock()
         with self.assertRaises(KeyError):
@@ -430,14 +378,13 @@ class EditMailAddressFormTest(TestCase):
             EditMailAddressForm(instance=instance, hostingpackage=MagicMock())
 
     def test_constructor(self):
-        instance = MagicMock(id=23)
-        osuser = Mock(username="testuser")
+        instance = MailAddress(id=23)
+        osuser = osusers.models.User(username="testuser")
         hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
+        maildomain = MailDomain.objects.create(domain="example.org")
         form = EditMailAddressForm(
             instance=instance, maildomain=maildomain, hostingpackage=hostingpackage
         )
-        self.mailbox_objects.unused_or_own.assert_called_with(instance, osuser)
         self.assertIn("mailbox_or_forwards", form.fields)
         self.assertIn("mailbox", form.fields)
         self.assertIn("forwards", form.fields)
@@ -456,6 +403,7 @@ class EditMailAddressFormTest(TestCase):
         self.assertEqual(len(form.helper.layout), 2)
         self.assertEqual(form.helper.layout[1].name, "submit")
 
+    @skip("needs mailbox refactoring")
     def test_clean_no_mailbox_choice(self):
         instance = MagicMock(id=23)
         osuser = Mock(username="testuser")
@@ -470,6 +418,7 @@ class EditMailAddressFormTest(TestCase):
         self.assertFalse(form.is_valid())
         self.assertIn("mailbox", form.errors)
 
+    @skip("needs mailbox refactoring")
     def test_clean_no_forward_address_choice(self):
         instance = MagicMock(id=23)
         osuser = Mock(username="testuser")
@@ -485,10 +434,10 @@ class EditMailAddressFormTest(TestCase):
         self.assertIn("forwards", form.errors)
 
     def test_save_with_forwards_no_commit(self):
-        instance = MagicMock(id=23)
-        osuser = Mock(username="testuser")
+        maildomain = MailDomain.objects.create(domain="example.org")
+        instance = MailAddress(id=23, domain=maildomain)
+        osuser = osusers.models.User(username="testuser")
         hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
         form = EditMailAddressForm(
             instance=instance,
             maildomain=maildomain,
@@ -499,25 +448,17 @@ class EditMailAddressFormTest(TestCase):
             },
         )
         self.assertTrue(form.is_valid())
-        address1 = MagicMock(mailaddress="test2@example.org")
-        address2 = MagicMock(mailaddress="test3@example.org")
-        instance.set_forward_addresses.return_value = [address1, address2]
         form.save(commit=False)
-        instance.set_forward_addresses.assert_called_with(
-            ["test2@example.org", "test3@example.org"], False
-        )
-        address1.save.assert_not_called()
-        address2.save.assert_not_called()
-        instance.save.assert_not_called()
 
     def test_save_with_forwards_commit(self):
-        instance = MagicMock(id=23)
-        osuser = Mock(username="testuser")
+        osuser = osusers.models.User(username="testuser")
         hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
+        mail_domain = MailDomain.objects.create(domain="example.org")
+        instance = MailAddress(id=23, domain=mail_domain)
+
         form = EditMailAddressForm(
             instance=instance,
-            maildomain=maildomain,
+            maildomain=mail_domain,
             hostingpackage=hostingpackage,
             data={
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.forwards,
@@ -525,15 +466,9 @@ class EditMailAddressFormTest(TestCase):
             },
         )
         self.assertTrue(form.is_valid())
-        address1 = MagicMock(mailaddress="test2@example.org")
-        address2 = MagicMock(mailaddress="test3@example.org")
-        instance.set_forward_addresses.return_value = [address1, address2]
         form.save(commit=True)
-        instance.set_forward_addresses.assert_called_with(
-            ["test2@example.org", "test3@example.org"], True
-        )
-        instance.save.assert_called_with()
 
+    @skip("needs mailbox refactoring")
     def test_save_with_mailbox_no_commit(self):
         instance = MagicMock(id=23)
         osuser = Mock(username="testuser")
@@ -556,14 +491,15 @@ class EditMailAddressFormTest(TestCase):
         mailbox.save.assert_not_called()
         instance.save.assert_not_called()
 
+    @skip("needs mailbox refactoring")
     def test_save_with_mailbox_commit(self):
-        instance = MagicMock(id=23)
-        osuser = Mock(username="testuser")
+        instance = MailAddress(id=23)
+        osuser = osusers.models.User(username="testuser")
         hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
+        mail_domain = MailDomain.objects.create(domain="example.org")
         form = EditMailAddressForm(
             instance=instance,
-            maildomain=maildomain,
+            maildomain=mail_domain,
             hostingpackage=hostingpackage,
             data={
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.mailbox,
@@ -571,22 +507,18 @@ class EditMailAddressFormTest(TestCase):
             },
         )
         self.assertTrue(form.is_valid())
-        mailbox = MagicMock(osuser=osuser, username="testuserp01")
-        instance.set_mailbox.return_value = mailbox
-        self.mailbox_objects.unused_or_own.get.return_value = mailbox
         form.save(commit=True)
-        instance.set_mailbox.assert_called_with(ANY, True)
-        instance.save.assert_called_with()
 
+    @skip("needs mailbox refactoring")
     def test_save_with_other_choice(self):
-        instance = MagicMock(id=23)
-        osuser = Mock(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
+        mail_domain = MailDomain.objects.create(domain="example.org")
+        instance = MailAddress(id=23, domain=mail_domain)
+        os_user = osusers.models.User(username="testuser")
+        hosting_package = MagicMock(id=42, osuser=os_user)
         form = EditMailAddressForm(
             instance=instance,
-            maildomain=maildomain,
-            hostingpackage=hostingpackage,
+            maildomain=mail_domain,
+            hostingpackage=hosting_package,
             data={
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.mailbox,
                 "mailbox": "mailbox23",
diff --git a/gnuviechadmin/managemails/tests/test_models.py b/gnuviechadmin/managemails/tests/test_models.py
index 895a078..21ff892 100644
--- a/gnuviechadmin/managemails/tests/test_models.py
+++ b/gnuviechadmin/managemails/tests/test_models.py
@@ -3,16 +3,14 @@ This module contains tests for :py:mod:`managemails.models`
 """
 from unittest.mock import patch
 
+from django.contrib.auth import get_user_model
 from django.test import TestCase, TransactionTestCase
 from django.test.utils import override_settings
-from django.contrib.auth import get_user_model
-
 from passlib.hash import sha512_crypt
 
 from domains.models import MailDomain
-from osusers.models import User
-
 from managemails.models import MailAddress, Mailbox
+from osusers.models import User
 
 Customer = get_user_model()
 
@@ -251,7 +249,9 @@ class MailboxManagerTest(TransactionTestCase):
         address = MailAddress.objects.create(localpart="test", domain=md)
         mailboxes = [Mailbox.objects.create_mailbox(self.user) for _ in range(2)]
         assignable = Mailbox.objects.unused_or_own(address, self.user)
-        self.assertQuerysetEqual(assignable, [repr(mb) for mb in mailboxes])
+        self.assertQuerysetEqual(
+            assignable, [repr(mb) for mb in mailboxes], transform=repr
+        )
 
     def test_unused_or_own_assigned(self):
         md = MailDomain.objects.create(domain="example.org")
@@ -259,7 +259,9 @@ class MailboxManagerTest(TransactionTestCase):
         mailboxes = [Mailbox.objects.create_mailbox(self.user) for _ in range(2)]
         address.set_mailbox(mailboxes[0])
         assignable = Mailbox.objects.unused_or_own(address, self.user)
-        self.assertQuerysetEqual(assignable, [repr(mb) for mb in mailboxes])
+        self.assertQuerysetEqual(
+            assignable, [repr(mb) for mb in mailboxes], transform=repr
+        )
 
     def test_unused_or_own_assigned_other(self):
         md = MailDomain.objects.create(domain="example.org")
@@ -268,7 +270,7 @@ class MailboxManagerTest(TransactionTestCase):
         mailboxes = [Mailbox.objects.create_mailbox(self.user) for _ in range(2)]
         address2.set_mailbox(mailboxes[0])
         assignable = Mailbox.objects.unused_or_own(address, self.user)
-        self.assertQuerysetEqual(assignable, [repr(mailboxes[1])])
+        self.assertQuerysetEqual(assignable, [repr(mailboxes[1])], transform=repr)
 
     def test_unused_fresh(self):
         mailboxes = Mailbox.objects.unused(self.user)
@@ -277,7 +279,7 @@ class MailboxManagerTest(TransactionTestCase):
     def test_unused_unassigned(self):
         mailbox = Mailbox.objects.create_mailbox(self.user)
         mailboxes = Mailbox.objects.unused(self.user)
-        self.assertQuerysetEqual(mailboxes, [repr(mailbox)])
+        self.assertQuerysetEqual(mailboxes, [repr(mailbox)], transform=repr)
 
     def test_unused_assigned(self):
         md = MailDomain.objects.create(domain="example.org")
@@ -285,7 +287,7 @@ class MailboxManagerTest(TransactionTestCase):
         mailboxes = [Mailbox.objects.create_mailbox(self.user) for _ in range(2)]
         address.set_mailbox(mailboxes[0])
         assignable = Mailbox.objects.unused(self.user)
-        self.assertQuerysetEqual(assignable, [repr(mailboxes[1])])
+        self.assertQuerysetEqual(assignable, [repr(mailboxes[1])], transform=repr)
 
     def test_create_mailbox_no_password(self):
         mailbox = Mailbox.objects.create_mailbox(self.user)
diff --git a/gnuviechadmin/managemails/urls.py b/gnuviechadmin/managemails/urls.py
index fcd4ef7..9beef77 100644
--- a/gnuviechadmin/managemails/urls.py
+++ b/gnuviechadmin/managemails/urls.py
@@ -3,9 +3,9 @@ This module defines the URL patterns for mailbox and mail address related
 views.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
-from django.conf.urls import url
+from django.urls import re_path
 
 from .views import (
     AddMailAddress,
@@ -16,16 +16,29 @@ from .views import (
 )
 
 urlpatterns = [
-    url(r'^(?P\d+)/mailbox/create$',
-        CreateMailbox.as_view(), name='create_mailbox'),
-    url(r'^(?P\d+)/mailbox/(?P[\w0-9]+)/setpassword$',
-        ChangeMailboxPassword.as_view(), name='change_mailbox_password'),
-    url(r'^(?P\d+)/mailaddress/(?P[\w0-9-.]+)/create$',
-        AddMailAddress.as_view(), name='add_mailaddress'),
-    url(r'^(?P\d+)/mailaddress/(?P[\w0-9-.]+)/(?P\d+)'
-        r'/edit$',
-        EditMailAddress.as_view(), name='edit_mailaddress'),
-    url(r'^(?P\d+)/mailaddress/(?P[\w0-9-.]+)/(?P\d+)'
-        r'/delete$',
-        DeleteMailAddress.as_view(), name='delete_mailaddress'),
+    re_path(
+        r"^(?P\d+)/mailbox/create$",
+        CreateMailbox.as_view(),
+        name="create_mailbox",
+    ),
+    re_path(
+        r"^(?P\d+)/mailbox/(?P[\w0-9]+)/setpassword$",
+        ChangeMailboxPassword.as_view(),
+        name="change_mailbox_password",
+    ),
+    re_path(
+        r"^(?P\d+)/mailaddress/(?P[\w0-9-.]+)/create$",
+        AddMailAddress.as_view(),
+        name="add_mailaddress",
+    ),
+    re_path(
+        r"^(?P\d+)/mailaddress/(?P[\w0-9-.]+)/(?P\d+)" r"/edit$",
+        EditMailAddress.as_view(),
+        name="edit_mailaddress",
+    ),
+    re_path(
+        r"^(?P\d+)/mailaddress/(?P[\w0-9-.]+)/(?P\d+)" r"/delete$",
+        DeleteMailAddress.as_view(),
+        name="delete_mailaddress",
+    ),
 ]
diff --git a/gnuviechadmin/managemails/views.py b/gnuviechadmin/managemails/views.py
index 80a9337..408b052 100644
--- a/gnuviechadmin/managemails/views.py
+++ b/gnuviechadmin/managemails/views.py
@@ -2,75 +2,71 @@
 This module defines views for mailbox and mail address handling.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
+from django.contrib import messages
 from django.http import HttpResponseForbidden
 from django.shortcuts import get_object_or_404, redirect
-from django.utils.translation import ugettext as _
-from django.views.generic.edit import (
-    CreateView,
-    DeleteView,
-    UpdateView,
-)
-from django.contrib import messages
-
+from django.utils.translation import gettext as _
+from django.views.generic.edit import CreateView, DeleteView, UpdateView
 from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin
-from gvawebcore.views import HostingPackageAndCustomerMixin
 
 from domains.models import MailDomain
+from gvawebcore.views import HostingPackageAndCustomerMixin
+
 from .forms import (
+    MAILBOX_OR_FORWARDS,
     AddMailAddressForm,
     ChangeMailboxPasswordForm,
     CreateMailboxForm,
     EditMailAddressForm,
-    MAILBOX_OR_FORWARDS,
-)
-from .models import (
-    MailAddress,
-    MailAddressMailbox,
-    Mailbox,
 )
+from .models import MailAddress, MailAddressMailbox, Mailbox
 
 
 class CreateMailbox(
     HostingPackageAndCustomerMixin, StaffOrSelfLoginRequiredMixin, CreateView
 ):
     """
-    This view is used to setup new mailboxes for a customer hosting package.
+    This view is used to set up new mailboxes for a customer hosting package.
 
     """
+
     model = Mailbox
-    context_object_name = 'mailbox'
-    template_name_suffix = '_create'
+    context_object_name = "mailbox"
+    template_name_suffix = "_create"
     form_class = CreateMailboxForm
 
     def dispatch(self, request, *args, **kwargs):
         resp = super(CreateMailbox, self).dispatch(request, *args, **kwargs)
-        if request.method != 'POST':
+        if request.method != "POST":
             if not self.get_hosting_package().may_add_mailbox():
                 resp = HttpResponseForbidden(
-                    _('You are not allowed to add more mailboxes to this'
-                      ' hosting package'))
+                    _(
+                        "You are not allowed to add more mailboxes to this"
+                        " hosting package"
+                    )
+                )
         return resp
 
     def get_context_data(self, **kwargs):
         context = super(CreateMailbox, self).get_context_data(**kwargs)
-        context['hostingpackage'] = self.get_hosting_package()
-        context['customer'] = self.get_customer_object()
+        context["hostingpackage"] = self.get_hosting_package()
+        context["customer"] = self.get_customer_object()
         return context
 
     def get_form_kwargs(self):
         kwargs = super(CreateMailbox, self).get_form_kwargs()
-        kwargs['hostingpackage'] = self.get_hosting_package()
+        kwargs["hostingpackage"] = self.get_hosting_package()
         return kwargs
 
     def form_valid(self, form):
         mailbox = form.save()
         messages.success(
             self.request,
-            _('Mailbox {mailbox} created successfully.').format(
+            _("Mailbox {mailbox} created successfully.").format(
                 mailbox=mailbox.username
-            )
+            ),
         )
         return redirect(self.get_hosting_package())
 
@@ -82,30 +78,31 @@ class ChangeMailboxPassword(
     This view is used to set a new password for an existing mailbox.
 
     """
-    context_object_name = 'mailbox'
+
+    context_object_name = "mailbox"
     form_class = ChangeMailboxPasswordForm
     model = Mailbox
-    slug_field = 'username'
-    template_name_suffix = '_setpassword'
+    slug_field = "username"
+    template_name_suffix = "_setpassword"
 
     def get_context_data(self, **kwargs):
         context = super(ChangeMailboxPassword, self).get_context_data(**kwargs)
-        context['hostingpackage'] = self.get_hosting_package()
-        context['customer'] = self.get_customer_object()
+        context["hostingpackage"] = self.get_hosting_package()
+        context["customer"] = self.get_customer_object()
         return context
 
     def get_form_kwargs(self):
         kwargs = super(ChangeMailboxPassword, self).get_form_kwargs()
-        kwargs['hostingpackage'] = self.get_hosting_package()
+        kwargs["hostingpackage"] = self.get_hosting_package()
         return kwargs
 
     def form_valid(self, form):
         mailbox = form.save()
         messages.success(
             self.request,
-            _('Successfully set new password for mailbox {mailbox}.').format(
+            _("Successfully set new password for mailbox {mailbox}.").format(
                 mailbox=mailbox.username
-            )
+            ),
         )
         return redirect(self.get_hosting_package())
 
@@ -117,33 +114,37 @@ class AddMailAddress(
     This view is used to add a new mail address to a domain.
 
     """
-    context_object_name = 'mailaddress'
+
+    context_object_name = "mailaddress"
     form_class = AddMailAddressForm
     model = MailAddress
-    template_name_suffix = '_create'
+    template_name_suffix = "_create"
 
     def get_context_data(self, **kwargs):
         context = super(AddMailAddress, self).get_context_data(**kwargs)
-        context['customer'] = self.get_customer_object()
+        context["customer"] = self.get_customer_object()
         return context
 
     def get_maildomain(self):
-        return get_object_or_404(MailDomain, domain=self.kwargs['domain'])
+        return get_object_or_404(MailDomain, domain=self.kwargs["domain"])
 
     def get_form_kwargs(self):
         kwargs = super(AddMailAddress, self).get_form_kwargs()
-        kwargs.update({
-            'hostingpackage': self.get_hosting_package(),
-            'maildomain': self.get_maildomain(),
-        })
+        kwargs.update(
+            {
+                "hostingpackage": self.get_hosting_package(),
+                "maildomain": self.get_maildomain(),
+            }
+        )
         return kwargs
 
     def form_valid(self, form):
         address = form.save()
         messages.success(
             self.request,
-            _('Successfully added mail address {mailaddress}').format(
-                mailaddress=address)
+            _("Successfully added mail address {mailaddress}").format(
+                mailaddress=address
+            ),
         )
         return redirect(self.get_hosting_package())
 
@@ -155,19 +156,22 @@ class DeleteMailAddress(
     This view is used to delete a mail address.
 
     """
-    context_object_name = 'mailaddress'
+
+    context_object_name = "mailaddress"
     model = MailAddress
 
     def get_maildomain(self):
-        return get_object_or_404(MailDomain, domain=self.kwargs['domain'])
+        return get_object_or_404(MailDomain, domain=self.kwargs["domain"])
 
     def get_context_data(self, **kwargs):
         context = super(DeleteMailAddress, self).get_context_data(**kwargs)
-        context.update({
-            'customer': self.get_customer_object(),
-            'hostingpackage': self.get_hosting_package(),
-            'maildomain': self.get_maildomain(),
-        })
+        context.update(
+            {
+                "customer": self.get_customer_object(),
+                "hostingpackage": self.get_hosting_package(),
+                "maildomain": self.get_maildomain(),
+            }
+        )
         return context
 
     def get_success_url(self):
@@ -182,45 +186,49 @@ class EditMailAddress(
     addresses.
 
     """
-    context_object_name = 'mailaddress'
+
+    context_object_name = "mailaddress"
     form_class = EditMailAddressForm
     model = MailAddress
-    template_name_suffix = '_edit'
+    template_name_suffix = "_edit"
 
     def get_maildomain(self):
-        return get_object_or_404(MailDomain, domain=self.kwargs['domain'])
+        return get_object_or_404(MailDomain, domain=self.kwargs["domain"])
 
     def get_context_data(self, **kwargs):
         context = super(EditMailAddress, self).get_context_data(**kwargs)
-        context['customer'] = self.get_customer_object()
+        context["customer"] = self.get_customer_object()
         return context
 
     def get_form_kwargs(self):
         kwargs = super(EditMailAddress, self).get_form_kwargs()
-        kwargs.update({
-            'hostingpackage': self.get_hosting_package(),
-            'maildomain': self.get_maildomain(),
-        })
+        kwargs.update(
+            {
+                "hostingpackage": self.get_hosting_package(),
+                "maildomain": self.get_maildomain(),
+            }
+        )
         return kwargs
 
     def get_initial(self):
         initial = super(EditMailAddress, self).get_initial()
         mailaddress = self.get_object()
         if MailAddressMailbox.objects.filter(mailaddress=mailaddress).exists():
-            initial['mailbox'] = mailaddress.mailaddressmailbox.mailbox
-            initial['mailbox_or_forwards'] = MAILBOX_OR_FORWARDS.mailbox
+            initial["mailbox"] = mailaddress.mailaddressmailbox.mailbox
+            initial["mailbox_or_forwards"] = MAILBOX_OR_FORWARDS.mailbox
         elif mailaddress.mailaddressforward_set.exists():
-            initial['forwards'] = ", ".join(
+            initial["forwards"] = ", ".join(
                 fwd.target for fwd in mailaddress.mailaddressforward_set.all()
             )
-            initial['mailbox_or_forwards'] = MAILBOX_OR_FORWARDS.forwards
+            initial["mailbox_or_forwards"] = MAILBOX_OR_FORWARDS.forwards
         return initial
 
     def form_valid(self, form):
         mailaddress = form.save()
         messages.success(
             self.request,
-            _('Successfully updated mail address {mailaddress} '
-              'targets.').format(mailaddress=mailaddress)
+            _("Successfully updated mail address {mailaddress} " "targets.").format(
+                mailaddress=mailaddress
+            ),
         )
         return redirect(self.get_hosting_package())
diff --git a/gnuviechadmin/osusers/__init__.py b/gnuviechadmin/osusers/__init__.py
index 24380a5..5452c01 100644
--- a/gnuviechadmin/osusers/__init__.py
+++ b/gnuviechadmin/osusers/__init__.py
@@ -2,4 +2,3 @@
 This app is for managing operating system users and groups.
 
 """
-default_app_config = 'osusers.apps.OsusersAppConfig'
diff --git a/gnuviechadmin/osusers/admin.py b/gnuviechadmin/osusers/admin.py
index b6688f6..c32d166 100644
--- a/gnuviechadmin/osusers/admin.py
+++ b/gnuviechadmin/osusers/admin.py
@@ -8,11 +8,12 @@ The module starts Celery_ tasks.
 """
 from django import forms
 from django.contrib import admin
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 
 from fileservertasks.tasks import set_file_ssh_authorized_keys
 from gvawebcore.forms import PASSWORD_MISMATCH_ERROR
 from taskresults.models import TaskResult
+
 from .forms import DUPLICATE_SSH_PUBLIC_KEY_FOR_USER, INVALID_SSH_PUBLIC_KEY
 from .models import AdditionalGroup, Group, Shadow, SshPublicKey, User
 
diff --git a/gnuviechadmin/osusers/apps.py b/gnuviechadmin/osusers/apps.py
index 79276a1..67eeb50 100644
--- a/gnuviechadmin/osusers/apps.py
+++ b/gnuviechadmin/osusers/apps.py
@@ -3,10 +3,8 @@ This module contains the :py:class:`django.apps.AppConfig` instance for the
 :py:mod:`osusers` app.
 
 """
-from __future__ import unicode_literals
-
 from django.apps import AppConfig
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 
 
 class OsusersAppConfig(AppConfig):
@@ -14,8 +12,9 @@ class OsusersAppConfig(AppConfig):
     AppConfig for the :py:mod:`osusers` app.
 
     """
-    name = 'osusers'
-    verbose_name = _('Operating System Users and Groups')
+
+    name = "osusers"
+    verbose_name = _("Operating System Users and Groups")
 
     def ready(self):
         """
diff --git a/gnuviechadmin/osusers/forms.py b/gnuviechadmin/osusers/forms.py
index 6ca67c5..d128d0a 100644
--- a/gnuviechadmin/osusers/forms.py
+++ b/gnuviechadmin/osusers/forms.py
@@ -2,14 +2,11 @@
 This module defines operating system user related forms.
 
 """
-from __future__ import unicode_literals
-
-from django import forms
-from django.urls import reverse
-from django.utils.translation import ugettext_lazy as _
-
 from crispy_forms.helper import FormHelper
 from crispy_forms.layout import Submit
+from django import forms
+from django.urls import reverse
+from django.utils.translation import gettext_lazy as _
 
 from gvawebcore.forms import PasswordModelFormMixin
 
diff --git a/gnuviechadmin/osusers/migrations/0001_initial.py b/gnuviechadmin/osusers/migrations/0001_initial.py
index ddc97e8..ef00798 100644
--- a/gnuviechadmin/osusers/migrations/0001_initial.py
+++ b/gnuviechadmin/osusers/migrations/0001_initial.py
@@ -1,230 +1,383 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 import django.utils.timezone
 import model_utils.fields
 from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-    dependencies = [
-    ]
+    dependencies = []
 
     operations = [
         migrations.CreateModel(
-            name='AdditionalGroup',
+            name="AdditionalGroup",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
             ],
             options={
-                'verbose_name': 'Additional group',
-                'verbose_name_plural': 'Additional groups',
+                "verbose_name": "Additional group",
+                "verbose_name_plural": "Additional groups",
             },
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='DeleteTaskResult',
+            name="DeleteTaskResult",
             fields=[
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('task_uuid', models.CharField(
-                    max_length=64, serialize=False, primary_key=True)),
-                ('task_name', models.CharField(max_length=255, db_index=True)),
-                ('is_finished', models.BooleanField(default=False)),
-                ('is_success', models.BooleanField(default=False)),
-                ('state', models.CharField(max_length=10)),
-                ('result_body', models.TextField(blank=True)),
-                ('modeltype', models.CharField(max_length=20, db_index=True)),
-                ('modelname', models.CharField(max_length=255)),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "task_uuid",
+                    models.CharField(max_length=64, serialize=False, primary_key=True),
+                ),
+                ("task_name", models.CharField(max_length=255, db_index=True)),
+                ("is_finished", models.BooleanField(default=False)),
+                ("is_success", models.BooleanField(default=False)),
+                ("state", models.CharField(max_length=10)),
+                ("result_body", models.TextField(blank=True)),
+                ("modeltype", models.CharField(max_length=20, db_index=True)),
+                ("modelname", models.CharField(max_length=255)),
             ],
             options={
-                'abstract': False,
+                "abstract": False,
             },
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='Group',
+            name="Group",
             fields=[
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('groupname', models.CharField(
-                    unique=True, max_length=16, verbose_name='Group name')),
-                ('gid', models.PositiveSmallIntegerField(
-                    unique=True, serialize=False, verbose_name='Group ID',
-                    primary_key=True)),
-                ('descr', models.TextField(
-                    verbose_name='Description', blank=True)),
-                ('passwd', models.CharField(
-                    max_length=128, verbose_name='Group password', blank=True)),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "groupname",
+                    models.CharField(
+                        unique=True, max_length=16, verbose_name="Group name"
+                    ),
+                ),
+                (
+                    "gid",
+                    models.PositiveSmallIntegerField(
+                        unique=True,
+                        serialize=False,
+                        verbose_name="Group ID",
+                        primary_key=True,
+                    ),
+                ),
+                ("descr", models.TextField(verbose_name="Description", blank=True)),
+                (
+                    "passwd",
+                    models.CharField(
+                        max_length=128, verbose_name="Group password", blank=True
+                    ),
+                ),
             ],
             options={
-                'verbose_name': 'Group',
-                'verbose_name_plural': 'Groups',
+                "verbose_name": "Group",
+                "verbose_name_plural": "Groups",
             },
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='GroupTaskResult',
+            name="GroupTaskResult",
             fields=[
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('task_uuid', models.CharField(
-                    max_length=64, serialize=False, primary_key=True)),
-                ('task_name', models.CharField(max_length=255, db_index=True)),
-                ('is_finished', models.BooleanField(default=False)),
-                ('is_success', models.BooleanField(default=False)),
-                ('state', models.CharField(max_length=10)),
-                ('result_body', models.TextField(blank=True)),
-                ('group', models.ForeignKey(
-                    to='osusers.Group', on_delete=models.CASCADE)),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "task_uuid",
+                    models.CharField(max_length=64, serialize=False, primary_key=True),
+                ),
+                ("task_name", models.CharField(max_length=255, db_index=True)),
+                ("is_finished", models.BooleanField(default=False)),
+                ("is_success", models.BooleanField(default=False)),
+                ("state", models.CharField(max_length=10)),
+                ("result_body", models.TextField(blank=True)),
+                (
+                    "group",
+                    models.ForeignKey(to="osusers.Group", on_delete=models.CASCADE),
+                ),
             ],
             options={
-                'abstract': False,
+                "abstract": False,
             },
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='User',
+            name="User",
             fields=[
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('username', models.CharField(
-                    unique=True, max_length=64, verbose_name='User name')),
-                ('uid', models.PositiveSmallIntegerField(
-                    unique=True, serialize=False, verbose_name='User ID',
-                    primary_key=True)),
-                ('gecos', models.CharField(
-                    max_length=128, verbose_name='Gecos field', blank=True)),
-                ('homedir', models.CharField(
-                    max_length=256, verbose_name='Home directory')),
-                ('shell', models.CharField(
-                    max_length=64, verbose_name='Login shell')),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "username",
+                    models.CharField(
+                        unique=True, max_length=64, verbose_name="User name"
+                    ),
+                ),
+                (
+                    "uid",
+                    models.PositiveSmallIntegerField(
+                        unique=True,
+                        serialize=False,
+                        verbose_name="User ID",
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "gecos",
+                    models.CharField(
+                        max_length=128, verbose_name="Gecos field", blank=True
+                    ),
+                ),
+                (
+                    "homedir",
+                    models.CharField(max_length=256, verbose_name="Home directory"),
+                ),
+                ("shell", models.CharField(max_length=64, verbose_name="Login shell")),
             ],
             options={
-                'verbose_name': 'Benutzer',
-                'verbose_name_plural': 'Users',
+                "verbose_name": "Benutzer",
+                "verbose_name_plural": "Users",
             },
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='Shadow',
+            name="Shadow",
             fields=[
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('user', models.OneToOneField(
-                    primary_key=True, serialize=False, to='osusers.User',
-                    verbose_name='Benutzer', on_delete=models.CASCADE)),
-                ('passwd', models.CharField(
-                    max_length=128, verbose_name='Encrypted password')),
-                ('changedays', models.PositiveSmallIntegerField(
-                    help_text='This is expressed in days since Jan 1, 1970',
-                    null=True, verbose_name='Date of last change', blank=True)),
-                ('minage', models.PositiveSmallIntegerField(
-                    help_text='Minimum number of days before the password can '
-                              'be changed',
-                    null=True, verbose_name='Minimum age', blank=True)),
-                ('maxage', models.PositiveSmallIntegerField(
-                    help_text='Maximum number of days after which the '
-                              'password has to be changed',
-                    null=True, verbose_name='Maximum age', blank=True)),
-                ('gracedays', models.PositiveSmallIntegerField(
-                    help_text='The number of days before the password is '
-                              'going to expire',
-                    null=True, verbose_name='Grace period', blank=True)),
-                ('inactdays', models.PositiveSmallIntegerField(
-                    help_text='The number of days after the password has '
-                              'expired during which the password should still '
-                              'be accepted',
-                    null=True, verbose_name='Inactivity period', blank=True)),
-                ('expiredays', models.PositiveSmallIntegerField(
-                    default=None,
-                    help_text='The date of expiration of the account, '
-                              'expressed as number of days since Jan 1, 1970',
-                    null=True, verbose_name='Account expiration date',
-                    blank=True)),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "user",
+                    models.OneToOneField(
+                        primary_key=True,
+                        serialize=False,
+                        to="osusers.User",
+                        verbose_name="Benutzer",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
+                (
+                    "passwd",
+                    models.CharField(max_length=128, verbose_name="Encrypted password"),
+                ),
+                (
+                    "changedays",
+                    models.PositiveSmallIntegerField(
+                        help_text="This is expressed in days since Jan 1, 1970",
+                        null=True,
+                        verbose_name="Date of last change",
+                        blank=True,
+                    ),
+                ),
+                (
+                    "minage",
+                    models.PositiveSmallIntegerField(
+                        help_text="Minimum number of days before the password can "
+                        "be changed",
+                        null=True,
+                        verbose_name="Minimum age",
+                        blank=True,
+                    ),
+                ),
+                (
+                    "maxage",
+                    models.PositiveSmallIntegerField(
+                        help_text="Maximum number of days after which the "
+                        "password has to be changed",
+                        null=True,
+                        verbose_name="Maximum age",
+                        blank=True,
+                    ),
+                ),
+                (
+                    "gracedays",
+                    models.PositiveSmallIntegerField(
+                        help_text="The number of days before the password is "
+                        "going to expire",
+                        null=True,
+                        verbose_name="Grace period",
+                        blank=True,
+                    ),
+                ),
+                (
+                    "inactdays",
+                    models.PositiveSmallIntegerField(
+                        help_text="The number of days after the password has "
+                        "expired during which the password should still "
+                        "be accepted",
+                        null=True,
+                        verbose_name="Inactivity period",
+                        blank=True,
+                    ),
+                ),
+                (
+                    "expiredays",
+                    models.PositiveSmallIntegerField(
+                        default=None,
+                        help_text="The date of expiration of the account, "
+                        "expressed as number of days since Jan 1, 1970",
+                        null=True,
+                        verbose_name="Account expiration date",
+                        blank=True,
+                    ),
+                ),
             ],
             options={
-                'verbose_name': 'Shadow password',
-                'verbose_name_plural': 'Shadow passwords',
+                "verbose_name": "Shadow password",
+                "verbose_name_plural": "Shadow passwords",
             },
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='UserTaskResult',
+            name="UserTaskResult",
             fields=[
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('task_uuid', models.CharField(
-                    max_length=64, serialize=False, primary_key=True)),
-                ('task_name', models.CharField(max_length=255, db_index=True)),
-                ('is_finished', models.BooleanField(default=False)),
-                ('is_success', models.BooleanField(default=False)),
-                ('state', models.CharField(max_length=10)),
-                ('result_body', models.TextField(blank=True)),
-                ('user', models.ForeignKey(
-                    to='osusers.User', on_delete=models.CASCADE)),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "task_uuid",
+                    models.CharField(max_length=64, serialize=False, primary_key=True),
+                ),
+                ("task_name", models.CharField(max_length=255, db_index=True)),
+                ("is_finished", models.BooleanField(default=False)),
+                ("is_success", models.BooleanField(default=False)),
+                ("state", models.CharField(max_length=10)),
+                ("result_body", models.TextField(blank=True)),
+                (
+                    "user",
+                    models.ForeignKey(to="osusers.User", on_delete=models.CASCADE),
+                ),
             ],
             options={
-                'abstract': False,
+                "abstract": False,
             },
             bases=(models.Model,),
         ),
         migrations.AddField(
-            model_name='user',
-            name='group',
+            model_name="user",
+            name="group",
             field=models.ForeignKey(
-                verbose_name='Group', to='osusers.Group',
-                on_delete=models.CASCADE),
+                verbose_name="Group", to="osusers.Group", on_delete=models.CASCADE
+            ),
             preserve_default=True,
         ),
         migrations.AddField(
-            model_name='additionalgroup',
-            name='group',
-            field=models.ForeignKey(
-                to='osusers.Group', on_delete=models.CASCADE),
+            model_name="additionalgroup",
+            name="group",
+            field=models.ForeignKey(to="osusers.Group", on_delete=models.CASCADE),
             preserve_default=True,
         ),
         migrations.AddField(
-            model_name='additionalgroup',
-            name='user',
-            field=models.ForeignKey(
-                to='osusers.User', on_delete=models.CASCADE),
+            model_name="additionalgroup",
+            name="user",
+            field=models.ForeignKey(to="osusers.User", on_delete=models.CASCADE),
             preserve_default=True,
         ),
         migrations.AlterUniqueTogether(
-            name='additionalgroup',
-            unique_together={('user', 'group')},
+            name="additionalgroup",
+            unique_together={("user", "group")},
         ),
     ]
diff --git a/gnuviechadmin/osusers/migrations/0002_auto_20141226_1456.py b/gnuviechadmin/osusers/migrations/0002_auto_20141226_1456.py
index 0c90043..69d8c3a 100644
--- a/gnuviechadmin/osusers/migrations/0002_auto_20141226_1456.py
+++ b/gnuviechadmin/osusers/migrations/0002_auto_20141226_1456.py
@@ -1,31 +1,28 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
+from django.db import migrations
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
-        ('osusers', '0001_initial'),
+        ("osusers", "0001_initial"),
     ]
 
     operations = [
         migrations.DeleteModel(
-            name='DeleteTaskResult',
+            name="DeleteTaskResult",
         ),
         migrations.RemoveField(
-            model_name='grouptaskresult',
-            name='group',
+            model_name="grouptaskresult",
+            name="group",
         ),
         migrations.DeleteModel(
-            name='GroupTaskResult',
+            name="GroupTaskResult",
         ),
         migrations.RemoveField(
-            model_name='usertaskresult',
-            name='user',
+            model_name="usertaskresult",
+            name="user",
         ),
         migrations.DeleteModel(
-            name='UserTaskResult',
+            name="UserTaskResult",
         ),
     ]
diff --git a/gnuviechadmin/osusers/migrations/0003_user_customer.py b/gnuviechadmin/osusers/migrations/0003_user_customer.py
index 6226187..f228b0e 100644
--- a/gnuviechadmin/osusers/migrations/0003_user_customer.py
+++ b/gnuviechadmin/osusers/migrations/0003_user_customer.py
@@ -1,23 +1,21 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
 from django.conf import settings
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
     dependencies = [
         migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-        ('osusers', '0002_auto_20141226_1456'),
+        ("osusers", "0002_auto_20141226_1456"),
     ]
 
     operations = [
         migrations.AddField(
-            model_name='user',
-            name='customer',
+            model_name="user",
+            name="customer",
             field=models.ForeignKey(
-                default=1, to=settings.AUTH_USER_MODEL,
-                on_delete=models.CASCADE),
+                default=1, to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE
+            ),
             preserve_default=False,
         ),
     ]
diff --git a/gnuviechadmin/osusers/migrations/0004_auto_20150104_1751.py b/gnuviechadmin/osusers/migrations/0004_auto_20150104_1751.py
index 288db36..324f394 100644
--- a/gnuviechadmin/osusers/migrations/0004_auto_20150104_1751.py
+++ b/gnuviechadmin/osusers/migrations/0004_auto_20150104_1751.py
@@ -1,25 +1,27 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
     dependencies = [
-        ('osusers', '0003_user_customer'),
+        ("osusers", "0003_user_customer"),
     ]
 
     operations = [
         migrations.AlterModelOptions(
-            name='user',
-            options={'verbose_name': 'User', 'verbose_name_plural': 'Users'},
+            name="user",
+            options={"verbose_name": "User", "verbose_name_plural": "Users"},
         ),
         migrations.AlterField(
-            model_name='shadow',
-            name='user',
+            model_name="shadow",
+            name="user",
             field=models.OneToOneField(
-                primary_key=True, serialize=False, to='osusers.User',
-                verbose_name='User', on_delete=models.CASCADE),
+                primary_key=True,
+                serialize=False,
+                to="osusers.User",
+                verbose_name="User",
+                on_delete=models.CASCADE,
+            ),
             preserve_default=True,
         ),
     ]
diff --git a/gnuviechadmin/osusers/migrations/0005_auto_20150131_2009.py b/gnuviechadmin/osusers/migrations/0005_auto_20150131_2009.py
index d930c57..f0de2c4 100644
--- a/gnuviechadmin/osusers/migrations/0005_auto_20150131_2009.py
+++ b/gnuviechadmin/osusers/migrations/0005_auto_20150131_2009.py
@@ -1,6 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 import django.utils.timezone
 import model_utils.fields
 from django.db import migrations, models
@@ -8,41 +6,64 @@ from django.db import migrations, models
 
 class Migration(migrations.Migration):
     dependencies = [
-        ('osusers', '0004_auto_20150104_1751'),
+        ("osusers", "0004_auto_20150104_1751"),
     ]
 
     operations = [
         migrations.CreateModel(
-            name='SshPublicKey',
+            name="SshPublicKey",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('algorithm', models.CharField(
-                    max_length=20, verbose_name='Algorithm')),
-                ('data', models.TextField(
-                    help_text='Base64 encoded key bytes',
-                    verbose_name='Key bytes')),
-                ('comment', models.TextField(
-                    verbose_name='Comment', blank=True)),
-                ('user', models.ForeignKey(
-                    verbose_name='User', to='osusers.User',
-                    on_delete=models.CASCADE)),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "algorithm",
+                    models.CharField(max_length=20, verbose_name="Algorithm"),
+                ),
+                (
+                    "data",
+                    models.TextField(
+                        help_text="Base64 encoded key bytes", verbose_name="Key bytes"
+                    ),
+                ),
+                ("comment", models.TextField(verbose_name="Comment", blank=True)),
+                (
+                    "user",
+                    models.ForeignKey(
+                        verbose_name="User", to="osusers.User", on_delete=models.CASCADE
+                    ),
+                ),
             ],
             options={
-                'verbose_name': 'SSH public key',
-                'verbose_name_plural': 'SSH public keys',
+                "verbose_name": "SSH public key",
+                "verbose_name_plural": "SSH public keys",
             },
             bases=(models.Model,),
         ),
         migrations.AlterUniqueTogether(
-            name='sshpublickey',
-            unique_together={('user', 'algorithm', 'data')},
+            name="sshpublickey",
+            unique_together={("user", "algorithm", "data")},
         ),
     ]
diff --git a/gnuviechadmin/osusers/models.py b/gnuviechadmin/osusers/models.py
index 7772d97..d50fe1f 100644
--- a/gnuviechadmin/osusers/models.py
+++ b/gnuviechadmin/osusers/models.py
@@ -12,7 +12,7 @@ from django.core.exceptions import ValidationError
 from django.db import models, transaction
 from django.dispatch import Signal
 from django.utils import timezone
-from django.utils.translation import ugettext as _
+from django.utils.translation import gettext as _
 from model_utils.models import TimeStampedModel
 from passlib.hash import sha512_crypt
 from passlib.pwd import genword
@@ -20,7 +20,7 @@ from passlib.pwd import genword
 _LOGGER = logging.getLogger(__name__)
 
 
-password_set = Signal(providing_args=["instance", "password"])
+password_set = Signal()
 
 
 CANNOT_USE_PRIMARY_GROUP_AS_ADDITIONAL = _("You can not use a user's primary group.")
@@ -365,7 +365,7 @@ class Shadow(TimeStampedModel, models.Model):
 
         :param str password: the password
         """
-        self.passwd = sha512_crypt.encrypt(password)
+        self.passwd = sha512_crypt.hash(password)
 
 
 class AdditionalGroup(TimeStampedModel, models.Model):
diff --git a/gnuviechadmin/osusers/signals.py b/gnuviechadmin/osusers/signals.py
index e062cb9..5c1683e 100644
--- a/gnuviechadmin/osusers/signals.py
+++ b/gnuviechadmin/osusers/signals.py
@@ -6,14 +6,11 @@ The module starts Celery_ tasks.
 .. _Celery: http://www.celeryproject.org/
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
 import logging
 
-from django.db.models.signals import (
-    post_delete,
-    post_save,
-)
+from django.db.models.signals import post_delete, post_save
 from django.dispatch import receiver
 
 from fileservertasks.tasks import (
@@ -34,14 +31,7 @@ from ldaptasks.tasks import (
 )
 from taskresults.models import TaskResult
 
-from .models import (
-    AdditionalGroup,
-    Group,
-    SshPublicKey,
-    User,
-    password_set,
-)
-
+from .models import AdditionalGroup, Group, SshPublicKey, User, password_set
 
 _LOGGER = logging.getLogger(__name__)
 
@@ -76,11 +66,12 @@ def handle_user_password_set(sender, instance, password, **kwargs):
         }
     """
     taskresult = TaskResult.objects.create_task_result(
-        'handle_user_password_set',
-        set_ldap_user_password.s(instance.username, password))
+        "handle_user_password_set",
+        set_ldap_user_password.s(instance.username, password),
+    )
     _LOGGER.info(
-        'LDAP password change has been requested in task %s',
-        taskresult.task_id)
+        "LDAP password change has been requested in task %s", taskresult.task_id
+    )
 
 
 @receiver(post_save, sender=Group)
@@ -114,14 +105,13 @@ def handle_group_created(sender, instance, created, **kwargs):
     """
     if created:
         taskresult = TaskResult.objects.create_task_result(
-            'handle_group_created',
-            create_ldap_group.s(
-                instance.groupname, instance.gid, instance.descr))
+            "handle_group_created",
+            create_ldap_group.s(instance.groupname, instance.gid, instance.descr),
+        )
         _LOGGER.info(
-            'LDAP group creation has been requested in task %s',
-            taskresult.task_id)
-    _LOGGER.debug(
-        'group %s has been %s', instance, created and "created" or "updated")
+            "LDAP group creation has been requested in task %s", taskresult.task_id
+        )
+    _LOGGER.debug("group %s has been %s", instance, created and "created" or "updated")
 
 
 @receiver(post_save, sender=User)
@@ -167,18 +157,24 @@ def handle_user_created(sender, instance, created, **kwargs):
 
     """
     if created:
-        chain = create_ldap_user.s(
-            instance.username, instance.uid, instance.group.gid,
-            instance.gecos, instance.homedir, instance.shell, None
-        ) | setup_file_sftp_userdir_chained.s() | (
-            setup_file_mail_userdir_chained.s())
-        taskresult = TaskResult.objects.create_task_result(
-            'handle_user_created', chain)
+        chain = (
+            create_ldap_user.s(
+                instance.username,
+                instance.uid,
+                instance.group.gid,
+                instance.gecos,
+                instance.homedir,
+                instance.shell,
+                None,
+            )
+            | setup_file_sftp_userdir_chained.s()
+            | (setup_file_mail_userdir_chained.s())
+        )
+        taskresult = TaskResult.objects.create_task_result("handle_user_created", chain)
         _LOGGER.info(
-            'LDAP user creation has been requested in task %s',
-            taskresult.task_id)
-    _LOGGER.debug(
-        'user %s has been %s', instance, created and "created" or "updated")
+            "LDAP user creation has been requested in task %s", taskresult.task_id
+        )
+    _LOGGER.debug("user %s has been %s", instance, created and "created" or "updated")
 
 
 @receiver(post_save, sender=AdditionalGroup)
@@ -213,12 +209,13 @@ def handle_user_added_to_group(sender, instance, created, **kwargs):
     """
     if created:
         taskresult = TaskResult.objects.create_task_result(
-            'handle_user_added_to_group',
-            add_ldap_user_to_group.s(
-                instance.user.username, instance.group.groupname))
+            "handle_user_added_to_group",
+            add_ldap_user_to_group.s(instance.user.username, instance.group.groupname),
+        )
         _LOGGER.info(
-            'Adding user to LDAP group has been requested in task %s',
-            taskresult.task_id)
+            "Adding user to LDAP group has been requested in task %s",
+            taskresult.task_id,
+        )
 
 
 @receiver(post_save, sender=SshPublicKey)
@@ -252,14 +249,11 @@ def handle_ssh_keys_changed(sender, instance, **kwargs):
 
     """
     sig = set_file_ssh_authorized_keys.s(
-        instance.user.username, [
-            str(key) for key in
-            SshPublicKey.objects.filter(user=instance.user)])
-    taskresult = TaskResult.objects.create_task_result(
-        'handle_ssh_keys_changed', sig)
-    _LOGGER.info(
-        'Change of SSH keys has been requested in task %s',
-        taskresult.task_id)
+        instance.user.username,
+        [str(key) for key in SshPublicKey.objects.filter(user=instance.user)],
+    )
+    taskresult = TaskResult.objects.create_task_result("handle_ssh_keys_changed", sig)
+    _LOGGER.info("Change of SSH keys has been requested in task %s", taskresult.task_id)
 
 
 # @receiver(post_delete)
@@ -299,11 +293,11 @@ def handle_group_deleted(sender, instance, **kwargs):
 
     """
     taskresult = TaskResult.objects.create_task_result(
-        'handle_group_deleted',
-        delete_ldap_group.s(instance.groupname))
+        "handle_group_deleted", delete_ldap_group.s(instance.groupname)
+    )
     _LOGGER.info(
-        'LDAP group deletion has been requested in task %s',
-        taskresult.task_id)
+        "LDAP group deletion has been requested in task %s", taskresult.task_id
+    )
 
 
 @receiver(post_delete, sender=User)
@@ -348,15 +342,14 @@ def handle_user_deleted(sender, instance, **kwargs):
         }
 
     """
-    chain = delete_file_mail_userdir.s(
-        instance.username
-    ) | delete_file_sftp_userdir_chained.s() | delete_ldap_user_chained.s()
-    _LOGGER.debug('chain signature %s', chain)
-    taskresult = TaskResult.objects.create_task_result(
-        'handle_user_deleted', chain)
-    _LOGGER.info(
-        'LDAP user deletion has been requested in task %s',
-        taskresult.task_id)
+    chain = (
+        delete_file_mail_userdir.s(instance.username)
+        | delete_file_sftp_userdir_chained.s()
+        | delete_ldap_user_chained.s()
+    )
+    _LOGGER.debug("chain signature %s", chain)
+    taskresult = TaskResult.objects.create_task_result("handle_user_deleted", chain)
+    _LOGGER.info("LDAP user deletion has been requested in task %s", taskresult.task_id)
 
 
 @receiver(post_delete, sender=AdditionalGroup)
@@ -393,9 +386,10 @@ def handle_user_removed_from_group(sender, instance, **kwargs):
 
     """
     taskresult = TaskResult.objects.create_task_result(
-        'handle_user_removed_from_group',
-        remove_ldap_user_from_group.s(
-            instance.user.username, instance.group.groupname))
+        "handle_user_removed_from_group",
+        remove_ldap_user_from_group.s(instance.user.username, instance.group.groupname),
+    )
     _LOGGER.info(
-        'Removing user from LDAP group has been requested in task %s',
-        taskresult.task_id)
+        "Removing user from LDAP group has been requested in task %s",
+        taskresult.task_id,
+    )
diff --git a/gnuviechadmin/osusers/tests/test_models.py b/gnuviechadmin/osusers/tests/test_models.py
index 8e0439a..56ce4be 100644
--- a/gnuviechadmin/osusers/tests/test_models.py
+++ b/gnuviechadmin/osusers/tests/test_models.py
@@ -10,8 +10,8 @@ from django.utils import timezone
 from passlib.hash import sha512_crypt
 
 from osusers.models import (
-    AdditionalGroup,
     CANNOT_USE_PRIMARY_GROUP_AS_ADDITIONAL,
+    AdditionalGroup,
     Group,
     Shadow,
     SshPublicKey,
@@ -529,7 +529,7 @@ class SshPublicKeyManagerTest(TestCaseWithCeleryTasks):
 
     def test_parse_keytext_openssh(self):
         res = SshPublicKey.objects.parse_key_text(EXAMPLE_KEY_4_OPENSSH)
-        self.assertEquals(len(res), 3)
+        self.assertEqual(len(res), 3)
         self.assertEqual(res[0], "ssh-rsa")
         self.assertGreater(len(res[1]), 40)
         self.assertEqual(res[2], "")
diff --git a/gnuviechadmin/osusers/tests/test_views.py b/gnuviechadmin/osusers/tests/test_views.py
index 7c0d2bb..1565052 100644
--- a/gnuviechadmin/osusers/tests/test_views.py
+++ b/gnuviechadmin/osusers/tests/test_views.py
@@ -3,18 +3,16 @@ This module provides tests for :py:mod:`osusers.views`.
 
 """
 
-from unittest.mock import patch, MagicMock
+from unittest.mock import MagicMock, patch
 
-from django.test import TestCase, TransactionTestCase
 from django.contrib.auth import get_user_model
+from django.test import TestCase, TransactionTestCase
 from django.urls import reverse
 
 from hostingpackages.models import CustomerHostingPackage, HostingPackageTemplate
-
 from osusers.models import SshPublicKey
 from osusers.views import AddSshPublicKey, DeleteSshPublicKey, EditSshPublicKeyComment
 
-
 User = get_user_model()
 
 TEST_USER = "test"
@@ -31,7 +29,6 @@ EXAMPLE_KEY = "".join(
 
 
 class HostingPackageAwareTestMixin(object):
-
     # noinspection PyMethodMayBeStatic
     def _setup_hosting_package(self, customer):
         template = HostingPackageTemplate.objects.create(
@@ -169,7 +166,7 @@ class DeleteSshPublicKeyTest(HostingPackageAwareTestMixin, TestCase):
             kwargs={"package": str(self.package.pk), "pk": str(self.sshkey.pk)},
         )
         queryset = view.get_queryset()
-        self.assertQuerysetEqual(queryset, [repr(self.sshkey)])
+        self.assertQuerysetEqual(queryset, [repr(self.sshkey)], transform=repr)
 
     def test_get_context_data(self):
         self.client.login(username=TEST_USER, password=TEST_PASSWORD)
@@ -237,7 +234,7 @@ class EditSshPublicKeyCommentTest(HostingPackageAwareTestMixin, TransactionTestC
             kwargs={"package": str(self.package.pk), "pk": str(self.sshkey.pk)},
         )
         queryset = view.get_queryset()
-        self.assertQuerysetEqual(queryset, [repr(self.sshkey)])
+        self.assertQuerysetEqual(queryset, [repr(self.sshkey)], transform=repr)
 
     def test_get_form_kwargs(self):
         self.client.login(username=TEST_USER, password=TEST_PASSWORD)
diff --git a/gnuviechadmin/osusers/urls.py b/gnuviechadmin/osusers/urls.py
index 086a2bf..bf7f80a 100644
--- a/gnuviechadmin/osusers/urls.py
+++ b/gnuviechadmin/osusers/urls.py
@@ -2,9 +2,9 @@
 This module defines the URL patterns for operating system user related views.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
-from django.conf.urls import url
+from django.urls import re_path
 
 from .views import (
     AddSshPublicKey,
@@ -14,16 +14,30 @@ from .views import (
     SetOsUserPassword,
 )
 
-
 urlpatterns = [
-    url(r'^(?P[\w0-9@.+-_]+)/setpassword$', SetOsUserPassword.as_view(),
-        name='set_osuser_password'),
-    url(r'^(?P\d+)/ssh-keys/$', ListSshPublicKeys.as_view(),
-        name='list_ssh_keys'),
-    url(r'^(?P\d+)/ssh-keys/add$', AddSshPublicKey.as_view(),
-        name='add_ssh_key'),
-    url(r'^(?P\d+)/ssh-keys/(?P\d+)/edit-comment$',
-        EditSshPublicKeyComment.as_view(), name='edit_ssh_key_comment'),
-    url(r'^(?P\d+)/ssh-keys/(?P\d+)/delete$',
-        DeleteSshPublicKey.as_view(), name='delete_ssh_key'),
+    re_path(
+        r"^(?P[\w0-9@.+-_]+)/setpassword$",
+        SetOsUserPassword.as_view(),
+        name="set_osuser_password",
+    ),
+    re_path(
+        r"^(?P\d+)/ssh-keys/$",
+        ListSshPublicKeys.as_view(),
+        name="list_ssh_keys",
+    ),
+    re_path(
+        r"^(?P\d+)/ssh-keys/add$",
+        AddSshPublicKey.as_view(),
+        name="add_ssh_key",
+    ),
+    re_path(
+        r"^(?P\d+)/ssh-keys/(?P\d+)/edit-comment$",
+        EditSshPublicKeyComment.as_view(),
+        name="edit_ssh_key_comment",
+    ),
+    re_path(
+        r"^(?P\d+)/ssh-keys/(?P\d+)/delete$",
+        DeleteSshPublicKey.as_view(),
+        name="delete_ssh_key",
+    ),
 ]
diff --git a/gnuviechadmin/osusers/views.py b/gnuviechadmin/osusers/views.py
index 3a0a938..e04be72 100644
--- a/gnuviechadmin/osusers/views.py
+++ b/gnuviechadmin/osusers/views.py
@@ -2,20 +2,15 @@
 This module defines the views for gnuviechadmin operating system user handling.
 
 """
-from __future__ import unicode_literals, absolute_import
+from __future__ import absolute_import
 
+from django.contrib import messages
 from django.shortcuts import redirect
 from django.urls import reverse
-from django.views.generic import (
-    CreateView,
-    DeleteView,
-    ListView,
-    UpdateView,
-)
-from django.utils.translation import ugettext as _
-from django.contrib import messages
-
+from django.utils.translation import gettext as _
+from django.views.generic import CreateView, DeleteView, ListView, UpdateView
 from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin
+
 from gvawebcore.views import HostingPackageAndCustomerMixin
 
 from .forms import (
@@ -23,10 +18,7 @@ from .forms import (
     ChangeOsUserPasswordForm,
     EditSshPublicKeyCommentForm,
 )
-from .models import (
-    SshPublicKey,
-    User,
-)
+from .models import SshPublicKey, User
 
 
 class SetOsUserPassword(StaffOrSelfLoginRequiredMixin, UpdateView):
@@ -34,19 +26,19 @@ class SetOsUserPassword(StaffOrSelfLoginRequiredMixin, UpdateView):
     This view is used for setting a new operating system user password.
 
     """
+
     model = User
-    slug_field = 'username'
-    template_name_suffix = '_setpassword'
-    context_object_name = 'osuser'
+    slug_field = "username"
+    template_name_suffix = "_setpassword"
+    context_object_name = "osuser"
     form_class = ChangeOsUserPasswordForm
 
     def get_customer_object(self):
         return self.get_object().customer
 
     def get_context_data(self, *args, **kwargs):
-        context = super(SetOsUserPassword, self).get_context_data(
-            *args, **kwargs)
-        context['customer'] = self.get_customer_object()
+        context = super(SetOsUserPassword, self).get_context_data(*args, **kwargs)
+        context["customer"] = self.get_customer_object()
         return context
 
     def form_valid(self, form):
@@ -55,7 +47,8 @@ class SetOsUserPassword(StaffOrSelfLoginRequiredMixin, UpdateView):
             self.request,
             _("New password for {username} has been set successfully.").format(
                 username=osuser.username
-            ))
+            ),
+        )
         return redirect(osuser.customerhostingpackage)
 
 
@@ -67,30 +60,34 @@ class AddSshPublicKey(
     operating system user.
 
     """
+
     model = SshPublicKey
-    context_object_name = 'key'
-    template_name_suffix = '_create'
+    context_object_name = "key"
+    template_name_suffix = "_create"
     form_class = AddSshPublicKeyForm
 
     def get_form_kwargs(self):
         kwargs = super(AddSshPublicKey, self).get_form_kwargs()
-        kwargs['hostingpackage'] = self.get_hosting_package()
+        kwargs["hostingpackage"] = self.get_hosting_package()
         return kwargs
 
     def get_context_data(self, **kwargs):
         context = super(AddSshPublicKey, self).get_context_data(**kwargs)
-        context.update({
-            'customer': self.get_customer_object(),
-            'osuser': self.get_hosting_package().osuser.username,
-        })
+        context.update(
+            {
+                "customer": self.get_customer_object(),
+                "osuser": self.get_hosting_package().osuser.username,
+            }
+        )
         return context
 
     def form_valid(self, form):
         key = form.save()
         messages.success(
             self.request,
-            _('Successfully added new {algorithm} SSH public key.').format(
-                algorithm=key.algorithm)
+            _("Successfully added new {algorithm} SSH public key.").format(
+                algorithm=key.algorithm
+            ),
         )
         return redirect(self.get_hosting_package())
 
@@ -104,20 +101,22 @@ class ListSshPublicKeys(
     via URL parameter 'pattern'.
 
     """
+
     model = SshPublicKey
-    context_object_name = 'keys'
+    context_object_name = "keys"
 
     def get_queryset(self):
-        return SshPublicKey.objects.filter(
-            user=self.get_hosting_package().osuser)
+        return SshPublicKey.objects.filter(user=self.get_hosting_package().osuser)
 
     def get_context_data(self, **kwargs):
         context = super(ListSshPublicKeys, self).get_context_data(**kwargs)
-        context.update({
-            'hostingpackage': self.get_hosting_package(),
-            'customer': self.get_customer_object(),
-            'osuser': self.get_hosting_package().osuser.username,
-        })
+        context.update(
+            {
+                "hostingpackage": self.get_hosting_package(),
+                "customer": self.get_customer_object(),
+                "osuser": self.get_hosting_package().osuser.username,
+            }
+        )
         return context
 
 
@@ -131,24 +130,29 @@ class DeleteSshPublicKey(
     """
 
     model = SshPublicKey
-    context_object_name = 'key'
+    context_object_name = "key"
 
     def get_queryset(self):
-        return super(DeleteSshPublicKey, self).get_queryset().filter(
-            user=self.get_hosting_package().osuser)
+        return (
+            super(DeleteSshPublicKey, self)
+            .get_queryset()
+            .filter(user=self.get_hosting_package().osuser)
+        )
 
     def get_context_data(self, **kwargs):
         context = super(DeleteSshPublicKey, self).get_context_data(**kwargs)
-        context.update({
-            'hostingpackage': self.get_hosting_package(),
-            'customer': self.get_customer_object(),
-            'osuser': self.get_hosting_package().osuser.username,
-        })
+        context.update(
+            {
+                "hostingpackage": self.get_hosting_package(),
+                "customer": self.get_customer_object(),
+                "osuser": self.get_hosting_package().osuser.username,
+            }
+        )
         return context
 
     def get_success_url(self):
         return reverse(
-            'list_ssh_keys', kwargs={'package': self.get_hosting_package().id}
+            "list_ssh_keys", kwargs={"package": self.get_hosting_package().id}
         )
 
 
@@ -160,31 +164,36 @@ class EditSshPublicKeyComment(
     key `.
 
     """
+
     model = SshPublicKey
-    context_object_name = 'key'
-    template_name_suffix = '_edit_comment'
+    context_object_name = "key"
+    template_name_suffix = "_edit_comment"
     form_class = EditSshPublicKeyCommentForm
 
     def get_queryset(self):
-        return super(EditSshPublicKeyComment, self).get_queryset().filter(
-            user=self.get_hosting_package().osuser)
+        return (
+            super(EditSshPublicKeyComment, self)
+            .get_queryset()
+            .filter(user=self.get_hosting_package().osuser)
+        )
 
     def get_form_kwargs(self):
         kwargs = super(EditSshPublicKeyComment, self).get_form_kwargs()
-        kwargs['hostingpackage'] = self.get_hosting_package()
+        kwargs["hostingpackage"] = self.get_hosting_package()
         return kwargs
 
     def get_context_data(self, **kwargs):
-        context = super(EditSshPublicKeyComment, self).get_context_data(
-            **kwargs)
-        context.update({
-            'hostingpackage': self.get_hosting_package(),
-            'customer': self.get_customer_object(),
-            'osuser': self.get_hosting_package().osuser.username,
-        })
+        context = super(EditSshPublicKeyComment, self).get_context_data(**kwargs)
+        context.update(
+            {
+                "hostingpackage": self.get_hosting_package(),
+                "customer": self.get_customer_object(),
+                "osuser": self.get_hosting_package().osuser.username,
+            }
+        )
         return context
 
     def get_success_url(self):
         return reverse(
-            'list_ssh_keys', kwargs={'package': self.get_hosting_package().id}
+            "list_ssh_keys", kwargs={"package": self.get_hosting_package().id}
         )
diff --git a/gnuviechadmin/taskresults/management/commands/fetch_taskresults.py b/gnuviechadmin/taskresults/management/commands/fetch_taskresults.py
index 8ccbd78..8f42a1e 100644
--- a/gnuviechadmin/taskresults/management/commands/fetch_taskresults.py
+++ b/gnuviechadmin/taskresults/management/commands/fetch_taskresults.py
@@ -4,8 +4,6 @@ results of all `Celery `
 
     """
-    actions = ['perform_delete_selected']
+
+    actions = ["perform_delete_selected"]
     add_form = DatabaseUserCreationForm
 
     def get_form(self, request, obj=None, **kwargs):
@@ -101,12 +102,13 @@ class DatabaseUserAdmin(admin.ModelAdmin):
         """
         defaults = {}
         if obj is None:
-            defaults.update({
-                'form': self.add_form,
-            })
+            defaults.update(
+                {
+                    "form": self.add_form,
+                }
+            )
         defaults.update(kwargs)
-        return super(DatabaseUserAdmin, self).get_form(
-            request, obj, **defaults)
+        return super(DatabaseUserAdmin, self).get_form(request, obj, **defaults)
 
     def get_readonly_fields(self, request, obj=None):
         """
@@ -122,7 +124,7 @@ class DatabaseUserAdmin(admin.ModelAdmin):
 
         """
         if obj:
-            return ['osuser', 'name', 'db_type']
+            return ["osuser", "name", "db_type"]
         return []
 
     def save_model(self, request, obj, form, change):
@@ -154,8 +156,8 @@ class DatabaseUserAdmin(admin.ModelAdmin):
         """
         for dbuser in queryset.all():
             dbuser.delete()
-    perform_delete_selected.short_description = _(
-        'Delete selected database users')
+
+    perform_delete_selected.short_description = _("Delete selected database users")
 
     def get_actions(self, request):
         """
@@ -170,8 +172,8 @@ class DatabaseUserAdmin(admin.ModelAdmin):
 
         """
         actions = super(DatabaseUserAdmin, self).get_actions(request)
-        if 'delete_selected' in actions:  # pragma: no cover
-            del actions['delete_selected']
+        if "delete_selected" in actions:  # pragma: no cover
+            del actions["delete_selected"]
         return actions
 
 
@@ -181,7 +183,8 @@ class UserDatabaseAdmin(admin.ModelAdmin):
     `
 
     """
-    actions = ['perform_delete_selected']
+
+    actions = ["perform_delete_selected"]
     add_form = UserDatabaseCreationForm
 
     def get_form(self, request, obj=None, **kwargs):
@@ -199,12 +202,13 @@ class UserDatabaseAdmin(admin.ModelAdmin):
         """
         defaults = {}
         if obj is None:
-            defaults.update({
-                'form': self.add_form,
-            })
+            defaults.update(
+                {
+                    "form": self.add_form,
+                }
+            )
         defaults.update(kwargs)
-        return super(UserDatabaseAdmin, self).get_form(
-            request, obj, **defaults)
+        return super(UserDatabaseAdmin, self).get_form(request, obj, **defaults)
 
     def get_readonly_fields(self, request, obj=None):
         """
@@ -220,7 +224,7 @@ class UserDatabaseAdmin(admin.ModelAdmin):
 
         """
         if obj:
-            return ['db_name', 'db_user']
+            return ["db_name", "db_user"]
         return []
 
     def save_model(self, request, obj, form, change):
@@ -252,8 +256,8 @@ class UserDatabaseAdmin(admin.ModelAdmin):
         """
         for database in queryset.all():
             database.delete()
-    perform_delete_selected.short_description = _(
-        'Delete selected user databases')
+
+    perform_delete_selected.short_description = _("Delete selected user databases")
 
     def get_actions(self, request):
         """
@@ -268,8 +272,8 @@ class UserDatabaseAdmin(admin.ModelAdmin):
 
         """
         actions = super(UserDatabaseAdmin, self).get_actions(request)
-        if 'delete_selected' in actions:  # pragma: no cover
-            del actions['delete_selected']
+        if "delete_selected" in actions:  # pragma: no cover
+            del actions["delete_selected"]
         return actions
 
 
diff --git a/gnuviechadmin/userdbs/apps.py b/gnuviechadmin/userdbs/apps.py
index 304f4d2..b48ab66 100644
--- a/gnuviechadmin/userdbs/apps.py
+++ b/gnuviechadmin/userdbs/apps.py
@@ -3,10 +3,8 @@ This module contains the :py:class:`django.apps.AppConfig` instance for the
 :py:mod:`userdbs` app.
 
 """
-from __future__ import unicode_literals
-
 from django.apps import AppConfig
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 
 
 class UserdbsAppConfig(AppConfig):
@@ -14,8 +12,9 @@ class UserdbsAppConfig(AppConfig):
     AppConfig for the :py:mod:`userdbs` app.
 
     """
-    name = 'userdbs'
-    verbose_name = _('Database Users and their Databases')
+
+    name = "userdbs"
+    verbose_name = _("Database Users and their Databases")
 
     def ready(self):
         """
diff --git a/gnuviechadmin/userdbs/forms.py b/gnuviechadmin/userdbs/forms.py
index bf9a099..5c2d983 100644
--- a/gnuviechadmin/userdbs/forms.py
+++ b/gnuviechadmin/userdbs/forms.py
@@ -2,32 +2,27 @@
 This module defines form classes for user database editing.
 
 """
-from __future__ import absolute_import, unicode_literals
-
-from django import forms
-from django.urls import reverse
-from django.utils.translation import ugettext_lazy as _
+from __future__ import absolute_import
 
 from crispy_forms.helper import FormHelper
-from crispy_forms.layout import (
-    Submit,
-)
+from crispy_forms.layout import Submit
+from django import forms
+from django.urls import reverse
+from django.utils.translation import gettext_lazy as _
 
-from .models import (
-    DB_TYPES,
-    DatabaseUser,
-    UserDatabase,
-)
 from gvawebcore.forms import PasswordModelFormMixin
 
+from .models import DB_TYPES, DatabaseUser, UserDatabase
+
 
 class AddUserDatabaseForm(forms.ModelForm, PasswordModelFormMixin):
     """
     This form is used to create new user database instances.
 
     """
+
     db_type = forms.TypedChoiceField(
-        label=_('Database type'),
+        label=_("Database type"),
         choices=DB_TYPES,
         widget=forms.RadioSelect,
         coerce=int,
@@ -38,17 +33,18 @@ class AddUserDatabaseForm(forms.ModelForm, PasswordModelFormMixin):
         fields = []
 
     def __init__(self, *args, **kwargs):
-        self.hosting_package = kwargs.pop('hostingpackage')
-        self.available_dbtypes = kwargs.pop('dbtypes')
+        self.hosting_package = kwargs.pop("hostingpackage")
+        self.available_dbtypes = kwargs.pop("dbtypes")
         super(AddUserDatabaseForm, self).__init__(*args, **kwargs)
-        self.fields['db_type'].choices = self.available_dbtypes
+        self.fields["db_type"].choices = self.available_dbtypes
         if len(self.available_dbtypes) == 1:
-            self.fields['db_type'].initial = self.available_dbtypes[0][0]
-            self.fields['db_type'].widget = forms.HiddenInput()
+            self.fields["db_type"].initial = self.available_dbtypes[0][0]
+            self.fields["db_type"].widget = forms.HiddenInput()
         self.helper = FormHelper()
         self.helper.form_action = reverse(
-            'add_userdatabase', kwargs={'package': self.hosting_package.id})
-        self.helper.add_input(Submit('submit', _('Create database')))
+            "add_userdatabase", kwargs={"package": self.hosting_package.id}
+        )
+        self.helper.add_input(Submit("submit", _("Create database")))
 
     def save(self, commit=True):
         """
@@ -62,8 +58,11 @@ class AddUserDatabaseForm(forms.ModelForm, PasswordModelFormMixin):
         """
         data = self.cleaned_data
         self.instance = UserDatabase.objects.create_userdatabase_with_user(
-            data['db_type'], self.hosting_package.osuser,
-            password=data['password1'], commit=commit)
+            data["db_type"],
+            self.hosting_package.osuser,
+            password=data["password1"],
+            commit=commit,
+        )
         return super(AddUserDatabaseForm, self).save(commit)
 
 
@@ -72,21 +71,24 @@ class ChangeDatabaseUserPasswordForm(forms.ModelForm, PasswordModelFormMixin):
     This form is used to change the password of a database user.
 
     """
+
     class Meta:
         model = DatabaseUser
         fields = []
 
     def __init__(self, *args, **kwargs):
-        self.hosting_package = kwargs.pop('hostingpackage')
+        self.hosting_package = kwargs.pop("hostingpackage")
         super(ChangeDatabaseUserPasswordForm, self).__init__(*args, **kwargs)
         self.helper = FormHelper()
         self.helper.form_action = reverse(
-            'change_dbuser_password', kwargs={
-                'slug': self.instance.name,
-                'package': self.hosting_package.id,
-            })
-        self.helper.add_input(Submit('submit', _('Set password')))
+            "change_dbuser_password",
+            kwargs={
+                "slug": self.instance.name,
+                "package": self.hosting_package.id,
+            },
+        )
+        self.helper.add_input(Submit("submit", _("Set password")))
 
     def save(self, commit=True):
-        self.instance.set_password(self.cleaned_data['password1'])
+        self.instance.set_password(self.cleaned_data["password1"])
         return super(ChangeDatabaseUserPasswordForm, self).save()
diff --git a/gnuviechadmin/userdbs/migrations/0001_initial.py b/gnuviechadmin/userdbs/migrations/0001_initial.py
index 54015a3..6a3402e 100644
--- a/gnuviechadmin/userdbs/migrations/0001_initial.py
+++ b/gnuviechadmin/userdbs/migrations/0001_initial.py
@@ -1,6 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 import django.utils.timezone
 import model_utils.fields
 from django.db import migrations, models
@@ -8,66 +6,110 @@ from django.db import migrations, models
 
 class Migration(migrations.Migration):
     dependencies = [
-        ('osusers', '0004_auto_20150104_1751'),
+        ("osusers", "0004_auto_20150104_1751"),
     ]
 
     operations = [
         migrations.CreateModel(
-            name='DatabaseUser',
+            name="DatabaseUser",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('name', models.CharField(
-                    max_length=63, verbose_name='username')),
-                ('db_type', models.PositiveSmallIntegerField(
-                    verbose_name='database type',
-                    choices=[(0, 'PostgreSQL'), (1, 'MySQL')])),
-                ('osuser', models.ForeignKey(
-                    to='osusers.User', on_delete=models.CASCADE)),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                ("name", models.CharField(max_length=63, verbose_name="username")),
+                (
+                    "db_type",
+                    models.PositiveSmallIntegerField(
+                        verbose_name="database type",
+                        choices=[(0, "PostgreSQL"), (1, "MySQL")],
+                    ),
+                ),
+                (
+                    "osuser",
+                    models.ForeignKey(to="osusers.User", on_delete=models.CASCADE),
+                ),
             ],
             options={
-                'verbose_name': 'database user',
-                'verbose_name_plural': 'database users',
+                "verbose_name": "database user",
+                "verbose_name_plural": "database users",
             },
             bases=(models.Model,),
         ),
         migrations.CreateModel(
-            name='UserDatabase',
+            name="UserDatabase",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('created', model_utils.fields.AutoCreatedField(
-                    default=django.utils.timezone.now, verbose_name='created',
-                    editable=False)),
-                ('modified', model_utils.fields.AutoLastModifiedField(
-                    default=django.utils.timezone.now, verbose_name='modified',
-                    editable=False)),
-                ('db_name', models.CharField(
-                    max_length=63, verbose_name='database name')),
-                ('db_user', models.ForeignKey(
-                    verbose_name='database user', to='userdbs.DatabaseUser',
-                    on_delete=models.CASCADE)),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "created",
+                    model_utils.fields.AutoCreatedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="created",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "modified",
+                    model_utils.fields.AutoLastModifiedField(
+                        default=django.utils.timezone.now,
+                        verbose_name="modified",
+                        editable=False,
+                    ),
+                ),
+                (
+                    "db_name",
+                    models.CharField(max_length=63, verbose_name="database name"),
+                ),
+                (
+                    "db_user",
+                    models.ForeignKey(
+                        verbose_name="database user",
+                        to="userdbs.DatabaseUser",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
             ],
             options={
-                'verbose_name': 'user database',
-                'verbose_name_plural': 'user specific database',
+                "verbose_name": "user database",
+                "verbose_name_plural": "user specific database",
             },
             bases=(models.Model,),
         ),
         migrations.AlterUniqueTogether(
-            name='userdatabase',
-            unique_together={('db_name', 'db_user')},
+            name="userdatabase",
+            unique_together={("db_name", "db_user")},
         ),
         migrations.AlterUniqueTogether(
-            name='databaseuser',
-            unique_together={('name', 'db_type')},
+            name="databaseuser",
+            unique_together={("name", "db_type")},
         ),
     ]
diff --git a/gnuviechadmin/userdbs/models.py b/gnuviechadmin/userdbs/models.py
index c9eafb5..879cc3c 100644
--- a/gnuviechadmin/userdbs/models.py
+++ b/gnuviechadmin/userdbs/models.py
@@ -1,24 +1,21 @@
-from __future__ import unicode_literals
-
 from django.db import models, transaction
 from django.dispatch import Signal
-from django.utils.encoding import python_2_unicode_compatible
-from django.utils.translation import ugettext as _
+from django.utils.translation import gettext as _
 from model_utils import Choices
 from model_utils.models import TimeStampedModel
 
 from osusers.models import User as OsUser
 
 DB_TYPES = Choices(
-    (0, 'pgsql', _('PostgreSQL')),
-    (1, 'mysql', _('MySQL')),
+    (0, "pgsql", _("PostgreSQL")),
+    (1, "mysql", _("MySQL")),
 )
 """
 Database type choice enumeration.
 """
 
 
-password_set = Signal(providing_args=['instance', 'password'])
+password_set = Signal()
 
 
 class DatabaseUserManager(models.Manager):
@@ -40,10 +37,10 @@ class DatabaseUserManager(models.Manager):
         dbuser_name_format = "{0}db{{0:02d}}".format(osuser.username)
         nextname = dbuser_name_format.format(count)
 
-        for user in self.values('name').filter(
-            osuser=osuser, db_type=db_type
-        ).order_by('name'):
-            if user['name'] == nextname:
+        for user in (
+            self.values("name").filter(osuser=osuser, db_type=db_type).order_by("name")
+        ):
+            if user["name"] == nextname:
                 count += 1
                 nextname = dbuser_name_format.format(count)
             else:
@@ -74,33 +71,29 @@ class DatabaseUserManager(models.Manager):
         """
         if username is None:
             username = self._get_next_dbuser_name(osuser, db_type)
-        db_user = DatabaseUser(
-            osuser=osuser, db_type=db_type, name=username)
+        db_user = DatabaseUser(osuser=osuser, db_type=db_type, name=username)
         if commit:
             db_user.save()
         return db_user
 
 
-@python_2_unicode_compatible
 class DatabaseUser(TimeStampedModel, models.Model):
     osuser = models.ForeignKey(OsUser, on_delete=models.CASCADE)
-    name = models.CharField(
-        _('username'), max_length=63)
-    db_type = models.PositiveSmallIntegerField(
-        _('database type'), choices=DB_TYPES)
+    name = models.CharField(_("username"), max_length=63)
+    db_type = models.PositiveSmallIntegerField(_("database type"), choices=DB_TYPES)
 
     objects = DatabaseUserManager()
 
     class Meta:
-        unique_together = ['name', 'db_type']
-        verbose_name = _('database user')
-        verbose_name_plural = _('database users')
+        unique_together = ["name", "db_type"]
+        verbose_name = _("database user")
+        verbose_name_plural = _("database users")
 
     def __str__(self):
         return "%(name)s (%(db_type)s for %(osuser)s)" % {
-            'name': self.name,
-            'db_type': self.get_db_type_display(),
-            'osuser': self.osuser.username,
+            "name": self.name,
+            "db_type": self.get_db_type_display(),
+            "osuser": self.osuser.username,
         }
 
     @transaction.atomic
@@ -110,8 +103,7 @@ class DatabaseUser(TimeStampedModel, models.Model):
 
         :param str password: new password for the database user
         """
-        password_set.send(
-            sender=self.__class__, password=password, instance=self)
+        password_set.send(sender=self.__class__, password=password, instance=self)
 
     @transaction.atomic
     def delete(self, *args, **kwargs):
@@ -149,10 +141,8 @@ class UserDatabaseManager(models.Manager):
         db_name_format = "{0}_{{0:02d}}".format(db_user.name)
         # first db is named the same as the user
         nextname = db_user.name
-        for name in self.values('db_name').filter(db_user=db_user).order_by(
-            'db_name'
-        ):
-            if name['db_name'] == nextname:
+        for name in self.values("db_name").filter(db_user=db_user).order_by("db_name"):
+            if name["db_name"] == nextname:
                 count += 1
                 nextname = db_name_format.format(count)
             else:
@@ -161,7 +151,8 @@ class UserDatabaseManager(models.Manager):
 
     @transaction.atomic
     def create_userdatabase_with_user(
-            self, db_type, osuser, password=None, commit=True):
+        self, db_type, osuser, password=None, commit=True
+    ):
         """
         Creates a new user database with a new user.
 
@@ -175,7 +166,8 @@ class UserDatabaseManager(models.Manager):
 
         """
         dbuser = DatabaseUser.objects.create_database_user(
-            osuser, db_type, password=password, commit=commit)
+            osuser, db_type, password=password, commit=commit
+        )
         database = self.create_userdatabase(dbuser, commit=commit)
         return database
 
@@ -198,24 +190,22 @@ class UserDatabaseManager(models.Manager):
         return database
 
 
-@python_2_unicode_compatible
 class UserDatabase(TimeStampedModel, models.Model):
     # MySQL limits to 64, PostgreSQL to 63 characters
-    db_name = models.CharField(
-        _('database name'), max_length=63)
+    db_name = models.CharField(_("database name"), max_length=63)
     db_user = models.ForeignKey(
-        DatabaseUser, verbose_name=_('database user'),
-        on_delete=models.CASCADE)
+        DatabaseUser, verbose_name=_("database user"), on_delete=models.CASCADE
+    )
 
     objects = UserDatabaseManager()
 
     class Meta:
-        unique_together = ['db_name', 'db_user']
-        verbose_name = _('user database')
-        verbose_name_plural = _('user specific database')
+        unique_together = ["db_name", "db_user"]
+        verbose_name = _("user database")
+        verbose_name_plural = _("user specific database")
 
     def __str__(self):
         return "%(db_name)s (%(db_user)s)" % {
-            'db_name': self.db_name,
-            'db_user': self.db_user,
+            "db_name": self.db_name,
+            "db_user": self.db_user,
         }
diff --git a/gnuviechadmin/userdbs/signals.py b/gnuviechadmin/userdbs/signals.py
index 4a5bc32..d9c70b0 100644
--- a/gnuviechadmin/userdbs/signals.py
+++ b/gnuviechadmin/userdbs/signals.py
@@ -6,20 +6,26 @@ The module starts Celery_ tasks.
 .. _Celery: http://www.celeryproject.org/
 
 """
-from __future__ import unicode_literals
-
 import logging
 
 from django.db.models.signals import post_delete, post_save
 from django.dispatch import receiver
-from passlib.utils import generate_password
+from passlib.pwd import genword
 
-from mysqltasks.tasks import (create_mysql_database, create_mysql_user,
-                              delete_mysql_database, delete_mysql_user,
-                              set_mysql_userpassword)
-from pgsqltasks.tasks import (create_pgsql_database, create_pgsql_user,
-                              delete_pgsql_database, delete_pgsql_user,
-                              set_pgsql_userpassword)
+from mysqltasks.tasks import (
+    create_mysql_database,
+    create_mysql_user,
+    delete_mysql_database,
+    delete_mysql_user,
+    set_mysql_userpassword,
+)
+from pgsqltasks.tasks import (
+    create_pgsql_database,
+    create_pgsql_user,
+    delete_pgsql_database,
+    delete_pgsql_user,
+    set_pgsql_userpassword,
+)
 from taskresults.models import TaskResult
 
 from .models import DB_TYPES, DatabaseUser, UserDatabase, password_set
@@ -64,25 +70,29 @@ def handle_dbuser_password_set(sender, instance, password, **kwargs):
     """
     if instance.db_type == DB_TYPES.mysql:
         taskresult = TaskResult.objects.create_task_result(
-            'handle_dbuser_password_set',
+            "handle_dbuser_password_set",
             set_mysql_userpassword.s(instance.name, password),
-            'mysql password change')
+            "mysql password change",
+        )
         _LOGGER.info(
-            'MySQL password change has been requested in task %s',
-            taskresult.task_id)
+            "MySQL password change has been requested in task %s", taskresult.task_id
+        )
     elif instance.db_type == DB_TYPES.pgsql:
         taskresult = TaskResult.objects.create_task_result(
-            'handle_dbuser_password_set',
+            "handle_dbuser_password_set",
             set_pgsql_userpassword.s(instance.name, password),
-            'pgsql password change')
+            "pgsql password change",
+        )
         _LOGGER.info(
-            'PostgreSQL password change has been requested in task %s',
-            taskresult.task_id)
+            "PostgreSQL password change has been requested in task %s",
+            taskresult.task_id,
+        )
     else:
         _LOGGER.warning(
-            'Password change has been requested for unknown database %s'
-            ' the request has been ignored.',
-            instance.db_type)
+            "Password change has been requested for unknown database %s"
+            " the request has been ignored.",
+            instance.db_type,
+        )
 
 
 @receiver(post_save, sender=DatabaseUser)
@@ -122,32 +132,37 @@ def handle_dbuser_created(sender, instance, created, **kwargs):
 
     """
     if created:
-        password = kwargs.get('password', generate_password())
+        password = kwargs.get("password", genword())
         # TODO: send GPG encrypted mail with this information
         if instance.db_type == DB_TYPES.mysql:
             taskresult = TaskResult.objects.create_task_result(
-                'handle_dbuser_created',
+                "handle_dbuser_created",
                 create_mysql_user.s(instance.name, password),
-                'mysql user creation')
+                "mysql user creation",
+            )
             _LOGGER.info(
-                'A new MySQL user %s creation has been requested in task %s',
-                instance.name, taskresult.task_id)
+                "A new MySQL user %s creation has been requested in task %s",
+                instance.name,
+                taskresult.task_id,
+            )
         elif instance.db_type == DB_TYPES.pgsql:
             taskresult = TaskResult.objects.create_task_result(
-                'handle_dbuser_created',
+                "handle_dbuser_created",
                 create_pgsql_user.s(instance.name, password),
-                'pgsql user creation')
+                "pgsql user creation",
+            )
             _LOGGER.info(
-                'A new PostgreSQL user %s creation has been requested in task'
-                ' %s',
-                instance.name, taskresult.task_id)
+                "A new PostgreSQL user %s creation has been requested in task" " %s",
+                instance.name,
+                taskresult.task_id,
+            )
         else:
             _LOGGER.warning(
-                'created DatabaseUser for unknown database type %s',
-                instance.db_type)
+                "created DatabaseUser for unknown database type %s", instance.db_type
+            )
     _LOGGER.debug(
-        'database user %s has been %s',
-        instance, created and "created" or "updated")
+        "database user %s has been %s", instance, created and "created" or "updated"
+    )
 
 
 @receiver(post_delete, sender=DatabaseUser)
@@ -185,26 +200,33 @@ def handle_dbuser_deleted(sender, instance, **kwargs):
     """
     if instance.db_type == DB_TYPES.mysql:
         taskresult = TaskResult.objects.create_task_result(
-            'handle_dbuser_deleted',
+            "handle_dbuser_deleted",
             delete_mysql_user.s(instance.name),
-            'mysql user deletion')
+            "mysql user deletion",
+        )
         _LOGGER.info(
-            'MySQL user %s deletion has been requested in task %s',
-            instance.name, taskresult.task_id)
+            "MySQL user %s deletion has been requested in task %s",
+            instance.name,
+            taskresult.task_id,
+        )
     elif instance.db_type == DB_TYPES.pgsql:
         taskresult = TaskResult.objects.create_task_result(
-            'handle_dbuser_deleted',
+            "handle_dbuser_deleted",
             delete_pgsql_user.s(instance.name),
-            'pgsql user deletion')
+            "pgsql user deletion",
+        )
         _LOGGER.info(
-            'PostgreSQL user %s deletion has been requested in task %s',
-            instance.name, taskresult.task_id)
+            "PostgreSQL user %s deletion has been requested in task %s",
+            instance.name,
+            taskresult.task_id,
+        )
     else:
         _LOGGER.warning(
-            'deleted DatabaseUser %s for unknown database type %s',
-            instance.name, instance.db_type)
-    _LOGGER.debug(
-        'database user %s has been deleted', instance)
+            "deleted DatabaseUser %s for unknown database type %s",
+            instance.name,
+            instance.db_type,
+        )
+    _LOGGER.debug("database user %s has been deleted", instance)
 
 
 @receiver(post_save, sender=UserDatabase)
@@ -245,31 +267,36 @@ def handle_userdb_created(sender, instance, created, **kwargs):
     if created:
         if instance.db_user.db_type == DB_TYPES.mysql:
             taskresult = TaskResult.objects.create_task_result(
-                'handle_userdb_created',
-                create_mysql_database.s(
-                    instance.db_name, instance.db_user.name),
-                'mysql database creation')
+                "handle_userdb_created",
+                create_mysql_database.s(instance.db_name, instance.db_user.name),
+                "mysql database creation",
+            )
             _LOGGER.info(
-                'The creation of a new MySQL database %s has been requested in'
-                ' task %s',
-                instance.db_name, taskresult.task_id)
+                "The creation of a new MySQL database %s has been requested in"
+                " task %s",
+                instance.db_name,
+                taskresult.task_id,
+            )
         elif instance.db_user.db_type == DB_TYPES.pgsql:
             taskresult = TaskResult.objects.create_task_result(
-                'handle_userdb_created',
-                create_pgsql_database.s(
-                    instance.db_name, instance.db_user.name),
-                'pgsql database creation')
+                "handle_userdb_created",
+                create_pgsql_database.s(instance.db_name, instance.db_user.name),
+                "pgsql database creation",
+            )
             _LOGGER.info(
-                'The creation of a new PostgreSQL database %s has been'
-                ' requested in task %s',
-                instance.db_name, taskresult.task_id)
+                "The creation of a new PostgreSQL database %s has been"
+                " requested in task %s",
+                instance.db_name,
+                taskresult.task_id,
+            )
         else:
             _LOGGER.warning(
-                'created UserDatabase for unknown database type %s',
-                instance.db_user.db_type)
+                "created UserDatabase for unknown database type %s",
+                instance.db_user.db_type,
+            )
     _LOGGER.debug(
-        'database %s has been %s',
-        instance, created and "created" or "updated")
+        "database %s has been %s", instance, created and "created" or "updated"
+    )
 
 
 @receiver(post_delete, sender=UserDatabase)
@@ -307,25 +334,31 @@ def handle_userdb_deleted(sender, instance, **kwargs):
     """
     if instance.db_user.db_type == DB_TYPES.mysql:
         taskresult = TaskResult.objects.create_task_result(
-            'handle_userdb_deleted',
+            "handle_userdb_deleted",
             delete_mysql_database.s(instance.db_name, instance.db_user.name),
-            'mysql database deletion')
+            "mysql database deletion",
+        )
         _LOGGER.info(
-            'The deletion of MySQL database %s has been requested in task %s',
-            instance.db_name, taskresult.task_id)
+            "The deletion of MySQL database %s has been requested in task %s",
+            instance.db_name,
+            taskresult.task_id,
+        )
     elif instance.db_user.db_type == DB_TYPES.pgsql:
         taskresult = TaskResult.objects.create_task_result(
-            'handle_userdb_deleted',
+            "handle_userdb_deleted",
             delete_pgsql_database.s(instance.db_name),
-            'pgsql database deletion')
+            "pgsql database deletion",
+        )
         _LOGGER.info(
-            'The deletion of PostgreSQL database %s has been requested in '
-            ' task %s',
-            instance.db_name, taskresult.task_id)
+            "The deletion of PostgreSQL database %s has been requested in " " task %s",
+            instance.db_name,
+            taskresult.task_id,
+        )
     else:
         _LOGGER.warning(
-            'deleted UserDatabase %s of unknown type %s',
-            instance.db_name, instance.db_type)
+            "deleted UserDatabase %s of unknown type %s",
+            instance.db_name,
+            instance.db_type,
+        )
         pass
-    _LOGGER.debug(
-        'database %s has been deleted', instance)
+    _LOGGER.debug("database %s has been deleted", instance)
diff --git a/gnuviechadmin/userdbs/tests/templatetags/test_userdb.py b/gnuviechadmin/userdbs/tests/templatetags/test_userdb.py
index 120f18c..ad0a161 100644
--- a/gnuviechadmin/userdbs/tests/templatetags/test_userdb.py
+++ b/gnuviechadmin/userdbs/tests/templatetags/test_userdb.py
@@ -3,8 +3,6 @@ This module provides tests for the functions in
 :py:mod:`userdbs.templatetags.userdb`.
 
 """
-from __future__ import unicode_literals
-
 from unittest import TestCase
 
 from django.utils.translation import gettext as _
@@ -20,26 +18,22 @@ class UserdbTemplateTagTests(TestCase):
     """
 
     def test_db_type_icon_class_unknown(self):
-        self.assertEqual(
-            db_type_icon_class({'db_type': 'unknown'}),
-            'icon-database')
+        self.assertEqual(db_type_icon_class({"db_type": "unknown"}), "icon-database")
 
     def test_db_type_icon_class_mysql(self):
-        self.assertEqual(
-            db_type_icon_class({'db_type': DB_TYPES.mysql}),
-            'icon-mysql')
+        self.assertEqual(db_type_icon_class({"db_type": DB_TYPES.mysql}), "icon-mysql")
 
     def test_db_type_icon_class_pgsql(self):
         self.assertEqual(
-            db_type_icon_class({'db_type': DB_TYPES.pgsql}),
-            'icon-postgres')
+            db_type_icon_class({"db_type": DB_TYPES.pgsql}), "icon-postgres"
+        )
 
     def test_db_type_name_mysql(self):
         self.assertEqual(
-            db_type_name({'db_type': DB_TYPES.mysql}),
-            _(DB_TYPES[DB_TYPES.mysql]))
+            db_type_name({"db_type": DB_TYPES.mysql}), _(DB_TYPES[DB_TYPES.mysql])
+        )
 
     def test_db_type_name_pgsql(self):
         self.assertEqual(
-            db_type_name({'db_type': DB_TYPES.pgsql}),
-            _(DB_TYPES[DB_TYPES.pgsql]))
+            db_type_name({"db_type": DB_TYPES.pgsql}), _(DB_TYPES[DB_TYPES.pgsql])
+        )
diff --git a/gnuviechadmin/userdbs/urls.py b/gnuviechadmin/userdbs/urls.py
index 6aee543..4447273 100644
--- a/gnuviechadmin/userdbs/urls.py
+++ b/gnuviechadmin/userdbs/urls.py
@@ -2,21 +2,24 @@
 This module defines the URL patterns for user database views.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
-from django.conf.urls import url
+from django.urls import re_path
 
-from .views import (
-    AddUserDatabase,
-    ChangeDatabaseUserPassword,
-    DeleteUserDatabase,
-)
+from .views import AddUserDatabase, ChangeDatabaseUserPassword, DeleteUserDatabase
 
 urlpatterns = [
-    url(r'^(?P\d+)/create$',
-        AddUserDatabase.as_view(), name='add_userdatabase'),
-    url(r'^(?P\d+)/(?P[\w0-9]+)/setpassword',
-        ChangeDatabaseUserPassword.as_view(), name='change_dbuser_password'),
-    url(r'^(?P\d+)/(?P[\w0-9]+)/delete',
-        DeleteUserDatabase.as_view(), name='delete_userdatabase'),
+    re_path(
+        r"^(?P\d+)/create$", AddUserDatabase.as_view(), name="add_userdatabase"
+    ),
+    re_path(
+        r"^(?P\d+)/(?P[\w0-9]+)/setpassword",
+        ChangeDatabaseUserPassword.as_view(),
+        name="change_dbuser_password",
+    ),
+    re_path(
+        r"^(?P\d+)/(?P[\w0-9]+)/delete",
+        DeleteUserDatabase.as_view(),
+        name="delete_userdatabase",
+    ),
 ]
diff --git a/gnuviechadmin/userdbs/views.py b/gnuviechadmin/userdbs/views.py
index d16eb5a..b5dbdd2 100644
--- a/gnuviechadmin/userdbs/views.py
+++ b/gnuviechadmin/userdbs/views.py
@@ -2,30 +2,19 @@
 This module defines views for user database handling.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
+from django.contrib import messages
 from django.core.exceptions import SuspiciousOperation
 from django.shortcuts import redirect
-from django.utils.translation import ugettext as _
-from django.views.generic.edit import (
-    CreateView,
-    DeleteView,
-    UpdateView,
-)
-from django.contrib import messages
-
+from django.utils.translation import gettext as _
+from django.views.generic.edit import CreateView, DeleteView, UpdateView
 from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin
+
 from gvawebcore.views import HostingPackageAndCustomerMixin
 
-from .forms import (
-    AddUserDatabaseForm,
-    ChangeDatabaseUserPasswordForm,
-)
-from .models import (
-    DB_TYPES,
-    DatabaseUser,
-    UserDatabase,
-)
+from .forms import AddUserDatabaseForm, ChangeDatabaseUserPasswordForm
+from .models import DB_TYPES, DatabaseUser, UserDatabase
 
 
 class AddUserDatabase(
@@ -35,9 +24,10 @@ class AddUserDatabase(
     This view is used to setup new user databases.
 
     """
+
     model = UserDatabase
-    context_object_name = 'database'
-    template_name_suffix = '_create'
+    context_object_name = "database"
+    template_name_suffix = "_create"
     form_class = AddUserDatabaseForm
 
     def _get_dbtypes(self, hostingpackage):
@@ -45,29 +35,33 @@ class AddUserDatabase(
         db_options = hostingpackage.get_databases()
         for opt in db_options:
             dbs_of_type = UserDatabase.objects.filter(
-                db_user__osuser=hostingpackage.osuser,
-                db_user__db_type=opt['db_type']).count()
-            if dbs_of_type < opt['number']:
-                retval.append((opt['db_type'], DB_TYPES[opt['db_type']]))
+                db_user__osuser=hostingpackage.osuser, db_user__db_type=opt["db_type"]
+            ).count()
+            if dbs_of_type < opt["number"]:
+                retval.append((opt["db_type"], DB_TYPES[opt["db_type"]]))
         if len(retval) < 1:
             raise SuspiciousOperation(
-                _("The hosting package has no database products assigned."))
+                _("The hosting package has no database products assigned.")
+            )
         return retval
 
     def get_form_kwargs(self):
         kwargs = super(AddUserDatabase, self).get_form_kwargs()
-        kwargs['hostingpackage'] = self.get_hosting_package()
-        kwargs['dbtypes'] = self._get_dbtypes(kwargs['hostingpackage'])
+        kwargs["hostingpackage"] = self.get_hosting_package()
+        kwargs["dbtypes"] = self._get_dbtypes(kwargs["hostingpackage"])
         return kwargs
 
     def form_valid(self, form):
         userdatabase = form.save()
         messages.success(
             self.request,
-            _('Successfully create new {type} database {dbname} for user '
-              '{dbuser}.').format(
-                  type=userdatabase.db_user.db_type,
-                  dbname=userdatabase.db_name, dbuser=userdatabase.db_user)
+            _(
+                "Successfully create new {type} database {dbname} for user " "{dbuser}."
+            ).format(
+                type=userdatabase.db_user.db_type,
+                dbname=userdatabase.db_name,
+                dbuser=userdatabase.db_user,
+            ),
         )
         return redirect(self.get_hosting_package())
 
@@ -79,30 +73,31 @@ class ChangeDatabaseUserPassword(
     This view is used to change a database user's password.
 
     """
+
     model = DatabaseUser
-    slug_field = 'name'
-    context_object_name = 'dbuser'
-    template_name_suffix = '_setpassword'
+    slug_field = "name"
+    context_object_name = "dbuser"
+    template_name_suffix = "_setpassword"
     form_class = ChangeDatabaseUserPasswordForm
 
     def get_form_kwargs(self):
         kwargs = super(ChangeDatabaseUserPassword, self).get_form_kwargs()
-        kwargs['hostingpackage'] = self.get_hosting_package()
+        kwargs["hostingpackage"] = self.get_hosting_package()
         return kwargs
 
     def get_context_data(self, **kwargs):
-        context = super(ChangeDatabaseUserPassword, self).get_context_data(
-            **kwargs)
-        context['hostingpackage'] = self.get_hosting_package()
-        context['customer'] = self.get_customer_object()
+        context = super(ChangeDatabaseUserPassword, self).get_context_data(**kwargs)
+        context["hostingpackage"] = self.get_hosting_package()
+        context["customer"] = self.get_customer_object()
         return context
 
     def form_valid(self, form):
         db_user = form.save()
         messages.success(
             self.request,
-            _('Successfully changed password of database user {dbuser}.'
-              ).format(dbuser=db_user.name)
+            _("Successfully changed password of database user {dbuser}.").format(
+                dbuser=db_user.name
+            ),
         )
         return redirect(self.get_hosting_package())
 
@@ -115,21 +110,24 @@ class DeleteUserDatabase(
     no more databases assigned.
 
     """
+
     model = UserDatabase
-    slug_field = 'db_name'
-    context_object_name = 'database'
+    slug_field = "db_name"
+    context_object_name = "database"
 
     def get_context_data(self, **kwargs):
         context = super(DeleteUserDatabase, self).get_context_data(**kwargs)
-        context.update({
-            'hostingpackage': self.get_hosting_package(),
-            'customer': self.get_customer_object(),
-        })
+        context.update(
+            {
+                "hostingpackage": self.get_hosting_package(),
+                "customer": self.get_customer_object(),
+            }
+        )
         return context
 
     def get_success_url(self):
         messages.success(
             self.request,
-            _('Database deleted.'),
+            _("Database deleted."),
         )
         return self.get_hosting_package().get_absolute_url()
diff --git a/gnuviechadmin/websites/__init__.py b/gnuviechadmin/websites/__init__.py
index 8e793c3..96f532f 100644
--- a/gnuviechadmin/websites/__init__.py
+++ b/gnuviechadmin/websites/__init__.py
@@ -2,4 +2,3 @@
 This app takes care of websites.
 
 """
-default_app_config = 'websites.apps.WebsitesAppConfig'
diff --git a/gnuviechadmin/websites/apps.py b/gnuviechadmin/websites/apps.py
index 363d7ad..a5fd48b 100644
--- a/gnuviechadmin/websites/apps.py
+++ b/gnuviechadmin/websites/apps.py
@@ -3,9 +3,8 @@ This module contains the :py:class:`django.apps.AppConfig` instance for the
 :py:mod:`websites` app.
 
 """
-from __future__ import unicode_literals
 from django.apps import AppConfig
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 
 
 class WebsitesAppConfig(AppConfig):
@@ -13,5 +12,6 @@ class WebsitesAppConfig(AppConfig):
     AppConfig for the :py:mod:`websites` app.
 
     """
-    name = 'websites'
-    verbose_name = _('Websites')
+
+    name = "websites"
+    verbose_name = _("Websites")
diff --git a/gnuviechadmin/websites/forms.py b/gnuviechadmin/websites/forms.py
index 94e52d1..8d253d7 100644
--- a/gnuviechadmin/websites/forms.py
+++ b/gnuviechadmin/websites/forms.py
@@ -2,20 +2,17 @@
 This module defines form classes for website editing.
 
 """
-from __future__ import absolute_import, unicode_literals
-
-from django import forms
-from django.urls import reverse
-from django.utils.translation import ugettext as _
+from __future__ import absolute_import
 
 from crispy_forms.bootstrap import AppendedText
 from crispy_forms.helper import FormHelper
-from crispy_forms.layout import (
-    Layout,
-    Submit,
-)
+from crispy_forms.layout import Layout, Submit
+from django import forms
+from django.urls import reverse
+from django.utils.translation import gettext as _
 
 from domains.forms import relative_domain_validator
+
 from .models import Website
 
 
@@ -24,42 +21,40 @@ class AddWebsiteForm(forms.ModelForm):
     This form is used to create new Website instances.
 
     """
+
     class Meta:
         model = Website
-        fields = ['subdomain', 'wildcard']
+        fields = ["subdomain", "wildcard"]
 
     def __init__(self, *args, **kwargs):
-        self.hosting_package = kwargs.pop('hostingpackage')
-        self.hosting_domain = kwargs.pop('domain')
+        self.hosting_package = kwargs.pop("hostingpackage")
+        self.hosting_domain = kwargs.pop("domain")
         super(AddWebsiteForm, self).__init__(*args, **kwargs)
-        self.fields['subdomain'].validators.append(relative_domain_validator)
-        if Website.objects.filter(
-            wildcard=True, domain=self.hosting_domain
-        ).exists():
-            self.fields['wildcard'].widget = forms.HiddenInput()
+        self.fields["subdomain"].validators.append(relative_domain_validator)
+        if Website.objects.filter(wildcard=True, domain=self.hosting_domain).exists():
+            self.fields["wildcard"].widget = forms.HiddenInput()
 
         self.helper = FormHelper()
         self.helper.form_action = reverse(
-            'add_website', kwargs={
-                'package': self.hosting_package.id,
-                'domain': self.hosting_domain.domain,
-            }
+            "add_website",
+            kwargs={
+                "package": self.hosting_package.id,
+                "domain": self.hosting_domain.domain,
+            },
         )
         self.helper.layout = Layout(
-            AppendedText('subdomain', '.' + self.hosting_domain.domain),
-            'wildcard',
-            Submit('submit', _('Add website')),
+            AppendedText("subdomain", "." + self.hosting_domain.domain),
+            "wildcard",
+            Submit("submit", _("Add website")),
         )
 
     def clean_subdomain(self):
-        data = self.cleaned_data['subdomain']
-        if Website.objects.filter(
-            domain=self.hosting_domain, subdomain=data
-        ).exists():
+        data = self.cleaned_data["subdomain"]
+        if Website.objects.filter(domain=self.hosting_domain, subdomain=data).exists():
             raise forms.ValidationError(
-                _('There is already a website for this subdomain'))
-        relative_domain_validator(
-            "{0}.{1}".format(data, self.hosting_domain.domain))
+                _("There is already a website for this subdomain")
+            )
+        relative_domain_validator("{0}.{1}".format(data, self.hosting_domain.domain))
         return data
 
     def save(self, commit=True):
diff --git a/gnuviechadmin/websites/migrations/0001_initial.py b/gnuviechadmin/websites/migrations/0001_initial.py
index 51dbee9..ae67ef2 100644
--- a/gnuviechadmin/websites/migrations/0001_initial.py
+++ b/gnuviechadmin/websites/migrations/0001_initial.py
@@ -1,41 +1,59 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
     dependencies = [
-        ('osusers', '0004_auto_20150104_1751'),
-        ('domains', '0002_auto_20150124_1909'),
+        ("osusers", "0004_auto_20150104_1751"),
+        ("domains", "0002_auto_20150124_1909"),
     ]
 
     operations = [
         migrations.CreateModel(
-            name='Website',
+            name="Website",
             fields=[
-                ('id', models.AutoField(
-                    verbose_name='ID', serialize=False, auto_created=True,
-                    primary_key=True)),
-                ('subdomain', models.CharField(
-                    max_length=64, verbose_name='sub domain')),
-                ('wildcard', models.BooleanField(
-                    default=False, verbose_name='wildcard')),
-                ('domain', models.ForeignKey(
-                    verbose_name='domain', to='domains.HostingDomain',
-                    on_delete=models.CASCADE)),
-                ('osuser', models.ForeignKey(
-                    verbose_name='operating system user', to='osusers.User',
-                    on_delete=models.CASCADE)),
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "subdomain",
+                    models.CharField(max_length=64, verbose_name="sub domain"),
+                ),
+                (
+                    "wildcard",
+                    models.BooleanField(default=False, verbose_name="wildcard"),
+                ),
+                (
+                    "domain",
+                    models.ForeignKey(
+                        verbose_name="domain",
+                        to="domains.HostingDomain",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
+                (
+                    "osuser",
+                    models.ForeignKey(
+                        verbose_name="operating system user",
+                        to="osusers.User",
+                        on_delete=models.CASCADE,
+                    ),
+                ),
             ],
             options={
-                'verbose_name': 'website',
-                'verbose_name_plural': 'websites',
+                "verbose_name": "website",
+                "verbose_name_plural": "websites",
             },
             bases=(models.Model,),
         ),
         migrations.AlterUniqueTogether(
-            name='website',
-            unique_together={('domain', 'subdomain')},
+            name="website",
+            unique_together={("domain", "subdomain")},
         ),
     ]
diff --git a/gnuviechadmin/websites/models.py b/gnuviechadmin/websites/models.py
index a0b2168..44b5f84 100644
--- a/gnuviechadmin/websites/models.py
+++ b/gnuviechadmin/websites/models.py
@@ -2,19 +2,17 @@
 This module defines the database models for website handling.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
 from django.db import models, transaction
-from django.utils.encoding import python_2_unicode_compatible
-from django.utils.translation import ugettext as _
+from django.utils.translation import gettext as _
 
 from domains.models import HostingDomain
-from osusers.models import User as OsUser
-
 from fileservertasks.tasks import (
     create_file_website_hierarchy,
     delete_file_website_hierarchy,
 )
+from osusers.models import User as OsUser
 from webtasks.tasks import (
     create_web_php_fpm_pool_config,
     create_web_vhost_config,
@@ -25,25 +23,23 @@ from webtasks.tasks import (
 )
 
 
-@python_2_unicode_compatible
 class Website(models.Model):
     """
     This is the model for a website.
 
     """
-    subdomain = models.CharField(
-        _('sub domain'), max_length=64)
+
+    subdomain = models.CharField(_("sub domain"), max_length=64)
     osuser = models.ForeignKey(
-        OsUser, verbose_name=_('operating system user'),
-        on_delete=models.CASCADE)
-    domain = models.ForeignKey(
-        HostingDomain, models.CASCADE, verbose_name=_('domain'))
-    wildcard = models.BooleanField(_('wildcard'), default=False)
+        OsUser, verbose_name=_("operating system user"), on_delete=models.CASCADE
+    )
+    domain = models.ForeignKey(HostingDomain, models.CASCADE, verbose_name=_("domain"))
+    wildcard = models.BooleanField(_("wildcard"), default=False)
 
     class Meta:
-        unique_together = [('domain', 'subdomain')]
-        verbose_name = _('website')
-        verbose_name_plural = _('websites')
+        unique_together = [("domain", "subdomain")]
+        verbose_name = _("website")
+        verbose_name_plural = _("websites")
 
     def __str__(self):
         return self.get_fqdn()
@@ -58,12 +54,11 @@ class Website(models.Model):
         if not self.pk:
             fqdn = self.get_fqdn()
             if not Website.objects.filter(osuser=self.osuser).exists():
-                create_web_php_fpm_pool_config.delay(
-                    self.osuser.username).get()
-            create_file_website_hierarchy.delay(
-                self.osuser.username, fqdn).get()
+                create_web_php_fpm_pool_config.delay(self.osuser.username).get()
+            create_file_website_hierarchy.delay(self.osuser.username, fqdn).get()
             create_web_vhost_config.delay(
-                self.osuser.username, fqdn, self.wildcard).get()
+                self.osuser.username, fqdn, self.wildcard
+            ).get()
             enable_web_vhost.delay(fqdn).get()
         return super(Website, self).save(*args, **kwargs)
 
diff --git a/gnuviechadmin/websites/urls.py b/gnuviechadmin/websites/urls.py
index 1fba405..54b0c10 100644
--- a/gnuviechadmin/websites/urls.py
+++ b/gnuviechadmin/websites/urls.py
@@ -2,19 +2,21 @@
 This module defines the URL patterns for website related views.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
-from django.conf.urls import url
-
-from .views import (
-    AddWebsite,
-    DeleteWebsite,
-)
+from django.urls import re_path
 
+from .views import AddWebsite, DeleteWebsite
 
 urlpatterns = [
-    url(r'^(?P\d+)/(?P[\w0-9.-]+)/create$',
-        AddWebsite.as_view(), name='add_website'),
-    url(r'^(?P\d+)/(?P[\w0-9.-]+)/(?P\d+)/delete$',
-        DeleteWebsite.as_view(), name='delete_website'),
+    re_path(
+        r"^(?P\d+)/(?P[\w0-9.-]+)/create$",
+        AddWebsite.as_view(),
+        name="add_website",
+    ),
+    re_path(
+        r"^(?P\d+)/(?P[\w0-9.-]+)/(?P\d+)/delete$",
+        DeleteWebsite.as_view(),
+        name="delete_website",
+    ),
 ]
diff --git a/gnuviechadmin/websites/views.py b/gnuviechadmin/websites/views.py
index 803386f..56bb24e 100644
--- a/gnuviechadmin/websites/views.py
+++ b/gnuviechadmin/websites/views.py
@@ -2,20 +2,17 @@
 This module defines views for website handling.
 
 """
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
 
-from django.shortcuts import get_object_or_404, redirect
-from django.utils.translation import ugettext as _
-from django.views.generic.edit import (
-    CreateView,
-    DeleteView,
-)
 from django.contrib import messages
-
+from django.shortcuts import get_object_or_404, redirect
+from django.utils.translation import gettext as _
+from django.views.generic.edit import CreateView, DeleteView
 from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin
-from gvawebcore.views import HostingPackageAndCustomerMixin
 
 from domains.models import HostingDomain
+from gvawebcore.views import HostingPackageAndCustomerMixin
+
 from .forms import AddWebsiteForm
 from .models import Website
 
@@ -27,36 +24,43 @@ class AddWebsite(
     This view is used to setup new websites for a customer hosting package.
 
     """
+
     model = Website
-    context_object_name = 'website'
-    template_name_suffix = '_create'
+    context_object_name = "website"
+    template_name_suffix = "_create"
     form_class = AddWebsiteForm
 
     def get_form_kwargs(self):
         kwargs = super(AddWebsite, self).get_form_kwargs()
-        kwargs.update({
-            'hostingpackage': self.get_hosting_package(),
-            'domain': get_object_or_404(
-                HostingDomain, domain=self.kwargs['domain']),
-        })
+        kwargs.update(
+            {
+                "hostingpackage": self.get_hosting_package(),
+                "domain": get_object_or_404(
+                    HostingDomain, domain=self.kwargs["domain"]
+                ),
+            }
+        )
         return kwargs
 
     def get_context_data(self, **kwargs):
         context = super(AddWebsite, self).get_context_data(**kwargs)
-        context.update({
-            'customer': self.get_customer_object(),
-            'domain': get_object_or_404(
-                HostingDomain, domain=self.kwargs['domain'])
-        })
+        context.update(
+            {
+                "customer": self.get_customer_object(),
+                "domain": get_object_or_404(
+                    HostingDomain, domain=self.kwargs["domain"]
+                ),
+            }
+        )
         return context
 
     def form_valid(self, form):
         website = form.save()
         messages.success(
             self.request,
-            _('Successfully added website {subdomain}.{domain}').format(
+            _("Successfully added website {subdomain}.{domain}").format(
                 subdomain=website.subdomain, domain=website.domain.domain
-            )
+            ),
         )
         return redirect(self.get_hosting_package())
 
@@ -68,15 +72,18 @@ class DeleteWebsite(
     This view is used to delete websites in a customer hosting package.
 
     """
-    context_object_name = 'website'
+
+    context_object_name = "website"
     model = Website
 
     def get_context_data(self, **kwargs):
         context = super(DeleteWebsite, self).get_context_data(**kwargs)
-        context.update({
-            'customer': self.get_customer_object(),
-            'hostingpackage': self.get_hosting_package(),
-        })
+        context.update(
+            {
+                "customer": self.get_customer_object(),
+                "hostingpackage": self.get_hosting_package(),
+            }
+        )
         return context
 
     def get_success_url(self):
diff --git a/poetry.lock b/poetry.lock
index d96f1cb..6c8f206 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -27,6 +27,24 @@ files = [
 [package.dependencies]
 vine = ">=5.0.0"
 
+[[package]]
+name = "asgiref"
+version = "3.6.0"
+description = "ASGI specs, helper code, and adapters"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "asgiref-3.6.0-py3-none-any.whl", hash = "sha256:71e68008da809b957b7ee4b43dbccff33d1b23519fb8344e33f049897077afac"},
+    {file = "asgiref-3.6.0.tar.gz", hash = "sha256:9567dfe7bd8d3c8c892227827c41cce860b368104c3431da67a0c5a65a949506"},
+]
+
+[package.dependencies]
+typing-extensions = {version = "*", markers = "python_version < \"3.8\""}
+
+[package.extras]
+tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"]
+
 [[package]]
 name = "async-timeout"
 version = "4.0.2"
@@ -600,22 +618,23 @@ files = [
 
 [[package]]
 name = "django"
-version = "2.2.28"
+version = "3.2.18"
 description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design."
 category = "main"
 optional = false
-python-versions = ">=3.5"
+python-versions = ">=3.6"
 files = [
-    {file = "Django-2.2.28-py3-none-any.whl", hash = "sha256:365429d07c1336eb42ba15aa79f45e1c13a0b04d5c21569e7d596696418a6a45"},
-    {file = "Django-2.2.28.tar.gz", hash = "sha256:0200b657afbf1bc08003845ddda053c7641b9b24951e52acd51f6abda33a7413"},
+    {file = "Django-3.2.18-py3-none-any.whl", hash = "sha256:4d492d9024c7b3dfababf49f94511ab6a58e2c9c3c7207786f1ba4eb77750706"},
+    {file = "Django-3.2.18.tar.gz", hash = "sha256:08208dfe892eb64fff073ca743b3b952311104f939e7f6dae954fe72dcc533ba"},
 ]
 
 [package.dependencies]
+asgiref = ">=3.3.2,<4"
 pytz = "*"
 sqlparse = ">=0.2.2"
 
 [package.extras]
-argon2 = ["argon2-cffi (>=16.1.0)"]
+argon2 = ["argon2-cffi (>=19.1.0)"]
 bcrypt = ["bcrypt"]
 
 [[package]]
@@ -665,34 +684,34 @@ files = [
 
 [[package]]
 name = "django-debug-toolbar"
-version = "3.2.4"
+version = "3.8.1"
 description = "A configurable set of panels that display various debug information about the current request/response."
 category = "main"
 optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.7"
 files = [
-    {file = "django-debug-toolbar-3.2.4.tar.gz", hash = "sha256:644bbd5c428d3283aa9115722471769cac1bec189edf3a0c855fd8ff870375a9"},
-    {file = "django_debug_toolbar-3.2.4-py3-none-any.whl", hash = "sha256:6b633b6cfee24f232d73569870f19aa86c819d750e7f3e833f2344a9eb4b4409"},
+    {file = "django_debug_toolbar-3.8.1-py3-none-any.whl", hash = "sha256:879f8a4672d41621c06a4d322dcffa630fc4df056cada6e417ed01db0e5e0478"},
+    {file = "django_debug_toolbar-3.8.1.tar.gz", hash = "sha256:24ef1a7d44d25e60d7951e378454c6509bf536dce7e7d9d36e7c387db499bc27"},
 ]
 
 [package.dependencies]
-Django = ">=2.2"
-sqlparse = ">=0.2.0"
+django = ">=3.2.4"
+sqlparse = ">=0.2"
 
 [[package]]
 name = "django-model-utils"
-version = "4.0.0"
+version = "4.3.1"
 description = "Django model mixins and utilities"
 category = "main"
 optional = false
-python-versions = "*"
+python-versions = ">=3.7"
 files = [
-    {file = "django-model-utils-4.0.0.tar.gz", hash = "sha256:adf09e5be15122a7f4e372cb5a6dd512bbf8d78a23a90770ad0983ee9d909061"},
-    {file = "django_model_utils-4.0.0-py2.py3-none-any.whl", hash = "sha256:9cf882e5b604421b62dbe57ad2b18464dc9c8f963fc3f9831badccae66c1139c"},
+    {file = "django-model-utils-4.3.1.tar.gz", hash = "sha256:2e2e4f13e4f14613134a9777db7ad4265f59a1d8f1384107bcaa3028fe3c87c1"},
+    {file = "django_model_utils-4.3.1-py3-none-any.whl", hash = "sha256:8c0b0177bab909a8635b602d960daa67e80607aa5469217857271a60726d7a4b"},
 ]
 
 [package.dependencies]
-Django = ">=2.0.1"
+Django = ">=3.2"
 
 [[package]]
 name = "docutils"
@@ -1122,47 +1141,83 @@ wcwidth = "*"
 
 [[package]]
 name = "psycopg2-binary"
-version = "2.8.6"
+version = "2.9.5"
 description = "psycopg2 - Python-PostgreSQL Database Adapter"
 category = "main"
 optional = false
-python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
+python-versions = ">=3.6"
 files = [
-    {file = "psycopg2-binary-2.8.6.tar.gz", hash = "sha256:11b9c0ebce097180129e422379b824ae21c8f2a6596b159c7659e2e5a00e1aa0"},
-    {file = "psycopg2_binary-2.8.6-cp27-cp27m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:d14b140a4439d816e3b1229a4a525df917d6ea22a0771a2a78332273fd9528a4"},
-    {file = "psycopg2_binary-2.8.6-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1fabed9ea2acc4efe4671b92c669a213db744d2af8a9fc5d69a8e9bc14b7a9db"},
-    {file = "psycopg2_binary-2.8.6-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:f5ab93a2cb2d8338b1674be43b442a7f544a0971da062a5da774ed40587f18f5"},
-    {file = "psycopg2_binary-2.8.6-cp27-cp27m-win32.whl", hash = "sha256:b4afc542c0ac0db720cf516dd20c0846f71c248d2b3d21013aa0d4ef9c71ca25"},
-    {file = "psycopg2_binary-2.8.6-cp27-cp27m-win_amd64.whl", hash = "sha256:e74a55f6bad0e7d3968399deb50f61f4db1926acf4a6d83beaaa7df986f48b1c"},
-    {file = "psycopg2_binary-2.8.6-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:0deac2af1a587ae12836aa07970f5cb91964f05a7c6cdb69d8425ff4c15d4e2c"},
-    {file = "psycopg2_binary-2.8.6-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ad20d2eb875aaa1ea6d0f2916949f5c08a19c74d05b16ce6ebf6d24f2c9f75d1"},
-    {file = "psycopg2_binary-2.8.6-cp34-cp34m-win32.whl", hash = "sha256:950bc22bb56ee6ff142a2cb9ee980b571dd0912b0334aa3fe0fe3788d860bea2"},
-    {file = "psycopg2_binary-2.8.6-cp34-cp34m-win_amd64.whl", hash = "sha256:b8a3715b3c4e604bcc94c90a825cd7f5635417453b253499664f784fc4da0152"},
-    {file = "psycopg2_binary-2.8.6-cp35-cp35m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:d1b4ab59e02d9008efe10ceabd0b31e79519da6fb67f7d8e8977118832d0f449"},
-    {file = "psycopg2_binary-2.8.6-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:ac0c682111fbf404525dfc0f18a8b5f11be52657d4f96e9fcb75daf4f3984859"},
-    {file = "psycopg2_binary-2.8.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7d92a09b788cbb1aec325af5fcba9fed7203897bbd9269d5691bb1e3bce29550"},
-    {file = "psycopg2_binary-2.8.6-cp35-cp35m-win32.whl", hash = "sha256:aaa4213c862f0ef00022751161df35804127b78adf4a2755b9f991a507e425fd"},
-    {file = "psycopg2_binary-2.8.6-cp35-cp35m-win_amd64.whl", hash = "sha256:c2507d796fca339c8fb03216364cca68d87e037c1f774977c8fc377627d01c71"},
-    {file = "psycopg2_binary-2.8.6-cp36-cp36m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:ee69dad2c7155756ad114c02db06002f4cded41132cc51378e57aad79cc8e4f4"},
-    {file = "psycopg2_binary-2.8.6-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:e82aba2188b9ba309fd8e271702bd0d0fc9148ae3150532bbb474f4590039ffb"},
-    {file = "psycopg2_binary-2.8.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d5227b229005a696cc67676e24c214740efd90b148de5733419ac9aaba3773da"},
-    {file = "psycopg2_binary-2.8.6-cp36-cp36m-win32.whl", hash = "sha256:a0eb43a07386c3f1f1ebb4dc7aafb13f67188eab896e7397aa1ee95a9c884eb2"},
-    {file = "psycopg2_binary-2.8.6-cp36-cp36m-win_amd64.whl", hash = "sha256:e1f57aa70d3f7cc6947fd88636a481638263ba04a742b4a37dd25c373e41491a"},
-    {file = "psycopg2_binary-2.8.6-cp37-cp37m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:833709a5c66ca52f1d21d41865a637223b368c0ee76ea54ca5bad6f2526c7679"},
-    {file = "psycopg2_binary-2.8.6-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ba28584e6bca48c59eecbf7efb1576ca214b47f05194646b081717fa628dfddf"},
-    {file = "psycopg2_binary-2.8.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:6a32f3a4cb2f6e1a0b15215f448e8ce2da192fd4ff35084d80d5e39da683e79b"},
-    {file = "psycopg2_binary-2.8.6-cp37-cp37m-win32.whl", hash = "sha256:0e4dc3d5996760104746e6cfcdb519d9d2cd27c738296525d5867ea695774e67"},
-    {file = "psycopg2_binary-2.8.6-cp37-cp37m-win_amd64.whl", hash = "sha256:cec7e622ebc545dbb4564e483dd20e4e404da17ae07e06f3e780b2dacd5cee66"},
-    {file = "psycopg2_binary-2.8.6-cp38-cp38-macosx_10_9_x86_64.macosx_10_9_intel.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:ba381aec3a5dc29634f20692349d73f2d21f17653bda1decf0b52b11d694541f"},
-    {file = "psycopg2_binary-2.8.6-cp38-cp38-manylinux1_i686.whl", hash = "sha256:a0c50db33c32594305b0ef9abc0cb7db13de7621d2cadf8392a1d9b3c437ef77"},
-    {file = "psycopg2_binary-2.8.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2dac98e85565d5688e8ab7bdea5446674a83a3945a8f416ad0110018d1501b94"},
-    {file = "psycopg2_binary-2.8.6-cp38-cp38-win32.whl", hash = "sha256:bd1be66dde2b82f80afb9459fc618216753f67109b859a361cf7def5c7968729"},
-    {file = "psycopg2_binary-2.8.6-cp38-cp38-win_amd64.whl", hash = "sha256:8cd0fb36c7412996859cb4606a35969dd01f4ea34d9812a141cd920c3b18be77"},
-    {file = "psycopg2_binary-2.8.6-cp39-cp39-macosx_10_9_x86_64.macosx_10_9_intel.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:89705f45ce07b2dfa806ee84439ec67c5d9a0ef20154e0e475e2b2ed392a5b83"},
-    {file = "psycopg2_binary-2.8.6-cp39-cp39-manylinux1_i686.whl", hash = "sha256:42ec1035841b389e8cc3692277a0bd81cdfe0b65d575a2c8862cec7a80e62e52"},
-    {file = "psycopg2_binary-2.8.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7312e931b90fe14f925729cde58022f5d034241918a5c4f9797cac62f6b3a9dd"},
-    {file = "psycopg2_binary-2.8.6-cp39-cp39-win32.whl", hash = "sha256:6422f2ff0919fd720195f64ffd8f924c1395d30f9a495f31e2392c2efafb5056"},
-    {file = "psycopg2_binary-2.8.6-cp39-cp39-win_amd64.whl", hash = "sha256:15978a1fbd225583dd8cdaf37e67ccc278b5abecb4caf6b2d6b8e2b948e953f6"},
+    {file = "psycopg2-binary-2.9.5.tar.gz", hash = "sha256:33e632d0885b95a8b97165899006c40e9ecdc634a529dca7b991eb7de4ece41c"},
+    {file = "psycopg2_binary-2.9.5-cp310-cp310-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:0775d6252ccb22b15da3b5d7adbbf8cfe284916b14b6dc0ff503a23edb01ee85"},
+    {file = "psycopg2_binary-2.9.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ec46ed947801652c9643e0b1dc334cfb2781232e375ba97312c2fc256597632"},
+    {file = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3520d7af1ebc838cc6084a3281145d5cd5bdd43fdef139e6db5af01b92596cb7"},
+    {file = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cbc554ba47ecca8cd3396ddaca85e1ecfe3e48dd57dc5e415e59551affe568e"},
+    {file = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:5d28ecdf191db558d0c07d0f16524ee9d67896edf2b7990eea800abeb23ebd61"},
+    {file = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_24_ppc64le.whl", hash = "sha256:b9c33d4aef08dfecbd1736ceab8b7b3c4358bf10a0121483e5cd60d3d308cc64"},
+    {file = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:05b3d479425e047c848b9782cd7aac9c6727ce23181eb9647baf64ffdfc3da41"},
+    {file = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1e491e6489a6cb1d079df8eaa15957c277fdedb102b6a68cfbf40c4994412fd0"},
+    {file = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:9e32cedc389bcb76d9f24ea8a012b3cb8385ee362ea437e1d012ffaed106c17d"},
+    {file = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:46850a640df62ae940e34a163f72e26aca1f88e2da79148e1862faaac985c302"},
+    {file = "psycopg2_binary-2.9.5-cp310-cp310-win32.whl", hash = "sha256:3d790f84201c3698d1bfb404c917f36e40531577a6dda02e45ba29b64d539867"},
+    {file = "psycopg2_binary-2.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:1764546ffeaed4f9428707be61d68972eb5ede81239b46a45843e0071104d0dd"},
+    {file = "psycopg2_binary-2.9.5-cp311-cp311-macosx_10_9_universal2.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:426c2ae999135d64e6a18849a7d1ad0e1bd007277e4a8f4752eaa40a96b550ff"},
+    {file = "psycopg2_binary-2.9.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7cf1d44e710ca3a9ce952bda2855830fe9f9017ed6259e01fcd71ea6287565f5"},
+    {file = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:024030b13bdcbd53d8a93891a2cf07719715724fc9fee40243f3bd78b4264b8f"},
+    {file = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcda1c84a1c533c528356da5490d464a139b6e84eb77cc0b432e38c5c6dd7882"},
+    {file = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:2ef892cabdccefe577088a79580301f09f2a713eb239f4f9f62b2b29cafb0577"},
+    {file = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_24_ppc64le.whl", hash = "sha256:af0516e1711995cb08dc19bbd05bec7dbdebf4185f68870595156718d237df3e"},
+    {file = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e72c91bda9880f097c8aa3601a2c0de6c708763ba8128006151f496ca9065935"},
+    {file = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e67b3c26e9b6d37b370c83aa790bbc121775c57bfb096c2e77eacca25fd0233b"},
+    {file = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5fc447058d083b8c6ac076fc26b446d44f0145308465d745fba93a28c14c9e32"},
+    {file = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d892bfa1d023c3781a3cab8dd5af76b626c483484d782e8bd047c180db590e4c"},
+    {file = "psycopg2_binary-2.9.5-cp311-cp311-win32.whl", hash = "sha256:2abccab84d057723d2ca8f99ff7b619285d40da6814d50366f61f0fc385c3903"},
+    {file = "psycopg2_binary-2.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:bef7e3f9dc6f0c13afdd671008534be5744e0e682fb851584c8c3a025ec09720"},
+    {file = "psycopg2_binary-2.9.5-cp36-cp36m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:6e63814ec71db9bdb42905c925639f319c80e7909fb76c3b84edc79dadef8d60"},
+    {file = "psycopg2_binary-2.9.5-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:212757ffcecb3e1a5338d4e6761bf9c04f750e7d027117e74aa3cd8a75bb6fbd"},
+    {file = "psycopg2_binary-2.9.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f8a9bcab7b6db2e3dbf65b214dfc795b4c6b3bb3af922901b6a67f7cb47d5f8"},
+    {file = "psycopg2_binary-2.9.5-cp36-cp36m-manylinux_2_24_aarch64.whl", hash = "sha256:56b2957a145f816726b109ee3d4e6822c23f919a7d91af5a94593723ed667835"},
+    {file = "psycopg2_binary-2.9.5-cp36-cp36m-manylinux_2_24_ppc64le.whl", hash = "sha256:f95b8aca2703d6a30249f83f4fe6a9abf2e627aa892a5caaab2267d56be7ab69"},
+    {file = "psycopg2_binary-2.9.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:70831e03bd53702c941da1a1ad36c17d825a24fbb26857b40913d58df82ec18b"},
+    {file = "psycopg2_binary-2.9.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:dbc332beaf8492b5731229a881807cd7b91b50dbbbaf7fe2faf46942eda64a24"},
+    {file = "psycopg2_binary-2.9.5-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:2d964eb24c8b021623df1c93c626671420c6efadbdb8655cb2bd5e0c6fa422ba"},
+    {file = "psycopg2_binary-2.9.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:95076399ec3b27a8f7fa1cc9a83417b1c920d55cf7a97f718a94efbb96c7f503"},
+    {file = "psycopg2_binary-2.9.5-cp36-cp36m-win32.whl", hash = "sha256:3fc33295cfccad697a97a76dec3f1e94ad848b7b163c3228c1636977966b51e2"},
+    {file = "psycopg2_binary-2.9.5-cp36-cp36m-win_amd64.whl", hash = "sha256:02551647542f2bf89073d129c73c05a25c372fc0a49aa50e0de65c3c143d8bd0"},
+    {file = "psycopg2_binary-2.9.5-cp37-cp37m-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:63e318dbe52709ed10d516a356f22a635e07a2e34c68145484ed96a19b0c4c68"},
+    {file = "psycopg2_binary-2.9.5-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7e518a0911c50f60313cb9e74a169a65b5d293770db4770ebf004245f24b5c5"},
+    {file = "psycopg2_binary-2.9.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9d38a4656e4e715d637abdf7296e98d6267df0cc0a8e9a016f8ba07e4aa3eeb"},
+    {file = "psycopg2_binary-2.9.5-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:68d81a2fe184030aa0c5c11e518292e15d342a667184d91e30644c9d533e53e1"},
+    {file = "psycopg2_binary-2.9.5-cp37-cp37m-manylinux_2_24_ppc64le.whl", hash = "sha256:7ee3095d02d6f38bd7d9a5358fcc9ea78fcdb7176921528dd709cc63f40184f5"},
+    {file = "psycopg2_binary-2.9.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:46512486be6fbceef51d7660dec017394ba3e170299d1dc30928cbedebbf103a"},
+    {file = "psycopg2_binary-2.9.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b911dfb727e247340d36ae20c4b9259e4a64013ab9888ccb3cbba69b77fd9636"},
+    {file = "psycopg2_binary-2.9.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:422e3d43b47ac20141bc84b3d342eead8d8099a62881a501e97d15f6addabfe9"},
+    {file = "psycopg2_binary-2.9.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c5682a45df7d9642eff590abc73157c887a68f016df0a8ad722dcc0f888f56d7"},
+    {file = "psycopg2_binary-2.9.5-cp37-cp37m-win32.whl", hash = "sha256:b8104f709590fff72af801e916817560dbe1698028cd0afe5a52d75ceb1fce5f"},
+    {file = "psycopg2_binary-2.9.5-cp37-cp37m-win_amd64.whl", hash = "sha256:7b3751857da3e224f5629400736a7b11e940b5da5f95fa631d86219a1beaafec"},
+    {file = "psycopg2_binary-2.9.5-cp38-cp38-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:043a9fd45a03858ff72364b4b75090679bd875ee44df9c0613dc862ca6b98460"},
+    {file = "psycopg2_binary-2.9.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9ffdc51001136b699f9563b1c74cc1f8c07f66ef7219beb6417a4c8aaa896c28"},
+    {file = "psycopg2_binary-2.9.5-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c15ba5982c177bc4b23a7940c7e4394197e2d6a424a2d282e7c236b66da6d896"},
+    {file = "psycopg2_binary-2.9.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc85b3777068ed30aff8242be2813038a929f2084f69e43ef869daddae50f6ee"},
+    {file = "psycopg2_binary-2.9.5-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:215d6bf7e66732a514f47614f828d8c0aaac9a648c46a831955cb103473c7147"},
+    {file = "psycopg2_binary-2.9.5-cp38-cp38-manylinux_2_24_ppc64le.whl", hash = "sha256:7d07f552d1e412f4b4e64ce386d4c777a41da3b33f7098b6219012ba534fb2c2"},
+    {file = "psycopg2_binary-2.9.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a0adef094c49f242122bb145c3c8af442070dc0e4312db17e49058c1702606d4"},
+    {file = "psycopg2_binary-2.9.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:00475004e5ed3e3bf5e056d66e5dcdf41a0dc62efcd57997acd9135c40a08a50"},
+    {file = "psycopg2_binary-2.9.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:7d88db096fa19d94f433420eaaf9f3c45382da2dd014b93e4bf3215639047c16"},
+    {file = "psycopg2_binary-2.9.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:902844f9c4fb19b17dfa84d9e2ca053d4a4ba265723d62ea5c9c26b38e0aa1e6"},
+    {file = "psycopg2_binary-2.9.5-cp38-cp38-win32.whl", hash = "sha256:4e7904d1920c0c89105c0517dc7e3f5c20fb4e56ba9cdef13048db76947f1d79"},
+    {file = "psycopg2_binary-2.9.5-cp38-cp38-win_amd64.whl", hash = "sha256:a36a0e791805aa136e9cbd0ffa040d09adec8610453ee8a753f23481a0057af5"},
+    {file = "psycopg2_binary-2.9.5-cp39-cp39-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:25382c7d174c679ce6927c16b6fbb68b10e56ee44b1acb40671e02d29f2fce7c"},
+    {file = "psycopg2_binary-2.9.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9c38d3869238e9d3409239bc05bc27d6b7c99c2a460ea337d2814b35fb4fea1b"},
+    {file = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5c6527c8efa5226a9e787507652dd5ba97b62d29b53c371a85cd13f957fe4d42"},
+    {file = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e59137cdb970249ae60be2a49774c6dfb015bd0403f05af1fe61862e9626642d"},
+    {file = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:d4c7b3a31502184e856df1f7bbb2c3735a05a8ce0ade34c5277e1577738a5c91"},
+    {file = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_24_ppc64le.whl", hash = "sha256:b9a794cef1d9c1772b94a72eec6da144c18e18041d294a9ab47669bc77a80c1d"},
+    {file = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c5254cbd4f4855e11cebf678c1a848a3042d455a22a4ce61349c36aafd4c2267"},
+    {file = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c5e65c6ac0ae4bf5bef1667029f81010b6017795dcb817ba5c7b8a8d61fab76f"},
+    {file = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:74eddec4537ab1f701a1647214734bc52cee2794df748f6ae5908e00771f180a"},
+    {file = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:01ad49d68dd8c5362e4bfb4158f2896dc6e0c02e87b8a3770fc003459f1a4425"},
+    {file = "psycopg2_binary-2.9.5-cp39-cp39-win32.whl", hash = "sha256:937880290775033a743f4836aa253087b85e62784b63fd099ee725d567a48aa1"},
+    {file = "psycopg2_binary-2.9.5-cp39-cp39-win_amd64.whl", hash = "sha256:484405b883630f3e74ed32041a87456c5e0e63a8e3429aa93e8714c366d62bd1"},
 ]
 
 [[package]]
@@ -1735,4 +1790,4 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools"
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.7"
-content-hash = "45edcf8e776501a35fd1621b430bb434206d3429455c8637a71ea652445bda6a"
+content-hash = "37ecfcb75a397eb82b3afbdf901a356d735fb1a941e7067c4b74fb2fe0227c84"
diff --git a/pyproject.toml b/pyproject.toml
index 56704ca..7294701 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -8,14 +8,14 @@ readme = "README.md"
 
 [tool.poetry.dependencies]
 python = "^3.7"
-django = "<3"
-psycopg2-binary = "<2.9"
+django = "<4"
+psycopg2-binary = "^2.9"
 celery = "^5.2.7"
 django-allauth = "^0.52.0"
 django-braces = "^1.15.0"
 django-crispy-forms = "<2"
-django-debug-toolbar = "<3.8"
-django-model-utils = "<4.1"
+django-debug-toolbar = "^3.8"
+django-model-utils = "^4.1"
 gvacommon = {version = "^0.5.0", source = "gnuviech"}
 passlib = "^1.7.4"
 redis = "^4.5.1"
@@ -38,6 +38,7 @@ url = "https://pypi.gnuviech-server.de/simple"
 default = false
 secondary = false
 
+
 [build-system]
 requires = ["poetry-core"]
 build-backend = "poetry.core.masonry.api"
From d6fc29a2b8725ab4c8f4ebe73a3ce708c67dd53f Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sun, 19 Feb 2023 12:38:19 +0100
Subject: [PATCH 05/46] Update to gvacommon 0.6.0
---
 poetry.lock    | 12 ++++++------
 pyproject.toml |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/poetry.lock b/poetry.lock
index 6c8f206..a57a7e4 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -739,17 +739,17 @@ files = [
 
 [[package]]
 name = "gvacommon"
-version = "0.5.0"
-description = "common utility code for gnuviechadmin applications"
+version = "0.6.0"
+description = ""
 category = "main"
 optional = false
-python-versions = "*"
+python-versions = ">=3.7,<4.0"
 files = [
-    {file = "gvacommon-0.5.0-py3-none-any.whl", hash = "sha256:adf1ebc824433196d112764c61d9ca869481d33f612818c2840069f57ab42c25"},
+    {file = "gvacommon-0.6.0-py3-none-any.whl", hash = "sha256:89977984ae8fd76860c326b0221a3327c48b7f3349ef058541770f0d1a3a55d8"},
 ]
 
 [package.dependencies]
-Django = "*"
+django = "<4"
 
 [package.source]
 type = "legacy"
@@ -1790,4 +1790,4 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools"
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.7"
-content-hash = "37ecfcb75a397eb82b3afbdf901a356d735fb1a941e7067c4b74fb2fe0227c84"
+content-hash = "c11eec493daca3a228f3c99300d0ebf0fa35060624c93649e2dce4c71cdf67f2"
diff --git a/pyproject.toml b/pyproject.toml
index 7294701..12fc1af 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -16,7 +16,7 @@ django-braces = "^1.15.0"
 django-crispy-forms = "<2"
 django-debug-toolbar = "^3.8"
 django-model-utils = "^4.1"
-gvacommon = {version = "^0.5.0", source = "gnuviech"}
+gvacommon = {version = "^0.6.0", source = "gnuviech"}
 passlib = "^1.7.4"
 redis = "^4.5.1"
 requests-oauthlib = "^1.3.1"
From 610f8976fcc366a73bebde8839627b9354be8e3c Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sun, 19 Feb 2023 13:45:30 +0100
Subject: [PATCH 06/46] Refactor managemails to use signals
- use signals to trigger Celery tasks to create and delete mailboxes
- add generic TestCaseWithCeleryTasks class to handle celery task tests
  in a uniform way
---
 gnuviechadmin/managemails/apps.py             |  8 +++
 gnuviechadmin/managemails/models.py           | 11 ----
 gnuviechadmin/managemails/signals.py          | 62 +++++++++++++++++++
 .../managemails/tests/test_models.py          | 49 +++++++--------
 gnuviechadmin/taskresults/tests/testutils.py  | 21 +++++++
 5 files changed, 114 insertions(+), 37 deletions(-)
 create mode 100644 gnuviechadmin/managemails/signals.py
 create mode 100644 gnuviechadmin/taskresults/tests/testutils.py
diff --git a/gnuviechadmin/managemails/apps.py b/gnuviechadmin/managemails/apps.py
index 1cf2135..328a964 100644
--- a/gnuviechadmin/managemails/apps.py
+++ b/gnuviechadmin/managemails/apps.py
@@ -15,3 +15,11 @@ class ManageMailsAppConfig(AppConfig):
 
     name = "managemails"
     verbose_name = _("Mailboxes and Mail Addresses")
+
+    def ready(self):
+        """
+        Takes care of importing the signal handlers of the :py:mod:`userdbs`
+        app.
+
+        """
+        import managemails.signals  # NOQA
diff --git a/gnuviechadmin/managemails/models.py b/gnuviechadmin/managemails/models.py
index 9b303f1..cef5cf4 100644
--- a/gnuviechadmin/managemails/models.py
+++ b/gnuviechadmin/managemails/models.py
@@ -8,7 +8,6 @@ from model_utils.models import TimeStampedModel
 from passlib.handlers.sha2_crypt import sha512_crypt
 
 from domains.models import MailDomain
-from fileservertasks.tasks import create_file_mailbox, delete_file_mailbox
 from osusers.models import User as OsUser
 
 
@@ -123,16 +122,6 @@ class Mailbox(ActivateAbleMixin, TimeStampedModel):
         """
         self.password = sha512_crypt.hash(password)
 
-    def save(self, *args, **kwargs):
-        # TODO: refactor to use signals
-        create_file_mailbox.delay(self.osuser.username, self.username).get()
-        super(Mailbox, self).save(*args, **kwargs)
-
-    def delete(self, *args, **kwargs):
-        # TODO: refactor to use signals
-        delete_file_mailbox.delay(self.osuser.username, self.username).get()
-        super(Mailbox, self).delete(*args, **kwargs)
-
     def get_mailaddresses(self):
         """
         Get a list of mail addresses assigned to this mailbox.
diff --git a/gnuviechadmin/managemails/signals.py b/gnuviechadmin/managemails/signals.py
new file mode 100644
index 0000000..2c3bb87
--- /dev/null
+++ b/gnuviechadmin/managemails/signals.py
@@ -0,0 +1,62 @@
+"""
+This module contains the signal handlers of the :py:mod:`managemails` app.
+
+The module starts Celery_ tasks.
+
+.. _Celery: https://www.celeryproject.org/
+
+"""
+import logging
+
+from django.db.models.signals import post_delete, post_save
+from django.dispatch import receiver
+
+from fileservertasks.tasks import create_file_mailbox, delete_file_mailbox
+from managemails.models import Mailbox
+from taskresults.models import TaskResult
+
+_LOGGER = logging.getLogger(__name__)
+
+
+@receiver(post_save, sender=Mailbox)
+def handle_mailbox_created(sender, instance, created, **kwargs):
+    """
+    Handles post creation actions on :py:class:`Mailbox ` instances.
+
+    :param sender: sender of the signal
+    :param instance: Mailbox instance
+    :param created: whether the instance has just been created
+
+    This signal handler starts a Celery_ task.
+
+    """
+    if created:
+        taskresult = TaskResult.objects.create_task_result(
+            "handle_mailbox_created",
+            create_file_mailbox.s(instance.osuser.username, instance.username),
+        )
+        _LOGGER.info(
+            "Mailbox creation has been requested in task %s", taskresult.task_id
+        )
+    _LOGGER.debug("mailbox %s has been %s", instance, created and "created" or "updated")
+
+
+@receiver(post_delete, sender=Mailbox)
+def handle_mailbox_deleted(sender, instance, **kwargs):
+    """
+    Handles cleanup actions to be done after deletion of a
+    :py:class:`Mailbox ` instance.
+
+    :param sender: sender of the signal
+    :param instance: Mailbox instance
+
+    This signal handler starts a Celery_ task.
+
+    """
+    taskresult = TaskResult.objects.create_task_result(
+        "handle_mailbox_deleted",
+        delete_file_mailbox.s(instance.osuser.username, instance.username)
+    )
+    _LOGGER.info(
+        "Mailbox deletion has been requested in task %s", taskresult.task_id
+    )
diff --git a/gnuviechadmin/managemails/tests/test_models.py b/gnuviechadmin/managemails/tests/test_models.py
index 21ff892..18562d3 100644
--- a/gnuviechadmin/managemails/tests/test_models.py
+++ b/gnuviechadmin/managemails/tests/test_models.py
@@ -1,24 +1,20 @@
 """
 This module contains tests for :py:mod:`managemails.models`
 """
-from unittest.mock import patch
-
 from django.contrib.auth import get_user_model
 from django.test import TestCase, TransactionTestCase
 from django.test.utils import override_settings
-from passlib.hash import sha512_crypt
+from passlib.handlers.sha2_crypt import sha512_crypt
 
 from domains.models import MailDomain
 from managemails.models import MailAddress, Mailbox
 from osusers.models import User
+from taskresults.tests.testutils import TestCaseWithCeleryTasks
 
 Customer = get_user_model()
 
 
-@override_settings(
-    CELERY_ALWAYS_EAGER=True, CELERY_CACHE_BACKEND="memory", BROKER_BACKEND="memory"
-)
-class MailboxTest(TestCase):
+class MailboxTest(TestCaseWithCeleryTasks):
     def setUp(self):
         super(MailboxTest, self).setUp()
         self.customer = Customer.objects.create_user("test")
@@ -35,22 +31,32 @@ class MailboxTest(TestCase):
         mb.set_password("test")
         self.assertEqual(str(mb), "test")
 
-    @patch("managemails.models.create_file_mailbox")
-    def test_save(self, create_file_mailbox_task):
+    def test_save(self):
         user = User.objects.create_user(self.customer)
+
+        self.resetCeleryTasks()
+
         mb = Mailbox.objects.create_mailbox(user)
         self.assertIsNotNone(mb.pk)
-        create_file_mailbox_task.delay.assert_called_with(user.username, mb.username)
 
-    @patch("managemails.models.delete_file_mailbox")
-    def test_delete(self, delete_file_mailbox_task):
+        self.assertCeleryTasksRun([
+            (1, "handle_mailbox_created"),
+        ])
+
+    def test_delete(self):
         user = User.objects.create_user(self.customer)
         mb = Mailbox.objects.create_mailbox(user)
+
+        self.resetCeleryTasks()
+
         mb.delete()
         self.assertIsNone(mb.pk)
-        delete_file_mailbox_task.delay.assert_called_with(user.username, mb.username)
 
-    def test_get_mailaddresses(self):
+        self.assertCeleryTasksRun([
+            (1, "handle_mailbox_deleted"),
+        ])
+
+    def test_get_mail_addresses(self):
         user = User.objects.create_user(self.customer)
         mb = Mailbox.objects.create_mailbox(user)
         md = MailDomain.objects.create(domain="example.org")
@@ -61,10 +67,7 @@ class MailboxTest(TestCase):
         self.assertIn(address, mailaddresses)
 
 
-@override_settings(
-    CELERY_ALWAYS_EAGER=True, CELERY_CACHE_BACKEND="memory", BROKER_BACKEND="memory"
-)
-class MailAddressTest(TransactionTestCase):
+class MailAddressTest(TestCaseWithCeleryTasks):
     def test__str__(self):
         md = MailDomain.objects.create(domain="example.org")
         ma = MailAddress.objects.create(localpart="test", domain=md)
@@ -214,10 +217,7 @@ class MailAddressTest(TransactionTestCase):
         self.assertEqual(mafwds[0].target, "test2@example.org")
 
 
-@override_settings(
-    CELERY_ALWAYS_EAGER=True, CELERY_CACHE_BACKEND="memory", BROKER_BACKEND="memory"
-)
-class MailboxManagerTest(TransactionTestCase):
+class MailboxManagerTest(TestCaseWithCeleryTasks):
     def setUp(self):
         super(MailboxManagerTest, self).setUp()
         self.customer = Customer.objects.create_user("test")
@@ -302,10 +302,7 @@ class MailboxManagerTest(TransactionTestCase):
         self.assertTrue(sha512_crypt.verify("test", mailbox.password))
 
 
-@override_settings(
-    CELERY_ALWAYS_EAGER=True, CELERY_CACHE_BACKEND="memory", BROKER_BACKEND="memory"
-)
-class MailAddressMailboxTest(TestCase):
+class MailAddressMailboxTest(TestCaseWithCeleryTasks):
     def setUp(self):
         super(MailAddressMailboxTest, self).setUp()
         self.customer = Customer.objects.create_user("test")
diff --git a/gnuviechadmin/taskresults/tests/testutils.py b/gnuviechadmin/taskresults/tests/testutils.py
new file mode 100644
index 0000000..3bfdcb7
--- /dev/null
+++ b/gnuviechadmin/taskresults/tests/testutils.py
@@ -0,0 +1,21 @@
+from django.test import TestCase
+from django.test.utils import override_settings
+
+from taskresults.models import TaskResult
+
+
+@override_settings(
+    CELERY_ALWAYS_EAGER=True, CELERY_CACHE_BACKEND="memory", BROKER_BACKEND="memory"
+)
+class TestCaseWithCeleryTasks(TestCase):
+    def resetCeleryTasks(self):
+        TaskResult.objects.all().delete()
+
+    def assertCeleryTasksRun(self, tasks):
+        task_results = TaskResult.objects.all()
+
+        self.assertEqual(task_results.count(), sum([t[0] for t in tasks]))
+
+        creators = [r.creator for r in task_results]
+        for t_count, t_creator in tasks:
+            self.assertEqual(creators.count(t_creator), t_count)
From a8392ef91e90badaccf31e206145caa3850a01bf Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sun, 19 Feb 2023 13:47:08 +0100
Subject: [PATCH 07/46] Use sha512_crypt from passlib.handlers.sha2_crypt
---
 gnuviechadmin/osusers/models.py            | 5 ++---
 gnuviechadmin/osusers/signals.py           | 9 +--------
 gnuviechadmin/osusers/tests/test_models.py | 2 +-
 3 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/gnuviechadmin/osusers/models.py b/gnuviechadmin/osusers/models.py
index d50fe1f..ff36f49 100644
--- a/gnuviechadmin/osusers/models.py
+++ b/gnuviechadmin/osusers/models.py
@@ -14,7 +14,7 @@ from django.dispatch import Signal
 from django.utils import timezone
 from django.utils.translation import gettext as _
 from model_utils.models import TimeStampedModel
-from passlib.hash import sha512_crypt
+from passlib.handlers.sha2_crypt import sha512_crypt
 from passlib.pwd import genword
 
 _LOGGER = logging.getLogger(__name__)
@@ -175,8 +175,7 @@ class UserManager(models.Manager):
             shell=settings.OSUSER_DEFAULT_SHELL,
         )
         user.set_password(password)
-        if commit:
-            user.save()
+        user.save()
         return user
 
 
diff --git a/gnuviechadmin/osusers/signals.py b/gnuviechadmin/osusers/signals.py
index 5c1683e..a817af1 100644
--- a/gnuviechadmin/osusers/signals.py
+++ b/gnuviechadmin/osusers/signals.py
@@ -3,7 +3,7 @@ This module contains the signal handlers of the :py:mod:`osusers` app.
 
 The module starts Celery_ tasks.
 
-.. _Celery: http://www.celeryproject.org/
+.. _Celery: https://www.celeryproject.org/
 
 """
 from __future__ import absolute_import
@@ -256,13 +256,6 @@ def handle_ssh_keys_changed(sender, instance, **kwargs):
     _LOGGER.info("Change of SSH keys has been requested in task %s", taskresult.task_id)
 
 
-# @receiver(post_delete)
-# def handle_post_delete(sender, **kwargs):
-#     _LOGGER.debug(
-#         'handling post_delete signal for %s with args %s',
-#         sender, kwargs)
-
-
 @receiver(post_delete, sender=Group)
 def handle_group_deleted(sender, instance, **kwargs):
     """
diff --git a/gnuviechadmin/osusers/tests/test_models.py b/gnuviechadmin/osusers/tests/test_models.py
index 56ce4be..8770263 100644
--- a/gnuviechadmin/osusers/tests/test_models.py
+++ b/gnuviechadmin/osusers/tests/test_models.py
@@ -7,7 +7,7 @@ from django.core.exceptions import ValidationError
 from django.test import TestCase
 from django.test.utils import override_settings
 from django.utils import timezone
-from passlib.hash import sha512_crypt
+from passlib.handlers.sha2_crypt import sha512_crypt
 
 from osusers.models import (
     CANNOT_USE_PRIMARY_GROUP_AS_ADDITIONAL,
From fc8f22432cfd5f0e994e104a8b7c2ee20ffa0bbf Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sun, 19 Feb 2023 15:13:31 +0100
Subject: [PATCH 08/46] Fix skipped tests in managemails
---
 gnuviechadmin/managemails/tests/test_forms.py | 327 ++++++++----------
 gnuviechadmin/osusers/tests/testutils.py      |  13 +
 2 files changed, 149 insertions(+), 191 deletions(-)
 create mode 100644 gnuviechadmin/osusers/tests/testutils.py
diff --git a/gnuviechadmin/managemails/tests/test_forms.py b/gnuviechadmin/managemails/tests/test_forms.py
index d0beb59..32fe366 100644
--- a/gnuviechadmin/managemails/tests/test_forms.py
+++ b/gnuviechadmin/managemails/tests/test_forms.py
@@ -2,14 +2,14 @@
 This module provides tests for :py:mod:`managemails.forms`.
 
 """
-from unittest import skip
-from unittest.mock import ANY, MagicMock, Mock, patch
+from unittest.mock import MagicMock, Mock, patch
 
 from django.forms import ValidationError
 from django.test import TestCase
 from django.urls import reverse
 
-import osusers.models
+from osusers.tests.testutils import create_test_user
+
 from domains.models import MailDomain
 from managemails.forms import (
     MAILBOX_OR_FORWARDS,
@@ -21,20 +21,21 @@ from managemails.forms import (
     multiple_email_validator,
 )
 from managemails.models import MailAddress, Mailbox
+from taskresults.tests.testutils import TestCaseWithCeleryTasks
 
 
 class CreateMailboxFormTest(TestCase):
-    def test_constructor_needs_hostingpackage(self):
-        instance = MagicMock()
+    def test_constructor_needs_hosting_package(self):
+        instance = Mailbox()
         with self.assertRaises(KeyError):
             CreateMailboxForm(instance)
 
     def test_constructor(self):
-        hostingpackage = Mock(id=42)
+        hosting_package = Mock(id=42)
         instance = MagicMock()
-        form = CreateMailboxForm(instance, hostingpackage=hostingpackage)
+        form = CreateMailboxForm(instance, hostingpackage=hosting_package)
         self.assertTrue(hasattr(form, "hosting_package"))
-        self.assertEqual(form.hosting_package, hostingpackage)
+        self.assertEqual(form.hosting_package, hosting_package)
         self.assertTrue(hasattr(form, "helper"))
         self.assertEqual(
             form.helper.form_action, reverse("create_mailbox", kwargs={"package": 42})
@@ -134,32 +135,47 @@ class MailAddressFieldMixinTest(TestCase):
         self.assertIn("forwards", form.fields)
 
 
-class AddMailAddressFormTest(TestCase):
-    def test_constructor_needs_hostingpackage(self):
-        instance = MailAddress()
-        with self.assertRaises(KeyError):
-            AddMailAddressForm(instance=instance, maildomain=None)
+def create_test_mailbox(os_user=None):
+    if os_user is None:
+        os_user = create_test_user()
 
-    def test_constructor_needs_maildomain(self):
-        instance = MagicMock()
+    mail_box = Mailbox.objects.create(osuser=os_user, username="mailbox23")
+    mail_box.set_password("test")
+
+    return mail_box
+
+
+def create_test_mail_domain():
+    return MailDomain.objects.create(domain="example.org")
+
+
+class AddMailAddressFormTest(TestCaseWithCeleryTasks):
+    def setUp(self) -> None:
+        super().setUp()
+        self.mail_domain = create_test_mail_domain()
+        self.instance = MailAddress()
+        self.os_user = create_test_user()
+        self.hosting_package = create_test_hosting_package(os_user=self.os_user)
+
+    def test_constructor_needs_hosting_package(self):
         with self.assertRaises(KeyError):
-            AddMailAddressForm(instance=instance, hostingpackage=MagicMock())
+            AddMailAddressForm(instance=self.instance, maildomain=MagicMock())
+
+    def test_constructor_needs_mail_domain(self):
+        with self.assertRaises(KeyError):
+            AddMailAddressForm(instance=self.instance, hostingpackage=MagicMock())
 
     def test_constructor(self):
-        instance = MailAddress()
-        os_user = osusers.models.User(username="testuser")
-        hosting_package = MagicMock(id=42, osuser=os_user)
-        mail_domain = MailDomain(domain="example.org")
         form = AddMailAddressForm(
-            instance=instance, hostingpackage=hosting_package, maildomain=mail_domain
+            instance=self.instance, hostingpackage=self.hosting_package, maildomain=self.mail_domain
         )
         self.assertIn("mailbox_or_forwards", form.fields)
         self.assertIn("mailbox", form.fields)
         self.assertIn("forwards", form.fields)
         self.assertTrue(hasattr(form, "hosting_package"))
-        self.assertEqual(form.hosting_package, hosting_package)
+        self.assertEqual(form.hosting_package, self.hosting_package)
         self.assertTrue(hasattr(form, "maildomain"))
-        self.assertEqual(form.maildomain, mail_domain)
+        self.assertEqual(form.maildomain, self.mail_domain)
         self.assertTrue(hasattr(form, "helper"))
         self.assertEqual(
             form.helper.form_action,
@@ -169,15 +185,10 @@ class AddMailAddressFormTest(TestCase):
         self.assertEqual(form.helper.layout[1].name, "submit")
 
     def test_clean_localpart_valid(self):
-        mail_domain = MailDomain.objects.create(domain="example.org")
-
-        instance = MailAddress()
-        os_user = osusers.models.User(username="testuser")
-        hosting_package = MagicMock(id=42, osuser=os_user)
         form = AddMailAddressForm(
-            instance=instance,
-            hostingpackage=hosting_package,
-            maildomain=mail_domain,
+            instance=self.instance,
+            hostingpackage=self.hosting_package,
+            maildomain=self.mail_domain,
             data={
                 "localpart": "test",
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.forwards,
@@ -188,17 +199,12 @@ class AddMailAddressFormTest(TestCase):
         self.assertEqual("test", form.clean_localpart())
 
     def test_clean_localpart_duplicate(self):
-        mail_domain = MailDomain.objects.create(domain="example.org")
+        MailAddress.objects.create(localpart="test", domain=self.mail_domain)
 
-        MailAddress.objects.create(localpart="test", domain=mail_domain)
-
-        instance = MailAddress()
-        osuser = osusers.models.User(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
         form = AddMailAddressForm(
-            instance=instance,
-            hostingpackage=hostingpackage,
-            maildomain=mail_domain,
+            instance=self.instance,
+            hostingpackage=self.hosting_package,
+            maildomain=self.mail_domain,
             data={
                 "localpart": "test",
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.forwards,
@@ -209,14 +215,10 @@ class AddMailAddressFormTest(TestCase):
         self.assertIn("localpart", form.errors)
 
     def test_clean_no_mailbox_choice(self):
-        instance = MailAddress()
-        osuser = osusers.models.User(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MailDomain(domain="example.org")
         form = AddMailAddressForm(
-            instance=instance,
-            hostingpackage=hostingpackage,
-            maildomain=maildomain,
+            instance=self.instance,
+            hostingpackage=self.hosting_package,
+            maildomain=self.mail_domain,
             data={
                 "localpart": "test",
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.mailbox,
@@ -226,14 +228,10 @@ class AddMailAddressFormTest(TestCase):
         self.assertIn("mailbox", form.errors)
 
     def test_clean_no_forward_address_choice(self):
-        instance = MailAddress()
-        os_user = osusers.models.User(username="testuser")
-        hosting_package = MagicMock(id=42, osuser=os_user)
-        mail_domain = MailDomain(domain="example.org")
         form = AddMailAddressForm(
-            instance=instance,
-            hostingpackage=hosting_package,
-            maildomain=mail_domain,
+            instance=self.instance,
+            hostingpackage=self.hosting_package,
+            maildomain=self.mail_domain,
             data={
                 "localpart": "test",
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.forwards,
@@ -243,15 +241,10 @@ class AddMailAddressFormTest(TestCase):
         self.assertIn("forwards", form.errors)
 
     def test_save_with_forwards_no_commit(self):
-        mail_domain = MailDomain.objects.create(domain="example.org")
-
-        instance = MailAddress()
-        os_user = osusers.models.User(username="testuser")
-        hosting_package = MagicMock(id=42, osuser=os_user)
         form = AddMailAddressForm(
-            instance=instance,
-            hostingpackage=hosting_package,
-            maildomain=mail_domain,
+            instance=self.instance,
+            hostingpackage=self.hosting_package,
+            maildomain=self.mail_domain,
             data={
                 "localpart": "test",
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.forwards,
@@ -260,18 +253,13 @@ class AddMailAddressFormTest(TestCase):
         )
         self.assertTrue(form.is_valid())
         form.save(commit=False)
-        self.assertEqual(mail_domain, instance.domain)
+        self.assertEqual(self.mail_domain, self.instance.domain)
 
     def test_save_with_forwards_commit(self):
-        maildomain = MailDomain.objects.create(domain="example.org")
-
-        instance = MailAddress()
-        osuser = osusers.models.User(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
         form = AddMailAddressForm(
-            instance=instance,
-            hostingpackage=hostingpackage,
-            maildomain=maildomain,
+            instance=self.instance,
+            hostingpackage=self.hosting_package,
+            maildomain=self.mail_domain,
             data={
                 "localpart": "test",
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.forwards,
@@ -280,85 +268,60 @@ class AddMailAddressFormTest(TestCase):
         )
         self.assertTrue(form.is_valid())
         form.save(commit=True)
-        self.assertEqual(maildomain, instance.domain)
+        self.assertEqual(self.mail_domain, self.instance.domain)
         forwards = list(
-            instance.mailaddressforward_set.values_list("target", flat=True).order_by(
+            self.instance.mailaddressforward_set.values_list("target", flat=True).order_by(
                 "target"
             )
         )
         self.assertEqual(len(forwards), 2)
         self.assertEqual(forwards, ["test2@example.org", "test3@example.org"])
 
-    @skip("does not work because it will create a real mailbox")
     def test_save_with_mailbox_no_commit(self):
-        instance = MailAddress()
-
-        os_user = osusers.models.User(username="testuser")
-        hosting_package = MagicMock(id=42, osuser=os_user)
-
-        mail_domain = MailDomain.objects.create(domain="example.org")
-        mail_box = Mailbox.objects.create(osuser=os_user, username="mailbox23")
-        mail_box.set_password("test")
+        mail_box = create_test_mailbox(os_user=self.os_user)
 
         form = AddMailAddressForm(
-            instance=instance,
-            hostingpackage=hosting_package,
-            maildomain=mail_domain,
+            instance=self.instance,
+            hostingpackage=self.hosting_package,
+            maildomain=self.mail_domain,
             data={
                 "localpart": "test",
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.mailbox,
-                "mailbox": "mailbox23",
+                "mailbox": mail_box,
             },
         )
         self.assertTrue(form.is_valid())
         form.save(commit=False)
-        self.assertEqual(mail_domain, instance.domain)
+        self.assertEqual(self.mail_domain, self.instance.domain)
 
-    @skip("does not work because it will create a real mailbox")
     def test_save_with_mailbox_commit(self):
-        mail_domain = MailDomain.objects.create(domain="example.org")
-
-        instance = MailAddress()
-        os_user = osusers.models.User(username="testuser")
-
-        mail_box = Mailbox.objects.create(osuser=os_user, username="mailbox23")
-        mail_box.set_password("test")
-
-        hosting_package = MagicMock(id=42, osuser=os_user)
+        mail_box = create_test_mailbox(os_user=self.os_user)
 
         form = AddMailAddressForm(
-            instance=instance,
-            hostingpackage=hosting_package,
-            maildomain=mail_domain,
+            instance=self.instance,
+            hostingpackage=self.hosting_package,
+            maildomain=self.mail_domain,
             data={
                 "localpart": "test",
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.mailbox,
-                "mailbox": "mailbox23",
+                "mailbox": mail_box,
             },
         )
         self.assertTrue(form.is_valid())
         form.save(commit=True)
-        self.assertEqual(mail_domain, instance.domain)
+        self.assertEqual(self.mail_domain, self.instance.domain)
 
-    @skip("does not work because it will create a real mailbox")
     def test_save_with_other_choice(self):
-        mail_domain = MailDomain.objects.create(domain="example.org")
-
-        instance = MailAddress()
-        os_user = osusers.models.User(username="testuser")
-        hosting_package = MagicMock(id=42, osuser=os_user)
-
-        mail_box = Mailbox.objects.create(osuser=os_user, username="mailbox23")
-        mail_box.set_password("test")
+        mail_box = create_test_mailbox(os_user=self.os_user)
 
         form = AddMailAddressForm(
-            instance=instance,
-            hostingpackage=hosting_package,
-            maildomain=mail_domain,
+            instance=self.instance,
+            hostingpackage=self.hosting_package,
+            maildomain=self.mail_domain,
             data={
                 "localpart": "test",
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.mailbox,
-                "mailbox": "mailbox23",
+                "mailbox": mail_box,
             },
         )
         self.assertTrue(form.is_valid())
@@ -366,82 +329,78 @@ class AddMailAddressFormTest(TestCase):
         form.save(commit=True)
 
 
-class EditMailAddressFormTest(TestCase):
-    def test_constructor_needs_hostingpackage(self):
+def create_test_hosting_package(os_user=None):
+    if os_user is None:
+        os_user = create_test_user()
+
+    return MagicMock(id=42, osuser=os_user)
+
+
+class EditMailAddressFormTest(TestCaseWithCeleryTasks):
+    def setUp(self) -> None:
+        super().setUp()
+        self.os_user = create_test_user()
+        self.hosting_package = create_test_hosting_package(os_user=self.os_user)
+        self.mail_domain = create_test_mail_domain()
+        self.instance = MailAddress.objects.create(localpart="test", domain=self.mail_domain)
+
+    def test_constructor_needs_hosting_package(self):
         instance = MagicMock()
         with self.assertRaises(KeyError):
             EditMailAddressForm(instance=instance, maildomain=MagicMock())
 
-    def test_constructor_needs_maildomain(self):
+    def test_constructor_needs_mail_domain(self):
         instance = MagicMock()
         with self.assertRaises(KeyError):
             EditMailAddressForm(instance=instance, hostingpackage=MagicMock())
 
     def test_constructor(self):
-        instance = MailAddress(id=23)
-        osuser = osusers.models.User(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MailDomain.objects.create(domain="example.org")
         form = EditMailAddressForm(
-            instance=instance, maildomain=maildomain, hostingpackage=hostingpackage
+            instance=self.instance, maildomain=self.mail_domain, hostingpackage=self.hosting_package
         )
         self.assertIn("mailbox_or_forwards", form.fields)
         self.assertIn("mailbox", form.fields)
         self.assertIn("forwards", form.fields)
         self.assertTrue(hasattr(form, "hosting_package"))
-        self.assertEqual(form.hosting_package, hostingpackage)
+        self.assertEqual(form.hosting_package, self.hosting_package)
         self.assertTrue(hasattr(form, "maildomain"))
-        self.assertEqual(form.maildomain, maildomain)
+        self.assertEqual(form.maildomain, self.mail_domain)
         self.assertTrue(hasattr(form, "helper"))
         self.assertEqual(
             form.helper.form_action,
             reverse(
                 "edit_mailaddress",
-                kwargs={"package": 42, "domain": "example.org", "pk": 23},
+                kwargs={"package": 42, "domain": "example.org", "pk": self.instance.pk},
             ),
         )
         self.assertEqual(len(form.helper.layout), 2)
         self.assertEqual(form.helper.layout[1].name, "submit")
 
-    @skip("needs mailbox refactoring")
     def test_clean_no_mailbox_choice(self):
-        instance = MagicMock(id=23)
-        osuser = Mock(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
         form = EditMailAddressForm(
-            instance=instance,
-            maildomain=maildomain,
-            hostingpackage=hostingpackage,
+            instance=self.instance,
+            maildomain=self.mail_domain,
+            hostingpackage=self.hosting_package,
             data={"mailbox_or_forwards": MAILBOX_OR_FORWARDS.mailbox},
         )
         self.assertFalse(form.is_valid())
         self.assertIn("mailbox", form.errors)
 
-    @skip("needs mailbox refactoring")
     def test_clean_no_forward_address_choice(self):
-        instance = MagicMock(id=23)
-        osuser = Mock(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
         form = EditMailAddressForm(
-            instance=instance,
-            maildomain=maildomain,
-            hostingpackage=hostingpackage,
+            instance=self.instance,
+            maildomain=self.mail_domain,
+            hostingpackage=self.hosting_package,
             data={"mailbox_or_forwards": MAILBOX_OR_FORWARDS.forwards},
         )
         self.assertFalse(form.is_valid())
         self.assertIn("forwards", form.errors)
 
     def test_save_with_forwards_no_commit(self):
-        maildomain = MailDomain.objects.create(domain="example.org")
-        instance = MailAddress(id=23, domain=maildomain)
-        osuser = osusers.models.User(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
         form = EditMailAddressForm(
-            instance=instance,
-            maildomain=maildomain,
-            hostingpackage=hostingpackage,
+            instance=self.instance,
+            maildomain=self.mail_domain,
+            hostingpackage=self.hosting_package,
             data={
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.forwards,
                 "forwards": "test2@example.org,test3@example.org",
@@ -451,15 +410,10 @@ class EditMailAddressFormTest(TestCase):
         form.save(commit=False)
 
     def test_save_with_forwards_commit(self):
-        osuser = osusers.models.User(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
-        mail_domain = MailDomain.objects.create(domain="example.org")
-        instance = MailAddress(id=23, domain=mail_domain)
-
         form = EditMailAddressForm(
-            instance=instance,
-            maildomain=mail_domain,
-            hostingpackage=hostingpackage,
+            instance=self.instance,
+            maildomain=self.mail_domain,
+            hostingpackage=self.hosting_package,
             data={
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.forwards,
                 "forwards": "test2@example.org,test3@example.org",
@@ -468,64 +422,55 @@ class EditMailAddressFormTest(TestCase):
         self.assertTrue(form.is_valid())
         form.save(commit=True)
 
-    @skip("needs mailbox refactoring")
     def test_save_with_mailbox_no_commit(self):
-        instance = MagicMock(id=23)
-        osuser = Mock(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
-        maildomain = MagicMock(domain="example.org")
+        mail_box = create_test_mailbox(os_user=self.os_user)
+
         form = EditMailAddressForm(
-            instance=instance,
-            maildomain=maildomain,
-            hostingpackage=hostingpackage,
+            instance=self.instance,
+            maildomain=self.mail_domain,
+            hostingpackage=self.hosting_package,
             data={
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.mailbox,
-                "mailbox": "mailbox23",
+                "mailbox": mail_box,
             },
         )
         self.assertTrue(form.is_valid())
-        mailbox = MagicMock(osuser=osuser, username="testuserp01")
-        instance.set_mailbox.return_value = mailbox
         form.save(commit=False)
-        instance.set_mailbox.assert_called_with(ANY, False)
-        mailbox.save.assert_not_called()
-        instance.save.assert_not_called()
 
-    @skip("needs mailbox refactoring")
+        self.instance.refresh_from_db()
+        self.assertFalse(hasattr(self.instance, "mailaddressmailbox"))
+
     def test_save_with_mailbox_commit(self):
-        instance = MailAddress(id=23)
-        osuser = osusers.models.User(username="testuser")
-        hostingpackage = MagicMock(id=42, osuser=osuser)
-        mail_domain = MailDomain.objects.create(domain="example.org")
+        mail_box = create_test_mailbox(os_user=self.os_user)
+
         form = EditMailAddressForm(
-            instance=instance,
-            maildomain=mail_domain,
-            hostingpackage=hostingpackage,
+            instance=self.instance,
+            maildomain=self.mail_domain,
+            hostingpackage=self.hosting_package,
             data={
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.mailbox,
-                "mailbox": "mailbox23",
+                "mailbox": mail_box,
             },
         )
         self.assertTrue(form.is_valid())
         form.save(commit=True)
 
-    @skip("needs mailbox refactoring")
+        self.instance.refresh_from_db()
+        self.assertEqual(self.instance.mailaddressmailbox.mailbox, mail_box)
+
     def test_save_with_other_choice(self):
-        mail_domain = MailDomain.objects.create(domain="example.org")
-        instance = MailAddress(id=23, domain=mail_domain)
-        os_user = osusers.models.User(username="testuser")
-        hosting_package = MagicMock(id=42, osuser=os_user)
+        mail_box = create_test_mailbox(os_user=self.os_user)
+
         form = EditMailAddressForm(
-            instance=instance,
-            maildomain=mail_domain,
-            hostingpackage=hosting_package,
+            instance=self.instance,
+            maildomain=self.mail_domain,
+            hostingpackage=self.hosting_package,
             data={
                 "mailbox_or_forwards": MAILBOX_OR_FORWARDS.mailbox,
-                "mailbox": "mailbox23",
+                "mailbox": mail_box,
             },
         )
         self.assertTrue(form.is_valid())
+
         form.cleaned_data["mailbox_or_forwards"] = -1
         form.save(commit=True)
-        instance.set_mailbox.assert_not_called()
-        instance.save.assert_called_with()
diff --git a/gnuviechadmin/osusers/tests/testutils.py b/gnuviechadmin/osusers/tests/testutils.py
new file mode 100644
index 0000000..dcee73e
--- /dev/null
+++ b/gnuviechadmin/osusers/tests/testutils.py
@@ -0,0 +1,13 @@
+from django.contrib import auth
+
+from osusers.models import User
+
+
+def create_test_customer():
+    customer_model = auth.get_user_model()
+    return customer_model.objects.create_user("test_customer", "testuser@example.org", "test_password")
+
+
+def create_test_user():
+    customer = create_test_customer()
+    return User.objects.create_user(customer)
From d2f94c7bec2c497cc6b6050d88b0244caaef0e86 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sun, 19 Feb 2023 15:53:00 +0100
Subject: [PATCH 09/46] Fix Dockerfile for poetry
---
 Dockerfile | 68 ++++++++++++++++++++++++++++++++----------------------
 gva.sh     |  2 +-
 2 files changed, 41 insertions(+), 29 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index 53ba4cc..be47096 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,51 +1,63 @@
 ARG DEBIAN_RELEASE=buster
-FROM debian:$DEBIAN_RELEASE
-LABEL maintainer="Jan Dittberner "
+FROM debian:$DEBIAN_RELEASE AS builder
+
+ARG GVAAPP=gva
+ARG POETRY_VERSION=1.3.1
 
 ENV LC_ALL=C.UTF-8
 ENV LANG=C.UTF-8
+ENV DEBIAN_FRONTEND=noninteractive
 
 RUN apt-get update \
-    && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
-    build-essential \
-    dumb-init \
-    gettext \
-    git \
-    python3-dev \
-    python3-pip \
-    python3-setuptools \
-    python3-virtualenv \
-    python3-wheel \
-    && apt-get clean \
-    && rm -rf /var/lib/apt/lists/*.*
+    && apt-get install -y --no-install-recommends \
+      build-essential \
+      curl \
+      git \
+      libpq-dev \
+      python3-dev \
+      python3-setuptools \
+      python3-virtualenv \
+      python3-wheel
 
-RUN python3 -m pip install --prefix=/usr/local pipenv
+RUN curl -sSL https://install.python-poetry.org | POETRY_HOME=/root/.local POETRY_VERSION=$POETRY_VERSION python3 - \
+    && /root/.local/bin/poetry config virtualenvs.in-project true
+
+WORKDIR /srv/$GVAAPP
+
+COPY poetry.lock pyproject.toml /srv/$GVAAPP/
+
+RUN /root/.local/bin/poetry install --only=main
+
+FROM debian:$DEBIAN_RELEASE
+LABEL maintainer="Jan Dittberner "
 
 RUN apt-get update \
-    && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
-    libpq-dev \
-    postgresql-client \
+    && apt-get install -y --no-install-recommends \
+       ca-certificates \
+       dumb-init \
+       gettext \
+       postgresql-client \
+       python3 \
+       python3-pip \
+       python3-wheel \
     && apt-get clean \
-    && rm -rf /var/lib/apt/lists/*.*
-
-ARG GVAGID=2000
-ARG GVAUID=2000
+    && rm -rf /var/cache/apt/archives /var/lib/apt/lists/*
 
 ARG GVAAPP=gva
+ARG GVAGID=2000
+ARG GVAUID=2000
 
 VOLUME /srv/$GVAAPP/media /srv/$GVAAPP/static
 
 WORKDIR /srv/$GVAAPP
 
-COPY Pipfile Pipfile.lock /srv/$GVAAPP/
-
 RUN addgroup --gid $GVAGID $GVAAPP ; \
-    adduser --home /home/$GVAAPP --shell /bin/bash --uid $GVAUID --gid $GVAGID --disabled-password --gecos "User for gnuviechadmin component $GVAAPP" $GVAAPP
+    adduser --home /home/$GVAAPP --shell /bin/bash --uid $GVAUID --gid $GVAGID --disabled-password \
+            --gecos "User for gnuviechadmin component $GVAAPP" $GVAAPP
+
+COPY --chown=$GVAAPP:$GVAAPP --from=builder /srv/$GVAAPP/.venv /srv/$GVAAPP/.venv
 
 USER $GVAAPP
-RUN python3 -m virtualenv --python=python3 /home/$GVAAPP/$GVAAPP-venv ; \
-    /home/$GVAAPP/$GVAAPP-venv/bin/python3 -m pip install -U pip ; \
-    VIRTUAL_ENV=/home/$GVAAPP/$GVAAPP-venv pipenv install --deploy --ignore-pipfile --dev
 
 VOLUME /srv/$GVAAPP
 
diff --git a/gva.sh b/gva.sh
index 4b0f3c2..3ca009c 100755
--- a/gva.sh
+++ b/gva.sh
@@ -15,7 +15,7 @@ done
 
 echo " db is ready"
 
-. /home/gva/gva-venv/bin/activate
+. /srv/gva/.venv/bin/activate
 cd /srv/gva/gnuviechadmin
 python3 manage.py compilemessages
 python3 manage.py collectstatic --noinput
From 38dae51a7aea8baf8c689c2aed9dc7ce20e24d85 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sun, 19 Feb 2023 17:48:25 +0100
Subject: [PATCH 10/46] Unify with gvaldap/gvaweb
---
 Dockerfile | 8 ++++++--
 gva.sh     | 3 ++-
 2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index be47096..1cd97eb 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -31,6 +31,10 @@ RUN /root/.local/bin/poetry install --only=main
 FROM debian:$DEBIAN_RELEASE
 LABEL maintainer="Jan Dittberner "
 
+ENV LC_ALL=C.UTF-8
+ENV LANG=C.UTF-8
+ENV DEBIAN_FRONTEND=noninteractive
+
 RUN apt-get update \
     && apt-get install -y --no-install-recommends \
        ca-certificates \
@@ -63,6 +67,6 @@ VOLUME /srv/$GVAAPP
 
 EXPOSE 8000
 
-COPY gva.sh /srv/
+COPY ${GVAAPP}.sh /srv/
 
-ENTRYPOINT ["dumb-init", "/srv/gva.sh"]
+ENTRYPOINT ["dumb-init", "/srv/${GVAAPP}.sh"]
diff --git a/gva.sh b/gva.sh
index 3ca009c..2314974 100755
--- a/gva.sh
+++ b/gva.sh
@@ -7,8 +7,9 @@ DB_PORT="${GVA_PGSQL_PORT:-5432}"
 DB_USER="${GVA_PGSQL_USER:-gnuviechadmin}"
 DB_NAME="${GVA_PGSQL_DATABASE:-gnuviechadmin}"
 
-until pg_isready -q -h "${DB_HOST}" -p "${DB_PORT}" -U "${PG_USER}" -d "${DB_NAME}"
+until pg_isready -q -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}"
 do
+  # shellcheck disable=SC2039
   echo -n "."
   sleep 1
 done
From f89de16f6e953d5d868f4f1515b828848fb5301d Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Mon, 20 Feb 2023 15:39:14 +0100
Subject: [PATCH 11/46] Improve docker build
- add .dockerignore
- add entrypoint.sh to ensure proper permissions in Docker volumes
- add TZ variable for consistent Celery timestamps
---
 .dockerignore               | 18 ++++++++++++++++++
 Dockerfile                  | 14 ++++++--------
 docker-compose.yml          | 17 +++++++++--------
 docker/django_media/.empty  |  0
 docker/django_static/.empty |  0
 entrypoint.sh               |  7 +++++++
 gva.sh                      |  5 +++--
 7 files changed, 43 insertions(+), 18 deletions(-)
 create mode 100644 .dockerignore
 delete mode 100644 docker/django_media/.empty
 delete mode 100644 docker/django_static/.empty
 create mode 100755 entrypoint.sh
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..652558d
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,18 @@
+**/*.pyc
+**/.*.swp
+**/.coverage
+**/__pycache__
+.dockerignore
+.env
+.envrc
+.git
+.gitignore
+.idea
+.isort.cfg
+.vagrant
+Dockerfile
+Vagrantfile
+docker-compose.yml
+docs
+media
+static
diff --git a/Dockerfile b/Dockerfile
index 1cd97eb..93b979c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -51,22 +51,20 @@ ARG GVAAPP=gva
 ARG GVAGID=2000
 ARG GVAUID=2000
 
-VOLUME /srv/$GVAAPP/media /srv/$GVAAPP/static
-
-WORKDIR /srv/$GVAAPP
-
 RUN addgroup --gid $GVAGID $GVAAPP ; \
     adduser --home /home/$GVAAPP --shell /bin/bash --uid $GVAUID --gid $GVAGID --disabled-password \
             --gecos "User for gnuviechadmin component $GVAAPP" $GVAAPP
 
 COPY --chown=$GVAAPP:$GVAAPP --from=builder /srv/$GVAAPP/.venv /srv/$GVAAPP/.venv
 
-USER $GVAAPP
+WORKDIR /srv/$GVAAPP
 
-VOLUME /srv/$GVAAPP
+VOLUME /srv/$GVAAPP/media /srv/$GVAAPP/static
+
+VOLUME /srv/$GVAAPP/gnuviechadmin
 
 EXPOSE 8000
 
-COPY ${GVAAPP}.sh /srv/
+COPY ${GVAAPP}.sh entrypoint.sh /srv/
 
-ENTRYPOINT ["dumb-init", "/srv/${GVAAPP}.sh"]
+ENTRYPOINT ["dumb-init", "/srv/entrypoint.sh"]
diff --git a/docker-compose.yml b/docker-compose.yml
index dd174b0..4e611c1 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,3 +1,4 @@
+---
 version: "3"
 services:
   db:
@@ -36,9 +37,9 @@ services:
       GVA_DOMAIN_NAME: localhost
       GVA_SITE_NAME: localhost
     volumes:
-      - "./docker/django_media:/srv/gva/media"
-      - "./docker/django_static:/srv/gva/static"
-      - ".:/srv/gva"
+      - "django_media:/srv/gva/media"
+      - "django_static:/srv/gva/static"
+      - "./gnuviechadmin:/srv/gva/gnuviechadmin"
   web:
     image: gnuviech/gvaweb:buster
     build:
@@ -51,7 +52,7 @@ services:
       - redis
     env_file: ../gvaweb/.env
     volumes:
-      - "../gvaweb:/srv/gvaweb"
+      - "../gvaweb/gvaweb:/srv/gvaweb/gvaweb"
   ldap:
     image: gnuviech/gvaldap:buster
     build:
@@ -64,7 +65,7 @@ services:
       - redis
     env_file: ../gvaldap/.env
     volumes:
-      - "../gvaldap:/srv/gvaldap"
+      - "../gvaldap/gvaldap:/srv/gvaldap/gvaldap"
   file:
     image: gnuviech/gvafile:buster
     build:
@@ -77,7 +78,7 @@ services:
       - redis
     env_file: ../gvafile/.env
     volumes:
-      - "../gvafile:/srv/gvafile"
+      - "../gvafile/gvafile:/srv/gvafile/gvafile"
   pgsql:
     image: gnuviech/gvapgsql:buster
     build:
@@ -90,7 +91,7 @@ services:
       - redis
     env_file: ../gvapgsql/.env
     volumes:
-      - "../gvapgsql:/srv/gvapgsql"
+      - "../gvapgsql/gvapgsql:/srv/gvapgsql/gvapgsql"
   mysql:
     image: gnuviech/gvamysql:buster
     build:
@@ -103,7 +104,7 @@ services:
       - redis
     env_file: ../gvamysql/.env
     volumes:
-      - "../gvamysql:/srv/gvamysql"
+      - "../gvamysql/gvamysql:/srv/gvamysql/gvamysql"
 volumes:
   django_media:
   django_static:
diff --git a/docker/django_media/.empty b/docker/django_media/.empty
deleted file mode 100644
index e69de29..0000000
diff --git a/docker/django_static/.empty b/docker/django_static/.empty
deleted file mode 100644
index e69de29..0000000
diff --git a/entrypoint.sh b/entrypoint.sh
new file mode 100755
index 0000000..b8e2187
--- /dev/null
+++ b/entrypoint.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+set -e
+
+chown -Rc gva.gva /srv/gva/media /srv/gva/static
+
+su -c /srv/gva.sh gva
diff --git a/gva.sh b/gva.sh
index 2314974..f8c0ce4 100755
--- a/gva.sh
+++ b/gva.sh
@@ -14,11 +14,12 @@ do
   sleep 1
 done
 
-echo " db is ready"
+echo ". db is ready"
+
+export TZ="Europe/Berlin"
 
 . /srv/gva/.venv/bin/activate
 cd /srv/gva/gnuviechadmin
-python3 manage.py compilemessages
 python3 manage.py collectstatic --noinput
 python3 manage.py migrate --noinput
 python3 manage.py runserver 0.0.0.0:8000
From 3452e2a8c2b55088f6d75b09c3b7c0b8e5003b89 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Fri, 14 Apr 2023 18:43:11 +0200
Subject: [PATCH 12/46] Update dependencies
---
 poetry.lock | 753 +++++++++++++++++++++++++---------------------------
 1 file changed, 360 insertions(+), 393 deletions(-)
diff --git a/poetry.lock b/poetry.lock
index a57a7e4..876312e 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -62,18 +62,18 @@ typing-extensions = {version = ">=3.6.5", markers = "python_version < \"3.8\""}
 
 [[package]]
 name = "babel"
-version = "2.11.0"
+version = "2.12.1"
 description = "Internationalization utilities"
 category = "dev"
 optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.7"
 files = [
-    {file = "Babel-2.11.0-py3-none-any.whl", hash = "sha256:1ad3eca1c885218f6dce2ab67291178944f810a10a9b5f3cb8382a5a232b64fe"},
-    {file = "Babel-2.11.0.tar.gz", hash = "sha256:5ef4b3226b0180dedded4229651c8b0e1a3a6a2837d45a073272f313e4cf97f6"},
+    {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"},
+    {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"},
 ]
 
 [package.dependencies]
-pytz = ">=2015.7"
+pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""}
 
 [[package]]
 name = "billiard"
@@ -89,37 +89,37 @@ files = [
 
 [[package]]
 name = "black"
-version = "23.1.0"
+version = "23.3.0"
 description = "The uncompromising code formatter."
 category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "black-23.1.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:b6a92a41ee34b883b359998f0c8e6eb8e99803aa8bf3123bf2b2e6fec505a221"},
-    {file = "black-23.1.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:57c18c5165c1dbe291d5306e53fb3988122890e57bd9b3dcb75f967f13411a26"},
-    {file = "black-23.1.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:9880d7d419bb7e709b37e28deb5e68a49227713b623c72b2b931028ea65f619b"},
-    {file = "black-23.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6663f91b6feca5d06f2ccd49a10f254f9298cc1f7f49c46e498a0771b507104"},
-    {file = "black-23.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:9afd3f493666a0cd8f8df9a0200c6359ac53940cbde049dcb1a7eb6ee2dd7074"},
-    {file = "black-23.1.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:bfffba28dc52a58f04492181392ee380e95262af14ee01d4bc7bb1b1c6ca8d27"},
-    {file = "black-23.1.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c1c476bc7b7d021321e7d93dc2cbd78ce103b84d5a4cf97ed535fbc0d6660648"},
-    {file = "black-23.1.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:382998821f58e5c8238d3166c492139573325287820963d2f7de4d518bd76958"},
-    {file = "black-23.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bf649fda611c8550ca9d7592b69f0637218c2369b7744694c5e4902873b2f3a"},
-    {file = "black-23.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:121ca7f10b4a01fd99951234abdbd97728e1240be89fde18480ffac16503d481"},
-    {file = "black-23.1.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:a8471939da5e824b891b25751955be52ee7f8a30a916d570a5ba8e0f2eb2ecad"},
-    {file = "black-23.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8178318cb74f98bc571eef19068f6ab5613b3e59d4f47771582f04e175570ed8"},
-    {file = "black-23.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a436e7881d33acaf2536c46a454bb964a50eff59b21b51c6ccf5a40601fbef24"},
-    {file = "black-23.1.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:a59db0a2094d2259c554676403fa2fac3473ccf1354c1c63eccf7ae65aac8ab6"},
-    {file = "black-23.1.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:0052dba51dec07ed029ed61b18183942043e00008ec65d5028814afaab9a22fd"},
-    {file = "black-23.1.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:49f7b39e30f326a34b5c9a4213213a6b221d7ae9d58ec70df1c4a307cf2a1580"},
-    {file = "black-23.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:162e37d49e93bd6eb6f1afc3e17a3d23a823042530c37c3c42eeeaf026f38468"},
-    {file = "black-23.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b70eb40a78dfac24842458476135f9b99ab952dd3f2dab738c1881a9b38b753"},
-    {file = "black-23.1.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:a29650759a6a0944e7cca036674655c2f0f63806ddecc45ed40b7b8aa314b651"},
-    {file = "black-23.1.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:bb460c8561c8c1bec7824ecbc3ce085eb50005883a6203dcfb0122e95797ee06"},
-    {file = "black-23.1.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:c91dfc2c2a4e50df0026f88d2215e166616e0c80e86004d0003ece0488db2739"},
-    {file = "black-23.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a951cc83ab535d248c89f300eccbd625e80ab880fbcfb5ac8afb5f01a258ac9"},
-    {file = "black-23.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:0680d4380db3719ebcfb2613f34e86c8e6d15ffeabcf8ec59355c5e7b85bb555"},
-    {file = "black-23.1.0-py3-none-any.whl", hash = "sha256:7a0f701d314cfa0896b9001df70a530eb2472babb76086344e688829efd97d32"},
-    {file = "black-23.1.0.tar.gz", hash = "sha256:b0bd97bea8903f5a2ba7219257a44e3f1f9d00073d6cc1add68f0beec69692ac"},
+    {file = "black-23.3.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915"},
+    {file = "black-23.3.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9"},
+    {file = "black-23.3.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2"},
+    {file = "black-23.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c"},
+    {file = "black-23.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c"},
+    {file = "black-23.3.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6"},
+    {file = "black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"},
+    {file = "black-23.3.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d"},
+    {file = "black-23.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70"},
+    {file = "black-23.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326"},
+    {file = "black-23.3.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b"},
+    {file = "black-23.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2"},
+    {file = "black-23.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925"},
+    {file = "black-23.3.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27"},
+    {file = "black-23.3.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331"},
+    {file = "black-23.3.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5"},
+    {file = "black-23.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961"},
+    {file = "black-23.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8"},
+    {file = "black-23.3.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30"},
+    {file = "black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"},
+    {file = "black-23.3.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266"},
+    {file = "black-23.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab"},
+    {file = "black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"},
+    {file = "black-23.3.0-py3-none-any.whl", hash = "sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4"},
+    {file = "black-23.3.0.tar.gz", hash = "sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940"},
 ]
 
 [package.dependencies]
@@ -320,100 +320,87 @@ pycparser = "*"
 
 [[package]]
 name = "charset-normalizer"
-version = "3.0.1"
+version = "3.1.0"
 description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
 category = "main"
 optional = false
-python-versions = "*"
+python-versions = ">=3.7.0"
 files = [
-    {file = "charset-normalizer-3.0.1.tar.gz", hash = "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f"},
-    {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6"},
-    {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db"},
-    {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539"},
-    {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d"},
-    {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8"},
-    {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e"},
-    {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d"},
-    {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783"},
-    {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555"},
-    {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639"},
-    {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76"},
-    {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6"},
-    {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e"},
-    {file = "charset_normalizer-3.0.1-cp310-cp310-win32.whl", hash = "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b"},
-    {file = "charset_normalizer-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59"},
-    {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d"},
-    {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3"},
-    {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c"},
-    {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b"},
-    {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1"},
-    {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317"},
-    {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603"},
-    {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18"},
-    {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a"},
-    {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7"},
-    {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc"},
-    {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b"},
-    {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6"},
-    {file = "charset_normalizer-3.0.1-cp311-cp311-win32.whl", hash = "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3"},
-    {file = "charset_normalizer-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c"},
-    {file = "charset_normalizer-3.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a"},
-    {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea"},
-    {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72"},
-    {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478"},
-    {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d"},
-    {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837"},
-    {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6"},
-    {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc"},
-    {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a"},
-    {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c"},
-    {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a"},
-    {file = "charset_normalizer-3.0.1-cp36-cp36m-win32.whl", hash = "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41"},
-    {file = "charset_normalizer-3.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602"},
-    {file = "charset_normalizer-3.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14"},
-    {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d"},
-    {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc"},
-    {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3"},
-    {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866"},
-    {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b"},
-    {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087"},
-    {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8"},
-    {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b"},
-    {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918"},
-    {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d"},
-    {file = "charset_normalizer-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154"},
-    {file = "charset_normalizer-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5"},
-    {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42"},
-    {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c"},
-    {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e"},
-    {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58"},
-    {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174"},
-    {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753"},
-    {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b"},
-    {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1"},
-    {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a"},
-    {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed"},
-    {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479"},
-    {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291"},
-    {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820"},
-    {file = "charset_normalizer-3.0.1-cp38-cp38-win32.whl", hash = "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e"},
-    {file = "charset_normalizer-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af"},
-    {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f"},
-    {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678"},
-    {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be"},
-    {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b"},
-    {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca"},
-    {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e"},
-    {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3"},
-    {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541"},
-    {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d"},
-    {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579"},
-    {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4"},
-    {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c"},
-    {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786"},
-    {file = "charset_normalizer-3.0.1-cp39-cp39-win32.whl", hash = "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8"},
-    {file = "charset_normalizer-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59"},
-    {file = "charset_normalizer-3.0.1-py3-none-any.whl", hash = "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24"},
+    {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"},
+    {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"},
+    {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"},
+    {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"},
+    {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"},
+    {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"},
+    {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"},
 ]
 
 [[package]]
@@ -496,63 +483,63 @@ files = [
 
 [[package]]
 name = "coverage"
-version = "7.1.0"
+version = "7.2.3"
 description = "Code coverage measurement for Python"
 category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "coverage-7.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3b946bbcd5a8231383450b195cfb58cb01cbe7f8949f5758566b881df4b33baf"},
-    {file = "coverage-7.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec8e767f13be637d056f7e07e61d089e555f719b387a7070154ad80a0ff31801"},
-    {file = "coverage-7.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4a5a5879a939cb84959d86869132b00176197ca561c664fc21478c1eee60d75"},
-    {file = "coverage-7.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b643cb30821e7570c0aaf54feaf0bfb630b79059f85741843e9dc23f33aaca2c"},
-    {file = "coverage-7.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32df215215f3af2c1617a55dbdfb403b772d463d54d219985ac7cd3bf124cada"},
-    {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:33d1ae9d4079e05ac4cc1ef9e20c648f5afabf1a92adfaf2ccf509c50b85717f"},
-    {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:29571503c37f2ef2138a306d23e7270687c0efb9cab4bd8038d609b5c2393a3a"},
-    {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:63ffd21aa133ff48c4dff7adcc46b7ec8b565491bfc371212122dd999812ea1c"},
-    {file = "coverage-7.1.0-cp310-cp310-win32.whl", hash = "sha256:4b14d5e09c656de5038a3f9bfe5228f53439282abcab87317c9f7f1acb280352"},
-    {file = "coverage-7.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:8361be1c2c073919500b6601220a6f2f98ea0b6d2fec5014c1d9cfa23dd07038"},
-    {file = "coverage-7.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:da9b41d4539eefd408c46725fb76ecba3a50a3367cafb7dea5f250d0653c1040"},
-    {file = "coverage-7.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5b15ed7644ae4bee0ecf74fee95808dcc34ba6ace87e8dfbf5cb0dc20eab45a"},
-    {file = "coverage-7.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d12d076582507ea460ea2a89a8c85cb558f83406c8a41dd641d7be9a32e1274f"},
-    {file = "coverage-7.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2617759031dae1bf183c16cef8fcfb3de7617f394c813fa5e8e46e9b82d4222"},
-    {file = "coverage-7.1.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4e4881fa9e9667afcc742f0c244d9364d197490fbc91d12ac3b5de0bf2df146"},
-    {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9d58885215094ab4a86a6aef044e42994a2bd76a446dc59b352622655ba6621b"},
-    {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ffeeb38ee4a80a30a6877c5c4c359e5498eec095878f1581453202bfacc8fbc2"},
-    {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3baf5f126f30781b5e93dbefcc8271cb2491647f8283f20ac54d12161dff080e"},
-    {file = "coverage-7.1.0-cp311-cp311-win32.whl", hash = "sha256:ded59300d6330be27bc6cf0b74b89ada58069ced87c48eaf9344e5e84b0072f7"},
-    {file = "coverage-7.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:6a43c7823cd7427b4ed763aa7fb63901ca8288591323b58c9cd6ec31ad910f3c"},
-    {file = "coverage-7.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7a726d742816cb3a8973c8c9a97539c734b3a309345236cd533c4883dda05b8d"},
-    {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc7c85a150501286f8b56bd8ed3aa4093f4b88fb68c0843d21ff9656f0009d6a"},
-    {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b4198d85a3755d27e64c52f8c95d6333119e49fd001ae5798dac872c95e0f8"},
-    {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddb726cb861c3117a553f940372a495fe1078249ff5f8a5478c0576c7be12050"},
-    {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:51b236e764840a6df0661b67e50697aaa0e7d4124ca95e5058fa3d7cbc240b7c"},
-    {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7ee5c9bb51695f80878faaa5598040dd6c9e172ddcf490382e8aedb8ec3fec8d"},
-    {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c31b75ae466c053a98bf26843563b3b3517b8f37da4d47b1c582fdc703112bc3"},
-    {file = "coverage-7.1.0-cp37-cp37m-win32.whl", hash = "sha256:3b155caf3760408d1cb903b21e6a97ad4e2bdad43cbc265e3ce0afb8e0057e73"},
-    {file = "coverage-7.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2a60d6513781e87047c3e630b33b4d1e89f39836dac6e069ffee28c4786715f5"},
-    {file = "coverage-7.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2cba5c6db29ce991029b5e4ac51eb36774458f0a3b8d3137241b32d1bb91f06"},
-    {file = "coverage-7.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beeb129cacea34490ffd4d6153af70509aa3cda20fdda2ea1a2be870dfec8d52"},
-    {file = "coverage-7.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c45948f613d5d18c9ec5eaa203ce06a653334cf1bd47c783a12d0dd4fd9c851"},
-    {file = "coverage-7.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef382417db92ba23dfb5864a3fc9be27ea4894e86620d342a116b243ade5d35d"},
-    {file = "coverage-7.1.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c7c0d0827e853315c9bbd43c1162c006dd808dbbe297db7ae66cd17b07830f0"},
-    {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e5cdbb5cafcedea04924568d990e20ce7f1945a1dd54b560f879ee2d57226912"},
-    {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9817733f0d3ea91bea80de0f79ef971ae94f81ca52f9b66500c6a2fea8e4b4f8"},
-    {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:218fe982371ac7387304153ecd51205f14e9d731b34fb0568181abaf7b443ba0"},
-    {file = "coverage-7.1.0-cp38-cp38-win32.whl", hash = "sha256:04481245ef966fbd24ae9b9e537ce899ae584d521dfbe78f89cad003c38ca2ab"},
-    {file = "coverage-7.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:8ae125d1134bf236acba8b83e74c603d1b30e207266121e76484562bc816344c"},
-    {file = "coverage-7.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2bf1d5f2084c3932b56b962a683074a3692bce7cabd3aa023c987a2a8e7612f6"},
-    {file = "coverage-7.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:98b85dd86514d889a2e3dd22ab3c18c9d0019e696478391d86708b805f4ea0fa"},
-    {file = "coverage-7.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38da2db80cc505a611938d8624801158e409928b136c8916cd2e203970dde4dc"},
-    {file = "coverage-7.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3164d31078fa9efe406e198aecd2a02d32a62fecbdef74f76dad6a46c7e48311"},
-    {file = "coverage-7.1.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db61a79c07331e88b9a9974815c075fbd812bc9dbc4dc44b366b5368a2936063"},
-    {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ccb092c9ede70b2517a57382a601619d20981f56f440eae7e4d7eaafd1d1d09"},
-    {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:33ff26d0f6cc3ca8de13d14fde1ff8efe1456b53e3f0273e63cc8b3c84a063d8"},
-    {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d47dd659a4ee952e90dc56c97d78132573dc5c7b09d61b416a9deef4ebe01a0c"},
-    {file = "coverage-7.1.0-cp39-cp39-win32.whl", hash = "sha256:d248cd4a92065a4d4543b8331660121b31c4148dd00a691bfb7a5cdc7483cfa4"},
-    {file = "coverage-7.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:7ed681b0f8e8bcbbffa58ba26fcf5dbc8f79e7997595bf071ed5430d8c08d6f3"},
-    {file = "coverage-7.1.0-pp37.pp38.pp39-none-any.whl", hash = "sha256:755e89e32376c850f826c425ece2c35a4fc266c081490eb0a841e7c1cb0d3bda"},
-    {file = "coverage-7.1.0.tar.gz", hash = "sha256:10188fe543560ec4874f974b5305cd1a8bdcfa885ee00ea3a03733464c4ca265"},
+    {file = "coverage-7.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e58c0d41d336569d63d1b113bd573db8363bc4146f39444125b7f8060e4e04f5"},
+    {file = "coverage-7.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:344e714bd0fe921fc72d97404ebbdbf9127bac0ca1ff66d7b79efc143cf7c0c4"},
+    {file = "coverage-7.2.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:974bc90d6f6c1e59ceb1516ab00cf1cdfbb2e555795d49fa9571d611f449bcb2"},
+    {file = "coverage-7.2.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0743b0035d4b0e32bc1df5de70fba3059662ace5b9a2a86a9f894cfe66569013"},
+    {file = "coverage-7.2.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d0391fb4cfc171ce40437f67eb050a340fdbd0f9f49d6353a387f1b7f9dd4fa"},
+    {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a42e1eff0ca9a7cb7dc9ecda41dfc7cbc17cb1d02117214be0561bd1134772b"},
+    {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:be19931a8dcbe6ab464f3339966856996b12a00f9fe53f346ab3be872d03e257"},
+    {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:72fcae5bcac3333a4cf3b8f34eec99cea1187acd55af723bcbd559adfdcb5535"},
+    {file = "coverage-7.2.3-cp310-cp310-win32.whl", hash = "sha256:aeae2aa38395b18106e552833f2a50c27ea0000122bde421c31d11ed7e6f9c91"},
+    {file = "coverage-7.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:83957d349838a636e768251c7e9979e899a569794b44c3728eaebd11d848e58e"},
+    {file = "coverage-7.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dfd393094cd82ceb9b40df4c77976015a314b267d498268a076e940fe7be6b79"},
+    {file = "coverage-7.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:182eb9ac3f2b4874a1f41b78b87db20b66da6b9cdc32737fbbf4fea0c35b23fc"},
+    {file = "coverage-7.2.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bb1e77a9a311346294621be905ea8a2c30d3ad371fc15bb72e98bfcfae532df"},
+    {file = "coverage-7.2.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca0f34363e2634deffd390a0fef1aa99168ae9ed2af01af4a1f5865e362f8623"},
+    {file = "coverage-7.2.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55416d7385774285b6e2a5feca0af9652f7f444a4fa3d29d8ab052fafef9d00d"},
+    {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:06ddd9c0249a0546997fdda5a30fbcb40f23926df0a874a60a8a185bc3a87d93"},
+    {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:fff5aaa6becf2c6a1699ae6a39e2e6fb0672c2d42eca8eb0cafa91cf2e9bd312"},
+    {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ea53151d87c52e98133eb8ac78f1206498c015849662ca8dc246255265d9c3c4"},
+    {file = "coverage-7.2.3-cp311-cp311-win32.whl", hash = "sha256:8f6c930fd70d91ddee53194e93029e3ef2aabe26725aa3c2753df057e296b925"},
+    {file = "coverage-7.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:fa546d66639d69aa967bf08156eb8c9d0cd6f6de84be9e8c9819f52ad499c910"},
+    {file = "coverage-7.2.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b2317d5ed777bf5a033e83d4f1389fd4ef045763141d8f10eb09a7035cee774c"},
+    {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be9824c1c874b73b96288c6d3de793bf7f3a597770205068c6163ea1f326e8b9"},
+    {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c3b2803e730dc2797a017335827e9da6da0e84c745ce0f552e66400abdfb9a1"},
+    {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f69770f5ca1994cb32c38965e95f57504d3aea96b6c024624fdd5bb1aa494a1"},
+    {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1127b16220f7bfb3f1049ed4a62d26d81970a723544e8252db0efde853268e21"},
+    {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:aa784405f0c640940595fa0f14064d8e84aff0b0f762fa18393e2760a2cf5841"},
+    {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3146b8e16fa60427e03884301bf8209221f5761ac754ee6b267642a2fd354c48"},
+    {file = "coverage-7.2.3-cp37-cp37m-win32.whl", hash = "sha256:1fd78b911aea9cec3b7e1e2622c8018d51c0d2bbcf8faaf53c2497eb114911c1"},
+    {file = "coverage-7.2.3-cp37-cp37m-win_amd64.whl", hash = "sha256:0f3736a5d34e091b0a611964c6262fd68ca4363df56185902528f0b75dbb9c1f"},
+    {file = "coverage-7.2.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:981b4df72c93e3bc04478153df516d385317628bd9c10be699c93c26ddcca8ab"},
+    {file = "coverage-7.2.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c0045f8f23a5fb30b2eb3b8a83664d8dc4fb58faddf8155d7109166adb9f2040"},
+    {file = "coverage-7.2.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f760073fcf8f3d6933178d67754f4f2d4e924e321f4bb0dcef0424ca0215eba1"},
+    {file = "coverage-7.2.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c86bd45d1659b1ae3d0ba1909326b03598affbc9ed71520e0ff8c31a993ad911"},
+    {file = "coverage-7.2.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:172db976ae6327ed4728e2507daf8a4de73c7cc89796483e0a9198fd2e47b462"},
+    {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d2a3a6146fe9319926e1d477842ca2a63fe99af5ae690b1f5c11e6af074a6b5c"},
+    {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f649dd53833b495c3ebd04d6eec58479454a1784987af8afb77540d6c1767abd"},
+    {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7c4ed4e9f3b123aa403ab424430b426a1992e6f4c8fd3cb56ea520446e04d152"},
+    {file = "coverage-7.2.3-cp38-cp38-win32.whl", hash = "sha256:eb0edc3ce9760d2f21637766c3aa04822030e7451981ce569a1b3456b7053f22"},
+    {file = "coverage-7.2.3-cp38-cp38-win_amd64.whl", hash = "sha256:63cdeaac4ae85a179a8d6bc09b77b564c096250d759eed343a89d91bce8b6367"},
+    {file = "coverage-7.2.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:20d1a2a76bb4eb00e4d36b9699f9b7aba93271c9c29220ad4c6a9581a0320235"},
+    {file = "coverage-7.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ea748802cc0de4de92ef8244dd84ffd793bd2e7be784cd8394d557a3c751e21"},
+    {file = "coverage-7.2.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21b154aba06df42e4b96fc915512ab39595105f6c483991287021ed95776d934"},
+    {file = "coverage-7.2.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd214917cabdd6f673a29d708574e9fbdb892cb77eb426d0eae3490d95ca7859"},
+    {file = "coverage-7.2.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c2e58e45fe53fab81f85474e5d4d226eeab0f27b45aa062856c89389da2f0d9"},
+    {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:87ecc7c9a1a9f912e306997ffee020297ccb5ea388421fe62a2a02747e4d5539"},
+    {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:387065e420aed3c71b61af7e82c7b6bc1c592f7e3c7a66e9f78dd178699da4fe"},
+    {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ea3f5bc91d7d457da7d48c7a732beaf79d0c8131df3ab278e6bba6297e23c6c4"},
+    {file = "coverage-7.2.3-cp39-cp39-win32.whl", hash = "sha256:ae7863a1d8db6a014b6f2ff9c1582ab1aad55a6d25bac19710a8df68921b6e30"},
+    {file = "coverage-7.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:3f04becd4fcda03c0160d0da9c8f0c246bc78f2f7af0feea1ec0930e7c93fa4a"},
+    {file = "coverage-7.2.3-pp37.pp38.pp39-none-any.whl", hash = "sha256:965ee3e782c7892befc25575fa171b521d33798132692df428a09efacaffe8d0"},
+    {file = "coverage-7.2.3.tar.gz", hash = "sha256:d298c2815fa4891edd9abe5ad6e6cb4207104c7dd9fd13aea3fdebf6f9b91259"},
 ]
 
 [package.extras]
@@ -560,35 +547,31 @@ toml = ["tomli"]
 
 [[package]]
 name = "cryptography"
-version = "39.0.1"
+version = "40.0.2"
 description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
 category = "main"
 optional = false
 python-versions = ">=3.6"
 files = [
-    {file = "cryptography-39.0.1-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:6687ef6d0a6497e2b58e7c5b852b53f62142cfa7cd1555795758934da363a965"},
-    {file = "cryptography-39.0.1-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:706843b48f9a3f9b9911979761c91541e3d90db1ca905fd63fee540a217698bc"},
-    {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:5d2d8b87a490bfcd407ed9d49093793d0f75198a35e6eb1a923ce1ee86c62b41"},
-    {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83e17b26de248c33f3acffb922748151d71827d6021d98c70e6c1a25ddd78505"},
-    {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e124352fd3db36a9d4a21c1aa27fd5d051e621845cb87fb851c08f4f75ce8be6"},
-    {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:5aa67414fcdfa22cf052e640cb5ddc461924a045cacf325cd164e65312d99502"},
-    {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:35f7c7d015d474f4011e859e93e789c87d21f6f4880ebdc29896a60403328f1f"},
-    {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f24077a3b5298a5a06a8e0536e3ea9ec60e4c7ac486755e5fb6e6ea9b3500106"},
-    {file = "cryptography-39.0.1-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:f0c64d1bd842ca2633e74a1a28033d139368ad959872533b1bab8c80e8240a0c"},
-    {file = "cryptography-39.0.1-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:0f8da300b5c8af9f98111ffd512910bc792b4c77392a9523624680f7956a99d4"},
-    {file = "cryptography-39.0.1-cp36-abi3-win32.whl", hash = "sha256:fe913f20024eb2cb2f323e42a64bdf2911bb9738a15dba7d3cce48151034e3a8"},
-    {file = "cryptography-39.0.1-cp36-abi3-win_amd64.whl", hash = "sha256:ced4e447ae29ca194449a3f1ce132ded8fcab06971ef5f618605aacaa612beac"},
-    {file = "cryptography-39.0.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:807ce09d4434881ca3a7594733669bd834f5b2c6d5c7e36f8c00f691887042ad"},
-    {file = "cryptography-39.0.1-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c5caeb8188c24888c90b5108a441c106f7faa4c4c075a2bcae438c6e8ca73cef"},
-    {file = "cryptography-39.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4789d1e3e257965e960232345002262ede4d094d1a19f4d3b52e48d4d8f3b885"},
-    {file = "cryptography-39.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:96f1157a7c08b5b189b16b47bc9db2332269d6680a196341bf30046330d15388"},
-    {file = "cryptography-39.0.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e422abdec8b5fa8462aa016786680720d78bdce7a30c652b7fadf83a4ba35336"},
-    {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:b0afd054cd42f3d213bf82c629efb1ee5f22eba35bf0eec88ea9ea7304f511a2"},
-    {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:6f8ba7f0328b79f08bdacc3e4e66fb4d7aab0c3584e0bd41328dce5262e26b2e"},
-    {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:ef8b72fa70b348724ff1218267e7f7375b8de4e8194d1636ee60510aae104cd0"},
-    {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:aec5a6c9864be7df2240c382740fcf3b96928c46604eaa7f3091f58b878c0bb6"},
-    {file = "cryptography-39.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fdd188c8a6ef8769f148f88f859884507b954cc64db6b52f66ef199bb9ad660a"},
-    {file = "cryptography-39.0.1.tar.gz", hash = "sha256:d1f6198ee6d9148405e49887803907fe8962a23e6c6f83ea7d98f1c0de375695"},
+    {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:8f79b5ff5ad9d3218afb1e7e20ea74da5f76943ee5edb7f76e56ec5161ec782b"},
+    {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:05dc219433b14046c476f6f09d7636b92a1c3e5808b9a6536adf4932b3b2c440"},
+    {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4df2af28d7bedc84fe45bd49bc35d710aede676e2a4cb7fc6d103a2adc8afe4d"},
+    {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dcca15d3a19a66e63662dc8d30f8036b07be851a8680eda92d079868f106288"},
+    {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:a04386fb7bc85fab9cd51b6308633a3c271e3d0d3eae917eebab2fac6219b6d2"},
+    {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:adc0d980fd2760c9e5de537c28935cc32b9353baaf28e0814df417619c6c8c3b"},
+    {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:d5a1bd0e9e2031465761dfa920c16b0065ad77321d8a8c1f5ee331021fda65e9"},
+    {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:a95f4802d49faa6a674242e25bfeea6fc2acd915b5e5e29ac90a32b1139cae1c"},
+    {file = "cryptography-40.0.2-cp36-abi3-win32.whl", hash = "sha256:aecbb1592b0188e030cb01f82d12556cf72e218280f621deed7d806afd2113f9"},
+    {file = "cryptography-40.0.2-cp36-abi3-win_amd64.whl", hash = "sha256:b12794f01d4cacfbd3177b9042198f3af1c856eedd0a98f10f141385c809a14b"},
+    {file = "cryptography-40.0.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:142bae539ef28a1c76794cca7f49729e7c54423f615cfd9b0b1fa90ebe53244b"},
+    {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:956ba8701b4ffe91ba59665ed170a2ebbdc6fc0e40de5f6059195d9f2b33ca0e"},
+    {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4f01c9863da784558165f5d4d916093737a75203a5c5286fde60e503e4276c7a"},
+    {file = "cryptography-40.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3daf9b114213f8ba460b829a02896789751626a2a4e7a43a28ee77c04b5e4958"},
+    {file = "cryptography-40.0.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48f388d0d153350f378c7f7b41497a54ff1513c816bcbbcafe5b829e59b9ce5b"},
+    {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c0764e72b36a3dc065c155e5b22f93df465da9c39af65516fe04ed3c68c92636"},
+    {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:cbaba590180cba88cb99a5f76f90808a624f18b169b90a4abb40c1fd8c19420e"},
+    {file = "cryptography-40.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7a38250f433cd41df7fcb763caa3ee9362777fdb4dc642b9a349721d2bf47404"},
+    {file = "cryptography-40.0.2.tar.gz", hash = "sha256:c33c0d32b8594fa647d2e01dbccc303478e16fdd7cf98652d5b3ed11aa5e5c99"},
 ]
 
 [package.dependencies]
@@ -597,10 +580,10 @@ cffi = ">=1.12"
 [package.extras]
 docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"]
 docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"]
-pep8test = ["black", "check-manifest", "mypy", "ruff", "types-pytz", "types-requests"]
+pep8test = ["black", "check-manifest", "mypy", "ruff"]
 sdist = ["setuptools-rust (>=0.11.4)"]
 ssh = ["bcrypt (>=3.1.5)"]
-test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist", "pytz"]
+test = ["iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist"]
 test-randomorder = ["pytest-randomly"]
 tox = ["tox"]
 
@@ -974,14 +957,14 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"]
 
 [[package]]
 name = "packaging"
-version = "23.0"
+version = "23.1"
 description = "Core utilities for Python packages"
 category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"},
-    {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"},
+    {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
+    {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
 ]
 
 [[package]]
@@ -1004,136 +987,125 @@ totp = ["cryptography"]
 
 [[package]]
 name = "pathspec"
-version = "0.11.0"
+version = "0.11.1"
 description = "Utility library for gitignore style pattern matching of file paths."
 category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "pathspec-0.11.0-py3-none-any.whl", hash = "sha256:3a66eb970cbac598f9e5ccb5b2cf58930cd8e3ed86d393d541eaf2d8b1705229"},
-    {file = "pathspec-0.11.0.tar.gz", hash = "sha256:64d338d4e0914e91c1792321e6907b5a593f1ab1851de7fc269557a21b30ebbc"},
+    {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"},
+    {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"},
 ]
 
 [[package]]
 name = "pillow"
-version = "9.4.0"
+version = "9.5.0"
 description = "Python Imaging Library (Fork)"
 category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "Pillow-9.4.0-1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b4b4e9dda4f4e4c4e6896f93e84a8f0bcca3b059de9ddf67dac3c334b1195e1"},
-    {file = "Pillow-9.4.0-1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:fb5c1ad6bad98c57482236a21bf985ab0ef42bd51f7ad4e4538e89a997624e12"},
-    {file = "Pillow-9.4.0-1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:f0caf4a5dcf610d96c3bd32932bfac8aee61c96e60481c2a0ea58da435e25acd"},
-    {file = "Pillow-9.4.0-1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:3f4cc516e0b264c8d4ccd6b6cbc69a07c6d582d8337df79be1e15a5056b258c9"},
-    {file = "Pillow-9.4.0-1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:b8c2f6eb0df979ee99433d8b3f6d193d9590f735cf12274c108bd954e30ca858"},
-    {file = "Pillow-9.4.0-1-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b70756ec9417c34e097f987b4d8c510975216ad26ba6e57ccb53bc758f490dab"},
-    {file = "Pillow-9.4.0-1-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:43521ce2c4b865d385e78579a082b6ad1166ebed2b1a2293c3be1d68dd7ca3b9"},
-    {file = "Pillow-9.4.0-2-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:9d9a62576b68cd90f7075876f4e8444487db5eeea0e4df3ba298ee38a8d067b0"},
-    {file = "Pillow-9.4.0-2-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:87708d78a14d56a990fbf4f9cb350b7d89ee8988705e58e39bdf4d82c149210f"},
-    {file = "Pillow-9.4.0-2-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:8a2b5874d17e72dfb80d917213abd55d7e1ed2479f38f001f264f7ce7bae757c"},
-    {file = "Pillow-9.4.0-2-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:83125753a60cfc8c412de5896d10a0a405e0bd88d0470ad82e0869ddf0cb3848"},
-    {file = "Pillow-9.4.0-2-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9e5f94742033898bfe84c93c831a6f552bb629448d4072dd312306bab3bd96f1"},
-    {file = "Pillow-9.4.0-2-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:013016af6b3a12a2f40b704677f8b51f72cb007dac785a9933d5c86a72a7fe33"},
-    {file = "Pillow-9.4.0-2-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:99d92d148dd03fd19d16175b6d355cc1b01faf80dae93c6c3eb4163709edc0a9"},
-    {file = "Pillow-9.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:2968c58feca624bb6c8502f9564dd187d0e1389964898f5e9e1fbc8533169157"},
-    {file = "Pillow-9.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c5c1362c14aee73f50143d74389b2c158707b4abce2cb055b7ad37ce60738d47"},
-    {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd752c5ff1b4a870b7661234694f24b1d2b9076b8bf337321a814c612665f343"},
-    {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a3049a10261d7f2b6514d35bbb7a4dfc3ece4c4de14ef5876c4b7a23a0e566d"},
-    {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16a8df99701f9095bea8a6c4b3197da105df6f74e6176c5b410bc2df2fd29a57"},
-    {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:94cdff45173b1919350601f82d61365e792895e3c3a3443cf99819e6fbf717a5"},
-    {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:ed3e4b4e1e6de75fdc16d3259098de7c6571b1a6cc863b1a49e7d3d53e036070"},
-    {file = "Pillow-9.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5b2f8a31bd43e0f18172d8ac82347c8f37ef3e0b414431157718aa234991b28"},
-    {file = "Pillow-9.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:09b89ddc95c248ee788328528e6a2996e09eaccddeeb82a5356e92645733be35"},
-    {file = "Pillow-9.4.0-cp310-cp310-win32.whl", hash = "sha256:f09598b416ba39a8f489c124447b007fe865f786a89dbfa48bb5cf395693132a"},
-    {file = "Pillow-9.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:f6e78171be3fb7941f9910ea15b4b14ec27725865a73c15277bc39f5ca4f8391"},
-    {file = "Pillow-9.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:3fa1284762aacca6dc97474ee9c16f83990b8eeb6697f2ba17140d54b453e133"},
-    {file = "Pillow-9.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:eaef5d2de3c7e9b21f1e762f289d17b726c2239a42b11e25446abf82b26ac132"},
-    {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4dfdae195335abb4e89cc9762b2edc524f3c6e80d647a9a81bf81e17e3fb6f0"},
-    {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6abfb51a82e919e3933eb137e17c4ae9c0475a25508ea88993bb59faf82f3b35"},
-    {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:451f10ef963918e65b8869e17d67db5e2f4ab40e716ee6ce7129b0cde2876eab"},
-    {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:6663977496d616b618b6cfa43ec86e479ee62b942e1da76a2c3daa1c75933ef4"},
-    {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:60e7da3a3ad1812c128750fc1bc14a7ceeb8d29f77e0a2356a8fb2aa8925287d"},
-    {file = "Pillow-9.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:19005a8e58b7c1796bc0167862b1f54a64d3b44ee5d48152b06bb861458bc0f8"},
-    {file = "Pillow-9.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f715c32e774a60a337b2bb8ad9839b4abf75b267a0f18806f6f4f5f1688c4b5a"},
-    {file = "Pillow-9.4.0-cp311-cp311-win32.whl", hash = "sha256:b222090c455d6d1a64e6b7bb5f4035c4dff479e22455c9eaa1bdd4c75b52c80c"},
-    {file = "Pillow-9.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:ba6612b6548220ff5e9df85261bddc811a057b0b465a1226b39bfb8550616aee"},
-    {file = "Pillow-9.4.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5f532a2ad4d174eb73494e7397988e22bf427f91acc8e6ebf5bb10597b49c493"},
-    {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dd5a9c3091a0f414a963d427f920368e2b6a4c2f7527fdd82cde8ef0bc7a327"},
-    {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef21af928e807f10bf4141cad4746eee692a0dd3ff56cfb25fce076ec3cc8abe"},
-    {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:847b114580c5cc9ebaf216dd8c8dbc6b00a3b7ab0131e173d7120e6deade1f57"},
-    {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:653d7fb2df65efefbcbf81ef5fe5e5be931f1ee4332c2893ca638c9b11a409c4"},
-    {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:46f39cab8bbf4a384ba7cb0bc8bae7b7062b6a11cfac1ca4bc144dea90d4a9f5"},
-    {file = "Pillow-9.4.0-cp37-cp37m-win32.whl", hash = "sha256:7ac7594397698f77bce84382929747130765f66406dc2cd8b4ab4da68ade4c6e"},
-    {file = "Pillow-9.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:46c259e87199041583658457372a183636ae8cd56dbf3f0755e0f376a7f9d0e6"},
-    {file = "Pillow-9.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:0e51f608da093e5d9038c592b5b575cadc12fd748af1479b5e858045fff955a9"},
-    {file = "Pillow-9.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:765cb54c0b8724a7c12c55146ae4647e0274a839fb6de7bcba841e04298e1011"},
-    {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:519e14e2c49fcf7616d6d2cfc5c70adae95682ae20f0395e9280db85e8d6c4df"},
-    {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d197df5489004db87d90b918033edbeee0bd6df3848a204bca3ff0a903bef837"},
-    {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0845adc64fe9886db00f5ab68c4a8cd933ab749a87747555cec1c95acea64b0b"},
-    {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:e1339790c083c5a4de48f688b4841f18df839eb3c9584a770cbd818b33e26d5d"},
-    {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:a96e6e23f2b79433390273eaf8cc94fec9c6370842e577ab10dabdcc7ea0a66b"},
-    {file = "Pillow-9.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7cfc287da09f9d2a7ec146ee4d72d6ea1342e770d975e49a8621bf54eaa8f30f"},
-    {file = "Pillow-9.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d7081c084ceb58278dd3cf81f836bc818978c0ccc770cbbb202125ddabec6628"},
-    {file = "Pillow-9.4.0-cp38-cp38-win32.whl", hash = "sha256:df41112ccce5d47770a0c13651479fbcd8793f34232a2dd9faeccb75eb5d0d0d"},
-    {file = "Pillow-9.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:7a21222644ab69ddd9967cfe6f2bb420b460dae4289c9d40ff9a4896e7c35c9a"},
-    {file = "Pillow-9.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0f3269304c1a7ce82f1759c12ce731ef9b6e95b6df829dccd9fe42912cc48569"},
-    {file = "Pillow-9.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cb362e3b0976dc994857391b776ddaa8c13c28a16f80ac6522c23d5257156bed"},
-    {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2e0f87144fcbbe54297cae708c5e7f9da21a4646523456b00cc956bd4c65815"},
-    {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:28676836c7796805914b76b1837a40f76827ee0d5398f72f7dcc634bae7c6264"},
-    {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0884ba7b515163a1a05440a138adeb722b8a6ae2c2b33aea93ea3118dd3a899e"},
-    {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:53dcb50fbdc3fb2c55431a9b30caeb2f7027fcd2aeb501459464f0214200a503"},
-    {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:e8c5cf126889a4de385c02a2c3d3aba4b00f70234bfddae82a5eaa3ee6d5e3e6"},
-    {file = "Pillow-9.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6c6b1389ed66cdd174d040105123a5a1bc91d0aa7059c7261d20e583b6d8cbd2"},
-    {file = "Pillow-9.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0dd4c681b82214b36273c18ca7ee87065a50e013112eea7d78c7a1b89a739153"},
-    {file = "Pillow-9.4.0-cp39-cp39-win32.whl", hash = "sha256:6d9dfb9959a3b0039ee06c1a1a90dc23bac3b430842dcb97908ddde05870601c"},
-    {file = "Pillow-9.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:54614444887e0d3043557d9dbc697dbb16cfb5a35d672b7a0fcc1ed0cf1c600b"},
-    {file = "Pillow-9.4.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b9b752ab91e78234941e44abdecc07f1f0d8f51fb62941d32995b8161f68cfe5"},
-    {file = "Pillow-9.4.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3b56206244dc8711f7e8b7d6cad4663917cd5b2d950799425076681e8766286"},
-    {file = "Pillow-9.4.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aabdab8ec1e7ca7f1434d042bf8b1e92056245fb179790dc97ed040361f16bfd"},
-    {file = "Pillow-9.4.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:db74f5562c09953b2c5f8ec4b7dfd3f5421f31811e97d1dbc0a7c93d6e3a24df"},
-    {file = "Pillow-9.4.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e9d7747847c53a16a729b6ee5e737cf170f7a16611c143d95aa60a109a59c336"},
-    {file = "Pillow-9.4.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b52ff4f4e002f828ea6483faf4c4e8deea8d743cf801b74910243c58acc6eda3"},
-    {file = "Pillow-9.4.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:575d8912dca808edd9acd6f7795199332696d3469665ef26163cd090fa1f8bfa"},
-    {file = "Pillow-9.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3c4ed2ff6760e98d262e0cc9c9a7f7b8a9f61aa4d47c58835cdaf7b0b8811bb"},
-    {file = "Pillow-9.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e621b0246192d3b9cb1dc62c78cfa4c6f6d2ddc0ec207d43c0dedecb914f152a"},
-    {file = "Pillow-9.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:8f127e7b028900421cad64f51f75c051b628db17fb00e099eb148761eed598c9"},
-    {file = "Pillow-9.4.0.tar.gz", hash = "sha256:a1c2d7780448eb93fbcc3789bf3916aa5720d942e37945f4056680317f1cd23e"},
+    {file = "Pillow-9.5.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:ace6ca218308447b9077c14ea4ef381ba0b67ee78d64046b3f19cf4e1139ad16"},
+    {file = "Pillow-9.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3d403753c9d5adc04d4694d35cf0391f0f3d57c8e0030aac09d7678fa8030aa"},
+    {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ba1b81ee69573fe7124881762bb4cd2e4b6ed9dd28c9c60a632902fe8db8b38"},
+    {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe7e1c262d3392afcf5071df9afa574544f28eac825284596ac6db56e6d11062"},
+    {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f36397bf3f7d7c6a3abdea815ecf6fd14e7fcd4418ab24bae01008d8d8ca15e"},
+    {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:252a03f1bdddce077eff2354c3861bf437c892fb1832f75ce813ee94347aa9b5"},
+    {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:85ec677246533e27770b0de5cf0f9d6e4ec0c212a1f89dfc941b64b21226009d"},
+    {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b416f03d37d27290cb93597335a2f85ed446731200705b22bb927405320de903"},
+    {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1781a624c229cb35a2ac31cc4a77e28cafc8900733a864870c49bfeedacd106a"},
+    {file = "Pillow-9.5.0-cp310-cp310-win32.whl", hash = "sha256:8507eda3cd0608a1f94f58c64817e83ec12fa93a9436938b191b80d9e4c0fc44"},
+    {file = "Pillow-9.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:d3c6b54e304c60c4181da1c9dadf83e4a54fd266a99c70ba646a9baa626819eb"},
+    {file = "Pillow-9.5.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:7ec6f6ce99dab90b52da21cf0dc519e21095e332ff3b399a357c187b1a5eee32"},
+    {file = "Pillow-9.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:560737e70cb9c6255d6dcba3de6578a9e2ec4b573659943a5e7e4af13f298f5c"},
+    {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96e88745a55b88a7c64fa49bceff363a1a27d9a64e04019c2281049444a571e3"},
+    {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9c206c29b46cfd343ea7cdfe1232443072bbb270d6a46f59c259460db76779a"},
+    {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfcc2c53c06f2ccb8976fb5c71d448bdd0a07d26d8e07e321c103416444c7ad1"},
+    {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:a0f9bb6c80e6efcde93ffc51256d5cfb2155ff8f78292f074f60f9e70b942d99"},
+    {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8d935f924bbab8f0a9a28404422da8af4904e36d5c33fc6f677e4c4485515625"},
+    {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fed1e1cf6a42577953abbe8e6cf2fe2f566daebde7c34724ec8803c4c0cda579"},
+    {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c1170d6b195555644f0616fd6ed929dfcf6333b8675fcca044ae5ab110ded296"},
+    {file = "Pillow-9.5.0-cp311-cp311-win32.whl", hash = "sha256:54f7102ad31a3de5666827526e248c3530b3a33539dbda27c6843d19d72644ec"},
+    {file = "Pillow-9.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfa4561277f677ecf651e2b22dc43e8f5368b74a25a8f7d1d4a3a243e573f2d4"},
+    {file = "Pillow-9.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:965e4a05ef364e7b973dd17fc765f42233415974d773e82144c9bbaaaea5d089"},
+    {file = "Pillow-9.5.0-cp312-cp312-win32.whl", hash = "sha256:22baf0c3cf0c7f26e82d6e1adf118027afb325e703922c8dfc1d5d0156bb2eeb"},
+    {file = "Pillow-9.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:432b975c009cf649420615388561c0ce7cc31ce9b2e374db659ee4f7d57a1f8b"},
+    {file = "Pillow-9.5.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5d4ebf8e1db4441a55c509c4baa7a0587a0210f7cd25fcfe74dbbce7a4bd1906"},
+    {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:375f6e5ee9620a271acb6820b3d1e94ffa8e741c0601db4c0c4d3cb0a9c224bf"},
+    {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99eb6cafb6ba90e436684e08dad8be1637efb71c4f2180ee6b8f940739406e78"},
+    {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dfaaf10b6172697b9bceb9a3bd7b951819d1ca339a5ef294d1f1ac6d7f63270"},
+    {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:763782b2e03e45e2c77d7779875f4432e25121ef002a41829d8868700d119392"},
+    {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:35f6e77122a0c0762268216315bf239cf52b88865bba522999dc38f1c52b9b47"},
+    {file = "Pillow-9.5.0-cp37-cp37m-win32.whl", hash = "sha256:aca1c196f407ec7cf04dcbb15d19a43c507a81f7ffc45b690899d6a76ac9fda7"},
+    {file = "Pillow-9.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322724c0032af6692456cd6ed554bb85f8149214d97398bb80613b04e33769f6"},
+    {file = "Pillow-9.5.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:a0aa9417994d91301056f3d0038af1199eb7adc86e646a36b9e050b06f526597"},
+    {file = "Pillow-9.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8286396b351785801a976b1e85ea88e937712ee2c3ac653710a4a57a8da5d9c"},
+    {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c830a02caeb789633863b466b9de10c015bded434deb3ec87c768e53752ad22a"},
+    {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbd359831c1657d69bb81f0db962905ee05e5e9451913b18b831febfe0519082"},
+    {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8fc330c3370a81bbf3f88557097d1ea26cd8b019d6433aa59f71195f5ddebbf"},
+    {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:7002d0797a3e4193c7cdee3198d7c14f92c0836d6b4a3f3046a64bd1ce8df2bf"},
+    {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:229e2c79c00e85989a34b5981a2b67aa079fd08c903f0aaead522a1d68d79e51"},
+    {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9adf58f5d64e474bed00d69bcd86ec4bcaa4123bfa70a65ce72e424bfb88ed96"},
+    {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:662da1f3f89a302cc22faa9f14a262c2e3951f9dbc9617609a47521c69dd9f8f"},
+    {file = "Pillow-9.5.0-cp38-cp38-win32.whl", hash = "sha256:6608ff3bf781eee0cd14d0901a2b9cc3d3834516532e3bd673a0a204dc8615fc"},
+    {file = "Pillow-9.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:e49eb4e95ff6fd7c0c402508894b1ef0e01b99a44320ba7d8ecbabefddcc5569"},
+    {file = "Pillow-9.5.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:482877592e927fd263028c105b36272398e3e1be3269efda09f6ba21fd83ec66"},
+    {file = "Pillow-9.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3ded42b9ad70e5f1754fb7c2e2d6465a9c842e41d178f262e08b8c85ed8a1d8e"},
+    {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c446d2245ba29820d405315083d55299a796695d747efceb5717a8b450324115"},
+    {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aca1152d93dcc27dc55395604dcfc55bed5f25ef4c98716a928bacba90d33a3"},
+    {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:608488bdcbdb4ba7837461442b90ea6f3079397ddc968c31265c1e056964f1ef"},
+    {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:60037a8db8750e474af7ffc9faa9b5859e6c6d0a50e55c45576bf28be7419705"},
+    {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:07999f5834bdc404c442146942a2ecadd1cb6292f5229f4ed3b31e0a108746b1"},
+    {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a127ae76092974abfbfa38ca2d12cbeddcdeac0fb71f9627cc1135bedaf9d51a"},
+    {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:489f8389261e5ed43ac8ff7b453162af39c3e8abd730af8363587ba64bb2e865"},
+    {file = "Pillow-9.5.0-cp39-cp39-win32.whl", hash = "sha256:9b1af95c3a967bf1da94f253e56b6286b50af23392a886720f563c547e48e964"},
+    {file = "Pillow-9.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:77165c4a5e7d5a284f10a6efaa39a0ae8ba839da344f20b111d62cc932fa4e5d"},
+    {file = "Pillow-9.5.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:833b86a98e0ede388fa29363159c9b1a294b0905b5128baf01db683672f230f5"},
+    {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaf305d6d40bd9632198c766fb64f0c1a83ca5b667f16c1e79e1661ab5060140"},
+    {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0852ddb76d85f127c135b6dd1f0bb88dbb9ee990d2cd9aa9e28526c93e794fba"},
+    {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:91ec6fe47b5eb5a9968c79ad9ed78c342b1f97a091677ba0e012701add857829"},
+    {file = "Pillow-9.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb841572862f629b99725ebaec3287fc6d275be9b14443ea746c1dd325053cbd"},
+    {file = "Pillow-9.5.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c380b27d041209b849ed246b111b7c166ba36d7933ec6e41175fd15ab9eb1572"},
+    {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c9af5a3b406a50e313467e3565fc99929717f780164fe6fbb7704edba0cebbe"},
+    {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5671583eab84af046a397d6d0ba25343c00cd50bce03787948e0fff01d4fd9b1"},
+    {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:84a6f19ce086c1bf894644b43cd129702f781ba5751ca8572f08aa40ef0ab7b7"},
+    {file = "Pillow-9.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1e7723bd90ef94eda669a3c2c19d549874dd5badaeefabefd26053304abe5799"},
+    {file = "Pillow-9.5.0.tar.gz", hash = "sha256:bf548479d336726d7a0eceb6e767e179fbde37833ae42794602631a070d630f1"},
 ]
 
 [package.extras]
-docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-issues (>=3.0.1)", "sphinx-removed-in", "sphinxext-opengraph"]
+docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"]
 tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"]
 
 [[package]]
 name = "platformdirs"
-version = "3.0.0"
+version = "3.2.0"
 description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
 category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "platformdirs-3.0.0-py3-none-any.whl", hash = "sha256:b1d5eb14f221506f50d6604a561f4c5786d9e80355219694a1b244bcd96f4567"},
-    {file = "platformdirs-3.0.0.tar.gz", hash = "sha256:8a1228abb1ef82d788f74139988b137e78692984ec7b08eaa6c65f1723af28f9"},
+    {file = "platformdirs-3.2.0-py3-none-any.whl", hash = "sha256:ebe11c0d7a805086e99506aa331612429a72ca7cd52a1f0d277dc4adc20cb10e"},
+    {file = "platformdirs-3.2.0.tar.gz", hash = "sha256:d5b638ca397f25f979350ff789db335903d7ea010ab28903f57b27e1b16c2b08"},
 ]
 
 [package.dependencies]
-typing-extensions = {version = ">=4.4", markers = "python_version < \"3.8\""}
+typing-extensions = {version = ">=4.5", markers = "python_version < \"3.8\""}
 
 [package.extras]
 docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"]
-test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.2.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
 
 [[package]]
 name = "prompt-toolkit"
-version = "3.0.36"
+version = "3.0.38"
 description = "Library for building powerful interactive command lines in Python"
 category = "main"
 optional = false
-python-versions = ">=3.6.2"
+python-versions = ">=3.7.0"
 files = [
-    {file = "prompt_toolkit-3.0.36-py3-none-any.whl", hash = "sha256:aa64ad242a462c5ff0363a7b9cfe696c20d55d9fc60c11fd8e632d064804d305"},
-    {file = "prompt_toolkit-3.0.36.tar.gz", hash = "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63"},
+    {file = "prompt_toolkit-3.0.38-py3-none-any.whl", hash = "sha256:45ea77a2f7c60418850331366c81cf6b5b9cf4c7fd34616f733c5427e6abbb1f"},
+    {file = "prompt_toolkit-3.0.38.tar.gz", hash = "sha256:23ac5d50538a9a38c8bde05fecb47d0b403ecd0662857a86f886f798563d5b9b"},
 ]
 
 [package.dependencies]
@@ -1141,83 +1113,74 @@ wcwidth = "*"
 
 [[package]]
 name = "psycopg2-binary"
-version = "2.9.5"
+version = "2.9.6"
 description = "psycopg2 - Python-PostgreSQL Database Adapter"
 category = "main"
 optional = false
 python-versions = ">=3.6"
 files = [
-    {file = "psycopg2-binary-2.9.5.tar.gz", hash = "sha256:33e632d0885b95a8b97165899006c40e9ecdc634a529dca7b991eb7de4ece41c"},
-    {file = "psycopg2_binary-2.9.5-cp310-cp310-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:0775d6252ccb22b15da3b5d7adbbf8cfe284916b14b6dc0ff503a23edb01ee85"},
-    {file = "psycopg2_binary-2.9.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ec46ed947801652c9643e0b1dc334cfb2781232e375ba97312c2fc256597632"},
-    {file = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3520d7af1ebc838cc6084a3281145d5cd5bdd43fdef139e6db5af01b92596cb7"},
-    {file = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cbc554ba47ecca8cd3396ddaca85e1ecfe3e48dd57dc5e415e59551affe568e"},
-    {file = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:5d28ecdf191db558d0c07d0f16524ee9d67896edf2b7990eea800abeb23ebd61"},
-    {file = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_24_ppc64le.whl", hash = "sha256:b9c33d4aef08dfecbd1736ceab8b7b3c4358bf10a0121483e5cd60d3d308cc64"},
-    {file = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:05b3d479425e047c848b9782cd7aac9c6727ce23181eb9647baf64ffdfc3da41"},
-    {file = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1e491e6489a6cb1d079df8eaa15957c277fdedb102b6a68cfbf40c4994412fd0"},
-    {file = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:9e32cedc389bcb76d9f24ea8a012b3cb8385ee362ea437e1d012ffaed106c17d"},
-    {file = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:46850a640df62ae940e34a163f72e26aca1f88e2da79148e1862faaac985c302"},
-    {file = "psycopg2_binary-2.9.5-cp310-cp310-win32.whl", hash = "sha256:3d790f84201c3698d1bfb404c917f36e40531577a6dda02e45ba29b64d539867"},
-    {file = "psycopg2_binary-2.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:1764546ffeaed4f9428707be61d68972eb5ede81239b46a45843e0071104d0dd"},
-    {file = "psycopg2_binary-2.9.5-cp311-cp311-macosx_10_9_universal2.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:426c2ae999135d64e6a18849a7d1ad0e1bd007277e4a8f4752eaa40a96b550ff"},
-    {file = "psycopg2_binary-2.9.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7cf1d44e710ca3a9ce952bda2855830fe9f9017ed6259e01fcd71ea6287565f5"},
-    {file = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:024030b13bdcbd53d8a93891a2cf07719715724fc9fee40243f3bd78b4264b8f"},
-    {file = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcda1c84a1c533c528356da5490d464a139b6e84eb77cc0b432e38c5c6dd7882"},
-    {file = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:2ef892cabdccefe577088a79580301f09f2a713eb239f4f9f62b2b29cafb0577"},
-    {file = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_24_ppc64le.whl", hash = "sha256:af0516e1711995cb08dc19bbd05bec7dbdebf4185f68870595156718d237df3e"},
-    {file = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e72c91bda9880f097c8aa3601a2c0de6c708763ba8128006151f496ca9065935"},
-    {file = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e67b3c26e9b6d37b370c83aa790bbc121775c57bfb096c2e77eacca25fd0233b"},
-    {file = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5fc447058d083b8c6ac076fc26b446d44f0145308465d745fba93a28c14c9e32"},
-    {file = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d892bfa1d023c3781a3cab8dd5af76b626c483484d782e8bd047c180db590e4c"},
-    {file = "psycopg2_binary-2.9.5-cp311-cp311-win32.whl", hash = "sha256:2abccab84d057723d2ca8f99ff7b619285d40da6814d50366f61f0fc385c3903"},
-    {file = "psycopg2_binary-2.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:bef7e3f9dc6f0c13afdd671008534be5744e0e682fb851584c8c3a025ec09720"},
-    {file = "psycopg2_binary-2.9.5-cp36-cp36m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:6e63814ec71db9bdb42905c925639f319c80e7909fb76c3b84edc79dadef8d60"},
-    {file = "psycopg2_binary-2.9.5-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:212757ffcecb3e1a5338d4e6761bf9c04f750e7d027117e74aa3cd8a75bb6fbd"},
-    {file = "psycopg2_binary-2.9.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f8a9bcab7b6db2e3dbf65b214dfc795b4c6b3bb3af922901b6a67f7cb47d5f8"},
-    {file = "psycopg2_binary-2.9.5-cp36-cp36m-manylinux_2_24_aarch64.whl", hash = "sha256:56b2957a145f816726b109ee3d4e6822c23f919a7d91af5a94593723ed667835"},
-    {file = "psycopg2_binary-2.9.5-cp36-cp36m-manylinux_2_24_ppc64le.whl", hash = "sha256:f95b8aca2703d6a30249f83f4fe6a9abf2e627aa892a5caaab2267d56be7ab69"},
-    {file = "psycopg2_binary-2.9.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:70831e03bd53702c941da1a1ad36c17d825a24fbb26857b40913d58df82ec18b"},
-    {file = "psycopg2_binary-2.9.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:dbc332beaf8492b5731229a881807cd7b91b50dbbbaf7fe2faf46942eda64a24"},
-    {file = "psycopg2_binary-2.9.5-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:2d964eb24c8b021623df1c93c626671420c6efadbdb8655cb2bd5e0c6fa422ba"},
-    {file = "psycopg2_binary-2.9.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:95076399ec3b27a8f7fa1cc9a83417b1c920d55cf7a97f718a94efbb96c7f503"},
-    {file = "psycopg2_binary-2.9.5-cp36-cp36m-win32.whl", hash = "sha256:3fc33295cfccad697a97a76dec3f1e94ad848b7b163c3228c1636977966b51e2"},
-    {file = "psycopg2_binary-2.9.5-cp36-cp36m-win_amd64.whl", hash = "sha256:02551647542f2bf89073d129c73c05a25c372fc0a49aa50e0de65c3c143d8bd0"},
-    {file = "psycopg2_binary-2.9.5-cp37-cp37m-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:63e318dbe52709ed10d516a356f22a635e07a2e34c68145484ed96a19b0c4c68"},
-    {file = "psycopg2_binary-2.9.5-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7e518a0911c50f60313cb9e74a169a65b5d293770db4770ebf004245f24b5c5"},
-    {file = "psycopg2_binary-2.9.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9d38a4656e4e715d637abdf7296e98d6267df0cc0a8e9a016f8ba07e4aa3eeb"},
-    {file = "psycopg2_binary-2.9.5-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:68d81a2fe184030aa0c5c11e518292e15d342a667184d91e30644c9d533e53e1"},
-    {file = "psycopg2_binary-2.9.5-cp37-cp37m-manylinux_2_24_ppc64le.whl", hash = "sha256:7ee3095d02d6f38bd7d9a5358fcc9ea78fcdb7176921528dd709cc63f40184f5"},
-    {file = "psycopg2_binary-2.9.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:46512486be6fbceef51d7660dec017394ba3e170299d1dc30928cbedebbf103a"},
-    {file = "psycopg2_binary-2.9.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b911dfb727e247340d36ae20c4b9259e4a64013ab9888ccb3cbba69b77fd9636"},
-    {file = "psycopg2_binary-2.9.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:422e3d43b47ac20141bc84b3d342eead8d8099a62881a501e97d15f6addabfe9"},
-    {file = "psycopg2_binary-2.9.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c5682a45df7d9642eff590abc73157c887a68f016df0a8ad722dcc0f888f56d7"},
-    {file = "psycopg2_binary-2.9.5-cp37-cp37m-win32.whl", hash = "sha256:b8104f709590fff72af801e916817560dbe1698028cd0afe5a52d75ceb1fce5f"},
-    {file = "psycopg2_binary-2.9.5-cp37-cp37m-win_amd64.whl", hash = "sha256:7b3751857da3e224f5629400736a7b11e940b5da5f95fa631d86219a1beaafec"},
-    {file = "psycopg2_binary-2.9.5-cp38-cp38-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:043a9fd45a03858ff72364b4b75090679bd875ee44df9c0613dc862ca6b98460"},
-    {file = "psycopg2_binary-2.9.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9ffdc51001136b699f9563b1c74cc1f8c07f66ef7219beb6417a4c8aaa896c28"},
-    {file = "psycopg2_binary-2.9.5-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c15ba5982c177bc4b23a7940c7e4394197e2d6a424a2d282e7c236b66da6d896"},
-    {file = "psycopg2_binary-2.9.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc85b3777068ed30aff8242be2813038a929f2084f69e43ef869daddae50f6ee"},
-    {file = "psycopg2_binary-2.9.5-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:215d6bf7e66732a514f47614f828d8c0aaac9a648c46a831955cb103473c7147"},
-    {file = "psycopg2_binary-2.9.5-cp38-cp38-manylinux_2_24_ppc64le.whl", hash = "sha256:7d07f552d1e412f4b4e64ce386d4c777a41da3b33f7098b6219012ba534fb2c2"},
-    {file = "psycopg2_binary-2.9.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a0adef094c49f242122bb145c3c8af442070dc0e4312db17e49058c1702606d4"},
-    {file = "psycopg2_binary-2.9.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:00475004e5ed3e3bf5e056d66e5dcdf41a0dc62efcd57997acd9135c40a08a50"},
-    {file = "psycopg2_binary-2.9.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:7d88db096fa19d94f433420eaaf9f3c45382da2dd014b93e4bf3215639047c16"},
-    {file = "psycopg2_binary-2.9.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:902844f9c4fb19b17dfa84d9e2ca053d4a4ba265723d62ea5c9c26b38e0aa1e6"},
-    {file = "psycopg2_binary-2.9.5-cp38-cp38-win32.whl", hash = "sha256:4e7904d1920c0c89105c0517dc7e3f5c20fb4e56ba9cdef13048db76947f1d79"},
-    {file = "psycopg2_binary-2.9.5-cp38-cp38-win_amd64.whl", hash = "sha256:a36a0e791805aa136e9cbd0ffa040d09adec8610453ee8a753f23481a0057af5"},
-    {file = "psycopg2_binary-2.9.5-cp39-cp39-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:25382c7d174c679ce6927c16b6fbb68b10e56ee44b1acb40671e02d29f2fce7c"},
-    {file = "psycopg2_binary-2.9.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9c38d3869238e9d3409239bc05bc27d6b7c99c2a460ea337d2814b35fb4fea1b"},
-    {file = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5c6527c8efa5226a9e787507652dd5ba97b62d29b53c371a85cd13f957fe4d42"},
-    {file = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e59137cdb970249ae60be2a49774c6dfb015bd0403f05af1fe61862e9626642d"},
-    {file = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:d4c7b3a31502184e856df1f7bbb2c3735a05a8ce0ade34c5277e1577738a5c91"},
-    {file = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_24_ppc64le.whl", hash = "sha256:b9a794cef1d9c1772b94a72eec6da144c18e18041d294a9ab47669bc77a80c1d"},
-    {file = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c5254cbd4f4855e11cebf678c1a848a3042d455a22a4ce61349c36aafd4c2267"},
-    {file = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c5e65c6ac0ae4bf5bef1667029f81010b6017795dcb817ba5c7b8a8d61fab76f"},
-    {file = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:74eddec4537ab1f701a1647214734bc52cee2794df748f6ae5908e00771f180a"},
-    {file = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:01ad49d68dd8c5362e4bfb4158f2896dc6e0c02e87b8a3770fc003459f1a4425"},
-    {file = "psycopg2_binary-2.9.5-cp39-cp39-win32.whl", hash = "sha256:937880290775033a743f4836aa253087b85e62784b63fd099ee725d567a48aa1"},
-    {file = "psycopg2_binary-2.9.5-cp39-cp39-win_amd64.whl", hash = "sha256:484405b883630f3e74ed32041a87456c5e0e63a8e3429aa93e8714c366d62bd1"},
+    {file = "psycopg2-binary-2.9.6.tar.gz", hash = "sha256:1f64dcfb8f6e0c014c7f55e51c9759f024f70ea572fbdef123f85318c297947c"},
+    {file = "psycopg2_binary-2.9.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d26e0342183c762de3276cca7a530d574d4e25121ca7d6e4a98e4f05cb8e4df7"},
+    {file = "psycopg2_binary-2.9.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c48d8f2db17f27d41fb0e2ecd703ea41984ee19362cbce52c097963b3a1b4365"},
+    {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffe9dc0a884a8848075e576c1de0290d85a533a9f6e9c4e564f19adf8f6e54a7"},
+    {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a76e027f87753f9bd1ab5f7c9cb8c7628d1077ef927f5e2446477153a602f2c"},
+    {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6460c7a99fc939b849431f1e73e013d54aa54293f30f1109019c56a0b2b2ec2f"},
+    {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae102a98c547ee2288637af07393dd33f440c25e5cd79556b04e3fca13325e5f"},
+    {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9972aad21f965599ed0106f65334230ce826e5ae69fda7cbd688d24fa922415e"},
+    {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7a40c00dbe17c0af5bdd55aafd6ff6679f94a9be9513a4c7e071baf3d7d22a70"},
+    {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:cacbdc5839bdff804dfebc058fe25684cae322987f7a38b0168bc1b2df703fb1"},
+    {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7f0438fa20fb6c7e202863e0d5ab02c246d35efb1d164e052f2f3bfe2b152bd0"},
+    {file = "psycopg2_binary-2.9.6-cp310-cp310-win32.whl", hash = "sha256:b6c8288bb8a84b47e07013bb4850f50538aa913d487579e1921724631d02ea1b"},
+    {file = "psycopg2_binary-2.9.6-cp310-cp310-win_amd64.whl", hash = "sha256:61b047a0537bbc3afae10f134dc6393823882eb263088c271331602b672e52e9"},
+    {file = "psycopg2_binary-2.9.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:964b4dfb7c1c1965ac4c1978b0f755cc4bd698e8aa2b7667c575fb5f04ebe06b"},
+    {file = "psycopg2_binary-2.9.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afe64e9b8ea66866a771996f6ff14447e8082ea26e675a295ad3bdbffdd72afb"},
+    {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15e2ee79e7cf29582ef770de7dab3d286431b01c3bb598f8e05e09601b890081"},
+    {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfa74c903a3c1f0d9b1c7e7b53ed2d929a4910e272add6700c38f365a6002820"},
+    {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b83456c2d4979e08ff56180a76429263ea254c3f6552cd14ada95cff1dec9bb8"},
+    {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0645376d399bfd64da57148694d78e1f431b1e1ee1054872a5713125681cf1be"},
+    {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e99e34c82309dd78959ba3c1590975b5d3c862d6f279f843d47d26ff89d7d7e1"},
+    {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4ea29fc3ad9d91162c52b578f211ff1c931d8a38e1f58e684c45aa470adf19e2"},
+    {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4ac30da8b4f57187dbf449294d23b808f8f53cad6b1fc3623fa8a6c11d176dd0"},
+    {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e78e6e2a00c223e164c417628572a90093c031ed724492c763721c2e0bc2a8df"},
+    {file = "psycopg2_binary-2.9.6-cp311-cp311-win32.whl", hash = "sha256:1876843d8e31c89c399e31b97d4b9725a3575bb9c2af92038464231ec40f9edb"},
+    {file = "psycopg2_binary-2.9.6-cp311-cp311-win_amd64.whl", hash = "sha256:b4b24f75d16a89cc6b4cdff0eb6a910a966ecd476d1e73f7ce5985ff1328e9a6"},
+    {file = "psycopg2_binary-2.9.6-cp36-cp36m-win32.whl", hash = "sha256:498807b927ca2510baea1b05cc91d7da4718a0f53cb766c154c417a39f1820a0"},
+    {file = "psycopg2_binary-2.9.6-cp36-cp36m-win_amd64.whl", hash = "sha256:0d236c2825fa656a2d98bbb0e52370a2e852e5a0ec45fc4f402977313329174d"},
+    {file = "psycopg2_binary-2.9.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:34b9ccdf210cbbb1303c7c4db2905fa0319391bd5904d32689e6dd5c963d2ea8"},
+    {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84d2222e61f313c4848ff05353653bf5f5cf6ce34df540e4274516880d9c3763"},
+    {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30637a20623e2a2eacc420059be11527f4458ef54352d870b8181a4c3020ae6b"},
+    {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8122cfc7cae0da9a3077216528b8bb3629c43b25053284cc868744bfe71eb141"},
+    {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38601cbbfe600362c43714482f43b7c110b20cb0f8172422c616b09b85a750c5"},
+    {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c7e62ab8b332147a7593a385d4f368874d5fe4ad4e341770d4983442d89603e3"},
+    {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2ab652e729ff4ad76d400df2624d223d6e265ef81bb8aa17fbd63607878ecbee"},
+    {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c83a74b68270028dc8ee74d38ecfaf9c90eed23c8959fca95bd703d25b82c88e"},
+    {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d4e6036decf4b72d6425d5b29bbd3e8f0ff1059cda7ac7b96d6ac5ed34ffbacd"},
+    {file = "psycopg2_binary-2.9.6-cp37-cp37m-win32.whl", hash = "sha256:a8c28fd40a4226b4a84bdf2d2b5b37d2c7bd49486b5adcc200e8c7ec991dfa7e"},
+    {file = "psycopg2_binary-2.9.6-cp37-cp37m-win_amd64.whl", hash = "sha256:51537e3d299be0db9137b321dfb6a5022caaab275775680e0c3d281feefaca6b"},
+    {file = "psycopg2_binary-2.9.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cf4499e0a83b7b7edcb8dabecbd8501d0d3a5ef66457200f77bde3d210d5debb"},
+    {file = "psycopg2_binary-2.9.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7e13a5a2c01151f1208d5207e42f33ba86d561b7a89fca67c700b9486a06d0e2"},
+    {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e0f754d27fddcfd74006455b6e04e6705d6c31a612ec69ddc040a5468e44b4e"},
+    {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d57c3fd55d9058645d26ae37d76e61156a27722097229d32a9e73ed54819982a"},
+    {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:71f14375d6f73b62800530b581aed3ada394039877818b2d5f7fc77e3bb6894d"},
+    {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:441cc2f8869a4f0f4bb408475e5ae0ee1f3b55b33f350406150277f7f35384fc"},
+    {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:65bee1e49fa6f9cf327ce0e01c4c10f39165ee76d35c846ade7cb0ec6683e303"},
+    {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:af335bac6b666cc6aea16f11d486c3b794029d9df029967f9938a4bed59b6a19"},
+    {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:cfec476887aa231b8548ece2e06d28edc87c1397ebd83922299af2e051cf2827"},
+    {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:65c07febd1936d63bfde78948b76cd4c2a411572a44ac50719ead41947d0f26b"},
+    {file = "psycopg2_binary-2.9.6-cp38-cp38-win32.whl", hash = "sha256:4dfb4be774c4436a4526d0c554af0cc2e02082c38303852a36f6456ece7b3503"},
+    {file = "psycopg2_binary-2.9.6-cp38-cp38-win_amd64.whl", hash = "sha256:02c6e3cf3439e213e4ee930308dc122d6fb4d4bea9aef4a12535fbd605d1a2fe"},
+    {file = "psycopg2_binary-2.9.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e9182eb20f41417ea1dd8e8f7888c4d7c6e805f8a7c98c1081778a3da2bee3e4"},
+    {file = "psycopg2_binary-2.9.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8a6979cf527e2603d349a91060f428bcb135aea2be3201dff794813256c274f1"},
+    {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8338a271cb71d8da40b023a35d9c1e919eba6cbd8fa20a54b748a332c355d896"},
+    {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3ed340d2b858d6e6fb5083f87c09996506af483227735de6964a6100b4e6a54"},
+    {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f81e65376e52f03422e1fb475c9514185669943798ed019ac50410fb4c4df232"},
+    {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfb13af3c5dd3a9588000910178de17010ebcccd37b4f9794b00595e3a8ddad3"},
+    {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4c727b597c6444a16e9119386b59388f8a424223302d0c06c676ec8b4bc1f963"},
+    {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4d67fbdaf177da06374473ef6f7ed8cc0a9dc640b01abfe9e8a2ccb1b1402c1f"},
+    {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0892ef645c2fabb0c75ec32d79f4252542d0caec1d5d949630e7d242ca4681a3"},
+    {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:02c0f3757a4300cf379eb49f543fb7ac527fb00144d39246ee40e1df684ab514"},
+    {file = "psycopg2_binary-2.9.6-cp39-cp39-win32.whl", hash = "sha256:c3dba7dab16709a33a847e5cd756767271697041fbe3fe97c215b1fc1f5c9848"},
+    {file = "psycopg2_binary-2.9.6-cp39-cp39-win_amd64.whl", hash = "sha256:f6a88f384335bb27812293fdb11ac6aee2ca3f51d3c7820fe03de0a304ab6249"},
 ]
 
 [[package]]
@@ -1277,14 +1240,14 @@ files = [
 
 [[package]]
 name = "pygments"
-version = "2.14.0"
+version = "2.15.0"
 description = "Pygments is a syntax highlighting package written in Python."
 category = "dev"
 optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.7"
 files = [
-    {file = "Pygments-2.14.0-py3-none-any.whl", hash = "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"},
-    {file = "Pygments-2.14.0.tar.gz", hash = "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297"},
+    {file = "Pygments-2.15.0-py3-none-any.whl", hash = "sha256:77a3299119af881904cd5ecd1ac6a66214b6e9bed1f2db16993b54adede64094"},
+    {file = "Pygments-2.15.0.tar.gz", hash = "sha256:f7e36cffc4c517fbc252861b9a6e4644ca0e5abadf9a113c72d1358ad09b9500"},
 ]
 
 [package.extras]
@@ -1360,30 +1323,30 @@ postgresql = ["psycopg2"]
 
 [[package]]
 name = "pytz"
-version = "2022.7.1"
+version = "2023.3"
 description = "World timezone definitions, modern and historical"
 category = "main"
 optional = false
 python-versions = "*"
 files = [
-    {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"},
-    {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"},
+    {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"},
+    {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"},
 ]
 
 [[package]]
 name = "redis"
-version = "4.5.1"
+version = "4.5.4"
 description = "Python client for Redis database and key-value store"
 category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "redis-4.5.1-py3-none-any.whl", hash = "sha256:5deb072d26e67d2be1712603bfb7947ec3431fb0eec9c578994052e33035af6d"},
-    {file = "redis-4.5.1.tar.gz", hash = "sha256:1eec3741cda408d3a5f84b78d089c8b8d895f21b3b050988351e925faf202864"},
+    {file = "redis-4.5.4-py3-none-any.whl", hash = "sha256:2c19e6767c474f2e85167909061d525ed65bea9301c0770bb151e041b7ac89a2"},
+    {file = "redis-4.5.4.tar.gz", hash = "sha256:73ec35da4da267d6847e47f68730fdd5f62e2ca69e3ef5885c6a78a9374c3893"},
 ]
 
 [package.dependencies]
-async-timeout = ">=4.0.2"
+async-timeout = {version = ">=4.0.2", markers = "python_version <= \"3.11.2\""}
 importlib-metadata = {version = ">=1.0", markers = "python_version < \"3.8\""}
 typing-extensions = {version = "*", markers = "python_version < \"3.8\""}
 
@@ -1393,14 +1356,14 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"
 
 [[package]]
 name = "releases"
-version = "2.0.0"
+version = "2.1.0"
 description = "A Sphinx extension for changelog manipulation"
 category = "dev"
 optional = false
 python-versions = ">=3.6"
 files = [
-    {file = "releases-2.0.0-py3-none-any.whl", hash = "sha256:ea6470d8d2ecb4161845a4e169527aecb8b9a8a628c590ae0855dd11fd6e8864"},
-    {file = "releases-2.0.0.tar.gz", hash = "sha256:99296a3acab3838e27e96ec5c3713450982f385b6b6fd54fc9e2425393972e8c"},
+    {file = "releases-2.1.0-py3-none-any.whl", hash = "sha256:21d2efb9b67b0bbd28a43775cbb5c3c300bb37fcf0dc3e635f570dc9ea3202c8"},
+    {file = "releases-2.1.0.tar.gz", hash = "sha256:1303b87d6f0427fbdcc40c31bb893b1dab5be4c8619a4b1c2710c0a218e3c79c"},
 ]
 
 [package.dependencies]
@@ -1462,14 +1425,14 @@ files = [
 
 [[package]]
 name = "setuptools"
-version = "67.3.2"
+version = "67.6.1"
 description = "Easily download, build, install, upgrade, and uninstall Python packages"
 category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "setuptools-67.3.2-py3-none-any.whl", hash = "sha256:bb6d8e508de562768f2027902929f8523932fcd1fb784e6d573d2cafac995a48"},
-    {file = "setuptools-67.3.2.tar.gz", hash = "sha256:95f00380ef2ffa41d9bba85d95b27689d923c93dfbafed4aecd7cf988a25e012"},
+    {file = "setuptools-67.6.1-py3-none-any.whl", hash = "sha256:e728ca814a823bf7bf60162daf9db95b93d532948c4c0bea762ce62f60189078"},
+    {file = "setuptools-67.6.1.tar.gz", hash = "sha256:257de92a9d50a60b8e22abfcbb771571fde0dbf3ec234463212027a4eeecbe9a"},
 ]
 
 [package.extras]
@@ -1720,14 +1683,14 @@ files = [
 
 [[package]]
 name = "urllib3"
-version = "1.26.14"
+version = "1.26.15"
 description = "HTTP library with thread-safe connection pooling, file post, and more."
 category = "main"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
 files = [
-    {file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"},
-    {file = "urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"},
+    {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"},
+    {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"},
 ]
 
 [package.extras]
@@ -1761,31 +1724,35 @@ files = [
 
 [[package]]
 name = "webcolors"
-version = "1.12"
-description = "A library for working with color names and color values formats defined by HTML and CSS."
+version = "1.13"
+description = "A library for working with the color formats defined by HTML and CSS."
 category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "webcolors-1.12-py3-none-any.whl", hash = "sha256:d98743d81d498a2d3eaf165196e65481f0d2ea85281463d856b1e51b09f62dce"},
-    {file = "webcolors-1.12.tar.gz", hash = "sha256:16d043d3a08fd6a1b1b7e3e9e62640d09790dce80d2bdd4792a175b35fe794a9"},
+    {file = "webcolors-1.13-py3-none-any.whl", hash = "sha256:29bc7e8752c0a1bd4a1f03c14d6e6a72e93d82193738fa860cbff59d0fcc11bf"},
+    {file = "webcolors-1.13.tar.gz", hash = "sha256:c225b674c83fa923be93d235330ce0300373d02885cef23238813b0d5668304a"},
 ]
 
+[package.extras]
+docs = ["furo", "sphinx", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-notfound-page", "sphinxext-opengraph"]
+tests = ["pytest", "pytest-cov"]
+
 [[package]]
 name = "zipp"
-version = "3.14.0"
+version = "3.15.0"
 description = "Backport of pathlib-compatible object wrapper for zip files"
 category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "zipp-3.14.0-py3-none-any.whl", hash = "sha256:188834565033387710d046e3fe96acfc9b5e86cbca7f39ff69cf21a4128198b7"},
-    {file = "zipp-3.14.0.tar.gz", hash = "sha256:9e5421e176ef5ab4c0ad896624e87a7b2f07aca746c9b2aa305952800cb8eecb"},
+    {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"},
+    {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"},
 ]
 
 [package.extras]
 docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
-testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"]
+testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"]
 
 [metadata]
 lock-version = "2.0"
From 35aae85c8d723d338309fc14d5846eba4e0c36c2 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Fri, 14 Apr 2023 19:16:30 +0200
Subject: [PATCH 13/46] Move dashboard templates to dashboard app
---
 gnuviechadmin/{ => dashboard}/templates/dashboard/index.html      | 0
 .../{ => dashboard}/templates/dashboard/user_dashboard.html       | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename gnuviechadmin/{ => dashboard}/templates/dashboard/index.html (100%)
 rename gnuviechadmin/{ => dashboard}/templates/dashboard/user_dashboard.html (100%)
diff --git a/gnuviechadmin/templates/dashboard/index.html b/gnuviechadmin/dashboard/templates/dashboard/index.html
similarity index 100%
rename from gnuviechadmin/templates/dashboard/index.html
rename to gnuviechadmin/dashboard/templates/dashboard/index.html
diff --git a/gnuviechadmin/templates/dashboard/user_dashboard.html b/gnuviechadmin/dashboard/templates/dashboard/user_dashboard.html
similarity index 100%
rename from gnuviechadmin/templates/dashboard/user_dashboard.html
rename to gnuviechadmin/dashboard/templates/dashboard/user_dashboard.html
From a5b65974fb16c4b8febd3e884db56ef2b809ad47 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Fri, 14 Apr 2023 19:16:58 +0200
Subject: [PATCH 14/46] Remove django-braces requirement
---
 gnuviechadmin/domains/views.py         |  5 +++--
 gnuviechadmin/hostingpackages/views.py | 22 +++++++++++++++-------
 poetry.lock                            | 17 +----------------
 pyproject.toml                         |  1 -
 4 files changed, 19 insertions(+), 26 deletions(-)
diff --git a/gnuviechadmin/domains/views.py b/gnuviechadmin/domains/views.py
index c81e3b4..ac387ec 100644
--- a/gnuviechadmin/domains/views.py
+++ b/gnuviechadmin/domains/views.py
@@ -4,8 +4,8 @@ This module defines views related to domains.
 """
 from __future__ import absolute_import
 
-from braces.views import StaffuserRequiredMixin
 from django.contrib import messages
+from django.contrib.auth.mixins import PermissionRequiredMixin
 from django.shortcuts import get_object_or_404, redirect
 from django.utils.translation import gettext as _
 from django.views.generic.edit import CreateView
@@ -16,7 +16,7 @@ from .forms import CreateHostingDomainForm
 from .models import HostingDomain
 
 
-class CreateHostingDomain(StaffuserRequiredMixin, CreateView):
+class CreateHostingDomain(PermissionRequiredMixin, CreateView):
     """
     This view is used for creating a new HostingDomain instance for an existing
     hosting package.
@@ -24,6 +24,7 @@ class CreateHostingDomain(StaffuserRequiredMixin, CreateView):
 
     model = HostingDomain
     raise_exception = True
+    permission_required = 'domains.add_hostingdomain'
     template_name_suffix = "_create"
     form_class = CreateHostingDomainForm
 
diff --git a/gnuviechadmin/hostingpackages/views.py b/gnuviechadmin/hostingpackages/views.py
index 82dffac..038acb2 100644
--- a/gnuviechadmin/hostingpackages/views.py
+++ b/gnuviechadmin/hostingpackages/views.py
@@ -4,10 +4,10 @@ This module defines views related to hosting packages.
 """
 from __future__ import absolute_import
 
-from braces.views import LoginRequiredMixin, StaffuserRequiredMixin
 from django.conf import settings
 from django.contrib import messages
 from django.contrib.auth import get_user_model
+from django.contrib.auth.mixins import PermissionRequiredMixin, UserPassesTestMixin
 from django.http import Http404
 from django.shortcuts import get_object_or_404, redirect
 from django.utils.translation import gettext as _
@@ -30,7 +30,7 @@ from .models import (
 )
 
 
-class CreateHostingPackage(LoginRequiredMixin, StaffuserRequiredMixin, CreateView):
+class CreateHostingPackage(PermissionRequiredMixin, CreateView):
     """
     Create a hosting package.
 
@@ -38,6 +38,7 @@ class CreateHostingPackage(LoginRequiredMixin, StaffuserRequiredMixin, CreateVie
 
     model = CustomerHostingPackage
     raise_exception = True
+    permission_required = 'domains.add_customerhostingpackage'
     template_name_suffix = "_create"
     form_class = CreateHostingPackageForm
 
@@ -120,9 +121,16 @@ class CustomerHostingPackageDetails(StaffOrSelfLoginRequiredMixin, DetailView):
         return context
 
 
-class AllCustomerHostingPackageList(
-    LoginRequiredMixin, StaffuserRequiredMixin, ListView
-):
+class StaffUserRequiredMixin(UserPassesTestMixin):
+    """
+    Mixin to make views available to staff members only.
+
+    """
+    def test_func(self):
+        return self.request.user.is_staff
+
+
+class AllCustomerHostingPackageList(StaffUserRequiredMixin, ListView):
     """
     This view is used for showing a list of all hosting packages.
 
@@ -161,7 +169,7 @@ class CustomerHostingPackageList(StaffOrSelfLoginRequiredMixin, ListView):
         )
 
 
-class HostingOptionChoices(LoginRequiredMixin, StaffuserRequiredMixin, DetailView):
+class HostingOptionChoices(StaffUserRequiredMixin, DetailView):
     """
     This view displays choices of hosting options for a customer hosting
     package.
@@ -205,7 +213,7 @@ class HostingOptionChoices(LoginRequiredMixin, StaffuserRequiredMixin, DetailVie
         return context
 
 
-class AddHostingOption(LoginRequiredMixin, StaffuserRequiredMixin, FormView):
+class AddHostingOption(StaffUserRequiredMixin, FormView):
     template_name = "hostingpackages/add_hosting_option.html"
 
     def get_form_class(self):
diff --git a/poetry.lock b/poetry.lock
index 876312e..720f7ea 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -638,21 +638,6 @@ python3-openid = ">=3.0.8"
 requests = "*"
 requests-oauthlib = ">=0.3.0"
 
-[[package]]
-name = "django-braces"
-version = "1.15.0"
-description = "Reusable, generic mixins for Django"
-category = "main"
-optional = false
-python-versions = "*"
-files = [
-    {file = "django-braces-1.15.0.tar.gz", hash = "sha256:f451d08ffc1078d81209a2e17f2219bce20196928853c82405451b18a46875e0"},
-    {file = "django_braces-1.15.0-py2.py3-none-any.whl", hash = "sha256:28f00b0f98368c9a37f30cce6087fc57127f0a24c5b8b449f9e1245bded6405d"},
-]
-
-[package.dependencies]
-Django = ">=2.2"
-
 [[package]]
 name = "django-crispy-forms"
 version = "1.14.0"
@@ -1757,4 +1742,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.7"
-content-hash = "c11eec493daca3a228f3c99300d0ebf0fa35060624c93649e2dce4c71cdf67f2"
+content-hash = "6041c8bb49cd1df098f1948f8ad2cbd48fd8f42ff44e410f3fecb61be7e80a18"
diff --git a/pyproject.toml b/pyproject.toml
index 12fc1af..3f3b448 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -12,7 +12,6 @@ django = "<4"
 psycopg2-binary = "^2.9"
 celery = "^5.2.7"
 django-allauth = "^0.52.0"
-django-braces = "^1.15.0"
 django-crispy-forms = "<2"
 django-debug-toolbar = "^3.8"
 django-model-utils = "^4.1"
From dd67ee91da68e563e9ffeac6c4345bd4163ca889 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Fri, 14 Apr 2023 19:33:44 +0200
Subject: [PATCH 15/46] Require login for index view
---
 gnuviechadmin/dashboard/tests/test_views.py         | 10 ++++++++++
 gnuviechadmin/dashboard/views.py                    |  3 ++-
 .../gnuviechadmin/tests/test_contextprocessors.py   | 13 +++++++++++--
 3 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/gnuviechadmin/dashboard/tests/test_views.py b/gnuviechadmin/dashboard/tests/test_views.py
index 2ff835b..dc1dde5 100644
--- a/gnuviechadmin/dashboard/tests/test_views.py
+++ b/gnuviechadmin/dashboard/tests/test_views.py
@@ -14,7 +14,17 @@ TEST_PASSWORD = "secret"
 
 
 class IndexViewTest(TestCase):
+    def test_index_view_anonymous(self):
+        response = self.client.get(reverse("dashboard"))
+        self.assertRedirects(response, "/accounts/login/?next=/")
+
     def test_index_view(self):
+        user = User.objects.create(username=TEST_USER)
+        user.set_password(TEST_PASSWORD)
+        user.save()
+
+        self.client.login(username=TEST_USER, password=TEST_PASSWORD)
+
         response = self.client.get(reverse("dashboard"))
         self.assertEqual(response.status_code, 200)
         self.assertTemplateUsed(response, "dashboard/index.html")
diff --git a/gnuviechadmin/dashboard/views.py b/gnuviechadmin/dashboard/views.py
index af9d7e0..7f30316 100644
--- a/gnuviechadmin/dashboard/views.py
+++ b/gnuviechadmin/dashboard/views.py
@@ -3,13 +3,14 @@ This module defines the views for the gnuviechadmin customer dashboard.
 
 """
 from django.contrib.auth import get_user_model
+from django.contrib.auth.mixins import LoginRequiredMixin
 from django.views.generic import DetailView, TemplateView
 from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin
 
 from hostingpackages.models import CustomerHostingPackage
 
 
-class IndexView(TemplateView):
+class IndexView(LoginRequiredMixin, TemplateView):
     """
     This is the dashboard view.
 
diff --git a/gnuviechadmin/gnuviechadmin/tests/test_contextprocessors.py b/gnuviechadmin/gnuviechadmin/tests/test_contextprocessors.py
index 664e8d2..94578cd 100644
--- a/gnuviechadmin/gnuviechadmin/tests/test_contextprocessors.py
+++ b/gnuviechadmin/gnuviechadmin/tests/test_contextprocessors.py
@@ -18,13 +18,16 @@ from gnuviechadmin.context_processors import navigation
 
 User = get_user_model()
 
+TEST_USER = "test"
+TEST_PASSWORD = "secret"
+
 
 class NavigationContextProcessorTest(TestCase):
 
     EXPECTED_ITEMS = ("webmail_url", "phpmyadmin_url", "phppgadmin_url", "active_item")
 
     def test_ajax_request(self):
-        response = self.client.get("/", HTTP_X_REQUESTED_WITH="XMLHttpRequest")
+        response = self.client.get("/accounts/login/", HTTP_X_REQUESTED_WITH="XMLHttpRequest")
         for item in self.EXPECTED_ITEMS:
             self.assertNotIn(item, response.context)
 
@@ -34,6 +37,12 @@ class NavigationContextProcessorTest(TestCase):
         self.assertEqual(context["phppgadmin_url"], settings.GVA_LINK_PHPPGADMIN)
 
     def test_index_page_context(self):
+        user = User.objects.create(username=TEST_USER)
+        user.set_password(TEST_PASSWORD)
+        user.save()
+
+        self.client.login(username=TEST_USER, password=TEST_PASSWORD)
+
         response = self.client.get("/")
         for item in self.EXPECTED_ITEMS:
             self.assertIn(item, response.context)
@@ -106,6 +115,6 @@ class NavigationContextProcessorTest(TestCase):
 
 class VersionInfoContextProcessorTest(TestCase):
     def test_version_info_in_context(self):
-        response = self.client.get("/")
+        response = self.client.get("/accounts/login/")
         self.assertIn("gnuviechadmin_version", response.context)
         self.assertEqual(response.context["gnuviechadmin_version"], gvaversion)
From 472e27230594df92b152e94d24ca447600e5f992 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Fri, 14 Apr 2023 19:56:41 +0200
Subject: [PATCH 16/46] Remove Twitter login, disable signups
---
 gnuviechadmin/gnuviechadmin/auth.py           | 11 +++++
 gnuviechadmin/gnuviechadmin/settings.py       |  3 +-
 gnuviechadmin/templates/account/login.html    | 47 +++++++++----------
 .../socialaccount/snippets/provider_list.html | 40 ++++++++--------
 4 files changed, 56 insertions(+), 45 deletions(-)
 create mode 100644 gnuviechadmin/gnuviechadmin/auth.py
diff --git a/gnuviechadmin/gnuviechadmin/auth.py b/gnuviechadmin/gnuviechadmin/auth.py
new file mode 100644
index 0000000..f493471
--- /dev/null
+++ b/gnuviechadmin/gnuviechadmin/auth.py
@@ -0,0 +1,11 @@
+from allauth.account.adapter import DefaultAccountAdapter
+
+
+class NoNewUsersAccountAdapter(DefaultAccountAdapter):
+    """
+    Adapter to disable allauth new signups
+
+    """
+
+    def is_open_for_signup(self, request):
+        return False
diff --git a/gnuviechadmin/gnuviechadmin/settings.py b/gnuviechadmin/gnuviechadmin/settings.py
index 5e3e890..b1a6d1c 100644
--- a/gnuviechadmin/gnuviechadmin/settings.py
+++ b/gnuviechadmin/gnuviechadmin/settings.py
@@ -216,7 +216,6 @@ ALLAUTH_APPS = (
     "allauth.socialaccount",
     "allauth.socialaccount.providers.google",
     "allauth.socialaccount.providers.linkedin_oauth2",
-    "allauth.socialaccount.providers.twitter",
 )
 
 # Apps specific for this project go here.
@@ -251,9 +250,11 @@ MESSAGE_TAGS = {
 
 
 # ######### ALLAUTH CONFIGURATION
+ACCOUNT_ADAPTER = "gnuviechadmin.auth.NoNewUsersAccountAdapter"
 ACCOUNT_EMAIL_REQUIRED = True
 ACCOUNT_EMAIL_VERIFICATION = "mandatory"
 LOGIN_REDIRECT_URL = "/"
+SOCIALACCOUNT_AUTO_SIGNUP = False
 SOCIALACCOUNT_QUERY_EMAIL = True
 # ######### END ALLAUTH CONFIGURATION
 
diff --git a/gnuviechadmin/templates/account/login.html b/gnuviechadmin/templates/account/login.html
index 88862b6..57f9b1c 100644
--- a/gnuviechadmin/templates/account/login.html
+++ b/gnuviechadmin/templates/account/login.html
@@ -5,32 +5,29 @@
 {% block page_title %}{% trans "Sign In" %}{% endblock page_title %}
 
 {% block content %}
-{% get_providers as socialaccount_providers %}
-{% if socialaccount_providers  %}
-{% blocktrans with site.name as site_name %}Please sign in with one
-of your existing third party accounts. Or, sign up 
-for a {{site_name}} account and sign in below:{% endblocktrans %}
-
-
-  {% include "socialaccount/snippets/provider_list.html" with process="login" %}
- 
-{% trans 'or' %}
-{% else %}
-{% blocktrans %}If you have not created an account yet, then please
-sign up  first.{% endblocktrans %}
-{% endif %}
-
-
+    {% get_providers as socialaccount_providers %}
+    
+        
+        
+            {% if socialaccount_providers %}
+                
+                    {% include "socialaccount/snippets/provider_list.html" with process="login" %}
+                 
+            {% endif %}
+        
+    
-  {{brand.name}} 
- 
-{% endfor %}
-{% endif %}
-
-   {{provider.name}} 
- 
-{% endfor %}
-
+
+    {% for provider in socialaccount_providers %}
+        {% if provider.id == "openid" %}
+            {% for brand in provider.get_brands %}
+                
+                    {{ brand.name }} 
+                 
+            {% endfor %}
+        {% endif %}
+        
+             {{ provider.name }}
+             
+         
+    {% endfor %}
+ 
From d499b781d4d349561068d7af7ef07fd62cd6d8ef Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sat, 15 Apr 2023 11:48:53 +0200
Subject: [PATCH 17/46] Implement impersonation
---
 gnuviechadmin/gnuviechadmin/settings.py       | 70 ++++++++++---------
 gnuviechadmin/gnuviechadmin/urls.py           |  3 +-
 gnuviechadmin/templates/base.html             |  9 ++-
 .../templates/impersonate/list_users.html     | 31 ++++++++
 .../templates/impersonate/search_users.html   | 45 ++++++++++++
 poetry.lock                                   | 13 +++-
 pyproject.toml                                |  1 +
 7 files changed, 135 insertions(+), 37 deletions(-)
 create mode 100644 gnuviechadmin/templates/impersonate/list_users.html
 create mode 100644 gnuviechadmin/templates/impersonate/search_users.html
diff --git a/gnuviechadmin/gnuviechadmin/settings.py b/gnuviechadmin/gnuviechadmin/settings.py
index b1a6d1c..243b6e8 100644
--- a/gnuviechadmin/gnuviechadmin/settings.py
+++ b/gnuviechadmin/gnuviechadmin/settings.py
@@ -86,7 +86,6 @@ USE_TZ = True
 
 LOCALE_PATHS = (normpath(join(SITE_ROOT, "gnuviechadmin", "locale")),)
 
-
 # ######### MEDIA CONFIGURATION
 # See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root
 MEDIA_ROOT = normpath(join(SITE_ROOT, "media"))
@@ -180,7 +179,6 @@ AUTHENTICATION_BACKENDS = (
     "allauth.account.auth_backends.AuthenticationBackend",
 )
 
-
 # ######### URL CONFIGURATION
 # See: https://docs.djangoproject.com/en/dev/ref/settings/#root-urlconf
 ROOT_URLCONF = "%s.urls" % SITE_NAME
@@ -208,6 +206,7 @@ DJANGO_APPS = (
     # Flatpages for about page
     "django.contrib.flatpages",
     "crispy_forms",
+    "impersonate",
 )
 
 ALLAUTH_APPS = (
@@ -277,7 +276,7 @@ LOGGING = {
     "formatters": {
         "verbose": {
             "format": "%(levelname)s %(asctime)s %(name)s "
-            "%(module)s:%(lineno)d %(process)d %(thread)d %(message)s"
+                      "%(module)s:%(lineno)d %(process)d %(thread)d %(message)s"
         },
         "simple": {"format": "%(levelname)s %(name)s:%(lineno)d %(message)s"},
     },
@@ -366,7 +365,10 @@ def show_debug_toolbar(request):
 # See: http://django-debug-toolbar.readthedocs.org/en/latest/installation.html#explicit-setup # noqa
 INSTALLED_APPS += ("debug_toolbar",)
 
-MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"]
+MIDDLEWARE += [
+    "impersonate.middleware.ImpersonateMiddleware",
+    "debug_toolbar.middleware.DebugToolbarMiddleware",
+]
 
 DEBUG_TOOLBAR_CONFIG = {
     "SHOW_TOOLBAR_CALLBACK": "gnuviechadmin.settings.show_debug_toolbar"
@@ -403,21 +405,21 @@ if GVA_ENVIRONMENT == "local":
             [
                 (key, {"handlers": ["console"], "level": "DEBUG", "propagate": True})
                 for key in [
-                    "dashboard",
-                    "domains",
-                    "fileservertasks",
-                    "gvacommon",
-                    "gvawebcore",
-                    "hostingpackages",
-                    "ldaptasks",
-                    "managemails",
-                    "mysqltasks",
-                    "osusers",
-                    "pgsqltasks",
-                    "taskresults",
-                    "userdbs",
-                    "websites",
-                ]
+                "dashboard",
+                "domains",
+                "fileservertasks",
+                "gvacommon",
+                "gvawebcore",
+                "hostingpackages",
+                "ldaptasks",
+                "managemails",
+                "mysqltasks",
+                "osusers",
+                "pgsqltasks",
+                "taskresults",
+                "userdbs",
+                "websites",
+            ]
             ]
         )
     )
@@ -438,21 +440,21 @@ elif GVA_ENVIRONMENT == "test":
             [
                 (key, {"handlers": ["console"], "level": "ERROR", "propagate": True})
                 for key in [
-                    "dashboard",
-                    "domains",
-                    "fileservertasks",
-                    "gvacommon",
-                    "gvawebcore",
-                    "hostingpackages",
-                    "ldaptasks",
-                    "managemails",
-                    "mysqltasks",
-                    "osusers",
-                    "pgsqltasks",
-                    "taskresults",
-                    "userdbs",
-                    "websites",
-                ]
+                "dashboard",
+                "domains",
+                "fileservertasks",
+                "gvacommon",
+                "gvawebcore",
+                "hostingpackages",
+                "ldaptasks",
+                "managemails",
+                "mysqltasks",
+                "osusers",
+                "pgsqltasks",
+                "taskresults",
+                "userdbs",
+                "websites",
+            ]
             ]
         )
     )
diff --git a/gnuviechadmin/gnuviechadmin/urls.py b/gnuviechadmin/gnuviechadmin/urls.py
index 8be802e..8bcfca5 100644
--- a/gnuviechadmin/gnuviechadmin/urls.py
+++ b/gnuviechadmin/gnuviechadmin/urls.py
@@ -11,6 +11,8 @@ admin.autodiscover()
 
 urlpatterns = [
     re_path(r"", include("dashboard.urls")),
+    re_path(r"^admin/", admin.site.urls),
+    re_path(r"^impersonate/", include("impersonate.urls")),
     re_path(r"^accounts/", include("allauth.urls")),
     re_path(r"^database/", include("userdbs.urls")),
     re_path(r"^domains/", include("domains.urls")),
@@ -18,7 +20,6 @@ urlpatterns = [
     re_path(r"^website/", include("websites.urls")),
     re_path(r"^mail/", include("managemails.urls")),
     re_path(r"^osuser/", include("osusers.urls")),
-    re_path(r"^admin/", admin.site.urls),
     re_path(r"^contact/", include("contact_form.urls")),
     re_path(r"^impressum/$", views.flatpage, {"url": "/impressum/"}, name="imprint"),
 ]
diff --git a/gnuviechadmin/templates/base.html b/gnuviechadmin/templates/base.html
index 8040f63..de0c35b 100644
--- a/gnuviechadmin/templates/base.html
+++ b/gnuviechadmin/templates/base.html
@@ -71,6 +71,7 @@
             
               
+        {% trans "List all users" %} 
+    
+
+    
+        {% if query and page.object_list %}
+            
+                {% for user in page.object_list %}
+                    {{ user }}  - Impersonate
+                     
+        {% endif %}
+                                                                                                          
+
+    
+        {% if query and page.has_previous %}
+            Previous
+                Page   
+        {% endif %}
+
+        {% if query and page.has_next %}
+            Next
+                Page 
+        {% endif %}
+    
+{% endblock %}
\ No newline at end of file
diff --git a/poetry.lock b/poetry.lock
index 720f7ea..9825743 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -666,6 +666,17 @@ files = [
 django = ">=3.2.4"
 sqlparse = ">=0.2"
 
+[[package]]
+name = "django-impersonate"
+version = "1.9.1"
+description = "Django app to allow superusers to impersonate other users."
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+    {file = "django-impersonate-1.9.1.tar.gz", hash = "sha256:0befdb096198b458507239a6f21574c9e0f608ab01fad352d71eb9284e5bb9c9"},
+]
+
 [[package]]
 name = "django-model-utils"
 version = "4.3.1"
@@ -1742,4 +1753,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.7"
-content-hash = "6041c8bb49cd1df098f1948f8ad2cbd48fd8f42ff44e410f3fecb61be7e80a18"
+content-hash = "dd56e0233689448f08dfcae943871bf9d72c05ad7bfd326c69f9ecb33ea8a461"
diff --git a/pyproject.toml b/pyproject.toml
index 3f3b448..3fcd8d1 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -19,6 +19,7 @@ gvacommon = {version = "^0.6.0", source = "gnuviech"}
 passlib = "^1.7.4"
 redis = "^4.5.1"
 requests-oauthlib = "^1.3.1"
+django-impersonate = "^1.9.1"
 
 
 [tool.poetry.group.dev.dependencies]
From 345b32f28679cb0d40e5dba4d08ec7c61c2ae928 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sat, 15 Apr 2023 12:06:44 +0200
Subject: [PATCH 18/46] Remove unused powerdns support tables
---
 gnuviechadmin/domains/admin.py                |  19 +-
 .../0005_remove_unused_pdns_tables.py         |  74 ++++
 gnuviechadmin/domains/models.py               | 330 ------------------
 3 files changed, 75 insertions(+), 348 deletions(-)
 create mode 100644 gnuviechadmin/domains/migrations/0005_remove_unused_pdns_tables.py
diff --git a/gnuviechadmin/domains/admin.py b/gnuviechadmin/domains/admin.py
index 87be497..0369116 100644
--- a/gnuviechadmin/domains/admin.py
+++ b/gnuviechadmin/domains/admin.py
@@ -5,24 +5,7 @@ with the django admin site.
 """
 from django.contrib import admin
 
-from .models import (
-    DNSComment,
-    DNSCryptoKey,
-    DNSDomain,
-    DNSDomainMetadata,
-    DNSRecord,
-    DNSSupermaster,
-    DNSTSIGKey,
-    HostingDomain,
-    MailDomain,
-)
+from domains.models import HostingDomain, MailDomain
 
 admin.site.register(MailDomain)
 admin.site.register(HostingDomain)
-admin.site.register(DNSComment)
-admin.site.register(DNSCryptoKey)
-admin.site.register(DNSDomain)
-admin.site.register(DNSDomainMetadata)
-admin.site.register(DNSRecord)
-admin.site.register(DNSSupermaster)
-admin.site.register(DNSTSIGKey)
diff --git a/gnuviechadmin/domains/migrations/0005_remove_unused_pdns_tables.py b/gnuviechadmin/domains/migrations/0005_remove_unused_pdns_tables.py
new file mode 100644
index 0000000..87e9c32
--- /dev/null
+++ b/gnuviechadmin/domains/migrations/0005_remove_unused_pdns_tables.py
@@ -0,0 +1,74 @@
+# Generated by Django 3.2.18 on 2023-04-15 09:53
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('domains', '0004_auto_20151107_1708'),
+    ]
+
+    operations = [
+        migrations.AlterIndexTogether(
+            name='dnscomment',
+            index_together=None,
+        ),
+        migrations.RemoveField(
+            model_name='dnscomment',
+            name='customer',
+        ),
+        migrations.RemoveField(
+            model_name='dnscomment',
+            name='domain',
+        ),
+        migrations.RemoveField(
+            model_name='dnscryptokey',
+            name='domain',
+        ),
+        migrations.RemoveField(
+            model_name='dnsdomain',
+            name='customer',
+        ),
+        migrations.RemoveField(
+            model_name='dnsdomainmetadata',
+            name='domain',
+        ),
+        migrations.AlterIndexTogether(
+            name='dnsrecord',
+            index_together=None,
+        ),
+        migrations.RemoveField(
+            model_name='dnsrecord',
+            name='domain',
+        ),
+        migrations.AlterUniqueTogether(
+            name='dnssupermaster',
+            unique_together=None,
+        ),
+        migrations.RemoveField(
+            model_name='dnssupermaster',
+            name='customer',
+        ),
+        migrations.DeleteModel(
+            name='DNSTSIGKey',
+        ),
+        migrations.DeleteModel(
+            name='DNSComment',
+        ),
+        migrations.DeleteModel(
+            name='DNSCryptoKey',
+        ),
+        migrations.DeleteModel(
+            name='DNSDomain',
+        ),
+        migrations.DeleteModel(
+            name='DNSDomainMetadata',
+        ),
+        migrations.DeleteModel(
+            name='DNSRecord',
+        ),
+        migrations.DeleteModel(
+            name='DNSSupermaster',
+        ),
+    ]
diff --git a/gnuviechadmin/domains/models.py b/gnuviechadmin/domains/models.py
index 00a96e3..7332dd6 100644
--- a/gnuviechadmin/domains/models.py
+++ b/gnuviechadmin/domains/models.py
@@ -7,45 +7,8 @@ from __future__ import absolute_import
 from django.conf import settings
 from django.db import models, transaction
 from django.utils.translation import gettext as _
-from model_utils import Choices
 from model_utils.models import TimeStampedModel
 
-DNS_DOMAIN_TYPES = Choices(
-    ("MASTER", _("Master")),
-    ("SLAVE", _("Slave")),
-    ("NATIVE", _("Native")),
-)
-
-# see https://doc.powerdns.com/md/authoritative/domainmetadata/
-DNS_DOMAIN_METADATA_KINDS = Choices(
-    "ALLOW-DNSUPDATE-FROM",
-    "ALSO-NOTIFY",
-    "AXFR-MASTER-TSIG",
-    "AXFR-SOURCE",
-    "FORWARD-DNSUPDATE",
-    "GSS-ACCEPTOR-PRINCIPAL",
-    "GSS-ALLOW-AXFR-PRINCIPAL",
-    "LUA-AXFR-SCRIPT",
-    "NSEC3NARROW",
-    "NSEC3PARAM",
-    "PRESIGNED",
-    "PUBLISH_CDNSKEY",
-    "PUBLISH_CDS",
-    "SOA-EDIT",
-    "SOA-EDIT-DNSUPDATE",
-    "TSIG-ALLOW-AXFR",
-    "TSIG-ALLOW-DNSUPDATE",
-)
-
-DNS_TSIG_KEY_ALGORITHMS = Choices(
-    ("hmac-md5", _("HMAC MD5")),
-    ("hmac-sha1", _("HMAC SHA1")),
-    ("hmac-sha224", _("HMAC SHA224")),
-    ("hmac-sha256", _("HMAC SHA256")),
-    ("hmac-sha384", _("HMAC SHA384")),
-    ("hmac-sha512", _("HMAC SHA512")),
-)
-
 
 class DomainBase(TimeStampedModel):
     """
@@ -140,296 +103,3 @@ class HostingDomain(DomainBase):
 
     def __str__(self):
         return self.domain
-
-
-class DNSDomain(DomainBase):
-    """
-    This model represents a DNS zone. The model is similar to the domain table
-    in the PowerDNS schema specified in
-    https://doc.powerdns.com/md/authoritative/backend-generic-mypgsql/.
-
-    .. code-block:: sql
-
-       CREATE TABLE domains (
-         id                    SERIAL PRIMARY KEY,
-         name                  VARCHAR(255) NOT NULL,
-         master                VARCHAR(128) DEFAULT NULL,
-         last_check            INT DEFAULT NULL,
-         type                  VARCHAR(6) NOT NULL,
-         notified_serial       INT DEFAULT NULL,
-         account               VARCHAR(40) DEFAULT NULL,
-         CONSTRAINT c_lowercase_name CHECK (
-             ((name)::TEXT = LOWER((name)::TEXT)))
-       );
-
-       CREATE UNIQUE INDEX name_index ON domains(name);
-
-    """
-
-    # name is represented by domain
-    master = models.CharField(max_length=128, blank=True, null=True)
-    last_check = models.IntegerField(null=True)
-    domaintype = models.CharField(
-        max_length=6, choices=DNS_DOMAIN_TYPES, db_column="type"
-    )
-    notified_serial = models.IntegerField(null=True)
-    # account is represented by customer_id
-    # check constraint is added via RunSQL in migration
-
-    class Meta:
-        verbose_name = _("DNS domain")
-        verbose_name_plural = _("DNS domains")
-
-    def __str__(self):
-        return self.domain
-
-
-class DNSRecord(models.Model):
-    """
-    This model represents a DNS record. The model is similar to the record
-    table in the PowerDNS schema specified in
-    https://doc.powerdns.com/md/authoritative/backend-generic-mypgsql/.
-
-    .. code-block:: sql
-
-       CREATE TABLE records (
-         id                    SERIAL PRIMARY KEY,
-         domain_id             INT DEFAULT NULL,
-         name                  VARCHAR(255) DEFAULT NULL,
-         type                  VARCHAR(10) DEFAULT NULL,
-         content               VARCHAR(65535) DEFAULT NULL,
-         ttl                   INT DEFAULT NULL,
-         prio                  INT DEFAULT NULL,
-         change_date           INT DEFAULT NULL,
-         disabled              BOOL DEFAULT 'f',
-         ordername             VARCHAR(255),
-         auth                  BOOL DEFAULT 't',
-         CONSTRAINT domain_exists
-         FOREIGN KEY(domain_id) REFERENCES domains(id)
-         ON DELETE CASCADE,
-         CONSTRAINT c_lowercase_name CHECK (
-             ((name)::TEXT = LOWER((name)::TEXT)))
-       );
-
-       CREATE INDEX rec_name_index ON records(name);
-       CREATE INDEX nametype_index ON records(name,type);
-       CREATE INDEX domain_id ON records(domain_id);
-       CREATE INDEX recordorder ON records (
-           domain_id, ordername text_pattern_ops);
-
-    """
-
-    domain = models.ForeignKey("DNSDomain", on_delete=models.CASCADE)
-    name = models.CharField(max_length=255, blank=True, null=True, db_index=True)
-    recordtype = models.CharField(
-        max_length=10, blank=True, null=True, db_column="type"
-    )
-    content = models.CharField(max_length=65535, blank=True, null=True)
-    ttl = models.IntegerField(null=True)
-    prio = models.IntegerField(null=True)
-    change_date = models.IntegerField(null=True)
-    disabled = models.BooleanField(default=False)
-    ordername = models.CharField(max_length=255)
-    auth = models.BooleanField(default=True)
-    # check constraint and index recordorder are added via RunSQL in migration
-
-    class Meta:
-        verbose_name = _("DNS record")
-        verbose_name_plural = _("DNS records")
-        index_together = [["name", "recordtype"]]
-
-    def __str__(self):
-        return "{name} IN {type} {content}".format(
-            name=self.name, type=self.recordtype, content=self.content
-        )
-
-
-class DNSSupermaster(models.Model):
-    """
-    This model represents the supermasters table in the PowerDNS schema
-    specified in
-    https://doc.powerdns.com/md/authoritative/backend-generic-mypgsql/.
-
-    .. code-block:: sql
-
-       CREATE TABLE supermasters (
-         ip                    INET NOT NULL,
-         nameserver            VARCHAR(255) NOT NULL,
-         account               VARCHAR(40) NOT NULL,
-         PRIMARY KEY(ip, nameserver)
-       );
-
-    """
-
-    ip = models.GenericIPAddressField()
-    nameserver = models.CharField(max_length=255)
-    # account is replaced by customer
-    customer = models.ForeignKey(
-        settings.AUTH_USER_MODEL, verbose_name=_("customer"), on_delete=models.CASCADE
-    )
-
-    class Meta:
-        verbose_name = _("DNS supermaster")
-        verbose_name_plural = _("DNS supermasters")
-        unique_together = ("ip", "nameserver")
-
-    def __str__(self):
-        return "{ip} {nameserver}".format(ip=self.ip, nameserver=self.nameserver)
-
-
-class DNSComment(models.Model):
-    """
-    This model represents the comments table in the PowerDNS schema specified
-    in https://doc.powerdns.com/md/authoritative/backend-generic-mypgsql/. The
-    comments table is used to store user comments related to individual DNS
-    records.
-
-    .. code-block:: sql
-
-       CREATE TABLE comments (
-         id                    SERIAL PRIMARY KEY,
-         domain_id             INT NOT NULL,
-         name                  VARCHAR(255) NOT NULL,
-         type                  VARCHAR(10) NOT NULL,
-         modified_at           INT NOT NULL,
-         account               VARCHAR(40) DEFAULT NULL,
-         comment               VARCHAR(65535) NOT NULL,
-         CONSTRAINT domain_exists
-         FOREIGN KEY(domain_id) REFERENCES domains(id)
-         ON DELETE CASCADE,
-         CONSTRAINT c_lowercase_name CHECK (
-             ((name)::TEXT = LOWER((name)::TEXT)))
-       );
-
-       CREATE INDEX comments_domain_id_idx ON comments (domain_id);
-       CREATE INDEX comments_name_type_idx ON comments (name, type);
-       CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);
-
-    """
-
-    domain = models.ForeignKey("DNSDomain", on_delete=models.CASCADE)
-    name = models.CharField(max_length=255)
-    commenttype = models.CharField(max_length=10, db_column="type")
-    modified_at = models.IntegerField()
-    # account is replaced by customer
-    customer = models.ForeignKey(
-        settings.AUTH_USER_MODEL, verbose_name=_("customer"), on_delete=models.CASCADE
-    )
-    comment = models.CharField(max_length=65535)
-    # check constraint is added via RunSQL in migration
-
-    class Meta:
-        verbose_name = _("DNS comment")
-        verbose_name_plural = _("DNS comments")
-        index_together = [["name", "commenttype"], ["domain", "modified_at"]]
-
-    def __str__(self):
-        return "{name} IN {type}: {comment}".format(
-            name=self.name, type=self.commenttype, comment=self.comment
-        )
-
-
-class DNSDomainMetadata(models.Model):
-    """
-    This model represents the domainmetadata table in the PowerDNS schema
-    specified in
-    https://doc.powerdns.com/md/authoritative/backend-generic-mypgsql/.
-    The domainmetadata table is used to store domain meta data as described in
-    https://doc.powerdns.com/md/authoritative/domainmetadata/.
-
-    .. code-block:: sql
-
-       CREATE TABLE domainmetadata (
-         id                    SERIAL PRIMARY KEY,
-         domain_id             INT REFERENCES domains(id) ON DELETE CASCADE,
-         kind                  VARCHAR(32),
-         content               TEXT
-       );
-
-       CREATE INDEX domainidmetaindex ON domainmetadata(domain_id);
-
-    """
-
-    domain = models.ForeignKey("DNSDomain", on_delete=models.CASCADE)
-    kind = models.CharField(max_length=32, choices=DNS_DOMAIN_METADATA_KINDS)
-    content = models.TextField()
-
-    class Meta:
-        verbose_name = _("DNS domain metadata item")
-        verbose_name_plural = _("DNS domain metadata items")
-
-    def __str__(self):
-        return "{domain} {kind} {content}".format(
-            domain=self.domain.domain, kind=self.kind, content=self.content
-        )
-
-
-class DNSCryptoKey(models.Model):
-    """
-    This model represents the cryptokeys table in the PowerDNS schema
-    specified in
-    https://doc.powerdns.com/md/authoritative/backend-generic-mypgsql/.
-
-    .. code-block:: sql
-
-       CREATE TABLE cryptokeys (
-         id                    SERIAL PRIMARY KEY,
-         domain_id             INT REFERENCES domains(id) ON DELETE CASCADE,
-         flags                 INT NOT NULL,
-         active                BOOL,
-         content               TEXT
-       );
-
-       CREATE INDEX domainidindex ON cryptokeys(domain_id);
-
-    """
-
-    domain = models.ForeignKey("DNSDomain", on_delete=models.CASCADE)
-    flags = models.IntegerField()
-    active = models.BooleanField(default=True)
-    content = models.TextField()
-
-    class Meta:
-        verbose_name = _("DNS crypto key")
-        verbose_name_plural = _("DNS crypto keys")
-
-    def __str__(self):
-        return "{domain} {content}".format(
-            domain=self.domain.domain, content=self.content
-        )
-
-
-class DNSTSIGKey(models.Model):
-    """
-    This model represents the tsigkeys table in the PowerDNS schema specified
-    in https://doc.powerdns.com/md/authoritative/backend-generic-mypgsql/.
-
-    .. code-block:: sql
-
-       CREATE TABLE tsigkeys (
-         id                    SERIAL PRIMARY KEY,
-         name                  VARCHAR(255),
-         algorithm             VARCHAR(50),
-         secret                VARCHAR(255),
-         CONSTRAINT c_lowercase_name CHECK (
-             ((name)::TEXT = LOWER((name)::TEXT)))
-       );
-
-       CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);
-
-    """
-
-    name = models.CharField(max_length=255)
-    algorithm = models.CharField(max_length=50, choices=DNS_TSIG_KEY_ALGORITHMS)
-    secret = models.CharField(max_length=255)
-    # check constraint is added via RunSQL in migration
-
-    class Meta:
-        verbose_name = _("DNS TSIG key")
-        verbose_name_plural = _("DNS TSIG keys")
-        unique_together = [["name", "algorithm"]]
-
-    def __str__(self):
-        return "{name} {algorithm} XXXX".format(
-            name=self.name, algorithm=self.algorithm
-        )
From e44bdd7be2270915ee8bef993c8ffc6276f1527b Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sat, 15 Apr 2023 12:07:12 +0200
Subject: [PATCH 19/46] Bump version to 0.13.0
---
 gnuviechadmin/gnuviechadmin/__init__.py | 2 +-
 pyproject.toml                          | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/gnuviechadmin/gnuviechadmin/__init__.py b/gnuviechadmin/gnuviechadmin/__init__.py
index 1fd249f..7dfb6e8 100644
--- a/gnuviechadmin/gnuviechadmin/__init__.py
+++ b/gnuviechadmin/gnuviechadmin/__init__.py
@@ -1,4 +1,4 @@
 # import celery_app to initialize it
 from gnuviechadmin.celery import app as celery_app  # NOQA
 
-__version__ = '0.12.1'
+__version__ = "0.13.0"
diff --git a/pyproject.toml b/pyproject.toml
index 3fcd8d1..d28421e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "gva"
-version = "0.12.1"
+version = "0.13.0"
 description = "gnuviechadmin web interface"
 authors = ["Jan Dittberner "]
 license = "AGPL-3+"
From 37f3ed2506de71a8ecbeb29ce594d71880409af9 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sat, 15 Apr 2023 12:12:02 +0200
Subject: [PATCH 20/46] Update changelog
---
 docs/changelog.rst | 6 ++++++
 1 file changed, 6 insertions(+)
diff --git a/docs/changelog.rst b/docs/changelog.rst
index a8ef494..7e6be33 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -1,6 +1,12 @@
 Changelog
 =========
 
+* :support:`-` remove unused PowerDNS support tables from domains app
+* :feature:`-` add impersonation support for superusers
+* :support:`-` remove django-braces dependency
+* :support:`-` remove Twitter support
+* :support:`-` update dependencies
+
 * :release:`0.12.1 <2020-04-13>`
 * :bug:`7` fix handling of undefined mail domains in customer hosting package
   detail template
From 4b7e311c626fbc86fc914751063be13c9a7f9596 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sun, 16 Apr 2023 11:14:26 +0200
Subject: [PATCH 21/46] Remove tests for removed models
---
 gnuviechadmin/domains/tests/test_models.py | 60 +---------------------
 1 file changed, 2 insertions(+), 58 deletions(-)
diff --git a/gnuviechadmin/domains/tests/test_models.py b/gnuviechadmin/domains/tests/test_models.py
index fd6d645..ef3b0d8 100644
--- a/gnuviechadmin/domains/tests/test_models.py
+++ b/gnuviechadmin/domains/tests/test_models.py
@@ -7,19 +7,9 @@ from unittest.mock import patch
 from django.test import TestCase
 from django.contrib.auth import get_user_model
 
-from domains.models import (
-    DNSComment,
-    DNSCryptoKey,
-    DNSDomain,
-    DNSDomainMetadata,
-    DNSRecord,
-    DNSSupermaster,
-    DNSTSIGKey,
-    HostingDomain,
-    MailDomain,
-)
-from hostingpackages.models import CustomerHostingPackage, HostingPackageTemplate
+from domains.models import HostingDomain, MailDomain
 
+from hostingpackages.models import CustomerHostingPackage, HostingPackageTemplate
 
 User = get_user_model()
 
@@ -77,49 +67,3 @@ class HostingDomainTest(TestCase):
     def test___str__(self):
         hostingdomain = HostingDomain(domain="test")
         self.assertEqual(str(hostingdomain), "test")
-
-
-class DNSDomainTest(TestCase):
-    def test___str__(self):
-        dnsdomain = DNSDomain(domain="test")
-        self.assertEqual(str(dnsdomain), "test")
-
-
-class DNSRecordTest(TestCase):
-    def test___str__(self):
-        dnsrecord = DNSRecord(name="localhost", recordtype="A", content="127.0.0.1")
-        self.assertEqual(str(dnsrecord), "localhost IN A 127.0.0.1")
-
-
-class DNSSupermasterTest(TestCase):
-    def test___str__(self):
-        dnssupermaster = DNSSupermaster(ip="127.0.0.1", nameserver="dns.example.org")
-        self.assertEqual(str(dnssupermaster), "127.0.0.1 dns.example.org")
-
-
-class DNSCommentTest(TestCase):
-    def test___str__(self):
-        dnscomment = DNSComment(name="localhost", commenttype="A", comment="good stuff")
-        self.assertEqual(str(dnscomment), "localhost IN A: good stuff")
-
-
-class DNSDomainMetadataTest(TestCase):
-    def test___str__(self):
-        dnsdomain = DNSDomain(domain="test")
-        dnsdomainmetadata = DNSDomainMetadata(
-            domain=dnsdomain, kind="SOA-EDIT", content="INCEPTION"
-        )
-        self.assertEqual(str(dnsdomainmetadata), "test SOA-EDIT INCEPTION")
-
-
-class DNSCryptoKeyTest(TestCase):
-    def test___str__(self):
-        dnsdomain = DNSDomain(domain="test")
-        dnscryptokey = DNSCryptoKey(domain=dnsdomain, content="testvalue")
-        self.assertEqual(str(dnscryptokey), "test testvalue")
-
-
-class DNSTSIGKeyTest(TestCase):
-    def test___str__(self):
-        dnstsigkey = DNSTSIGKey(name="testkey", algorithm="hmac-md5", secret="dummykey")
-        self.assertEqual(str(dnstsigkey), "testkey hmac-md5 XXXX")
From f9ea88cd24a4712b85b48f99521abf6e7fc12094 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sun, 16 Apr 2023 12:20:37 +0200
Subject: [PATCH 22/46] Add new app 'help' for user support
This commit adds a new model that enhances the user profile with an
offline support code, a postal address and an email address to allow
users to reset their profile.
The commit adds to Django admin commands 'populate' and
'reset_offline_code' to maintain the help user profiles from the Django
command line.
---
 docs/changelog.rst                            |  2 +
 gnuviechadmin/gnuviechadmin/settings.py       | 39 ++-----------
 gnuviechadmin/help/__init__.py                |  0
 gnuviechadmin/help/admin.py                   | 22 ++++++++
 gnuviechadmin/help/apps.py                    |  8 +++
 gnuviechadmin/help/management/__init__.py     |  0
 .../help/management/commands/__init__.py      |  0
 .../help/management/commands/populate.py      | 17 ++++++
 .../management/commands/reset_offline_code.py | 29 ++++++++++
 .../0001_add_help_user_model_extension.py     | 55 +++++++++++++++++++
 gnuviechadmin/help/migrations/__init__.py     |  0
 gnuviechadmin/help/models.py                  | 17 ++++++
 gnuviechadmin/help/tests.py                   |  3 +
 gnuviechadmin/help/views.py                   |  3 +
 14 files changed, 161 insertions(+), 34 deletions(-)
 create mode 100644 gnuviechadmin/help/__init__.py
 create mode 100644 gnuviechadmin/help/admin.py
 create mode 100644 gnuviechadmin/help/apps.py
 create mode 100644 gnuviechadmin/help/management/__init__.py
 create mode 100644 gnuviechadmin/help/management/commands/__init__.py
 create mode 100644 gnuviechadmin/help/management/commands/populate.py
 create mode 100644 gnuviechadmin/help/management/commands/reset_offline_code.py
 create mode 100644 gnuviechadmin/help/migrations/0001_add_help_user_model_extension.py
 create mode 100644 gnuviechadmin/help/migrations/__init__.py
 create mode 100644 gnuviechadmin/help/models.py
 create mode 100644 gnuviechadmin/help/tests.py
 create mode 100644 gnuviechadmin/help/views.py
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 7e6be33..4aeb686 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -1,6 +1,8 @@
 Changelog
 =========
 
+* :feature:`-` add support model for offline account reset codes in new help
+  app
 * :support:`-` remove unused PowerDNS support tables from domains app
 * :feature:`-` add impersonation support for superusers
 * :support:`-` remove django-braces dependency
diff --git a/gnuviechadmin/gnuviechadmin/settings.py b/gnuviechadmin/gnuviechadmin/settings.py
index 243b6e8..089e171 100644
--- a/gnuviechadmin/gnuviechadmin/settings.py
+++ b/gnuviechadmin/gnuviechadmin/settings.py
@@ -232,6 +232,7 @@ LOCAL_APPS = (
     "userdbs",
     "hostingpackages",
     "websites",
+    "help",
     "contact_form",
 )
 
@@ -276,7 +277,7 @@ LOGGING = {
     "formatters": {
         "verbose": {
             "format": "%(levelname)s %(asctime)s %(name)s "
-                      "%(module)s:%(lineno)d %(process)d %(thread)d %(message)s"
+            "%(module)s:%(lineno)d %(process)d %(thread)d %(message)s"
         },
         "simple": {"format": "%(levelname)s %(name)s:%(lineno)d %(message)s"},
     },
@@ -404,23 +405,8 @@ if GVA_ENVIRONMENT == "local":
         dict(
             [
                 (key, {"handlers": ["console"], "level": "DEBUG", "propagate": True})
-                for key in [
-                "dashboard",
-                "domains",
-                "fileservertasks",
-                "gvacommon",
-                "gvawebcore",
-                "hostingpackages",
-                "ldaptasks",
-                "managemails",
-                "mysqltasks",
-                "osusers",
-                "pgsqltasks",
-                "taskresults",
-                "userdbs",
-                "websites",
-            ]
-            ]
+                for key in LOCAL_APPS
+            ],
         )
     )
 elif GVA_ENVIRONMENT == "test":
@@ -439,22 +425,7 @@ elif GVA_ENVIRONMENT == "test":
         dict(
             [
                 (key, {"handlers": ["console"], "level": "ERROR", "propagate": True})
-                for key in [
-                "dashboard",
-                "domains",
-                "fileservertasks",
-                "gvacommon",
-                "gvawebcore",
-                "hostingpackages",
-                "ldaptasks",
-                "managemails",
-                "mysqltasks",
-                "osusers",
-                "pgsqltasks",
-                "taskresults",
-                "userdbs",
-                "websites",
-            ]
+                for key in LOCAL_APPS
             ]
         )
     )
diff --git a/gnuviechadmin/help/__init__.py b/gnuviechadmin/help/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/gnuviechadmin/help/admin.py b/gnuviechadmin/help/admin.py
new file mode 100644
index 0000000..b143c6c
--- /dev/null
+++ b/gnuviechadmin/help/admin.py
@@ -0,0 +1,22 @@
+from django.contrib import admin
+from django.contrib.auth import get_user_model
+from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
+from django.utils.translation import ugettext_lazy as _
+
+from help.models import HelpUser
+
+User = get_user_model()
+
+
+class HelpUserInline(admin.StackedInline):
+    model = HelpUser
+    can_delete = False
+    readonly_fields = ("offline_account_code",)
+
+
+class UserAdmin(BaseUserAdmin):
+    inlines = (HelpUserInline,)
+
+
+admin.site.unregister(User)
+admin.site.register(User, UserAdmin)
diff --git a/gnuviechadmin/help/apps.py b/gnuviechadmin/help/apps.py
new file mode 100644
index 0000000..870ccf9
--- /dev/null
+++ b/gnuviechadmin/help/apps.py
@@ -0,0 +1,8 @@
+from django.apps import AppConfig
+from django.utils.translation import gettext_lazy as _
+
+
+class HelpConfig(AppConfig):
+    default_auto_field = "django.db.models.BigAutoField"
+    name = "help"
+    verbose_name = _("User self help")
diff --git a/gnuviechadmin/help/management/__init__.py b/gnuviechadmin/help/management/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/gnuviechadmin/help/management/commands/__init__.py b/gnuviechadmin/help/management/commands/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/gnuviechadmin/help/management/commands/populate.py b/gnuviechadmin/help/management/commands/populate.py
new file mode 100644
index 0000000..77ee7c3
--- /dev/null
+++ b/gnuviechadmin/help/management/commands/populate.py
@@ -0,0 +1,17 @@
+from django.contrib.auth import get_user_model
+from django.core.management import BaseCommand
+
+from help.models import HelpUser
+
+User = get_user_model()
+
+
+class Command(BaseCommand):
+    help = "Populate help user information for existing users"
+
+    def handle(self, *args, **options):
+        for user in User.objects.filter(helpuser=None):
+            help_user = HelpUser.objects.create(user_id=user.id, email_address=user.email)
+            help_user.generate_offline_account_code()
+            help_user.save()
+            self.stdout.write(f"created offline account code {help_user.offline_account_code} for {user}.")
diff --git a/gnuviechadmin/help/management/commands/reset_offline_code.py b/gnuviechadmin/help/management/commands/reset_offline_code.py
new file mode 100644
index 0000000..a93579d
--- /dev/null
+++ b/gnuviechadmin/help/management/commands/reset_offline_code.py
@@ -0,0 +1,29 @@
+from django.contrib.auth import get_user_model
+from django.core.management import BaseCommand, CommandError
+
+from help.models import HelpUser
+
+User = get_user_model()
+
+
+class Command(BaseCommand):
+    help = "Reset offline account reset code for existing users"
+
+    def add_arguments(self, parser):
+        parser.add_argument("users", nargs='+', type=str)
+
+    def handle(self, *args, **options):
+        for name in options["users"]:
+            try:
+                user = User.objects.get(username=name)
+            except User.DoesNotExist:
+                raise CommandError(f'User {name} does not exist')
+
+            help_user = user.helpuser
+            if help_user is None:
+                help_user = HelpUser.objects.create(email_address=user.email)
+
+            help_user.generate_offline_account_code()
+            help_user.save()
+
+            self.stdout.write(f"generated new offline account reset code {help_user.offline_account_code} for {name}")
diff --git a/gnuviechadmin/help/migrations/0001_add_help_user_model_extension.py b/gnuviechadmin/help/migrations/0001_add_help_user_model_extension.py
new file mode 100644
index 0000000..fb20210
--- /dev/null
+++ b/gnuviechadmin/help/migrations/0001_add_help_user_model_extension.py
@@ -0,0 +1,55 @@
+# Generated by Django 3.2.18 on 2023-04-16 09:32
+
+import django.db.models.deletion
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+    initial = True
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="HelpUser",
+            fields=[
+                (
+                    "id",
+                    models.BigAutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "email_address",
+                    models.EmailField(
+                        help_text="Contact email address", max_length=254
+                    ),
+                ),
+                (
+                    "postal_address",
+                    models.TextField(blank=True, help_text="Contact postal address"),
+                ),
+                (
+                    "offline_account_code",
+                    models.CharField(
+                        default="",
+                        help_text="Offline account reset code",
+                        max_length=36,
+                    ),
+                ),
+                (
+                    "user",
+                    models.OneToOneField(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
+            ],
+        ),
+    ]
diff --git a/gnuviechadmin/help/migrations/__init__.py b/gnuviechadmin/help/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/gnuviechadmin/help/models.py b/gnuviechadmin/help/models.py
new file mode 100644
index 0000000..5debb7e
--- /dev/null
+++ b/gnuviechadmin/help/models.py
@@ -0,0 +1,17 @@
+import uuid
+
+from django.conf import settings
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+
+
+class HelpUser(models.Model):
+    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
+    email_address = models.EmailField(help_text=_("Contact email address"))
+    postal_address = models.TextField(help_text=_("Contact postal address"), blank=True)
+    offline_account_code = models.CharField(
+        help_text=_("Offline account reset code"), max_length=36, default=""
+    )
+
+    def generate_offline_account_code(self):
+        self.offline_account_code = str(uuid.uuid4())
diff --git a/gnuviechadmin/help/tests.py b/gnuviechadmin/help/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/gnuviechadmin/help/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/gnuviechadmin/help/views.py b/gnuviechadmin/help/views.py
new file mode 100644
index 0000000..91ea44a
--- /dev/null
+++ b/gnuviechadmin/help/views.py
@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.
From 9731d4e793aba2aa75122dd3a221251ecd1a22d8 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sun, 16 Apr 2023 12:24:32 +0200
Subject: [PATCH 23/46] Add Django REST framework dependencies
---
 poetry.lock    | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-
 pyproject.toml |  3 +++
 2 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/poetry.lock b/poetry.lock
index 9825743..69ee4a3 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -666,6 +666,21 @@ files = [
 django = ">=3.2.4"
 sqlparse = ">=0.2"
 
+[[package]]
+name = "django-filter"
+version = "23.1"
+description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically."
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "django-filter-23.1.tar.gz", hash = "sha256:dee5dcf2cea4d7f767e271b6d01f767fce7500676d5e5dc58dac8154000b87df"},
+    {file = "django_filter-23.1-py3-none-any.whl", hash = "sha256:e3c52ad83c32fb5882125105efb5fea2a1d6a85e7dc64b04ef52edbf14451b6c"},
+]
+
+[package.dependencies]
+Django = ">=3.2"
+
 [[package]]
 name = "django-impersonate"
 version = "1.9.1"
@@ -692,6 +707,22 @@ files = [
 [package.dependencies]
 Django = ">=3.2"
 
+[[package]]
+name = "djangorestframework"
+version = "3.14.0"
+description = "Web APIs for Django, made easy."
+category = "main"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "djangorestframework-3.14.0-py3-none-any.whl", hash = "sha256:eb63f58c9f218e1a7d064d17a70751f528ed4e1d35547fdade9aaf4cd103fd08"},
+    {file = "djangorestframework-3.14.0.tar.gz", hash = "sha256:579a333e6256b09489cbe0a067e66abe55c6595d8926be6b99423786334350c8"},
+]
+
+[package.dependencies]
+django = ">=3.0"
+pytz = "*"
+
 [[package]]
 name = "docutils"
 version = "0.19"
@@ -850,6 +881,24 @@ sqs = ["boto3 (>=1.9.12)", "pycurl (>=7.44.1,<7.45.0)", "urllib3 (>=1.26.7)"]
 yaml = ["PyYAML (>=3.10)"]
 zookeeper = ["kazoo (>=1.3.1)"]
 
+[[package]]
+name = "markdown"
+version = "3.4.3"
+description = "Python implementation of John Gruber's Markdown."
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "Markdown-3.4.3-py3-none-any.whl", hash = "sha256:065fd4df22da73a625f14890dd77eb8040edcbd68794bcd35943be14490608b2"},
+    {file = "Markdown-3.4.3.tar.gz", hash = "sha256:8bf101198e004dc93e84a12a7395e31aac6a9c9942848ae1d99b9d72cf9b3520"},
+]
+
+[package.dependencies]
+importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""}
+
+[package.extras]
+testing = ["coverage", "pyyaml"]
+
 [[package]]
 name = "markupsafe"
 version = "2.1.2"
@@ -1753,4 +1802,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.7"
-content-hash = "dd56e0233689448f08dfcae943871bf9d72c05ad7bfd326c69f9ecb33ea8a461"
+content-hash = "12e95bb19c0dc9d4b1388423e1007628e37e5e13a217de01b27bb34b20d5ac34"
diff --git a/pyproject.toml b/pyproject.toml
index d28421e..5082329 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -20,6 +20,9 @@ passlib = "^1.7.4"
 redis = "^4.5.1"
 requests-oauthlib = "^1.3.1"
 django-impersonate = "^1.9.1"
+djangorestframework = "^3.14.0"
+markdown = "^3.4.3"
+django-filter = "^23.1"
 
 
 [tool.poetry.group.dev.dependencies]
From a65b1574dba558ee2b2115e977322a086758204f Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sun, 16 Apr 2023 13:21:57 +0200
Subject: [PATCH 24/46] Add admin user information REST API
---
 docs/changelog.rst                      |  1 +
 gnuviechadmin/gnuviechadmin/settings.py | 13 +++++++++++
 gnuviechadmin/gnuviechadmin/urls.py     |  9 ++++++++
 gnuviechadmin/help/serializers.py       | 30 +++++++++++++++++++++++++
 gnuviechadmin/help/views.py             | 30 +++++++++++++++++++++++--
 5 files changed, 81 insertions(+), 2 deletions(-)
 create mode 100644 gnuviechadmin/help/serializers.py
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 4aeb686..9dc3203 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -1,6 +1,7 @@
 Changelog
 =========
 
+* :feature:`-` add REST API to retrieve and set user information as admin
 * :feature:`-` add support model for offline account reset codes in new help
   app
 * :support:`-` remove unused PowerDNS support tables from domains app
diff --git a/gnuviechadmin/gnuviechadmin/settings.py b/gnuviechadmin/gnuviechadmin/settings.py
index 089e171..6d81694 100644
--- a/gnuviechadmin/gnuviechadmin/settings.py
+++ b/gnuviechadmin/gnuviechadmin/settings.py
@@ -207,6 +207,8 @@ DJANGO_APPS = (
     "django.contrib.flatpages",
     "crispy_forms",
     "impersonate",
+    "rest_framework",
+    "rest_framework.authtoken",
 )
 
 ALLAUTH_APPS = (
@@ -264,6 +266,17 @@ CRISPY_TEMPLATE_PACK = "bootstrap3"
 # ######### END CRISPY_FORMS CONFIGURATION
 
 
+# ######### REST FRAMEWORK CONFIGURATION
+REST_FRAMEWORK = {
+    "DEFAULT_AUTHENTICATION_CLASSES": [
+        "rest_framework.authentication.BasicAuthentication",
+        "rest_framework.authentication.SessionAuthentication",
+        "rest_framework.authentication.TokenAuthentication",
+    ]
+}
+# ######### END REST FRAMEWORK CONFIGURATION
+
+
 # ######### LOGGING CONFIGURATION
 # See: https://docs.djangoproject.com/en/dev/ref/settings/#logging
 # A sample logging configuration. The only tangible logging
diff --git a/gnuviechadmin/gnuviechadmin/urls.py b/gnuviechadmin/gnuviechadmin/urls.py
index 8bcfca5..34a7d7c 100644
--- a/gnuviechadmin/gnuviechadmin/urls.py
+++ b/gnuviechadmin/gnuviechadmin/urls.py
@@ -6,11 +6,20 @@ from django.contrib import admin
 from django.contrib.flatpages import views
 from django.contrib.staticfiles.urls import staticfiles_urlpatterns
 from django.urls import path, re_path
+from rest_framework import routers
+
+from help import views as help_views
 
 admin.autodiscover()
 
+router = routers.DefaultRouter()
+router.register(r"users", help_views.UserViewSet)
+router.register(r"help-users", help_views.HelpUserViewSet)
+
 urlpatterns = [
     re_path(r"", include("dashboard.urls")),
+    path("api/", include(router.urls)),
+    path("api-auth/", include("rest_framework.urls", namespace="rest_framework")),
     re_path(r"^admin/", admin.site.urls),
     re_path(r"^impersonate/", include("impersonate.urls")),
     re_path(r"^accounts/", include("allauth.urls")),
diff --git a/gnuviechadmin/help/serializers.py b/gnuviechadmin/help/serializers.py
new file mode 100644
index 0000000..2052926
--- /dev/null
+++ b/gnuviechadmin/help/serializers.py
@@ -0,0 +1,30 @@
+"""
+Serializers for the REST API
+"""
+
+from django.contrib.auth import get_user_model
+from rest_framework import serializers
+
+from help.models import HelpUser
+
+User = get_user_model()
+
+
+class UserSerializer(serializers.HyperlinkedModelSerializer):
+    class Meta:
+        model = User
+        fields = ["url", "username", "helpuser"]
+        read_only_fields = ["username", "helpuser"]
+
+
+class HelpUserSerializer(serializers.HyperlinkedModelSerializer):
+    class Meta:
+        model = HelpUser
+        fields = [
+            "url",
+            "user",
+            "email_address",
+            "postal_address",
+            "offline_account_code",
+        ]
+        read_only_fields = ["user", "offline_account_code"]
diff --git a/gnuviechadmin/help/views.py b/gnuviechadmin/help/views.py
index 91ea44a..cdfcff6 100644
--- a/gnuviechadmin/help/views.py
+++ b/gnuviechadmin/help/views.py
@@ -1,3 +1,29 @@
-from django.shortcuts import render
+from django.contrib.auth import get_user_model
+from rest_framework import permissions, viewsets
 
-# Create your views here.
+from help.models import HelpUser
+from help.serializers import HelpUserSerializer, UserSerializer
+
+User = get_user_model()
+
+
+class UserViewSet(viewsets.ReadOnlyModelViewSet):
+    """
+    API endpoint that allows users to be viewed or edited.
+
+    """
+
+    queryset = User.objects.all().order_by("-username")
+    serializer_class = UserSerializer
+    permission_classes = [permissions.IsAdminUser]
+
+
+class HelpUserViewSet(viewsets.ModelViewSet):
+    """
+    API endpoint that allows user help profile to be viewed or edited.
+
+    """
+
+    queryset = HelpUser.objects.all().order_by("-user__username")
+    serializer_class = HelpUserSerializer
+    permission_classes = [permissions.IsAdminUser]
From 0f91587c60d982bf35ef69bbd5061c2ab88e2d91 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sun, 16 Apr 2023 13:50:01 +0200
Subject: [PATCH 25/46] Remove unneeded users API view
The help-users API view is sufficient
---
 gnuviechadmin/gnuviechadmin/urls.py |  1 -
 gnuviechadmin/help/serializers.py   | 12 ++----------
 gnuviechadmin/help/views.py         | 18 ++----------------
 3 files changed, 4 insertions(+), 27 deletions(-)
diff --git a/gnuviechadmin/gnuviechadmin/urls.py b/gnuviechadmin/gnuviechadmin/urls.py
index 34a7d7c..046d1fb 100644
--- a/gnuviechadmin/gnuviechadmin/urls.py
+++ b/gnuviechadmin/gnuviechadmin/urls.py
@@ -13,7 +13,6 @@ from help import views as help_views
 admin.autodiscover()
 
 router = routers.DefaultRouter()
-router.register(r"users", help_views.UserViewSet)
 router.register(r"help-users", help_views.HelpUserViewSet)
 
 urlpatterns = [
diff --git a/gnuviechadmin/help/serializers.py b/gnuviechadmin/help/serializers.py
index 2052926..f4beec2 100644
--- a/gnuviechadmin/help/serializers.py
+++ b/gnuviechadmin/help/serializers.py
@@ -2,22 +2,14 @@
 Serializers for the REST API
 """
 
-from django.contrib.auth import get_user_model
 from rest_framework import serializers
 
 from help.models import HelpUser
 
-User = get_user_model()
-
-
-class UserSerializer(serializers.HyperlinkedModelSerializer):
-    class Meta:
-        model = User
-        fields = ["url", "username", "helpuser"]
-        read_only_fields = ["username", "helpuser"]
-
 
 class HelpUserSerializer(serializers.HyperlinkedModelSerializer):
+    user = serializers.StringRelatedField()
+
     class Meta:
         model = HelpUser
         fields = [
diff --git a/gnuviechadmin/help/views.py b/gnuviechadmin/help/views.py
index cdfcff6..8e81193 100644
--- a/gnuviechadmin/help/views.py
+++ b/gnuviechadmin/help/views.py
@@ -1,21 +1,7 @@
-from django.contrib.auth import get_user_model
 from rest_framework import permissions, viewsets
 
 from help.models import HelpUser
-from help.serializers import HelpUserSerializer, UserSerializer
-
-User = get_user_model()
-
-
-class UserViewSet(viewsets.ReadOnlyModelViewSet):
-    """
-    API endpoint that allows users to be viewed or edited.
-
-    """
-
-    queryset = User.objects.all().order_by("-username")
-    serializer_class = UserSerializer
-    permission_classes = [permissions.IsAdminUser]
+from help.serializers import HelpUserSerializer
 
 
 class HelpUserViewSet(viewsets.ModelViewSet):
@@ -24,6 +10,6 @@ class HelpUserViewSet(viewsets.ModelViewSet):
 
     """
 
-    queryset = HelpUser.objects.all().order_by("-user__username")
+    queryset = HelpUser.objects.all().order_by("user__username")
     serializer_class = HelpUserSerializer
     permission_classes = [permissions.IsAdminUser]
From 5cf7ef7a239aeabffd1610080395d9b93de47dde Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sun, 16 Apr 2023 14:34:45 +0200
Subject: [PATCH 26/46] Strip API to required minimum
- disable browseable API
- use IsAdminUser for DEFAULT_PERMISSION_CLASSES
- register explicit API views for HelpUser model
---
 gnuviechadmin/gnuviechadmin/settings.py |  8 +++++++-
 gnuviechadmin/gnuviechadmin/urls.py     | 12 ++++++------
 gnuviechadmin/help/views.py             | 19 +++++++++++++++----
 3 files changed, 28 insertions(+), 11 deletions(-)
diff --git a/gnuviechadmin/gnuviechadmin/settings.py b/gnuviechadmin/gnuviechadmin/settings.py
index 6d81694..2f10c77 100644
--- a/gnuviechadmin/gnuviechadmin/settings.py
+++ b/gnuviechadmin/gnuviechadmin/settings.py
@@ -272,7 +272,13 @@ REST_FRAMEWORK = {
         "rest_framework.authentication.BasicAuthentication",
         "rest_framework.authentication.SessionAuthentication",
         "rest_framework.authentication.TokenAuthentication",
-    ]
+    ],
+    "DEFAULT_RENDERER_CLASSES": [
+        "rest_framework.renderers.JSONRenderer",
+    ],
+    "DEFAULT_PERMISSION_CLASSES": [
+        "rest_framework.permissions.IsAdminUser",
+    ],
 }
 # ######### END REST FRAMEWORK CONFIGURATION
 
diff --git a/gnuviechadmin/gnuviechadmin/urls.py b/gnuviechadmin/gnuviechadmin/urls.py
index 046d1fb..2bfea87 100644
--- a/gnuviechadmin/gnuviechadmin/urls.py
+++ b/gnuviechadmin/gnuviechadmin/urls.py
@@ -6,19 +6,19 @@ from django.contrib import admin
 from django.contrib.flatpages import views
 from django.contrib.staticfiles.urls import staticfiles_urlpatterns
 from django.urls import path, re_path
-from rest_framework import routers
 
 from help import views as help_views
 
 admin.autodiscover()
 
-router = routers.DefaultRouter()
-router.register(r"help-users", help_views.HelpUserViewSet)
-
 urlpatterns = [
     re_path(r"", include("dashboard.urls")),
-    path("api/", include(router.urls)),
-    path("api-auth/", include("rest_framework.urls", namespace="rest_framework")),
+    path("api/users/", help_views.ListHelpUserAPIView.as_view()),
+    path(
+        "api/users//",
+        help_views.HelpUserAPIView.as_view(),
+        name="helpuser-detail",
+    ),
     re_path(r"^admin/", admin.site.urls),
     re_path(r"^impersonate/", include("impersonate.urls")),
     re_path(r"^accounts/", include("allauth.urls")),
diff --git a/gnuviechadmin/help/views.py b/gnuviechadmin/help/views.py
index 8e81193..2c27870 100644
--- a/gnuviechadmin/help/views.py
+++ b/gnuviechadmin/help/views.py
@@ -1,15 +1,26 @@
-from rest_framework import permissions, viewsets
+from rest_framework import generics
 
 from help.models import HelpUser
 from help.serializers import HelpUserSerializer
 
 
-class HelpUserViewSet(viewsets.ModelViewSet):
+class ListHelpUserAPIView(generics.ListAPIView):
     """
     API endpoint that allows user help profile to be viewed or edited.
 
     """
 
-    queryset = HelpUser.objects.all().order_by("user__username")
+    queryset = (
+        HelpUser.objects.all().prefetch_related("user").order_by("user__username")
+    )
+    serializer_class = HelpUserSerializer
+
+
+class HelpUserAPIView(generics.RetrieveUpdateAPIView):
+    """
+    API endpoint that allows user help profile to be viewed or edited.
+
+    """
+
+    queryset = HelpUser.objects.all()
     serializer_class = HelpUserSerializer
-    permission_classes = [permissions.IsAdminUser]
From 8e42cb9c18fd932e5cea7bfce00d54debcec7155 Mon Sep 17 00:00:00 2001
From: Jan Dittberner 
Date: Sun, 16 Apr 2023 22:11:32 +0200
Subject: [PATCH 27/46] Start switch to Bootstrap 5
- drop jQuery and fontawesome dependencies
- add bootstrap5 and bootstrap-icons
- update fonts mfizz
- update base templates and the first set of other templates
- replace blocktrans and trans with blocktranslate and translate to
  prepare for Django 4
- move hostingpakcage templates to hostingpackages/templates
- update translations
---
 frontend/.gitignore                           |    1 +
 frontend/package-lock.json                    |   46 +
 frontend/package.json                         |    6 +
 .../locale/de/LC_MESSAGES/django.po           |   16 +-
 .../dashboard/locale/de/LC_MESSAGES/django.po |   88 +-
 .../dashboard/templates/dashboard/index.html  |   19 +-
 .../templates/dashboard/user_dashboard.html   |  107 +-
 .../domains/locale/de/LC_MESSAGES/django.po   |  124 +-
 gnuviechadmin/gnuviechadmin/settings.py       |    4 +-
 gnuviechadmin/gnuviechadmin/urls.py           |   27 +-
 .../locale/de/LC_MESSAGES/django.po           |   12 +-
 .../help/locale/de/LC_MESSAGES/django.po      |   36 +
 .../locale/de/LC_MESSAGES/django.po           |  464 +-
 .../hostingpackages/add_hosting_option.html   |   13 +
 .../templates/hostingpackages/base.html       |    0
 .../customerhostingpackage_admin_list.html    |   34 +
 .../customerhostingpackage_create.html        |   12 +
 .../customerhostingpackage_detail.html        |  280 +
 .../customerhostingpackage_list.html          |   48 +
 ...customerhostingpackage_option_choices.html |   29 +
 gnuviechadmin/locale/de/LC_MESSAGES/django.po |  821 +--
 .../locale/de/LC_MESSAGES/django.po           |   62 +-
 .../osusers/locale/de/LC_MESSAGES/django.po   |  109 +-
 gnuviechadmin/static/css/bootstrap-icons.css  | 5882 +++++++++++++++++
 .../static/css/bootstrap-theme.min.css        |    5 -
 gnuviechadmin/static/css/bootstrap.min.css    |   12 +-
 .../static/css/bootstrap.min.css.map          |    1 +
 gnuviechadmin/static/css/font-awesome.min.css |    4 -
 gnuviechadmin/static/css/gnuviechadmin.css    |   28 +-
 gnuviechadmin/static/fonts/FontAwesome.otf    |  Bin 93888 -> 0 bytes
 .../static/fonts/bootstrap-icons.woff         |  Bin 0 -> 164360 bytes
 .../static/fonts/bootstrap-icons.woff2        |  Bin 0 -> 121340 bytes
 gnuviechadmin/static/fonts/font-mfizz.css     |  574 +-
 gnuviechadmin/static/fonts/font-mfizz.eot     |  Bin 43154 -> 63766 bytes
 gnuviechadmin/static/fonts/font-mfizz.svg     | 3611 ++++++----
 gnuviechadmin/static/fonts/font-mfizz.ttf     |  Bin 45324 -> 63584 bytes
 gnuviechadmin/static/fonts/font-mfizz.woff    |  Bin 29056 -> 40904 bytes
 .../static/fonts/fontawesome-webfont.eot      |  Bin 60767 -> 0 bytes
 .../static/fonts/fontawesome-webfont.svg      |  565 --
 .../static/fonts/fontawesome-webfont.ttf      |  Bin 122092 -> 0 bytes
 .../static/fonts/fontawesome-webfont.woff     |  Bin 71508 -> 0 bytes
 .../static/fonts/fontawesome-webfont.woff2    |  Bin 56780 -> 0 bytes
 .../fonts/glyphicons-halflings-regular.eot    |  Bin 20127 -> 0 bytes
 .../fonts/glyphicons-halflings-regular.svg    |  288 -
 .../fonts/glyphicons-halflings-regular.ttf    |  Bin 45404 -> 0 bytes
 .../fonts/glyphicons-halflings-regular.woff   |  Bin 23424 -> 0 bytes
 .../fonts/glyphicons-halflings-regular.woff2  |  Bin 18028 -> 0 bytes
 .../static/js/bootstrap.bundle.min.js         |    7 +
 .../static/js/bootstrap.bundle.min.js.map     |    1 +
 gnuviechadmin/static/js/bootstrap.min.js      |    7 -
 .../locale/de/LC_MESSAGES/django.po           |   24 +-
 .../templates/account/account_inactive.html   |    6 +-
 gnuviechadmin/templates/account/email.html    |   32 +-
 .../email/email_confirmation_message.txt      |    4 +-
 .../email/email_confirmation_subject.txt      |    2 +-
 .../email/password_reset_key_message.txt      |    8 +-
 .../email/password_reset_key_subject.txt      |    2 +-
 .../templates/account/email_confirm.html      |   29 +-
 .../templates/account/email_confirmed.html    |   10 +-
 gnuviechadmin/templates/account/login.html    |    8 +-
 gnuviechadmin/templates/account/logout.html   |    8 +-
 .../messages/cannot_delete_primary_email.txt  |    2 +-
 .../messages/email_confirmation_sent.txt      |    2 +-
 .../account/messages/email_confirmed.txt      |    2 +-
 .../account/messages/email_deleted.txt        |    2 +-
 .../templates/account/messages/logged_in.txt  |    2 +-
 .../templates/account/messages/logged_out.txt |    2 +-
 .../account/messages/password_changed.txt     |    2 +-
 .../account/messages/password_set.txt         |    2 +-
 .../account/messages/primary_email_set.txt    |    2 +-
 .../messages/unverified_primary_email.txt     |    2 +-
 .../templates/account/password_change.html    |    6 +-
 .../templates/account/password_reset.html     |   24 +-
 .../account/password_reset_done.html          |   13 +-
 .../account/password_reset_from_key.html      |   34 +-
 .../account/password_reset_from_key_done.html |    6 +-
 .../templates/account/password_set.html       |    6 +-
 gnuviechadmin/templates/account/signup.html   |   24 +-
 .../templates/account/signup_closed.html      |    6 +-
 .../account/snippets/already_logged_in.html   |    4 +-
 .../templates/account/verification_sent.html  |    9 +-
 .../account/verified_email_required.html      |   21 +-
 gnuviechadmin/templates/base.html             |  262 +-
 .../templates/contact_form/contact_form.html  |   26 +-
 .../contact_form/contact_success.html         |    6 +-
 .../domains/hostingdomain_create.html         |   21 +-
 .../hostingpackages/add_hosting_option.html   |    8 -
 .../customerhostingpackage_admin_list.html    |   32 -
 .../customerhostingpackage_create.html        |    7 -
 .../customerhostingpackage_detail.html        |  213 -
 .../customerhostingpackage_list.html          |   43 -
 ...customerhostingpackage_option_choices.html |   23 -
 .../templates/impersonate/list_users.html     |    8 +-
 .../templates/impersonate/search_users.html   |    8 +-
 .../mailaddress_confirm_delete.html           |   52 +-
 .../managemails/mailaddress_create.html       |   44 +-
 .../managemails/mailaddress_edit.html         |   30 +-
 .../templates/managemails/mailbox_create.html |   59 +-
 .../managemails/mailbox_setpassword.html      |   56 +-
 .../osusers/sshpublickey_confirm_delete.html  |   62 +-
 .../osusers/sshpublickey_create.html          |   42 +-
 .../osusers/sshpublickey_edit_comment.html    |   41 +-
 .../templates/osusers/sshpublickey_list.html  |   88 +-
 .../templates/osusers/user_setpassword.html   |   45 +-
 .../templates/registration/login.html         |   18 +-
 .../socialaccount/authentication_error.html   |    8 +-
 .../templates/socialaccount/connections.html  |   84 +-
 .../templates/socialaccount/login.html        |   22 +
 .../socialaccount/login_cancelled.html        |   13 +-
 .../messages/account_connected.txt            |    2 +-
 .../messages/account_connected_other.txt      |    2 +-
 .../messages/account_disconnected.txt         |    2 +-
 .../templates/socialaccount/signup.html       |   23 +-
 .../socialaccount/snippets/provider_list.html |    2 +-
 .../userdbs/databaseuser_setpassword.html     |   52 +-
 .../templates/userdbs/snippets/db_type.html   |    2 +-
 .../userdbs/userdatabase_confirm_delete.html  |   61 +-
 .../userdbs/userdatabase_create.html          |   46 +-
 .../websites/website_confirm_delete.html      |   57 +-
 .../templates/websites/website_create.html    |   40 +-
 .../userdbs/locale/de/LC_MESSAGES/django.po   |   47 +-
 .../websites/locale/de/LC_MESSAGES/django.po  |   24 +-
 poetry.lock                                   |   30 +-
 pyproject.toml                                |    3 +-
 124 files changed, 10873 insertions(+), 4490 deletions(-)
 create mode 100644 frontend/.gitignore
 create mode 100644 frontend/package-lock.json
 create mode 100644 frontend/package.json
 create mode 100644 gnuviechadmin/help/locale/de/LC_MESSAGES/django.po
 create mode 100644 gnuviechadmin/hostingpackages/templates/hostingpackages/add_hosting_option.html
 rename gnuviechadmin/{ => hostingpackages}/templates/hostingpackages/base.html (100%)
 create mode 100644 gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_admin_list.html
 create mode 100644 gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_create.html
 create mode 100644 gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html
 create mode 100644 gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_list.html
 create mode 100644 gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_option_choices.html
 create mode 100644 gnuviechadmin/static/css/bootstrap-icons.css
 delete mode 100644 gnuviechadmin/static/css/bootstrap-theme.min.css
 create mode 100644 gnuviechadmin/static/css/bootstrap.min.css.map
 delete mode 100644 gnuviechadmin/static/css/font-awesome.min.css
 delete mode 100644 gnuviechadmin/static/fonts/FontAwesome.otf
 create mode 100644 gnuviechadmin/static/fonts/bootstrap-icons.woff
 create mode 100644 gnuviechadmin/static/fonts/bootstrap-icons.woff2
 delete mode 100644 gnuviechadmin/static/fonts/fontawesome-webfont.eot
 delete mode 100644 gnuviechadmin/static/fonts/fontawesome-webfont.svg
 delete mode 100644 gnuviechadmin/static/fonts/fontawesome-webfont.ttf
 delete mode 100644 gnuviechadmin/static/fonts/fontawesome-webfont.woff
 delete mode 100644 gnuviechadmin/static/fonts/fontawesome-webfont.woff2
 delete mode 100644 gnuviechadmin/static/fonts/glyphicons-halflings-regular.eot
 delete mode 100644 gnuviechadmin/static/fonts/glyphicons-halflings-regular.svg
 delete mode 100644 gnuviechadmin/static/fonts/glyphicons-halflings-regular.ttf
 delete mode 100644 gnuviechadmin/static/fonts/glyphicons-halflings-regular.woff
 delete mode 100644 gnuviechadmin/static/fonts/glyphicons-halflings-regular.woff2
 create mode 100644 gnuviechadmin/static/js/bootstrap.bundle.min.js
 create mode 100644 gnuviechadmin/static/js/bootstrap.bundle.min.js.map
 delete mode 100644 gnuviechadmin/static/js/bootstrap.min.js
 delete mode 100644 gnuviechadmin/templates/hostingpackages/add_hosting_option.html
 delete mode 100644 gnuviechadmin/templates/hostingpackages/customerhostingpackage_admin_list.html
 delete mode 100644 gnuviechadmin/templates/hostingpackages/customerhostingpackage_create.html
 delete mode 100644 gnuviechadmin/templates/hostingpackages/customerhostingpackage_detail.html
 delete mode 100644 gnuviechadmin/templates/hostingpackages/customerhostingpackage_list.html
 delete mode 100644 gnuviechadmin/templates/hostingpackages/customerhostingpackage_option_choices.html
 create mode 100644 gnuviechadmin/templates/socialaccount/login.html
diff --git a/frontend/.gitignore b/frontend/.gitignore
new file mode 100644
index 0000000..c2658d7
--- /dev/null
+++ b/frontend/.gitignore
@@ -0,0 +1 @@
+node_modules/
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
new file mode 100644
index 0000000..db31233
--- /dev/null
+++ b/frontend/package-lock.json
@@ -0,0 +1,46 @@
+{
+  "name": "frontend",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "dependencies": {
+        "bootstrap": "^5.2.3",
+        "bootstrap-icons": "^1.10.4"
+      }
+    },
+    "node_modules/@popperjs/core": {
+      "version": "2.11.7",
+      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz",
+      "integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==",
+      "peer": true,
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/popperjs"
+      }
+    },
+    "node_modules/bootstrap": {
+      "version": "5.2.3",
+      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.3.tgz",
+      "integrity": "sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/twbs"
+        },
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/bootstrap"
+        }
+      ],
+      "peerDependencies": {
+        "@popperjs/core": "^2.11.6"
+      }
+    },
+    "node_modules/bootstrap-icons": {
+      "version": "1.10.4",
+      "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.10.4.tgz",
+      "integrity": "sha512-eI3HyIUmpGKRiRv15FCZccV+2sreGE2NnmH8mtxV/nPOzQVu0sPEj8HhF1MwjJ31IhjF0rgMvtYOX5VqIzcb/A=="
+    }
+  }
+}
diff --git a/frontend/package.json b/frontend/package.json
new file mode 100644
index 0000000..15bb51c
--- /dev/null
+++ b/frontend/package.json
@@ -0,0 +1,6 @@
+{
+  "dependencies": {
+    "bootstrap": "^5.2.3",
+    "bootstrap-icons": "^1.10.4"
+  }
+}
diff --git a/gnuviechadmin/contact_form/locale/de/LC_MESSAGES/django.po b/gnuviechadmin/contact_form/locale/de/LC_MESSAGES/django.po
index ffeeaa3..aaf030a 100644
--- a/gnuviechadmin/contact_form/locale/de/LC_MESSAGES/django.po
+++ b/gnuviechadmin/contact_form/locale/de/LC_MESSAGES/django.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: contact_form\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-29 11:04+0100\n"
-"PO-Revision-Date: 2015-02-01 19:03+0100\n"
+"POT-Creation-Date: 2023-04-16 22:07+0200\n"
+"PO-Revision-Date: 2023-04-16 18:25+0200\n"
 "Last-Translator: Jan Dittberner \n"
 "Language-Team: Jan Dittberner \n"
 "Language: de\n"
@@ -16,21 +16,21 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 1.6.10\n"
+"X-Generator: Poedit 3.2.2\n"
 "X-Poedit-SourceCharset: UTF-8\n"
 
-#: contact_form/forms.py:27
+#: contact_form/forms.py:25
 msgid "Your name"
 msgstr "Ihr Name"
 
-#: contact_form/forms.py:28
+#: contact_form/forms.py:26
 msgid "Your email address"
-msgstr "Ihre E-Mailadresse"
+msgstr "Ihre E-Mail-Adresse"
 
-#: contact_form/forms.py:29
+#: contact_form/forms.py:27
 msgid "Your message"
 msgstr "Ihre Nachricht"
 
-#: contact_form/forms.py:41
+#: contact_form/forms.py:39
 msgid "Send message"
 msgstr "Nachricht senden"
diff --git a/gnuviechadmin/dashboard/locale/de/LC_MESSAGES/django.po b/gnuviechadmin/dashboard/locale/de/LC_MESSAGES/django.po
index 71d4e75..b3e750a 100644
--- a/gnuviechadmin/dashboard/locale/de/LC_MESSAGES/django.po
+++ b/gnuviechadmin/dashboard/locale/de/LC_MESSAGES/django.po
@@ -7,18 +7,92 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnuviechadmin dashboard\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-01-17 15:59+0100\n"
-"PO-Revision-Date: 2015-01-17 16:01+0100\n"
+"POT-Creation-Date: 2023-04-16 22:07+0200\n"
+"PO-Revision-Date: 2023-04-16 18:31+0200\n"
 "Last-Translator: Jan Dittberner \n"
-"Language-Team: Jan Dittberner \n"
+"Language-Team: Jan Dittberner \n"
 "Language: de\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 1.6.10\n"
+"X-Generator: Poedit 3.2.2\n"
 "X-Poedit-SourceCharset: UTF-8\n"
 
-#: dashboard/views.py:43
-msgid "You are not allowed to view this page."
-msgstr "Sie haben nicht die nötigen Berechtigungen um diese Seite zu sehen."
+#: dashboard/templates/dashboard/index.html:3
+msgid "Welcome"
+msgstr "Willkommen"
+
+#: dashboard/templates/dashboard/index.html:4
+msgid "Welcome to our customer self service"
+msgstr "Willkommen in unserem Selbstservice-System"
+
+#: dashboard/templates/dashboard/index.html:7
+#, python-format
+msgid ""
+"Hello %(full_name)s,Dashboard  to view and modify your hosting "
+"options."
+msgstr ""
+"Hallo %(full_name)s,Startseite  besuchen, um Ihre "
+"Hostingeinstellungen anzusehen und zu bearbeiten."
+
+#: dashboard/templates/dashboard/user_dashboard.html:3
+#: dashboard/templates/dashboard/user_dashboard.html:6
+#, python-format
+msgid "Dashboard for %(full_name)s"
+msgstr "Startseite für %(full_name)s"
+
+#: dashboard/templates/dashboard/user_dashboard.html:10
+msgid "Hosting packages"
+msgstr "Hostingpakete"
+
+#: dashboard/templates/dashboard/user_dashboard.html:17
+msgid "Name"
+msgstr "Name"
+
+#: dashboard/templates/dashboard/user_dashboard.html:18
+msgid "Disk space"
+msgstr "Speicherplatz"
+
+#: dashboard/templates/dashboard/user_dashboard.html:19
+msgid "Mailboxes"
+msgstr "Postfächer"
+
+#: dashboard/templates/dashboard/user_dashboard.html:20
+msgid "Databases"
+msgstr "Datenbanken"
+
+#: dashboard/templates/dashboard/user_dashboard.html:21
+msgid "Actions"
+msgstr "Aktionen"
+
+#: dashboard/templates/dashboard/user_dashboard.html:28
+#, python-format
+msgid "Show details for %(packagename)s"
+msgstr "Details für %(packagename)s anzeigen"
+
+#: dashboard/templates/dashboard/user_dashboard.html:34
+#, python-format
+msgid ""
+"The reserved disk space for your hosting package is %(diskspace)s bytes."
+msgstr ""
+"Der für Ihr Hostingpaket reservierte Speicherplatz sind %(diskspace)s Bytes."
+
+#: dashboard/templates/dashboard/user_dashboard.html:40
+#, python-format
+msgid "used %(num)s of %(total)s"
+msgstr "%(num)s von %(total)s genutzt"
+
+#: dashboard/templates/dashboard/user_dashboard.html:55
+msgid "You have no hosting packages yet."
+msgstr "Sie haben noch keine Hostingpakete."
+
+#: dashboard/templates/dashboard/user_dashboard.html:56
+msgid "This user has no hosting packages assigned yet."
+msgstr "Diesem Benutzer sind noch keine Hostingpakete zugewiesen."
+
+#: dashboard/templates/dashboard/user_dashboard.html:60
+msgid "Add hosting package"
+msgstr "Hostingpaket anlegen"
diff --git a/gnuviechadmin/dashboard/templates/dashboard/index.html b/gnuviechadmin/dashboard/templates/dashboard/index.html
index 6b435eb..8cfcd8d 100644
--- a/gnuviechadmin/dashboard/templates/dashboard/index.html
+++ b/gnuviechadmin/dashboard/templates/dashboard/index.html
@@ -1,14 +1,11 @@
 {% extends "base.html" %}
 {% load i18n %}
-{% block title %}{{ block.super }} - {% trans "Welcome" %}{% endblock title %}
-{% block page_title %}{% trans "Welcome to our customer self service" %}{% endblock page_title %}
+{% block title %}{{ block.super }} - {% translate "Welcome" %}{% endblock title %}
+{% block page_title %}{% translate "Welcome to our customer self service" %}{% endblock page_title %}
 {% block content %}
-{% if user.is_authenticated %}
-{% url 'customer_dashboard' slug=user.username as dashboard_url %}{% blocktrans with full_name=user.get_full_name %}Hello {{ full_name }},Dashboard  to view and modify your hosting options.
-{% endblocktrans %}
-{% else %}
-{% trans "This is your entry to our customer self service sytem." %}
-{% url 'account_login' as login_url %}{% url 'dashboard' as dashboard_url %}{% blocktrans %}If you are already a customer you can Sign in  to view and modify your hosting options.{% endblocktrans %}
-{% endif %}
-{% endblock content %}
+    {% url 'customer_dashboard' slug=user.username as dashboard_url %}
+        {% blocktranslate with full_name=user.get_full_name trimmed %}
+            Hello {{ full_name }},Dashboard  to view and modify your hosting options.
+        {% endblocktranslate %}
+{% endblock content %}
\ No newline at end of file
diff --git a/gnuviechadmin/dashboard/templates/dashboard/user_dashboard.html b/gnuviechadmin/dashboard/templates/dashboard/user_dashboard.html
index 7afb025..19d05cd 100644
--- a/gnuviechadmin/dashboard/templates/dashboard/user_dashboard.html
+++ b/gnuviechadmin/dashboard/templates/dashboard/user_dashboard.html
@@ -1,51 +1,64 @@
 {% extends "base.html" %}
 {% load i18n %}
-{% block title %}{{ block.super }} - {% blocktrans with full_name=dashboard_user.get_full_name %}Dashboard for {{ full_name }}{% endblocktrans %}{% endblock title %}
-{% block page_title %}{% blocktrans with full_name=dashboard_user.get_full_name %}Dashboard for {{ full_name }}{% endblocktrans %}{% endblock page_title %}
+{% block title %}{{ block.super }} - {% blocktranslate with full_name=dashboard_user.get_full_name trimmed %}
+    Dashboard for {{ full_name }}
+{% endblocktranslate %}{% endblock title %}
+{% block page_title %}{% blocktranslate with full_name=dashboard_user.get_full_name trimmed %}
+    Dashboard for {{ full_name }}
+{% endblocktranslate %}{% endblock page_title %}
 {% block content %}
-
-  
-    
-      
{% trans "Hosting packages" %}
-      
-        {% if hosting_packages %}
-        
-          
-            
-              {% trans "Name" %} 
-              {% trans "Disk space" %} 
-              {% trans "Mailboxes" %} 
-              {% trans "Databases" %} 
-              {% trans "Actions" %} 
-             
-           
-          
-            {% for package in hosting_packages %}
-            
-              {{ package.name }} 
-                {% with diskspace=package.get_disk_space %}
-                {{ diskspace|filesizeformat }} 
-                {% endwith %}
-               
-              {% blocktrans with num=package.used_mailbox_count total=package.mailbox_count %}used {{ num }} of {{ total }}{% endblocktrans %} 
-              {% for dbtype in package.get_databases %}
-                {{ dbtype.number }} {% include "userdbs/snippets/db_type.html" with db_type=dbtype.db_type %}
-                {% if not forloop.last %} / {% endif %}
-              {% endfor %} 
-               
-            {% endfor %}
-           
-        
-        {% else %}
-        
{% if user == object %}{% trans "You have no hosting packages yet." %}{% else %}{% trans "This user has no hosting packages assigned yet." %}{% endif %}
-        {% endif %}
-        {% if user.is_staff %}
-        
{% trans "Add hosting package" %} 
-        {% endif %}
-      
+    
{% translate "Hosting packages" %} 
+    
+        
+            {% if hosting_packages %}
+                
+                    
+                    
+                        {% translate "Name" %} 
+                        {% translate "Disk space" %} 
+                        {% translate "Mailboxes" %} 
+                        {% translate "Databases" %} 
+                        {% translate "Actions" %} 
+                     
+                     
+                    
+                    {% for package in hosting_packages %}
+                        
+                            {{ package.name }} 
+                            
+                                {% with diskspace=package.get_disk_space %}
+                                    {{ diskspace|filesizeformat }} 
+                                {% endwith %}
+                             
+                            
+                                {% blocktranslate with num=package.used_mailbox_count total=package.mailbox_count trimmed %}
+                                    used {{ num }} of {{ total }}
+                                {% endblocktranslate %} 
+                            {% for dbtype in package.get_databases %}
+                                {{ dbtype.number }}
+                                {% include "userdbs/snippets/db_type.html" with db_type=dbtype.db_type %}
+                                {% if not forloop.last %} / {% endif %}
+                            {% endfor %} 
+                             
+                    {% endfor %}
+                     
+                
+            {% else %}
+                
+                    {% if user == object %}{% translate "You have no hosting packages yet." %}{% else %}
+                        {% translate "This user has no hosting packages assigned yet." %}{% endif %}
+            {% endif %}
+            {% if user.is_staff %}
+                
{% translate "Add hosting package" %} 
+            {% endif %}
+        
-  
-
-{% endblock content %}
+{% endblock content %}
\ No newline at end of file
diff --git a/gnuviechadmin/domains/locale/de/LC_MESSAGES/django.po b/gnuviechadmin/domains/locale/de/LC_MESSAGES/django.po
index 4e559af..b07cba5 100644
--- a/gnuviechadmin/domains/locale/de/LC_MESSAGES/django.po
+++ b/gnuviechadmin/domains/locale/de/LC_MESSAGES/django.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnuviechadmin domains\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-29 11:04+0100\n"
-"PO-Revision-Date: 2015-11-08 12:02+0100\n"
+"POT-Creation-Date: 2023-04-16 22:07+0200\n"
+"PO-Revision-Date: 2023-04-16 18:20+0200\n"
 "Last-Translator: Jan Dittberner 
\n"
 "Language-Team: Jan Dittberner \n"
 "Language: de\n"
@@ -16,152 +16,60 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 1.8.6\n"
+"X-Generator: Poedit 3.2.2\n"
 "X-Poedit-SourceCharset: UTF-8\n"
 
 #: domains/apps.py:17
 msgid "Domains"
 msgstr "Domains"
 
-#: domains/forms.py:30 domains/tests/test_forms.py:24
+#: domains/forms.py:25 domains/tests/test_forms.py:20
 msgid "host name too long"
 msgstr "zu langer Hostname"
 
-#: domains/forms.py:33 domains/tests/test_forms.py:29
-#: domains/tests/test_forms.py:34 domains/tests/test_forms.py:39
-#: domains/tests/test_forms.py:44
+#: domains/forms.py:28 domains/tests/test_forms.py:24
+#: domains/tests/test_forms.py:28 domains/tests/test_forms.py:32
+#: domains/tests/test_forms.py:36
 msgid "invalid domain name"
 msgstr "ungültiger Domainname"
 
-#: domains/forms.py:56
+#: domains/forms.py:51
 msgid "Add Hosting Domain"
 msgstr "Hostingdomain hinzufügen"
 
-#: domains/models.py:17
-msgid "Master"
-msgstr "Master"
-
-#: domains/models.py:18
-msgid "Slave"
-msgstr "Slave"
-
 #: domains/models.py:19
-msgid "Native"
-msgstr "Native"
-
-#: domains/models.py:44
-msgid "HMAC MD5"
-msgstr "HMAC MD5"
-
-#: domains/models.py:45
-msgid "HMAC SHA1"
-msgstr "HMAC SHA1"
-
-#: domains/models.py:46
-msgid "HMAC SHA224"
-msgstr "HMAC SHA224"
-
-#: domains/models.py:47
-msgid "HMAC SHA256"
-msgstr "HMAC SHA256"
-
-#: domains/models.py:48
-msgid "HMAC SHA384"
-msgstr "HMAC SHA384"
-
-#: domains/models.py:49
-msgid "HMAC SHA512"
-msgstr "HMAC SHA512"
-
-#: domains/models.py:58
 msgid "domain name"
 msgstr "Domainname"
 
-#: domains/models.py:60 domains/models.py:258 domains/models.py:308
+#: domains/models.py:22
 msgid "customer"
 msgstr "Kunde"
 
-#: domains/models.py:76
+#: domains/models.py:41
 msgid "Mail domain"
 msgstr "E-Maildomain"
 
-#: domains/models.py:77
+#: domains/models.py:42
 msgid "Mail domains"
 msgstr "E-Maildomains"
 
-#: domains/models.py:121
+#: domains/models.py:91
 msgid "mail domain"
 msgstr "E-Maildomain"
 
-#: domains/models.py:122
+#: domains/models.py:94
 msgid "assigned mail domain for this domain"
 msgstr "zugeordnete E-Maildomain für diese Domain"
 
-#: domains/models.py:128
+#: domains/models.py:101
 msgid "Hosting domain"
 msgstr "Hostingdomain"
 
-#: domains/models.py:129
+#: domains/models.py:102
 msgid "Hosting domains"
 msgstr "Hostingdomains"
 
-#: domains/models.py:169
-msgid "DNS domain"
-msgstr "DNS-Domain"
-
-#: domains/models.py:170
-msgid "DNS domains"
-msgstr "DNS-Domains"
-
-#: domains/models.py:226
-msgid "DNS record"
-msgstr "DNS-Record"
-
-#: domains/models.py:227
-msgid "DNS records"
-msgstr "DNS-Records"
-
-#: domains/models.py:261
-msgid "DNS supermaster"
-msgstr "DNS-Supermaster"
-
-#: domains/models.py:262
-msgid "DNS supermasters"
-msgstr "DNS-Supermasters"
-
-#: domains/models.py:313
-msgid "DNS comment"
-msgstr "DNS-Kommentar"
-
-#: domains/models.py:314
-msgid "DNS comments"
-msgstr "DNS-Kommentare"
-
-#: domains/models.py:351
-msgid "DNS domain metadata item"
-msgstr "DNS-Domainmetadaten-Eintrag"
-
-#: domains/models.py:352
-msgid "DNS domain metadata items"
-msgstr "DNS-Domainmetadaten-Einträge"
-
-#: domains/models.py:385
-msgid "DNS crypto key"
-msgstr "DNS-Cryposchlüssel"
-
-#: domains/models.py:386
-msgid "DNS crypto keys"
-msgstr "DNS-Cryptoschlüssel"
-
-#: domains/models.py:420
-msgid "DNS TSIG key"
-msgstr "DNS-TSIG-Schlüssel"
-
-#: domains/models.py:421
-msgid "DNS TSIG keys"
-msgstr "DNS-TSIG-Schlüssel"
-
-#: domains/views.py:58
+#: domains/views.py:51
 #, python-brace-format
 msgid "Successfully created domain {domainname}"
 msgstr "Domain {domainname} erfolgreich angelegt"
diff --git a/gnuviechadmin/gnuviechadmin/settings.py b/gnuviechadmin/gnuviechadmin/settings.py
index 2f10c77..3a90de0 100644
--- a/gnuviechadmin/gnuviechadmin/settings.py
+++ b/gnuviechadmin/gnuviechadmin/settings.py
@@ -206,6 +206,7 @@ DJANGO_APPS = (
     # Flatpages for about page
     "django.contrib.flatpages",
     "crispy_forms",
+    "crispy_bootstrap5",
     "impersonate",
     "rest_framework",
     "rest_framework.authtoken",
@@ -262,7 +263,8 @@ SOCIALACCOUNT_QUERY_EMAIL = True
 
 
 # ######### CRISPY FORMS CONFIGURATION
-CRISPY_TEMPLATE_PACK = "bootstrap3"
+CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
+CRISPY_TEMPLATE_PACK = "bootstrap5"
 # ######### END CRISPY_FORMS CONFIGURATION
 
 
diff --git a/gnuviechadmin/gnuviechadmin/urls.py b/gnuviechadmin/gnuviechadmin/urls.py
index 2bfea87..a22a5b4 100644
--- a/gnuviechadmin/gnuviechadmin/urls.py
+++ b/gnuviechadmin/gnuviechadmin/urls.py
@@ -5,31 +5,32 @@ from django.conf.urls import include
 from django.contrib import admin
 from django.contrib.flatpages import views
 from django.contrib.staticfiles.urls import staticfiles_urlpatterns
-from django.urls import path, re_path
+from django.urls import path
 
 from help import views as help_views
 
 admin.autodiscover()
 
 urlpatterns = [
-    re_path(r"", include("dashboard.urls")),
+    path("", include("dashboard.urls")),
     path("api/users/", help_views.ListHelpUserAPIView.as_view()),
     path(
         "api/users//",
         help_views.HelpUserAPIView.as_view(),
         name="helpuser-detail",
     ),
-    re_path(r"^admin/", admin.site.urls),
-    re_path(r"^impersonate/", include("impersonate.urls")),
-    re_path(r"^accounts/", include("allauth.urls")),
-    re_path(r"^database/", include("userdbs.urls")),
-    re_path(r"^domains/", include("domains.urls")),
-    re_path(r"^hosting/", include("hostingpackages.urls")),
-    re_path(r"^website/", include("websites.urls")),
-    re_path(r"^mail/", include("managemails.urls")),
-    re_path(r"^osuser/", include("osusers.urls")),
-    re_path(r"^contact/", include("contact_form.urls")),
-    re_path(r"^impressum/$", views.flatpage, {"url": "/impressum/"}, name="imprint"),
+    path("admin/", admin.site.urls),
+    path("impersonate/", include("impersonate.urls")),
+    path("accounts/", include("allauth.urls")),
+    path("database/", include("userdbs.urls")),
+    path("domains/", include("domains.urls")),
+    path("hosting/", include("hostingpackages.urls")),
+    path("website/", include("websites.urls")),
+    path("mail/", include("managemails.urls")),
+    path("osuser/", include("osusers.urls")),
+    path("contact/", include("contact_form.urls")),
+    path("impressum/", views.flatpage, {"url": "/impressum/"}, name="imprint"),
+    path("datenschutz/", views.flatpage, {"url": "/datenschutz/"}, name="privacy"),
 ]
 
 # Uncomment the next line to serve media files in dev.
diff --git a/gnuviechadmin/gvawebcore/locale/de/LC_MESSAGES/django.po b/gnuviechadmin/gvawebcore/locale/de/LC_MESSAGES/django.po
index 6b80207..bcedefd 100644
--- a/gnuviechadmin/gvawebcore/locale/de/LC_MESSAGES/django.po
+++ b/gnuviechadmin/gvawebcore/locale/de/LC_MESSAGES/django.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gvawebcore\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-29 11:04+0100\n"
-"PO-Revision-Date: 2015-01-25 11:49+0100\n"
+"POT-Creation-Date: 2023-04-16 22:07+0200\n"
+"PO-Revision-Date: 2023-04-16 18:21+0200\n"
 "Last-Translator: Jan Dittberner \n"
 "Language-Team: Jan Dittberner \n"
 "Language: de\n"
@@ -16,17 +16,17 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 1.6.10\n"
+"X-Generator: Poedit 3.2.2\n"
 "X-Poedit-SourceCharset: UTF-8\n"
 
-#: gvawebcore/forms.py:12
+#: gvawebcore/forms.py:11
 msgid "Passwords don't match"
 msgstr "Passwörter stimmen nicht überein"
 
 #: gvawebcore/forms.py:25
 msgid "Password"
-msgstr "Passwort: "
+msgstr "Passwort"
 
-#: gvawebcore/forms.py:28
+#: gvawebcore/forms.py:29
 msgid "Password (again)"
 msgstr "Passwortwiederholung"
diff --git a/gnuviechadmin/help/locale/de/LC_MESSAGES/django.po b/gnuviechadmin/help/locale/de/LC_MESSAGES/django.po
new file mode 100644
index 0000000..9014e63
--- /dev/null
+++ b/gnuviechadmin/help/locale/de/LC_MESSAGES/django.po
@@ -0,0 +1,36 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR , YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: help\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-04-16 22:07+0200\n"
+"PO-Revision-Date: 2023-04-16 18:21+0200\n"
+"Last-Translator: \n"
+"Language-Team: Jan Dittberner \n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 3.2.2\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+
+#: help/apps.py:8
+msgid "User self help"
+msgstr "Selbsthilfe für Nutzer"
+
+#: help/models.py:10
+msgid "Contact email address"
+msgstr "Kontakt-E-Mail-Adresse"
+
+#: help/models.py:11
+msgid "Contact postal address"
+msgstr "Kontakt-Postanschrift"
+
+#: help/models.py:13
+msgid "Offline account reset code"
+msgstr "Offline-Code für die Konto-Rücksetzung"
diff --git a/gnuviechadmin/hostingpackages/locale/de/LC_MESSAGES/django.po b/gnuviechadmin/hostingpackages/locale/de/LC_MESSAGES/django.po
index d8edc2e..c068c93 100644
--- a/gnuviechadmin/hostingpackages/locale/de/LC_MESSAGES/django.po
+++ b/gnuviechadmin/hostingpackages/locale/de/LC_MESSAGES/django.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnuviechadmin hostingpackages\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-29 11:04+0100\n"
-"PO-Revision-Date: 2015-01-25 15:49+0100\n"
+"POT-Creation-Date: 2023-04-16 22:07+0200\n"
+"PO-Revision-Date: 2023-04-16 19:10+0200\n"
 "Last-Translator: Jan Dittberner \n"
 "Language-Team: Jan Dittberner \n"
 "Language: de\n"
@@ -16,221 +16,557 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 1.6.10\n"
+"X-Generator: Poedit 3.2.2\n"
 "X-Poedit-SourceCharset: UTF-8\n"
 
 #: hostingpackages/apps.py:17
 msgid "Hosting Packages and Options"
 msgstr "Hostingpakete und -Optionen"
 
-#: hostingpackages/forms.py:49 hostingpackages/forms.py:74
+#: hostingpackages/forms.py:44 hostingpackages/forms.py:68
 msgid "Add Hosting Package"
 msgstr "Hostingpaket anlegen"
 
-#: hostingpackages/forms.py:95
+#: hostingpackages/forms.py:90
 msgid "Add disk space option"
 msgstr "Speicherplatzoption hinzufügen"
 
-#: hostingpackages/forms.py:120
+#: hostingpackages/forms.py:116
 msgid "Add mailbox option"
 msgstr "Postfachoption hinzufügen"
 
-#: hostingpackages/forms.py:145
+#: hostingpackages/forms.py:142
 msgid "Add database option"
 msgstr "Datenbankoption hinzufügen"
 
-#: hostingpackages/models.py:31
+#: hostingpackages/models.py:21
 msgid "MiB"
 msgstr "MiB"
 
-#: hostingpackages/models.py:32
+#: hostingpackages/models.py:21
 msgid "GiB"
 msgstr "GiB"
 
-#: hostingpackages/models.py:33
+#: hostingpackages/models.py:21
 msgid "TiB"
 msgstr "TiB"
 
-#: hostingpackages/models.py:45
+#: hostingpackages/models.py:27
 msgid "description"
 msgstr "Beschreibung"
 
-#: hostingpackages/models.py:46
+#: hostingpackages/models.py:28
 msgid "mailbox count"
 msgstr "Anzahl Postfächer"
 
-#: hostingpackages/models.py:48 hostingpackages/models.py:76
+#: hostingpackages/models.py:30 hostingpackages/models.py:59
 msgid "disk space"
 msgstr "Speicherplatz"
 
-#: hostingpackages/models.py:48
+#: hostingpackages/models.py:30
 msgid "disk space for the hosting package"
 msgstr "Speicherplatz für das Hostingpaket"
 
-#: hostingpackages/models.py:50 hostingpackages/models.py:78
+#: hostingpackages/models.py:33 hostingpackages/models.py:61
 msgid "unit of disk space"
 msgstr "Maßeinheit für den Speicherplatz"
 
-#: hostingpackages/models.py:60 hostingpackages/models.py:213
+#: hostingpackages/models.py:44 hostingpackages/models.py:192
 msgid "name"
 msgstr "Name"
 
-#: hostingpackages/models.py:63
+#: hostingpackages/models.py:47
 msgid "Hosting package"
 msgstr "Hostingpaket"
 
-#: hostingpackages/models.py:64
+#: hostingpackages/models.py:48
 msgid "Hosting packages"
 msgstr "Hostingpakete"
 
-#: hostingpackages/models.py:83
+#: hostingpackages/models.py:67
 msgid "Disk space option"
 msgstr "Speicherplatzoption"
 
-#: hostingpackages/models.py:84
+#: hostingpackages/models.py:68
 msgid "Disk space options"
 msgstr "Speicherplatzoptionen"
 
-#: hostingpackages/models.py:87
+#: hostingpackages/models.py:71
 #, python-brace-format
 msgid "Additional disk space {space} {unit}"
 msgstr "Zusätzlicher Speicherplatz {space} {unit}"
 
-#: hostingpackages/models.py:104
+#: hostingpackages/models.py:88
 msgid "number of databases"
 msgstr "Anzahl von Datenbanken"
 
-#: hostingpackages/models.py:106
+#: hostingpackages/models.py:89
 msgid "database type"
 msgstr "Datenbanktyp"
 
-#: hostingpackages/models.py:111
+#: hostingpackages/models.py:94
 msgid "Database option"
 msgstr "Datenbankoption"
 
-#: hostingpackages/models.py:112
+#: hostingpackages/models.py:95
 msgid "Database options"
 msgstr "Datenbankoptionen"
 
-#: hostingpackages/models.py:116
+#: hostingpackages/models.py:99
 #, python-brace-format
 msgid "{type} database"
 msgid_plural "{count} {type} databases"
 msgstr[0] "{type}-Datenbank"
 msgstr[1] "{count} {type}-Datenbanken"
 
-#: hostingpackages/models.py:141
+#: hostingpackages/models.py:120
 msgid "number of mailboxes"
 msgstr "Anzahl von Postfächern"
 
-#: hostingpackages/models.py:146
+#: hostingpackages/models.py:125
 msgid "Mailbox option"
 msgstr "Postfachoption"
 
-#: hostingpackages/models.py:147
+#: hostingpackages/models.py:126
 msgid "Mailbox options"
 msgstr "Postfachoptionen"
 
-#: hostingpackages/models.py:151
+#: hostingpackages/models.py:130
 #, python-brace-format
 msgid "{count} additional mailbox"
 msgid_plural "{count} additional mailboxes"
 msgstr[0] "{count} zusätzliches Postfach"
 msgstr[1] "{count} zusätzliche Postfächer"
 
-#: hostingpackages/models.py:206
+#: hostingpackages/models.py:182
 msgid "customer"
 msgstr "Kunde"
 
-#: hostingpackages/models.py:208
+#: hostingpackages/models.py:186
 msgid "hosting package template"
 msgstr "Hostingpaketvorlage"
 
-#: hostingpackages/models.py:210
+#: hostingpackages/models.py:188
 msgid "The hosting package template that this hosting package is based on"
 msgstr "Die Hostingpaketvorlage, auf der dieses Hostingpaket aufgebaut ist"
 
-#: hostingpackages/models.py:215
+#: hostingpackages/models.py:195
 msgid "Operating system user"
 msgstr "Betriebssystemnutzer"
 
-#: hostingpackages/models.py:222
+#: hostingpackages/models.py:205
 msgid "customer hosting package"
 msgstr "Kundenhostingpaket"
 
-#: hostingpackages/models.py:223
+#: hostingpackages/models.py:206
 msgid "customer hosting packages"
 msgstr "Kundenhostingpakete"
 
-#: hostingpackages/models.py:226
+#: hostingpackages/models.py:209
 #, python-brace-format
 msgid "{name} for {customer}"
 msgstr "{name} für {customer}"
 
-#: hostingpackages/models.py:404 hostingpackages/models.py:426
+#: hostingpackages/models.py:388 hostingpackages/models.py:415
 msgid "hosting package"
 msgstr "Hostingpaket"
 
-#: hostingpackages/models.py:407
+#: hostingpackages/models.py:393
 msgid "hosting domain"
 msgstr "Hostingdomain"
 
-#: hostingpackages/models.py:429
+#: hostingpackages/models.py:420
 msgid "customer hosting option"
 msgstr "kundenspezifische Hostingoption"
 
-#: hostingpackages/models.py:430
+#: hostingpackages/models.py:421
 msgid "customer hosting options"
 msgstr "kundenspezifische Hostingoptionen"
 
-#: hostingpackages/models.py:442
+#: hostingpackages/models.py:433
 msgid "disk space option template"
 msgstr "Speicherplatzoptionsvorlage"
 
-#: hostingpackages/models.py:444
+#: hostingpackages/models.py:435
 msgid "The disk space option template that this disk space option is based on"
 msgstr ""
 "Die Speicherplatzoptionsvorlage auf der diese Speicherplatzoption aufgebaut "
 "ist"
 
-#: hostingpackages/models.py:458
+#: hostingpackages/models.py:450
 msgid "user database option template"
 msgstr "Nutzerdatenbankoptionsvorlage"
 
-#: hostingpackages/models.py:460
+#: hostingpackages/models.py:452
 msgid "The user database option template that this database option is based on"
 msgstr ""
 "Die Nutzerdatenbankoptionsvorlage auf der diese Datenbankoption aufgebaut ist"
 
-#: hostingpackages/models.py:474
+#: hostingpackages/models.py:467
 msgid "mailbox option template"
 msgstr "Postfachoptionsvorlage"
 
-#: hostingpackages/models.py:476
+#: hostingpackages/models.py:468
 msgid "The mailbox option template that this mailbox option is based on"
 msgstr "Die Postfachoptionsvorlage auf der diese Postfachoption aufgebaut ist"
 
-#: hostingpackages/views.py:60 hostingpackages/views.py:94
+#: hostingpackages/templates/hostingpackages/add_hosting_option.html:4
+#: hostingpackages/templates/hostingpackages/add_hosting_option.html:7
+#, python-format
+msgid "Add Option to Hosting Package %(package)s of Customer %(full_name)s"
+msgstr ""
+"Option zum Hostingpaket %(package)s des Kunden %(full_name)s hinzufügen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_admin_list.html:3
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_admin_list.html:4
+msgid "All hosting packages"
+msgstr "Alle Hostingpakete"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_admin_list.html:11
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:36
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_list.html:26
+msgid "Name"
+msgstr "Name"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_admin_list.html:12
+msgid "Customer"
+msgstr "Kunde"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_admin_list.html:13
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_list.html:27
+msgid "Setup date"
+msgstr "Einrichtungsdatum"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_admin_list.html:29
+msgid "No hosting packages have been setup yet."
+msgstr "Es wurden noch keine Hostingpakete eingerichtet."
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_admin_list.html:32
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_list.html:46
+msgid "Add hosting package"
+msgstr "Hostingpaket anlegen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_create.html:3
+#, python-format
+msgid "Add hosting package for Customer %(full_name)s"
+msgstr "Hostingpaket für Kunde %(full_name)s hinzufügen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_create.html:6
+#, python-format
+msgid "Add Hosting Package for Customer %(full_name)s"
+msgstr "Hosting Paket für Kunde %(full_name)s"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:6
+#, python-format
+msgid "Details for your Hosting Package %(package)s"
+msgstr "Details zu Ihrem Hostingpaket %(package)s"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:10
+#, python-format
+msgid "Details for Hosting Package %(package)s of %(full_name)s"
+msgstr "Details zum Hostingpaket %(package)s von %(full_name)s"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:16
+#, python-format
+msgid "Details of Hosting Package %(package)s"
+msgstr "Details zum Hostingpaket %(package)s"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:25
+msgid "Hosting Package Information"
+msgstr "Informationen zum Hostingpaket"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:29
+msgid "Edit Hosting Package Information"
+msgstr "Informationen zum Hostingpaket ändern"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:38
+msgid "Description"
+msgstr "Beschreibung"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:40
+#: hostingpackages/views.py:190
+msgid "Disk space"
+msgstr "Speicherplatz"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:43
+#, python-format
+msgid "The reserved disk space for your hosting package is %(diskspace)s bytes"
+msgstr ""
+"Der für Ihr Hostingpaket reservierte Speicherplatz beträgt %(diskspace)s "
+"Bytes"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:47
+#, python-format
+msgid ""
+"The package contributes %(humanbytes)s (%(packagespace)s bytes) the "
+"difference comes from disk space options"
+msgstr ""
+"Das Paket trägt %(humanbytes)s (%(packagespace)s Bytes) zur Gesamtgröße bei, "
+"der Unterschied ergibt sich aus Speicherplatzoptionen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:52
+#: hostingpackages/views.py:197
+msgid "Mailboxes"
+msgstr "Postfächer"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:54
+#, python-format
+msgid "%(num)s of %(total)s in use"
+msgstr "%(num)s von %(total)s genutzt"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:57
+#, python-format
+msgid ""
+"The package provides %(mailboxcount)s mailboxes the difference comes from "
+"mailbox options."
+msgstr ""
+"Das Paket bietet %(mailboxcount)s Postfächer, der Unterschied ergibt sich "
+"durch die Postfachoptionen."
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:59
+msgid "SFTP username"
+msgstr "SFTP-Benutzername"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:60
+msgid "SSH/SFTP username"
+msgstr "SSH/SFTP-Benutzername"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:63
+#, python-format
+msgid "There is an SSH public key set for this user."
+msgid_plural "There are %(counter)s SSH public keys set for this user."
+msgstr[0] "Es wurde ein SSH-Schlüssel für diesen Nutzer hinterlegt."
+msgstr[1] "Es wurden %(counter)s SSH-Schlüssel für diesen Nutzer hinterlegt."
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:65
+msgid "Upload server"
+msgstr "Uploadserver"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:73
+msgid "Hosting Package Options"
+msgstr "Hostingpaketoptionen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:81
+msgid "No options booked"
+msgstr "Keine Optionen gebucht"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:87
+msgid "Add another hosting option"
+msgstr "Eine weitere Hostingoption hinzufügen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:87
+msgid "Add option"
+msgstr "Option hinzufügen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:94
+msgid "Hosting Package Actions"
+msgstr "Aktionen zum Hostingpaket"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:98
+msgid "Edit Hosting Package Description"
+msgstr "Beschreibung des Hostingpakets bearbeiten"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:98
+msgid "Edit description"
+msgstr "Beschreibung bearbeiten"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:101
+msgid "Set SFTP password"
+msgstr "SFTP-Passwort setzen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:102
+msgid "Set SSH/SFTP password"
+msgstr "SSH/SFTP-Passwort setzen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:105
+msgid "Add an SSH public key that can be used as an alternative for password"
+msgstr ""
+"Einen SSH-Schlüssel, der als Alternative zum Passwort genutzt werden kann, "
+"hinzufügen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:107
+msgid "Add SSH public key"
+msgstr "SSH-Schlüssel hinzufügen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:116
+msgid "Domains"
+msgstr "Domains"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:121
+msgid "Domain name"
+msgstr "Domainname"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:122
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:201
+msgid "Mail addresses"
+msgstr "E-Mailadressen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:123
+msgid "Websites"
+msgstr "Webauftritte"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:124
+msgid "Domain actions"
+msgstr "Domainaktionen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:125
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:204
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:247
+msgid "Actions"
+msgstr "Aktionen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:137
+msgid "Edit mail address targets"
+msgstr "E-Mailadressziele bearbeiten"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:139
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:141
+msgid "Delete mail address"
+msgstr "E-Mailadresse löschen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:146
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:161
+msgid "None"
+msgstr "Keine"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:154
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:156
+msgid "Delete website"
+msgstr "Webauftritt löschen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:167
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:169
+msgid "Add mail address"
+msgstr "E-Mailadresse hinzufügen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:174
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:175
+msgid "Add website"
+msgstr "Webauftritt anlegen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:183
+msgid "There are no domains assigned to this hosting package yet."
+msgstr "Diesem Paket sind noch keine Domains zugeordnet."
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:187
+msgid "Add domain"
+msgstr "Domain hinzufügen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:195
+msgid "E-Mail-Accounts"
+msgstr "E-Mail-Konten"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:200
+msgid "Mailbox"
+msgstr "Postfach"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:202
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:214
+msgid "Active"
+msgstr "Aktiv"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:203
+msgid "Mailbox actions"
+msgstr "Postfachaktionen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:215
+msgid "inactive"
+msgstr "inaktiv"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:218
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:219
+msgid "Set mailbox password"
+msgstr "Postfachpasswort setzen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:225
+msgid "There are no mailboxes assigned to this hosting package yet."
+msgstr "Diesem Hostingpaket sind noch keine Postfächer zugeordnet."
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:230
+msgid "Add mailbox"
+msgstr "Postfach hinzufügen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:237
+#: hostingpackages/views.py:204
+msgid "Databases"
+msgstr "Datenbanken"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:242
+msgid "Database name"
+msgstr "Datenbankname"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:243
+msgid "Database user"
+msgstr "Datenbanknutzer"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:244
+msgid "Database type"
+msgstr "Datenbanktyp"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:245
+msgid "Type"
+msgstr "Typ"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:246
+msgid "Database actions"
+msgstr "Datenbankaktionen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:258
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:260
+msgid "Set database user password"
+msgstr "Datenbanknutzerpasswort setzen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:262
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:263
+msgid "Delete database"
+msgstr "Datenbank löschen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:270
+msgid "There are no databases assigned to this hosting package yet."
+msgstr "Diesem Hostingpaket sind noch keine Datenbanken zugeordnet."
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html:275
+msgid "Add database"
+msgstr "Datenbank hinzufügen"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_list.html:5
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_list.html:14
+msgid "Your hosting packages"
+msgstr "Ihre Hostingpakete"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_list.html:7
+#, python-format
+msgid "Hosting Packages of %(customer)s"
+msgstr "Hostingpakete des Kunden %(customer)s"
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_list.html:16
+#, python-format
+msgid "Hosting Packages of %(customer)s "
+msgstr "Hostingpakete des Kunden %(customer)s "
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_list.html:41
+msgid "You have no hosting packages setup yet."
+msgstr "Es wurden noch keine Hostingpakete für Sie eingerichtet."
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_list.html:42
+msgid "There are no hosting packages setup for this customer yet."
+msgstr "Es wurden noch keine Hostingpakete für diesen Kunden eingerichtet."
+
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_option_choices.html:5
+#: hostingpackages/templates/hostingpackages/customerhostingpackage_option_choices.html:8
+#, python-format
+msgid ""
+"Choose new Option for Hosting Package %(package)s of Customer %(full_name)s"
+msgstr ""
+"Wählen Sie eine neue Option für das Hostingpaket %(package)s des Kunden "
+"%(full_name)s"
+
+#: hostingpackages/views.py:49 hostingpackages/views.py:83
 #, python-brace-format
 msgid "Started setup of new hosting package {name}."
 msgstr "Einrichtung des Hostingpakets {name} wurde gestartet."
 
-#: hostingpackages/views.py:186
-msgid "Disk space"
-msgstr "Speicherplatz"
-
-#: hostingpackages/views.py:189
-msgid "Mailboxes"
-msgstr "Postfächer"
-
-#: hostingpackages/views.py:192
-msgid "Databases"
-msgstr "Datenbanken"
-
-#: hostingpackages/views.py:262
+#: hostingpackages/views.py:278
 #, python-brace-format
 msgid "Successfully added option {option} to hosting package {package}."
 msgstr "Option {option} erfolgreich zum Hostingpaket {package} hinzugefügt."
-
-#~ msgid "Hosting options"
-#~ msgstr "Hostingoptionen"
diff --git a/gnuviechadmin/hostingpackages/templates/hostingpackages/add_hosting_option.html b/gnuviechadmin/hostingpackages/templates/hostingpackages/add_hosting_option.html
new file mode 100644
index 0000000..172234c
--- /dev/null
+++ b/gnuviechadmin/hostingpackages/templates/hostingpackages/add_hosting_option.html
@@ -0,0 +1,13 @@
+{% extends "hostingpackages/base.html" %}
+{% load i18n crispy_forms_tags %}
+{% block title %}{{ block.super }} -
+    {% blocktranslate with package=hostingpackage.name full_name=customer.get_full_name trimmed %}
+        Add Option to Hosting Package {{ package }} of Customer {{ full_name }}
+    {% endblocktranslate %}{% endblock title %}
+{% block page_title %}{% blocktranslate with package=hostingpackage.name full_name=customer.get_full_name trimmed %}
+    Add Option to Hosting Package {{ package }} of Customer {{ full_name }}
+{% endblocktranslate %}{% endblock page_title %}
+
+{% block content %}
+    {% crispy form %}
+{% endblock content %}
diff --git a/gnuviechadmin/templates/hostingpackages/base.html b/gnuviechadmin/hostingpackages/templates/hostingpackages/base.html
similarity index 100%
rename from gnuviechadmin/templates/hostingpackages/base.html
rename to gnuviechadmin/hostingpackages/templates/hostingpackages/base.html
diff --git a/gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_admin_list.html b/gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_admin_list.html
new file mode 100644
index 0000000..5476caf
--- /dev/null
+++ b/gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_admin_list.html
@@ -0,0 +1,34 @@
+{% extends "hostingpackages/base.html" %}
+{% load i18n %}
+{% block title %}{{ block.super }} - {% translate "All hosting packages" %}{% endblock title %}
+{% block page_title %}{% translate "All hosting packages" %}{% endblock page_title %}
+
+{% block content %}
+    {% if customerhostingpackage_list %}
+        
+            
+            
+                {% translate "Name" %} 
+                {% translate "Customer" %} 
+                {% translate "Setup date" %} 
+             
+             
+            
+            {% for package in customerhostingpackage_list %}
+                
+                    {{ package.name }} 
+                        {{ package.customer }} 
+                     
+                    {{ package.created }} 
+                 
+            {% endfor %}
+             
+        
+    {% else %}
+        {% translate "No hosting packages have been setup yet." %}
+    {% endif %}
+    
+        {% translate "Add hosting package" %} 
+    
+{% endblock content %}
\ No newline at end of file
diff --git a/gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_create.html b/gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_create.html
new file mode 100644
index 0000000..8134bd9
--- /dev/null
+++ b/gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_create.html
@@ -0,0 +1,12 @@
+{% extends "hostingpackages/base.html" %}
+{% load i18n crispy_forms_tags %}
+{% block title %}{{ block.super }} - {% blocktranslate with full_name=customer.get_full_name trimmed %}
+    Add hosting package for Customer {{ full_name }}
+{% endblocktranslate %}{% endblock title %}
+{% block page_title %}{% blocktranslate with full_name=customer.get_full_name trimmed %}
+    Add Hosting Package for Customer {{ full_name }}
+{% endblocktranslate %}{% endblock page_title %}
+
+{% block content %}
+    {% crispy form %}
+{% endblock content %}
diff --git a/gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html b/gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html
new file mode 100644
index 0000000..c04be76
--- /dev/null
+++ b/gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_detail.html
@@ -0,0 +1,280 @@
+{% extends "hostingpackages/base.html" %}
+{% load i18n %}
+
+{% block title %}{{ block.super }} - {% spaceless %}
+    {% if user == customer %}
+        {% blocktranslate with package=hostingpackage.name trimmed %}
+            Details for your Hosting Package {{ package }}
+        {% endblocktranslate %}
+    {% else %}
+        {% blocktranslate with package=hostingpackage.name full_name=customer.get_full_name trimmed %}
+            Details for Hosting Package {{ package }} of {{ full_name }}
+        {% endblocktranslate %}
+    {% endif %}
+{% endspaceless %}{% endblock title %}
+
+{% block page_title %}{% blocktranslate with package=hostingpackage.name trimmed %}
+    Details of Hosting Package {{ package }}
+{% endblocktranslate %}{% endblock page_title %}
+
+{% block content %}
+    
+        
+            
+                
+                
+                    
+                        {% translate "Name" %} 
+                        {{ hostingpackage.name }} 
+                        {% translate "Description" %} 
+                        {{ hostingpackage.description|default:"-" }} 
+                        {% translate "Disk space" %} 
+                        {% with diskspace=hostingpackage.get_disk_space packagespace=hostingpackage.get_package_space %}
+                            
+                                {{ diskspace|filesizeformat }} 
+                                 
+                        {% endwith %}
+                        {% translate "Mailboxes" %} 
+                        
+                            {% blocktranslate with num=hostingpackage.used_mailbox_count total=hostingpackage.mailbox_count trimmed %}
+                                {{ num }} of {{ total }} in use{% endblocktranslate %}
+                             
+                        {% if osuser.is_sftp_user %}{% translate "SFTP username" %}{% else %}
+                            {% translate "SSH/SFTP username" %}{% endif %} 
+                        {{ osuser.username }}{% if sshkeys %}
+                             
+                        {% translate "Upload server" %} 
+                        {{ uploadserver }} 
+                     
+                
+            
+        
+        
+            
+                
+                {% if hostingoptions %}
+                    
+                        {% for opt in hostingoptions %}
+                            {{ opt }} 
+                        {% endfor %}
+                     
+                {% else %}
+                    
{% translate "No options booked" %}
+                {% endif %}
+                {% if user.is_staff %}
+                    
+                {% endif %}
+            
+        
+        
+    
+        
+            
+                
+                {% if domains %}
+                    
+                        
+                        
+                            {% translate "Domain name" %} 
+                            {% translate "Mail addresses" %} 
+                            {% translate "Websites" %} 
+                            {% translate "Actions" %}  
+                         
+                        
+                        {% for domain in domains %}
+                            
+                                {{ domain.domain }} 
+                                {% if domain.domain.maildomain.mailaddress_set.exists %}
+                                    
+                                        {% with maildomain=domain.domain.maildomain %}
+                                            {% for mailaddress in maildomain.mailaddresses %}{% spaceless %}
+                                                {{ mailaddress }} 
+                                                 {% translate "Delete mail address" %}  
+                                {% else %}
+                                    {% translate "None" %} 
+                                {% endif %}
+                                {% if domain.domain.website_set.exists %}
+                                    
+                                        {% with domain=domain.domain %}
+                                            {% for website in domain.website_set.all %}{% spaceless %}
+                                                {{ website }}
+                                                 {% translate "Delete website" %}  
+                                {% else %}
+                                    {% translate "None" %} 
+                                {% endif %}
+                                
+                                    {% if domain.domain.maildomain %}
+                                        {% with maildomain=domain.domain.maildomain %}
+                                             {% translate "Add mail address" %}  {% translate "Add website" %}  
+                             
+                        {% endfor %}
+                         
+                    
+                {% else %}
+                    
{% translate "There are no domains assigned to this hosting package yet." %}
+                {% endif %}
+                {% if user.is_staff %}
+                    
+                {% endif %}
+            
+        
+    
+        
+            
+                
+                {% if mailboxes %}
+                    
+                        
+                        
+                            {% translate "Mailbox" %} 
+                            {% translate "Mail addresses" %} 
+                            {% translate "Active" %} 
+                            {% translate "Actions" %}  
+                         
+                        
+                        {% for mailbox in mailboxes %}
+                            
+                            {{ mailbox.username }} 
+                            {{ mailbox.mailaddresses|join:", " }} 
+                            
+                                 {% if mailbox.active %}{% translate "Active" %}{% else %}
+                                {% translate "inactive" %}{% endif %}  
+                            
+                                 {% translate "Set mailbox password" %}  
+                        {% endfor %}
+                          
+                    
+                {% else %}
+                    
{% translate "There are no mailboxes assigned to this hosting package yet." %}
+                {% endif %}
+                {% if hostingpackage.may_add_mailbox %}
+                    
+                {% endif %}
+            
+        
+        
+            
+                
+                {% if databases %}
+                    
+                        
+                        
+                            {% translate "Database name" %} 
+                            {% translate "Database user" %} 
+                            {% translate "Type" %} {% translate "Actions" %}  
+                         
+                        
+                        {% for database in databases %}
+                            
+                                {{ database.db_name }} 
+                                {{ database.db_user.name }} 
+                                {% include "userdbs/snippets/db_type.html" with db_type=database.db_user.db_type %} 
+                                
+                                     {% translate "Set database user password" %} {% translate "Delete database" %}  
+                             
+                        {% endfor %}
+                         
+                    
+                {% else %}
+                    
{% translate "There are no databases assigned to this hosting package yet." %}
+                {% endif %}
+                {% if hostingpackage.may_add_database %}
+                    
+                {% endif %}
+            
+        
+    
of {{ customer }} {% endblocktranslate %}
+    {% endif %}
+{% endspaceless %}{% endblock page_title %}
+
+{% block content %}
+    {% if customerhostingpackage_list %}
+        
+            
+            
+                {% translate "Name" %} 
+                {% translate "Setup date" %} 
+             
+             
+            
+            {% for package in customerhostingpackage_list %}
+                
+                    {{ package.name }} {{ package.created }} 
+                 
+            {% endfor %}
+             
+        
+    {% else %}
+        
+            {% if user == customer %}{% translate "You have no hosting packages setup yet." %}{% else %}
+                {% translate "There are no hosting packages setup for this customer yet." %}{% endif %}
+    {% endif %}
+    {% if user.is_staff %}
+        {% translate "Add hosting package" %} 
+    {% endif %}
+{% endblock content %}
diff --git a/gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_option_choices.html b/gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_option_choices.html
new file mode 100644
index 0000000..3da2568
--- /dev/null
+++ b/gnuviechadmin/hostingpackages/templates/hostingpackages/customerhostingpackage_option_choices.html
@@ -0,0 +1,29 @@
+{% extends "hostingpackages/base.html" %}
+{% load i18n %}
+
+{% block title %}{{ block.super }} -
+    {% blocktranslate with package=hostingpackage.name full_name=customer.get_full_name trimmed %}Choose new Option for
+        Hosting Package {{ package }} of Customer {{ full_name }}{% endblocktranslate %}{% endblock title %}
+
+{% block page_title %}{% blocktranslate with package=hostingpackage.name full_name=customer.get_full_name trimmed %}
+    Choose new Option for Hosting Package {{ package }} of Customer {{ full_name }}
+{% endblocktranslate %}{% endblock page_title %}
+
+{% block content %}
+    
+        {% for label, items in hosting_options %}
+            
+                
+                    
+                    
+                        {% for item, option_type in items %}
+                             
+                
+            
+        {% endfor %}
+    
\n"
 "Language-Team: Jan Dittberner \n"
 "Language: de\n"
@@ -16,7 +16,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 1.6.10\n"
+"X-Generator: Poedit 3.2.2\n"
 "X-Poedit-SourceCharset: UTF-8\n"
 
 #: templates/account/account_inactive.html:4
@@ -44,7 +44,7 @@ msgstr "Die folgenden E-Mailadressen sind Ihrem Konto zugeordnet:"
 msgid "Email address"
 msgstr "E-Mailadresse"
 
-#: templates/account/email.html:15 templates/account/email.html.py:25
+#: templates/account/email.html:15 templates/account/email.html:25
 msgid "Verified"
 msgstr "Geprüft"
 
@@ -68,7 +68,7 @@ msgstr "Als primär definieren"
 msgid "Re-send Verification"
 msgstr "Prüf-E-Mail noch einmal verschicken"
 
-#: templates/account/email.html:45 templates/socialaccount/connections.html:36
+#: templates/account/email.html:45 templates/socialaccount/connections.html:42
 msgid "Remove"
 msgstr "Entfernen"
 
@@ -158,15 +158,15 @@ msgstr ""
 "Bitte bestätigen Sie, dass %(email)s  eine E-"
 "Mailadresse des Benutzers %(user_display)s ist."
 
-#: templates/account/email_confirm.html:12
+#: templates/account/email_confirm.html:14
 msgid "Confirm"
 msgstr "Bestätigen"
 
-#: templates/account/email_confirm.html:16
+#: templates/account/email_confirm.html:18
 #, python-format
 msgid ""
-"This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request ."
+"This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request ."
 msgstr ""
 "Dieser E-Mail-Bestätigungslink ist abgelaufen oder ungültig. Bitte stellen "
 "Sie eine neue E-Mail-Bestätigungsanfrage ."
@@ -180,42 +180,17 @@ msgstr ""
 "Sie haben bestätigt, dass %(email)s  eine E-"
 "Mailadresse des Benutzers %(user_display)s ist."
 
-#: templates/account/login.html:4 templates/account/login.html.py:5
-#: templates/account/login.html:30 templates/base.html.py:81
-#: templates/registration/login.html:4
+#: templates/account/login.html:4 templates/account/login.html:5
+#: templates/account/login.html:18 templates/base.html:124
+#: templates/registration/login.html:4 templates/socialaccount/login.html:4
 msgid "Sign In"
 msgstr "Anmelden"
 
-#: templates/account/login.html:10
-#, python-format
-msgid ""
-"Please sign in with one\n"
-"of your existing third party accounts. Or, sign "
-"up \n"
-"for a %(site_name)s account and sign in below:"
-msgstr ""
-"Bitte melden Sie sich mit Ihrem bestehenden Drittanbieterkonto an. Oder, registrieren Sie sich  für ein Konto auf "
-"%(site_name)s und melden Sie sich unten an:"
-
 #: templates/account/login.html:17
-msgid "or"
-msgstr "oder"
-
-#: templates/account/login.html:19
-#, python-format
-msgid ""
-"If you have not created an account yet, then please\n"
-"sign up  first."
-msgstr ""
-"Wenn Sie noch kein Konto haben, Registrieren Sie "
-"sich  bitte erst."
-
-#: templates/account/login.html:29
 msgid "Forgot Password?"
 msgstr "Passwort vergessen?"
 
-#: templates/account/logout.html:4 templates/account/logout.html.py:5
+#: templates/account/logout.html:4 templates/account/logout.html:5
 #: templates/account/logout.html:15
 msgid "Sign Out"
 msgstr "Abmelden"
@@ -317,22 +292,22 @@ msgstr ""
 msgid "Bad Token"
 msgstr "Ungültiges Token"
 
-#: templates/account/password_reset_from_key.html:9
+#: templates/account/password_reset_from_key.html:10
 #, python-format
 msgid ""
 "The password reset link was invalid, possibly because it has already been "
-"used.  Please request a new password reset"
+"used. Please request a  new password reset"
 "a>."
 msgstr ""
 "Der Passwortrücksetzungslink war ungültig, möglicherweise wurde er bereits "
-"verwendet. Bitte fordern Sie erneut eine  Passwortrücksetzung  an."
+"verwendet. Bitte fordern Sie erneut eine Passwortrücksetzung  an."
 
-#: templates/account/password_reset_from_key.html:15
+#: templates/account/password_reset_from_key.html:17
 msgid "change password"
 msgstr "Passwort ändern"
 
-#: templates/account/password_reset_from_key.html:18
+#: templates/account/password_reset_from_key.html:20
 #: templates/account/password_reset_from_key_done.html:7
 msgid "Your password is now changed."
 msgstr "Ihr Passwort wurde geändert."
@@ -342,13 +317,12 @@ msgstr "Ihr Passwort wurde geändert."
 msgid "Set Password"
 msgstr "Passwort setzen"
 
-#: templates/account/signup.html:4 templates/socialaccount/signup.html.py:4
+#: templates/account/signup.html:4 templates/socialaccount/signup.html:4
 msgid "Signup"
 msgstr "Registrieren"
 
-#: templates/account/signup.html:5 templates/account/signup.html.py:15
-#: templates/base.html:82 templates/socialaccount/signup.html.py:5
-#: templates/socialaccount/signup.html:15
+#: templates/account/signup.html:5 templates/account/signup.html:17
+#: templates/socialaccount/signup.html:5 templates/socialaccount/signup.html:18
 msgid "Sign Up"
 msgstr "Registrieren"
 
@@ -398,23 +372,23 @@ msgstr ""
 
 #: templates/account/verified_email_required.html:9
 msgid ""
-"This part of the site requires us to verify that\n"
-"you are who you claim to be. For this purpose, we require that you\n"
-"verify ownership of your e-mail address. "
+"This part of the site requires us to verify that you are who you claim to "
+"be. For this purpose, we require that you verify ownership of your e-mail "
+"address."
 msgstr ""
 "Dieser Teil unseres Angebots erfordert eine Bestätigung, dass Sie derjenige "
 "sind, der Sie vorgeben zu sein. Zu diesem Zweck benötigen wir die "
-"Bestätigung, dass Sie der Eigentümer Ihrer E-Mailadresse sind."
+"Bestätigung, dass Sie der Eigentümer Ihrer E-Mail-Adresse sind."
 
 #: templates/account/verified_email_required.html:13
 msgid ""
-"We have sent an e-mail to you for\n"
-"verification. Please click on the link inside this e-mail. Please\n"
-"contact us if you do not receive it within a few minutes."
+"We have sent an e-mail to you for verification. Please click on the link "
+"inside this e-mail. Please contact us if you do not receive it within a few "
+"minutes."
 msgstr ""
-"Wir haben Ihnen zur Bestätigung eine E-Mail geschickt.\n"
-"Bitte klicken Sie auf den Link in dieser Mail. Bitte kontaktieren\n"
-"Sie uns, wenn Sie die E-Mail nicht in den nächsten Minuten erhalten."
+"Wir haben Ihnen zur Bestätigung eine E-Mail geschickt. Bitte klicken Sie auf "
+"den Link in dieser Mail. Bitte kontaktieren Sie uns, wenn Sie die E-Mail "
+"nicht in den nächsten Minuten erhalten."
 
 #: templates/account/verified_email_required.html:17
 #, python-format
@@ -425,31 +399,31 @@ msgstr ""
 "Hinweis:  Sie können Ihre E-"
 "Mailadresse noch ändern ."
 
-#: templates/base.html:43
+#: templates/base.html:32
 msgid "Dashboard"
 msgstr "Dashboard"
 
-#: templates/base.html:49 templates/base.html.py:56
+#: templates/base.html:34
+msgid "Toggle navigation"
+msgstr "Navigation umschalten"
+
+#: templates/base.html:42 templates/base.html:53
 msgid "Hosting"
 msgstr "Hosting"
 
-#: templates/base.html:51
-#: templates/hostingpackages/customerhostingpackage_list.html:5
-#: templates/hostingpackages/customerhostingpackage_list.html:13
+#: templates/base.html:45
 msgid "Your hosting packages"
 msgstr "Ihre Hostingpakete"
 
-#: templates/base.html:52
-#: templates/hostingpackages/customerhostingpackage_admin_list.html:3
-#: templates/hostingpackages/customerhostingpackage_admin_list.html:4
+#: templates/base.html:47
 msgid "All hosting packages"
 msgstr "Alle Hostingpakete"
 
-#: templates/base.html:59
+#: templates/base.html:57
 msgid "Links"
 msgstr "Links"
 
-#: templates/base.html:61
+#: templates/base.html:60
 msgid "Web based mail system"
 msgstr "Webbasiertes E-Mailsystem"
 
@@ -457,63 +431,86 @@ msgstr "Webbasiertes E-Mailsystem"
 msgid "Webmail"
 msgstr "Webmail"
 
-#: templates/base.html:62
+#: templates/base.html:63
 msgid "phpMyAdmin - MySQL database administration tool"
 msgstr "phpMyAdmin - MySQL-Datenbankverwaltungswerkzeug"
 
-#: templates/base.html:62
+#: templates/base.html:64
 msgid "phpMyAdmin"
 msgstr "phpMyAdmin"
 
-#: templates/base.html:63
+#: templates/base.html:66
 msgid "phpPgAdmin - PostgreSQL database administration tool"
 msgstr "phpPgAdmin - PostgreSQL-Datenbankverwaltungswerkzeug"
 
-#: templates/base.html:63
+#: templates/base.html:67
 msgid "phpPgAdmin"
 msgstr "phpPgAdmin"
 
-#: templates/base.html:66
+#: templates/base.html:71
 msgid "Imprint"
 msgstr "Impressum"
 
-#: templates/base.html:67 templates/contact_form/contact_form.html.py:4
+#: templates/base.html:74
+msgid "Privacy policy"
+msgstr "Datenschutz"
+
+#: templates/base.html:78 templates/contact_form/contact_form.html:4
 #: templates/contact_form/contact_form.html:5
 #: templates/contact_form/contact_success.html:4
 #: templates/contact_form/contact_success.html:5
 msgid "Contact"
 msgstr "Kontakt"
 
-#: templates/base.html:72
-msgid "My Account"
-msgstr "Mein Konto"
+#: templates/base.html:86
+#, python-format
+msgid ""
+"Signed in as %(user_display)s  %(user_display)s  %(user_display)s "
 msgstr ""
-"Angemeldet als %(user_display)s "
+"Angemeldet als %(user_display)s "
 
-#: templates/base.html:101
+#: templates/base.html:103
+msgid "My Account"
+msgstr "Mein Konto"
+
+#: templates/base.html:107
+msgid "Impersonate user"
+msgstr "Als Nutzer agieren"
+
+#: templates/base.html:111
+msgid "Admin site"
+msgstr "Adminsite"
+
+#: templates/base.html:113
+msgid "Change Email"
+msgstr "E-Mail ändern"
+
+#: templates/base.html:116
+msgid "Social Accounts"
+msgstr "Konten in sozialen Netzwerken"
+
+#: templates/base.html:118
+msgid "Logout"
+msgstr "Abmelden"
+
+#: templates/base.html:139
 msgid "Close"
 msgstr "Schließen"
 
@@ -521,448 +518,70 @@ msgstr "Schließen"
 msgid "Your message has been sent successfully."
 msgstr "Ihre Nachricht wurde erfolgreich übermittelt."
 
-#: templates/dashboard/index.html:3
-msgid "Welcome"
-msgstr "Willkommen"
-
-#: templates/dashboard/index.html:4
-msgid "Welcome to our customer self service"
-msgstr "Willkommen in unserem Selbstservice-System"
-
-#: templates/dashboard/index.html:7
-#, python-format
-msgid ""
-"Hello %(full_name)s,Dashboard  to view and "
-"modify your hosting options.\n"
-msgstr ""
-"Hallo %(full_name)s,Startseite  besuchen, um "
-"Ihre Hostingeinstellungen anzusehen und zu bearbeiten.\n"
-
-#: templates/dashboard/index.html:11
-msgid "This is your entry to our customer self service sytem."
-msgstr "Dies ist Ihr Einstieg in unser Selbstservice-System"
-
-#: templates/dashboard/index.html:12
-#, python-format
-msgid ""
-"If you are already a customer you can Sign in  to view and modify your hosting options."
-msgstr ""
-"Wenn Sie bereits Kunde bei uns sind, können Sie sich Anmelden  um Ihre Hostingeinstellungen anzusehen "
-"und zu bearbeiten."
-
-#: templates/dashboard/user_dashboard.html:3
-#: templates/dashboard/user_dashboard.html:4
-#, python-format
-msgid "Dashboard for %(full_name)s"
-msgstr "Startseite für %(full_name)s"
-
-#: templates/dashboard/user_dashboard.html:9
-msgid "Hosting packages"
-msgstr "Hostingpakete"
-
-#: templates/dashboard/user_dashboard.html:15
-#: templates/hostingpackages/customerhostingpackage_admin_list.html:11
-#: templates/hostingpackages/customerhostingpackage_detail.html:27
-#: templates/hostingpackages/customerhostingpackage_list.html:24
-msgid "Name"
-msgstr "Name"
-
-#: templates/dashboard/user_dashboard.html:16
-#: templates/hostingpackages/customerhostingpackage_detail.html:31
-msgid "Disk space"
-msgstr "Speicherplatz"
-
-#: templates/dashboard/user_dashboard.html:17
-#: templates/hostingpackages/customerhostingpackage_detail.html:38
-msgid "Mailboxes"
-msgstr "Postfächer"
-
-#: templates/dashboard/user_dashboard.html:18
-#: templates/hostingpackages/customerhostingpackage_detail.html:177
-msgid "Databases"
-msgstr "Datenbanken"
-
-#: templates/dashboard/user_dashboard.html:19
-#: templates/hostingpackages/customerhostingpackage_detail.html:87
-#: templates/hostingpackages/customerhostingpackage_detail.html:150
-#: templates/hostingpackages/customerhostingpackage_detail.html:185
-#: templates/osusers/sshpublickey_list.html:27
-msgid "Actions"
-msgstr "Aktionen"
-
-#: templates/dashboard/user_dashboard.html:25
-#, python-format
-msgid "Show details for %(packagename)s"
-msgstr "Details für %(packagename)s anzeigen"
-
-#: templates/dashboard/user_dashboard.html:28
-#, python-format
-msgid ""
-"The reserved disk space for your hosting package is %(diskspace)s bytes."
-msgstr ""
-"Der für Ihr Hostingpaket reservierte Speicherplatz sind %(diskspace)s Bytes."
-
-#: templates/dashboard/user_dashboard.html:31
-#, python-format
-msgid "used %(num)s of %(total)s"
-msgstr "%(num)s von %(total)s genutzt"
-
-#: templates/dashboard/user_dashboard.html:42
-msgid "You have no hosting packages yet."
-msgstr "Sie haben noch keine Hostingpakete."
-
-#: templates/dashboard/user_dashboard.html:42
-msgid "This user has no hosting packages assigned yet."
-msgstr "Diesem Benutzer sind noch keine Hostingpakete zugewiesen."
-
-#: templates/dashboard/user_dashboard.html:45
-#: templates/hostingpackages/customerhostingpackage_admin_list.html:30
-#: templates/hostingpackages/customerhostingpackage_list.html:41
-msgid "Add hosting package"
-msgstr "Hostingpaket anlegen"
-
-#: templates/domains/hostingdomain_create.html:3
 #: templates/domains/hostingdomain_create.html:4
+#: templates/domains/hostingdomain_create.html:7
 #, python-format
 msgid "Add Domain to Hosting Package %(package)s of Customer %(full_name)s"
 msgstr ""
 "Domain zum Hostingpaket %(package)s des Kunden %(full_name)s hinzufügen"
 
-#: templates/hostingpackages/add_hosting_option.html:3
-#: templates/hostingpackages/add_hosting_option.html:4
+#: templates/impersonate/list_users.html:4
+msgid "Django Impersonate - User List"
+msgstr "Django Impersonate - Nutzerliste"
+
+#: templates/impersonate/list_users.html:5
 #, python-format
-msgid "Add Option to Hosting Package %(package)s of Customer %(full_name)s"
-msgstr ""
-"Option zum Hostingpaket %(package)s des Kunden %(full_name)s hinzufügen"
+msgid "User List - Page %(page_number)s"
+msgstr "Nutzerliste - Seite %(page_number)s"
 
-#: templates/hostingpackages/customerhostingpackage_admin_list.html:12
-msgid "Customer"
-msgstr "Kunde"
+#: templates/impersonate/list_users.html:21
+msgid "Search users"
+msgstr "Nutzer suchen"
 
-#: templates/hostingpackages/customerhostingpackage_admin_list.html:13
-#: templates/hostingpackages/customerhostingpackage_list.html:25
-msgid "Setup date"
-msgstr "Einrichtungsdatum"
+#: templates/impersonate/search_users.html:4
+msgid "Django Impersonate - Search Users"
+msgstr "Django Impersonate - Nutzersuche"
 
-#: templates/hostingpackages/customerhostingpackage_admin_list.html:27
-msgid "There are no hosting packages setup yet."
-msgstr "Es sind noch keine Hostingpakete eingerichtet."
+#: templates/impersonate/search_users.html:11
+msgid "Enter Search Query:"
+msgstr "Suchanfrage eingeben:"
 
-#: templates/hostingpackages/customerhostingpackage_create.html:3
-#, python-format
-msgid "Add hosting package for Customer %(full_name)s"
-msgstr "Hostingpaket für Kunde %(full_name)s hinzufügen"
+#: templates/impersonate/search_users.html:15
+msgid "Search"
+msgstr "Suchen"
 
-#: templates/hostingpackages/customerhostingpackage_create.html:4
-#, python-format
-msgid "Add Hosting Package for Customer %(full_name)s"
-msgstr "Hosting Paket für Kunde %(full_name)s"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:6
-#, python-format
-msgid "Details for your Hosting Package %(package)s"
-msgstr "Details zu Ihrem Hostingpaket %(package)s"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:8
-#, python-format
-msgid "Details for Hosting Package %(package)s of %(full_name)s"
-msgstr "Details zum Hostingpaket %(package)s von %(full_name)s"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:12
-#, python-format
-msgid "Details of Hosting Package %(package)s"
-msgstr "Details zum Hostingpaket %(package)s"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:19
-msgid "Hosting Package Information"
-msgstr "Informationen zum Hostingpaket"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:22
-msgid "Edit Hosting Package Information"
-msgstr "Informationen zum Hostingpaket ändern"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:29
-msgid "Description"
-msgstr "Beschreibung"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:34
-#, python-format
-msgid "The reserved disk space for your hosting package is %(diskspace)s bytes"
-msgstr ""
-"Der für Ihr Hostingpaket reservierte Speicherplatz beträgt %(diskspace)s "
-"Bytes."
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:35
-#, python-format
-msgid ""
-"The package contributes %(humanbytes)s (%(packagespace)s bytes) the "
-"difference comes from disk space options"
-msgstr ""
-"Das Paket trägt %(humanbytes)s (%(packagespace)s Bytes) zur Gesamtgröße bei, "
-"der Unterschied ergibt sich aus Speicherplatzoptionen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:39
-#, python-format
-msgid "%(num)s of %(total)s in use"
-msgstr "%(num)s von %(total)s genutzt"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:40
-#, python-format
-msgid ""
-"The package provides %(mailboxcount)s mailboxes the difference comes from "
-"mailbox options."
-msgstr ""
-"Das Paket bietet %(mailboxcount)s Postfächer, der Unterschied ergibt sich "
-"durch die Postfachoptionen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:41
-msgid "SFTP username"
-msgstr "SFTP-Benutzername"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:41
-msgid "SSH/SFTP username"
-msgstr "SSH/SFTP-Benutzername"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:42
-#, python-format
-msgid "There is an SSH public key set for this user."
-msgid_plural "There are %(counter)s SSH public keys set for this user."
-msgstr[0] "Es wurde ein SSH-Schlüssel für diesen Nutzer hinterlegt."
-msgstr[1] "Es wurden %(counter)s SSH-Schlüssel für diesen Nutzer hinterlegt."
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:43
-msgid "Upload server"
-msgstr "Uploadserver"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:50
-msgid "Hosting Package Options"
-msgstr "Hostingpaketoptionen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:58
-msgid "No options booked"
-msgstr "Keine Optionen gebucht"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:61
-msgid "Add another hosting option"
-msgstr "Eine weitere Hostingoption hinzufügen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:61
-msgid "Add option"
-msgstr "Option hinzufügen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:67
-msgid "Hosting Package Actions"
-msgstr "Aktionen zum Hostingpaket"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:69
-msgid "Edit Hosting Package Description"
-msgstr "Beschreibung des Hostingpakets bearbeiten"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:69
-msgid "Edit description"
-msgstr "Beschreibung bearbeiten"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:70
-msgid "Set SFTP password"
-msgstr "SFTP-Passwort setzen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:70
-msgid "Set SSH/SFTP password"
-msgstr "SSH/SFTP-Passwort setzen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:71
-msgid "Add an SSH public key that can be used as an alternative for password"
-msgstr ""
-"Einen SSH-Schlüssel, der als Alternative zum Passwort genutzt werden kann, "
-"hinzufügen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:71
-#: templates/osusers/sshpublickey_list.html:46
-msgid "Add SSH public key"
-msgstr "SSH-Schlüssel hinzufügen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:79
-msgid "Domains"
-msgstr "Domains"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:84
-msgid "Domain name"
-msgstr "Domainname"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:85
-#: templates/hostingpackages/customerhostingpackage_detail.html:148
-msgid "Mail addresses"
-msgstr "E-Mailadressen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:86
-msgid "Websites"
-msgstr "Webauftritte"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:87
-msgid "Domain actions"
-msgstr "Domainaktionen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:98
-msgid "Edit mail address targets"
-msgstr "E-Mailadressziele bearbeiten"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:99
-msgid "Delete mail address"
-msgstr "E-Mailadresse löschen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:104
-#: templates/hostingpackages/customerhostingpackage_detail.html:116
-msgid "None"
-msgstr "Keine"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:111
-msgid "Delete website"
-msgstr "Webauftritt löschen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:120
-msgid "Add mail address"
-msgstr "E-Mailadresse hinzufügen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:123
-msgid "Add website"
-msgstr "Webauftritt anlegen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:131
-msgid "There are no domains assigned to this hosting package yet."
-msgstr "Diesem Paket sind noch keine Domains zugeordnet."
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:134
-msgid "Add domain"
-msgstr "Domain hinzufügen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:142
-msgid "E-Mail-Accounts"
-msgstr "E-Mailkonten"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:147
-msgid "Mailbox"
-msgstr "Postfach"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:149
-#: templates/hostingpackages/customerhostingpackage_detail.html:158
-msgid "Active"
-msgstr "Aktiv"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:150
-msgid "Mailbox actions"
-msgstr "Postfachaktionen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:158
-msgid "inactive"
-msgstr "inaktiv"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:160
-msgid "Set mailbox password"
-msgstr "Postfachpasswort setzen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:166
-msgid "There are no mailboxes assigned to this hosting package yet."
-msgstr "Diesem Hostingpaket sind noch keine Postfächer zugeordnet."
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:169
-msgid "Add mailbox"
-msgstr "Postfach hinzufügen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:182
-msgid "Database name"
-msgstr "Datenbankname"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:183
-msgid "Database user"
-msgstr "Datenbanknutzer"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:184
-msgid "Database type"
-msgstr "Datenbanktyp"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:184
-msgid "Type"
-msgstr "Typ"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:185
-msgid "Database actions"
-msgstr "Datenbankaktionen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:195
-msgid "Set database user password"
-msgstr "Datenbanknutzerpasswort setzen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:196
-msgid "Delete database"
-msgstr "Datenbank löschen"
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:203
-msgid "There are no databases assigned to this hosting package yet."
-msgstr "Diesem Hostingpaket sind noch keine Datenbanken zugeordnet."
-
-#: templates/hostingpackages/customerhostingpackage_detail.html:206
-msgid "Add database"
-msgstr "Datenbank hinzufügen"
-
-#: templates/hostingpackages/customerhostingpackage_list.html:7
-#, python-format
-msgid "Hosting Packages of %(customer)s"
-msgstr "Hostingpakete des Kunden %(customer)s"
-
-#: templates/hostingpackages/customerhostingpackage_list.html:15
-#, python-format
-msgid "Hosting Packages of %(customer)s "
-msgstr "Hostingpakete des Kunden %(customer)s "
-
-#: templates/hostingpackages/customerhostingpackage_list.html:38
-msgid "You have no hosting packages setup yet."
-msgstr "Es wurden noch keine Hostingpakete für Sie eingerichtet."
-
-#: templates/hostingpackages/customerhostingpackage_list.html:38
-msgid "There are no hosting packages setup for this customer yet."
-msgstr "Es wurden noch keine Hostingpakete für diesen Kunden eingerichtet."
-
-#: templates/hostingpackages/customerhostingpackage_option_choices.html:4
-#: templates/hostingpackages/customerhostingpackage_option_choices.html:6
-#, python-format
-msgid ""
-"Choose new Option for Hosting Package %(package)s of Customer %(full_name)s"
-msgstr ""
-"Wählen Sie eine neue Option für das Hostingpaket %(package)s des Kunden "
-"%(full_name)s"
+#: templates/impersonate/search_users.html:19
+msgid "List all users"
+msgstr "Alle Nutzer auflisten"
 
 #: templates/managemails/mailaddress_confirm_delete.html:6
-#: templates/managemails/mailaddress_confirm_delete.html:14
+#: templates/managemails/mailaddress_confirm_delete.html:16
 #, python-format
 msgid "Delete Mail Address %(mailaddress)s"
 msgstr "E-Mailadresse %(mailaddress)s löschen"
 
 #: templates/managemails/mailaddress_confirm_delete.html:8
-#: templates/managemails/mailaddress_confirm_delete.html:16
+#: templates/managemails/mailaddress_confirm_delete.html:18
 #, python-format
 msgid "Delete Mail Address %(mailaddress)s of Customer %(full_name)s"
 msgstr "E-Mailadresse %(mailaddress)s des Kunden %(full_name)s löschen"
 
-#: templates/managemails/mailaddress_confirm_delete.html:23
+#: templates/managemails/mailaddress_confirm_delete.html:26
 #, python-format
 msgid "Do you really want to delete the mail address %(mailaddress)s?"
 msgstr "Wollen Sie die E-Mailadresse %(mailaddress)s wirklich löschen?"
 
-#: templates/managemails/mailaddress_confirm_delete.html:28
-#: templates/osusers/sshpublickey_confirm_delete.html:30
-#: templates/userdbs/userdatabase_confirm_delete.html:29
-#: templates/websites/website_confirm_delete.html:29
+#: templates/managemails/mailaddress_confirm_delete.html:33
+#: templates/osusers/sshpublickey_confirm_delete.html:41
+#: templates/userdbs/userdatabase_confirm_delete.html:42
+#: templates/websites/website_confirm_delete.html:38
 msgid "Yes, do it!"
 msgstr "Ja, so soll es sein!"
 
-#: templates/managemails/mailaddress_confirm_delete.html:29
-#: templates/osusers/sshpublickey_confirm_delete.html:31
-#: templates/userdbs/userdatabase_confirm_delete.html:30
-#: templates/websites/website_confirm_delete.html:30
+#: templates/managemails/mailaddress_confirm_delete.html:34
+#: templates/osusers/sshpublickey_confirm_delete.html:43
+#: templates/userdbs/userdatabase_confirm_delete.html:43
+#: templates/websites/website_confirm_delete.html:39
 msgid "Cancel"
 msgstr "Abbrechen"
 
@@ -974,12 +593,8 @@ msgstr "Neue E-Mailadresse hinzufügen"
 #: templates/managemails/mailaddress_create.html:8
 #: templates/managemails/mailaddress_create.html:18
 #, python-format
-msgid ""
-"\n"
-"Add new Mail Address for Customer %(full_name)s\n"
-msgstr ""
-"\n"
-"Neue E-Mailadresse für Kunde %(full_name)s hinzufügen\n"
+msgid "Add new Mail Address for Customer %(full_name)s"
+msgstr "Neue E-Mailadresse für Kunde %(full_name)s hinzufügen"
 
 #: templates/managemails/mailaddress_edit.html:6
 #: templates/managemails/mailaddress_edit.html:16
@@ -989,51 +604,47 @@ msgstr "E-Mailadressziel ändern"
 #: templates/managemails/mailaddress_edit.html:8
 #: templates/managemails/mailaddress_edit.html:18
 #, python-format
-msgid ""
-"\n"
-"Change target of Mail Address for Customer %(full_name)s\n"
-msgstr ""
-"\n"
-"E-Mailadressziel der E-Mailadresse des Kunden %(full_name)s ändern\n"
+msgid "Change target of Mail Address for Customer %(full_name)s"
+msgstr "E-Mailadressziel der E-Mailadresse des Kunden %(full_name)s ändern"
 
 #: templates/managemails/mailbox_create.html:6
-#: templates/managemails/mailbox_create.html:15
+#: templates/managemails/mailbox_create.html:17
 #, python-format
 msgid "Add Mailbox to Hosting Package %(package)s"
 msgstr "Postfach zum Hostingpaket %(package)s hinzufügen"
 
 #: templates/managemails/mailbox_create.html:8
-#: templates/managemails/mailbox_create.html:17
+#: templates/managemails/mailbox_create.html:19
 #, python-format
 msgid "Add Mailbox to Hosting Package %(package)s of Customer %(full_name)s"
 msgstr ""
 "Postfach zum Hostingpaket %(package)s des Kunden %(full_name)s hinzufügen"
 
-#: templates/managemails/mailbox_create.html:23
+#: templates/managemails/mailbox_create.html:28
 msgid "Please specify the password for your new mailbox."
 msgstr "Bitte geben Sie das Passwort für Ihr neues Postfach ein."
 
-#: templates/managemails/mailbox_create.html:23
+#: templates/managemails/mailbox_create.html:30
 msgid "Please specify the password for the new mailbox."
 msgstr "Bitte geben Sie das Passwort für das neue Postfach ein."
 
 #: templates/managemails/mailbox_setpassword.html:6
-#: templates/managemails/mailbox_setpassword.html:15
+#: templates/managemails/mailbox_setpassword.html:17
 #, python-format
 msgid "Set Password for Mailbox %(mailbox)s"
 msgstr "Passwort für Postfach %(mailbox)s setzen"
 
 #: templates/managemails/mailbox_setpassword.html:8
-#: templates/managemails/mailbox_setpassword.html:17
+#: templates/managemails/mailbox_setpassword.html:19
 #, python-format
 msgid "Set Password for Mailbox %(mailbox)s of Customer %(full_name)s"
 msgstr "Passwort für Postfach %(mailbox)s des Kunden %(full_name)s setzen"
 
-#: templates/managemails/mailbox_setpassword.html:23
+#: templates/managemails/mailbox_setpassword.html:27
 msgid "Please specify the new password for your mailbox."
 msgstr "Bitte geben Sie das neue Passwort für Ihr Postfach ein."
 
-#: templates/managemails/mailbox_setpassword.html:23
+#: templates/managemails/mailbox_setpassword.html:28
 msgid "Please specify the new password for the mailbox."
 msgstr "Bitte geben Sie das neue Passwort für das Postfach ein."
 
@@ -1051,14 +662,14 @@ msgstr ""
 "SSH-Schlüssel des Betriebssystemnutzers %(osuser)s des Kunden %(full_name)s "
 "löschen"
 
-#: templates/osusers/sshpublickey_confirm_delete.html:14
+#: templates/osusers/sshpublickey_confirm_delete.html:16
 #, python-format
 msgid ""
 "Delete SSH Public Key for Operating System User %(osuser)s "
 msgstr ""
 "SSH-Schlüssel löschen für Betriebssystemnutzer %(osuser)s "
 
-#: templates/osusers/sshpublickey_confirm_delete.html:16
+#: templates/osusers/sshpublickey_confirm_delete.html:20
 #, python-format
 msgid ""
 "Delete SSH Public Key for Operating System User %(osuser)s of "
@@ -1067,12 +678,12 @@ msgstr ""
 "SSH-Schlüssel löschen von Betriebssystemnutzer %(osuser)s des Kunden "
 "%(full_name)s "
 
-#: templates/osusers/sshpublickey_confirm_delete.html:23
+#: templates/osusers/sshpublickey_confirm_delete.html:29
 #, python-format
 msgid "Do you really want to delete the %(algorithm)s SSH public key?"
 msgstr "Wollen Sie den %(algorithm)s-SSH-Schlüssel wirklich löschen?"
 
-#: templates/osusers/sshpublickey_confirm_delete.html:26
+#: templates/osusers/sshpublickey_confirm_delete.html:34
 msgid ""
 "When you confirm the deletion of this key you will no longer be able to use "
 "the corresponding private key for authentication."
@@ -1081,7 +692,7 @@ msgstr ""
 "dazugehörigen privaten Schlüssel nicht weiter für die Anmeldung verwenden "
 "können."
 
-#: templates/osusers/sshpublickey_confirm_delete.html:31
+#: templates/osusers/sshpublickey_confirm_delete.html:43
 msgid "Cancel and go back to the SSH key list"
 msgstr "Abbrechen und zurückgehen zur Liste der SSH-Schlüssel"
 
@@ -1090,7 +701,7 @@ msgstr "Abbrechen und zurückgehen zur Liste der SSH-Schlüssel"
 msgid "Add new SSH Public Key for Operating System User %(osuser)s"
 msgstr "Neuen SSH-Schlüssel für Betriebssystemnutzer %(osuser)s hinterlegen"
 
-#: templates/osusers/sshpublickey_create.html:8
+#: templates/osusers/sshpublickey_create.html:10
 #, python-format
 msgid ""
 "Add a new SSH Public Key for Operating System User %(osuser)s of Customer "
@@ -1099,7 +710,7 @@ msgstr ""
 "Neuen SSH-Schlüssel für Betriebssystemnutzer %(osuser)s des Kunden "
 "%(full_name)s hinterlegen"
 
-#: templates/osusers/sshpublickey_create.html:14
+#: templates/osusers/sshpublickey_create.html:18
 #, python-format
 msgid ""
 "Add new SSH Public Key for Operating System User %(osuser)s "
@@ -1107,7 +718,7 @@ msgstr ""
 "Neuen SSH-Schlüssel hinterlegen für Betriebssystemnutzer %(osuser)s"
 "small>"
 
-#: templates/osusers/sshpublickey_create.html:16
+#: templates/osusers/sshpublickey_create.html:22
 #, python-format
 msgid ""
 "Add a new SSH Public Key for Operating System User %(osuser)s of "
@@ -1131,7 +742,7 @@ msgstr ""
 "Kommentar des SSH-Schlüssels des Betriebssystemnutzers %(osuser)s des Kunden "
 "%(full_name)s ändern"
 
-#: templates/osusers/sshpublickey_edit_comment.html:14
+#: templates/osusers/sshpublickey_edit_comment.html:16
 #, python-format
 msgid ""
 "Edit Comment of Public Key for Operating System User %(osuser)s"
@@ -1140,7 +751,7 @@ msgstr ""
 "Kommentar eines SSH-Schlüssels ändern für Betriebssystemnutzer "
 "%(osuser)s "
 
-#: templates/osusers/sshpublickey_edit_comment.html:16
+#: templates/osusers/sshpublickey_edit_comment.html:20
 #, python-format
 msgid ""
 "Edit Comment of SSH Public Key for Operating System User %(osuser)s "
@@ -1162,12 +773,12 @@ msgid ""
 msgstr ""
 "SSH-Schlüssel des Betriebssystemnutzers %(osuser)s des Kunden %(full_name)s"
 
-#: templates/osusers/sshpublickey_list.html:14
+#: templates/osusers/sshpublickey_list.html:16
 #, python-format
 msgid "SSH Public Keys for Operating System User %(osuser)s "
 msgstr "SSH-Schlüssel für Betriebssystemnutzer %(osuser)s "
 
-#: templates/osusers/sshpublickey_list.html:16
+#: templates/osusers/sshpublickey_list.html:20
 #, python-format
 msgid ""
 "SSH Public Keys for Operating System User %(osuser)s of Customer "
@@ -1176,50 +787,57 @@ msgstr ""
 "SSH-Schlüssel des Betriebssystemnutzers %(osuser)s des Kunden "
 "%(full_name)s "
 
-#: templates/osusers/sshpublickey_list.html:25
+#: templates/osusers/sshpublickey_list.html:31
 msgid "Algorithm"
 msgstr "Algorithmus"
 
-#: templates/osusers/sshpublickey_list.html:26
+#: templates/osusers/sshpublickey_list.html:32
 msgid "Comment"
 msgstr "Kommentar"
 
-#: templates/osusers/sshpublickey_list.html:27
+#: templates/osusers/sshpublickey_list.html:33
 msgid "SSH public key actions"
 msgstr "Aktionen für SSH-Schlüssel"
 
-#: templates/osusers/sshpublickey_list.html:36
+#: templates/osusers/sshpublickey_list.html:34
+msgid "Actions"
+msgstr "Aktionen"
+
+#: templates/osusers/sshpublickey_list.html:44
 msgid "Delete this SSH public key"
 msgstr "Diesen SSH-Schlüssel löschen"
 
-#: templates/osusers/sshpublickey_list.html:36
+#: templates/osusers/sshpublickey_list.html:46
 msgid "Delete"
 msgstr "Löschen"
 
-#: templates/osusers/sshpublickey_list.html:37
+#: templates/osusers/sshpublickey_list.html:48
 msgid "Edit this SSH public key's comment"
 msgstr "Den Kommentar dieses SSH-Schlüssels ändern"
 
-#: templates/osusers/sshpublickey_list.html:37
+#: templates/osusers/sshpublickey_list.html:50
 msgid "Edit Comment"
 msgstr "Kommentar ändern"
 
-#: templates/osusers/sshpublickey_list.html:44
+#: templates/osusers/sshpublickey_list.html:57
 msgid "There are now SSH public keys set for this operating system user yet."
 msgstr "Diesem Betriebssytemnutzer wurden noch keine SSH-Schlüssel zugeordnet."
 
+#: templates/osusers/sshpublickey_list.html:60
+msgid "Add SSH public key"
+msgstr "SSH-Schlüssel hinzufügen"
+
 #: templates/osusers/user_setpassword.html:5
-#: templates/osusers/user_setpassword.html:13
+#: templates/osusers/user_setpassword.html:15
 #, python-format
 msgid "Set new password for user %(osuser)s"
 msgstr "Neues Passwort für Benutzer %(osuser)s setzen"
 
 #: templates/osusers/user_setpassword.html:7
-#: templates/osusers/user_setpassword.html:15
+#: templates/osusers/user_setpassword.html:17
 #, python-format
 msgid "Set new password for user %(osuser)s of customer %(full_name)s"
-msgstr ""
-"Neues Passwort für Benutzer %(osuser)s des Kunden %(full_name)s setzen."
+msgstr "Neues Passwort für Benutzer %(osuser)s des Kunden %(full_name)s setzen"
 
 #: templates/registration/login.html:3 templates/registration/login.html:10
 msgid "Sign in"
@@ -1247,32 +865,63 @@ msgid ""
 "You can sign in to your account using any of the following third party "
 "accounts:"
 msgstr ""
-"Sie können Sich mit Ihrem Konto bei einem der folgenden Drittanbieter "
-"anmelden:"
+"You can sign in to your account using any of the following third party "
+"accounts:"
 
-#: templates/socialaccount/connections.html:18
+#: templates/socialaccount/connections.html:21
 msgid "Select"
 msgstr "Auswählen"
 
-#: templates/socialaccount/connections.html:19
+#: templates/socialaccount/connections.html:22
 msgid "Provider"
 msgstr "Anbieter"
 
-#: templates/socialaccount/connections.html:20
+#: templates/socialaccount/connections.html:23
 msgid "Account name"
 msgstr "Kontoname"
 
-#: templates/socialaccount/connections.html:39
+#: templates/socialaccount/connections.html:45
 msgid ""
 "You currently have no social network accounts connected to this account."
 msgstr ""
 "Bisher sind noch keine Konten aus sozialen Netzwerken mit diesem "
 "Benutzerkonto verknüpft."
 
-#: templates/socialaccount/connections.html:42
+#: templates/socialaccount/connections.html:48
 msgid "Add a 3rd Party Account"
 msgstr "Drittanbieterkonto hinzufügen"
 
+#: templates/socialaccount/login.html:5
+msgid "Social Network Sign In"
+msgstr "Anmeldung über ein soziales Netzwerk"
+
+#: templates/socialaccount/login.html:9
+#, python-format
+msgid "Connect %(provider)s"
+msgstr "Verbinde %(provider)s"
+
+#: templates/socialaccount/login.html:11
+#, python-format
+msgid "You are about to connect a new third party account from %(provider)s."
+msgstr ""
+"Sie sind dabei Ihr Benutzerkonto mit einem Benutzerkonto bei %(provider)s zu "
+"verbinden."
+
+#: templates/socialaccount/login.html:13
+#, python-format
+msgid "Sign In Via %(provider)s"
+msgstr "Anmelden mit %(provider)s"
+
+#: templates/socialaccount/login.html:15
+#, python-format
+msgid "You are about to sign in using a third party account from %(provider)s."
+msgstr ""
+"Sie sind dabei sich mit einem Benutzerkonto von %(provider)s anzumelden."
+
+#: templates/socialaccount/login.html:20
+msgid "Continue"
+msgstr "Fortsetzen"
+
 #: templates/socialaccount/login_cancelled.html:4
 #: templates/socialaccount/login_cancelled.html:5
 msgid "Login Cancelled"
@@ -1282,8 +931,8 @@ msgstr "Anmeldung abgebrochen"
 #, python-format
 msgid ""
 "You decided to cancel logging in to our site using one of your existing "
-"accounts. If this was a mistake, please proceed to sign in ."
+"accounts. If this was a mistake, please proceed to sign in ."
 msgstr ""
 "Sie haben sich entschieden Ihre Anmeldung auf unserem Angebot mit einem "
 "Ihrer bereits bestehenden Konten abzubrechen. Wenn dies ein Versehen war, "
@@ -1305,10 +954,10 @@ msgstr "Die Verknüpfung zum Drittanbieterkonto wurde entfernt."
 #: templates/socialaccount/signup.html:8
 #, python-format
 msgid ""
-"You are about to use your %(provider_name)s account to login to\n"
+"You are about to use your %(provider_name)s account to login to "
 "%(site_name)s. As a final step, please complete the following form:"
 msgstr ""
-"Sie sind im Begriff Ihr %(provider_name)s-Konto zur Anmeldung bei\n"
+"Sie sind im Begriff Ihr %(provider_name)s-Konto zur Anmeldung bei "
 "%(site_name)s zu nutzen. Als letzten Schritt füllen Sie bitte folgendes "
 "Formular aus:"
 
@@ -1321,14 +970,14 @@ msgstr "Neues Datenbanknutzerpasswort für %(dbuser)s setzen"
 #, python-format
 msgid "Set Database User Password for %(dbuser)s of Customer %(full_name)s"
 msgstr ""
-"Neues Datenbanknutzerpasswort für %(dbuser)s des Kunden %(full_name)s setzen."
+"Neues Datenbanknutzerpasswort für %(dbuser)s des Kunden %(full_name)s setzen"
 
-#: templates/userdbs/databaseuser_setpassword.html:14
+#: templates/userdbs/databaseuser_setpassword.html:16
 #, python-format
 msgid "Set Database User Password for %(dbuser)s "
 msgstr "Datenbanknutzerpasswort setzen für %(dbuser)s "
 
-#: templates/userdbs/databaseuser_setpassword.html:16
+#: templates/userdbs/databaseuser_setpassword.html:20
 #, python-format
 msgid ""
 "Set Database User Password for %(dbuser)s of Customer %(full_name)s"
@@ -1337,11 +986,11 @@ msgstr ""
 "Neues Datenbanknutzerpasswort setzen für %(dbuser)s des Kunden "
 "%(full_name)s "
 
-#: templates/userdbs/databaseuser_setpassword.html:21
+#: templates/userdbs/databaseuser_setpassword.html:28
 msgid "Please specify the new password for your database user."
 msgstr "Bitte geben Sie das neue Passwort für Ihren Datenbanknutzer ein."
 
-#: templates/userdbs/databaseuser_setpassword.html:21
+#: templates/userdbs/databaseuser_setpassword.html:30
 msgid "Please specify the new password of the database user."
 msgstr "Bitte geben Sie das neue Passwort für den Datenbanknutzer ein."
 
@@ -1355,22 +1004,22 @@ msgstr "Datenbank %(database)s löschen"
 msgid "Delete Database %(database)s of customer %(full_name)s"
 msgstr "Datenbank %(database)s des Kunden %(full_name)s löschen"
 
-#: templates/userdbs/userdatabase_confirm_delete.html:14
+#: templates/userdbs/userdatabase_confirm_delete.html:16
 #, python-format
 msgid "Delete Database %(database)s "
 msgstr "Datenbank löschen %(database)s "
 
-#: templates/userdbs/userdatabase_confirm_delete.html:16
+#: templates/userdbs/userdatabase_confirm_delete.html:20
 #, python-format
 msgid "Delete Database %(database)s of customer %(full_name)s "
 msgstr "Datenbank löschen %(database)s des Kunden %(full_name)s "
 
-#: templates/userdbs/userdatabase_confirm_delete.html:23
+#: templates/userdbs/userdatabase_confirm_delete.html:29
 #, python-format
 msgid "Do you really want to delete the database %(database)s?"
 msgstr "Wollen Sie die Datenbank %(database)s wirklich löschen?"
 
-#: templates/userdbs/userdatabase_confirm_delete.html:26
+#: templates/userdbs/userdatabase_confirm_delete.html:34
 msgid ""
 "When you confirm the deletion the database will be removed from the database "
 "server. All data in the database will be lost!  If the "
@@ -1383,17 +1032,17 @@ msgstr ""
 "zugeordnet sind, wird er ebenfalls gelöscht."
 
 #: templates/userdbs/userdatabase_create.html:6
-#: templates/userdbs/userdatabase_create.html:14
+#: templates/userdbs/userdatabase_create.html:16
 msgid "Add new Database"
 msgstr "Neue Datenbank hinzufügen"
 
 #: templates/userdbs/userdatabase_create.html:8
-#: templates/userdbs/userdatabase_create.html:16
+#: templates/userdbs/userdatabase_create.html:18
 #, python-format
 msgid "Add new Database for Customer %(full_name)s"
 msgstr "Neue Datenbank für Kunde %(full_name)s anlegen"
 
-#: templates/userdbs/userdatabase_create.html:21
+#: templates/userdbs/userdatabase_create.html:25
 msgid "Please enter a password for a new database user for your database."
 msgstr ""
 "Bitte geben Sie ein Passwort für den neuen Datenbanknutzer für Ihre "
@@ -1409,23 +1058,23 @@ msgstr "Webauftritt %(website)s löschen"
 msgid "Delete Website %(website)s of Customer %(full_name)s"
 msgstr "Webauftritt %(website)s des Kunden %(full_name)s löschen"
 
-#: templates/websites/website_confirm_delete.html:14
+#: templates/websites/website_confirm_delete.html:16
 #, python-format
 msgid "Delete Website %(website)s "
 msgstr "Webauftritt löschen %(website)s "
 
-#: templates/websites/website_confirm_delete.html:16
+#: templates/websites/website_confirm_delete.html:18
 #, python-format
 msgid "Delete Website %(website)s of Customer %(full_name)s "
 msgstr ""
 "Webauftritt löschen %(website)s des Kunden %(full_name)s "
 
-#: templates/websites/website_confirm_delete.html:23
+#: templates/websites/website_confirm_delete.html:27
 #, python-format
 msgid "Do you really want to delete the website %(website)s?"
 msgstr "Wollen Sie den Webauftritt %(website)s wirklich löschen?"
 
-#: templates/websites/website_confirm_delete.html:26
+#: templates/websites/website_confirm_delete.html:30
 msgid ""
 "Please be aware that the website directory is removed from the webserver and "
 "the webserver configuration is changed so that the website will not be "
@@ -1450,12 +1099,12 @@ msgstr ""
 "Webauftritt für Subdomain der Domain %(domain)s des Kunden %(full_name)s "
 "anlegen"
 
-#: templates/websites/website_create.html:14
+#: templates/websites/website_create.html:16
 #, python-format
 msgid "Add Website for Subdomain of %(domain)s "
 msgstr "Website anlegen für Subdomain von %(domain)s "
 
-#: templates/websites/website_create.html:16
+#: templates/websites/website_create.html:20
 #, python-format
 msgid ""
 "Add Website for Subdomain of Domain %(domain)s of Customer "
@@ -1463,11 +1112,3 @@ msgid ""
 msgstr ""
 "Webauftritt anlegen für Subdomain der Domain %(domain)s des Kunden "
 "%(full_name)s "
-
-#, fuzzy
-#~| msgid "Password Reset"
-#~ msgid "Password (again)"
-#~ msgstr "Passwort zurücksetzen"
-
-#~ msgid "My Profile"
-#~ msgstr "Mein Profil"
diff --git a/gnuviechadmin/managemails/locale/de/LC_MESSAGES/django.po b/gnuviechadmin/managemails/locale/de/LC_MESSAGES/django.po
index 6e53cbc..9988858 100644
--- a/gnuviechadmin/managemails/locale/de/LC_MESSAGES/django.po
+++ b/gnuviechadmin/managemails/locale/de/LC_MESSAGES/django.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: managemails\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-29 11:04+0100\n"
-"PO-Revision-Date: 2015-01-25 22:17+0100\n"
+"POT-Creation-Date: 2023-04-16 22:07+0200\n"
+"PO-Revision-Date: 2023-04-16 18:21+0200\n"
 "Last-Translator: Jan Dittberner \n"
 "Language-Team: Jan Dittberner \n"
 "Language: de\n"
@@ -16,30 +16,30 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 1.6.10\n"
+"X-Generator: Poedit 3.2.2\n"
 "X-Poedit-SourceCharset: UTF-8\n"
 
-#: managemails/admin.py:14
+#: managemails/admin.py:9
 msgid "Passwords don't match"
 msgstr "Passwörter stimmen nicht überein"
 
-#: managemails/admin.py:21 managemails/tests/test_admin.py:40
+#: managemails/admin.py:15 managemails/tests/test_admin.py:35
 msgid "Hash"
 msgstr "Hash-Code"
 
-#: managemails/admin.py:44
+#: managemails/admin.py:39
 msgid "Password"
 msgstr "Passwort"
 
-#: managemails/admin.py:46
+#: managemails/admin.py:40
 msgid "Password (again)"
 msgstr "Passwortwiederholung"
 
-#: managemails/admin.py:100
+#: managemails/admin.py:93
 msgid "Activate"
 msgstr "Aktivieren"
 
-#: managemails/admin.py:101
+#: managemails/admin.py:94
 msgid "Deactivate"
 msgstr "Deaktivieren"
 
@@ -47,32 +47,32 @@ msgstr "Deaktivieren"
 msgid "Mailboxes and Mail Addresses"
 msgstr "Postfächer und E-Mailadressen"
 
-#: managemails/forms.py:29 managemails/forms.py:120 managemails/models.py:120
+#: managemails/forms.py:21 managemails/forms.py:118 managemails/models.py:113
 msgid "Mailbox"
 msgstr "Postfach"
 
-#: managemails/forms.py:30 managemails/forms.py:125
+#: managemails/forms.py:22 managemails/forms.py:123
 msgid "Forwards"
 msgstr "Weiterleitungen"
 
-#: managemails/forms.py:49
+#: managemails/forms.py:43
 msgid "Create mailbox"
 msgstr "Postfach anlegen"
 
-#: managemails/forms.py:85
+#: managemails/forms.py:82
 msgid "Set password"
 msgstr "Passwort setzen"
 
-#: managemails/forms.py:113
+#: managemails/forms.py:111
 msgid "Mailbox or Forwards"
 msgstr "Postfach oder Weiterleitungen"
 
-#: managemails/forms.py:129
+#: managemails/forms.py:127
 msgid "Please enter one or more email addresses separated by commas."
 msgstr ""
 "Bitte geben Sie eine oder mehrere durch Kommata getrennte E-Mailadressen ein."
 
-#: managemails/forms.py:176
+#: managemails/forms.py:177
 msgid "Add mail address"
 msgstr "E-Mailadresse hinzufügen"
 
@@ -80,60 +80,60 @@ msgstr "E-Mailadresse hinzufügen"
 msgid "This mail address is already in use."
 msgstr "Diese E-Mailadresse wird bereits verwendet."
 
-#: managemails/forms.py:195 managemails/forms.py:277
+#: managemails/forms.py:195 managemails/forms.py:281
 msgid "No mailbox selected"
 msgstr "Kein Postfach ausgewählt"
 
-#: managemails/forms.py:198 managemails/forms.py:280
+#: managemails/forms.py:198 managemails/forms.py:284
 msgid "No forward addresses selected"
 msgstr "Keine Weiterleitungsadressen ausgewählt"
 
-#: managemails/forms.py:202 managemails/forms.py:284
+#: managemails/forms.py:202 managemails/forms.py:288
 msgid "Illegal choice for target of the mail address"
 msgstr "Ungültige Auswahl für das Ziel der E-Mailadresse"
 
-#: managemails/forms.py:270
+#: managemails/forms.py:274
 msgid "Change mail address targets"
 msgstr "E-Mailadressziele ändern"
 
-#: managemails/models.py:121
+#: managemails/models.py:114
 msgid "Mailboxes"
 msgstr "Postfächer"
 
-#: managemails/models.py:164
+#: managemails/models.py:145
 msgid "local part"
 msgstr "Lokaler Teil"
 
-#: managemails/models.py:165
+#: managemails/models.py:147
 msgid "domain"
 msgstr "Domain"
 
-#: managemails/models.py:170
+#: managemails/models.py:153
 msgid "Mail address"
 msgstr "E-Mailadresse"
 
-#: managemails/models.py:171
+#: managemails/models.py:154
 msgid "Mail addresses"
 msgstr "E-Mailadressen"
 
-#: managemails/models.py:253
+#: managemails/models.py:236
 msgid "mailaddress"
 msgstr "E-Mailadresse"
 
-#: managemails/models.py:254
+#: managemails/models.py:241
 msgid "mailbox"
 msgstr "Postfach"
 
-#: managemails/views.py:52
+#: managemails/views.py:46
 msgid "You are not allowed to add more mailboxes to this hosting package"
 msgstr "Sie können keine weiteren Postfächer zu diesem Hostingpaket hinzufügen"
 
-#: managemails/views.py:71
+#: managemails/views.py:67
 #, python-brace-format
 msgid "Mailbox {mailbox} created successfully."
 msgstr "Postfach {mailbox} erfolgreich angelegt."
 
-#: managemails/views.py:106
+#: managemails/views.py:103
 #, python-brace-format
 msgid "Successfully set new password for mailbox {mailbox}."
 msgstr ""
@@ -144,7 +144,7 @@ msgstr ""
 msgid "Successfully added mail address {mailaddress}"
 msgstr "E-Mailadresse {mailaddress} erfolgreich hinzugefügt"
 
-#: managemails/views.py:223
+#: managemails/views.py:230
 #, python-brace-format
 msgid "Successfully updated mail address {mailaddress} targets."
 msgstr "Ziele der E-Mailadresse {mailaddress} erfolgreich aktualisiert."
diff --git a/gnuviechadmin/osusers/locale/de/LC_MESSAGES/django.po b/gnuviechadmin/osusers/locale/de/LC_MESSAGES/django.po
index 81dba23..ffd0efd 100644
--- a/gnuviechadmin/osusers/locale/de/LC_MESSAGES/django.po
+++ b/gnuviechadmin/osusers/locale/de/LC_MESSAGES/django.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: osusers\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-29 11:04+0100\n"
-"PO-Revision-Date: 2016-01-29 11:07+0100\n"
+"POT-Creation-Date: 2023-04-16 22:07+0200\n"
+"PO-Revision-Date: 2023-04-16 18:21+0200\n"
 "Last-Translator: Jan Dittberner \n"
 "Language-Team: Jan Dittberner \n"
 "Language: de\n"
@@ -16,144 +16,144 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 1.8.6\n"
+"X-Generator: Poedit 3.2.2\n"
 "X-Poedit-SourceCharset: UTF-8\n"
 
-#: osusers/admin.py:53
+#: osusers/admin.py:49
 msgid "Password"
 msgstr "Passwort"
 
-#: osusers/admin.py:57
+#: osusers/admin.py:52
 msgid "Password (again)"
 msgstr "Passwortwiederholung"
 
-#: osusers/admin.py:166
+#: osusers/admin.py:167
 msgid "Delete selected users"
 msgstr "Ausgewählte Nutzer löschen"
 
-#: osusers/admin.py:207
+#: osusers/admin.py:210
 msgid "Delete selected groups"
 msgstr "Ausgewählte Gruppen löschen"
 
-#: osusers/admin.py:234 osusers/forms.py:62
+#: osusers/admin.py:238 osusers/forms.py:60
 msgid "Key text"
 msgstr "Schlüsseltext"
 
-#: osusers/admin.py:235 osusers/forms.py:63
+#: osusers/admin.py:240 osusers/forms.py:62
 msgid "A SSH public key in either OpenSSH or RFC 4716 format"
 msgstr ""
 "Öffentlicher Teil eines SSH-Schlüssels entweder im OpenSSH- oder im RFC-4716-"
 "Format"
 
-#: osusers/admin.py:361
+#: osusers/admin.py:389
 msgid "Delete selected SSH public keys"
 msgstr "Ausgewählte SSH-Schlüssel löschen"
 
-#: osusers/apps.py:18
+#: osusers/apps.py:17
 msgid "Operating System Users and Groups"
 msgstr "Betriebssystemnutzer- und Gruppen"
 
-#: osusers/forms.py:21
+#: osusers/forms.py:15
 msgid "Invalid SSH public key data format."
 msgstr "Ungültiges Format für den öffentlichen Teil eines SSH-Schlüssels."
 
-#: osusers/forms.py:23
+#: osusers/forms.py:17
 msgid "This SSH public key is already assigned to this user."
 msgstr "Dieser SSH-Schlüssel wurde diesem Nutzer bereits zugeordnet."
 
-#: osusers/forms.py:40
+#: osusers/forms.py:37
 msgid "Set password"
 msgstr "Passwort setzen"
 
-#: osusers/forms.py:76
+#: osusers/forms.py:77
 msgid "Add SSH public key"
 msgstr "SSH-Schlüssel hinzufügen"
 
-#: osusers/forms.py:135
+#: osusers/forms.py:139
 msgid "Change Comment"
 msgstr "Kommentar ändern"
 
-#: osusers/models.py:34
+#: osusers/models.py:26
 msgid "You can not use a user's primary group."
 msgstr "Sie können nicht die primäre Gruppe des Nutzers verwenden."
 
-#: osusers/models.py:64
+#: osusers/models.py:55
 msgid "Group name"
 msgstr "Gruppenname"
 
-#: osusers/models.py:66
+#: osusers/models.py:56
 msgid "Group ID"
 msgstr "Gruppen-ID"
 
-#: osusers/models.py:67
+#: osusers/models.py:57
 msgid "Description"
 msgstr "Beschreibung"
 
-#: osusers/models.py:69
+#: osusers/models.py:58
 msgid "Group password"
 msgstr "Gruppenpasswort"
 
-#: osusers/models.py:74 osusers/models.py:201
+#: osusers/models.py:63 osusers/models.py:190
 msgid "Group"
 msgstr "Gruppe"
 
-#: osusers/models.py:75
+#: osusers/models.py:64
 msgid "Groups"
 msgstr "Gruppen"
 
-#: osusers/models.py:198
+#: osusers/models.py:188
 msgid "User name"
 msgstr "Nutzername"
 
-#: osusers/models.py:200
+#: osusers/models.py:189
 msgid "User ID"
 msgstr "Nutzer-ID"
 
-#: osusers/models.py:202
+#: osusers/models.py:191
 msgid "Gecos field"
 msgstr "GECOS-Feld"
 
-#: osusers/models.py:203
+#: osusers/models.py:192
 msgid "Home directory"
 msgstr "Home-Verzeichnis"
 
-#: osusers/models.py:204
+#: osusers/models.py:193
 msgid "Login shell"
 msgstr "Loginshell"
 
-#: osusers/models.py:210 osusers/models.py:310 osusers/models.py:501
+#: osusers/models.py:199 osusers/models.py:303 osusers/models.py:513
 msgid "User"
 msgstr "Nutzer"
 
-#: osusers/models.py:211
+#: osusers/models.py:200
 msgid "Users"
 msgstr "Nutzer"
 
-#: osusers/models.py:311
+#: osusers/models.py:305
 msgid "Encrypted password"
 msgstr "Verschlüsseltes Passwort"
 
-#: osusers/models.py:313
+#: osusers/models.py:307
 msgid "Date of last change"
 msgstr "Datum der letzten Änderung"
 
-#: osusers/models.py:314
+#: osusers/models.py:308
 msgid "This is expressed in days since Jan 1, 1970"
 msgstr "Ausgedrückt als Tage seit dem 1. Januar 1970"
 
-#: osusers/models.py:317
+#: osusers/models.py:313
 msgid "Minimum age"
 msgstr "Minimales Alter"
 
-#: osusers/models.py:318
+#: osusers/models.py:314
 msgid "Minimum number of days before the password can be changed"
 msgstr "Minmale Anzahl von Tagen bevor das Passwort geändert werden kann"
 
-#: osusers/models.py:322
+#: osusers/models.py:319
 msgid "Maximum age"
 msgstr "Maximales Alter"
 
-#: osusers/models.py:323
+#: osusers/models.py:321
 msgid "Maximum number of days after which the password has to be changed"
 msgstr ""
 "Maximale Anzahl von Tagen, nach denen das Passwort geändert werden muss"
@@ -166,11 +166,11 @@ msgstr "Duldungsperiode"
 msgid "The number of days before the password is going to expire"
 msgstr "Anzahl von Tagen nach denen das Passwort verfällt"
 
-#: osusers/models.py:332
+#: osusers/models.py:333
 msgid "Inactivity period"
 msgstr "Inaktivitätsperiode"
 
-#: osusers/models.py:333
+#: osusers/models.py:335
 msgid ""
 "The number of days after the password has expired during which the password "
 "should still be accepted"
@@ -178,65 +178,62 @@ msgstr ""
 "Die Anzahl von Tagen für die ein verfallenes Passwort noch akzeptiert werden "
 "soll"
 
-#: osusers/models.py:337
+#: osusers/models.py:342
 msgid "Account expiration date"
 msgstr "Kontoverfallsdatum"
 
-#: osusers/models.py:338
+#: osusers/models.py:344
 msgid ""
 "The date of expiration of the account, expressed as number of days since Jan "
 "1, 1970"
 msgstr "Kontoverfallsdatum in Tagen seit dem 1. Januar 1970"
 
-#: osusers/models.py:345
+#: osusers/models.py:355
 msgid "Shadow password"
 msgstr "Shadow-Passwort"
 
-#: osusers/models.py:346
+#: osusers/models.py:356
 msgid "Shadow passwords"
 msgstr "Shadow-Passwörter"
 
-#: osusers/models.py:372
+#: osusers/models.py:382
 msgid "Additional group"
 msgstr "Weitere Gruppe"
 
-#: osusers/models.py:373
+#: osusers/models.py:383
 msgid "Additional groups"
 msgstr "Weitere Gruppen"
 
-#: osusers/models.py:502
+#: osusers/models.py:514
 msgid "Algorithm"
 msgstr "Algorithmus"
 
-#: osusers/models.py:503
+#: osusers/models.py:515
 msgid "Key bytes"
 msgstr "Schlüsselbytes"
 
-#: osusers/models.py:504
+#: osusers/models.py:515
 msgid "Base64 encoded key bytes"
 msgstr "Base64-kodierte Schlüsselbytes"
 
-#: osusers/models.py:505
+#: osusers/models.py:516
 msgid "Comment"
 msgstr "Kommentar"
 
-#: osusers/models.py:510
+#: osusers/models.py:521
 msgid "SSH public key"
 msgstr "Öffentlicher SSH-Schlüssel"
 
-#: osusers/models.py:511
+#: osusers/models.py:522
 msgid "SSH public keys"
 msgstr "Öffentliche SSH-Schlüssel"
 
-#: osusers/views.py:56
+#: osusers/views.py:48
 #, python-brace-format
 msgid "New password for {username} has been set successfully."
 msgstr "Für {username} wurde erfolgreich ein neues Passwort gesetzt."
 
-#: osusers/views.py:92
+#: osusers/views.py:88
 #, python-brace-format
 msgid "Successfully added new {algorithm} SSH public key."
 msgstr "Neuer {algorithm}-SSH-Schlüssel erfolgreich hinzugefügt."
-
-#~ msgid "Passwords don't match"
-#~ msgstr "Passwörter stimmen nicht überein"
diff --git a/gnuviechadmin/static/css/bootstrap-icons.css b/gnuviechadmin/static/css/bootstrap-icons.css
new file mode 100644
index 0000000..ace876c
--- /dev/null
+++ b/gnuviechadmin/static/css/bootstrap-icons.css
@@ -0,0 +1,5882 @@
+@charset "UTF-8";
+/*!
+ * Bootstrap Icons (https://icons.getbootstrap.com/)
+ * Copyright 2019-2023 The Bootstrap Authors
+ * Licensed under MIT (https://github.com/twbs/icons/blob/main/LICENSE.md)
+ */
+@font-face {
+  font-display: block;
+  font-family: "bootstrap-icons";
+  src: url("../fonts/bootstrap-icons.woff2?24e3eb84d0bcaf83d77f904c78ac1f47") format("woff2"), url("../fonts/bootstrap-icons.woff?24e3eb84d0bcaf83d77f904c78ac1f47") format("woff"); }
+.bi::before,
+[class^="bi-"]::before,
+[class*=" bi-"]::before {
+  display: inline-block;
+  font-family: "bootstrap-icons" !important;
+  font-style: normal;
+  font-weight: normal !important;
+  font-variant: normal;
+  text-transform: none;
+  line-height: 1;
+  vertical-align: -.125em;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale; }
+
+.bi-123::before {
+  content: ""; }
+
+.bi-alarm-fill::before {
+  content: ""; }
+
+.bi-alarm::before {
+  content: ""; }
+
+.bi-align-bottom::before {
+  content: ""; }
+
+.bi-align-center::before {
+  content: ""; }
+
+.bi-align-end::before {
+  content: ""; }
+
+.bi-align-middle::before {
+  content: ""; }
+
+.bi-align-start::before {
+  content: ""; }
+
+.bi-align-top::before {
+  content: ""; }
+
+.bi-alt::before {
+  content: ""; }
+
+.bi-app-indicator::before {
+  content: ""; }
+
+.bi-app::before {
+  content: ""; }
+
+.bi-archive-fill::before {
+  content: ""; }
+
+.bi-archive::before {
+  content: ""; }
+
+.bi-arrow-90deg-down::before {
+  content: ""; }
+
+.bi-arrow-90deg-left::before {
+  content: ""; }
+
+.bi-arrow-90deg-right::before {
+  content: ""; }
+
+.bi-arrow-90deg-up::before {
+  content: ""; }
+
+.bi-arrow-bar-down::before {
+  content: ""; }
+
+.bi-arrow-bar-left::before {
+  content: ""; }
+
+.bi-arrow-bar-right::before {
+  content: ""; }
+
+.bi-arrow-bar-up::before {
+  content: ""; }
+
+.bi-arrow-clockwise::before {
+  content: ""; }
+
+.bi-arrow-counterclockwise::before {
+  content: ""; }
+
+.bi-arrow-down-circle-fill::before {
+  content: ""; }
+
+.bi-arrow-down-circle::before {
+  content: ""; }
+
+.bi-arrow-down-left-circle-fill::before {
+  content: ""; }
+
+.bi-arrow-down-left-circle::before {
+  content: ""; }
+
+.bi-arrow-down-left-square-fill::before {
+  content: ""; }
+
+.bi-arrow-down-left-square::before {
+  content: ""; }
+
+.bi-arrow-down-left::before {
+  content: ""; }
+
+.bi-arrow-down-right-circle-fill::before {
+  content: ""; }
+
+.bi-arrow-down-right-circle::before {
+  content: ""; }
+
+.bi-arrow-down-right-square-fill::before {
+  content: ""; }
+
+.bi-arrow-down-right-square::before {
+  content: ""; }
+
+.bi-arrow-down-right::before {
+  content: ""; }
+
+.bi-arrow-down-short::before {
+  content: ""; }
+
+.bi-arrow-down-square-fill::before {
+  content: ""; }
+
+.bi-arrow-down-square::before {
+  content: ""; }
+
+.bi-arrow-down-up::before {
+  content: ""; }
+
+.bi-arrow-down::before {
+  content: ""; }
+
+.bi-arrow-left-circle-fill::before {
+  content: ""; }
+
+.bi-arrow-left-circle::before {
+  content: ""; }
+
+.bi-arrow-left-right::before {
+  content: ""; }
+
+.bi-arrow-left-short::before {
+  content: ""; }
+
+.bi-arrow-left-square-fill::before {
+  content: ""; }
+
+.bi-arrow-left-square::before {
+  content: ""; }
+
+.bi-arrow-left::before {
+  content: ""; }
+
+.bi-arrow-repeat::before {
+  content: ""; }
+
+.bi-arrow-return-left::before {
+  content: ""; }
+
+.bi-arrow-return-right::before {
+  content: ""; }
+
+.bi-arrow-right-circle-fill::before {
+  content: ""; }
+
+.bi-arrow-right-circle::before {
+  content: ""; }
+
+.bi-arrow-right-short::before {
+  content: ""; }
+
+.bi-arrow-right-square-fill::before {
+  content: ""; }
+
+.bi-arrow-right-square::before {
+  content: ""; }
+
+.bi-arrow-right::before {
+  content: ""; }
+
+.bi-arrow-up-circle-fill::before {
+  content: ""; }
+
+.bi-arrow-up-circle::before {
+  content: ""; }
+
+.bi-arrow-up-left-circle-fill::before {
+  content: ""; }
+
+.bi-arrow-up-left-circle::before {
+  content: ""; }
+
+.bi-arrow-up-left-square-fill::before {
+  content: ""; }
+
+.bi-arrow-up-left-square::before {
+  content: ""; }
+
+.bi-arrow-up-left::before {
+  content: ""; }
+
+.bi-arrow-up-right-circle-fill::before {
+  content: ""; }
+
+.bi-arrow-up-right-circle::before {
+  content: ""; }
+
+.bi-arrow-up-right-square-fill::before {
+  content: ""; }
+
+.bi-arrow-up-right-square::before {
+  content: ""; }
+
+.bi-arrow-up-right::before {
+  content: ""; }
+
+.bi-arrow-up-short::before {
+  content: ""; }
+
+.bi-arrow-up-square-fill::before {
+  content: ""; }
+
+.bi-arrow-up-square::before {
+  content: ""; }
+
+.bi-arrow-up::before {
+  content: ""; }
+
+.bi-arrows-angle-contract::before {
+  content: ""; }
+
+.bi-arrows-angle-expand::before {
+  content: ""; }
+
+.bi-arrows-collapse::before {
+  content: ""; }
+
+.bi-arrows-expand::before {
+  content: ""; }
+
+.bi-arrows-fullscreen::before {
+  content: ""; }
+
+.bi-arrows-move::before {
+  content: ""; }
+
+.bi-aspect-ratio-fill::before {
+  content: ""; }
+
+.bi-aspect-ratio::before {
+  content: ""; }
+
+.bi-asterisk::before {
+  content: ""; }
+
+.bi-at::before {
+  content: ""; }
+
+.bi-award-fill::before {
+  content: ""; }
+
+.bi-award::before {
+  content: ""; }
+
+.bi-back::before {
+  content: ""; }
+
+.bi-backspace-fill::before {
+  content: ""; }
+
+.bi-backspace-reverse-fill::before {
+  content: ""; }
+
+.bi-backspace-reverse::before {
+  content: ""; }
+
+.bi-backspace::before {
+  content: ""; }
+
+.bi-badge-3d-fill::before {
+  content: ""; }
+
+.bi-badge-3d::before {
+  content: ""; }
+
+.bi-badge-4k-fill::before {
+  content: ""; }
+
+.bi-badge-4k::before {
+  content: ""; }
+
+.bi-badge-8k-fill::before {
+  content: ""; }
+
+.bi-badge-8k::before {
+  content: ""; }
+
+.bi-badge-ad-fill::before {
+  content: ""; }
+
+.bi-badge-ad::before {
+  content: ""; }
+
+.bi-badge-ar-fill::before {
+  content: ""; }
+
+.bi-badge-ar::before {
+  content: ""; }
+
+.bi-badge-cc-fill::before {
+  content: ""; }
+
+.bi-badge-cc::before {
+  content: ""; }
+
+.bi-badge-hd-fill::before {
+  content: ""; }
+
+.bi-badge-hd::before {
+  content: ""; }
+
+.bi-badge-tm-fill::before {
+  content: ""; }
+
+.bi-badge-tm::before {
+  content: ""; }
+
+.bi-badge-vo-fill::before {
+  content: ""; }
+
+.bi-badge-vo::before {
+  content: ""; }
+
+.bi-badge-vr-fill::before {
+  content: ""; }
+
+.bi-badge-vr::before {
+  content: ""; }
+
+.bi-badge-wc-fill::before {
+  content: ""; }
+
+.bi-badge-wc::before {
+  content: ""; }
+
+.bi-bag-check-fill::before {
+  content: ""; }
+
+.bi-bag-check::before {
+  content: ""; }
+
+.bi-bag-dash-fill::before {
+  content: ""; }
+
+.bi-bag-dash::before {
+  content: ""; }
+
+.bi-bag-fill::before {
+  content: ""; }
+
+.bi-bag-plus-fill::before {
+  content: ""; }
+
+.bi-bag-plus::before {
+  content: ""; }
+
+.bi-bag-x-fill::before {
+  content: ""; }
+
+.bi-bag-x::before {
+  content: ""; }
+
+.bi-bag::before {
+  content: ""; }
+
+.bi-bar-chart-fill::before {
+  content: ""; }
+
+.bi-bar-chart-line-fill::before {
+  content: ""; }
+
+.bi-bar-chart-line::before {
+  content: ""; }
+
+.bi-bar-chart-steps::before {
+  content: ""; }
+
+.bi-bar-chart::before {
+  content: ""; }
+
+.bi-basket-fill::before {
+  content: ""; }
+
+.bi-basket::before {
+  content: ""; }
+
+.bi-basket2-fill::before {
+  content: ""; }
+
+.bi-basket2::before {
+  content: ""; }
+
+.bi-basket3-fill::before {
+  content: ""; }
+
+.bi-basket3::before {
+  content: ""; }
+
+.bi-battery-charging::before {
+  content: ""; }
+
+.bi-battery-full::before {
+  content: ""; }
+
+.bi-battery-half::before {
+  content: ""; }
+
+.bi-battery::before {
+  content: ""; }
+
+.bi-bell-fill::before {
+  content: ""; }
+
+.bi-bell::before {
+  content: ""; }
+
+.bi-bezier::before {
+  content: ""; }
+
+.bi-bezier2::before {
+  content: ""; }
+
+.bi-bicycle::before {
+  content: ""; }
+
+.bi-binoculars-fill::before {
+  content: ""; }
+
+.bi-binoculars::before {
+  content: ""; }
+
+.bi-blockquote-left::before {
+  content: ""; }
+
+.bi-blockquote-right::before {
+  content: ""; }
+
+.bi-book-fill::before {
+  content: ""; }
+
+.bi-book-half::before {
+  content: ""; }
+
+.bi-book::before {
+  content: ""; }
+
+.bi-bookmark-check-fill::before {
+  content: ""; }
+
+.bi-bookmark-check::before {
+  content: ""; }
+
+.bi-bookmark-dash-fill::before {
+  content: ""; }
+
+.bi-bookmark-dash::before {
+  content: ""; }
+
+.bi-bookmark-fill::before {
+  content: ""; }
+
+.bi-bookmark-heart-fill::before {
+  content: ""; }
+
+.bi-bookmark-heart::before {
+  content: ""; }
+
+.bi-bookmark-plus-fill::before {
+  content: ""; }
+
+.bi-bookmark-plus::before {
+  content: ""; }
+
+.bi-bookmark-star-fill::before {
+  content: ""; }
+
+.bi-bookmark-star::before {
+  content: ""; }
+
+.bi-bookmark-x-fill::before {
+  content: ""; }
+
+.bi-bookmark-x::before {
+  content: ""; }
+
+.bi-bookmark::before {
+  content: ""; }
+
+.bi-bookmarks-fill::before {
+  content: ""; }
+
+.bi-bookmarks::before {
+  content: ""; }
+
+.bi-bookshelf::before {
+  content: ""; }
+
+.bi-bootstrap-fill::before {
+  content: ""; }
+
+.bi-bootstrap-reboot::before {
+  content: ""; }
+
+.bi-bootstrap::before {
+  content: ""; }
+
+.bi-border-all::before {
+  content: ""; }
+
+.bi-border-bottom::before {
+  content: ""; }
+
+.bi-border-center::before {
+  content: ""; }
+
+.bi-border-inner::before {
+  content: ""; }
+
+.bi-border-left::before {
+  content: ""; }
+
+.bi-border-middle::before {
+  content: ""; }
+
+.bi-border-outer::before {
+  content: ""; }
+
+.bi-border-right::before {
+  content: ""; }
+
+.bi-border-style::before {
+  content: ""; }
+
+.bi-border-top::before {
+  content: ""; }
+
+.bi-border-width::before {
+  content: ""; }
+
+.bi-border::before {
+  content: ""; }
+
+.bi-bounding-box-circles::before {
+  content: ""; }
+
+.bi-bounding-box::before {
+  content: ""; }
+
+.bi-box-arrow-down-left::before {
+  content: ""; }
+
+.bi-box-arrow-down-right::before {
+  content: ""; }
+
+.bi-box-arrow-down::before {
+  content: ""; }
+
+.bi-box-arrow-in-down-left::before {
+  content: ""; }
+
+.bi-box-arrow-in-down-right::before {
+  content: ""; }
+
+.bi-box-arrow-in-down::before {
+  content: ""; }
+
+.bi-box-arrow-in-left::before {
+  content: ""; }
+
+.bi-box-arrow-in-right::before {
+  content: ""; }
+
+.bi-box-arrow-in-up-left::before {
+  content: ""; }
+
+.bi-box-arrow-in-up-right::before {
+  content: ""; }
+
+.bi-box-arrow-in-up::before {
+  content: ""; }
+
+.bi-box-arrow-left::before {
+  content: ""; }
+
+.bi-box-arrow-right::before {
+  content: ""; }
+
+.bi-box-arrow-up-left::before {
+  content: ""; }
+
+.bi-box-arrow-up-right::before {
+  content: ""; }
+
+.bi-box-arrow-up::before {
+  content: ""; }
+
+.bi-box-seam::before {
+  content: ""; }
+
+.bi-box::before {
+  content: ""; }
+
+.bi-braces::before {
+  content: ""; }
+
+.bi-bricks::before {
+  content: ""; }
+
+.bi-briefcase-fill::before {
+  content: ""; }
+
+.bi-briefcase::before {
+  content: ""; }
+
+.bi-brightness-alt-high-fill::before {
+  content: ""; }
+
+.bi-brightness-alt-high::before {
+  content: ""; }
+
+.bi-brightness-alt-low-fill::before {
+  content: ""; }
+
+.bi-brightness-alt-low::before {
+  content: ""; }
+
+.bi-brightness-high-fill::before {
+  content: ""; }
+
+.bi-brightness-high::before {
+  content: ""; }
+
+.bi-brightness-low-fill::before {
+  content: ""; }
+
+.bi-brightness-low::before {
+  content: ""; }
+
+.bi-broadcast-pin::before {
+  content: ""; }
+
+.bi-broadcast::before {
+  content: ""; }
+
+.bi-brush-fill::before {
+  content: ""; }
+
+.bi-brush::before {
+  content: ""; }
+
+.bi-bucket-fill::before {
+  content: ""; }
+
+.bi-bucket::before {
+  content: ""; }
+
+.bi-bug-fill::before {
+  content: ""; }
+
+.bi-bug::before {
+  content: ""; }
+
+.bi-building::before {
+  content: ""; }
+
+.bi-bullseye::before {
+  content: ""; }
+
+.bi-calculator-fill::before {
+  content: ""; }
+
+.bi-calculator::before {
+  content: ""; }
+
+.bi-calendar-check-fill::before {
+  content: ""; }
+
+.bi-calendar-check::before {
+  content: ""; }
+
+.bi-calendar-date-fill::before {
+  content: ""; }
+
+.bi-calendar-date::before {
+  content: ""; }
+
+.bi-calendar-day-fill::before {
+  content: ""; }
+
+.bi-calendar-day::before {
+  content: ""; }
+
+.bi-calendar-event-fill::before {
+  content: ""; }
+
+.bi-calendar-event::before {
+  content: ""; }
+
+.bi-calendar-fill::before {
+  content: ""; }
+
+.bi-calendar-minus-fill::before {
+  content: ""; }
+
+.bi-calendar-minus::before {
+  content: ""; }
+
+.bi-calendar-month-fill::before {
+  content: ""; }
+
+.bi-calendar-month::before {
+  content: ""; }
+
+.bi-calendar-plus-fill::before {
+  content: ""; }
+
+.bi-calendar-plus::before {
+  content: ""; }
+
+.bi-calendar-range-fill::before {
+  content: ""; }
+
+.bi-calendar-range::before {
+  content: ""; }
+
+.bi-calendar-week-fill::before {
+  content: ""; }
+
+.bi-calendar-week::before {
+  content: ""; }
+
+.bi-calendar-x-fill::before {
+  content: ""; }
+
+.bi-calendar-x::before {
+  content: ""; }
+
+.bi-calendar::before {
+  content: ""; }
+
+.bi-calendar2-check-fill::before {
+  content: ""; }
+
+.bi-calendar2-check::before {
+  content: ""; }
+
+.bi-calendar2-date-fill::before {
+  content: ""; }
+
+.bi-calendar2-date::before {
+  content: ""; }
+
+.bi-calendar2-day-fill::before {
+  content: ""; }
+
+.bi-calendar2-day::before {
+  content: ""; }
+
+.bi-calendar2-event-fill::before {
+  content: ""; }
+
+.bi-calendar2-event::before {
+  content: ""; }
+
+.bi-calendar2-fill::before {
+  content: ""; }
+
+.bi-calendar2-minus-fill::before {
+  content: ""; }
+
+.bi-calendar2-minus::before {
+  content: ""; }
+
+.bi-calendar2-month-fill::before {
+  content: ""; }
+
+.bi-calendar2-month::before {
+  content: ""; }
+
+.bi-calendar2-plus-fill::before {
+  content: ""; }
+
+.bi-calendar2-plus::before {
+  content: ""; }
+
+.bi-calendar2-range-fill::before {
+  content: ""; }
+
+.bi-calendar2-range::before {
+  content: ""; }
+
+.bi-calendar2-week-fill::before {
+  content: ""; }
+
+.bi-calendar2-week::before {
+  content: ""; }
+
+.bi-calendar2-x-fill::before {
+  content: ""; }
+
+.bi-calendar2-x::before {
+  content: ""; }
+
+.bi-calendar2::before {
+  content: ""; }
+
+.bi-calendar3-event-fill::before {
+  content: ""; }
+
+.bi-calendar3-event::before {
+  content: ""; }
+
+.bi-calendar3-fill::before {
+  content: ""; }
+
+.bi-calendar3-range-fill::before {
+  content: ""; }
+
+.bi-calendar3-range::before {
+  content: ""; }
+
+.bi-calendar3-week-fill::before {
+  content: ""; }
+
+.bi-calendar3-week::before {
+  content: ""; }
+
+.bi-calendar3::before {
+  content: ""; }
+
+.bi-calendar4-event::before {
+  content: ""; }
+
+.bi-calendar4-range::before {
+  content: ""; }
+
+.bi-calendar4-week::before {
+  content: ""; }
+
+.bi-calendar4::before {
+  content: ""; }
+
+.bi-camera-fill::before {
+  content: ""; }
+
+.bi-camera-reels-fill::before {
+  content: ""; }
+
+.bi-camera-reels::before {
+  content: ""; }
+
+.bi-camera-video-fill::before {
+  content: ""; }
+
+.bi-camera-video-off-fill::before {
+  content: ""; }
+
+.bi-camera-video-off::before {
+  content: ""; }
+
+.bi-camera-video::before {
+  content: ""; }
+
+.bi-camera::before {
+  content: ""; }
+
+.bi-camera2::before {
+  content: ""; }
+
+.bi-capslock-fill::before {
+  content: ""; }
+
+.bi-capslock::before {
+  content: ""; }
+
+.bi-card-checklist::before {
+  content: ""; }
+
+.bi-card-heading::before {
+  content: ""; }
+
+.bi-card-image::before {
+  content: ""; }
+
+.bi-card-list::before {
+  content: ""; }
+
+.bi-card-text::before {
+  content: ""; }
+
+.bi-caret-down-fill::before {
+  content: ""; }
+
+.bi-caret-down-square-fill::before {
+  content: ""; }
+
+.bi-caret-down-square::before {
+  content: ""; }
+
+.bi-caret-down::before {
+  content: ""; }
+
+.bi-caret-left-fill::before {
+  content: ""; }
+
+.bi-caret-left-square-fill::before {
+  content: ""; }
+
+.bi-caret-left-square::before {
+  content: ""; }
+
+.bi-caret-left::before {
+  content: ""; }
+
+.bi-caret-right-fill::before {
+  content: ""; }
+
+.bi-caret-right-square-fill::before {
+  content: ""; }
+
+.bi-caret-right-square::before {
+  content: ""; }
+
+.bi-caret-right::before {
+  content: ""; }
+
+.bi-caret-up-fill::before {
+  content: ""; }
+
+.bi-caret-up-square-fill::before {
+  content: ""; }
+
+.bi-caret-up-square::before {
+  content: ""; }
+
+.bi-caret-up::before {
+  content: ""; }
+
+.bi-cart-check-fill::before {
+  content: ""; }
+
+.bi-cart-check::before {
+  content: ""; }
+
+.bi-cart-dash-fill::before {
+  content: ""; }
+
+.bi-cart-dash::before {
+  content: ""; }
+
+.bi-cart-fill::before {
+  content: ""; }
+
+.bi-cart-plus-fill::before {
+  content: ""; }
+
+.bi-cart-plus::before {
+  content: ""; }
+
+.bi-cart-x-fill::before {
+  content: ""; }
+
+.bi-cart-x::before {
+  content: ""; }
+
+.bi-cart::before {
+  content: ""; }
+
+.bi-cart2::before {
+  content: ""; }
+
+.bi-cart3::before {
+  content: ""; }
+
+.bi-cart4::before {
+  content: ""; }
+
+.bi-cash-stack::before {
+  content: ""; }
+
+.bi-cash::before {
+  content: ""; }
+
+.bi-cast::before {
+  content: ""; }
+
+.bi-chat-dots-fill::before {
+  content: ""; }
+
+.bi-chat-dots::before {
+  content: ""; }
+
+.bi-chat-fill::before {
+  content: ""; }
+
+.bi-chat-left-dots-fill::before {
+  content: ""; }
+
+.bi-chat-left-dots::before {
+  content: ""; }
+
+.bi-chat-left-fill::before {
+  content: ""; }
+
+.bi-chat-left-quote-fill::before {
+  content: ""; }
+
+.bi-chat-left-quote::before {
+  content: ""; }
+
+.bi-chat-left-text-fill::before {
+  content: ""; }
+
+.bi-chat-left-text::before {
+  content: ""; }
+
+.bi-chat-left::before {
+  content: ""; }
+
+.bi-chat-quote-fill::before {
+  content: ""; }
+
+.bi-chat-quote::before {
+  content: ""; }
+
+.bi-chat-right-dots-fill::before {
+  content: ""; }
+
+.bi-chat-right-dots::before {
+  content: ""; }
+
+.bi-chat-right-fill::before {
+  content: ""; }
+
+.bi-chat-right-quote-fill::before {
+  content: ""; }
+
+.bi-chat-right-quote::before {
+  content: ""; }
+
+.bi-chat-right-text-fill::before {
+  content: ""; }
+
+.bi-chat-right-text::before {
+  content: ""; }
+
+.bi-chat-right::before {
+  content: ""; }
+
+.bi-chat-square-dots-fill::before {
+  content: ""; }
+
+.bi-chat-square-dots::before {
+  content: ""; }
+
+.bi-chat-square-fill::before {
+  content: ""; }
+
+.bi-chat-square-quote-fill::before {
+  content: ""; }
+
+.bi-chat-square-quote::before {
+  content: ""; }
+
+.bi-chat-square-text-fill::before {
+  content: ""; }
+
+.bi-chat-square-text::before {
+  content: ""; }
+
+.bi-chat-square::before {
+  content: ""; }
+
+.bi-chat-text-fill::before {
+  content: ""; }
+
+.bi-chat-text::before {
+  content: ""; }
+
+.bi-chat::before {
+  content: ""; }
+
+.bi-check-all::before {
+  content: ""; }
+
+.bi-check-circle-fill::before {
+  content: ""; }
+
+.bi-check-circle::before {
+  content: ""; }
+
+.bi-check-square-fill::before {
+  content: ""; }
+
+.bi-check-square::before {
+  content: ""; }
+
+.bi-check::before {
+  content: ""; }
+
+.bi-check2-all::before {
+  content: ""; }
+
+.bi-check2-circle::before {
+  content: ""; }
+
+.bi-check2-square::before {
+  content: ""; }
+
+.bi-check2::before {
+  content: ""; }
+
+.bi-chevron-bar-contract::before {
+  content: ""; }
+
+.bi-chevron-bar-down::before {
+  content: ""; }
+
+.bi-chevron-bar-expand::before {
+  content: ""; }
+
+.bi-chevron-bar-left::before {
+  content: ""; }
+
+.bi-chevron-bar-right::before {
+  content: ""; }
+
+.bi-chevron-bar-up::before {
+  content: ""; }
+
+.bi-chevron-compact-down::before {
+  content: ""; }
+
+.bi-chevron-compact-left::before {
+  content: ""; }
+
+.bi-chevron-compact-right::before {
+  content: ""; }
+
+.bi-chevron-compact-up::before {
+  content: ""; }
+
+.bi-chevron-contract::before {
+  content: ""; }
+
+.bi-chevron-double-down::before {
+  content: ""; }
+
+.bi-chevron-double-left::before {
+  content: ""; }
+
+.bi-chevron-double-right::before {
+  content: ""; }
+
+.bi-chevron-double-up::before {
+  content: ""; }
+
+.bi-chevron-down::before {
+  content: ""; }
+
+.bi-chevron-expand::before {
+  content: ""; }
+
+.bi-chevron-left::before {
+  content: ""; }
+
+.bi-chevron-right::before {
+  content: ""; }
+
+.bi-chevron-up::before {
+  content: ""; }
+
+.bi-circle-fill::before {
+  content: ""; }
+
+.bi-circle-half::before {
+  content: ""; }
+
+.bi-circle-square::before {
+  content: ""; }
+
+.bi-circle::before {
+  content: ""; }
+
+.bi-clipboard-check::before {
+  content: ""; }
+
+.bi-clipboard-data::before {
+  content: ""; }
+
+.bi-clipboard-minus::before {
+  content: ""; }
+
+.bi-clipboard-plus::before {
+  content: ""; }
+
+.bi-clipboard-x::before {
+  content: ""; }
+
+.bi-clipboard::before {
+  content: ""; }
+
+.bi-clock-fill::before {
+  content: ""; }
+
+.bi-clock-history::before {
+  content: ""; }
+
+.bi-clock::before {
+  content: ""; }
+
+.bi-cloud-arrow-down-fill::before {
+  content: ""; }
+
+.bi-cloud-arrow-down::before {
+  content: ""; }
+
+.bi-cloud-arrow-up-fill::before {
+  content: ""; }
+
+.bi-cloud-arrow-up::before {
+  content: ""; }
+
+.bi-cloud-check-fill::before {
+  content: ""; }
+
+.bi-cloud-check::before {
+  content: ""; }
+
+.bi-cloud-download-fill::before {
+  content: ""; }
+
+.bi-cloud-download::before {
+  content: ""; }
+
+.bi-cloud-drizzle-fill::before {
+  content: ""; }
+
+.bi-cloud-drizzle::before {
+  content: ""; }
+
+.bi-cloud-fill::before {
+  content: ""; }
+
+.bi-cloud-fog-fill::before {
+  content: ""; }
+
+.bi-cloud-fog::before {
+  content: ""; }
+
+.bi-cloud-fog2-fill::before {
+  content: ""; }
+
+.bi-cloud-fog2::before {
+  content: ""; }
+
+.bi-cloud-hail-fill::before {
+  content: ""; }
+
+.bi-cloud-hail::before {
+  content: ""; }
+
+.bi-cloud-haze-fill::before {
+  content: ""; }
+
+.bi-cloud-haze::before {
+  content: ""; }
+
+.bi-cloud-haze2-fill::before {
+  content: ""; }
+
+.bi-cloud-lightning-fill::before {
+  content: ""; }
+
+.bi-cloud-lightning-rain-fill::before {
+  content: ""; }
+
+.bi-cloud-lightning-rain::before {
+  content: ""; }
+
+.bi-cloud-lightning::before {
+  content: ""; }
+
+.bi-cloud-minus-fill::before {
+  content: ""; }
+
+.bi-cloud-minus::before {
+  content: ""; }
+
+.bi-cloud-moon-fill::before {
+  content: ""; }
+
+.bi-cloud-moon::before {
+  content: ""; }
+
+.bi-cloud-plus-fill::before {
+  content: ""; }
+
+.bi-cloud-plus::before {
+  content: ""; }
+
+.bi-cloud-rain-fill::before {
+  content: ""; }
+
+.bi-cloud-rain-heavy-fill::before {
+  content: ""; }
+
+.bi-cloud-rain-heavy::before {
+  content: ""; }
+
+.bi-cloud-rain::before {
+  content: ""; }
+
+.bi-cloud-slash-fill::before {
+  content: ""; }
+
+.bi-cloud-slash::before {
+  content: ""; }
+
+.bi-cloud-sleet-fill::before {
+  content: ""; }
+
+.bi-cloud-sleet::before {
+  content: ""; }
+
+.bi-cloud-snow-fill::before {
+  content: ""; }
+
+.bi-cloud-snow::before {
+  content: ""; }
+
+.bi-cloud-sun-fill::before {
+  content: ""; }
+
+.bi-cloud-sun::before {
+  content: ""; }
+
+.bi-cloud-upload-fill::before {
+  content: ""; }
+
+.bi-cloud-upload::before {
+  content: ""; }
+
+.bi-cloud::before {
+  content: ""; }
+
+.bi-clouds-fill::before {
+  content: ""; }
+
+.bi-clouds::before {
+  content: ""; }
+
+.bi-cloudy-fill::before {
+  content: ""; }
+
+.bi-cloudy::before {
+  content: ""; }
+
+.bi-code-slash::before {
+  content: ""; }
+
+.bi-code-square::before {
+  content: ""; }
+
+.bi-code::before {
+  content: ""; }
+
+.bi-collection-fill::before {
+  content: ""; }
+
+.bi-collection-play-fill::before {
+  content: ""; }
+
+.bi-collection-play::before {
+  content: ""; }
+
+.bi-collection::before {
+  content: ""; }
+
+.bi-columns-gap::before {
+  content: ""; }
+
+.bi-columns::before {
+  content: ""; }
+
+.bi-command::before {
+  content: ""; }
+
+.bi-compass-fill::before {
+  content: ""; }
+
+.bi-compass::before {
+  content: ""; }
+
+.bi-cone-striped::before {
+  content: ""; }
+
+.bi-cone::before {
+  content: ""; }
+
+.bi-controller::before {
+  content: ""; }
+
+.bi-cpu-fill::before {
+  content: ""; }
+
+.bi-cpu::before {
+  content: ""; }
+
+.bi-credit-card-2-back-fill::before {
+  content: ""; }
+
+.bi-credit-card-2-back::before {
+  content: ""; }
+
+.bi-credit-card-2-front-fill::before {
+  content: ""; }
+
+.bi-credit-card-2-front::before {
+  content: ""; }
+
+.bi-credit-card-fill::before {
+  content: ""; }
+
+.bi-credit-card::before {
+  content: ""; }
+
+.bi-crop::before {
+  content: ""; }
+
+.bi-cup-fill::before {
+  content: ""; }
+
+.bi-cup-straw::before {
+  content: ""; }
+
+.bi-cup::before {
+  content: ""; }
+
+.bi-cursor-fill::before {
+  content: ""; }
+
+.bi-cursor-text::before {
+  content: ""; }
+
+.bi-cursor::before {
+  content: ""; }
+
+.bi-dash-circle-dotted::before {
+  content: ""; }
+
+.bi-dash-circle-fill::before {
+  content: ""; }
+
+.bi-dash-circle::before {
+  content: ""; }
+
+.bi-dash-square-dotted::before {
+  content: ""; }
+
+.bi-dash-square-fill::before {
+  content: ""; }
+
+.bi-dash-square::before {
+  content: ""; }
+
+.bi-dash::before {
+  content: ""; }
+
+.bi-diagram-2-fill::before {
+  content: ""; }
+
+.bi-diagram-2::before {
+  content: ""; }
+
+.bi-diagram-3-fill::before {
+  content: ""; }
+
+.bi-diagram-3::before {
+  content: ""; }
+
+.bi-diamond-fill::before {
+  content: ""; }
+
+.bi-diamond-half::before {
+  content: ""; }
+
+.bi-diamond::before {
+  content: ""; }
+
+.bi-dice-1-fill::before {
+  content: ""; }
+
+.bi-dice-1::before {
+  content: ""; }
+
+.bi-dice-2-fill::before {
+  content: ""; }
+
+.bi-dice-2::before {
+  content: ""; }
+
+.bi-dice-3-fill::before {
+  content: ""; }
+
+.bi-dice-3::before {
+  content: ""; }
+
+.bi-dice-4-fill::before {
+  content: ""; }
+
+.bi-dice-4::before {
+  content: ""; }
+
+.bi-dice-5-fill::before {
+  content: ""; }
+
+.bi-dice-5::before {
+  content: ""; }
+
+.bi-dice-6-fill::before {
+  content: ""; }
+
+.bi-dice-6::before {
+  content: ""; }
+
+.bi-disc-fill::before {
+  content: ""; }
+
+.bi-disc::before {
+  content: ""; }
+
+.bi-discord::before {
+  content: ""; }
+
+.bi-display-fill::before {
+  content: ""; }
+
+.bi-display::before {
+  content: ""; }
+
+.bi-distribute-horizontal::before {
+  content: ""; }
+
+.bi-distribute-vertical::before {
+  content: ""; }
+
+.bi-door-closed-fill::before {
+  content: ""; }
+
+.bi-door-closed::before {
+  content: ""; }
+
+.bi-door-open-fill::before {
+  content: ""; }
+
+.bi-door-open::before {
+  content: ""; }
+
+.bi-dot::before {
+  content: ""; }
+
+.bi-download::before {
+  content: ""; }
+
+.bi-droplet-fill::before {
+  content: ""; }
+
+.bi-droplet-half::before {
+  content: ""; }
+
+.bi-droplet::before {
+  content: ""; }
+
+.bi-earbuds::before {
+  content: ""; }
+
+.bi-easel-fill::before {
+  content: ""; }
+
+.bi-easel::before {
+  content: ""; }
+
+.bi-egg-fill::before {
+  content: ""; }
+
+.bi-egg-fried::before {
+  content: ""; }
+
+.bi-egg::before {
+  content: ""; }
+
+.bi-eject-fill::before {
+  content: ""; }
+
+.bi-eject::before {
+  content: ""; }
+
+.bi-emoji-angry-fill::before {
+  content: ""; }
+
+.bi-emoji-angry::before {
+  content: ""; }
+
+.bi-emoji-dizzy-fill::before {
+  content: ""; }
+
+.bi-emoji-dizzy::before {
+  content: ""; }
+
+.bi-emoji-expressionless-fill::before {
+  content: ""; }
+
+.bi-emoji-expressionless::before {
+  content: ""; }
+
+.bi-emoji-frown-fill::before {
+  content: ""; }
+
+.bi-emoji-frown::before {
+  content: ""; }
+
+.bi-emoji-heart-eyes-fill::before {
+  content: ""; }
+
+.bi-emoji-heart-eyes::before {
+  content: ""; }
+
+.bi-emoji-laughing-fill::before {
+  content: ""; }
+
+.bi-emoji-laughing::before {
+  content: ""; }
+
+.bi-emoji-neutral-fill::before {
+  content: ""; }
+
+.bi-emoji-neutral::before {
+  content: ""; }
+
+.bi-emoji-smile-fill::before {
+  content: ""; }
+
+.bi-emoji-smile-upside-down-fill::before {
+  content: ""; }
+
+.bi-emoji-smile-upside-down::before {
+  content: ""; }
+
+.bi-emoji-smile::before {
+  content: ""; }
+
+.bi-emoji-sunglasses-fill::before {
+  content: ""; }
+
+.bi-emoji-sunglasses::before {
+  content: ""; }
+
+.bi-emoji-wink-fill::before {
+  content: ""; }
+
+.bi-emoji-wink::before {
+  content: ""; }
+
+.bi-envelope-fill::before {
+  content: ""; }
+
+.bi-envelope-open-fill::before {
+  content: ""; }
+
+.bi-envelope-open::before {
+  content: ""; }
+
+.bi-envelope::before {
+  content: ""; }
+
+.bi-eraser-fill::before {
+  content: ""; }
+
+.bi-eraser::before {
+  content: ""; }
+
+.bi-exclamation-circle-fill::before {
+  content: ""; }
+
+.bi-exclamation-circle::before {
+  content: ""; }
+
+.bi-exclamation-diamond-fill::before {
+  content: ""; }
+
+.bi-exclamation-diamond::before {
+  content: ""; }
+
+.bi-exclamation-octagon-fill::before {
+  content: ""; }
+
+.bi-exclamation-octagon::before {
+  content: ""; }
+
+.bi-exclamation-square-fill::before {
+  content: ""; }
+
+.bi-exclamation-square::before {
+  content: ""; }
+
+.bi-exclamation-triangle-fill::before {
+  content: ""; }
+
+.bi-exclamation-triangle::before {
+  content: ""; }
+
+.bi-exclamation::before {
+  content: ""; }
+
+.bi-exclude::before {
+  content: ""; }
+
+.bi-eye-fill::before {
+  content: ""; }
+
+.bi-eye-slash-fill::before {
+  content: ""; }
+
+.bi-eye-slash::before {
+  content: ""; }
+
+.bi-eye::before {
+  content: ""; }
+
+.bi-eyedropper::before {
+  content: ""; }
+
+.bi-eyeglasses::before {
+  content: ""; }
+
+.bi-facebook::before {
+  content: ""; }
+
+.bi-file-arrow-down-fill::before {
+  content: ""; }
+
+.bi-file-arrow-down::before {
+  content: ""; }
+
+.bi-file-arrow-up-fill::before {
+  content: ""; }
+
+.bi-file-arrow-up::before {
+  content: ""; }
+
+.bi-file-bar-graph-fill::before {
+  content: ""; }
+
+.bi-file-bar-graph::before {
+  content: ""; }
+
+.bi-file-binary-fill::before {
+  content: ""; }
+
+.bi-file-binary::before {
+  content: ""; }
+
+.bi-file-break-fill::before {
+  content: ""; }
+
+.bi-file-break::before {
+  content: ""; }
+
+.bi-file-check-fill::before {
+  content: ""; }
+
+.bi-file-check::before {
+  content: ""; }
+
+.bi-file-code-fill::before {
+  content: ""; }
+
+.bi-file-code::before {
+  content: ""; }
+
+.bi-file-diff-fill::before {
+  content: ""; }
+
+.bi-file-diff::before {
+  content: ""; }
+
+.bi-file-earmark-arrow-down-fill::before {
+  content: ""; }
+
+.bi-file-earmark-arrow-down::before {
+  content: ""; }
+
+.bi-file-earmark-arrow-up-fill::before {
+  content: ""; }
+
+.bi-file-earmark-arrow-up::before {
+  content: ""; }
+
+.bi-file-earmark-bar-graph-fill::before {
+  content: ""; }
+
+.bi-file-earmark-bar-graph::before {
+  content: ""; }
+
+.bi-file-earmark-binary-fill::before {
+  content: ""; }
+
+.bi-file-earmark-binary::before {
+  content: ""; }
+
+.bi-file-earmark-break-fill::before {
+  content: ""; }
+
+.bi-file-earmark-break::before {
+  content: ""; }
+
+.bi-file-earmark-check-fill::before {
+  content: ""; }
+
+.bi-file-earmark-check::before {
+  content: ""; }
+
+.bi-file-earmark-code-fill::before {
+  content: ""; }
+
+.bi-file-earmark-code::before {
+  content: ""; }
+
+.bi-file-earmark-diff-fill::before {
+  content: ""; }
+
+.bi-file-earmark-diff::before {
+  content: ""; }
+
+.bi-file-earmark-easel-fill::before {
+  content: ""; }
+
+.bi-file-earmark-easel::before {
+  content: ""; }
+
+.bi-file-earmark-excel-fill::before {
+  content: ""; }
+
+.bi-file-earmark-excel::before {
+  content: ""; }
+
+.bi-file-earmark-fill::before {
+  content: ""; }
+
+.bi-file-earmark-font-fill::before {
+  content: ""; }
+
+.bi-file-earmark-font::before {
+  content: ""; }
+
+.bi-file-earmark-image-fill::before {
+  content: ""; }
+
+.bi-file-earmark-image::before {
+  content: ""; }
+
+.bi-file-earmark-lock-fill::before {
+  content: ""; }
+
+.bi-file-earmark-lock::before {
+  content: ""; }
+
+.bi-file-earmark-lock2-fill::before {
+  content: ""; }
+
+.bi-file-earmark-lock2::before {
+  content: ""; }
+
+.bi-file-earmark-medical-fill::before {
+  content: ""; }
+
+.bi-file-earmark-medical::before {
+  content: ""; }
+
+.bi-file-earmark-minus-fill::before {
+  content: ""; }
+
+.bi-file-earmark-minus::before {
+  content: ""; }
+
+.bi-file-earmark-music-fill::before {
+  content: ""; }
+
+.bi-file-earmark-music::before {
+  content: ""; }
+
+.bi-file-earmark-person-fill::before {
+  content: ""; }
+
+.bi-file-earmark-person::before {
+  content: ""; }
+
+.bi-file-earmark-play-fill::before {
+  content: ""; }
+
+.bi-file-earmark-play::before {
+  content: ""; }
+
+.bi-file-earmark-plus-fill::before {
+  content: ""; }
+
+.bi-file-earmark-plus::before {
+  content: ""; }
+
+.bi-file-earmark-post-fill::before {
+  content: ""; }
+
+.bi-file-earmark-post::before {
+  content: ""; }
+
+.bi-file-earmark-ppt-fill::before {
+  content: ""; }
+
+.bi-file-earmark-ppt::before {
+  content: ""; }
+
+.bi-file-earmark-richtext-fill::before {
+  content: ""; }
+
+.bi-file-earmark-richtext::before {
+  content: ""; }
+
+.bi-file-earmark-ruled-fill::before {
+  content: ""; }
+
+.bi-file-earmark-ruled::before {
+  content: ""; }
+
+.bi-file-earmark-slides-fill::before {
+  content: ""; }
+
+.bi-file-earmark-slides::before {
+  content: ""; }
+
+.bi-file-earmark-spreadsheet-fill::before {
+  content: ""; }
+
+.bi-file-earmark-spreadsheet::before {
+  content: ""; }
+
+.bi-file-earmark-text-fill::before {
+  content: ""; }
+
+.bi-file-earmark-text::before {
+  content: ""; }
+
+.bi-file-earmark-word-fill::before {
+  content: ""; }
+
+.bi-file-earmark-word::before {
+  content: ""; }
+
+.bi-file-earmark-x-fill::before {
+  content: ""; }
+
+.bi-file-earmark-x::before {
+  content: ""; }
+
+.bi-file-earmark-zip-fill::before {
+  content: ""; }
+
+.bi-file-earmark-zip::before {
+  content: ""; }
+
+.bi-file-earmark::before {
+  content: ""; }
+
+.bi-file-easel-fill::before {
+  content: ""; }
+
+.bi-file-easel::before {
+  content: ""; }
+
+.bi-file-excel-fill::before {
+  content: ""; }
+
+.bi-file-excel::before {
+  content: ""; }
+
+.bi-file-fill::before {
+  content: ""; }
+
+.bi-file-font-fill::before {
+  content: ""; }
+
+.bi-file-font::before {
+  content: ""; }
+
+.bi-file-image-fill::before {
+  content: ""; }
+
+.bi-file-image::before {
+  content: ""; }
+
+.bi-file-lock-fill::before {
+  content: ""; }
+
+.bi-file-lock::before {
+  content: ""; }
+
+.bi-file-lock2-fill::before {
+  content: ""; }
+
+.bi-file-lock2::before {
+  content: ""; }
+
+.bi-file-medical-fill::before {
+  content: ""; }
+
+.bi-file-medical::before {
+  content: ""; }
+
+.bi-file-minus-fill::before {
+  content: ""; }
+
+.bi-file-minus::before {
+  content: ""; }
+
+.bi-file-music-fill::before {
+  content: ""; }
+
+.bi-file-music::before {
+  content: ""; }
+
+.bi-file-person-fill::before {
+  content: ""; }
+
+.bi-file-person::before {
+  content: ""; }
+
+.bi-file-play-fill::before {
+  content: ""; }
+
+.bi-file-play::before {
+  content: ""; }
+
+.bi-file-plus-fill::before {
+  content: ""; }
+
+.bi-file-plus::before {
+  content: ""; }
+
+.bi-file-post-fill::before {
+  content: ""; }
+
+.bi-file-post::before {
+  content: ""; }
+
+.bi-file-ppt-fill::before {
+  content: ""; }
+
+.bi-file-ppt::before {
+  content: ""; }
+
+.bi-file-richtext-fill::before {
+  content: ""; }
+
+.bi-file-richtext::before {
+  content: ""; }
+
+.bi-file-ruled-fill::before {
+  content: ""; }
+
+.bi-file-ruled::before {
+  content: ""; }
+
+.bi-file-slides-fill::before {
+  content: ""; }
+
+.bi-file-slides::before {
+  content: ""; }
+
+.bi-file-spreadsheet-fill::before {
+  content: ""; }
+
+.bi-file-spreadsheet::before {
+  content: ""; }
+
+.bi-file-text-fill::before {
+  content: ""; }
+
+.bi-file-text::before {
+  content: ""; }
+
+.bi-file-word-fill::before {
+  content: ""; }
+
+.bi-file-word::before {
+  content: ""; }
+
+.bi-file-x-fill::before {
+  content: ""; }
+
+.bi-file-x::before {
+  content: ""; }
+
+.bi-file-zip-fill::before {
+  content: ""; }
+
+.bi-file-zip::before {
+  content: ""; }
+
+.bi-file::before {
+  content: ""; }
+
+.bi-files-alt::before {
+  content: ""; }
+
+.bi-files::before {
+  content: ""; }
+
+.bi-film::before {
+  content: ""; }
+
+.bi-filter-circle-fill::before {
+  content: ""; }
+
+.bi-filter-circle::before {
+  content: ""; }
+
+.bi-filter-left::before {
+  content: ""; }
+
+.bi-filter-right::before {
+  content: ""; }
+
+.bi-filter-square-fill::before {
+  content: ""; }
+
+.bi-filter-square::before {
+  content: ""; }
+
+.bi-filter::before {
+  content: ""; }
+
+.bi-flag-fill::before {
+  content: ""; }
+
+.bi-flag::before {
+  content: ""; }
+
+.bi-flower1::before {
+  content: ""; }
+
+.bi-flower2::before {
+  content: ""; }
+
+.bi-flower3::before {
+  content: ""; }
+
+.bi-folder-check::before {
+  content: ""; }
+
+.bi-folder-fill::before {
+  content: ""; }
+
+.bi-folder-minus::before {
+  content: ""; }
+
+.bi-folder-plus::before {
+  content: ""; }
+
+.bi-folder-symlink-fill::before {
+  content: ""; }
+
+.bi-folder-symlink::before {
+  content: ""; }
+
+.bi-folder-x::before {
+  content: ""; }
+
+.bi-folder::before {
+  content: ""; }
+
+.bi-folder2-open::before {
+  content: ""; }
+
+.bi-folder2::before {
+  content: ""; }
+
+.bi-fonts::before {
+  content: ""; }
+
+.bi-forward-fill::before {
+  content: ""; }
+
+.bi-forward::before {
+  content: ""; }
+
+.bi-front::before {
+  content: ""; }
+
+.bi-fullscreen-exit::before {
+  content: ""; }
+
+.bi-fullscreen::before {
+  content: ""; }
+
+.bi-funnel-fill::before {
+  content: ""; }
+
+.bi-funnel::before {
+  content: ""; }
+
+.bi-gear-fill::before {
+  content: ""; }
+
+.bi-gear-wide-connected::before {
+  content: ""; }
+
+.bi-gear-wide::before {
+  content: ""; }
+
+.bi-gear::before {
+  content: ""; }
+
+.bi-gem::before {
+  content: ""; }
+
+.bi-geo-alt-fill::before {
+  content: ""; }
+
+.bi-geo-alt::before {
+  content: ""; }
+
+.bi-geo-fill::before {
+  content: ""; }
+
+.bi-geo::before {
+  content: ""; }
+
+.bi-gift-fill::before {
+  content: ""; }
+
+.bi-gift::before {
+  content: ""; }
+
+.bi-github::before {
+  content: ""; }
+
+.bi-globe::before {
+  content: ""; }
+
+.bi-globe2::before {
+  content: ""; }
+
+.bi-google::before {
+  content: ""; }
+
+.bi-graph-down::before {
+  content: ""; }
+
+.bi-graph-up::before {
+  content: ""; }
+
+.bi-grid-1x2-fill::before {
+  content: ""; }
+
+.bi-grid-1x2::before {
+  content: ""; }
+
+.bi-grid-3x2-gap-fill::before {
+  content: ""; }
+
+.bi-grid-3x2-gap::before {
+  content: ""; }
+
+.bi-grid-3x2::before {
+  content: ""; }
+
+.bi-grid-3x3-gap-fill::before {
+  content: ""; }
+
+.bi-grid-3x3-gap::before {
+  content: ""; }
+
+.bi-grid-3x3::before {
+  content: ""; }
+
+.bi-grid-fill::before {
+  content: ""; }
+
+.bi-grid::before {
+  content: ""; }
+
+.bi-grip-horizontal::before {
+  content: ""; }
+
+.bi-grip-vertical::before {
+  content: ""; }
+
+.bi-hammer::before {
+  content: ""; }
+
+.bi-hand-index-fill::before {
+  content: ""; }
+
+.bi-hand-index-thumb-fill::before {
+  content: ""; }
+
+.bi-hand-index-thumb::before {
+  content: ""; }
+
+.bi-hand-index::before {
+  content: ""; }
+
+.bi-hand-thumbs-down-fill::before {
+  content: ""; }
+
+.bi-hand-thumbs-down::before {
+  content: ""; }
+
+.bi-hand-thumbs-up-fill::before {
+  content: ""; }
+
+.bi-hand-thumbs-up::before {
+  content: ""; }
+
+.bi-handbag-fill::before {
+  content: ""; }
+
+.bi-handbag::before {
+  content: ""; }
+
+.bi-hash::before {
+  content: ""; }
+
+.bi-hdd-fill::before {
+  content: ""; }
+
+.bi-hdd-network-fill::before {
+  content: ""; }
+
+.bi-hdd-network::before {
+  content: ""; }
+
+.bi-hdd-rack-fill::before {
+  content: ""; }
+
+.bi-hdd-rack::before {
+  content: ""; }
+
+.bi-hdd-stack-fill::before {
+  content: ""; }
+
+.bi-hdd-stack::before {
+  content: ""; }
+
+.bi-hdd::before {
+  content: ""; }
+
+.bi-headphones::before {
+  content: ""; }
+
+.bi-headset::before {
+  content: ""; }
+
+.bi-heart-fill::before {
+  content: ""; }
+
+.bi-heart-half::before {
+  content: ""; }
+
+.bi-heart::before {
+  content: ""; }
+
+.bi-heptagon-fill::before {
+  content: ""; }
+
+.bi-heptagon-half::before {
+  content: ""; }
+
+.bi-heptagon::before {
+  content: ""; }
+
+.bi-hexagon-fill::before {
+  content: ""; }
+
+.bi-hexagon-half::before {
+  content: ""; }
+
+.bi-hexagon::before {
+  content: ""; }
+
+.bi-hourglass-bottom::before {
+  content: ""; }
+
+.bi-hourglass-split::before {
+  content: ""; }
+
+.bi-hourglass-top::before {
+  content: ""; }
+
+.bi-hourglass::before {
+  content: ""; }
+
+.bi-house-door-fill::before {
+  content: ""; }
+
+.bi-house-door::before {
+  content: ""; }
+
+.bi-house-fill::before {
+  content: ""; }
+
+.bi-house::before {
+  content: ""; }
+
+.bi-hr::before {
+  content: ""; }
+
+.bi-hurricane::before {
+  content: ""; }
+
+.bi-image-alt::before {
+  content: ""; }
+
+.bi-image-fill::before {
+  content: ""; }
+
+.bi-image::before {
+  content: ""; }
+
+.bi-images::before {
+  content: ""; }
+
+.bi-inbox-fill::before {
+  content: ""; }
+
+.bi-inbox::before {
+  content: ""; }
+
+.bi-inboxes-fill::before {
+  content: ""; }
+
+.bi-inboxes::before {
+  content: ""; }
+
+.bi-info-circle-fill::before {
+  content: ""; }
+
+.bi-info-circle::before {
+  content: ""; }
+
+.bi-info-square-fill::before {
+  content: ""; }
+
+.bi-info-square::before {
+  content: ""; }
+
+.bi-info::before {
+  content: ""; }
+
+.bi-input-cursor-text::before {
+  content: ""; }
+
+.bi-input-cursor::before {
+  content: ""; }
+
+.bi-instagram::before {
+  content: ""; }
+
+.bi-intersect::before {
+  content: ""; }
+
+.bi-journal-album::before {
+  content: ""; }
+
+.bi-journal-arrow-down::before {
+  content: ""; }
+
+.bi-journal-arrow-up::before {
+  content: ""; }
+
+.bi-journal-bookmark-fill::before {
+  content: ""; }
+
+.bi-journal-bookmark::before {
+  content: ""; }
+
+.bi-journal-check::before {
+  content: ""; }
+
+.bi-journal-code::before {
+  content: ""; }
+
+.bi-journal-medical::before {
+  content: ""; }
+
+.bi-journal-minus::before {
+  content: ""; }
+
+.bi-journal-plus::before {
+  content: ""; }
+
+.bi-journal-richtext::before {
+  content: ""; }
+
+.bi-journal-text::before {
+  content: ""; }
+
+.bi-journal-x::before {
+  content: ""; }
+
+.bi-journal::before {
+  content: ""; }
+
+.bi-journals::before {
+  content: ""; }
+
+.bi-joystick::before {
+  content: ""; }
+
+.bi-justify-left::before {
+  content: ""; }
+
+.bi-justify-right::before {
+  content: ""; }
+
+.bi-justify::before {
+  content: ""; }
+
+.bi-kanban-fill::before {
+  content: ""; }
+
+.bi-kanban::before {
+  content: ""; }
+
+.bi-key-fill::before {
+  content: ""; }
+
+.bi-key::before {
+  content: ""; }
+
+.bi-keyboard-fill::before {
+  content: ""; }
+
+.bi-keyboard::before {
+  content: ""; }
+
+.bi-ladder::before {
+  content: ""; }
+
+.bi-lamp-fill::before {
+  content: ""; }
+
+.bi-lamp::before {
+  content: ""; }
+
+.bi-laptop-fill::before {
+  content: ""; }
+
+.bi-laptop::before {
+  content: ""; }
+
+.bi-layer-backward::before {
+  content: ""; }
+
+.bi-layer-forward::before {
+  content: ""; }
+
+.bi-layers-fill::before {
+  content: ""; }
+
+.bi-layers-half::before {
+  content: ""; }
+
+.bi-layers::before {
+  content: ""; }
+
+.bi-layout-sidebar-inset-reverse::before {
+  content: ""; }
+
+.bi-layout-sidebar-inset::before {
+  content: ""; }
+
+.bi-layout-sidebar-reverse::before {
+  content: ""; }
+
+.bi-layout-sidebar::before {
+  content: ""; }
+
+.bi-layout-split::before {
+  content: ""; }
+
+.bi-layout-text-sidebar-reverse::before {
+  content: ""; }
+
+.bi-layout-text-sidebar::before {
+  content: ""; }
+
+.bi-layout-text-window-reverse::before {
+  content: ""; }
+
+.bi-layout-text-window::before {
+  content: ""; }
+
+.bi-layout-three-columns::before {
+  content: ""; }
+
+.bi-layout-wtf::before {
+  content: ""; }
+
+.bi-life-preserver::before {
+  content: ""; }
+
+.bi-lightbulb-fill::before {
+  content: ""; }
+
+.bi-lightbulb-off-fill::before {
+  content: ""; }
+
+.bi-lightbulb-off::before {
+  content: ""; }
+
+.bi-lightbulb::before {
+  content: ""; }
+
+.bi-lightning-charge-fill::before {
+  content: ""; }
+
+.bi-lightning-charge::before {
+  content: ""; }
+
+.bi-lightning-fill::before {
+  content: ""; }
+
+.bi-lightning::before {
+  content: ""; }
+
+.bi-link-45deg::before {
+  content: ""; }
+
+.bi-link::before {
+  content: ""; }
+
+.bi-linkedin::before {
+  content: ""; }
+
+.bi-list-check::before {
+  content: ""; }
+
+.bi-list-nested::before {
+  content: ""; }
+
+.bi-list-ol::before {
+  content: ""; }
+
+.bi-list-stars::before {
+  content: ""; }
+
+.bi-list-task::before {
+  content: ""; }
+
+.bi-list-ul::before {
+  content: ""; }
+
+.bi-list::before {
+  content: ""; }
+
+.bi-lock-fill::before {
+  content: ""; }
+
+.bi-lock::before {
+  content: ""; }
+
+.bi-mailbox::before {
+  content: ""; }
+
+.bi-mailbox2::before {
+  content: ""; }
+
+.bi-map-fill::before {
+  content: ""; }
+
+.bi-map::before {
+  content: ""; }
+
+.bi-markdown-fill::before {
+  content: ""; }
+
+.bi-markdown::before {
+  content: ""; }
+
+.bi-mask::before {
+  content: ""; }
+
+.bi-megaphone-fill::before {
+  content: ""; }
+
+.bi-megaphone::before {
+  content: ""; }
+
+.bi-menu-app-fill::before {
+  content: ""; }
+
+.bi-menu-app::before {
+  content: ""; }
+
+.bi-menu-button-fill::before {
+  content: ""; }
+
+.bi-menu-button-wide-fill::before {
+  content: ""; }
+
+.bi-menu-button-wide::before {
+  content: ""; }
+
+.bi-menu-button::before {
+  content: ""; }
+
+.bi-menu-down::before {
+  content: ""; }
+
+.bi-menu-up::before {
+  content: ""; }
+
+.bi-mic-fill::before {
+  content: ""; }
+
+.bi-mic-mute-fill::before {
+  content: ""; }
+
+.bi-mic-mute::before {
+  content: ""; }
+
+.bi-mic::before {
+  content: ""; }
+
+.bi-minecart-loaded::before {
+  content: ""; }
+
+.bi-minecart::before {
+  content: ""; }
+
+.bi-moisture::before {
+  content: ""; }
+
+.bi-moon-fill::before {
+  content: ""; }
+
+.bi-moon-stars-fill::before {
+  content: ""; }
+
+.bi-moon-stars::before {
+  content: ""; }
+
+.bi-moon::before {
+  content: ""; }
+
+.bi-mouse-fill::before {
+  content: ""; }
+
+.bi-mouse::before {
+  content: ""; }
+
+.bi-mouse2-fill::before {
+  content: ""; }
+
+.bi-mouse2::before {
+  content: ""; }
+
+.bi-mouse3-fill::before {
+  content: ""; }
+
+.bi-mouse3::before {
+  content: ""; }
+
+.bi-music-note-beamed::before {
+  content: ""; }
+
+.bi-music-note-list::before {
+  content: ""; }
+
+.bi-music-note::before {
+  content: ""; }
+
+.bi-music-player-fill::before {
+  content: ""; }
+
+.bi-music-player::before {
+  content: ""; }
+
+.bi-newspaper::before {
+  content: ""; }
+
+.bi-node-minus-fill::before {
+  content: ""; }
+
+.bi-node-minus::before {
+  content: ""; }
+
+.bi-node-plus-fill::before {
+  content: ""; }
+
+.bi-node-plus::before {
+  content: ""; }
+
+.bi-nut-fill::before {
+  content: ""; }
+
+.bi-nut::before {
+  content: ""; }
+
+.bi-octagon-fill::before {
+  content: ""; }
+
+.bi-octagon-half::before {
+  content: ""; }
+
+.bi-octagon::before {
+  content: ""; }
+
+.bi-option::before {
+  content: ""; }
+
+.bi-outlet::before {
+  content: ""; }
+
+.bi-paint-bucket::before {
+  content: ""; }
+
+.bi-palette-fill::before {
+  content: ""; }
+
+.bi-palette::before {
+  content: ""; }
+
+.bi-palette2::before {
+  content: ""; }
+
+.bi-paperclip::before {
+  content: ""; }
+
+.bi-paragraph::before {
+  content: ""; }
+
+.bi-patch-check-fill::before {
+  content: ""; }
+
+.bi-patch-check::before {
+  content: ""; }
+
+.bi-patch-exclamation-fill::before {
+  content: ""; }
+
+.bi-patch-exclamation::before {
+  content: ""; }
+
+.bi-patch-minus-fill::before {
+  content: ""; }
+
+.bi-patch-minus::before {
+  content: ""; }
+
+.bi-patch-plus-fill::before {
+  content: ""; }
+
+.bi-patch-plus::before {
+  content: ""; }
+
+.bi-patch-question-fill::before {
+  content: ""; }
+
+.bi-patch-question::before {
+  content: ""; }
+
+.bi-pause-btn-fill::before {
+  content: ""; }
+
+.bi-pause-btn::before {
+  content: ""; }
+
+.bi-pause-circle-fill::before {
+  content: ""; }
+
+.bi-pause-circle::before {
+  content: ""; }
+
+.bi-pause-fill::before {
+  content: ""; }
+
+.bi-pause::before {
+  content: ""; }
+
+.bi-peace-fill::before {
+  content: ""; }
+
+.bi-peace::before {
+  content: ""; }
+
+.bi-pen-fill::before {
+  content: ""; }
+
+.bi-pen::before {
+  content: ""; }
+
+.bi-pencil-fill::before {
+  content: ""; }
+
+.bi-pencil-square::before {
+  content: ""; }
+
+.bi-pencil::before {
+  content: ""; }
+
+.bi-pentagon-fill::before {
+  content: ""; }
+
+.bi-pentagon-half::before {
+  content: ""; }
+
+.bi-pentagon::before {
+  content: ""; }
+
+.bi-people-fill::before {
+  content: ""; }
+
+.bi-people::before {
+  content: ""; }
+
+.bi-percent::before {
+  content: ""; }
+
+.bi-person-badge-fill::before {
+  content: ""; }
+
+.bi-person-badge::before {
+  content: ""; }
+
+.bi-person-bounding-box::before {
+  content: ""; }
+
+.bi-person-check-fill::before {
+  content: ""; }
+
+.bi-person-check::before {
+  content: ""; }
+
+.bi-person-circle::before {
+  content: ""; }
+
+.bi-person-dash-fill::before {
+  content: ""; }
+
+.bi-person-dash::before {
+  content: ""; }
+
+.bi-person-fill::before {
+  content: ""; }
+
+.bi-person-lines-fill::before {
+  content: ""; }
+
+.bi-person-plus-fill::before {
+  content: ""; }
+
+.bi-person-plus::before {
+  content: ""; }
+
+.bi-person-square::before {
+  content: ""; }
+
+.bi-person-x-fill::before {
+  content: ""; }
+
+.bi-person-x::before {
+  content: ""; }
+
+.bi-person::before {
+  content: ""; }
+
+.bi-phone-fill::before {
+  content: ""; }
+
+.bi-phone-landscape-fill::before {
+  content: ""; }
+
+.bi-phone-landscape::before {
+  content: ""; }
+
+.bi-phone-vibrate-fill::before {
+  content: ""; }
+
+.bi-phone-vibrate::before {
+  content: ""; }
+
+.bi-phone::before {
+  content: ""; }
+
+.bi-pie-chart-fill::before {
+  content: ""; }
+
+.bi-pie-chart::before {
+  content: ""; }
+
+.bi-pin-angle-fill::before {
+  content: ""; }
+
+.bi-pin-angle::before {
+  content: ""; }
+
+.bi-pin-fill::before {
+  content: ""; }
+
+.bi-pin::before {
+  content: ""; }
+
+.bi-pip-fill::before {
+  content: ""; }
+
+.bi-pip::before {
+  content: ""; }
+
+.bi-play-btn-fill::before {
+  content: ""; }
+
+.bi-play-btn::before {
+  content: ""; }
+
+.bi-play-circle-fill::before {
+  content: ""; }
+
+.bi-play-circle::before {
+  content: ""; }
+
+.bi-play-fill::before {
+  content: ""; }
+
+.bi-play::before {
+  content: ""; }
+
+.bi-plug-fill::before {
+  content: ""; }
+
+.bi-plug::before {
+  content: ""; }
+
+.bi-plus-circle-dotted::before {
+  content: ""; }
+
+.bi-plus-circle-fill::before {
+  content: ""; }
+
+.bi-plus-circle::before {
+  content: ""; }
+
+.bi-plus-square-dotted::before {
+  content: ""; }
+
+.bi-plus-square-fill::before {
+  content: ""; }
+
+.bi-plus-square::before {
+  content: ""; }
+
+.bi-plus::before {
+  content: ""; }
+
+.bi-power::before {
+  content: ""; }
+
+.bi-printer-fill::before {
+  content: ""; }
+
+.bi-printer::before {
+  content: ""; }
+
+.bi-puzzle-fill::before {
+  content: ""; }
+
+.bi-puzzle::before {
+  content: ""; }
+
+.bi-question-circle-fill::before {
+  content: ""; }
+
+.bi-question-circle::before {
+  content: ""; }
+
+.bi-question-diamond-fill::before {
+  content: ""; }
+
+.bi-question-diamond::before {
+  content: ""; }
+
+.bi-question-octagon-fill::before {
+  content: ""; }
+
+.bi-question-octagon::before {
+  content: ""; }
+
+.bi-question-square-fill::before {
+  content: ""; }
+
+.bi-question-square::before {
+  content: ""; }
+
+.bi-question::before {
+  content: ""; }
+
+.bi-rainbow::before {
+  content: ""; }
+
+.bi-receipt-cutoff::before {
+  content: ""; }
+
+.bi-receipt::before {
+  content: ""; }
+
+.bi-reception-0::before {
+  content: ""; }
+
+.bi-reception-1::before {
+  content: ""; }
+
+.bi-reception-2::before {
+  content: ""; }
+
+.bi-reception-3::before {
+  content: ""; }
+
+.bi-reception-4::before {
+  content: ""; }
+
+.bi-record-btn-fill::before {
+  content: ""; }
+
+.bi-record-btn::before {
+  content: ""; }
+
+.bi-record-circle-fill::before {
+  content: ""; }
+
+.bi-record-circle::before {
+  content: ""; }
+
+.bi-record-fill::before {
+  content: ""; }
+
+.bi-record::before {
+  content: ""; }
+
+.bi-record2-fill::before {
+  content: ""; }
+
+.bi-record2::before {
+  content: ""; }
+
+.bi-reply-all-fill::before {
+  content: ""; }
+
+.bi-reply-all::before {
+  content: ""; }
+
+.bi-reply-fill::before {
+  content: ""; }
+
+.bi-reply::before {
+  content: ""; }
+
+.bi-rss-fill::before {
+  content: ""; }
+
+.bi-rss::before {
+  content: ""; }
+
+.bi-rulers::before {
+  content: ""; }
+
+.bi-save-fill::before {
+  content: ""; }
+
+.bi-save::before {
+  content: ""; }
+
+.bi-save2-fill::before {
+  content: ""; }
+
+.bi-save2::before {
+  content: ""; }
+
+.bi-scissors::before {
+  content: ""; }
+
+.bi-screwdriver::before {
+  content: ""; }
+
+.bi-search::before {
+  content: ""; }
+
+.bi-segmented-nav::before {
+  content: ""; }
+
+.bi-server::before {
+  content: ""; }
+
+.bi-share-fill::before {
+  content: ""; }
+
+.bi-share::before {
+  content: ""; }
+
+.bi-shield-check::before {
+  content: ""; }
+
+.bi-shield-exclamation::before {
+  content: ""; }
+
+.bi-shield-fill-check::before {
+  content: ""; }
+
+.bi-shield-fill-exclamation::before {
+  content: ""; }
+
+.bi-shield-fill-minus::before {
+  content: ""; }
+
+.bi-shield-fill-plus::before {
+  content: ""; }
+
+.bi-shield-fill-x::before {
+  content: ""; }
+
+.bi-shield-fill::before {
+  content: ""; }
+
+.bi-shield-lock-fill::before {
+  content: ""; }
+
+.bi-shield-lock::before {
+  content: ""; }
+
+.bi-shield-minus::before {
+  content: ""; }
+
+.bi-shield-plus::before {
+  content: ""; }
+
+.bi-shield-shaded::before {
+  content: ""; }
+
+.bi-shield-slash-fill::before {
+  content: ""; }
+
+.bi-shield-slash::before {
+  content: ""; }
+
+.bi-shield-x::before {
+  content: ""; }
+
+.bi-shield::before {
+  content: ""; }
+
+.bi-shift-fill::before {
+  content: ""; }
+
+.bi-shift::before {
+  content: ""; }
+
+.bi-shop-window::before {
+  content: ""; }
+
+.bi-shop::before {
+  content: ""; }
+
+.bi-shuffle::before {
+  content: ""; }
+
+.bi-signpost-2-fill::before {
+  content: ""; }
+
+.bi-signpost-2::before {
+  content: ""; }
+
+.bi-signpost-fill::before {
+  content: ""; }
+
+.bi-signpost-split-fill::before {
+  content: ""; }
+
+.bi-signpost-split::before {
+  content: ""; }
+
+.bi-signpost::before {
+  content: ""; }
+
+.bi-sim-fill::before {
+  content: ""; }
+
+.bi-sim::before {
+  content: ""; }
+
+.bi-skip-backward-btn-fill::before {
+  content: ""; }
+
+.bi-skip-backward-btn::before {
+  content: ""; }
+
+.bi-skip-backward-circle-fill::before {
+  content: ""; }
+
+.bi-skip-backward-circle::before {
+  content: ""; }
+
+.bi-skip-backward-fill::before {
+  content: ""; }
+
+.bi-skip-backward::before {
+  content: ""; }
+
+.bi-skip-end-btn-fill::before {
+  content: ""; }
+
+.bi-skip-end-btn::before {
+  content: ""; }
+
+.bi-skip-end-circle-fill::before {
+  content: ""; }
+
+.bi-skip-end-circle::before {
+  content: ""; }
+
+.bi-skip-end-fill::before {
+  content: ""; }
+
+.bi-skip-end::before {
+  content: ""; }
+
+.bi-skip-forward-btn-fill::before {
+  content: ""; }
+
+.bi-skip-forward-btn::before {
+  content: ""; }
+
+.bi-skip-forward-circle-fill::before {
+  content: ""; }
+
+.bi-skip-forward-circle::before {
+  content: ""; }
+
+.bi-skip-forward-fill::before {
+  content: ""; }
+
+.bi-skip-forward::before {
+  content: ""; }
+
+.bi-skip-start-btn-fill::before {
+  content: ""; }
+
+.bi-skip-start-btn::before {
+  content: ""; }
+
+.bi-skip-start-circle-fill::before {
+  content: ""; }
+
+.bi-skip-start-circle::before {
+  content: ""; }
+
+.bi-skip-start-fill::before {
+  content: ""; }
+
+.bi-skip-start::before {
+  content: ""; }
+
+.bi-slack::before {
+  content: ""; }
+
+.bi-slash-circle-fill::before {
+  content: ""; }
+
+.bi-slash-circle::before {
+  content: ""; }
+
+.bi-slash-square-fill::before {
+  content: ""; }
+
+.bi-slash-square::before {
+  content: ""; }
+
+.bi-slash::before {
+  content: ""; }
+
+.bi-sliders::before {
+  content: ""; }
+
+.bi-smartwatch::before {
+  content: ""; }
+
+.bi-snow::before {
+  content: ""; }
+
+.bi-snow2::before {
+  content: ""; }
+
+.bi-snow3::before {
+  content: ""; }
+
+.bi-sort-alpha-down-alt::before {
+  content: ""; }
+
+.bi-sort-alpha-down::before {
+  content: ""; }
+
+.bi-sort-alpha-up-alt::before {
+  content: ""; }
+
+.bi-sort-alpha-up::before {
+  content: ""; }
+
+.bi-sort-down-alt::before {
+  content: ""; }
+
+.bi-sort-down::before {
+  content: ""; }
+
+.bi-sort-numeric-down-alt::before {
+  content: ""; }
+
+.bi-sort-numeric-down::before {
+  content: ""; }
+
+.bi-sort-numeric-up-alt::before {
+  content: ""; }
+
+.bi-sort-numeric-up::before {
+  content: ""; }
+
+.bi-sort-up-alt::before {
+  content: ""; }
+
+.bi-sort-up::before {
+  content: ""; }
+
+.bi-soundwave::before {
+  content: ""; }
+
+.bi-speaker-fill::before {
+  content: ""; }
+
+.bi-speaker::before {
+  content: ""; }
+
+.bi-speedometer::before {
+  content: ""; }
+
+.bi-speedometer2::before {
+  content: ""; }
+
+.bi-spellcheck::before {
+  content: ""; }
+
+.bi-square-fill::before {
+  content: ""; }
+
+.bi-square-half::before {
+  content: ""; }
+
+.bi-square::before {
+  content: ""; }
+
+.bi-stack::before {
+  content: ""; }
+
+.bi-star-fill::before {
+  content: ""; }
+
+.bi-star-half::before {
+  content: ""; }
+
+.bi-star::before {
+  content: ""; }
+
+.bi-stars::before {
+  content: ""; }
+
+.bi-stickies-fill::before {
+  content: ""; }
+
+.bi-stickies::before {
+  content: ""; }
+
+.bi-sticky-fill::before {
+  content: ""; }
+
+.bi-sticky::before {
+  content: ""; }
+
+.bi-stop-btn-fill::before {
+  content: ""; }
+
+.bi-stop-btn::before {
+  content: ""; }
+
+.bi-stop-circle-fill::before {
+  content: ""; }
+
+.bi-stop-circle::before {
+  content: ""; }
+
+.bi-stop-fill::before {
+  content: ""; }
+
+.bi-stop::before {
+  content: ""; }
+
+.bi-stoplights-fill::before {
+  content: ""; }
+
+.bi-stoplights::before {
+  content: ""; }
+
+.bi-stopwatch-fill::before {
+  content: ""; }
+
+.bi-stopwatch::before {
+  content: ""; }
+
+.bi-subtract::before {
+  content: ""; }
+
+.bi-suit-club-fill::before {
+  content: ""; }
+
+.bi-suit-club::before {
+  content: ""; }
+
+.bi-suit-diamond-fill::before {
+  content: ""; }
+
+.bi-suit-diamond::before {
+  content: ""; }
+
+.bi-suit-heart-fill::before {
+  content: ""; }
+
+.bi-suit-heart::before {
+  content: ""; }
+
+.bi-suit-spade-fill::before {
+  content: ""; }
+
+.bi-suit-spade::before {
+  content: ""; }
+
+.bi-sun-fill::before {
+  content: ""; }
+
+.bi-sun::before {
+  content: ""; }
+
+.bi-sunglasses::before {
+  content: ""; }
+
+.bi-sunrise-fill::before {
+  content: ""; }
+
+.bi-sunrise::before {
+  content: ""; }
+
+.bi-sunset-fill::before {
+  content: ""; }
+
+.bi-sunset::before {
+  content: ""; }
+
+.bi-symmetry-horizontal::before {
+  content: ""; }
+
+.bi-symmetry-vertical::before {
+  content: ""; }
+
+.bi-table::before {
+  content: ""; }
+
+.bi-tablet-fill::before {
+  content: ""; }
+
+.bi-tablet-landscape-fill::before {
+  content: ""; }
+
+.bi-tablet-landscape::before {
+  content: ""; }
+
+.bi-tablet::before {
+  content: ""; }
+
+.bi-tag-fill::before {
+  content: ""; }
+
+.bi-tag::before {
+  content: ""; }
+
+.bi-tags-fill::before {
+  content: ""; }
+
+.bi-tags::before {
+  content: ""; }
+
+.bi-telegram::before {
+  content: ""; }
+
+.bi-telephone-fill::before {
+  content: ""; }
+
+.bi-telephone-forward-fill::before {
+  content: ""; }
+
+.bi-telephone-forward::before {
+  content: ""; }
+
+.bi-telephone-inbound-fill::before {
+  content: ""; }
+
+.bi-telephone-inbound::before {
+  content: ""; }
+
+.bi-telephone-minus-fill::before {
+  content: ""; }
+
+.bi-telephone-minus::before {
+  content: ""; }
+
+.bi-telephone-outbound-fill::before {
+  content: ""; }
+
+.bi-telephone-outbound::before {
+  content: ""; }
+
+.bi-telephone-plus-fill::before {
+  content: ""; }
+
+.bi-telephone-plus::before {
+  content: ""; }
+
+.bi-telephone-x-fill::before {
+  content: ""; }
+
+.bi-telephone-x::before {
+  content: ""; }
+
+.bi-telephone::before {
+  content: ""; }
+
+.bi-terminal-fill::before {
+  content: ""; }
+
+.bi-terminal::before {
+  content: ""; }
+
+.bi-text-center::before {
+  content: ""; }
+
+.bi-text-indent-left::before {
+  content: ""; }
+
+.bi-text-indent-right::before {
+  content: ""; }
+
+.bi-text-left::before {
+  content: ""; }
+
+.bi-text-paragraph::before {
+  content: ""; }
+
+.bi-text-right::before {
+  content: ""; }
+
+.bi-textarea-resize::before {
+  content: ""; }
+
+.bi-textarea-t::before {
+  content: ""; }
+
+.bi-textarea::before {
+  content: ""; }
+
+.bi-thermometer-half::before {
+  content: ""; }
+
+.bi-thermometer-high::before {
+  content: ""; }
+
+.bi-thermometer-low::before {
+  content: ""; }
+
+.bi-thermometer-snow::before {
+  content: ""; }
+
+.bi-thermometer-sun::before {
+  content: ""; }
+
+.bi-thermometer::before {
+  content: ""; }
+
+.bi-three-dots-vertical::before {
+  content: ""; }
+
+.bi-three-dots::before {
+  content: ""; }
+
+.bi-toggle-off::before {
+  content: ""; }
+
+.bi-toggle-on::before {
+  content: ""; }
+
+.bi-toggle2-off::before {
+  content: ""; }
+
+.bi-toggle2-on::before {
+  content: ""; }
+
+.bi-toggles::before {
+  content: ""; }
+
+.bi-toggles2::before {
+  content: ""; }
+
+.bi-tools::before {
+  content: ""; }
+
+.bi-tornado::before {
+  content: ""; }
+
+.bi-trash-fill::before {
+  content: ""; }
+
+.bi-trash::before {
+  content: ""; }
+
+.bi-trash2-fill::before {
+  content: ""; }
+
+.bi-trash2::before {
+  content: ""; }
+
+.bi-tree-fill::before {
+  content: ""; }
+
+.bi-tree::before {
+  content: ""; }
+
+.bi-triangle-fill::before {
+  content: ""; }
+
+.bi-triangle-half::before {
+  content: ""; }
+
+.bi-triangle::before {
+  content: ""; }
+
+.bi-trophy-fill::before {
+  content: ""; }
+
+.bi-trophy::before {
+  content: ""; }
+
+.bi-tropical-storm::before {
+  content: ""; }
+
+.bi-truck-flatbed::before {
+  content: ""; }
+
+.bi-truck::before {
+  content: ""; }
+
+.bi-tsunami::before {
+  content: ""; }
+
+.bi-tv-fill::before {
+  content: ""; }
+
+.bi-tv::before {
+  content: ""; }
+
+.bi-twitch::before {
+  content: ""; }
+
+.bi-twitter::before {
+  content: ""; }
+
+.bi-type-bold::before {
+  content: ""; }
+
+.bi-type-h1::before {
+  content: ""; }
+
+.bi-type-h2::before {
+  content: ""; }
+
+.bi-type-h3::before {
+  content: ""; }
+
+.bi-type-italic::before {
+  content: ""; }
+
+.bi-type-strikethrough::before {
+  content: ""; }
+
+.bi-type-underline::before {
+  content: ""; }
+
+.bi-type::before {
+  content: ""; }
+
+.bi-ui-checks-grid::before {
+  content: ""; }
+
+.bi-ui-checks::before {
+  content: ""; }
+
+.bi-ui-radios-grid::before {
+  content: ""; }
+
+.bi-ui-radios::before {
+  content: ""; }
+
+.bi-umbrella-fill::before {
+  content: ""; }
+
+.bi-umbrella::before {
+  content: ""; }
+
+.bi-union::before {
+  content: ""; }
+
+.bi-unlock-fill::before {
+  content: ""; }
+
+.bi-unlock::before {
+  content: ""; }
+
+.bi-upc-scan::before {
+  content: ""; }
+
+.bi-upc::before {
+  content: ""; }
+
+.bi-upload::before {
+  content: ""; }
+
+.bi-vector-pen::before {
+  content: ""; }
+
+.bi-view-list::before {
+  content: ""; }
+
+.bi-view-stacked::before {
+  content: ""; }
+
+.bi-vinyl-fill::before {
+  content: ""; }
+
+.bi-vinyl::before {
+  content: ""; }
+
+.bi-voicemail::before {
+  content: ""; }
+
+.bi-volume-down-fill::before {
+  content: ""; }
+
+.bi-volume-down::before {
+  content: ""; }
+
+.bi-volume-mute-fill::before {
+  content: ""; }
+
+.bi-volume-mute::before {
+  content: ""; }
+
+.bi-volume-off-fill::before {
+  content: ""; }
+
+.bi-volume-off::before {
+  content: ""; }
+
+.bi-volume-up-fill::before {
+  content: ""; }
+
+.bi-volume-up::before {
+  content: ""; }
+
+.bi-vr::before {
+  content: ""; }
+
+.bi-wallet-fill::before {
+  content: ""; }
+
+.bi-wallet::before {
+  content: ""; }
+
+.bi-wallet2::before {
+  content: ""; }
+
+.bi-watch::before {
+  content: ""; }
+
+.bi-water::before {
+  content: ""; }
+
+.bi-whatsapp::before {
+  content: ""; }
+
+.bi-wifi-1::before {
+  content: ""; }
+
+.bi-wifi-2::before {
+  content: ""; }
+
+.bi-wifi-off::before {
+  content: ""; }
+
+.bi-wifi::before {
+  content: ""; }
+
+.bi-wind::before {
+  content: ""; }
+
+.bi-window-dock::before {
+  content: ""; }
+
+.bi-window-sidebar::before {
+  content: ""; }
+
+.bi-window::before {
+  content: ""; }
+
+.bi-wrench::before {
+  content: ""; }
+
+.bi-x-circle-fill::before {
+  content: ""; }
+
+.bi-x-circle::before {
+  content: ""; }
+
+.bi-x-diamond-fill::before {
+  content: ""; }
+
+.bi-x-diamond::before {
+  content: ""; }
+
+.bi-x-octagon-fill::before {
+  content: ""; }
+
+.bi-x-octagon::before {
+  content: ""; }
+
+.bi-x-square-fill::before {
+  content: ""; }
+
+.bi-x-square::before {
+  content: ""; }
+
+.bi-x::before {
+  content: ""; }
+
+.bi-youtube::before {
+  content: ""; }
+
+.bi-zoom-in::before {
+  content: ""; }
+
+.bi-zoom-out::before {
+  content: ""; }
+
+.bi-bank::before {
+  content: ""; }
+
+.bi-bank2::before {
+  content: ""; }
+
+.bi-bell-slash-fill::before {
+  content: ""; }
+
+.bi-bell-slash::before {
+  content: ""; }
+
+.bi-cash-coin::before {
+  content: ""; }
+
+.bi-check-lg::before {
+  content: ""; }
+
+.bi-coin::before {
+  content: ""; }
+
+.bi-currency-bitcoin::before {
+  content: ""; }
+
+.bi-currency-dollar::before {
+  content: ""; }
+
+.bi-currency-euro::before {
+  content: ""; }
+
+.bi-currency-exchange::before {
+  content: ""; }
+
+.bi-currency-pound::before {
+  content: ""; }
+
+.bi-currency-yen::before {
+  content: ""; }
+
+.bi-dash-lg::before {
+  content: ""; }
+
+.bi-exclamation-lg::before {
+  content: ""; }
+
+.bi-file-earmark-pdf-fill::before {
+  content: ""; }
+
+.bi-file-earmark-pdf::before {
+  content: ""; }
+
+.bi-file-pdf-fill::before {
+  content: ""; }
+
+.bi-file-pdf::before {
+  content: ""; }
+
+.bi-gender-ambiguous::before {
+  content: ""; }
+
+.bi-gender-female::before {
+  content: ""; }
+
+.bi-gender-male::before {
+  content: ""; }
+
+.bi-gender-trans::before {
+  content: ""; }
+
+.bi-headset-vr::before {
+  content: ""; }
+
+.bi-info-lg::before {
+  content: ""; }
+
+.bi-mastodon::before {
+  content: ""; }
+
+.bi-messenger::before {
+  content: ""; }
+
+.bi-piggy-bank-fill::before {
+  content: ""; }
+
+.bi-piggy-bank::before {
+  content: ""; }
+
+.bi-pin-map-fill::before {
+  content: ""; }
+
+.bi-pin-map::before {
+  content: ""; }
+
+.bi-plus-lg::before {
+  content: ""; }
+
+.bi-question-lg::before {
+  content: ""; }
+
+.bi-recycle::before {
+  content: ""; }
+
+.bi-reddit::before {
+  content: ""; }
+
+.bi-safe-fill::before {
+  content: ""; }
+
+.bi-safe2-fill::before {
+  content: ""; }
+
+.bi-safe2::before {
+  content: ""; }
+
+.bi-sd-card-fill::before {
+  content: ""; }
+
+.bi-sd-card::before {
+  content: ""; }
+
+.bi-skype::before {
+  content: ""; }
+
+.bi-slash-lg::before {
+  content: ""; }
+
+.bi-translate::before {
+  content: ""; }
+
+.bi-x-lg::before {
+  content: ""; }
+
+.bi-safe::before {
+  content: ""; }
+
+.bi-apple::before {
+  content: ""; }
+
+.bi-microsoft::before {
+  content: ""; }
+
+.bi-windows::before {
+  content: ""; }
+
+.bi-behance::before {
+  content: ""; }
+
+.bi-dribbble::before {
+  content: ""; }
+
+.bi-line::before {
+  content: ""; }
+
+.bi-medium::before {
+  content: ""; }
+
+.bi-paypal::before {
+  content: ""; }
+
+.bi-pinterest::before {
+  content: ""; }
+
+.bi-signal::before {
+  content: ""; }
+
+.bi-snapchat::before {
+  content: ""; }
+
+.bi-spotify::before {
+  content: ""; }
+
+.bi-stack-overflow::before {
+  content: ""; }
+
+.bi-strava::before {
+  content: ""; }
+
+.bi-wordpress::before {
+  content: ""; }
+
+.bi-vimeo::before {
+  content: ""; }
+
+.bi-activity::before {
+  content: ""; }
+
+.bi-easel2-fill::before {
+  content: ""; }
+
+.bi-easel2::before {
+  content: ""; }
+
+.bi-easel3-fill::before {
+  content: ""; }
+
+.bi-easel3::before {
+  content: ""; }
+
+.bi-fan::before {
+  content: ""; }
+
+.bi-fingerprint::before {
+  content: ""; }
+
+.bi-graph-down-arrow::before {
+  content: ""; }
+
+.bi-graph-up-arrow::before {
+  content: ""; }
+
+.bi-hypnotize::before {
+  content: ""; }
+
+.bi-magic::before {
+  content: ""; }
+
+.bi-person-rolodex::before {
+  content: ""; }
+
+.bi-person-video::before {
+  content: ""; }
+
+.bi-person-video2::before {
+  content: ""; }
+
+.bi-person-video3::before {
+  content: ""; }
+
+.bi-person-workspace::before {
+  content: ""; }
+
+.bi-radioactive::before {
+  content: ""; }
+
+.bi-webcam-fill::before {
+  content: ""; }
+
+.bi-webcam::before {
+  content: ""; }
+
+.bi-yin-yang::before {
+  content: ""; }
+
+.bi-bandaid-fill::before {
+  content: ""; }
+
+.bi-bandaid::before {
+  content: ""; }
+
+.bi-bluetooth::before {
+  content: ""; }
+
+.bi-body-text::before {
+  content: ""; }
+
+.bi-boombox::before {
+  content: ""; }
+
+.bi-boxes::before {
+  content: ""; }
+
+.bi-dpad-fill::before {
+  content: ""; }
+
+.bi-dpad::before {
+  content: ""; }
+
+.bi-ear-fill::before {
+  content: ""; }
+
+.bi-ear::before {
+  content: ""; }
+
+.bi-envelope-check-fill::before {
+  content: ""; }
+
+.bi-envelope-check::before {
+  content: ""; }
+
+.bi-envelope-dash-fill::before {
+  content: ""; }
+
+.bi-envelope-dash::before {
+  content: ""; }
+
+.bi-envelope-exclamation-fill::before {
+  content: ""; }
+
+.bi-envelope-exclamation::before {
+  content: ""; }
+
+.bi-envelope-plus-fill::before {
+  content: ""; }
+
+.bi-envelope-plus::before {
+  content: ""; }
+
+.bi-envelope-slash-fill::before {
+  content: ""; }
+
+.bi-envelope-slash::before {
+  content: ""; }
+
+.bi-envelope-x-fill::before {
+  content: ""; }
+
+.bi-envelope-x::before {
+  content: ""; }
+
+.bi-explicit-fill::before {
+  content: ""; }
+
+.bi-explicit::before {
+  content: ""; }
+
+.bi-git::before {
+  content: ""; }
+
+.bi-infinity::before {
+  content: ""; }
+
+.bi-list-columns-reverse::before {
+  content: ""; }
+
+.bi-list-columns::before {
+  content: ""; }
+
+.bi-meta::before {
+  content: ""; }
+
+.bi-nintendo-switch::before {
+  content: ""; }
+
+.bi-pc-display-horizontal::before {
+  content: ""; }
+
+.bi-pc-display::before {
+  content: ""; }
+
+.bi-pc-horizontal::before {
+  content: ""; }
+
+.bi-pc::before {
+  content: ""; }
+
+.bi-playstation::before {
+  content: ""; }
+
+.bi-plus-slash-minus::before {
+  content: ""; }
+
+.bi-projector-fill::before {
+  content: ""; }
+
+.bi-projector::before {
+  content: ""; }
+
+.bi-qr-code-scan::before {
+  content: ""; }
+
+.bi-qr-code::before {
+  content: ""; }
+
+.bi-quora::before {
+  content: ""; }
+
+.bi-quote::before {
+  content: ""; }
+
+.bi-robot::before {
+  content: ""; }
+
+.bi-send-check-fill::before {
+  content: ""; }
+
+.bi-send-check::before {
+  content: ""; }
+
+.bi-send-dash-fill::before {
+  content: ""; }
+
+.bi-send-dash::before {
+  content: ""; }
+
+.bi-send-exclamation-fill::before {
+  content: ""; }
+
+.bi-send-exclamation::before {
+  content: ""; }
+
+.bi-send-fill::before {
+  content: ""; }
+
+.bi-send-plus-fill::before {
+  content: ""; }
+
+.bi-send-plus::before {
+  content: ""; }
+
+.bi-send-slash-fill::before {
+  content: ""; }
+
+.bi-send-slash::before {
+  content: ""; }
+
+.bi-send-x-fill::before {
+  content: ""; }
+
+.bi-send-x::before {
+  content: ""; }
+
+.bi-send::before {
+  content: ""; }
+
+.bi-steam::before {
+  content: ""; }
+
+.bi-terminal-dash::before {
+  content: ""; }
+
+.bi-terminal-plus::before {
+  content: ""; }
+
+.bi-terminal-split::before {
+  content: ""; }
+
+.bi-ticket-detailed-fill::before {
+  content: ""; }
+
+.bi-ticket-detailed::before {
+  content: ""; }
+
+.bi-ticket-fill::before {
+  content: ""; }
+
+.bi-ticket-perforated-fill::before {
+  content: ""; }
+
+.bi-ticket-perforated::before {
+  content: ""; }
+
+.bi-ticket::before {
+  content: ""; }
+
+.bi-tiktok::before {
+  content: ""; }
+
+.bi-window-dash::before {
+  content: ""; }
+
+.bi-window-desktop::before {
+  content: ""; }
+
+.bi-window-fullscreen::before {
+  content: ""; }
+
+.bi-window-plus::before {
+  content: ""; }
+
+.bi-window-split::before {
+  content: ""; }
+
+.bi-window-stack::before {
+  content: ""; }
+
+.bi-window-x::before {
+  content: ""; }
+
+.bi-xbox::before {
+  content: ""; }
+
+.bi-ethernet::before {
+  content: ""; }
+
+.bi-hdmi-fill::before {
+  content: ""; }
+
+.bi-hdmi::before {
+  content: ""; }
+
+.bi-usb-c-fill::before {
+  content: ""; }
+
+.bi-usb-c::before {
+  content: ""; }
+
+.bi-usb-fill::before {
+  content: ""; }
+
+.bi-usb-plug-fill::before {
+  content: ""; }
+
+.bi-usb-plug::before {
+  content: ""; }
+
+.bi-usb-symbol::before {
+  content: ""; }
+
+.bi-usb::before {
+  content: ""; }
+
+.bi-boombox-fill::before {
+  content: ""; }
+
+.bi-displayport::before {
+  content: ""; }
+
+.bi-gpu-card::before {
+  content: ""; }
+
+.bi-memory::before {
+  content: ""; }
+
+.bi-modem-fill::before {
+  content: ""; }
+
+.bi-modem::before {
+  content: ""; }
+
+.bi-motherboard-fill::before {
+  content: ""; }
+
+.bi-motherboard::before {
+  content: ""; }
+
+.bi-optical-audio-fill::before {
+  content: ""; }
+
+.bi-optical-audio::before {
+  content: ""; }
+
+.bi-pci-card::before {
+  content: ""; }
+
+.bi-router-fill::before {
+  content: ""; }
+
+.bi-router::before {
+  content: ""; }
+
+.bi-thunderbolt-fill::before {
+  content: ""; }
+
+.bi-thunderbolt::before {
+  content: ""; }
+
+.bi-usb-drive-fill::before {
+  content: ""; }
+
+.bi-usb-drive::before {
+  content: ""; }
+
+.bi-usb-micro-fill::before {
+  content: ""; }
+
+.bi-usb-micro::before {
+  content: ""; }
+
+.bi-usb-mini-fill::before {
+  content: ""; }
+
+.bi-usb-mini::before {
+  content: ""; }
+
+.bi-cloud-haze2::before {
+  content: ""; }
+
+.bi-device-hdd-fill::before {
+  content: ""; }
+
+.bi-device-hdd::before {
+  content: ""; }
+
+.bi-device-ssd-fill::before {
+  content: ""; }
+
+.bi-device-ssd::before {
+  content: ""; }
+
+.bi-displayport-fill::before {
+  content: ""; }
+
+.bi-mortarboard-fill::before {
+  content: ""; }
+
+.bi-mortarboard::before {
+  content: ""; }
+
+.bi-terminal-x::before {
+  content: ""; }
+
+.bi-arrow-through-heart-fill::before {
+  content: ""; }
+
+.bi-arrow-through-heart::before {
+  content: ""; }
+
+.bi-badge-sd-fill::before {
+  content: ""; }
+
+.bi-badge-sd::before {
+  content: ""; }
+
+.bi-bag-heart-fill::before {
+  content: ""; }
+
+.bi-bag-heart::before {
+  content: ""; }
+
+.bi-balloon-fill::before {
+  content: ""; }
+
+.bi-balloon-heart-fill::before {
+  content: ""; }
+
+.bi-balloon-heart::before {
+  content: ""; }
+
+.bi-balloon::before {
+  content: ""; }
+
+.bi-box2-fill::before {
+  content: ""; }
+
+.bi-box2-heart-fill::before {
+  content: ""; }
+
+.bi-box2-heart::before {
+  content: ""; }
+
+.bi-box2::before {
+  content: ""; }
+
+.bi-braces-asterisk::before {
+  content: ""; }
+
+.bi-calendar-heart-fill::before {
+  content: ""; }
+
+.bi-calendar-heart::before {
+  content: ""; }
+
+.bi-calendar2-heart-fill::before {
+  content: ""; }
+
+.bi-calendar2-heart::before {
+  content: ""; }
+
+.bi-chat-heart-fill::before {
+  content: ""; }
+
+.bi-chat-heart::before {
+  content: ""; }
+
+.bi-chat-left-heart-fill::before {
+  content: ""; }
+
+.bi-chat-left-heart::before {
+  content: ""; }
+
+.bi-chat-right-heart-fill::before {
+  content: ""; }
+
+.bi-chat-right-heart::before {
+  content: ""; }
+
+.bi-chat-square-heart-fill::before {
+  content: ""; }
+
+.bi-chat-square-heart::before {
+  content: ""; }
+
+.bi-clipboard-check-fill::before {
+  content: ""; }
+
+.bi-clipboard-data-fill::before {
+  content: ""; }
+
+.bi-clipboard-fill::before {
+  content: ""; }
+
+.bi-clipboard-heart-fill::before {
+  content: ""; }
+
+.bi-clipboard-heart::before {
+  content: ""; }
+
+.bi-clipboard-minus-fill::before {
+  content: ""; }
+
+.bi-clipboard-plus-fill::before {
+  content: ""; }
+
+.bi-clipboard-pulse::before {
+  content: ""; }
+
+.bi-clipboard-x-fill::before {
+  content: ""; }
+
+.bi-clipboard2-check-fill::before {
+  content: ""; }
+
+.bi-clipboard2-check::before {
+  content: ""; }
+
+.bi-clipboard2-data-fill::before {
+  content: ""; }
+
+.bi-clipboard2-data::before {
+  content: ""; }
+
+.bi-clipboard2-fill::before {
+  content: ""; }
+
+.bi-clipboard2-heart-fill::before {
+  content: ""; }
+
+.bi-clipboard2-heart::before {
+  content: ""; }
+
+.bi-clipboard2-minus-fill::before {
+  content: ""; }
+
+.bi-clipboard2-minus::before {
+  content: ""; }
+
+.bi-clipboard2-plus-fill::before {
+  content: ""; }
+
+.bi-clipboard2-plus::before {
+  content: ""; }
+
+.bi-clipboard2-pulse-fill::before {
+  content: ""; }
+
+.bi-clipboard2-pulse::before {
+  content: ""; }
+
+.bi-clipboard2-x-fill::before {
+  content: ""; }
+
+.bi-clipboard2-x::before {
+  content: ""; }
+
+.bi-clipboard2::before {
+  content: ""; }
+
+.bi-emoji-kiss-fill::before {
+  content: ""; }
+
+.bi-emoji-kiss::before {
+  content: ""; }
+
+.bi-envelope-heart-fill::before {
+  content: ""; }
+
+.bi-envelope-heart::before {
+  content: ""; }
+
+.bi-envelope-open-heart-fill::before {
+  content: ""; }
+
+.bi-envelope-open-heart::before {
+  content: ""; }
+
+.bi-envelope-paper-fill::before {
+  content: ""; }
+
+.bi-envelope-paper-heart-fill::before {
+  content: ""; }
+
+.bi-envelope-paper-heart::before {
+  content: ""; }
+
+.bi-envelope-paper::before {
+  content: ""; }
+
+.bi-filetype-aac::before {
+  content: ""; }
+
+.bi-filetype-ai::before {
+  content: ""; }
+
+.bi-filetype-bmp::before {
+  content: ""; }
+
+.bi-filetype-cs::before {
+  content: ""; }
+
+.bi-filetype-css::before {
+  content: ""; }
+
+.bi-filetype-csv::before {
+  content: ""; }
+
+.bi-filetype-doc::before {
+  content: ""; }
+
+.bi-filetype-docx::before {
+  content: ""; }
+
+.bi-filetype-exe::before {
+  content: ""; }
+
+.bi-filetype-gif::before {
+  content: ""; }
+
+.bi-filetype-heic::before {
+  content: ""; }
+
+.bi-filetype-html::before {
+  content: ""; }
+
+.bi-filetype-java::before {
+  content: ""; }
+
+.bi-filetype-jpg::before {
+  content: ""; }
+
+.bi-filetype-js::before {
+  content: ""; }
+
+.bi-filetype-jsx::before {
+  content: ""; }
+
+.bi-filetype-key::before {
+  content: ""; }
+
+.bi-filetype-m4p::before {
+  content: ""; }
+
+.bi-filetype-md::before {
+  content: ""; }
+
+.bi-filetype-mdx::before {
+  content: ""; }
+
+.bi-filetype-mov::before {
+  content: ""; }
+
+.bi-filetype-mp3::before {
+  content: ""; }
+
+.bi-filetype-mp4::before {
+  content: ""; }
+
+.bi-filetype-otf::before {
+  content: ""; }
+
+.bi-filetype-pdf::before {
+  content: ""; }
+
+.bi-filetype-php::before {
+  content: ""; }
+
+.bi-filetype-png::before {
+  content: ""; }
+
+.bi-filetype-ppt::before {
+  content: ""; }
+
+.bi-filetype-psd::before {
+  content: ""; }
+
+.bi-filetype-py::before {
+  content: ""; }
+
+.bi-filetype-raw::before {
+  content: ""; }
+
+.bi-filetype-rb::before {
+  content: ""; }
+
+.bi-filetype-sass::before {
+  content: ""; }
+
+.bi-filetype-scss::before {
+  content: ""; }
+
+.bi-filetype-sh::before {
+  content: ""; }
+
+.bi-filetype-svg::before {
+  content: ""; }
+
+.bi-filetype-tiff::before {
+  content: ""; }
+
+.bi-filetype-tsx::before {
+  content: ""; }
+
+.bi-filetype-ttf::before {
+  content: ""; }
+
+.bi-filetype-txt::before {
+  content: ""; }
+
+.bi-filetype-wav::before {
+  content: ""; }
+
+.bi-filetype-woff::before {
+  content: ""; }
+
+.bi-filetype-xls::before {
+  content: ""; }
+
+.bi-filetype-xml::before {
+  content: ""; }
+
+.bi-filetype-yml::before {
+  content: ""; }
+
+.bi-heart-arrow::before {
+  content: ""; }
+
+.bi-heart-pulse-fill::before {
+  content: ""; }
+
+.bi-heart-pulse::before {
+  content: ""; }
+
+.bi-heartbreak-fill::before {
+  content: ""; }
+
+.bi-heartbreak::before {
+  content: ""; }
+
+.bi-hearts::before {
+  content: ""; }
+
+.bi-hospital-fill::before {
+  content: ""; }
+
+.bi-hospital::before {
+  content: ""; }
+
+.bi-house-heart-fill::before {
+  content: ""; }
+
+.bi-house-heart::before {
+  content: ""; }
+
+.bi-incognito::before {
+  content: ""; }
+
+.bi-magnet-fill::before {
+  content: ""; }
+
+.bi-magnet::before {
+  content: ""; }
+
+.bi-person-heart::before {
+  content: ""; }
+
+.bi-person-hearts::before {
+  content: ""; }
+
+.bi-phone-flip::before {
+  content: ""; }
+
+.bi-plugin::before {
+  content: ""; }
+
+.bi-postage-fill::before {
+  content: ""; }
+
+.bi-postage-heart-fill::before {
+  content: ""; }
+
+.bi-postage-heart::before {
+  content: ""; }
+
+.bi-postage::before {
+  content: ""; }
+
+.bi-postcard-fill::before {
+  content: ""; }
+
+.bi-postcard-heart-fill::before {
+  content: ""; }
+
+.bi-postcard-heart::before {
+  content: ""; }
+
+.bi-postcard::before {
+  content: ""; }
+
+.bi-search-heart-fill::before {
+  content: ""; }
+
+.bi-search-heart::before {
+  content: ""; }
+
+.bi-sliders2-vertical::before {
+  content: ""; }
+
+.bi-sliders2::before {
+  content: ""; }
+
+.bi-trash3-fill::before {
+  content: ""; }
+
+.bi-trash3::before {
+  content: ""; }
+
+.bi-valentine::before {
+  content: ""; }
+
+.bi-valentine2::before {
+  content: ""; }
+
+.bi-wrench-adjustable-circle-fill::before {
+  content: ""; }
+
+.bi-wrench-adjustable-circle::before {
+  content: ""; }
+
+.bi-wrench-adjustable::before {
+  content: ""; }
+
+.bi-filetype-json::before {
+  content: ""; }
+
+.bi-filetype-pptx::before {
+  content: ""; }
+
+.bi-filetype-xlsx::before {
+  content: ""; }
+
+.bi-1-circle-fill::before {
+  content: ""; }
+
+.bi-1-circle::before {
+  content: ""; }
+
+.bi-1-square-fill::before {
+  content: ""; }
+
+.bi-1-square::before {
+  content: ""; }
+
+.bi-2-circle-fill::before {
+  content: ""; }
+
+.bi-2-circle::before {
+  content: ""; }
+
+.bi-2-square-fill::before {
+  content: ""; }
+
+.bi-2-square::before {
+  content: ""; }
+
+.bi-3-circle-fill::before {
+  content: ""; }
+
+.bi-3-circle::before {
+  content: ""; }
+
+.bi-3-square-fill::before {
+  content: ""; }
+
+.bi-3-square::before {
+  content: ""; }
+
+.bi-4-circle-fill::before {
+  content: ""; }
+
+.bi-4-circle::before {
+  content: ""; }
+
+.bi-4-square-fill::before {
+  content: ""; }
+
+.bi-4-square::before {
+  content: ""; }
+
+.bi-5-circle-fill::before {
+  content: ""; }
+
+.bi-5-circle::before {
+  content: ""; }
+
+.bi-5-square-fill::before {
+  content: ""; }
+
+.bi-5-square::before {
+  content: ""; }
+
+.bi-6-circle-fill::before {
+  content: ""; }
+
+.bi-6-circle::before {
+  content: ""; }
+
+.bi-6-square-fill::before {
+  content: ""; }
+
+.bi-6-square::before {
+  content: ""; }
+
+.bi-7-circle-fill::before {
+  content: ""; }
+
+.bi-7-circle::before {
+  content: ""; }
+
+.bi-7-square-fill::before {
+  content: ""; }
+
+.bi-7-square::before {
+  content: ""; }
+
+.bi-8-circle-fill::before {
+  content: ""; }
+
+.bi-8-circle::before {
+  content: ""; }
+
+.bi-8-square-fill::before {
+  content: ""; }
+
+.bi-8-square::before {
+  content: ""; }
+
+.bi-9-circle-fill::before {
+  content: ""; }
+
+.bi-9-circle::before {
+  content: ""; }
+
+.bi-9-square-fill::before {
+  content: ""; }
+
+.bi-9-square::before {
+  content: ""; }
+
+.bi-airplane-engines-fill::before {
+  content: ""; }
+
+.bi-airplane-engines::before {
+  content: ""; }
+
+.bi-airplane-fill::before {
+  content: ""; }
+
+.bi-airplane::before {
+  content: ""; }
+
+.bi-alexa::before {
+  content: ""; }
+
+.bi-alipay::before {
+  content: ""; }
+
+.bi-android::before {
+  content: ""; }
+
+.bi-android2::before {
+  content: ""; }
+
+.bi-box-fill::before {
+  content: ""; }
+
+.bi-box-seam-fill::before {
+  content: ""; }
+
+.bi-browser-chrome::before {
+  content: ""; }
+
+.bi-browser-edge::before {
+  content: ""; }
+
+.bi-browser-firefox::before {
+  content: ""; }
+
+.bi-browser-safari::before {
+  content: ""; }
+
+.bi-c-circle-fill::before {
+  content: ""; }
+
+.bi-c-circle::before {
+  content: ""; }
+
+.bi-c-square-fill::before {
+  content: ""; }
+
+.bi-c-square::before {
+  content: ""; }
+
+.bi-capsule-pill::before {
+  content: ""; }
+
+.bi-capsule::before {
+  content: ""; }
+
+.bi-car-front-fill::before {
+  content: ""; }
+
+.bi-car-front::before {
+  content: ""; }
+
+.bi-cassette-fill::before {
+  content: ""; }
+
+.bi-cassette::before {
+  content: ""; }
+
+.bi-cc-circle-fill::before {
+  content: ""; }
+
+.bi-cc-circle::before {
+  content: ""; }
+
+.bi-cc-square-fill::before {
+  content: ""; }
+
+.bi-cc-square::before {
+  content: ""; }
+
+.bi-cup-hot-fill::before {
+  content: ""; }
+
+.bi-cup-hot::before {
+  content: ""; }
+
+.bi-currency-rupee::before {
+  content: ""; }
+
+.bi-dropbox::before {
+  content: ""; }
+
+.bi-escape::before {
+  content: ""; }
+
+.bi-fast-forward-btn-fill::before {
+  content: ""; }
+
+.bi-fast-forward-btn::before {
+  content: ""; }
+
+.bi-fast-forward-circle-fill::before {
+  content: ""; }
+
+.bi-fast-forward-circle::before {
+  content: ""; }
+
+.bi-fast-forward-fill::before {
+  content: ""; }
+
+.bi-fast-forward::before {
+  content: ""; }
+
+.bi-filetype-sql::before {
+  content: ""; }
+
+.bi-fire::before {
+  content: ""; }
+
+.bi-google-play::before {
+  content: ""; }
+
+.bi-h-circle-fill::before {
+  content: ""; }
+
+.bi-h-circle::before {
+  content: ""; }
+
+.bi-h-square-fill::before {
+  content: ""; }
+
+.bi-h-square::before {
+  content: ""; }
+
+.bi-indent::before {
+  content: ""; }
+
+.bi-lungs-fill::before {
+  content: ""; }
+
+.bi-lungs::before {
+  content: ""; }
+
+.bi-microsoft-teams::before {
+  content: ""; }
+
+.bi-p-circle-fill::before {
+  content: ""; }
+
+.bi-p-circle::before {
+  content: ""; }
+
+.bi-p-square-fill::before {
+  content: ""; }
+
+.bi-p-square::before {
+  content: ""; }
+
+.bi-pass-fill::before {
+  content: ""; }
+
+.bi-pass::before {
+  content: ""; }
+
+.bi-prescription::before {
+  content: ""; }
+
+.bi-prescription2::before {
+  content: ""; }
+
+.bi-r-circle-fill::before {
+  content: ""; }
+
+.bi-r-circle::before {
+  content: ""; }
+
+.bi-r-square-fill::before {
+  content: ""; }
+
+.bi-r-square::before {
+  content: ""; }
+
+.bi-repeat-1::before {
+  content: ""; }
+
+.bi-repeat::before {
+  content: ""; }
+
+.bi-rewind-btn-fill::before {
+  content: ""; }
+
+.bi-rewind-btn::before {
+  content: ""; }
+
+.bi-rewind-circle-fill::before {
+  content: ""; }
+
+.bi-rewind-circle::before {
+  content: ""; }
+
+.bi-rewind-fill::before {
+  content: ""; }
+
+.bi-rewind::before {
+  content: ""; }
+
+.bi-train-freight-front-fill::before {
+  content: ""; }
+
+.bi-train-freight-front::before {
+  content: ""; }
+
+.bi-train-front-fill::before {
+  content: ""; }
+
+.bi-train-front::before {
+  content: ""; }
+
+.bi-train-lightrail-front-fill::before {
+  content: ""; }
+
+.bi-train-lightrail-front::before {
+  content: ""; }
+
+.bi-truck-front-fill::before {
+  content: ""; }
+
+.bi-truck-front::before {
+  content: ""; }
+
+.bi-ubuntu::before {
+  content: ""; }
+
+.bi-unindent::before {
+  content: ""; }
+
+.bi-unity::before {
+  content: ""; }
+
+.bi-universal-access-circle::before {
+  content: ""; }
+
+.bi-universal-access::before {
+  content: ""; }
+
+.bi-virus::before {
+  content: ""; }
+
+.bi-virus2::before {
+  content: ""; }
+
+.bi-wechat::before {
+  content: ""; }
+
+.bi-yelp::before {
+  content: ""; }
+
+.bi-sign-stop-fill::before {
+  content: ""; }
+
+.bi-sign-stop-lights-fill::before {
+  content: ""; }
+
+.bi-sign-stop-lights::before {
+  content: ""; }
+
+.bi-sign-stop::before {
+  content: ""; }
+
+.bi-sign-turn-left-fill::before {
+  content: ""; }
+
+.bi-sign-turn-left::before {
+  content: ""; }
+
+.bi-sign-turn-right-fill::before {
+  content: ""; }
+
+.bi-sign-turn-right::before {
+  content: ""; }
+
+.bi-sign-turn-slight-left-fill::before {
+  content: ""; }
+
+.bi-sign-turn-slight-left::before {
+  content: ""; }
+
+.bi-sign-turn-slight-right-fill::before {
+  content: ""; }
+
+.bi-sign-turn-slight-right::before {
+  content: ""; }
+
+.bi-sign-yield-fill::before {
+  content: ""; }
+
+.bi-sign-yield::before {
+  content: ""; }
+
+.bi-ev-station-fill::before {
+  content: ""; }
+
+.bi-ev-station::before {
+  content: ""; }
+
+.bi-fuel-pump-diesel-fill::before {
+  content: ""; }
+
+.bi-fuel-pump-diesel::before {
+  content: ""; }
+
+.bi-fuel-pump-fill::before {
+  content: ""; }
+
+.bi-fuel-pump::before {
+  content: ""; }
+
+.bi-0-circle-fill::before {
+  content: ""; }
+
+.bi-0-circle::before {
+  content: ""; }
+
+.bi-0-square-fill::before {
+  content: ""; }
+
+.bi-0-square::before {
+  content: ""; }
+
+.bi-rocket-fill::before {
+  content: ""; }
+
+.bi-rocket-takeoff-fill::before {
+  content: ""; }
+
+.bi-rocket-takeoff::before {
+  content: ""; }
+
+.bi-rocket::before {
+  content: ""; }
+
+.bi-stripe::before {
+  content: ""; }
+
+.bi-subscript::before {
+  content: ""; }
+
+.bi-superscript::before {
+  content: ""; }
+
+.bi-trello::before {
+  content: ""; }
+
+.bi-envelope-at-fill::before {
+  content: ""; }
+
+.bi-envelope-at::before {
+  content: ""; }
+
+.bi-regex::before {
+  content: ""; }
+
+.bi-text-wrap::before {
+  content: ""; }
+
+.bi-sign-dead-end-fill::before {
+  content: ""; }
+
+.bi-sign-dead-end::before {
+  content: ""; }
+
+.bi-sign-do-not-enter-fill::before {
+  content: ""; }
+
+.bi-sign-do-not-enter::before {
+  content: ""; }
+
+.bi-sign-intersection-fill::before {
+  content: ""; }
+
+.bi-sign-intersection-side-fill::before {
+  content: ""; }
+
+.bi-sign-intersection-side::before {
+  content: ""; }
+
+.bi-sign-intersection-t-fill::before {
+  content: ""; }
+
+.bi-sign-intersection-t::before {
+  content: ""; }
+
+.bi-sign-intersection-y-fill::before {
+  content: ""; }
+
+.bi-sign-intersection-y::before {
+  content: ""; }
+
+.bi-sign-intersection::before {
+  content: ""; }
+
+.bi-sign-merge-left-fill::before {
+  content: ""; }
+
+.bi-sign-merge-left::before {
+  content: ""; }
+
+.bi-sign-merge-right-fill::before {
+  content: ""; }
+
+.bi-sign-merge-right::before {
+  content: ""; }
+
+.bi-sign-no-left-turn-fill::before {
+  content: ""; }
+
+.bi-sign-no-left-turn::before {
+  content: ""; }
+
+.bi-sign-no-parking-fill::before {
+  content: ""; }
+
+.bi-sign-no-parking::before {
+  content: ""; }
+
+.bi-sign-no-right-turn-fill::before {
+  content: ""; }
+
+.bi-sign-no-right-turn::before {
+  content: ""; }
+
+.bi-sign-railroad-fill::before {
+  content: ""; }
+
+.bi-sign-railroad::before {
+  content: ""; }
+
+.bi-building-add::before {
+  content: ""; }
+
+.bi-building-check::before {
+  content: ""; }
+
+.bi-building-dash::before {
+  content: ""; }
+
+.bi-building-down::before {
+  content: ""; }
+
+.bi-building-exclamation::before {
+  content: ""; }
+
+.bi-building-fill-add::before {
+  content: ""; }
+
+.bi-building-fill-check::before {
+  content: ""; }
+
+.bi-building-fill-dash::before {
+  content: ""; }
+
+.bi-building-fill-down::before {
+  content: ""; }
+
+.bi-building-fill-exclamation::before {
+  content: ""; }
+
+.bi-building-fill-gear::before {
+  content: ""; }
+
+.bi-building-fill-lock::before {
+  content: ""; }
+
+.bi-building-fill-slash::before {
+  content: ""; }
+
+.bi-building-fill-up::before {
+  content: ""; }
+
+.bi-building-fill-x::before {
+  content: ""; }
+
+.bi-building-fill::before {
+  content: ""; }
+
+.bi-building-gear::before {
+  content: ""; }
+
+.bi-building-lock::before {
+  content: ""; }
+
+.bi-building-slash::before {
+  content: ""; }
+
+.bi-building-up::before {
+  content: ""; }
+
+.bi-building-x::before {
+  content: ""; }
+
+.bi-buildings-fill::before {
+  content: ""; }
+
+.bi-buildings::before {
+  content: ""; }
+
+.bi-bus-front-fill::before {
+  content: ""; }
+
+.bi-bus-front::before {
+  content: ""; }
+
+.bi-ev-front-fill::before {
+  content: ""; }
+
+.bi-ev-front::before {
+  content: ""; }
+
+.bi-globe-americas::before {
+  content: ""; }
+
+.bi-globe-asia-australia::before {
+  content: ""; }
+
+.bi-globe-central-south-asia::before {
+  content: ""; }
+
+.bi-globe-europe-africa::before {
+  content: ""; }
+
+.bi-house-add-fill::before {
+  content: ""; }
+
+.bi-house-add::before {
+  content: ""; }
+
+.bi-house-check-fill::before {
+  content: ""; }
+
+.bi-house-check::before {
+  content: ""; }
+
+.bi-house-dash-fill::before {
+  content: ""; }
+
+.bi-house-dash::before {
+  content: ""; }
+
+.bi-house-down-fill::before {
+  content: ""; }
+
+.bi-house-down::before {
+  content: ""; }
+
+.bi-house-exclamation-fill::before {
+  content: ""; }
+
+.bi-house-exclamation::before {
+  content: ""; }
+
+.bi-house-gear-fill::before {
+  content: ""; }
+
+.bi-house-gear::before {
+  content: ""; }
+
+.bi-house-lock-fill::before {
+  content: ""; }
+
+.bi-house-lock::before {
+  content: ""; }
+
+.bi-house-slash-fill::before {
+  content: ""; }
+
+.bi-house-slash::before {
+  content: ""; }
+
+.bi-house-up-fill::before {
+  content: ""; }
+
+.bi-house-up::before {
+  content: ""; }
+
+.bi-house-x-fill::before {
+  content: ""; }
+
+.bi-house-x::before {
+  content: ""; }
+
+.bi-person-add::before {
+  content: ""; }
+
+.bi-person-down::before {
+  content: ""; }
+
+.bi-person-exclamation::before {
+  content: ""; }
+
+.bi-person-fill-add::before {
+  content: ""; }
+
+.bi-person-fill-check::before {
+  content: ""; }
+
+.bi-person-fill-dash::before {
+  content: ""; }
+
+.bi-person-fill-down::before {
+  content: ""; }
+
+.bi-person-fill-exclamation::before {
+  content: ""; }
+
+.bi-person-fill-gear::before {
+  content: ""; }
+
+.bi-person-fill-lock::before {
+  content: ""; }
+
+.bi-person-fill-slash::before {
+  content: ""; }
+
+.bi-person-fill-up::before {
+  content: ""; }
+
+.bi-person-fill-x::before {
+  content: ""; }
+
+.bi-person-gear::before {
+  content: ""; }
+
+.bi-person-lock::before {
+  content: ""; }
+
+.bi-person-slash::before {
+  content: ""; }
+
+.bi-person-up::before {
+  content: ""; }
+
+.bi-scooter::before {
+  content: ""; }
+
+.bi-taxi-front-fill::before {
+  content: ""; }
+
+.bi-taxi-front::before {
+  content: ""; }
+
+.bi-amd::before {
+  content: ""; }
+
+.bi-database-add::before {
+  content: ""; }
+
+.bi-database-check::before {
+  content: ""; }
+
+.bi-database-dash::before {
+  content: ""; }
+
+.bi-database-down::before {
+  content: ""; }
+
+.bi-database-exclamation::before {
+  content: ""; }
+
+.bi-database-fill-add::before {
+  content: ""; }
+
+.bi-database-fill-check::before {
+  content: ""; }
+
+.bi-database-fill-dash::before {
+  content: ""; }
+
+.bi-database-fill-down::before {
+  content: ""; }
+
+.bi-database-fill-exclamation::before {
+  content: ""; }
+
+.bi-database-fill-gear::before {
+  content: ""; }
+
+.bi-database-fill-lock::before {
+  content: ""; }
+
+.bi-database-fill-slash::before {
+  content: ""; }
+
+.bi-database-fill-up::before {
+  content: ""; }
+
+.bi-database-fill-x::before {
+  content: ""; }
+
+.bi-database-fill::before {
+  content: ""; }
+
+.bi-database-gear::before {
+  content: ""; }
+
+.bi-database-lock::before {
+  content: ""; }
+
+.bi-database-slash::before {
+  content: ""; }
+
+.bi-database-up::before {
+  content: ""; }
+
+.bi-database-x::before {
+  content: ""; }
+
+.bi-database::before {
+  content: ""; }
+
+.bi-houses-fill::before {
+  content: ""; }
+
+.bi-houses::before {
+  content: ""; }
+
+.bi-nvidia::before {
+  content: ""; }
+
+.bi-person-vcard-fill::before {
+  content: ""; }
+
+.bi-person-vcard::before {
+  content: ""; }
+
+.bi-sina-weibo::before {
+  content: ""; }
+
+.bi-tencent-qq::before {
+  content: ""; }
+
+.bi-wikipedia::before {
+  content: ""; }
diff --git a/gnuviechadmin/static/css/bootstrap-theme.min.css b/gnuviechadmin/static/css/bootstrap-theme.min.css
deleted file mode 100644
index ac8dd55..0000000
--- a/gnuviechadmin/static/css/bootstrap-theme.min.css
+++ /dev/null
@@ -1,5 +0,0 @@
-/*!
- * Bootstrap v3.3.2 (http://getbootstrap.com)
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary:disabled,.btn-primary[disabled]{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning:disabled,.btn-warning[disabled]{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger:disabled,.btn-danger[disabled]{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)}
\ No newline at end of file
diff --git a/gnuviechadmin/static/css/bootstrap.min.css b/gnuviechadmin/static/css/bootstrap.min.css
index 28f154d..f06f523 100644
--- a/gnuviechadmin/static/css/bootstrap.min.css
+++ b/gnuviechadmin/static/css/bootstrap.min.css
@@ -1,5 +1,7 @@
-/*!
- * Bootstrap v3.3.2 (http://getbootstrap.com)
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.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}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px \9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.form-group-sm .form-control{height:30px;line-height:30px}select[multiple].form-group-sm .form-control,textarea.form-group-sm .form-control{height:auto}.form-group-sm .form-control-static{height:30px;padding:5px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.form-group-lg .form-control{height:46px;line-height:46px}select[multiple].form-group-lg .form-control,textarea.form-group-lg .form-control{height:auto}.form-group-lg .form-control-static{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.active,.btn-default.focus,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important;visibility:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:absolute;top:0;right:0;left:0;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}
\ No newline at end of file
+@charset "UTF-8";/*!
+ * Bootstrap  v5.2.3 (https://getbootstrap.com/)
+ * Copyright 2011-2022 The Bootstrap Authors
+ * Copyright 2011-2022 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ */:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#0d6efd;--bs-link-hover-color:#0a58ca;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:1px solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--bs-link-color);text-decoration:underline}a:hover{color:var(--bs-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid var(--bs-border-color);border-radius:.375rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#6c757d}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color:var(--bs-body-color);--bs-table-bg:transparent;--bs-table-border-color:var(--bs-border-color);--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-body-color);--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:var(--bs-body-color);--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:var(--bs-body-color);--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:var(--bs-table-color);vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:2px solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-striped-columns>:not(caption)>tr>:nth-child(2n){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-color:#000;--bs-table-bg:#cfe2ff;--bs-table-border-color:#bacbe6;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#000;--bs-table-bg:#e2e3e5;--bs-table-border-color:#cbccce;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#000;--bs-table-bg:#d1e7dd;--bs-table-border-color:#bcd0c7;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#000;--bs-table-bg:#cff4fc;--bs-table-border-color:#badce3;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#000;--bs-table-bg:#fff3cd;--bs-table-border-color:#e6dbb9;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#000;--bs-table-bg:#f8d7da;--bs-table-border-color:#dfc2c4;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#000;--bs-table-bg:#f8f9fa;--bs-table-border-color:#dfe0e1;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#212529;--bs-table-border-color:#373b3e;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:#6c757d}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#212529;background-color:#fff;border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled{background-color:#e9ecef;opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#212529;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#212529;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{width:3rem;height:calc(1.5em + .75rem + 2px);padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:.375rem}.form-control-color::-webkit-color-swatch{border-radius:.375rem}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + 2px)}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + 2px)}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #ced4da;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #212529}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:.25rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:.5rem}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,.25);-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;width:100%;height:100%;padding:1rem .75rem;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::-moz-placeholder,.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown),.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:1px 0}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.375rem}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#198754}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(25,135,84,.9);border-radius:.375rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#198754;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#198754}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#198754}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#198754}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#198754}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.375rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#dc3545}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#dc3545}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#dc3545}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#212529;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:0.5rem}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:0.25rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:#212529;--bs-dropdown-bg:#fff;--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-border-radius:0.375rem;--bs-dropdown-border-width:1px;--bs-dropdown-inner-border-radius:calc(0.375rem - 1px);--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-dropdown-link-color:#212529;--bs-dropdown-link-hover-color:#1e2125;--bs-dropdown-link-hover-bg:#e9ecef;--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#6c757d;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#343a40;--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:.375rem}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#6c757d;display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#dee2e6;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#e9ecef #e9ecef #dee2e6;--bs-nav-tabs-link-active-color:#495057;--bs-nav-tabs-link-active-bg:#fff;--bs-nav-tabs-link-active-border-color:#dee2e6 #dee2e6 #fff;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:0.375rem;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0d6efd}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:0.5rem;--bs-navbar-color:rgba(0, 0, 0, 0.55);--bs-navbar-hover-color:rgba(0, 0, 0, 0.7);--bs-navbar-disabled-color:rgba(0, 0, 0, 0.3);--bs-navbar-active-color:rgba(0, 0, 0, 0.9);--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:rgba(0, 0, 0, 0.9);--bs-navbar-brand-hover-color:rgba(0, 0, 0, 0.9);--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(0, 0, 0, 0.1);--bs-navbar-toggler-border-radius:0.375rem;--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .show>.nav-link{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark{--bs-navbar-color:rgba(255, 255, 255, 0.55);--bs-navbar-hover-color:rgba(255, 255, 255, 0.75);--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-border-width:1px;--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:0.375rem;--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(0.375rem - 1px);--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:rgba(0, 0, 0, 0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:#fff;--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:#212529;--bs-accordion-bg:#fff;--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:1px;--bs-accordion-border-radius:0.375rem;--bs-accordion-inner-border-radius:calc(0.375rem - 1px);--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:#212529;--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-focus-border-color:#86b7fe;--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:#0c63e4;--bs-accordion-active-bg:#e7f1ff}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:var(--bs-accordion-btn-focus-border-color);outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button,.accordion-flush .accordion-item .accordion-button.collapsed{border-radius:0}.breadcrumb{--bs-breadcrumb-padding-x:0;--bs-breadcrumb-padding-y:0;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color:#6c757d;--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:#6c757d;display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:var(--bs-link-color);--bs-pagination-bg:#fff;--bs-pagination-border-width:1px;--bs-pagination-border-color:#dee2e6;--bs-pagination-border-radius:0.375rem;--bs-pagination-hover-color:var(--bs-link-hover-color);--bs-pagination-hover-bg:#e9ecef;--bs-pagination-hover-border-color:#dee2e6;--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:#e9ecef;--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#0d6efd;--bs-pagination-active-border-color:#0d6efd;--bs-pagination-disabled-color:#6c757d;--bs-pagination-disabled-bg:#fff;--bs-pagination-disabled-border-color:#dee2e6;display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:-1px}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:0.5rem}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:0.25rem}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:0.375rem;display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:1px solid var(--bs-alert-border-color);--bs-alert-border-radius:0.375rem;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:#084298;--bs-alert-bg:#cfe2ff;--bs-alert-border-color:#b6d4fe}.alert-primary .alert-link{color:#06357a}.alert-secondary{--bs-alert-color:#41464b;--bs-alert-bg:#e2e3e5;--bs-alert-border-color:#d3d6d8}.alert-secondary .alert-link{color:#34383c}.alert-success{--bs-alert-color:#0f5132;--bs-alert-bg:#d1e7dd;--bs-alert-border-color:#badbcc}.alert-success .alert-link{color:#0c4128}.alert-info{--bs-alert-color:#055160;--bs-alert-bg:#cff4fc;--bs-alert-border-color:#b6effb}.alert-info .alert-link{color:#04414d}.alert-warning{--bs-alert-color:#664d03;--bs-alert-bg:#fff3cd;--bs-alert-border-color:#ffecb5}.alert-warning .alert-link{color:#523e02}.alert-danger{--bs-alert-color:#842029;--bs-alert-bg:#f8d7da;--bs-alert-border-color:#f5c2c7}.alert-danger .alert-link{color:#6a1a21}.alert-light{--bs-alert-color:#636464;--bs-alert-bg:#fefefe;--bs-alert-border-color:#fdfdfe}.alert-light .alert-link{color:#4f5050}.alert-dark{--bs-alert-color:#141619;--bs-alert-bg:#d3d3d4;--bs-alert-border-color:#bcbebf}.alert-dark .alert-link{color:#101214}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:#e9ecef;--bs-progress-border-radius:0.375rem;--bs-progress-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#0d6efd;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color:#212529;--bs-list-group-bg:#fff;--bs-list-group-border-color:rgba(0, 0, 0, 0.125);--bs-list-group-border-width:1px;--bs-list-group-border-radius:0.375rem;--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:#495057;--bs-list-group-action-hover-color:#495057;--bs-list-group-action-hover-bg:#f8f9fa;--bs-list-group-action-active-color:#212529;--bs-list-group-action-active-bg:#e9ecef;--bs-list-group-disabled-color:#6c757d;--bs-list-group-disabled-bg:#fff;--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#0d6efd;--bs-list-group-active-border-color:#0d6efd;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#084298;background-color:#cfe2ff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#084298;background-color:#bacbe6}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#084298;border-color:#084298}.list-group-item-secondary{color:#41464b;background-color:#e2e3e5}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#41464b;background-color:#cbccce}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#41464b;border-color:#41464b}.list-group-item-success{color:#0f5132;background-color:#d1e7dd}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#0f5132;background-color:#bcd0c7}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#0f5132;border-color:#0f5132}.list-group-item-info{color:#055160;background-color:#cff4fc}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#055160;background-color:#badce3}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#055160;border-color:#055160}.list-group-item-warning{color:#664d03;background-color:#fff3cd}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#664d03;background-color:#e6dbb9}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#664d03;border-color:#664d03}.list-group-item-danger{color:#842029;background-color:#f8d7da}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#842029;background-color:#dfc2c4}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#842029;border-color:#842029}.list-group-item-light{color:#636464;background-color:#fefefe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#636464;background-color:#e5e5e5}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#636464;border-color:#636464}.list-group-item-dark{color:#141619;background-color:#d3d3d4}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#141619;background-color:#bebebf}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#141619;border-color:#141619}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#000;background:transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.375rem;opacity:.5}.btn-close:hover{color:#000;text-decoration:none;opacity:.75}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);opacity:1}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:rgba(255, 255, 255, 0.85);--bs-toast-border-width:1px;--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:0.375rem;--bs-toast-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-toast-header-color:#6c757d;--bs-toast-header-bg:rgba(255, 255, 255, 0.85);--bs-toast-header-border-color:rgba(0, 0, 0, 0.05);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex:1090;position:absolute;z-index:var(--bs-toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:#fff;--bs-modal-border-color:var(--bs-border-color-translucent);--bs-modal-border-width:1px;--bs-modal-border-radius:0.5rem;--bs-modal-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-modal-inner-border-radius:calc(0.5rem - 1px);--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:var(--bs-border-color);--bs-modal-header-border-width:1px;--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:var(--bs-border-color);--bs-modal-footer-border-width:1px;position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin:calc(-.5 * var(--bs-modal-header-padding-y)) calc(-.5 * var(--bs-modal-header-padding-x)) calc(-.5 * var(--bs-modal-header-padding-y)) auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:#fff;--bs-tooltip-bg:#000;--bs-tooltip-border-radius:0.375rem;--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;padding:var(--bs-tooltip-arrow-height);margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:#fff;--bs-popover-border-width:1px;--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:0.5rem;--bs-popover-inner-border-radius:calc(0.5rem - 1px);--bs-popover-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color: ;--bs-popover-header-bg:#f0f0f0;--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:#212529;--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color: ;--bs-offcanvas-bg:#fff;--bs-offcanvas-border-width:1px;--bs-offcanvas-border-color:var(--bs-border-color-translucent);--bs-offcanvas-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075)}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:575.98px){.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}}@media (max-width:575.98px){.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:767.98px){.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}}@media (max-width:767.98px){.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:991.98px){.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}}@media (max-width:991.98px){.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1199.98px){.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}}@media (max-width:1199.98px){.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}}@media (max-width:1399.98px){.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin-top:calc(-.5 * var(--bs-offcanvas-padding-y));margin-right:calc(-.5 * var(--bs-offcanvas-padding-x));margin-bottom:calc(-.5 * var(--bs-offcanvas-padding-y))}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(13,110,253,var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(108,117,125,var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(25,135,84,var(--bs-bg-opacity,1))!important}.text-bg-info{color:#000!important;background-color:RGBA(13,202,240,var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#000!important;background-color:RGBA(255,193,7,var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(220,53,69,var(--bs-bg-opacity,1))!important}.text-bg-light{color:#000!important;background-color:RGBA(248,249,250,var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(33,37,41,var(--bs-bg-opacity,1))!important}.link-primary{color:#0d6efd!important}.link-primary:focus,.link-primary:hover{color:#0a58ca!important}.link-secondary{color:#6c757d!important}.link-secondary:focus,.link-secondary:hover{color:#565e64!important}.link-success{color:#198754!important}.link-success:focus,.link-success:hover{color:#146c43!important}.link-info{color:#0dcaf0!important}.link-info:focus,.link-info:hover{color:#3dd5f3!important}.link-warning{color:#ffc107!important}.link-warning:focus,.link-warning:hover{color:#ffcd39!important}.link-danger{color:#dc3545!important}.link-danger:focus,.link-danger:hover{color:#b02a37!important}.link-light{color:#f8f9fa!important}.link-light:focus,.link-light:hover{color:#f9fafb!important}.link-dark{color:#212529!important}.link-dark:focus,.link-dark:hover{color:#1a1e21!important}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-1{--bs-border-width:1px}.border-2{--bs-border-width:2px}.border-3{--bs-border-width:3px}.border-4{--bs-border-width:4px}.border-5{--bs-border-width:5px}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-light{font-weight:300!important}.fw-lighter{font-weight:lighter!important}.fw-normal{font-weight:400!important}.fw-bold{font-weight:700!important}.fw-semibold{font-weight:600!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:#6c757d!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-2xl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}}
+/*# sourceMappingURL=bootstrap.min.css.map */
\ No newline at end of file
diff --git a/gnuviechadmin/static/css/bootstrap.min.css.map b/gnuviechadmin/static/css/bootstrap.min.css.map
new file mode 100644
index 0000000..336fa28
--- /dev/null
+++ b/gnuviechadmin/static/css/bootstrap.min.css.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../../scss/mixins/_banner.scss","../../scss/_root.scss","../../scss/vendor/_rfs.scss","../../scss/_reboot.scss","dist/css/bootstrap.css","../../scss/mixins/_border-radius.scss","../../scss/_type.scss","../../scss/mixins/_lists.scss","../../scss/_images.scss","../../scss/mixins/_image.scss","../../scss/_containers.scss","../../scss/mixins/_container.scss","../../scss/mixins/_breakpoints.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/_tables.scss","../../scss/mixins/_table-variants.scss","../../scss/forms/_labels.scss","../../scss/forms/_form-text.scss","../../scss/forms/_form-control.scss","../../scss/mixins/_transition.scss","../../scss/mixins/_gradients.scss","../../scss/forms/_form-select.scss","../../scss/forms/_form-check.scss","../../scss/forms/_form-range.scss","../../scss/forms/_floating-labels.scss","../../scss/forms/_input-group.scss","../../scss/mixins/_forms.scss","../../scss/_buttons.scss","../../scss/mixins/_buttons.scss","../../scss/_transitions.scss","../../scss/_dropdown.scss","../../scss/mixins/_caret.scss","../../scss/_button-group.scss","../../scss/_nav.scss","../../scss/_navbar.scss","../../scss/_card.scss","../../scss/_accordion.scss","../../scss/_breadcrumb.scss","../../scss/_pagination.scss","../../scss/mixins/_pagination.scss","../../scss/_badge.scss","../../scss/_alert.scss","../../scss/mixins/_alert.scss","../../scss/_progress.scss","../../scss/_list-group.scss","../../scss/mixins/_list-group.scss","../../scss/_close.scss","../../scss/_toasts.scss","../../scss/_modal.scss","../../scss/mixins/_backdrop.scss","../../scss/_tooltip.scss","../../scss/mixins/_reset-text.scss","../../scss/_popover.scss","../../scss/_carousel.scss","../../scss/mixins/_clearfix.scss","../../scss/_spinners.scss","../../scss/_offcanvas.scss","../../scss/_placeholders.scss","../../scss/helpers/_color-bg.scss","../../scss/helpers/_colored-links.scss","../../scss/helpers/_ratio.scss","../../scss/helpers/_position.scss","../../scss/helpers/_stacks.scss","../../scss/helpers/_visually-hidden.scss","../../scss/mixins/_visually-hidden.scss","../../scss/helpers/_stretched-link.scss","../../scss/helpers/_text-truncation.scss","../../scss/mixins/_text-truncate.scss","../../scss/helpers/_vr.scss","../../scss/mixins/_utilities.scss","../../scss/utilities/_api.scss"],"names":[],"mappings":"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","sourcesContent":["@mixin bsBanner($file) {\n  /*!\n   * Bootstrap #{$file} v5.2.3 (https://getbootstrap.com/)\n   * Copyright 2011-2022 The Bootstrap Authors\n   * Copyright 2011-2022 Twitter, Inc.\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   */\n}\n\n",":root {\n  // Note: Custom variable values only support SassScript inside `#{}`.\n\n  // Colors\n  //\n  // Generate palettes for full colors, grays, and theme colors.\n\n  @each $color, $value in $colors {\n    --#{$prefix}#{$color}: #{$value};\n  }\n\n  @each $color, $value in $grays {\n    --#{$prefix}gray-#{$color}: #{$value};\n  }\n\n  @each $color, $value in $theme-colors {\n    --#{$prefix}#{$color}: #{$value};\n  }\n\n  @each $color, $value in $theme-colors-rgb {\n    --#{$prefix}#{$color}-rgb: #{$value};\n  }\n\n  --#{$prefix}white-rgb: #{to-rgb($white)};\n  --#{$prefix}black-rgb: #{to-rgb($black)};\n  --#{$prefix}body-color-rgb: #{to-rgb($body-color)};\n  --#{$prefix}body-bg-rgb: #{to-rgb($body-bg)};\n\n  // Fonts\n\n  // Note: Use `inspect` for lists so that quoted items keep the quotes.\n  // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n  --#{$prefix}font-sans-serif: #{inspect($font-family-sans-serif)};\n  --#{$prefix}font-monospace: #{inspect($font-family-monospace)};\n  --#{$prefix}gradient: #{$gradient};\n\n  // Root and body\n  // scss-docs-start root-body-variables\n  @if $font-size-root != null {\n    --#{$prefix}root-font-size: #{$font-size-root};\n  }\n  --#{$prefix}body-font-family: #{$font-family-base};\n  @include rfs($font-size-base, --#{$prefix}body-font-size);\n  --#{$prefix}body-font-weight: #{$font-weight-base};\n  --#{$prefix}body-line-height: #{$line-height-base};\n  --#{$prefix}body-color: #{$body-color};\n  @if $body-text-align != null {\n    --#{$prefix}body-text-align: #{$body-text-align};\n  }\n  --#{$prefix}body-bg: #{$body-bg};\n  // scss-docs-end root-body-variables\n\n  // scss-docs-start root-border-var\n  --#{$prefix}border-width: #{$border-width};\n  --#{$prefix}border-style: #{$border-style};\n  --#{$prefix}border-color: #{$border-color};\n  --#{$prefix}border-color-translucent: #{$border-color-translucent};\n\n  --#{$prefix}border-radius: #{$border-radius};\n  --#{$prefix}border-radius-sm: #{$border-radius-sm};\n  --#{$prefix}border-radius-lg: #{$border-radius-lg};\n  --#{$prefix}border-radius-xl: #{$border-radius-xl};\n  --#{$prefix}border-radius-2xl: #{$border-radius-2xl};\n  --#{$prefix}border-radius-pill: #{$border-radius-pill};\n  // scss-docs-end root-border-var\n\n  --#{$prefix}link-color: #{$link-color};\n  --#{$prefix}link-hover-color: #{$link-hover-color};\n\n  --#{$prefix}code-color: #{$code-color};\n\n  --#{$prefix}highlight-bg: #{$mark-bg};\n}\n","// stylelint-disable property-blacklist, scss/dollar-variable-default\n\n// SCSS RFS mixin\n//\n// Automated responsive values for font sizes, paddings, margins and much more\n//\n// Licensed under MIT (https://github.com/twbs/rfs/blob/main/LICENSE)\n\n// Configuration\n\n// Base value\n$rfs-base-value: 1.25rem !default;\n$rfs-unit: rem !default;\n\n@if $rfs-unit != rem and $rfs-unit != px {\n  @error \"`#{$rfs-unit}` is not a valid unit for $rfs-unit. Use `px` or `rem`.\";\n}\n\n// Breakpoint at where values start decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n@if $rfs-breakpoint-unit != px and $rfs-breakpoint-unit != em and $rfs-breakpoint-unit != rem {\n  @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n}\n\n// Resize values based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != number or $rfs-factor <= 1 {\n  @error \"`#{$rfs-factor}` is not a valid  $rfs-factor, it must be greater than 1.\";\n}\n\n// Mode. Possibilities: \"min-media-query\", \"max-media-query\"\n$rfs-mode: min-media-query !default;\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-rfs to false\n$enable-rfs: true !default;\n\n// Cache $rfs-base-value unit\n$rfs-base-value-unit: unit($rfs-base-value);\n\n@function divide($dividend, $divisor, $precision: 10) {\n  $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1);\n  $dividend: abs($dividend);\n  $divisor: abs($divisor);\n  @if $dividend == 0 {\n    @return 0;\n  }\n  @if $divisor == 0 {\n    @error \"Cannot divide by 0\";\n  }\n  $remainder: $dividend;\n  $result: 0;\n  $factor: 10;\n  @while ($remainder > 0 and $precision >= 0) {\n    $quotient: 0;\n    @while ($remainder >= $divisor) {\n      $remainder: $remainder - $divisor;\n      $quotient: $quotient + 1;\n    }\n    $result: $result * 10 + $quotient;\n    $factor: $factor * .1;\n    $remainder: $remainder * 10;\n    $precision: $precision - 1;\n    @if ($precision < 0 and $remainder >= $divisor * 5) {\n      $result: $result + 1;\n    }\n  }\n  $result: $result * $factor * $sign;\n  $dividend-unit: unit($dividend);\n  $divisor-unit: unit($divisor);\n  $unit-map: (\n    \"px\": 1px,\n    \"rem\": 1rem,\n    \"em\": 1em,\n    \"%\": 1%\n  );\n  @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) {\n    $result: $result * map-get($unit-map, $dividend-unit);\n  }\n  @return $result;\n}\n\n// Remove px-unit from $rfs-base-value for calculations\n@if $rfs-base-value-unit == px {\n  $rfs-base-value: divide($rfs-base-value, $rfs-base-value * 0 + 1);\n}\n@else if $rfs-base-value-unit == rem {\n  $rfs-base-value: divide($rfs-base-value, divide($rfs-base-value * 0 + 1, $rfs-rem-value));\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == px {\n  $rfs-breakpoint: divide($rfs-breakpoint, $rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == rem or $rfs-breakpoint-unit-cache == \"em\" {\n  $rfs-breakpoint: divide($rfs-breakpoint, divide($rfs-breakpoint * 0 + 1, $rfs-rem-value));\n}\n\n// Calculate the media query value\n$rfs-mq-value: if($rfs-breakpoint-unit == px, #{$rfs-breakpoint}px, #{divide($rfs-breakpoint, $rfs-rem-value)}#{$rfs-breakpoint-unit});\n$rfs-mq-property-width: if($rfs-mode == max-media-query, max-width, min-width);\n$rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height);\n\n// Internal mixin used to determine which media query needs to be used\n@mixin _rfs-media-query {\n  @if $rfs-two-dimensional {\n    @if $rfs-mode == max-media-query {\n      @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}), (#{$rfs-mq-property-height}: #{$rfs-mq-value}) {\n        @content;\n      }\n    }\n    @else {\n      @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}) and (#{$rfs-mq-property-height}: #{$rfs-mq-value}) {\n        @content;\n      }\n    }\n  }\n  @else {\n    @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}) {\n      @content;\n    }\n  }\n}\n\n// Internal mixin that adds disable classes to the selector if needed.\n@mixin _rfs-rule {\n  @if $rfs-class == disable and $rfs-mode == max-media-query {\n    // Adding an extra class increases specificity, which prevents the media query to override the property\n    &,\n    .disable-rfs &,\n    &.disable-rfs {\n      @content;\n    }\n  }\n  @else if $rfs-class == enable and $rfs-mode == min-media-query {\n    .enable-rfs &,\n    &.enable-rfs {\n      @content;\n    }\n  }\n  @else {\n    @content;\n  }\n}\n\n// Internal mixin that adds enable classes to the selector if needed.\n@mixin _rfs-media-query-rule {\n\n  @if $rfs-class == enable {\n    @if $rfs-mode == min-media-query {\n      @content;\n    }\n\n    @include _rfs-media-query {\n      .enable-rfs &,\n      &.enable-rfs {\n        @content;\n      }\n    }\n  }\n  @else {\n    @if $rfs-class == disable and $rfs-mode == min-media-query {\n      .disable-rfs &,\n      &.disable-rfs {\n        @content;\n      }\n    }\n    @include _rfs-media-query {\n      @content;\n    }\n  }\n}\n\n// Helper function to get the formatted non-responsive value\n@function rfs-value($values) {\n  // Convert to list\n  $values: if(type-of($values) != list, ($values,), $values);\n\n  $val: '';\n\n  // Loop over each value and calculate value\n  @each $value in $values {\n    @if $value == 0 {\n      $val: $val + ' 0';\n    }\n    @else {\n      // Cache $value unit\n      $unit: if(type-of($value) == \"number\", unit($value), false);\n\n      @if $unit == px {\n        // Convert to rem if needed\n        $val: $val + ' ' + if($rfs-unit == rem, #{divide($value, $value * 0 + $rfs-rem-value)}rem, $value);\n      }\n      @else if $unit == rem {\n        // Convert to px if needed\n        $val: $val + ' ' + if($rfs-unit == px, #{divide($value, $value * 0 + 1) * $rfs-rem-value}px, $value);\n      }\n      @else {\n        // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n        $val: $val + ' ' + $value;\n      }\n    }\n  }\n\n  // Remove first space\n  @return unquote(str-slice($val, 2));\n}\n\n// Helper function to get the responsive value calculated by RFS\n@function rfs-fluid-value($values) {\n  // Convert to list\n  $values: if(type-of($values) != list, ($values,), $values);\n\n  $val: '';\n\n  // Loop over each value and calculate value\n  @each $value in $values {\n    @if $value == 0 {\n      $val: $val + ' 0';\n    }\n\n    @else {\n      // Cache $value unit\n      $unit: if(type-of($value) == \"number\", unit($value), false);\n\n      // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n      @if not $unit or $unit != px and $unit != rem {\n        $val: $val + ' ' + $value;\n      }\n\n      @else {\n        // Remove unit from $value for calculations\n        $value: divide($value, $value * 0 + if($unit == px, 1, divide(1, $rfs-rem-value)));\n\n        // Only add the media query if the value is greater than the minimum value\n        @if abs($value) <= $rfs-base-value or not $enable-rfs {\n          $val: $val + ' ' +  if($rfs-unit == rem, #{divide($value, $rfs-rem-value)}rem, #{$value}px);\n        }\n        @else {\n          // Calculate the minimum value\n          $value-min: $rfs-base-value + divide(abs($value) - $rfs-base-value, $rfs-factor);\n\n          // Calculate difference between $value and the minimum value\n          $value-diff: abs($value) - $value-min;\n\n          // Base value formatting\n          $min-width: if($rfs-unit == rem, #{divide($value-min, $rfs-rem-value)}rem, #{$value-min}px);\n\n          // Use negative value if needed\n          $min-width: if($value < 0, -$min-width, $min-width);\n\n          // Use `vmin` if two-dimensional is enabled\n          $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n          // Calculate the variable width between 0 and $rfs-breakpoint\n          $variable-width: #{divide($value-diff * 100, $rfs-breakpoint)}#{$variable-unit};\n\n          // Return the calculated value\n          $val: $val + ' calc(' + $min-width + if($value < 0, ' - ', ' + ') + $variable-width + ')';\n        }\n      }\n    }\n  }\n\n  // Remove first space\n  @return unquote(str-slice($val, 2));\n}\n\n// RFS mixin\n@mixin rfs($values, $property: font-size) {\n  @if $values != null {\n    $val: rfs-value($values);\n    $fluidVal: rfs-fluid-value($values);\n\n    // Do not print the media query if responsive & non-responsive values are the same\n    @if $val == $fluidVal {\n      #{$property}: $val;\n    }\n    @else {\n      @include _rfs-rule {\n        #{$property}: if($rfs-mode == max-media-query, $val, $fluidVal);\n\n        // Include safari iframe resize fix if needed\n        min-width: if($rfs-safari-iframe-resize-bug-fix, (0 * 1vw), null);\n      }\n\n      @include _rfs-media-query-rule {\n        #{$property}: if($rfs-mode == max-media-query, $fluidVal, $val);\n      }\n    }\n  }\n}\n\n// Shorthand helper mixins\n@mixin font-size($value) {\n  @include rfs($value);\n}\n\n@mixin padding($value) {\n  @include rfs($value, padding);\n}\n\n@mixin padding-top($value) {\n  @include rfs($value, padding-top);\n}\n\n@mixin padding-right($value) {\n  @include rfs($value, padding-right);\n}\n\n@mixin padding-bottom($value) {\n  @include rfs($value, padding-bottom);\n}\n\n@mixin padding-left($value) {\n  @include rfs($value, padding-left);\n}\n\n@mixin margin($value) {\n  @include rfs($value, margin);\n}\n\n@mixin margin-top($value) {\n  @include rfs($value, margin-top);\n}\n\n@mixin margin-right($value) {\n  @include rfs($value, margin-right);\n}\n\n@mixin margin-bottom($value) {\n  @include rfs($value, margin-bottom);\n}\n\n@mixin margin-left($value) {\n  @include rfs($value, margin-left);\n}\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n\n*,\n*::before,\n*::after {\n  box-sizing: border-box;\n}\n\n\n// Root\n//\n// Ability to the value of the root font sizes, affecting the value of `rem`.\n// null by default, thus nothing is generated.\n\n:root {\n  @if $font-size-root != null {\n    @include font-size(var(--#{$prefix}root-font-size));\n  }\n\n  @if $enable-smooth-scroll {\n    @media (prefers-reduced-motion: no-preference) {\n      scroll-behavior: smooth;\n    }\n  }\n}\n\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Prevent adjustments of font size after orientation changes in iOS.\n// 4. Change the default tap highlight to be completely transparent in iOS.\n\n// scss-docs-start reboot-body-rules\nbody {\n  margin: 0; // 1\n  font-family: var(--#{$prefix}body-font-family);\n  @include font-size(var(--#{$prefix}body-font-size));\n  font-weight: var(--#{$prefix}body-font-weight);\n  line-height: var(--#{$prefix}body-line-height);\n  color: var(--#{$prefix}body-color);\n  text-align: var(--#{$prefix}body-text-align);\n  background-color: var(--#{$prefix}body-bg); // 2\n  -webkit-text-size-adjust: 100%; // 3\n  -webkit-tap-highlight-color: rgba($black, 0); // 4\n}\n// scss-docs-end reboot-body-rules\n\n\n// Content grouping\n//\n// 1. Reset Firefox's gray color\n\nhr {\n  margin: $hr-margin-y 0;\n  color: $hr-color; // 1\n  border: 0;\n  border-top: $hr-border-width solid $hr-border-color;\n  opacity: $hr-opacity;\n}\n\n\n// Typography\n//\n// 1. Remove top margins from headings\n//    By default, ``-`` all receive top and bottom margins. We nuke the top\n//    margin for easier control within type scales as it avoids margin collapsing.\n\n%heading {\n  margin-top: 0; // 1\n  margin-bottom: $headings-margin-bottom;\n  font-family: $headings-font-family;\n  font-style: $headings-font-style;\n  font-weight: $headings-font-weight;\n  line-height: $headings-line-height;\n  color: $headings-color;\n}\n\nh1 {\n  @extend %heading;\n  @include font-size($h1-font-size);\n}\n\nh2 {\n  @extend %heading;\n  @include font-size($h2-font-size);\n}\n\nh3 {\n  @extend %heading;\n  @include font-size($h3-font-size);\n}\n\nh4 {\n  @extend %heading;\n  @include font-size($h4-font-size);\n}\n\nh5 {\n  @extend %heading;\n  @include font-size($h5-font-size);\n}\n\nh6 {\n  @extend %heading;\n  @include font-size($h6-font-size);\n}\n\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `  `s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\n\np {\n  margin-top: 0;\n  margin-bottom: $paragraph-margin-bottom;\n}\n\n\n// Abbreviations\n//\n// 1. Add the correct text decoration in Chrome, Edge, Opera, and Safari.\n// 2. Add explicit cursor to indicate changed behavior.\n// 3. Prevent the text-decoration to be skipped.\n\nabbr[title] {\n  text-decoration: underline dotted; // 1\n  cursor: help; // 2\n  text-decoration-skip-ink: none; // 3\n}\n\n\n// Address\n\naddress {\n  margin-bottom: 1rem;\n  font-style: normal;\n  line-height: inherit;\n}\n\n\n// Lists\n\nol,\nul {\n  padding-left: 2rem;\n}\n\nol,\nul,\ndl {\n  margin-top: 0;\n  margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n  margin-bottom: 0;\n}\n\ndt {\n  font-weight: $dt-font-weight;\n}\n\n// 1. Undo browser default\n\ndd {\n  margin-bottom: .5rem;\n  margin-left: 0; // 1\n}\n\n\n// Blockquote\n\nblockquote {\n  margin: 0 0 1rem;\n}\n\n\n// Strong\n//\n// Add the correct font weight in Chrome, Edge, and Safari\n\nb,\nstrong {\n  font-weight: $font-weight-bolder;\n}\n\n\n// Small\n//\n// Add the correct font size in all browsers\n\nsmall {\n  @include font-size($small-font-size);\n}\n\n\n// Mark\n\nmark {\n  padding: $mark-padding;\n  background-color: var(--#{$prefix}highlight-bg);\n}\n\n\n// Sub and Sup\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n\nsub,\nsup {\n  position: relative;\n  @include font-size($sub-sup-font-size);\n  line-height: 0;\n  vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n// Links\n\na {\n  color: var(--#{$prefix}link-color);\n  text-decoration: $link-decoration;\n\n  &:hover {\n    color: var(--#{$prefix}link-hover-color);\n    text-decoration: $link-hover-decoration;\n  }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n  &,\n  &:hover {\n    color: inherit;\n    text-decoration: none;\n  }\n}\n\n\n// Code\n\npre,\ncode,\nkbd,\nsamp {\n  font-family: $font-family-code;\n  @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\n// 1. Remove browser default top margin\n// 2. Reset browser default of `1em` to use `rem`s\n// 3. Don't allow content to break outside\n\npre {\n  display: block;\n  margin-top: 0; // 1\n  margin-bottom: 1rem; // 2\n  overflow: auto; // 3\n  @include font-size($code-font-size);\n  color: $pre-color;\n\n  // Account for some code outputs that place code tags in pre tags\n  code {\n    @include font-size(inherit);\n    color: inherit;\n    word-break: normal;\n  }\n}\n\ncode {\n  @include font-size($code-font-size);\n  color: var(--#{$prefix}code-color);\n  word-wrap: break-word;\n\n  // Streamline the style when inside anchors to avoid broken underline and more\n  a > & {\n    color: inherit;\n  }\n}\n\nkbd {\n  padding: $kbd-padding-y $kbd-padding-x;\n  @include font-size($kbd-font-size);\n  color: $kbd-color;\n  background-color: $kbd-bg;\n  @include border-radius($border-radius-sm);\n\n  kbd {\n    padding: 0;\n    @include font-size(1em);\n    font-weight: $nested-kbd-font-weight;\n  }\n}\n\n\n// Figures\n//\n// Apply a consistent margin strategy (matches our type styles).\n\nfigure {\n  margin: 0 0 1rem;\n}\n\n\n// Images and content\n\nimg,\nsvg {\n  vertical-align: middle;\n}\n\n\n// Tables\n//\n// Prevent double borders\n\ntable {\n  caption-side: bottom;\n  border-collapse: collapse;\n}\n\ncaption {\n  padding-top: $table-cell-padding-y;\n  padding-bottom: $table-cell-padding-y;\n  color: $table-caption-color;\n  text-align: left;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `
` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n  font-weight: $table-th-font-weight; // 1\n  text-align: inherit; // 2\n  text-align: -webkit-match-parent; // 3\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n  border-color: inherit;\n  border-style: solid;\n  border-width: 0;\n}\n\n\n// Forms\n//\n// 1. Allow labels to use `margin` for spacing.\n\nlabel {\n  display: inline-block; // 1\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n// See https://github.com/twbs/bootstrap/issues/24093\n\nbutton {\n  // stylelint-disable-next-line property-disallowed-list\n  border-radius: 0;\n}\n\n// Explicitly remove focus outline in Chromium when it shouldn't be\n// visible (e.g. as result of mouse click or touch tap). It already\n// should be doing this automatically, but seems to currently be\n// confused and applies its very visible two-tone outline anyway.\n\nbutton:focus:not(:focus-visible) {\n  outline: 0;\n}\n\n// 1. Remove the margin in Firefox and Safari\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n  margin: 0; // 1\n  font-family: inherit;\n  @include font-size(inherit);\n  line-height: inherit;\n}\n\n// Remove the inheritance of text transform in Firefox\nbutton,\nselect {\n  text-transform: none;\n}\n// Set the cursor for non-`` buttons\n//\n// Details at https://github.com/twbs/bootstrap/pull/30562\n[role=\"button\"] {\n  cursor: pointer;\n}\n\nselect {\n  // Remove the inheritance of word-wrap in Safari.\n  // See https://github.com/twbs/bootstrap/issues/24990\n  word-wrap: normal;\n\n  // Undo the opacity change from Chrome\n  &:disabled {\n    opacity: 1;\n  }\n}\n\n// Remove the dropdown arrow only from text type inputs built with datalists in Chrome.\n// See https://stackoverflow.com/a/54997118\n\n[list]:not([type=\"date\"]):not([type=\"datetime-local\"]):not([type=\"month\"]):not([type=\"week\"]):not([type=\"time\"])::-webkit-calendar-picker-indicator {\n  display: none !important;\n}\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n//    controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\n// 3. Opinionated: add \"hand\" cursor to non-disabled button elements.\n\nbutton,\n[type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n  -webkit-appearance: button; // 2\n\n  @if $enable-button-pointers {\n    &:not(:disabled) {\n      cursor: pointer; // 3\n    }\n  }\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\n\n::-moz-focus-inner {\n  padding: 0;\n  border-style: none;\n}\n\n// 1. Textareas should really only resize vertically so they don't break their (horizontal) containers.\n\ntextarea {\n  resize: vertical; // 1\n}\n\n// 1. Browsers set a default `min-width: min-content;` on fieldsets,\n//    unlike e.g. ``s, which have `min-width: 0;` by default.\n//    So we reset that to ensure fieldsets behave more like a standard block element.\n//    See https://github.com/twbs/bootstrap/issues/12359\n//    and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n// 2. Reset the default outline behavior of fieldsets so they don't affect page layout.\n\nfieldset {\n  min-width: 0; // 1\n  padding: 0; // 2\n  margin: 0; // 2\n  border: 0; // 2\n}\n\n// 1. By using `float: left`, the legend will behave like a block element.\n//    This way the border of a fieldset wraps around the legend if present.\n// 2. Fix wrapping bug.\n//    See https://github.com/twbs/bootstrap/issues/29712\n\nlegend {\n  float: left; // 1\n  width: 100%;\n  padding: 0;\n  margin-bottom: $legend-margin-bottom;\n  @include font-size($legend-font-size);\n  font-weight: $legend-font-weight;\n  line-height: inherit;\n\n  + * {\n    clear: left; // 2\n  }\n}\n\n// Fix height of inputs with a type of datetime-local, date, month, week, or time\n// See https://github.com/twbs/bootstrap/issues/18842\n\n::-webkit-datetime-edit-fields-wrapper,\n::-webkit-datetime-edit-text,\n::-webkit-datetime-edit-minute,\n::-webkit-datetime-edit-hour-field,\n::-webkit-datetime-edit-day-field,\n::-webkit-datetime-edit-month-field,\n::-webkit-datetime-edit-year-field {\n  padding: 0;\n}\n\n::-webkit-inner-spin-button {\n  height: auto;\n}\n\n// 1. Correct the outline style in Safari.\n// 2. This overrides the extra rounded corners on search inputs in iOS so that our\n//    `.form-control` class can properly style them. Note that this cannot simply\n//    be added to `.form-control` as it's not specific enough. For details, see\n//    https://github.com/twbs/bootstrap/issues/11586.\n\n[type=\"search\"] {\n  outline-offset: -2px; // 1\n  -webkit-appearance: textfield; // 2\n}\n\n// 1. A few input types should stay LTR\n// See https://rtlstyling.com/posts/rtl-styling#form-inputs\n// 2. RTL only output\n// See https://rtlcss.com/learn/usage-guide/control-directives/#raw\n\n/* rtl:raw:\n[type=\"tel\"],\n[type=\"url\"],\n[type=\"email\"],\n[type=\"number\"] {\n  direction: ltr;\n}\n*/\n\n// Remove the inner padding in Chrome and Safari on macOS.\n\n::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n// Remove padding around color pickers in webkit browsers\n\n::-webkit-color-swatch-wrapper {\n  padding: 0;\n}\n\n\n// 1. Inherit font family and line height for file input buttons\n// 2. Correct the inability to style clickable types in iOS and Safari.\n\n::file-selector-button {\n  font: inherit; // 1\n  -webkit-appearance: button; // 2\n}\n\n// Correct element displays\n\noutput {\n  display: inline-block;\n}\n\n// Remove border from iframe\n\niframe {\n  border: 0;\n}\n\n// Summary\n//\n// 1. Add the correct display in all browsers\n\nsummary {\n  display: list-item; // 1\n  cursor: pointer;\n}\n\n\n// Progress\n//\n// Add the correct vertical alignment in Chrome, Firefox, and Opera.\n\nprogress {\n  vertical-align: baseline;\n}\n\n\n// Hidden attribute\n//\n// Always hide an element with the `hidden` HTML attribute.\n\n[hidden] {\n  display: none !important;\n}\n","@charset \"UTF-8\";\n/*!\n * Bootstrap  v5.2.3 (https://getbootstrap.com/)\n * Copyright 2011-2022 The Bootstrap Authors\n * Copyright 2011-2022 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n:root {\n  --bs-blue: #0d6efd;\n  --bs-indigo: #6610f2;\n  --bs-purple: #6f42c1;\n  --bs-pink: #d63384;\n  --bs-red: #dc3545;\n  --bs-orange: #fd7e14;\n  --bs-yellow: #ffc107;\n  --bs-green: #198754;\n  --bs-teal: #20c997;\n  --bs-cyan: #0dcaf0;\n  --bs-black: #000;\n  --bs-white: #fff;\n  --bs-gray: #6c757d;\n  --bs-gray-dark: #343a40;\n  --bs-gray-100: #f8f9fa;\n  --bs-gray-200: #e9ecef;\n  --bs-gray-300: #dee2e6;\n  --bs-gray-400: #ced4da;\n  --bs-gray-500: #adb5bd;\n  --bs-gray-600: #6c757d;\n  --bs-gray-700: #495057;\n  --bs-gray-800: #343a40;\n  --bs-gray-900: #212529;\n  --bs-primary: #0d6efd;\n  --bs-secondary: #6c757d;\n  --bs-success: #198754;\n  --bs-info: #0dcaf0;\n  --bs-warning: #ffc107;\n  --bs-danger: #dc3545;\n  --bs-light: #f8f9fa;\n  --bs-dark: #212529;\n  --bs-primary-rgb: 13, 110, 253;\n  --bs-secondary-rgb: 108, 117, 125;\n  --bs-success-rgb: 25, 135, 84;\n  --bs-info-rgb: 13, 202, 240;\n  --bs-warning-rgb: 255, 193, 7;\n  --bs-danger-rgb: 220, 53, 69;\n  --bs-light-rgb: 248, 249, 250;\n  --bs-dark-rgb: 33, 37, 41;\n  --bs-white-rgb: 255, 255, 255;\n  --bs-black-rgb: 0, 0, 0;\n  --bs-body-color-rgb: 33, 37, 41;\n  --bs-body-bg-rgb: 255, 255, 255;\n  --bs-font-sans-serif: system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", \"Noto Sans\", \"Liberation Sans\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n  --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n  --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));\n  --bs-body-font-family: var(--bs-font-sans-serif);\n  --bs-body-font-size: 1rem;\n  --bs-body-font-weight: 400;\n  --bs-body-line-height: 1.5;\n  --bs-body-color: #212529;\n  --bs-body-bg: #fff;\n  --bs-border-width: 1px;\n  --bs-border-style: solid;\n  --bs-border-color: #dee2e6;\n  --bs-border-color-translucent: rgba(0, 0, 0, 0.175);\n  --bs-border-radius: 0.375rem;\n  --bs-border-radius-sm: 0.25rem;\n  --bs-border-radius-lg: 0.5rem;\n  --bs-border-radius-xl: 1rem;\n  --bs-border-radius-2xl: 2rem;\n  --bs-border-radius-pill: 50rem;\n  --bs-link-color: #0d6efd;\n  --bs-link-hover-color: #0a58ca;\n  --bs-code-color: #d63384;\n  --bs-highlight-bg: #fff3cd;\n}\n\n*,\n*::before,\n*::after {\n  box-sizing: border-box;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n  :root {\n    scroll-behavior: smooth;\n  }\n}\n\nbody {\n  margin: 0;\n  font-family: var(--bs-body-font-family);\n  font-size: var(--bs-body-font-size);\n  font-weight: var(--bs-body-font-weight);\n  line-height: var(--bs-body-line-height);\n  color: var(--bs-body-color);\n  text-align: var(--bs-body-text-align);\n  background-color: var(--bs-body-bg);\n  -webkit-text-size-adjust: 100%;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\nhr {\n  margin: 1rem 0;\n  color: inherit;\n  border: 0;\n  border-top: 1px solid;\n  opacity: 0.25;\n}\n\nh6, .h6, h5, .h5, h4, .h4, h3, .h3, h2, .h2, h1, .h1 {\n  margin-top: 0;\n  margin-bottom: 0.5rem;\n  font-weight: 500;\n  line-height: 1.2;\n}\n\nh1, .h1 {\n  font-size: calc(1.375rem + 1.5vw);\n}\n@media (min-width: 1200px) {\n  h1, .h1 {\n    font-size: 2.5rem;\n  }\n}\n\nh2, .h2 {\n  font-size: calc(1.325rem + 0.9vw);\n}\n@media (min-width: 1200px) {\n  h2, .h2 {\n    font-size: 2rem;\n  }\n}\n\nh3, .h3 {\n  font-size: calc(1.3rem + 0.6vw);\n}\n@media (min-width: 1200px) {\n  h3, .h3 {\n    font-size: 1.75rem;\n  }\n}\n\nh4, .h4 {\n  font-size: calc(1.275rem + 0.3vw);\n}\n@media (min-width: 1200px) {\n  h4, .h4 {\n    font-size: 1.5rem;\n  }\n}\n\nh5, .h5 {\n  font-size: 1.25rem;\n}\n\nh6, .h6 {\n  font-size: 1rem;\n}\n\np {\n  margin-top: 0;\n  margin-bottom: 1rem;\n}\n\nabbr[title] {\n  -webkit-text-decoration: underline dotted;\n  text-decoration: underline dotted;\n  cursor: help;\n  -webkit-text-decoration-skip-ink: none;\n  text-decoration-skip-ink: none;\n}\n\naddress {\n  margin-bottom: 1rem;\n  font-style: normal;\n  line-height: inherit;\n}\n\nol,\nul {\n  padding-left: 2rem;\n}\n\nol,\nul,\ndl {\n  margin-top: 0;\n  margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n  margin-bottom: 0;\n}\n\ndt {\n  font-weight: 700;\n}\n\ndd {\n  margin-bottom: 0.5rem;\n  margin-left: 0;\n}\n\nblockquote {\n  margin: 0 0 1rem;\n}\n\nb,\nstrong {\n  font-weight: bolder;\n}\n\nsmall, .small {\n  font-size: 0.875em;\n}\n\nmark, .mark {\n  padding: 0.1875em;\n  background-color: var(--bs-highlight-bg);\n}\n\nsub,\nsup {\n  position: relative;\n  font-size: 0.75em;\n  line-height: 0;\n  vertical-align: baseline;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nsup {\n  top: -0.5em;\n}\n\na {\n  color: var(--bs-link-color);\n  text-decoration: underline;\n}\na:hover {\n  color: var(--bs-link-hover-color);\n}\n\na:not([href]):not([class]), a:not([href]):not([class]):hover {\n  color: inherit;\n  text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n  font-family: var(--bs-font-monospace);\n  font-size: 1em;\n}\n\npre {\n  display: block;\n  margin-top: 0;\n  margin-bottom: 1rem;\n  overflow: auto;\n  font-size: 0.875em;\n}\npre code {\n  font-size: inherit;\n  color: inherit;\n  word-break: normal;\n}\n\ncode {\n  font-size: 0.875em;\n  color: var(--bs-code-color);\n  word-wrap: break-word;\n}\na > code {\n  color: inherit;\n}\n\nkbd {\n  padding: 0.1875rem 0.375rem;\n  font-size: 0.875em;\n  color: var(--bs-body-bg);\n  background-color: var(--bs-body-color);\n  border-radius: 0.25rem;\n}\nkbd kbd {\n  padding: 0;\n  font-size: 1em;\n}\n\nfigure {\n  margin: 0 0 1rem;\n}\n\nimg,\nsvg {\n  vertical-align: middle;\n}\n\ntable {\n  caption-side: bottom;\n  border-collapse: collapse;\n}\n\ncaption {\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n  color: #6c757d;\n  text-align: left;\n}\n\nth {\n  text-align: inherit;\n  text-align: -webkit-match-parent;\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n  border-color: inherit;\n  border-style: solid;\n  border-width: 0;\n}\n\nlabel {\n  display: inline-block;\n}\n\nbutton {\n  border-radius: 0;\n}\n\nbutton:focus:not(:focus-visible) {\n  outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n  margin: 0;\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n[role=button] {\n  cursor: pointer;\n}\n\nselect {\n  word-wrap: normal;\n}\nselect:disabled {\n  opacity: 1;\n}\n\n[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {\n  display: none !important;\n}\n\nbutton,\n[type=button],\n[type=reset],\n[type=submit] {\n  -webkit-appearance: button;\n}\nbutton:not(:disabled),\n[type=button]:not(:disabled),\n[type=reset]:not(:disabled),\n[type=submit]:not(:disabled) {\n  cursor: pointer;\n}\n\n::-moz-focus-inner {\n  padding: 0;\n  border-style: none;\n}\n\ntextarea {\n  resize: vertical;\n}\n\nfieldset {\n  min-width: 0;\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\n\nlegend {\n  float: left;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 0.5rem;\n  font-size: calc(1.275rem + 0.3vw);\n  line-height: inherit;\n}\n@media (min-width: 1200px) {\n  legend {\n    font-size: 1.5rem;\n  }\n}\nlegend + * {\n  clear: left;\n}\n\n::-webkit-datetime-edit-fields-wrapper,\n::-webkit-datetime-edit-text,\n::-webkit-datetime-edit-minute,\n::-webkit-datetime-edit-hour-field,\n::-webkit-datetime-edit-day-field,\n::-webkit-datetime-edit-month-field,\n::-webkit-datetime-edit-year-field {\n  padding: 0;\n}\n\n::-webkit-inner-spin-button {\n  height: auto;\n}\n\n[type=search] {\n  outline-offset: -2px;\n  -webkit-appearance: textfield;\n}\n\n/* rtl:raw:\n[type=\"tel\"],\n[type=\"url\"],\n[type=\"email\"],\n[type=\"number\"] {\n  direction: ltr;\n}\n*/\n::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n::-webkit-color-swatch-wrapper {\n  padding: 0;\n}\n\n::-webkit-file-upload-button {\n  font: inherit;\n  -webkit-appearance: button;\n}\n\n::file-selector-button {\n  font: inherit;\n  -webkit-appearance: button;\n}\n\noutput {\n  display: inline-block;\n}\n\niframe {\n  border: 0;\n}\n\nsummary {\n  display: list-item;\n  cursor: pointer;\n}\n\nprogress {\n  vertical-align: baseline;\n}\n\n[hidden] {\n  display: none !important;\n}\n\n.lead {\n  font-size: 1.25rem;\n  font-weight: 300;\n}\n\n.display-1 {\n  font-size: calc(1.625rem + 4.5vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-1 {\n    font-size: 5rem;\n  }\n}\n\n.display-2 {\n  font-size: calc(1.575rem + 3.9vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-2 {\n    font-size: 4.5rem;\n  }\n}\n\n.display-3 {\n  font-size: calc(1.525rem + 3.3vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-3 {\n    font-size: 4rem;\n  }\n}\n\n.display-4 {\n  font-size: calc(1.475rem + 2.7vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-4 {\n    font-size: 3.5rem;\n  }\n}\n\n.display-5 {\n  font-size: calc(1.425rem + 2.1vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-5 {\n    font-size: 3rem;\n  }\n}\n\n.display-6 {\n  font-size: calc(1.375rem + 1.5vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-6 {\n    font-size: 2.5rem;\n  }\n}\n\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n\n.list-inline {\n  padding-left: 0;\n  list-style: none;\n}\n\n.list-inline-item {\n  display: inline-block;\n}\n.list-inline-item:not(:last-child) {\n  margin-right: 0.5rem;\n}\n\n.initialism {\n  font-size: 0.875em;\n  text-transform: uppercase;\n}\n\n.blockquote {\n  margin-bottom: 1rem;\n  font-size: 1.25rem;\n}\n.blockquote > :last-child {\n  margin-bottom: 0;\n}\n\n.blockquote-footer {\n  margin-top: -1rem;\n  margin-bottom: 1rem;\n  font-size: 0.875em;\n  color: #6c757d;\n}\n.blockquote-footer::before {\n  content: \"— \";\n}\n\n.img-fluid {\n  max-width: 100%;\n  height: auto;\n}\n\n.img-thumbnail {\n  padding: 0.25rem;\n  background-color: #fff;\n  border: 1px solid var(--bs-border-color);\n  border-radius: 0.375rem;\n  max-width: 100%;\n  height: auto;\n}\n\n.figure {\n  display: inline-block;\n}\n\n.figure-img {\n  margin-bottom: 0.5rem;\n  line-height: 1;\n}\n\n.figure-caption {\n  font-size: 0.875em;\n  color: #6c757d;\n}\n\n.container,\n.container-fluid,\n.container-xxl,\n.container-xl,\n.container-lg,\n.container-md,\n.container-sm {\n  --bs-gutter-x: 1.5rem;\n  --bs-gutter-y: 0;\n  width: 100%;\n  padding-right: calc(var(--bs-gutter-x) * 0.5);\n  padding-left: calc(var(--bs-gutter-x) * 0.5);\n  margin-right: auto;\n  margin-left: auto;\n}\n\n@media (min-width: 576px) {\n  .container-sm, .container {\n    max-width: 540px;\n  }\n}\n@media (min-width: 768px) {\n  .container-md, .container-sm, .container {\n    max-width: 720px;\n  }\n}\n@media (min-width: 992px) {\n  .container-lg, .container-md, .container-sm, .container {\n    max-width: 960px;\n  }\n}\n@media (min-width: 1200px) {\n  .container-xl, .container-lg, .container-md, .container-sm, .container {\n    max-width: 1140px;\n  }\n}\n@media (min-width: 1400px) {\n  .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container {\n    max-width: 1320px;\n  }\n}\n.row {\n  --bs-gutter-x: 1.5rem;\n  --bs-gutter-y: 0;\n  display: flex;\n  flex-wrap: wrap;\n  margin-top: calc(-1 * var(--bs-gutter-y));\n  margin-right: calc(-0.5 * var(--bs-gutter-x));\n  margin-left: calc(-0.5 * var(--bs-gutter-x));\n}\n.row > * {\n  flex-shrink: 0;\n  width: 100%;\n  max-width: 100%;\n  padding-right: calc(var(--bs-gutter-x) * 0.5);\n  padding-left: calc(var(--bs-gutter-x) * 0.5);\n  margin-top: var(--bs-gutter-y);\n}\n\n.col {\n  flex: 1 0 0%;\n}\n\n.row-cols-auto > * {\n  flex: 0 0 auto;\n  width: auto;\n}\n\n.row-cols-1 > * {\n  flex: 0 0 auto;\n  width: 100%;\n}\n\n.row-cols-2 > * {\n  flex: 0 0 auto;\n  width: 50%;\n}\n\n.row-cols-3 > * {\n  flex: 0 0 auto;\n  width: 33.3333333333%;\n}\n\n.row-cols-4 > * {\n  flex: 0 0 auto;\n  width: 25%;\n}\n\n.row-cols-5 > * {\n  flex: 0 0 auto;\n  width: 20%;\n}\n\n.row-cols-6 > * {\n  flex: 0 0 auto;\n  width: 16.6666666667%;\n}\n\n.col-auto {\n  flex: 0 0 auto;\n  width: auto;\n}\n\n.col-1 {\n  flex: 0 0 auto;\n  width: 8.33333333%;\n}\n\n.col-2 {\n  flex: 0 0 auto;\n  width: 16.66666667%;\n}\n\n.col-3 {\n  flex: 0 0 auto;\n  width: 25%;\n}\n\n.col-4 {\n  flex: 0 0 auto;\n  width: 33.33333333%;\n}\n\n.col-5 {\n  flex: 0 0 auto;\n  width: 41.66666667%;\n}\n\n.col-6 {\n  flex: 0 0 auto;\n  width: 50%;\n}\n\n.col-7 {\n  flex: 0 0 auto;\n  width: 58.33333333%;\n}\n\n.col-8 {\n  flex: 0 0 auto;\n  width: 66.66666667%;\n}\n\n.col-9 {\n  flex: 0 0 auto;\n  width: 75%;\n}\n\n.col-10 {\n  flex: 0 0 auto;\n  width: 83.33333333%;\n}\n\n.col-11 {\n  flex: 0 0 auto;\n  width: 91.66666667%;\n}\n\n.col-12 {\n  flex: 0 0 auto;\n  width: 100%;\n}\n\n.offset-1 {\n  margin-left: 8.33333333%;\n}\n\n.offset-2 {\n  margin-left: 16.66666667%;\n}\n\n.offset-3 {\n  margin-left: 25%;\n}\n\n.offset-4 {\n  margin-left: 33.33333333%;\n}\n\n.offset-5 {\n  margin-left: 41.66666667%;\n}\n\n.offset-6 {\n  margin-left: 50%;\n}\n\n.offset-7 {\n  margin-left: 58.33333333%;\n}\n\n.offset-8 {\n  margin-left: 66.66666667%;\n}\n\n.offset-9 {\n  margin-left: 75%;\n}\n\n.offset-10 {\n  margin-left: 83.33333333%;\n}\n\n.offset-11 {\n  margin-left: 91.66666667%;\n}\n\n.g-0,\n.gx-0 {\n  --bs-gutter-x: 0;\n}\n\n.g-0,\n.gy-0 {\n  --bs-gutter-y: 0;\n}\n\n.g-1,\n.gx-1 {\n  --bs-gutter-x: 0.25rem;\n}\n\n.g-1,\n.gy-1 {\n  --bs-gutter-y: 0.25rem;\n}\n\n.g-2,\n.gx-2 {\n  --bs-gutter-x: 0.5rem;\n}\n\n.g-2,\n.gy-2 {\n  --bs-gutter-y: 0.5rem;\n}\n\n.g-3,\n.gx-3 {\n  --bs-gutter-x: 1rem;\n}\n\n.g-3,\n.gy-3 {\n  --bs-gutter-y: 1rem;\n}\n\n.g-4,\n.gx-4 {\n  --bs-gutter-x: 1.5rem;\n}\n\n.g-4,\n.gy-4 {\n  --bs-gutter-y: 1.5rem;\n}\n\n.g-5,\n.gx-5 {\n  --bs-gutter-x: 3rem;\n}\n\n.g-5,\n.gy-5 {\n  --bs-gutter-y: 3rem;\n}\n\n@media (min-width: 576px) {\n  .col-sm {\n    flex: 1 0 0%;\n  }\n  .row-cols-sm-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .row-cols-sm-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .row-cols-sm-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .row-cols-sm-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n  .row-cols-sm-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .row-cols-sm-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n  .row-cols-sm-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n  .col-sm-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .col-sm-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n  .col-sm-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n  .col-sm-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .col-sm-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n  .col-sm-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n  .col-sm-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .col-sm-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n  .col-sm-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n  .col-sm-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n  .col-sm-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n  .col-sm-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n  .col-sm-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .offset-sm-0 {\n    margin-left: 0;\n  }\n  .offset-sm-1 {\n    margin-left: 8.33333333%;\n  }\n  .offset-sm-2 {\n    margin-left: 16.66666667%;\n  }\n  .offset-sm-3 {\n    margin-left: 25%;\n  }\n  .offset-sm-4 {\n    margin-left: 33.33333333%;\n  }\n  .offset-sm-5 {\n    margin-left: 41.66666667%;\n  }\n  .offset-sm-6 {\n    margin-left: 50%;\n  }\n  .offset-sm-7 {\n    margin-left: 58.33333333%;\n  }\n  .offset-sm-8 {\n    margin-left: 66.66666667%;\n  }\n  .offset-sm-9 {\n    margin-left: 75%;\n  }\n  .offset-sm-10 {\n    margin-left: 83.33333333%;\n  }\n  .offset-sm-11 {\n    margin-left: 91.66666667%;\n  }\n  .g-sm-0,\n.gx-sm-0 {\n    --bs-gutter-x: 0;\n  }\n  .g-sm-0,\n.gy-sm-0 {\n    --bs-gutter-y: 0;\n  }\n  .g-sm-1,\n.gx-sm-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n  .g-sm-1,\n.gy-sm-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n  .g-sm-2,\n.gx-sm-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n  .g-sm-2,\n.gy-sm-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n  .g-sm-3,\n.gx-sm-3 {\n    --bs-gutter-x: 1rem;\n  }\n  .g-sm-3,\n.gy-sm-3 {\n    --bs-gutter-y: 1rem;\n  }\n  .g-sm-4,\n.gx-sm-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n  .g-sm-4,\n.gy-sm-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n  .g-sm-5,\n.gx-sm-5 {\n    --bs-gutter-x: 3rem;\n  }\n  .g-sm-5,\n.gy-sm-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 768px) {\n  .col-md {\n    flex: 1 0 0%;\n  }\n  .row-cols-md-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .row-cols-md-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .row-cols-md-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .row-cols-md-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n  .row-cols-md-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .row-cols-md-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n  .row-cols-md-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n  .col-md-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .col-md-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n  .col-md-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n  .col-md-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .col-md-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n  .col-md-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n  .col-md-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .col-md-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n  .col-md-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n  .col-md-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n  .col-md-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n  .col-md-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n  .col-md-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .offset-md-0 {\n    margin-left: 0;\n  }\n  .offset-md-1 {\n    margin-left: 8.33333333%;\n  }\n  .offset-md-2 {\n    margin-left: 16.66666667%;\n  }\n  .offset-md-3 {\n    margin-left: 25%;\n  }\n  .offset-md-4 {\n    margin-left: 33.33333333%;\n  }\n  .offset-md-5 {\n    margin-left: 41.66666667%;\n  }\n  .offset-md-6 {\n    margin-left: 50%;\n  }\n  .offset-md-7 {\n    margin-left: 58.33333333%;\n  }\n  .offset-md-8 {\n    margin-left: 66.66666667%;\n  }\n  .offset-md-9 {\n    margin-left: 75%;\n  }\n  .offset-md-10 {\n    margin-left: 83.33333333%;\n  }\n  .offset-md-11 {\n    margin-left: 91.66666667%;\n  }\n  .g-md-0,\n.gx-md-0 {\n    --bs-gutter-x: 0;\n  }\n  .g-md-0,\n.gy-md-0 {\n    --bs-gutter-y: 0;\n  }\n  .g-md-1,\n.gx-md-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n  .g-md-1,\n.gy-md-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n  .g-md-2,\n.gx-md-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n  .g-md-2,\n.gy-md-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n  .g-md-3,\n.gx-md-3 {\n    --bs-gutter-x: 1rem;\n  }\n  .g-md-3,\n.gy-md-3 {\n    --bs-gutter-y: 1rem;\n  }\n  .g-md-4,\n.gx-md-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n  .g-md-4,\n.gy-md-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n  .g-md-5,\n.gx-md-5 {\n    --bs-gutter-x: 3rem;\n  }\n  .g-md-5,\n.gy-md-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 992px) {\n  .col-lg {\n    flex: 1 0 0%;\n  }\n  .row-cols-lg-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .row-cols-lg-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .row-cols-lg-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .row-cols-lg-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n  .row-cols-lg-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .row-cols-lg-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n  .row-cols-lg-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n  .col-lg-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .col-lg-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n  .col-lg-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n  .col-lg-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .col-lg-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n  .col-lg-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n  .col-lg-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .col-lg-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n  .col-lg-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n  .col-lg-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n  .col-lg-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n  .col-lg-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n  .col-lg-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .offset-lg-0 {\n    margin-left: 0;\n  }\n  .offset-lg-1 {\n    margin-left: 8.33333333%;\n  }\n  .offset-lg-2 {\n    margin-left: 16.66666667%;\n  }\n  .offset-lg-3 {\n    margin-left: 25%;\n  }\n  .offset-lg-4 {\n    margin-left: 33.33333333%;\n  }\n  .offset-lg-5 {\n    margin-left: 41.66666667%;\n  }\n  .offset-lg-6 {\n    margin-left: 50%;\n  }\n  .offset-lg-7 {\n    margin-left: 58.33333333%;\n  }\n  .offset-lg-8 {\n    margin-left: 66.66666667%;\n  }\n  .offset-lg-9 {\n    margin-left: 75%;\n  }\n  .offset-lg-10 {\n    margin-left: 83.33333333%;\n  }\n  .offset-lg-11 {\n    margin-left: 91.66666667%;\n  }\n  .g-lg-0,\n.gx-lg-0 {\n    --bs-gutter-x: 0;\n  }\n  .g-lg-0,\n.gy-lg-0 {\n    --bs-gutter-y: 0;\n  }\n  .g-lg-1,\n.gx-lg-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n  .g-lg-1,\n.gy-lg-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n  .g-lg-2,\n.gx-lg-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n  .g-lg-2,\n.gy-lg-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n  .g-lg-3,\n.gx-lg-3 {\n    --bs-gutter-x: 1rem;\n  }\n  .g-lg-3,\n.gy-lg-3 {\n    --bs-gutter-y: 1rem;\n  }\n  .g-lg-4,\n.gx-lg-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n  .g-lg-4,\n.gy-lg-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n  .g-lg-5,\n.gx-lg-5 {\n    --bs-gutter-x: 3rem;\n  }\n  .g-lg-5,\n.gy-lg-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 1200px) {\n  .col-xl {\n    flex: 1 0 0%;\n  }\n  .row-cols-xl-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .row-cols-xl-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .row-cols-xl-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .row-cols-xl-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n  .row-cols-xl-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .row-cols-xl-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n  .row-cols-xl-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n  .col-xl-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .col-xl-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n  .col-xl-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n  .col-xl-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .col-xl-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n  .col-xl-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n  .col-xl-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .col-xl-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n  .col-xl-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n  .col-xl-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n  .col-xl-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n  .col-xl-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n  .col-xl-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .offset-xl-0 {\n    margin-left: 0;\n  }\n  .offset-xl-1 {\n    margin-left: 8.33333333%;\n  }\n  .offset-xl-2 {\n    margin-left: 16.66666667%;\n  }\n  .offset-xl-3 {\n    margin-left: 25%;\n  }\n  .offset-xl-4 {\n    margin-left: 33.33333333%;\n  }\n  .offset-xl-5 {\n    margin-left: 41.66666667%;\n  }\n  .offset-xl-6 {\n    margin-left: 50%;\n  }\n  .offset-xl-7 {\n    margin-left: 58.33333333%;\n  }\n  .offset-xl-8 {\n    margin-left: 66.66666667%;\n  }\n  .offset-xl-9 {\n    margin-left: 75%;\n  }\n  .offset-xl-10 {\n    margin-left: 83.33333333%;\n  }\n  .offset-xl-11 {\n    margin-left: 91.66666667%;\n  }\n  .g-xl-0,\n.gx-xl-0 {\n    --bs-gutter-x: 0;\n  }\n  .g-xl-0,\n.gy-xl-0 {\n    --bs-gutter-y: 0;\n  }\n  .g-xl-1,\n.gx-xl-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n  .g-xl-1,\n.gy-xl-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n  .g-xl-2,\n.gx-xl-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n  .g-xl-2,\n.gy-xl-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n  .g-xl-3,\n.gx-xl-3 {\n    --bs-gutter-x: 1rem;\n  }\n  .g-xl-3,\n.gy-xl-3 {\n    --bs-gutter-y: 1rem;\n  }\n  .g-xl-4,\n.gx-xl-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n  .g-xl-4,\n.gy-xl-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n  .g-xl-5,\n.gx-xl-5 {\n    --bs-gutter-x: 3rem;\n  }\n  .g-xl-5,\n.gy-xl-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 1400px) {\n  .col-xxl {\n    flex: 1 0 0%;\n  }\n  .row-cols-xxl-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .row-cols-xxl-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .row-cols-xxl-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .row-cols-xxl-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n  .row-cols-xxl-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .row-cols-xxl-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n  .row-cols-xxl-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n  .col-xxl-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .col-xxl-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n  .col-xxl-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n  .col-xxl-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .col-xxl-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n  .col-xxl-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n  .col-xxl-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .col-xxl-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n  .col-xxl-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n  .col-xxl-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n  .col-xxl-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n  .col-xxl-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n  .col-xxl-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .offset-xxl-0 {\n    margin-left: 0;\n  }\n  .offset-xxl-1 {\n    margin-left: 8.33333333%;\n  }\n  .offset-xxl-2 {\n    margin-left: 16.66666667%;\n  }\n  .offset-xxl-3 {\n    margin-left: 25%;\n  }\n  .offset-xxl-4 {\n    margin-left: 33.33333333%;\n  }\n  .offset-xxl-5 {\n    margin-left: 41.66666667%;\n  }\n  .offset-xxl-6 {\n    margin-left: 50%;\n  }\n  .offset-xxl-7 {\n    margin-left: 58.33333333%;\n  }\n  .offset-xxl-8 {\n    margin-left: 66.66666667%;\n  }\n  .offset-xxl-9 {\n    margin-left: 75%;\n  }\n  .offset-xxl-10 {\n    margin-left: 83.33333333%;\n  }\n  .offset-xxl-11 {\n    margin-left: 91.66666667%;\n  }\n  .g-xxl-0,\n.gx-xxl-0 {\n    --bs-gutter-x: 0;\n  }\n  .g-xxl-0,\n.gy-xxl-0 {\n    --bs-gutter-y: 0;\n  }\n  .g-xxl-1,\n.gx-xxl-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n  .g-xxl-1,\n.gy-xxl-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n  .g-xxl-2,\n.gx-xxl-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n  .g-xxl-2,\n.gy-xxl-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n  .g-xxl-3,\n.gx-xxl-3 {\n    --bs-gutter-x: 1rem;\n  }\n  .g-xxl-3,\n.gy-xxl-3 {\n    --bs-gutter-y: 1rem;\n  }\n  .g-xxl-4,\n.gx-xxl-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n  .g-xxl-4,\n.gy-xxl-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n  .g-xxl-5,\n.gx-xxl-5 {\n    --bs-gutter-x: 3rem;\n  }\n  .g-xxl-5,\n.gy-xxl-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n.table {\n  --bs-table-color: var(--bs-body-color);\n  --bs-table-bg: transparent;\n  --bs-table-border-color: var(--bs-border-color);\n  --bs-table-accent-bg: transparent;\n  --bs-table-striped-color: var(--bs-body-color);\n  --bs-table-striped-bg: rgba(0, 0, 0, 0.05);\n  --bs-table-active-color: var(--bs-body-color);\n  --bs-table-active-bg: rgba(0, 0, 0, 0.1);\n  --bs-table-hover-color: var(--bs-body-color);\n  --bs-table-hover-bg: rgba(0, 0, 0, 0.075);\n  width: 100%;\n  margin-bottom: 1rem;\n  color: var(--bs-table-color);\n  vertical-align: top;\n  border-color: var(--bs-table-border-color);\n}\n.table > :not(caption) > * > * {\n  padding: 0.5rem 0.5rem;\n  background-color: var(--bs-table-bg);\n  border-bottom-width: 1px;\n  box-shadow: inset 0 0 0 9999px var(--bs-table-accent-bg);\n}\n.table > tbody {\n  vertical-align: inherit;\n}\n.table > thead {\n  vertical-align: bottom;\n}\n\n.table-group-divider {\n  border-top: 2px solid currentcolor;\n}\n\n.caption-top {\n  caption-side: top;\n}\n\n.table-sm > :not(caption) > * > * {\n  padding: 0.25rem 0.25rem;\n}\n\n.table-bordered > :not(caption) > * {\n  border-width: 1px 0;\n}\n.table-bordered > :not(caption) > * > * {\n  border-width: 0 1px;\n}\n\n.table-borderless > :not(caption) > * > * {\n  border-bottom-width: 0;\n}\n.table-borderless > :not(:first-child) {\n  border-top-width: 0;\n}\n\n.table-striped > tbody > tr:nth-of-type(odd) > * {\n  --bs-table-accent-bg: var(--bs-table-striped-bg);\n  color: var(--bs-table-striped-color);\n}\n\n.table-striped-columns > :not(caption) > tr > :nth-child(even) {\n  --bs-table-accent-bg: var(--bs-table-striped-bg);\n  color: var(--bs-table-striped-color);\n}\n\n.table-active {\n  --bs-table-accent-bg: var(--bs-table-active-bg);\n  color: var(--bs-table-active-color);\n}\n\n.table-hover > tbody > tr:hover > * {\n  --bs-table-accent-bg: var(--bs-table-hover-bg);\n  color: var(--bs-table-hover-color);\n}\n\n.table-primary {\n  --bs-table-color: #000;\n  --bs-table-bg: #cfe2ff;\n  --bs-table-border-color: #bacbe6;\n  --bs-table-striped-bg: #c5d7f2;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #bacbe6;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #bfd1ec;\n  --bs-table-hover-color: #000;\n  color: var(--bs-table-color);\n  border-color: var(--bs-table-border-color);\n}\n\n.table-secondary {\n  --bs-table-color: #000;\n  --bs-table-bg: #e2e3e5;\n  --bs-table-border-color: #cbccce;\n  --bs-table-striped-bg: #d7d8da;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #cbccce;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #d1d2d4;\n  --bs-table-hover-color: #000;\n  color: var(--bs-table-color);\n  border-color: var(--bs-table-border-color);\n}\n\n.table-success {\n  --bs-table-color: #000;\n  --bs-table-bg: #d1e7dd;\n  --bs-table-border-color: #bcd0c7;\n  --bs-table-striped-bg: #c7dbd2;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #bcd0c7;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #c1d6cc;\n  --bs-table-hover-color: #000;\n  color: var(--bs-table-color);\n  border-color: var(--bs-table-border-color);\n}\n\n.table-info {\n  --bs-table-color: #000;\n  --bs-table-bg: #cff4fc;\n  --bs-table-border-color: #badce3;\n  --bs-table-striped-bg: #c5e8ef;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #badce3;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #bfe2e9;\n  --bs-table-hover-color: #000;\n  color: var(--bs-table-color);\n  border-color: var(--bs-table-border-color);\n}\n\n.table-warning {\n  --bs-table-color: #000;\n  --bs-table-bg: #fff3cd;\n  --bs-table-border-color: #e6dbb9;\n  --bs-table-striped-bg: #f2e7c3;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #e6dbb9;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #ece1be;\n  --bs-table-hover-color: #000;\n  color: var(--bs-table-color);\n  border-color: var(--bs-table-border-color);\n}\n\n.table-danger {\n  --bs-table-color: #000;\n  --bs-table-bg: #f8d7da;\n  --bs-table-border-color: #dfc2c4;\n  --bs-table-striped-bg: #eccccf;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #dfc2c4;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #e5c7ca;\n  --bs-table-hover-color: #000;\n  color: var(--bs-table-color);\n  border-color: var(--bs-table-border-color);\n}\n\n.table-light {\n  --bs-table-color: #000;\n  --bs-table-bg: #f8f9fa;\n  --bs-table-border-color: #dfe0e1;\n  --bs-table-striped-bg: #ecedee;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #dfe0e1;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #e5e6e7;\n  --bs-table-hover-color: #000;\n  color: var(--bs-table-color);\n  border-color: var(--bs-table-border-color);\n}\n\n.table-dark {\n  --bs-table-color: #fff;\n  --bs-table-bg: #212529;\n  --bs-table-border-color: #373b3e;\n  --bs-table-striped-bg: #2c3034;\n  --bs-table-striped-color: #fff;\n  --bs-table-active-bg: #373b3e;\n  --bs-table-active-color: #fff;\n  --bs-table-hover-bg: #323539;\n  --bs-table-hover-color: #fff;\n  color: var(--bs-table-color);\n  border-color: var(--bs-table-border-color);\n}\n\n.table-responsive {\n  overflow-x: auto;\n  -webkit-overflow-scrolling: touch;\n}\n\n@media (max-width: 575.98px) {\n  .table-responsive-sm {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n@media (max-width: 767.98px) {\n  .table-responsive-md {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n@media (max-width: 991.98px) {\n  .table-responsive-lg {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n@media (max-width: 1199.98px) {\n  .table-responsive-xl {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n@media (max-width: 1399.98px) {\n  .table-responsive-xxl {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n.form-label {\n  margin-bottom: 0.5rem;\n}\n\n.col-form-label {\n  padding-top: calc(0.375rem + 1px);\n  padding-bottom: calc(0.375rem + 1px);\n  margin-bottom: 0;\n  font-size: inherit;\n  line-height: 1.5;\n}\n\n.col-form-label-lg {\n  padding-top: calc(0.5rem + 1px);\n  padding-bottom: calc(0.5rem + 1px);\n  font-size: 1.25rem;\n}\n\n.col-form-label-sm {\n  padding-top: calc(0.25rem + 1px);\n  padding-bottom: calc(0.25rem + 1px);\n  font-size: 0.875rem;\n}\n\n.form-text {\n  margin-top: 0.25rem;\n  font-size: 0.875em;\n  color: #6c757d;\n}\n\n.form-control {\n  display: block;\n  width: 100%;\n  padding: 0.375rem 0.75rem;\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.5;\n  color: #212529;\n  background-color: #fff;\n  background-clip: padding-box;\n  border: 1px solid #ced4da;\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n  border-radius: 0.375rem;\n  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-control {\n    transition: none;\n  }\n}\n.form-control[type=file] {\n  overflow: hidden;\n}\n.form-control[type=file]:not(:disabled):not([readonly]) {\n  cursor: pointer;\n}\n.form-control:focus {\n  color: #212529;\n  background-color: #fff;\n  border-color: #86b7fe;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-control::-webkit-date-and-time-value {\n  height: 1.5em;\n}\n.form-control::-moz-placeholder {\n  color: #6c757d;\n  opacity: 1;\n}\n.form-control::placeholder {\n  color: #6c757d;\n  opacity: 1;\n}\n.form-control:disabled {\n  background-color: #e9ecef;\n  opacity: 1;\n}\n.form-control::-webkit-file-upload-button {\n  padding: 0.375rem 0.75rem;\n  margin: -0.375rem -0.75rem;\n  -webkit-margin-end: 0.75rem;\n  margin-inline-end: 0.75rem;\n  color: #212529;\n  background-color: #e9ecef;\n  pointer-events: none;\n  border-color: inherit;\n  border-style: solid;\n  border-width: 0;\n  border-inline-end-width: 1px;\n  border-radius: 0;\n  -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n.form-control::file-selector-button {\n  padding: 0.375rem 0.75rem;\n  margin: -0.375rem -0.75rem;\n  -webkit-margin-end: 0.75rem;\n  margin-inline-end: 0.75rem;\n  color: #212529;\n  background-color: #e9ecef;\n  pointer-events: none;\n  border-color: inherit;\n  border-style: solid;\n  border-width: 0;\n  border-inline-end-width: 1px;\n  border-radius: 0;\n  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-control::-webkit-file-upload-button {\n    -webkit-transition: none;\n    transition: none;\n  }\n  .form-control::file-selector-button {\n    transition: none;\n  }\n}\n.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button {\n  background-color: #dde0e3;\n}\n.form-control:hover:not(:disabled):not([readonly])::file-selector-button {\n  background-color: #dde0e3;\n}\n\n.form-control-plaintext {\n  display: block;\n  width: 100%;\n  padding: 0.375rem 0;\n  margin-bottom: 0;\n  line-height: 1.5;\n  color: #212529;\n  background-color: transparent;\n  border: solid transparent;\n  border-width: 1px 0;\n}\n.form-control-plaintext:focus {\n  outline: 0;\n}\n.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg {\n  padding-right: 0;\n  padding-left: 0;\n}\n\n.form-control-sm {\n  min-height: calc(1.5em + 0.5rem + 2px);\n  padding: 0.25rem 0.5rem;\n  font-size: 0.875rem;\n  border-radius: 0.25rem;\n}\n.form-control-sm::-webkit-file-upload-button {\n  padding: 0.25rem 0.5rem;\n  margin: -0.25rem -0.5rem;\n  -webkit-margin-end: 0.5rem;\n  margin-inline-end: 0.5rem;\n}\n.form-control-sm::file-selector-button {\n  padding: 0.25rem 0.5rem;\n  margin: -0.25rem -0.5rem;\n  -webkit-margin-end: 0.5rem;\n  margin-inline-end: 0.5rem;\n}\n\n.form-control-lg {\n  min-height: calc(1.5em + 1rem + 2px);\n  padding: 0.5rem 1rem;\n  font-size: 1.25rem;\n  border-radius: 0.5rem;\n}\n.form-control-lg::-webkit-file-upload-button {\n  padding: 0.5rem 1rem;\n  margin: -0.5rem -1rem;\n  -webkit-margin-end: 1rem;\n  margin-inline-end: 1rem;\n}\n.form-control-lg::file-selector-button {\n  padding: 0.5rem 1rem;\n  margin: -0.5rem -1rem;\n  -webkit-margin-end: 1rem;\n  margin-inline-end: 1rem;\n}\n\ntextarea.form-control {\n  min-height: calc(1.5em + 0.75rem + 2px);\n}\ntextarea.form-control-sm {\n  min-height: calc(1.5em + 0.5rem + 2px);\n}\ntextarea.form-control-lg {\n  min-height: calc(1.5em + 1rem + 2px);\n}\n\n.form-control-color {\n  width: 3rem;\n  height: calc(1.5em + 0.75rem + 2px);\n  padding: 0.375rem;\n}\n.form-control-color:not(:disabled):not([readonly]) {\n  cursor: pointer;\n}\n.form-control-color::-moz-color-swatch {\n  border: 0 !important;\n  border-radius: 0.375rem;\n}\n.form-control-color::-webkit-color-swatch {\n  border-radius: 0.375rem;\n}\n.form-control-color.form-control-sm {\n  height: calc(1.5em + 0.5rem + 2px);\n}\n.form-control-color.form-control-lg {\n  height: calc(1.5em + 1rem + 2px);\n}\n\n.form-select {\n  display: block;\n  width: 100%;\n  padding: 0.375rem 2.25rem 0.375rem 0.75rem;\n  -moz-padding-start: calc(0.75rem - 3px);\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.5;\n  color: #212529;\n  background-color: #fff;\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e\");\n  background-repeat: no-repeat;\n  background-position: right 0.75rem center;\n  background-size: 16px 12px;\n  border: 1px solid #ced4da;\n  border-radius: 0.375rem;\n  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-select {\n    transition: none;\n  }\n}\n.form-select:focus {\n  border-color: #86b7fe;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-select[multiple], .form-select[size]:not([size=\"1\"]) {\n  padding-right: 0.75rem;\n  background-image: none;\n}\n.form-select:disabled {\n  background-color: #e9ecef;\n}\n.form-select:-moz-focusring {\n  color: transparent;\n  text-shadow: 0 0 0 #212529;\n}\n\n.form-select-sm {\n  padding-top: 0.25rem;\n  padding-bottom: 0.25rem;\n  padding-left: 0.5rem;\n  font-size: 0.875rem;\n  border-radius: 0.25rem;\n}\n\n.form-select-lg {\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n  padding-left: 1rem;\n  font-size: 1.25rem;\n  border-radius: 0.5rem;\n}\n\n.form-check {\n  display: block;\n  min-height: 1.5rem;\n  padding-left: 1.5em;\n  margin-bottom: 0.125rem;\n}\n.form-check .form-check-input {\n  float: left;\n  margin-left: -1.5em;\n}\n\n.form-check-reverse {\n  padding-right: 1.5em;\n  padding-left: 0;\n  text-align: right;\n}\n.form-check-reverse .form-check-input {\n  float: right;\n  margin-right: -1.5em;\n  margin-left: 0;\n}\n\n.form-check-input {\n  width: 1em;\n  height: 1em;\n  margin-top: 0.25em;\n  vertical-align: top;\n  background-color: #fff;\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: contain;\n  border: 1px solid rgba(0, 0, 0, 0.25);\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n  -webkit-print-color-adjust: exact;\n  color-adjust: exact;\n  print-color-adjust: exact;\n}\n.form-check-input[type=checkbox] {\n  border-radius: 0.25em;\n}\n.form-check-input[type=radio] {\n  border-radius: 50%;\n}\n.form-check-input:active {\n  filter: brightness(90%);\n}\n.form-check-input:focus {\n  border-color: #86b7fe;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-check-input:checked {\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n}\n.form-check-input:checked[type=checkbox] {\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e\");\n}\n.form-check-input:checked[type=radio] {\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e\");\n}\n.form-check-input[type=checkbox]:indeterminate {\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e\");\n}\n.form-check-input:disabled {\n  pointer-events: none;\n  filter: none;\n  opacity: 0.5;\n}\n.form-check-input[disabled] ~ .form-check-label, .form-check-input:disabled ~ .form-check-label {\n  cursor: default;\n  opacity: 0.5;\n}\n\n.form-switch {\n  padding-left: 2.5em;\n}\n.form-switch .form-check-input {\n  width: 2em;\n  margin-left: -2.5em;\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e\");\n  background-position: left center;\n  border-radius: 2em;\n  transition: background-position 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-switch .form-check-input {\n    transition: none;\n  }\n}\n.form-switch .form-check-input:focus {\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e\");\n}\n.form-switch .form-check-input:checked {\n  background-position: right center;\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e\");\n}\n.form-switch.form-check-reverse {\n  padding-right: 2.5em;\n  padding-left: 0;\n}\n.form-switch.form-check-reverse .form-check-input {\n  margin-right: -2.5em;\n  margin-left: 0;\n}\n\n.form-check-inline {\n  display: inline-block;\n  margin-right: 1rem;\n}\n\n.btn-check {\n  position: absolute;\n  clip: rect(0, 0, 0, 0);\n  pointer-events: none;\n}\n.btn-check[disabled] + .btn, .btn-check:disabled + .btn {\n  pointer-events: none;\n  filter: none;\n  opacity: 0.65;\n}\n\n.form-range {\n  width: 100%;\n  height: 1.5rem;\n  padding: 0;\n  background-color: transparent;\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n}\n.form-range:focus {\n  outline: 0;\n}\n.form-range:focus::-webkit-slider-thumb {\n  box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-range:focus::-moz-range-thumb {\n  box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-range::-moz-focus-outer {\n  border: 0;\n}\n.form-range::-webkit-slider-thumb {\n  width: 1rem;\n  height: 1rem;\n  margin-top: -0.25rem;\n  background-color: #0d6efd;\n  border: 0;\n  border-radius: 1rem;\n  -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  -webkit-appearance: none;\n  appearance: none;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-range::-webkit-slider-thumb {\n    -webkit-transition: none;\n    transition: none;\n  }\n}\n.form-range::-webkit-slider-thumb:active {\n  background-color: #b6d4fe;\n}\n.form-range::-webkit-slider-runnable-track {\n  width: 100%;\n  height: 0.5rem;\n  color: transparent;\n  cursor: pointer;\n  background-color: #dee2e6;\n  border-color: transparent;\n  border-radius: 1rem;\n}\n.form-range::-moz-range-thumb {\n  width: 1rem;\n  height: 1rem;\n  background-color: #0d6efd;\n  border: 0;\n  border-radius: 1rem;\n  -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  -moz-appearance: none;\n  appearance: none;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-range::-moz-range-thumb {\n    -moz-transition: none;\n    transition: none;\n  }\n}\n.form-range::-moz-range-thumb:active {\n  background-color: #b6d4fe;\n}\n.form-range::-moz-range-track {\n  width: 100%;\n  height: 0.5rem;\n  color: transparent;\n  cursor: pointer;\n  background-color: #dee2e6;\n  border-color: transparent;\n  border-radius: 1rem;\n}\n.form-range:disabled {\n  pointer-events: none;\n}\n.form-range:disabled::-webkit-slider-thumb {\n  background-color: #adb5bd;\n}\n.form-range:disabled::-moz-range-thumb {\n  background-color: #adb5bd;\n}\n\n.form-floating {\n  position: relative;\n}\n.form-floating > .form-control,\n.form-floating > .form-control-plaintext,\n.form-floating > .form-select {\n  height: calc(3.5rem + 2px);\n  line-height: 1.25;\n}\n.form-floating > label {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  padding: 1rem 0.75rem;\n  overflow: hidden;\n  text-align: start;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  pointer-events: none;\n  border: 1px solid transparent;\n  transform-origin: 0 0;\n  transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-floating > label {\n    transition: none;\n  }\n}\n.form-floating > .form-control,\n.form-floating > .form-control-plaintext {\n  padding: 1rem 0.75rem;\n}\n.form-floating > .form-control::-moz-placeholder, .form-floating > .form-control-plaintext::-moz-placeholder {\n  color: transparent;\n}\n.form-floating > .form-control::placeholder,\n.form-floating > .form-control-plaintext::placeholder {\n  color: transparent;\n}\n.form-floating > .form-control:not(:-moz-placeholder-shown), .form-floating > .form-control-plaintext:not(:-moz-placeholder-shown) {\n  padding-top: 1.625rem;\n  padding-bottom: 0.625rem;\n}\n.form-floating > .form-control:focus, .form-floating > .form-control:not(:placeholder-shown),\n.form-floating > .form-control-plaintext:focus,\n.form-floating > .form-control-plaintext:not(:placeholder-shown) {\n  padding-top: 1.625rem;\n  padding-bottom: 0.625rem;\n}\n.form-floating > .form-control:-webkit-autofill,\n.form-floating > .form-control-plaintext:-webkit-autofill {\n  padding-top: 1.625rem;\n  padding-bottom: 0.625rem;\n}\n.form-floating > .form-select {\n  padding-top: 1.625rem;\n  padding-bottom: 0.625rem;\n}\n.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label {\n  opacity: 0.65;\n  transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);\n}\n.form-floating > .form-control:focus ~ label,\n.form-floating > .form-control:not(:placeholder-shown) ~ label,\n.form-floating > .form-control-plaintext ~ label,\n.form-floating > .form-select ~ label {\n  opacity: 0.65;\n  transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);\n}\n.form-floating > .form-control:-webkit-autofill ~ label {\n  opacity: 0.65;\n  transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);\n}\n.form-floating > .form-control-plaintext ~ label {\n  border-width: 1px 0;\n}\n\n.input-group {\n  position: relative;\n  display: flex;\n  flex-wrap: wrap;\n  align-items: stretch;\n  width: 100%;\n}\n.input-group > .form-control,\n.input-group > .form-select,\n.input-group > .form-floating {\n  position: relative;\n  flex: 1 1 auto;\n  width: 1%;\n  min-width: 0;\n}\n.input-group > .form-control:focus,\n.input-group > .form-select:focus,\n.input-group > .form-floating:focus-within {\n  z-index: 5;\n}\n.input-group .btn {\n  position: relative;\n  z-index: 2;\n}\n.input-group .btn:focus {\n  z-index: 5;\n}\n\n.input-group-text {\n  display: flex;\n  align-items: center;\n  padding: 0.375rem 0.75rem;\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.5;\n  color: #212529;\n  text-align: center;\n  white-space: nowrap;\n  background-color: #e9ecef;\n  border: 1px solid #ced4da;\n  border-radius: 0.375rem;\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .form-select,\n.input-group-lg > .input-group-text,\n.input-group-lg > .btn {\n  padding: 0.5rem 1rem;\n  font-size: 1.25rem;\n  border-radius: 0.5rem;\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .form-select,\n.input-group-sm > .input-group-text,\n.input-group-sm > .btn {\n  padding: 0.25rem 0.5rem;\n  font-size: 0.875rem;\n  border-radius: 0.25rem;\n}\n\n.input-group-lg > .form-select,\n.input-group-sm > .form-select {\n  padding-right: 3rem;\n}\n\n.input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),\n.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3),\n.input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-control,\n.input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-select {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.input-group.has-validation > :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),\n.input-group.has-validation > .dropdown-toggle:nth-last-child(n+4),\n.input-group.has-validation > .form-floating:nth-last-child(n+3) > .form-control,\n.input-group.has-validation > .form-floating:nth-last-child(n+3) > .form-select {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.input-group > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) {\n  margin-left: -1px;\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.input-group > .form-floating:not(:first-child) > .form-control,\n.input-group > .form-floating:not(:first-child) > .form-select {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n\n.valid-feedback {\n  display: none;\n  width: 100%;\n  margin-top: 0.25rem;\n  font-size: 0.875em;\n  color: #198754;\n}\n\n.valid-tooltip {\n  position: absolute;\n  top: 100%;\n  z-index: 5;\n  display: none;\n  max-width: 100%;\n  padding: 0.25rem 0.5rem;\n  margin-top: 0.1rem;\n  font-size: 0.875rem;\n  color: #fff;\n  background-color: rgba(25, 135, 84, 0.9);\n  border-radius: 0.375rem;\n}\n\n.was-validated :valid ~ .valid-feedback,\n.was-validated :valid ~ .valid-tooltip,\n.is-valid ~ .valid-feedback,\n.is-valid ~ .valid-tooltip {\n  display: block;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid {\n  border-color: #198754;\n  padding-right: calc(1.5em + 0.75rem);\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");\n  background-repeat: no-repeat;\n  background-position: right calc(0.375em + 0.1875rem) center;\n  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus {\n  border-color: #198754;\n  box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);\n}\n\n.was-validated textarea.form-control:valid, textarea.form-control.is-valid {\n  padding-right: calc(1.5em + 0.75rem);\n  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .form-select:valid, .form-select.is-valid {\n  border-color: #198754;\n}\n.was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size=\"1\"], .form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size=\"1\"] {\n  padding-right: 4.125rem;\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e\"), url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");\n  background-position: right 0.75rem center, center right 2.25rem;\n  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-select:valid:focus, .form-select.is-valid:focus {\n  border-color: #198754;\n  box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);\n}\n\n.was-validated .form-control-color:valid, .form-control-color.is-valid {\n  width: calc(3rem + calc(1.5em + 0.75rem));\n}\n\n.was-validated .form-check-input:valid, .form-check-input.is-valid {\n  border-color: #198754;\n}\n.was-validated .form-check-input:valid:checked, .form-check-input.is-valid:checked {\n  background-color: #198754;\n}\n.was-validated .form-check-input:valid:focus, .form-check-input.is-valid:focus {\n  box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);\n}\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n  color: #198754;\n}\n\n.form-check-inline .form-check-input ~ .valid-feedback {\n  margin-left: 0.5em;\n}\n\n.was-validated .input-group > .form-control:not(:focus):valid, .input-group > .form-control:not(:focus).is-valid,\n.was-validated .input-group > .form-select:not(:focus):valid,\n.input-group > .form-select:not(:focus).is-valid,\n.was-validated .input-group > .form-floating:not(:focus-within):valid,\n.input-group > .form-floating:not(:focus-within).is-valid {\n  z-index: 3;\n}\n\n.invalid-feedback {\n  display: none;\n  width: 100%;\n  margin-top: 0.25rem;\n  font-size: 0.875em;\n  color: #dc3545;\n}\n\n.invalid-tooltip {\n  position: absolute;\n  top: 100%;\n  z-index: 5;\n  display: none;\n  max-width: 100%;\n  padding: 0.25rem 0.5rem;\n  margin-top: 0.1rem;\n  font-size: 0.875rem;\n  color: #fff;\n  background-color: rgba(220, 53, 69, 0.9);\n  border-radius: 0.375rem;\n}\n\n.was-validated :invalid ~ .invalid-feedback,\n.was-validated :invalid ~ .invalid-tooltip,\n.is-invalid ~ .invalid-feedback,\n.is-invalid ~ .invalid-tooltip {\n  display: block;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid {\n  border-color: #dc3545;\n  padding-right: calc(1.5em + 0.75rem);\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\");\n  background-repeat: no-repeat;\n  background-position: right calc(0.375em + 0.1875rem) center;\n  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus {\n  border-color: #dc3545;\n  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid {\n  padding-right: calc(1.5em + 0.75rem);\n  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .form-select:invalid, .form-select.is-invalid {\n  border-color: #dc3545;\n}\n.was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size=\"1\"], .form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size=\"1\"] {\n  padding-right: 4.125rem;\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e\"), url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\");\n  background-position: right 0.75rem center, center right 2.25rem;\n  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-select:invalid:focus, .form-select.is-invalid:focus {\n  border-color: #dc3545;\n  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-control-color:invalid, .form-control-color.is-invalid {\n  width: calc(3rem + calc(1.5em + 0.75rem));\n}\n\n.was-validated .form-check-input:invalid, .form-check-input.is-invalid {\n  border-color: #dc3545;\n}\n.was-validated .form-check-input:invalid:checked, .form-check-input.is-invalid:checked {\n  background-color: #dc3545;\n}\n.was-validated .form-check-input:invalid:focus, .form-check-input.is-invalid:focus {\n  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);\n}\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n  color: #dc3545;\n}\n\n.form-check-inline .form-check-input ~ .invalid-feedback {\n  margin-left: 0.5em;\n}\n\n.was-validated .input-group > .form-control:not(:focus):invalid, .input-group > .form-control:not(:focus).is-invalid,\n.was-validated .input-group > .form-select:not(:focus):invalid,\n.input-group > .form-select:not(:focus).is-invalid,\n.was-validated .input-group > .form-floating:not(:focus-within):invalid,\n.input-group > .form-floating:not(:focus-within).is-invalid {\n  z-index: 4;\n}\n\n.btn {\n  --bs-btn-padding-x: 0.75rem;\n  --bs-btn-padding-y: 0.375rem;\n  --bs-btn-font-family: ;\n  --bs-btn-font-size: 1rem;\n  --bs-btn-font-weight: 400;\n  --bs-btn-line-height: 1.5;\n  --bs-btn-color: #212529;\n  --bs-btn-bg: transparent;\n  --bs-btn-border-width: 1px;\n  --bs-btn-border-color: transparent;\n  --bs-btn-border-radius: 0.375rem;\n  --bs-btn-hover-border-color: transparent;\n  --bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n  --bs-btn-disabled-opacity: 0.65;\n  --bs-btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);\n  display: inline-block;\n  padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x);\n  font-family: var(--bs-btn-font-family);\n  font-size: var(--bs-btn-font-size);\n  font-weight: var(--bs-btn-font-weight);\n  line-height: var(--bs-btn-line-height);\n  color: var(--bs-btn-color);\n  text-align: center;\n  text-decoration: none;\n  vertical-align: middle;\n  cursor: pointer;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  user-select: none;\n  border: var(--bs-btn-border-width) solid var(--bs-btn-border-color);\n  border-radius: var(--bs-btn-border-radius);\n  background-color: var(--bs-btn-bg);\n  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .btn {\n    transition: none;\n  }\n}\n.btn:hover {\n  color: var(--bs-btn-hover-color);\n  background-color: var(--bs-btn-hover-bg);\n  border-color: var(--bs-btn-hover-border-color);\n}\n.btn-check + .btn:hover {\n  color: var(--bs-btn-color);\n  background-color: var(--bs-btn-bg);\n  border-color: var(--bs-btn-border-color);\n}\n.btn:focus-visible {\n  color: var(--bs-btn-hover-color);\n  background-color: var(--bs-btn-hover-bg);\n  border-color: var(--bs-btn-hover-border-color);\n  outline: 0;\n  box-shadow: var(--bs-btn-focus-box-shadow);\n}\n.btn-check:focus-visible + .btn {\n  border-color: var(--bs-btn-hover-border-color);\n  outline: 0;\n  box-shadow: var(--bs-btn-focus-box-shadow);\n}\n.btn-check:checked + .btn, :not(.btn-check) + .btn:active, .btn:first-child:active, .btn.active, .btn.show {\n  color: var(--bs-btn-active-color);\n  background-color: var(--bs-btn-active-bg);\n  border-color: var(--bs-btn-active-border-color);\n}\n.btn-check:checked + .btn:focus-visible, :not(.btn-check) + .btn:active:focus-visible, .btn:first-child:active:focus-visible, .btn.active:focus-visible, .btn.show:focus-visible {\n  box-shadow: var(--bs-btn-focus-box-shadow);\n}\n.btn:disabled, .btn.disabled, fieldset:disabled .btn {\n  color: var(--bs-btn-disabled-color);\n  pointer-events: none;\n  background-color: var(--bs-btn-disabled-bg);\n  border-color: var(--bs-btn-disabled-border-color);\n  opacity: var(--bs-btn-disabled-opacity);\n}\n\n.btn-primary {\n  --bs-btn-color: #fff;\n  --bs-btn-bg: #0d6efd;\n  --bs-btn-border-color: #0d6efd;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #0b5ed7;\n  --bs-btn-hover-border-color: #0a58ca;\n  --bs-btn-focus-shadow-rgb: 49, 132, 253;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #0a58ca;\n  --bs-btn-active-border-color: #0a53be;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #fff;\n  --bs-btn-disabled-bg: #0d6efd;\n  --bs-btn-disabled-border-color: #0d6efd;\n}\n\n.btn-secondary {\n  --bs-btn-color: #fff;\n  --bs-btn-bg: #6c757d;\n  --bs-btn-border-color: #6c757d;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #5c636a;\n  --bs-btn-hover-border-color: #565e64;\n  --bs-btn-focus-shadow-rgb: 130, 138, 145;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #565e64;\n  --bs-btn-active-border-color: #51585e;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #fff;\n  --bs-btn-disabled-bg: #6c757d;\n  --bs-btn-disabled-border-color: #6c757d;\n}\n\n.btn-success {\n  --bs-btn-color: #fff;\n  --bs-btn-bg: #198754;\n  --bs-btn-border-color: #198754;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #157347;\n  --bs-btn-hover-border-color: #146c43;\n  --bs-btn-focus-shadow-rgb: 60, 153, 110;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #146c43;\n  --bs-btn-active-border-color: #13653f;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #fff;\n  --bs-btn-disabled-bg: #198754;\n  --bs-btn-disabled-border-color: #198754;\n}\n\n.btn-info {\n  --bs-btn-color: #000;\n  --bs-btn-bg: #0dcaf0;\n  --bs-btn-border-color: #0dcaf0;\n  --bs-btn-hover-color: #000;\n  --bs-btn-hover-bg: #31d2f2;\n  --bs-btn-hover-border-color: #25cff2;\n  --bs-btn-focus-shadow-rgb: 11, 172, 204;\n  --bs-btn-active-color: #000;\n  --bs-btn-active-bg: #3dd5f3;\n  --bs-btn-active-border-color: #25cff2;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #000;\n  --bs-btn-disabled-bg: #0dcaf0;\n  --bs-btn-disabled-border-color: #0dcaf0;\n}\n\n.btn-warning {\n  --bs-btn-color: #000;\n  --bs-btn-bg: #ffc107;\n  --bs-btn-border-color: #ffc107;\n  --bs-btn-hover-color: #000;\n  --bs-btn-hover-bg: #ffca2c;\n  --bs-btn-hover-border-color: #ffc720;\n  --bs-btn-focus-shadow-rgb: 217, 164, 6;\n  --bs-btn-active-color: #000;\n  --bs-btn-active-bg: #ffcd39;\n  --bs-btn-active-border-color: #ffc720;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #000;\n  --bs-btn-disabled-bg: #ffc107;\n  --bs-btn-disabled-border-color: #ffc107;\n}\n\n.btn-danger {\n  --bs-btn-color: #fff;\n  --bs-btn-bg: #dc3545;\n  --bs-btn-border-color: #dc3545;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #bb2d3b;\n  --bs-btn-hover-border-color: #b02a37;\n  --bs-btn-focus-shadow-rgb: 225, 83, 97;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #b02a37;\n  --bs-btn-active-border-color: #a52834;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #fff;\n  --bs-btn-disabled-bg: #dc3545;\n  --bs-btn-disabled-border-color: #dc3545;\n}\n\n.btn-light {\n  --bs-btn-color: #000;\n  --bs-btn-bg: #f8f9fa;\n  --bs-btn-border-color: #f8f9fa;\n  --bs-btn-hover-color: #000;\n  --bs-btn-hover-bg: #d3d4d5;\n  --bs-btn-hover-border-color: #c6c7c8;\n  --bs-btn-focus-shadow-rgb: 211, 212, 213;\n  --bs-btn-active-color: #000;\n  --bs-btn-active-bg: #c6c7c8;\n  --bs-btn-active-border-color: #babbbc;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #000;\n  --bs-btn-disabled-bg: #f8f9fa;\n  --bs-btn-disabled-border-color: #f8f9fa;\n}\n\n.btn-dark {\n  --bs-btn-color: #fff;\n  --bs-btn-bg: #212529;\n  --bs-btn-border-color: #212529;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #424649;\n  --bs-btn-hover-border-color: #373b3e;\n  --bs-btn-focus-shadow-rgb: 66, 70, 73;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #4d5154;\n  --bs-btn-active-border-color: #373b3e;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #fff;\n  --bs-btn-disabled-bg: #212529;\n  --bs-btn-disabled-border-color: #212529;\n}\n\n.btn-outline-primary {\n  --bs-btn-color: #0d6efd;\n  --bs-btn-border-color: #0d6efd;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #0d6efd;\n  --bs-btn-hover-border-color: #0d6efd;\n  --bs-btn-focus-shadow-rgb: 13, 110, 253;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #0d6efd;\n  --bs-btn-active-border-color: #0d6efd;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #0d6efd;\n  --bs-btn-disabled-bg: transparent;\n  --bs-btn-disabled-border-color: #0d6efd;\n  --bs-gradient: none;\n}\n\n.btn-outline-secondary {\n  --bs-btn-color: #6c757d;\n  --bs-btn-border-color: #6c757d;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #6c757d;\n  --bs-btn-hover-border-color: #6c757d;\n  --bs-btn-focus-shadow-rgb: 108, 117, 125;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #6c757d;\n  --bs-btn-active-border-color: #6c757d;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #6c757d;\n  --bs-btn-disabled-bg: transparent;\n  --bs-btn-disabled-border-color: #6c757d;\n  --bs-gradient: none;\n}\n\n.btn-outline-success {\n  --bs-btn-color: #198754;\n  --bs-btn-border-color: #198754;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #198754;\n  --bs-btn-hover-border-color: #198754;\n  --bs-btn-focus-shadow-rgb: 25, 135, 84;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #198754;\n  --bs-btn-active-border-color: #198754;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #198754;\n  --bs-btn-disabled-bg: transparent;\n  --bs-btn-disabled-border-color: #198754;\n  --bs-gradient: none;\n}\n\n.btn-outline-info {\n  --bs-btn-color: #0dcaf0;\n  --bs-btn-border-color: #0dcaf0;\n  --bs-btn-hover-color: #000;\n  --bs-btn-hover-bg: #0dcaf0;\n  --bs-btn-hover-border-color: #0dcaf0;\n  --bs-btn-focus-shadow-rgb: 13, 202, 240;\n  --bs-btn-active-color: #000;\n  --bs-btn-active-bg: #0dcaf0;\n  --bs-btn-active-border-color: #0dcaf0;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #0dcaf0;\n  --bs-btn-disabled-bg: transparent;\n  --bs-btn-disabled-border-color: #0dcaf0;\n  --bs-gradient: none;\n}\n\n.btn-outline-warning {\n  --bs-btn-color: #ffc107;\n  --bs-btn-border-color: #ffc107;\n  --bs-btn-hover-color: #000;\n  --bs-btn-hover-bg: #ffc107;\n  --bs-btn-hover-border-color: #ffc107;\n  --bs-btn-focus-shadow-rgb: 255, 193, 7;\n  --bs-btn-active-color: #000;\n  --bs-btn-active-bg: #ffc107;\n  --bs-btn-active-border-color: #ffc107;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #ffc107;\n  --bs-btn-disabled-bg: transparent;\n  --bs-btn-disabled-border-color: #ffc107;\n  --bs-gradient: none;\n}\n\n.btn-outline-danger {\n  --bs-btn-color: #dc3545;\n  --bs-btn-border-color: #dc3545;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #dc3545;\n  --bs-btn-hover-border-color: #dc3545;\n  --bs-btn-focus-shadow-rgb: 220, 53, 69;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #dc3545;\n  --bs-btn-active-border-color: #dc3545;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #dc3545;\n  --bs-btn-disabled-bg: transparent;\n  --bs-btn-disabled-border-color: #dc3545;\n  --bs-gradient: none;\n}\n\n.btn-outline-light {\n  --bs-btn-color: #f8f9fa;\n  --bs-btn-border-color: #f8f9fa;\n  --bs-btn-hover-color: #000;\n  --bs-btn-hover-bg: #f8f9fa;\n  --bs-btn-hover-border-color: #f8f9fa;\n  --bs-btn-focus-shadow-rgb: 248, 249, 250;\n  --bs-btn-active-color: #000;\n  --bs-btn-active-bg: #f8f9fa;\n  --bs-btn-active-border-color: #f8f9fa;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #f8f9fa;\n  --bs-btn-disabled-bg: transparent;\n  --bs-btn-disabled-border-color: #f8f9fa;\n  --bs-gradient: none;\n}\n\n.btn-outline-dark {\n  --bs-btn-color: #212529;\n  --bs-btn-border-color: #212529;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #212529;\n  --bs-btn-hover-border-color: #212529;\n  --bs-btn-focus-shadow-rgb: 33, 37, 41;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #212529;\n  --bs-btn-active-border-color: #212529;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #212529;\n  --bs-btn-disabled-bg: transparent;\n  --bs-btn-disabled-border-color: #212529;\n  --bs-gradient: none;\n}\n\n.btn-link {\n  --bs-btn-font-weight: 400;\n  --bs-btn-color: var(--bs-link-color);\n  --bs-btn-bg: transparent;\n  --bs-btn-border-color: transparent;\n  --bs-btn-hover-color: var(--bs-link-hover-color);\n  --bs-btn-hover-border-color: transparent;\n  --bs-btn-active-color: var(--bs-link-hover-color);\n  --bs-btn-active-border-color: transparent;\n  --bs-btn-disabled-color: #6c757d;\n  --bs-btn-disabled-border-color: transparent;\n  --bs-btn-box-shadow: none;\n  --bs-btn-focus-shadow-rgb: 49, 132, 253;\n  text-decoration: underline;\n}\n.btn-link:focus-visible {\n  color: var(--bs-btn-color);\n}\n.btn-link:hover {\n  color: var(--bs-btn-hover-color);\n}\n\n.btn-lg, .btn-group-lg > .btn {\n  --bs-btn-padding-y: 0.5rem;\n  --bs-btn-padding-x: 1rem;\n  --bs-btn-font-size: 1.25rem;\n  --bs-btn-border-radius: 0.5rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n  --bs-btn-padding-y: 0.25rem;\n  --bs-btn-padding-x: 0.5rem;\n  --bs-btn-font-size: 0.875rem;\n  --bs-btn-border-radius: 0.25rem;\n}\n\n.fade {\n  transition: opacity 0.15s linear;\n}\n@media (prefers-reduced-motion: reduce) {\n  .fade {\n    transition: none;\n  }\n}\n.fade:not(.show) {\n  opacity: 0;\n}\n\n.collapse:not(.show) {\n  display: none;\n}\n\n.collapsing {\n  height: 0;\n  overflow: hidden;\n  transition: height 0.35s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .collapsing {\n    transition: none;\n  }\n}\n.collapsing.collapse-horizontal {\n  width: 0;\n  height: auto;\n  transition: width 0.35s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .collapsing.collapse-horizontal {\n    transition: none;\n  }\n}\n\n.dropup,\n.dropend,\n.dropdown,\n.dropstart,\n.dropup-center,\n.dropdown-center {\n  position: relative;\n}\n\n.dropdown-toggle {\n  white-space: nowrap;\n}\n.dropdown-toggle::after {\n  display: inline-block;\n  margin-left: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n  border-top: 0.3em solid;\n  border-right: 0.3em solid transparent;\n  border-bottom: 0;\n  border-left: 0.3em solid transparent;\n}\n.dropdown-toggle:empty::after {\n  margin-left: 0;\n}\n\n.dropdown-menu {\n  --bs-dropdown-zindex: 1000;\n  --bs-dropdown-min-width: 10rem;\n  --bs-dropdown-padding-x: 0;\n  --bs-dropdown-padding-y: 0.5rem;\n  --bs-dropdown-spacer: 0.125rem;\n  --bs-dropdown-font-size: 1rem;\n  --bs-dropdown-color: #212529;\n  --bs-dropdown-bg: #fff;\n  --bs-dropdown-border-color: var(--bs-border-color-translucent);\n  --bs-dropdown-border-radius: 0.375rem;\n  --bs-dropdown-border-width: 1px;\n  --bs-dropdown-inner-border-radius: calc(0.375rem - 1px);\n  --bs-dropdown-divider-bg: var(--bs-border-color-translucent);\n  --bs-dropdown-divider-margin-y: 0.5rem;\n  --bs-dropdown-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n  --bs-dropdown-link-color: #212529;\n  --bs-dropdown-link-hover-color: #1e2125;\n  --bs-dropdown-link-hover-bg: #e9ecef;\n  --bs-dropdown-link-active-color: #fff;\n  --bs-dropdown-link-active-bg: #0d6efd;\n  --bs-dropdown-link-disabled-color: #adb5bd;\n  --bs-dropdown-item-padding-x: 1rem;\n  --bs-dropdown-item-padding-y: 0.25rem;\n  --bs-dropdown-header-color: #6c757d;\n  --bs-dropdown-header-padding-x: 1rem;\n  --bs-dropdown-header-padding-y: 0.5rem;\n  position: absolute;\n  z-index: var(--bs-dropdown-zindex);\n  display: none;\n  min-width: var(--bs-dropdown-min-width);\n  padding: var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);\n  margin: 0;\n  font-size: var(--bs-dropdown-font-size);\n  color: var(--bs-dropdown-color);\n  text-align: left;\n  list-style: none;\n  background-color: var(--bs-dropdown-bg);\n  background-clip: padding-box;\n  border: var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);\n  border-radius: var(--bs-dropdown-border-radius);\n}\n.dropdown-menu[data-bs-popper] {\n  top: 100%;\n  left: 0;\n  margin-top: var(--bs-dropdown-spacer);\n}\n\n.dropdown-menu-start {\n  --bs-position: start;\n}\n.dropdown-menu-start[data-bs-popper] {\n  right: auto;\n  left: 0;\n}\n\n.dropdown-menu-end {\n  --bs-position: end;\n}\n.dropdown-menu-end[data-bs-popper] {\n  right: 0;\n  left: auto;\n}\n\n@media (min-width: 576px) {\n  .dropdown-menu-sm-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-sm-start[data-bs-popper] {\n    right: auto;\n    left: 0;\n  }\n  .dropdown-menu-sm-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-sm-end[data-bs-popper] {\n    right: 0;\n    left: auto;\n  }\n}\n@media (min-width: 768px) {\n  .dropdown-menu-md-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-md-start[data-bs-popper] {\n    right: auto;\n    left: 0;\n  }\n  .dropdown-menu-md-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-md-end[data-bs-popper] {\n    right: 0;\n    left: auto;\n  }\n}\n@media (min-width: 992px) {\n  .dropdown-menu-lg-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-lg-start[data-bs-popper] {\n    right: auto;\n    left: 0;\n  }\n  .dropdown-menu-lg-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-lg-end[data-bs-popper] {\n    right: 0;\n    left: auto;\n  }\n}\n@media (min-width: 1200px) {\n  .dropdown-menu-xl-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-xl-start[data-bs-popper] {\n    right: auto;\n    left: 0;\n  }\n  .dropdown-menu-xl-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-xl-end[data-bs-popper] {\n    right: 0;\n    left: auto;\n  }\n}\n@media (min-width: 1400px) {\n  .dropdown-menu-xxl-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-xxl-start[data-bs-popper] {\n    right: auto;\n    left: 0;\n  }\n  .dropdown-menu-xxl-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-xxl-end[data-bs-popper] {\n    right: 0;\n    left: auto;\n  }\n}\n.dropup .dropdown-menu[data-bs-popper] {\n  top: auto;\n  bottom: 100%;\n  margin-top: 0;\n  margin-bottom: var(--bs-dropdown-spacer);\n}\n.dropup .dropdown-toggle::after {\n  display: inline-block;\n  margin-left: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n  border-top: 0;\n  border-right: 0.3em solid transparent;\n  border-bottom: 0.3em solid;\n  border-left: 0.3em solid transparent;\n}\n.dropup .dropdown-toggle:empty::after {\n  margin-left: 0;\n}\n\n.dropend .dropdown-menu[data-bs-popper] {\n  top: 0;\n  right: auto;\n  left: 100%;\n  margin-top: 0;\n  margin-left: var(--bs-dropdown-spacer);\n}\n.dropend .dropdown-toggle::after {\n  display: inline-block;\n  margin-left: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n  border-top: 0.3em solid transparent;\n  border-right: 0;\n  border-bottom: 0.3em solid transparent;\n  border-left: 0.3em solid;\n}\n.dropend .dropdown-toggle:empty::after {\n  margin-left: 0;\n}\n.dropend .dropdown-toggle::after {\n  vertical-align: 0;\n}\n\n.dropstart .dropdown-menu[data-bs-popper] {\n  top: 0;\n  right: 100%;\n  left: auto;\n  margin-top: 0;\n  margin-right: var(--bs-dropdown-spacer);\n}\n.dropstart .dropdown-toggle::after {\n  display: inline-block;\n  margin-left: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n}\n.dropstart .dropdown-toggle::after {\n  display: none;\n}\n.dropstart .dropdown-toggle::before {\n  display: inline-block;\n  margin-right: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n  border-top: 0.3em solid transparent;\n  border-right: 0.3em solid;\n  border-bottom: 0.3em solid transparent;\n}\n.dropstart .dropdown-toggle:empty::after {\n  margin-left: 0;\n}\n.dropstart .dropdown-toggle::before {\n  vertical-align: 0;\n}\n\n.dropdown-divider {\n  height: 0;\n  margin: var(--bs-dropdown-divider-margin-y) 0;\n  overflow: hidden;\n  border-top: 1px solid var(--bs-dropdown-divider-bg);\n  opacity: 1;\n}\n\n.dropdown-item {\n  display: block;\n  width: 100%;\n  padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);\n  clear: both;\n  font-weight: 400;\n  color: var(--bs-dropdown-link-color);\n  text-align: inherit;\n  text-decoration: none;\n  white-space: nowrap;\n  background-color: transparent;\n  border: 0;\n}\n.dropdown-item:hover, .dropdown-item:focus {\n  color: var(--bs-dropdown-link-hover-color);\n  background-color: var(--bs-dropdown-link-hover-bg);\n}\n.dropdown-item.active, .dropdown-item:active {\n  color: var(--bs-dropdown-link-active-color);\n  text-decoration: none;\n  background-color: var(--bs-dropdown-link-active-bg);\n}\n.dropdown-item.disabled, .dropdown-item:disabled {\n  color: var(--bs-dropdown-link-disabled-color);\n  pointer-events: none;\n  background-color: transparent;\n}\n\n.dropdown-menu.show {\n  display: block;\n}\n\n.dropdown-header {\n  display: block;\n  padding: var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);\n  margin-bottom: 0;\n  font-size: 0.875rem;\n  color: var(--bs-dropdown-header-color);\n  white-space: nowrap;\n}\n\n.dropdown-item-text {\n  display: block;\n  padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);\n  color: var(--bs-dropdown-link-color);\n}\n\n.dropdown-menu-dark {\n  --bs-dropdown-color: #dee2e6;\n  --bs-dropdown-bg: #343a40;\n  --bs-dropdown-border-color: var(--bs-border-color-translucent);\n  --bs-dropdown-box-shadow: ;\n  --bs-dropdown-link-color: #dee2e6;\n  --bs-dropdown-link-hover-color: #fff;\n  --bs-dropdown-divider-bg: var(--bs-border-color-translucent);\n  --bs-dropdown-link-hover-bg: rgba(255, 255, 255, 0.15);\n  --bs-dropdown-link-active-color: #fff;\n  --bs-dropdown-link-active-bg: #0d6efd;\n  --bs-dropdown-link-disabled-color: #adb5bd;\n  --bs-dropdown-header-color: #adb5bd;\n}\n\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-flex;\n  vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n  position: relative;\n  flex: 1 1 auto;\n}\n.btn-group > .btn-check:checked + .btn,\n.btn-group > .btn-check:focus + .btn,\n.btn-group > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn-check:checked + .btn,\n.btn-group-vertical > .btn-check:focus + .btn,\n.btn-group-vertical > .btn:hover,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n  z-index: 1;\n}\n\n.btn-toolbar {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: flex-start;\n}\n.btn-toolbar .input-group {\n  width: auto;\n}\n\n.btn-group {\n  border-radius: 0.375rem;\n}\n.btn-group > :not(.btn-check:first-child) + .btn,\n.btn-group > .btn-group:not(:first-child) {\n  margin-left: -1px;\n}\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn.dropdown-toggle-split:first-child,\n.btn-group > .btn-group:not(:last-child) > .btn {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn:nth-child(n+3),\n.btn-group > :not(.btn-check) + .btn,\n.btn-group > .btn-group:not(:first-child) > .btn {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n  padding-right: 0.5625rem;\n  padding-left: 0.5625rem;\n}\n.dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after, .dropend .dropdown-toggle-split::after {\n  margin-left: 0;\n}\n.dropstart .dropdown-toggle-split::before {\n  margin-right: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n  padding-right: 0.375rem;\n  padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n  padding-right: 0.75rem;\n  padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n  flex-direction: column;\n  align-items: flex-start;\n  justify-content: center;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group {\n  width: 100%;\n}\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) {\n  margin-top: -1px;\n}\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn ~ .btn,\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n\n.nav {\n  --bs-nav-link-padding-x: 1rem;\n  --bs-nav-link-padding-y: 0.5rem;\n  --bs-nav-link-font-weight: ;\n  --bs-nav-link-color: var(--bs-link-color);\n  --bs-nav-link-hover-color: var(--bs-link-hover-color);\n  --bs-nav-link-disabled-color: #6c757d;\n  display: flex;\n  flex-wrap: wrap;\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n\n.nav-link {\n  display: block;\n  padding: var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);\n  font-size: var(--bs-nav-link-font-size);\n  font-weight: var(--bs-nav-link-font-weight);\n  color: var(--bs-nav-link-color);\n  text-decoration: none;\n  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .nav-link {\n    transition: none;\n  }\n}\n.nav-link:hover, .nav-link:focus {\n  color: var(--bs-nav-link-hover-color);\n}\n.nav-link.disabled {\n  color: var(--bs-nav-link-disabled-color);\n  pointer-events: none;\n  cursor: default;\n}\n\n.nav-tabs {\n  --bs-nav-tabs-border-width: 1px;\n  --bs-nav-tabs-border-color: #dee2e6;\n  --bs-nav-tabs-border-radius: 0.375rem;\n  --bs-nav-tabs-link-hover-border-color: #e9ecef #e9ecef #dee2e6;\n  --bs-nav-tabs-link-active-color: #495057;\n  --bs-nav-tabs-link-active-bg: #fff;\n  --bs-nav-tabs-link-active-border-color: #dee2e6 #dee2e6 #fff;\n  border-bottom: var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color);\n}\n.nav-tabs .nav-link {\n  margin-bottom: calc(-1 * var(--bs-nav-tabs-border-width));\n  background: none;\n  border: var(--bs-nav-tabs-border-width) solid transparent;\n  border-top-left-radius: var(--bs-nav-tabs-border-radius);\n  border-top-right-radius: var(--bs-nav-tabs-border-radius);\n}\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n  isolation: isolate;\n  border-color: var(--bs-nav-tabs-link-hover-border-color);\n}\n.nav-tabs .nav-link.disabled, .nav-tabs .nav-link:disabled {\n  color: var(--bs-nav-link-disabled-color);\n  background-color: transparent;\n  border-color: transparent;\n}\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n  color: var(--bs-nav-tabs-link-active-color);\n  background-color: var(--bs-nav-tabs-link-active-bg);\n  border-color: var(--bs-nav-tabs-link-active-border-color);\n}\n.nav-tabs .dropdown-menu {\n  margin-top: calc(-1 * var(--bs-nav-tabs-border-width));\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n\n.nav-pills {\n  --bs-nav-pills-border-radius: 0.375rem;\n  --bs-nav-pills-link-active-color: #fff;\n  --bs-nav-pills-link-active-bg: #0d6efd;\n}\n.nav-pills .nav-link {\n  background: none;\n  border: 0;\n  border-radius: var(--bs-nav-pills-border-radius);\n}\n.nav-pills .nav-link:disabled {\n  color: var(--bs-nav-link-disabled-color);\n  background-color: transparent;\n  border-color: transparent;\n}\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n  color: var(--bs-nav-pills-link-active-color);\n  background-color: var(--bs-nav-pills-link-active-bg);\n}\n\n.nav-fill > .nav-link,\n.nav-fill .nav-item {\n  flex: 1 1 auto;\n  text-align: center;\n}\n\n.nav-justified > .nav-link,\n.nav-justified .nav-item {\n  flex-basis: 0;\n  flex-grow: 1;\n  text-align: center;\n}\n\n.nav-fill .nav-item .nav-link,\n.nav-justified .nav-item .nav-link {\n  width: 100%;\n}\n\n.tab-content > .tab-pane {\n  display: none;\n}\n.tab-content > .active {\n  display: block;\n}\n\n.navbar {\n  --bs-navbar-padding-x: 0;\n  --bs-navbar-padding-y: 0.5rem;\n  --bs-navbar-color: rgba(0, 0, 0, 0.55);\n  --bs-navbar-hover-color: rgba(0, 0, 0, 0.7);\n  --bs-navbar-disabled-color: rgba(0, 0, 0, 0.3);\n  --bs-navbar-active-color: rgba(0, 0, 0, 0.9);\n  --bs-navbar-brand-padding-y: 0.3125rem;\n  --bs-navbar-brand-margin-end: 1rem;\n  --bs-navbar-brand-font-size: 1.25rem;\n  --bs-navbar-brand-color: rgba(0, 0, 0, 0.9);\n  --bs-navbar-brand-hover-color: rgba(0, 0, 0, 0.9);\n  --bs-navbar-nav-link-padding-x: 0.5rem;\n  --bs-navbar-toggler-padding-y: 0.25rem;\n  --bs-navbar-toggler-padding-x: 0.75rem;\n  --bs-navbar-toggler-font-size: 1.25rem;\n  --bs-navbar-toggler-icon-bg: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n  --bs-navbar-toggler-border-color: rgba(0, 0, 0, 0.1);\n  --bs-navbar-toggler-border-radius: 0.375rem;\n  --bs-navbar-toggler-focus-width: 0.25rem;\n  --bs-navbar-toggler-transition: box-shadow 0.15s ease-in-out;\n  position: relative;\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  justify-content: space-between;\n  padding: var(--bs-navbar-padding-y) var(--bs-navbar-padding-x);\n}\n.navbar > .container,\n.navbar > .container-fluid,\n.navbar > .container-sm,\n.navbar > .container-md,\n.navbar > .container-lg,\n.navbar > .container-xl,\n.navbar > .container-xxl {\n  display: flex;\n  flex-wrap: inherit;\n  align-items: center;\n  justify-content: space-between;\n}\n.navbar-brand {\n  padding-top: var(--bs-navbar-brand-padding-y);\n  padding-bottom: var(--bs-navbar-brand-padding-y);\n  margin-right: var(--bs-navbar-brand-margin-end);\n  font-size: var(--bs-navbar-brand-font-size);\n  color: var(--bs-navbar-brand-color);\n  text-decoration: none;\n  white-space: nowrap;\n}\n.navbar-brand:hover, .navbar-brand:focus {\n  color: var(--bs-navbar-brand-hover-color);\n}\n\n.navbar-nav {\n  --bs-nav-link-padding-x: 0;\n  --bs-nav-link-padding-y: 0.5rem;\n  --bs-nav-link-font-weight: ;\n  --bs-nav-link-color: var(--bs-navbar-color);\n  --bs-nav-link-hover-color: var(--bs-navbar-hover-color);\n  --bs-nav-link-disabled-color: var(--bs-navbar-disabled-color);\n  display: flex;\n  flex-direction: column;\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n.navbar-nav .show > .nav-link,\n.navbar-nav .nav-link.active {\n  color: var(--bs-navbar-active-color);\n}\n.navbar-nav .dropdown-menu {\n  position: static;\n}\n\n.navbar-text {\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n  color: var(--bs-navbar-color);\n}\n.navbar-text a,\n.navbar-text a:hover,\n.navbar-text a:focus {\n  color: var(--bs-navbar-active-color);\n}\n\n.navbar-collapse {\n  flex-basis: 100%;\n  flex-grow: 1;\n  align-items: center;\n}\n\n.navbar-toggler {\n  padding: var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);\n  font-size: var(--bs-navbar-toggler-font-size);\n  line-height: 1;\n  color: var(--bs-navbar-color);\n  background-color: transparent;\n  border: var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);\n  border-radius: var(--bs-navbar-toggler-border-radius);\n  transition: var(--bs-navbar-toggler-transition);\n}\n@media (prefers-reduced-motion: reduce) {\n  .navbar-toggler {\n    transition: none;\n  }\n}\n.navbar-toggler:hover {\n  text-decoration: none;\n}\n.navbar-toggler:focus {\n  text-decoration: none;\n  outline: 0;\n  box-shadow: 0 0 0 var(--bs-navbar-toggler-focus-width);\n}\n\n.navbar-toggler-icon {\n  display: inline-block;\n  width: 1.5em;\n  height: 1.5em;\n  vertical-align: middle;\n  background-image: var(--bs-navbar-toggler-icon-bg);\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: 100%;\n}\n\n.navbar-nav-scroll {\n  max-height: var(--bs-scroll-height, 75vh);\n  overflow-y: auto;\n}\n\n@media (min-width: 576px) {\n  .navbar-expand-sm {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-sm .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-sm .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-sm .navbar-nav .nav-link {\n    padding-right: var(--bs-navbar-nav-link-padding-x);\n    padding-left: var(--bs-navbar-nav-link-padding-x);\n  }\n  .navbar-expand-sm .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-sm .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-sm .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-sm .offcanvas {\n    position: static;\n    z-index: auto;\n    flex-grow: 1;\n    width: auto !important;\n    height: auto !important;\n    visibility: visible !important;\n    background-color: transparent !important;\n    border: 0 !important;\n    transform: none !important;\n    transition: none;\n  }\n  .navbar-expand-sm .offcanvas .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-sm .offcanvas .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-expand-md {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-md .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-md .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-md .navbar-nav .nav-link {\n    padding-right: var(--bs-navbar-nav-link-padding-x);\n    padding-left: var(--bs-navbar-nav-link-padding-x);\n  }\n  .navbar-expand-md .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-md .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-md .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-md .offcanvas {\n    position: static;\n    z-index: auto;\n    flex-grow: 1;\n    width: auto !important;\n    height: auto !important;\n    visibility: visible !important;\n    background-color: transparent !important;\n    border: 0 !important;\n    transform: none !important;\n    transition: none;\n  }\n  .navbar-expand-md .offcanvas .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-md .offcanvas .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n@media (min-width: 992px) {\n  .navbar-expand-lg {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-lg .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-lg .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-lg .navbar-nav .nav-link {\n    padding-right: var(--bs-navbar-nav-link-padding-x);\n    padding-left: var(--bs-navbar-nav-link-padding-x);\n  }\n  .navbar-expand-lg .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-lg .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-lg .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-lg .offcanvas {\n    position: static;\n    z-index: auto;\n    flex-grow: 1;\n    width: auto !important;\n    height: auto !important;\n    visibility: visible !important;\n    background-color: transparent !important;\n    border: 0 !important;\n    transform: none !important;\n    transition: none;\n  }\n  .navbar-expand-lg .offcanvas .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-lg .offcanvas .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n@media (min-width: 1200px) {\n  .navbar-expand-xl {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-xl .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-xl .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-xl .navbar-nav .nav-link {\n    padding-right: var(--bs-navbar-nav-link-padding-x);\n    padding-left: var(--bs-navbar-nav-link-padding-x);\n  }\n  .navbar-expand-xl .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-xl .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-xl .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-xl .offcanvas {\n    position: static;\n    z-index: auto;\n    flex-grow: 1;\n    width: auto !important;\n    height: auto !important;\n    visibility: visible !important;\n    background-color: transparent !important;\n    border: 0 !important;\n    transform: none !important;\n    transition: none;\n  }\n  .navbar-expand-xl .offcanvas .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-xl .offcanvas .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n@media (min-width: 1400px) {\n  .navbar-expand-xxl {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-xxl .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-xxl .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-xxl .navbar-nav .nav-link {\n    padding-right: var(--bs-navbar-nav-link-padding-x);\n    padding-left: var(--bs-navbar-nav-link-padding-x);\n  }\n  .navbar-expand-xxl .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-xxl .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-xxl .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-xxl .offcanvas {\n    position: static;\n    z-index: auto;\n    flex-grow: 1;\n    width: auto !important;\n    height: auto !important;\n    visibility: visible !important;\n    background-color: transparent !important;\n    border: 0 !important;\n    transform: none !important;\n    transition: none;\n  }\n  .navbar-expand-xxl .offcanvas .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-xxl .offcanvas .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n.navbar-expand {\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n}\n.navbar-expand .navbar-nav {\n  flex-direction: row;\n}\n.navbar-expand .navbar-nav .dropdown-menu {\n  position: absolute;\n}\n.navbar-expand .navbar-nav .nav-link {\n  padding-right: var(--bs-navbar-nav-link-padding-x);\n  padding-left: var(--bs-navbar-nav-link-padding-x);\n}\n.navbar-expand .navbar-nav-scroll {\n  overflow: visible;\n}\n.navbar-expand .navbar-collapse {\n  display: flex !important;\n  flex-basis: auto;\n}\n.navbar-expand .navbar-toggler {\n  display: none;\n}\n.navbar-expand .offcanvas {\n  position: static;\n  z-index: auto;\n  flex-grow: 1;\n  width: auto !important;\n  height: auto !important;\n  visibility: visible !important;\n  background-color: transparent !important;\n  border: 0 !important;\n  transform: none !important;\n  transition: none;\n}\n.navbar-expand .offcanvas .offcanvas-header {\n  display: none;\n}\n.navbar-expand .offcanvas .offcanvas-body {\n  display: flex;\n  flex-grow: 0;\n  padding: 0;\n  overflow-y: visible;\n}\n\n.navbar-dark {\n  --bs-navbar-color: rgba(255, 255, 255, 0.55);\n  --bs-navbar-hover-color: rgba(255, 255, 255, 0.75);\n  --bs-navbar-disabled-color: rgba(255, 255, 255, 0.25);\n  --bs-navbar-active-color: #fff;\n  --bs-navbar-brand-color: #fff;\n  --bs-navbar-brand-hover-color: #fff;\n  --bs-navbar-toggler-border-color: rgba(255, 255, 255, 0.1);\n  --bs-navbar-toggler-icon-bg: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.card {\n  --bs-card-spacer-y: 1rem;\n  --bs-card-spacer-x: 1rem;\n  --bs-card-title-spacer-y: 0.5rem;\n  --bs-card-border-width: 1px;\n  --bs-card-border-color: var(--bs-border-color-translucent);\n  --bs-card-border-radius: 0.375rem;\n  --bs-card-box-shadow: ;\n  --bs-card-inner-border-radius: calc(0.375rem - 1px);\n  --bs-card-cap-padding-y: 0.5rem;\n  --bs-card-cap-padding-x: 1rem;\n  --bs-card-cap-bg: rgba(0, 0, 0, 0.03);\n  --bs-card-cap-color: ;\n  --bs-card-height: ;\n  --bs-card-color: ;\n  --bs-card-bg: #fff;\n  --bs-card-img-overlay-padding: 1rem;\n  --bs-card-group-margin: 0.75rem;\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  min-width: 0;\n  height: var(--bs-card-height);\n  word-wrap: break-word;\n  background-color: var(--bs-card-bg);\n  background-clip: border-box;\n  border: var(--bs-card-border-width) solid var(--bs-card-border-color);\n  border-radius: var(--bs-card-border-radius);\n}\n.card > hr {\n  margin-right: 0;\n  margin-left: 0;\n}\n.card > .list-group {\n  border-top: inherit;\n  border-bottom: inherit;\n}\n.card > .list-group:first-child {\n  border-top-width: 0;\n  border-top-left-radius: var(--bs-card-inner-border-radius);\n  border-top-right-radius: var(--bs-card-inner-border-radius);\n}\n.card > .list-group:last-child {\n  border-bottom-width: 0;\n  border-bottom-right-radius: var(--bs-card-inner-border-radius);\n  border-bottom-left-radius: var(--bs-card-inner-border-radius);\n}\n.card > .card-header + .list-group,\n.card > .list-group + .card-footer {\n  border-top: 0;\n}\n\n.card-body {\n  flex: 1 1 auto;\n  padding: var(--bs-card-spacer-y) var(--bs-card-spacer-x);\n  color: var(--bs-card-color);\n}\n\n.card-title {\n  margin-bottom: var(--bs-card-title-spacer-y);\n}\n\n.card-subtitle {\n  margin-top: calc(-0.5 * var(--bs-card-title-spacer-y));\n  margin-bottom: 0;\n}\n\n.card-text:last-child {\n  margin-bottom: 0;\n}\n\n.card-link + .card-link {\n  margin-left: var(--bs-card-spacer-x);\n}\n\n.card-header {\n  padding: var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);\n  margin-bottom: 0;\n  color: var(--bs-card-cap-color);\n  background-color: var(--bs-card-cap-bg);\n  border-bottom: var(--bs-card-border-width) solid var(--bs-card-border-color);\n}\n.card-header:first-child {\n  border-radius: var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0;\n}\n\n.card-footer {\n  padding: var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);\n  color: var(--bs-card-cap-color);\n  background-color: var(--bs-card-cap-bg);\n  border-top: var(--bs-card-border-width) solid var(--bs-card-border-color);\n}\n.card-footer:last-child {\n  border-radius: 0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius);\n}\n\n.card-header-tabs {\n  margin-right: calc(-0.5 * var(--bs-card-cap-padding-x));\n  margin-bottom: calc(-1 * var(--bs-card-cap-padding-y));\n  margin-left: calc(-0.5 * var(--bs-card-cap-padding-x));\n  border-bottom: 0;\n}\n.card-header-tabs .nav-link.active {\n  background-color: var(--bs-card-bg);\n  border-bottom-color: var(--bs-card-bg);\n}\n\n.card-header-pills {\n  margin-right: calc(-0.5 * var(--bs-card-cap-padding-x));\n  margin-left: calc(-0.5 * var(--bs-card-cap-padding-x));\n}\n\n.card-img-overlay {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  padding: var(--bs-card-img-overlay-padding);\n  border-radius: var(--bs-card-inner-border-radius);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n  width: 100%;\n}\n\n.card-img,\n.card-img-top {\n  border-top-left-radius: var(--bs-card-inner-border-radius);\n  border-top-right-radius: var(--bs-card-inner-border-radius);\n}\n\n.card-img,\n.card-img-bottom {\n  border-bottom-right-radius: var(--bs-card-inner-border-radius);\n  border-bottom-left-radius: var(--bs-card-inner-border-radius);\n}\n\n.card-group > .card {\n  margin-bottom: var(--bs-card-group-margin);\n}\n@media (min-width: 576px) {\n  .card-group {\n    display: flex;\n    flex-flow: row wrap;\n  }\n  .card-group > .card {\n    flex: 1 0 0%;\n    margin-bottom: 0;\n  }\n  .card-group > .card + .card {\n    margin-left: 0;\n    border-left: 0;\n  }\n  .card-group > .card:not(:last-child) {\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n  }\n  .card-group > .card:not(:last-child) .card-img-top,\n.card-group > .card:not(:last-child) .card-header {\n    border-top-right-radius: 0;\n  }\n  .card-group > .card:not(:last-child) .card-img-bottom,\n.card-group > .card:not(:last-child) .card-footer {\n    border-bottom-right-radius: 0;\n  }\n  .card-group > .card:not(:first-child) {\n    border-top-left-radius: 0;\n    border-bottom-left-radius: 0;\n  }\n  .card-group > .card:not(:first-child) .card-img-top,\n.card-group > .card:not(:first-child) .card-header {\n    border-top-left-radius: 0;\n  }\n  .card-group > .card:not(:first-child) .card-img-bottom,\n.card-group > .card:not(:first-child) .card-footer {\n    border-bottom-left-radius: 0;\n  }\n}\n\n.accordion {\n  --bs-accordion-color: #212529;\n  --bs-accordion-bg: #fff;\n  --bs-accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;\n  --bs-accordion-border-color: var(--bs-border-color);\n  --bs-accordion-border-width: 1px;\n  --bs-accordion-border-radius: 0.375rem;\n  --bs-accordion-inner-border-radius: calc(0.375rem - 1px);\n  --bs-accordion-btn-padding-x: 1.25rem;\n  --bs-accordion-btn-padding-y: 1rem;\n  --bs-accordion-btn-color: #212529;\n  --bs-accordion-btn-bg: var(--bs-accordion-bg);\n  --bs-accordion-btn-icon: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e\");\n  --bs-accordion-btn-icon-width: 1.25rem;\n  --bs-accordion-btn-icon-transform: rotate(-180deg);\n  --bs-accordion-btn-icon-transition: transform 0.2s ease-in-out;\n  --bs-accordion-btn-active-icon: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e\");\n  --bs-accordion-btn-focus-border-color: #86b7fe;\n  --bs-accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n  --bs-accordion-body-padding-x: 1.25rem;\n  --bs-accordion-body-padding-y: 1rem;\n  --bs-accordion-active-color: #0c63e4;\n  --bs-accordion-active-bg: #e7f1ff;\n}\n\n.accordion-button {\n  position: relative;\n  display: flex;\n  align-items: center;\n  width: 100%;\n  padding: var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);\n  font-size: 1rem;\n  color: var(--bs-accordion-btn-color);\n  text-align: left;\n  background-color: var(--bs-accordion-btn-bg);\n  border: 0;\n  border-radius: 0;\n  overflow-anchor: none;\n  transition: var(--bs-accordion-transition);\n}\n@media (prefers-reduced-motion: reduce) {\n  .accordion-button {\n    transition: none;\n  }\n}\n.accordion-button:not(.collapsed) {\n  color: var(--bs-accordion-active-color);\n  background-color: var(--bs-accordion-active-bg);\n  box-shadow: inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color);\n}\n.accordion-button:not(.collapsed)::after {\n  background-image: var(--bs-accordion-btn-active-icon);\n  transform: var(--bs-accordion-btn-icon-transform);\n}\n.accordion-button::after {\n  flex-shrink: 0;\n  width: var(--bs-accordion-btn-icon-width);\n  height: var(--bs-accordion-btn-icon-width);\n  margin-left: auto;\n  content: \"\";\n  background-image: var(--bs-accordion-btn-icon);\n  background-repeat: no-repeat;\n  background-size: var(--bs-accordion-btn-icon-width);\n  transition: var(--bs-accordion-btn-icon-transition);\n}\n@media (prefers-reduced-motion: reduce) {\n  .accordion-button::after {\n    transition: none;\n  }\n}\n.accordion-button:hover {\n  z-index: 2;\n}\n.accordion-button:focus {\n  z-index: 3;\n  border-color: var(--bs-accordion-btn-focus-border-color);\n  outline: 0;\n  box-shadow: var(--bs-accordion-btn-focus-box-shadow);\n}\n\n.accordion-header {\n  margin-bottom: 0;\n}\n\n.accordion-item {\n  color: var(--bs-accordion-color);\n  background-color: var(--bs-accordion-bg);\n  border: var(--bs-accordion-border-width) solid var(--bs-accordion-border-color);\n}\n.accordion-item:first-of-type {\n  border-top-left-radius: var(--bs-accordion-border-radius);\n  border-top-right-radius: var(--bs-accordion-border-radius);\n}\n.accordion-item:first-of-type .accordion-button {\n  border-top-left-radius: var(--bs-accordion-inner-border-radius);\n  border-top-right-radius: var(--bs-accordion-inner-border-radius);\n}\n.accordion-item:not(:first-of-type) {\n  border-top: 0;\n}\n.accordion-item:last-of-type {\n  border-bottom-right-radius: var(--bs-accordion-border-radius);\n  border-bottom-left-radius: var(--bs-accordion-border-radius);\n}\n.accordion-item:last-of-type .accordion-button.collapsed {\n  border-bottom-right-radius: var(--bs-accordion-inner-border-radius);\n  border-bottom-left-radius: var(--bs-accordion-inner-border-radius);\n}\n.accordion-item:last-of-type .accordion-collapse {\n  border-bottom-right-radius: var(--bs-accordion-border-radius);\n  border-bottom-left-radius: var(--bs-accordion-border-radius);\n}\n\n.accordion-body {\n  padding: var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x);\n}\n\n.accordion-flush .accordion-collapse {\n  border-width: 0;\n}\n.accordion-flush .accordion-item {\n  border-right: 0;\n  border-left: 0;\n  border-radius: 0;\n}\n.accordion-flush .accordion-item:first-child {\n  border-top: 0;\n}\n.accordion-flush .accordion-item:last-child {\n  border-bottom: 0;\n}\n.accordion-flush .accordion-item .accordion-button, .accordion-flush .accordion-item .accordion-button.collapsed {\n  border-radius: 0;\n}\n\n.breadcrumb {\n  --bs-breadcrumb-padding-x: 0;\n  --bs-breadcrumb-padding-y: 0;\n  --bs-breadcrumb-margin-bottom: 1rem;\n  --bs-breadcrumb-bg: ;\n  --bs-breadcrumb-border-radius: ;\n  --bs-breadcrumb-divider-color: #6c757d;\n  --bs-breadcrumb-item-padding-x: 0.5rem;\n  --bs-breadcrumb-item-active-color: #6c757d;\n  display: flex;\n  flex-wrap: wrap;\n  padding: var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);\n  margin-bottom: var(--bs-breadcrumb-margin-bottom);\n  font-size: var(--bs-breadcrumb-font-size);\n  list-style: none;\n  background-color: var(--bs-breadcrumb-bg);\n  border-radius: var(--bs-breadcrumb-border-radius);\n}\n\n.breadcrumb-item + .breadcrumb-item {\n  padding-left: var(--bs-breadcrumb-item-padding-x);\n}\n.breadcrumb-item + .breadcrumb-item::before {\n  float: left;\n  padding-right: var(--bs-breadcrumb-item-padding-x);\n  color: var(--bs-breadcrumb-divider-color);\n  content: var(--bs-breadcrumb-divider, \"/\") /* rtl: var(--bs-breadcrumb-divider, \"/\") */;\n}\n.breadcrumb-item.active {\n  color: var(--bs-breadcrumb-item-active-color);\n}\n\n.pagination {\n  --bs-pagination-padding-x: 0.75rem;\n  --bs-pagination-padding-y: 0.375rem;\n  --bs-pagination-font-size: 1rem;\n  --bs-pagination-color: var(--bs-link-color);\n  --bs-pagination-bg: #fff;\n  --bs-pagination-border-width: 1px;\n  --bs-pagination-border-color: #dee2e6;\n  --bs-pagination-border-radius: 0.375rem;\n  --bs-pagination-hover-color: var(--bs-link-hover-color);\n  --bs-pagination-hover-bg: #e9ecef;\n  --bs-pagination-hover-border-color: #dee2e6;\n  --bs-pagination-focus-color: var(--bs-link-hover-color);\n  --bs-pagination-focus-bg: #e9ecef;\n  --bs-pagination-focus-box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n  --bs-pagination-active-color: #fff;\n  --bs-pagination-active-bg: #0d6efd;\n  --bs-pagination-active-border-color: #0d6efd;\n  --bs-pagination-disabled-color: #6c757d;\n  --bs-pagination-disabled-bg: #fff;\n  --bs-pagination-disabled-border-color: #dee2e6;\n  display: flex;\n  padding-left: 0;\n  list-style: none;\n}\n\n.page-link {\n  position: relative;\n  display: block;\n  padding: var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);\n  font-size: var(--bs-pagination-font-size);\n  color: var(--bs-pagination-color);\n  text-decoration: none;\n  background-color: var(--bs-pagination-bg);\n  border: var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);\n  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .page-link {\n    transition: none;\n  }\n}\n.page-link:hover {\n  z-index: 2;\n  color: var(--bs-pagination-hover-color);\n  background-color: var(--bs-pagination-hover-bg);\n  border-color: var(--bs-pagination-hover-border-color);\n}\n.page-link:focus {\n  z-index: 3;\n  color: var(--bs-pagination-focus-color);\n  background-color: var(--bs-pagination-focus-bg);\n  outline: 0;\n  box-shadow: var(--bs-pagination-focus-box-shadow);\n}\n.page-link.active, .active > .page-link {\n  z-index: 3;\n  color: var(--bs-pagination-active-color);\n  background-color: var(--bs-pagination-active-bg);\n  border-color: var(--bs-pagination-active-border-color);\n}\n.page-link.disabled, .disabled > .page-link {\n  color: var(--bs-pagination-disabled-color);\n  pointer-events: none;\n  background-color: var(--bs-pagination-disabled-bg);\n  border-color: var(--bs-pagination-disabled-border-color);\n}\n\n.page-item:not(:first-child) .page-link {\n  margin-left: -1px;\n}\n.page-item:first-child .page-link {\n  border-top-left-radius: var(--bs-pagination-border-radius);\n  border-bottom-left-radius: var(--bs-pagination-border-radius);\n}\n.page-item:last-child .page-link {\n  border-top-right-radius: var(--bs-pagination-border-radius);\n  border-bottom-right-radius: var(--bs-pagination-border-radius);\n}\n\n.pagination-lg {\n  --bs-pagination-padding-x: 1.5rem;\n  --bs-pagination-padding-y: 0.75rem;\n  --bs-pagination-font-size: 1.25rem;\n  --bs-pagination-border-radius: 0.5rem;\n}\n\n.pagination-sm {\n  --bs-pagination-padding-x: 0.5rem;\n  --bs-pagination-padding-y: 0.25rem;\n  --bs-pagination-font-size: 0.875rem;\n  --bs-pagination-border-radius: 0.25rem;\n}\n\n.badge {\n  --bs-badge-padding-x: 0.65em;\n  --bs-badge-padding-y: 0.35em;\n  --bs-badge-font-size: 0.75em;\n  --bs-badge-font-weight: 700;\n  --bs-badge-color: #fff;\n  --bs-badge-border-radius: 0.375rem;\n  display: inline-block;\n  padding: var(--bs-badge-padding-y) var(--bs-badge-padding-x);\n  font-size: var(--bs-badge-font-size);\n  font-weight: var(--bs-badge-font-weight);\n  line-height: 1;\n  color: var(--bs-badge-color);\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: var(--bs-badge-border-radius);\n}\n.badge:empty {\n  display: none;\n}\n\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n\n.alert {\n  --bs-alert-bg: transparent;\n  --bs-alert-padding-x: 1rem;\n  --bs-alert-padding-y: 1rem;\n  --bs-alert-margin-bottom: 1rem;\n  --bs-alert-color: inherit;\n  --bs-alert-border-color: transparent;\n  --bs-alert-border: 1px solid var(--bs-alert-border-color);\n  --bs-alert-border-radius: 0.375rem;\n  position: relative;\n  padding: var(--bs-alert-padding-y) var(--bs-alert-padding-x);\n  margin-bottom: var(--bs-alert-margin-bottom);\n  color: var(--bs-alert-color);\n  background-color: var(--bs-alert-bg);\n  border: var(--bs-alert-border);\n  border-radius: var(--bs-alert-border-radius);\n}\n\n.alert-heading {\n  color: inherit;\n}\n\n.alert-link {\n  font-weight: 700;\n}\n\n.alert-dismissible {\n  padding-right: 3rem;\n}\n.alert-dismissible .btn-close {\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 2;\n  padding: 1.25rem 1rem;\n}\n\n.alert-primary {\n  --bs-alert-color: #084298;\n  --bs-alert-bg: #cfe2ff;\n  --bs-alert-border-color: #b6d4fe;\n}\n.alert-primary .alert-link {\n  color: #06357a;\n}\n\n.alert-secondary {\n  --bs-alert-color: #41464b;\n  --bs-alert-bg: #e2e3e5;\n  --bs-alert-border-color: #d3d6d8;\n}\n.alert-secondary .alert-link {\n  color: #34383c;\n}\n\n.alert-success {\n  --bs-alert-color: #0f5132;\n  --bs-alert-bg: #d1e7dd;\n  --bs-alert-border-color: #badbcc;\n}\n.alert-success .alert-link {\n  color: #0c4128;\n}\n\n.alert-info {\n  --bs-alert-color: #055160;\n  --bs-alert-bg: #cff4fc;\n  --bs-alert-border-color: #b6effb;\n}\n.alert-info .alert-link {\n  color: #04414d;\n}\n\n.alert-warning {\n  --bs-alert-color: #664d03;\n  --bs-alert-bg: #fff3cd;\n  --bs-alert-border-color: #ffecb5;\n}\n.alert-warning .alert-link {\n  color: #523e02;\n}\n\n.alert-danger {\n  --bs-alert-color: #842029;\n  --bs-alert-bg: #f8d7da;\n  --bs-alert-border-color: #f5c2c7;\n}\n.alert-danger .alert-link {\n  color: #6a1a21;\n}\n\n.alert-light {\n  --bs-alert-color: #636464;\n  --bs-alert-bg: #fefefe;\n  --bs-alert-border-color: #fdfdfe;\n}\n.alert-light .alert-link {\n  color: #4f5050;\n}\n\n.alert-dark {\n  --bs-alert-color: #141619;\n  --bs-alert-bg: #d3d3d4;\n  --bs-alert-border-color: #bcbebf;\n}\n.alert-dark .alert-link {\n  color: #101214;\n}\n\n@keyframes progress-bar-stripes {\n  0% {\n    background-position-x: 1rem;\n  }\n}\n.progress {\n  --bs-progress-height: 1rem;\n  --bs-progress-font-size: 0.75rem;\n  --bs-progress-bg: #e9ecef;\n  --bs-progress-border-radius: 0.375rem;\n  --bs-progress-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075);\n  --bs-progress-bar-color: #fff;\n  --bs-progress-bar-bg: #0d6efd;\n  --bs-progress-bar-transition: width 0.6s ease;\n  display: flex;\n  height: var(--bs-progress-height);\n  overflow: hidden;\n  font-size: var(--bs-progress-font-size);\n  background-color: var(--bs-progress-bg);\n  border-radius: var(--bs-progress-border-radius);\n}\n\n.progress-bar {\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  overflow: hidden;\n  color: var(--bs-progress-bar-color);\n  text-align: center;\n  white-space: nowrap;\n  background-color: var(--bs-progress-bar-bg);\n  transition: var(--bs-progress-bar-transition);\n}\n@media (prefers-reduced-motion: reduce) {\n  .progress-bar {\n    transition: none;\n  }\n}\n\n.progress-bar-striped {\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-size: var(--bs-progress-height) var(--bs-progress-height);\n}\n\n.progress-bar-animated {\n  animation: 1s linear infinite progress-bar-stripes;\n}\n@media (prefers-reduced-motion: reduce) {\n  .progress-bar-animated {\n    animation: none;\n  }\n}\n\n.list-group {\n  --bs-list-group-color: #212529;\n  --bs-list-group-bg: #fff;\n  --bs-list-group-border-color: rgba(0, 0, 0, 0.125);\n  --bs-list-group-border-width: 1px;\n  --bs-list-group-border-radius: 0.375rem;\n  --bs-list-group-item-padding-x: 1rem;\n  --bs-list-group-item-padding-y: 0.5rem;\n  --bs-list-group-action-color: #495057;\n  --bs-list-group-action-hover-color: #495057;\n  --bs-list-group-action-hover-bg: #f8f9fa;\n  --bs-list-group-action-active-color: #212529;\n  --bs-list-group-action-active-bg: #e9ecef;\n  --bs-list-group-disabled-color: #6c757d;\n  --bs-list-group-disabled-bg: #fff;\n  --bs-list-group-active-color: #fff;\n  --bs-list-group-active-bg: #0d6efd;\n  --bs-list-group-active-border-color: #0d6efd;\n  display: flex;\n  flex-direction: column;\n  padding-left: 0;\n  margin-bottom: 0;\n  border-radius: var(--bs-list-group-border-radius);\n}\n\n.list-group-numbered {\n  list-style-type: none;\n  counter-reset: section;\n}\n.list-group-numbered > .list-group-item::before {\n  content: counters(section, \".\") \". \";\n  counter-increment: section;\n}\n\n.list-group-item-action {\n  width: 100%;\n  color: var(--bs-list-group-action-color);\n  text-align: inherit;\n}\n.list-group-item-action:hover, .list-group-item-action:focus {\n  z-index: 1;\n  color: var(--bs-list-group-action-hover-color);\n  text-decoration: none;\n  background-color: var(--bs-list-group-action-hover-bg);\n}\n.list-group-item-action:active {\n  color: var(--bs-list-group-action-active-color);\n  background-color: var(--bs-list-group-action-active-bg);\n}\n\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);\n  color: var(--bs-list-group-color);\n  text-decoration: none;\n  background-color: var(--bs-list-group-bg);\n  border: var(--bs-list-group-border-width) solid var(--bs-list-group-border-color);\n}\n.list-group-item:first-child {\n  border-top-left-radius: inherit;\n  border-top-right-radius: inherit;\n}\n.list-group-item:last-child {\n  border-bottom-right-radius: inherit;\n  border-bottom-left-radius: inherit;\n}\n.list-group-item.disabled, .list-group-item:disabled {\n  color: var(--bs-list-group-disabled-color);\n  pointer-events: none;\n  background-color: var(--bs-list-group-disabled-bg);\n}\n.list-group-item.active {\n  z-index: 2;\n  color: var(--bs-list-group-active-color);\n  background-color: var(--bs-list-group-active-bg);\n  border-color: var(--bs-list-group-active-border-color);\n}\n.list-group-item + .list-group-item {\n  border-top-width: 0;\n}\n.list-group-item + .list-group-item.active {\n  margin-top: calc(-1 * var(--bs-list-group-border-width));\n  border-top-width: var(--bs-list-group-border-width);\n}\n\n.list-group-horizontal {\n  flex-direction: row;\n}\n.list-group-horizontal > .list-group-item:first-child:not(:last-child) {\n  border-bottom-left-radius: var(--bs-list-group-border-radius);\n  border-top-right-radius: 0;\n}\n.list-group-horizontal > .list-group-item:last-child:not(:first-child) {\n  border-top-right-radius: var(--bs-list-group-border-radius);\n  border-bottom-left-radius: 0;\n}\n.list-group-horizontal > .list-group-item.active {\n  margin-top: 0;\n}\n.list-group-horizontal > .list-group-item + .list-group-item {\n  border-top-width: var(--bs-list-group-border-width);\n  border-left-width: 0;\n}\n.list-group-horizontal > .list-group-item + .list-group-item.active {\n  margin-left: calc(-1 * var(--bs-list-group-border-width));\n  border-left-width: var(--bs-list-group-border-width);\n}\n\n@media (min-width: 576px) {\n  .list-group-horizontal-sm {\n    flex-direction: row;\n  }\n  .list-group-horizontal-sm > .list-group-item:first-child:not(:last-child) {\n    border-bottom-left-radius: var(--bs-list-group-border-radius);\n    border-top-right-radius: 0;\n  }\n  .list-group-horizontal-sm > .list-group-item:last-child:not(:first-child) {\n    border-top-right-radius: var(--bs-list-group-border-radius);\n    border-bottom-left-radius: 0;\n  }\n  .list-group-horizontal-sm > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-sm > .list-group-item + .list-group-item {\n    border-top-width: var(--bs-list-group-border-width);\n    border-left-width: 0;\n  }\n  .list-group-horizontal-sm > .list-group-item + .list-group-item.active {\n    margin-left: calc(-1 * var(--bs-list-group-border-width));\n    border-left-width: var(--bs-list-group-border-width);\n  }\n}\n@media (min-width: 768px) {\n  .list-group-horizontal-md {\n    flex-direction: row;\n  }\n  .list-group-horizontal-md > .list-group-item:first-child:not(:last-child) {\n    border-bottom-left-radius: var(--bs-list-group-border-radius);\n    border-top-right-radius: 0;\n  }\n  .list-group-horizontal-md > .list-group-item:last-child:not(:first-child) {\n    border-top-right-radius: var(--bs-list-group-border-radius);\n    border-bottom-left-radius: 0;\n  }\n  .list-group-horizontal-md > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-md > .list-group-item + .list-group-item {\n    border-top-width: var(--bs-list-group-border-width);\n    border-left-width: 0;\n  }\n  .list-group-horizontal-md > .list-group-item + .list-group-item.active {\n    margin-left: calc(-1 * var(--bs-list-group-border-width));\n    border-left-width: var(--bs-list-group-border-width);\n  }\n}\n@media (min-width: 992px) {\n  .list-group-horizontal-lg {\n    flex-direction: row;\n  }\n  .list-group-horizontal-lg > .list-group-item:first-child:not(:last-child) {\n    border-bottom-left-radius: var(--bs-list-group-border-radius);\n    border-top-right-radius: 0;\n  }\n  .list-group-horizontal-lg > .list-group-item:last-child:not(:first-child) {\n    border-top-right-radius: var(--bs-list-group-border-radius);\n    border-bottom-left-radius: 0;\n  }\n  .list-group-horizontal-lg > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-lg > .list-group-item + .list-group-item {\n    border-top-width: var(--bs-list-group-border-width);\n    border-left-width: 0;\n  }\n  .list-group-horizontal-lg > .list-group-item + .list-group-item.active {\n    margin-left: calc(-1 * var(--bs-list-group-border-width));\n    border-left-width: var(--bs-list-group-border-width);\n  }\n}\n@media (min-width: 1200px) {\n  .list-group-horizontal-xl {\n    flex-direction: row;\n  }\n  .list-group-horizontal-xl > .list-group-item:first-child:not(:last-child) {\n    border-bottom-left-radius: var(--bs-list-group-border-radius);\n    border-top-right-radius: 0;\n  }\n  .list-group-horizontal-xl > .list-group-item:last-child:not(:first-child) {\n    border-top-right-radius: var(--bs-list-group-border-radius);\n    border-bottom-left-radius: 0;\n  }\n  .list-group-horizontal-xl > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-xl > .list-group-item + .list-group-item {\n    border-top-width: var(--bs-list-group-border-width);\n    border-left-width: 0;\n  }\n  .list-group-horizontal-xl > .list-group-item + .list-group-item.active {\n    margin-left: calc(-1 * var(--bs-list-group-border-width));\n    border-left-width: var(--bs-list-group-border-width);\n  }\n}\n@media (min-width: 1400px) {\n  .list-group-horizontal-xxl {\n    flex-direction: row;\n  }\n  .list-group-horizontal-xxl > .list-group-item:first-child:not(:last-child) {\n    border-bottom-left-radius: var(--bs-list-group-border-radius);\n    border-top-right-radius: 0;\n  }\n  .list-group-horizontal-xxl > .list-group-item:last-child:not(:first-child) {\n    border-top-right-radius: var(--bs-list-group-border-radius);\n    border-bottom-left-radius: 0;\n  }\n  .list-group-horizontal-xxl > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-xxl > .list-group-item + .list-group-item {\n    border-top-width: var(--bs-list-group-border-width);\n    border-left-width: 0;\n  }\n  .list-group-horizontal-xxl > .list-group-item + .list-group-item.active {\n    margin-left: calc(-1 * var(--bs-list-group-border-width));\n    border-left-width: var(--bs-list-group-border-width);\n  }\n}\n.list-group-flush {\n  border-radius: 0;\n}\n.list-group-flush > .list-group-item {\n  border-width: 0 0 var(--bs-list-group-border-width);\n}\n.list-group-flush > .list-group-item:last-child {\n  border-bottom-width: 0;\n}\n\n.list-group-item-primary {\n  color: #084298;\n  background-color: #cfe2ff;\n}\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n  color: #084298;\n  background-color: #bacbe6;\n}\n.list-group-item-primary.list-group-item-action.active {\n  color: #fff;\n  background-color: #084298;\n  border-color: #084298;\n}\n\n.list-group-item-secondary {\n  color: #41464b;\n  background-color: #e2e3e5;\n}\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n  color: #41464b;\n  background-color: #cbccce;\n}\n.list-group-item-secondary.list-group-item-action.active {\n  color: #fff;\n  background-color: #41464b;\n  border-color: #41464b;\n}\n\n.list-group-item-success {\n  color: #0f5132;\n  background-color: #d1e7dd;\n}\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n  color: #0f5132;\n  background-color: #bcd0c7;\n}\n.list-group-item-success.list-group-item-action.active {\n  color: #fff;\n  background-color: #0f5132;\n  border-color: #0f5132;\n}\n\n.list-group-item-info {\n  color: #055160;\n  background-color: #cff4fc;\n}\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n  color: #055160;\n  background-color: #badce3;\n}\n.list-group-item-info.list-group-item-action.active {\n  color: #fff;\n  background-color: #055160;\n  border-color: #055160;\n}\n\n.list-group-item-warning {\n  color: #664d03;\n  background-color: #fff3cd;\n}\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n  color: #664d03;\n  background-color: #e6dbb9;\n}\n.list-group-item-warning.list-group-item-action.active {\n  color: #fff;\n  background-color: #664d03;\n  border-color: #664d03;\n}\n\n.list-group-item-danger {\n  color: #842029;\n  background-color: #f8d7da;\n}\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n  color: #842029;\n  background-color: #dfc2c4;\n}\n.list-group-item-danger.list-group-item-action.active {\n  color: #fff;\n  background-color: #842029;\n  border-color: #842029;\n}\n\n.list-group-item-light {\n  color: #636464;\n  background-color: #fefefe;\n}\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n  color: #636464;\n  background-color: #e5e5e5;\n}\n.list-group-item-light.list-group-item-action.active {\n  color: #fff;\n  background-color: #636464;\n  border-color: #636464;\n}\n\n.list-group-item-dark {\n  color: #141619;\n  background-color: #d3d3d4;\n}\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n  color: #141619;\n  background-color: #bebebf;\n}\n.list-group-item-dark.list-group-item-action.active {\n  color: #fff;\n  background-color: #141619;\n  border-color: #141619;\n}\n\n.btn-close {\n  box-sizing: content-box;\n  width: 1em;\n  height: 1em;\n  padding: 0.25em 0.25em;\n  color: #000;\n  background: transparent url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e\") center/1em auto no-repeat;\n  border: 0;\n  border-radius: 0.375rem;\n  opacity: 0.5;\n}\n.btn-close:hover {\n  color: #000;\n  text-decoration: none;\n  opacity: 0.75;\n}\n.btn-close:focus {\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n  opacity: 1;\n}\n.btn-close:disabled, .btn-close.disabled {\n  pointer-events: none;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  user-select: none;\n  opacity: 0.25;\n}\n\n.btn-close-white {\n  filter: invert(1) grayscale(100%) brightness(200%);\n}\n\n.toast {\n  --bs-toast-zindex: 1090;\n  --bs-toast-padding-x: 0.75rem;\n  --bs-toast-padding-y: 0.5rem;\n  --bs-toast-spacing: 1.5rem;\n  --bs-toast-max-width: 350px;\n  --bs-toast-font-size: 0.875rem;\n  --bs-toast-color: ;\n  --bs-toast-bg: rgba(255, 255, 255, 0.85);\n  --bs-toast-border-width: 1px;\n  --bs-toast-border-color: var(--bs-border-color-translucent);\n  --bs-toast-border-radius: 0.375rem;\n  --bs-toast-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n  --bs-toast-header-color: #6c757d;\n  --bs-toast-header-bg: rgba(255, 255, 255, 0.85);\n  --bs-toast-header-border-color: rgba(0, 0, 0, 0.05);\n  width: var(--bs-toast-max-width);\n  max-width: 100%;\n  font-size: var(--bs-toast-font-size);\n  color: var(--bs-toast-color);\n  pointer-events: auto;\n  background-color: var(--bs-toast-bg);\n  background-clip: padding-box;\n  border: var(--bs-toast-border-width) solid var(--bs-toast-border-color);\n  box-shadow: var(--bs-toast-box-shadow);\n  border-radius: var(--bs-toast-border-radius);\n}\n.toast.showing {\n  opacity: 0;\n}\n.toast:not(.show) {\n  display: none;\n}\n\n.toast-container {\n  --bs-toast-zindex: 1090;\n  position: absolute;\n  z-index: var(--bs-toast-zindex);\n  width: -webkit-max-content;\n  width: -moz-max-content;\n  width: max-content;\n  max-width: 100%;\n  pointer-events: none;\n}\n.toast-container > :not(:last-child) {\n  margin-bottom: var(--bs-toast-spacing);\n}\n\n.toast-header {\n  display: flex;\n  align-items: center;\n  padding: var(--bs-toast-padding-y) var(--bs-toast-padding-x);\n  color: var(--bs-toast-header-color);\n  background-color: var(--bs-toast-header-bg);\n  background-clip: padding-box;\n  border-bottom: var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);\n  border-top-left-radius: calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));\n  border-top-right-radius: calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));\n}\n.toast-header .btn-close {\n  margin-right: calc(-0.5 * var(--bs-toast-padding-x));\n  margin-left: var(--bs-toast-padding-x);\n}\n\n.toast-body {\n  padding: var(--bs-toast-padding-x);\n  word-wrap: break-word;\n}\n\n.modal {\n  --bs-modal-zindex: 1055;\n  --bs-modal-width: 500px;\n  --bs-modal-padding: 1rem;\n  --bs-modal-margin: 0.5rem;\n  --bs-modal-color: ;\n  --bs-modal-bg: #fff;\n  --bs-modal-border-color: var(--bs-border-color-translucent);\n  --bs-modal-border-width: 1px;\n  --bs-modal-border-radius: 0.5rem;\n  --bs-modal-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);\n  --bs-modal-inner-border-radius: calc(0.5rem - 1px);\n  --bs-modal-header-padding-x: 1rem;\n  --bs-modal-header-padding-y: 1rem;\n  --bs-modal-header-padding: 1rem 1rem;\n  --bs-modal-header-border-color: var(--bs-border-color);\n  --bs-modal-header-border-width: 1px;\n  --bs-modal-title-line-height: 1.5;\n  --bs-modal-footer-gap: 0.5rem;\n  --bs-modal-footer-bg: ;\n  --bs-modal-footer-border-color: var(--bs-border-color);\n  --bs-modal-footer-border-width: 1px;\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: var(--bs-modal-zindex);\n  display: none;\n  width: 100%;\n  height: 100%;\n  overflow-x: hidden;\n  overflow-y: auto;\n  outline: 0;\n}\n\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: var(--bs-modal-margin);\n  pointer-events: none;\n}\n.modal.fade .modal-dialog {\n  transition: transform 0.3s ease-out;\n  transform: translate(0, -50px);\n}\n@media (prefers-reduced-motion: reduce) {\n  .modal.fade .modal-dialog {\n    transition: none;\n  }\n}\n.modal.show .modal-dialog {\n  transform: none;\n}\n.modal.modal-static .modal-dialog {\n  transform: scale(1.02);\n}\n\n.modal-dialog-scrollable {\n  height: calc(100% - var(--bs-modal-margin) * 2);\n}\n.modal-dialog-scrollable .modal-content {\n  max-height: 100%;\n  overflow: hidden;\n}\n.modal-dialog-scrollable .modal-body {\n  overflow-y: auto;\n}\n\n.modal-dialog-centered {\n  display: flex;\n  align-items: center;\n  min-height: calc(100% - var(--bs-modal-margin) * 2);\n}\n\n.modal-content {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n  color: var(--bs-modal-color);\n  pointer-events: auto;\n  background-color: var(--bs-modal-bg);\n  background-clip: padding-box;\n  border: var(--bs-modal-border-width) solid var(--bs-modal-border-color);\n  border-radius: var(--bs-modal-border-radius);\n  outline: 0;\n}\n\n.modal-backdrop {\n  --bs-backdrop-zindex: 1050;\n  --bs-backdrop-bg: #000;\n  --bs-backdrop-opacity: 0.5;\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: var(--bs-backdrop-zindex);\n  width: 100vw;\n  height: 100vh;\n  background-color: var(--bs-backdrop-bg);\n}\n.modal-backdrop.fade {\n  opacity: 0;\n}\n.modal-backdrop.show {\n  opacity: var(--bs-backdrop-opacity);\n}\n\n.modal-header {\n  display: flex;\n  flex-shrink: 0;\n  align-items: center;\n  justify-content: space-between;\n  padding: var(--bs-modal-header-padding);\n  border-bottom: var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);\n  border-top-left-radius: var(--bs-modal-inner-border-radius);\n  border-top-right-radius: var(--bs-modal-inner-border-radius);\n}\n.modal-header .btn-close {\n  padding: calc(var(--bs-modal-header-padding-y) * 0.5) calc(var(--bs-modal-header-padding-x) * 0.5);\n  margin: calc(-0.5 * var(--bs-modal-header-padding-y)) calc(-0.5 * var(--bs-modal-header-padding-x)) calc(-0.5 * var(--bs-modal-header-padding-y)) auto;\n}\n\n.modal-title {\n  margin-bottom: 0;\n  line-height: var(--bs-modal-title-line-height);\n}\n\n.modal-body {\n  position: relative;\n  flex: 1 1 auto;\n  padding: var(--bs-modal-padding);\n}\n\n.modal-footer {\n  display: flex;\n  flex-shrink: 0;\n  flex-wrap: wrap;\n  align-items: center;\n  justify-content: flex-end;\n  padding: calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * 0.5);\n  background-color: var(--bs-modal-footer-bg);\n  border-top: var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);\n  border-bottom-right-radius: var(--bs-modal-inner-border-radius);\n  border-bottom-left-radius: var(--bs-modal-inner-border-radius);\n}\n.modal-footer > * {\n  margin: calc(var(--bs-modal-footer-gap) * 0.5);\n}\n\n@media (min-width: 576px) {\n  .modal {\n    --bs-modal-margin: 1.75rem;\n    --bs-modal-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n  }\n  .modal-dialog {\n    max-width: var(--bs-modal-width);\n    margin-right: auto;\n    margin-left: auto;\n  }\n  .modal-sm {\n    --bs-modal-width: 300px;\n  }\n}\n@media (min-width: 992px) {\n  .modal-lg,\n.modal-xl {\n    --bs-modal-width: 800px;\n  }\n}\n@media (min-width: 1200px) {\n  .modal-xl {\n    --bs-modal-width: 1140px;\n  }\n}\n.modal-fullscreen {\n  width: 100vw;\n  max-width: none;\n  height: 100%;\n  margin: 0;\n}\n.modal-fullscreen .modal-content {\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n}\n.modal-fullscreen .modal-header,\n.modal-fullscreen .modal-footer {\n  border-radius: 0;\n}\n.modal-fullscreen .modal-body {\n  overflow-y: auto;\n}\n\n@media (max-width: 575.98px) {\n  .modal-fullscreen-sm-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-sm-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-sm-down .modal-header,\n.modal-fullscreen-sm-down .modal-footer {\n    border-radius: 0;\n  }\n  .modal-fullscreen-sm-down .modal-body {\n    overflow-y: auto;\n  }\n}\n@media (max-width: 767.98px) {\n  .modal-fullscreen-md-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-md-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-md-down .modal-header,\n.modal-fullscreen-md-down .modal-footer {\n    border-radius: 0;\n  }\n  .modal-fullscreen-md-down .modal-body {\n    overflow-y: auto;\n  }\n}\n@media (max-width: 991.98px) {\n  .modal-fullscreen-lg-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-lg-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-lg-down .modal-header,\n.modal-fullscreen-lg-down .modal-footer {\n    border-radius: 0;\n  }\n  .modal-fullscreen-lg-down .modal-body {\n    overflow-y: auto;\n  }\n}\n@media (max-width: 1199.98px) {\n  .modal-fullscreen-xl-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-xl-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-xl-down .modal-header,\n.modal-fullscreen-xl-down .modal-footer {\n    border-radius: 0;\n  }\n  .modal-fullscreen-xl-down .modal-body {\n    overflow-y: auto;\n  }\n}\n@media (max-width: 1399.98px) {\n  .modal-fullscreen-xxl-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-xxl-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-xxl-down .modal-header,\n.modal-fullscreen-xxl-down .modal-footer {\n    border-radius: 0;\n  }\n  .modal-fullscreen-xxl-down .modal-body {\n    overflow-y: auto;\n  }\n}\n.tooltip {\n  --bs-tooltip-zindex: 1080;\n  --bs-tooltip-max-width: 200px;\n  --bs-tooltip-padding-x: 0.5rem;\n  --bs-tooltip-padding-y: 0.25rem;\n  --bs-tooltip-margin: ;\n  --bs-tooltip-font-size: 0.875rem;\n  --bs-tooltip-color: #fff;\n  --bs-tooltip-bg: #000;\n  --bs-tooltip-border-radius: 0.375rem;\n  --bs-tooltip-opacity: 0.9;\n  --bs-tooltip-arrow-width: 0.8rem;\n  --bs-tooltip-arrow-height: 0.4rem;\n  z-index: var(--bs-tooltip-zindex);\n  display: block;\n  padding: var(--bs-tooltip-arrow-height);\n  margin: var(--bs-tooltip-margin);\n  font-family: var(--bs-font-sans-serif);\n  font-style: normal;\n  font-weight: 400;\n  line-height: 1.5;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  white-space: normal;\n  word-spacing: normal;\n  line-break: auto;\n  font-size: var(--bs-tooltip-font-size);\n  word-wrap: break-word;\n  opacity: 0;\n}\n.tooltip.show {\n  opacity: var(--bs-tooltip-opacity);\n}\n.tooltip .tooltip-arrow {\n  display: block;\n  width: var(--bs-tooltip-arrow-width);\n  height: var(--bs-tooltip-arrow-height);\n}\n.tooltip .tooltip-arrow::before {\n  position: absolute;\n  content: \"\";\n  border-color: transparent;\n  border-style: solid;\n}\n\n.bs-tooltip-top .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow {\n  bottom: 0;\n}\n.bs-tooltip-top .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before {\n  top: -1px;\n  border-width: var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * 0.5) 0;\n  border-top-color: var(--bs-tooltip-bg);\n}\n\n/* rtl:begin:ignore */\n.bs-tooltip-end .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow {\n  left: 0;\n  width: var(--bs-tooltip-arrow-height);\n  height: var(--bs-tooltip-arrow-width);\n}\n.bs-tooltip-end .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before {\n  right: -1px;\n  border-width: calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * 0.5) 0;\n  border-right-color: var(--bs-tooltip-bg);\n}\n\n/* rtl:end:ignore */\n.bs-tooltip-bottom .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow {\n  top: 0;\n}\n.bs-tooltip-bottom .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before {\n  bottom: -1px;\n  border-width: 0 calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height);\n  border-bottom-color: var(--bs-tooltip-bg);\n}\n\n/* rtl:begin:ignore */\n.bs-tooltip-start .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow {\n  right: 0;\n  width: var(--bs-tooltip-arrow-height);\n  height: var(--bs-tooltip-arrow-width);\n}\n.bs-tooltip-start .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before {\n  left: -1px;\n  border-width: calc(var(--bs-tooltip-arrow-width) * 0.5) 0 calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height);\n  border-left-color: var(--bs-tooltip-bg);\n}\n\n/* rtl:end:ignore */\n.tooltip-inner {\n  max-width: var(--bs-tooltip-max-width);\n  padding: var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);\n  color: var(--bs-tooltip-color);\n  text-align: center;\n  background-color: var(--bs-tooltip-bg);\n  border-radius: var(--bs-tooltip-border-radius);\n}\n\n.popover {\n  --bs-popover-zindex: 1070;\n  --bs-popover-max-width: 276px;\n  --bs-popover-font-size: 0.875rem;\n  --bs-popover-bg: #fff;\n  --bs-popover-border-width: 1px;\n  --bs-popover-border-color: var(--bs-border-color-translucent);\n  --bs-popover-border-radius: 0.5rem;\n  --bs-popover-inner-border-radius: calc(0.5rem - 1px);\n  --bs-popover-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n  --bs-popover-header-padding-x: 1rem;\n  --bs-popover-header-padding-y: 0.5rem;\n  --bs-popover-header-font-size: 1rem;\n  --bs-popover-header-color: ;\n  --bs-popover-header-bg: #f0f0f0;\n  --bs-popover-body-padding-x: 1rem;\n  --bs-popover-body-padding-y: 1rem;\n  --bs-popover-body-color: #212529;\n  --bs-popover-arrow-width: 1rem;\n  --bs-popover-arrow-height: 0.5rem;\n  --bs-popover-arrow-border: var(--bs-popover-border-color);\n  z-index: var(--bs-popover-zindex);\n  display: block;\n  max-width: var(--bs-popover-max-width);\n  font-family: var(--bs-font-sans-serif);\n  font-style: normal;\n  font-weight: 400;\n  line-height: 1.5;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  white-space: normal;\n  word-spacing: normal;\n  line-break: auto;\n  font-size: var(--bs-popover-font-size);\n  word-wrap: break-word;\n  background-color: var(--bs-popover-bg);\n  background-clip: padding-box;\n  border: var(--bs-popover-border-width) solid var(--bs-popover-border-color);\n  border-radius: var(--bs-popover-border-radius);\n}\n.popover .popover-arrow {\n  display: block;\n  width: var(--bs-popover-arrow-width);\n  height: var(--bs-popover-arrow-height);\n}\n.popover .popover-arrow::before, .popover .popover-arrow::after {\n  position: absolute;\n  display: block;\n  content: \"\";\n  border-color: transparent;\n  border-style: solid;\n  border-width: 0;\n}\n\n.bs-popover-top > .popover-arrow, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow {\n  bottom: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));\n}\n.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before, .bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after {\n  border-width: var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * 0.5) 0;\n}\n.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before {\n  bottom: 0;\n  border-top-color: var(--bs-popover-arrow-border);\n}\n.bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after {\n  bottom: var(--bs-popover-border-width);\n  border-top-color: var(--bs-popover-bg);\n}\n\n/* rtl:begin:ignore */\n.bs-popover-end > .popover-arrow, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow {\n  left: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));\n  width: var(--bs-popover-arrow-height);\n  height: var(--bs-popover-arrow-width);\n}\n.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before, .bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after {\n  border-width: calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * 0.5) 0;\n}\n.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before {\n  left: 0;\n  border-right-color: var(--bs-popover-arrow-border);\n}\n.bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after {\n  left: var(--bs-popover-border-width);\n  border-right-color: var(--bs-popover-bg);\n}\n\n/* rtl:end:ignore */\n.bs-popover-bottom > .popover-arrow, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow {\n  top: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));\n}\n.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before, .bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after {\n  border-width: 0 calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height);\n}\n.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before {\n  top: 0;\n  border-bottom-color: var(--bs-popover-arrow-border);\n}\n.bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after {\n  top: var(--bs-popover-border-width);\n  border-bottom-color: var(--bs-popover-bg);\n}\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[data-popper-placement^=bottom] .popover-header::before {\n  position: absolute;\n  top: 0;\n  left: 50%;\n  display: block;\n  width: var(--bs-popover-arrow-width);\n  margin-left: calc(-0.5 * var(--bs-popover-arrow-width));\n  content: \"\";\n  border-bottom: var(--bs-popover-border-width) solid var(--bs-popover-header-bg);\n}\n\n/* rtl:begin:ignore */\n.bs-popover-start > .popover-arrow, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow {\n  right: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));\n  width: var(--bs-popover-arrow-height);\n  height: var(--bs-popover-arrow-width);\n}\n.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before, .bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after {\n  border-width: calc(var(--bs-popover-arrow-width) * 0.5) 0 calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height);\n}\n.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before {\n  right: 0;\n  border-left-color: var(--bs-popover-arrow-border);\n}\n.bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after {\n  right: var(--bs-popover-border-width);\n  border-left-color: var(--bs-popover-bg);\n}\n\n/* rtl:end:ignore */\n.popover-header {\n  padding: var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);\n  margin-bottom: 0;\n  font-size: var(--bs-popover-header-font-size);\n  color: var(--bs-popover-header-color);\n  background-color: var(--bs-popover-header-bg);\n  border-bottom: var(--bs-popover-border-width) solid var(--bs-popover-border-color);\n  border-top-left-radius: var(--bs-popover-inner-border-radius);\n  border-top-right-radius: var(--bs-popover-inner-border-radius);\n}\n.popover-header:empty {\n  display: none;\n}\n\n.popover-body {\n  padding: var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);\n  color: var(--bs-popover-body-color);\n}\n\n.carousel {\n  position: relative;\n}\n\n.carousel.pointer-event {\n  touch-action: pan-y;\n}\n\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n}\n.carousel-inner::after {\n  display: block;\n  clear: both;\n  content: \"\";\n}\n\n.carousel-item {\n  position: relative;\n  display: none;\n  float: left;\n  width: 100%;\n  margin-right: -100%;\n  -webkit-backface-visibility: hidden;\n  backface-visibility: hidden;\n  transition: transform 0.6s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .carousel-item {\n    transition: none;\n  }\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n  display: block;\n}\n\n.carousel-item-next:not(.carousel-item-start),\n.active.carousel-item-end {\n  transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-end),\n.active.carousel-item-start {\n  transform: translateX(-100%);\n}\n\n.carousel-fade .carousel-item {\n  opacity: 0;\n  transition-property: opacity;\n  transform: none;\n}\n.carousel-fade .carousel-item.active,\n.carousel-fade .carousel-item-next.carousel-item-start,\n.carousel-fade .carousel-item-prev.carousel-item-end {\n  z-index: 1;\n  opacity: 1;\n}\n.carousel-fade .active.carousel-item-start,\n.carousel-fade .active.carousel-item-end {\n  z-index: 0;\n  opacity: 0;\n  transition: opacity 0s 0.6s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .carousel-fade .active.carousel-item-start,\n.carousel-fade .active.carousel-item-end {\n    transition: none;\n  }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  z-index: 1;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 15%;\n  padding: 0;\n  color: #fff;\n  text-align: center;\n  background: none;\n  border: 0;\n  opacity: 0.5;\n  transition: opacity 0.15s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .carousel-control-prev,\n.carousel-control-next {\n    transition: none;\n  }\n}\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n  color: #fff;\n  text-decoration: none;\n  outline: 0;\n  opacity: 0.9;\n}\n\n.carousel-control-prev {\n  left: 0;\n}\n\n.carousel-control-next {\n  right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n  display: inline-block;\n  width: 2rem;\n  height: 2rem;\n  background-repeat: no-repeat;\n  background-position: 50%;\n  background-size: 100% 100%;\n}\n\n/* rtl:options: {\n  \"autoRename\": true,\n  \"stringMap\":[ {\n    \"name\"    : \"prev-next\",\n    \"search\"  : \"prev\",\n    \"replace\" : \"next\"\n  } ]\n} */\n.carousel-control-prev-icon {\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e\");\n}\n\n.carousel-control-next-icon {\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e\");\n}\n\n.carousel-indicators {\n  position: absolute;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 2;\n  display: flex;\n  justify-content: center;\n  padding: 0;\n  margin-right: 15%;\n  margin-bottom: 1rem;\n  margin-left: 15%;\n  list-style: none;\n}\n.carousel-indicators [data-bs-target] {\n  box-sizing: content-box;\n  flex: 0 1 auto;\n  width: 30px;\n  height: 3px;\n  padding: 0;\n  margin-right: 3px;\n  margin-left: 3px;\n  text-indent: -999px;\n  cursor: pointer;\n  background-color: #fff;\n  background-clip: padding-box;\n  border: 0;\n  border-top: 10px solid transparent;\n  border-bottom: 10px solid transparent;\n  opacity: 0.5;\n  transition: opacity 0.6s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .carousel-indicators [data-bs-target] {\n    transition: none;\n  }\n}\n.carousel-indicators .active {\n  opacity: 1;\n}\n\n.carousel-caption {\n  position: absolute;\n  right: 15%;\n  bottom: 1.25rem;\n  left: 15%;\n  padding-top: 1.25rem;\n  padding-bottom: 1.25rem;\n  color: #fff;\n  text-align: center;\n}\n\n.carousel-dark .carousel-control-prev-icon,\n.carousel-dark .carousel-control-next-icon {\n  filter: invert(1) grayscale(100);\n}\n.carousel-dark .carousel-indicators [data-bs-target] {\n  background-color: #000;\n}\n.carousel-dark .carousel-caption {\n  color: #000;\n}\n\n.spinner-grow,\n.spinner-border {\n  display: inline-block;\n  width: var(--bs-spinner-width);\n  height: var(--bs-spinner-height);\n  vertical-align: var(--bs-spinner-vertical-align);\n  border-radius: 50%;\n  animation: var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name);\n}\n\n@keyframes spinner-border {\n  to {\n    transform: rotate(360deg) /* rtl:ignore */;\n  }\n}\n.spinner-border {\n  --bs-spinner-width: 2rem;\n  --bs-spinner-height: 2rem;\n  --bs-spinner-vertical-align: -0.125em;\n  --bs-spinner-border-width: 0.25em;\n  --bs-spinner-animation-speed: 0.75s;\n  --bs-spinner-animation-name: spinner-border;\n  border: var(--bs-spinner-border-width) solid currentcolor;\n  border-right-color: transparent;\n}\n\n.spinner-border-sm {\n  --bs-spinner-width: 1rem;\n  --bs-spinner-height: 1rem;\n  --bs-spinner-border-width: 0.2em;\n}\n\n@keyframes spinner-grow {\n  0% {\n    transform: scale(0);\n  }\n  50% {\n    opacity: 1;\n    transform: none;\n  }\n}\n.spinner-grow {\n  --bs-spinner-width: 2rem;\n  --bs-spinner-height: 2rem;\n  --bs-spinner-vertical-align: -0.125em;\n  --bs-spinner-animation-speed: 0.75s;\n  --bs-spinner-animation-name: spinner-grow;\n  background-color: currentcolor;\n  opacity: 0;\n}\n\n.spinner-grow-sm {\n  --bs-spinner-width: 1rem;\n  --bs-spinner-height: 1rem;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .spinner-border,\n.spinner-grow {\n    --bs-spinner-animation-speed: 1.5s;\n  }\n}\n.offcanvas, .offcanvas-xxl, .offcanvas-xl, .offcanvas-lg, .offcanvas-md, .offcanvas-sm {\n  --bs-offcanvas-zindex: 1045;\n  --bs-offcanvas-width: 400px;\n  --bs-offcanvas-height: 30vh;\n  --bs-offcanvas-padding-x: 1rem;\n  --bs-offcanvas-padding-y: 1rem;\n  --bs-offcanvas-color: ;\n  --bs-offcanvas-bg: #fff;\n  --bs-offcanvas-border-width: 1px;\n  --bs-offcanvas-border-color: var(--bs-border-color-translucent);\n  --bs-offcanvas-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);\n}\n\n@media (max-width: 575.98px) {\n  .offcanvas-sm {\n    position: fixed;\n    bottom: 0;\n    z-index: var(--bs-offcanvas-zindex);\n    display: flex;\n    flex-direction: column;\n    max-width: 100%;\n    color: var(--bs-offcanvas-color);\n    visibility: hidden;\n    background-color: var(--bs-offcanvas-bg);\n    background-clip: padding-box;\n    outline: 0;\n    transition: transform 0.3s ease-in-out;\n  }\n}\n@media (max-width: 575.98px) and (prefers-reduced-motion: reduce) {\n  .offcanvas-sm {\n    transition: none;\n  }\n}\n@media (max-width: 575.98px) {\n  .offcanvas-sm.offcanvas-start {\n    top: 0;\n    left: 0;\n    width: var(--bs-offcanvas-width);\n    border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(-100%);\n  }\n}\n@media (max-width: 575.98px) {\n  .offcanvas-sm.offcanvas-end {\n    top: 0;\n    right: 0;\n    width: var(--bs-offcanvas-width);\n    border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(100%);\n  }\n}\n@media (max-width: 575.98px) {\n  .offcanvas-sm.offcanvas-top {\n    top: 0;\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(-100%);\n  }\n}\n@media (max-width: 575.98px) {\n  .offcanvas-sm.offcanvas-bottom {\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(100%);\n  }\n}\n@media (max-width: 575.98px) {\n  .offcanvas-sm.showing, .offcanvas-sm.show:not(.hiding) {\n    transform: none;\n  }\n}\n@media (max-width: 575.98px) {\n  .offcanvas-sm.showing, .offcanvas-sm.hiding, .offcanvas-sm.show {\n    visibility: visible;\n  }\n}\n@media (min-width: 576px) {\n  .offcanvas-sm {\n    --bs-offcanvas-height: auto;\n    --bs-offcanvas-border-width: 0;\n    background-color: transparent !important;\n  }\n  .offcanvas-sm .offcanvas-header {\n    display: none;\n  }\n  .offcanvas-sm .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n    background-color: transparent !important;\n  }\n}\n\n@media (max-width: 767.98px) {\n  .offcanvas-md {\n    position: fixed;\n    bottom: 0;\n    z-index: var(--bs-offcanvas-zindex);\n    display: flex;\n    flex-direction: column;\n    max-width: 100%;\n    color: var(--bs-offcanvas-color);\n    visibility: hidden;\n    background-color: var(--bs-offcanvas-bg);\n    background-clip: padding-box;\n    outline: 0;\n    transition: transform 0.3s ease-in-out;\n  }\n}\n@media (max-width: 767.98px) and (prefers-reduced-motion: reduce) {\n  .offcanvas-md {\n    transition: none;\n  }\n}\n@media (max-width: 767.98px) {\n  .offcanvas-md.offcanvas-start {\n    top: 0;\n    left: 0;\n    width: var(--bs-offcanvas-width);\n    border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(-100%);\n  }\n}\n@media (max-width: 767.98px) {\n  .offcanvas-md.offcanvas-end {\n    top: 0;\n    right: 0;\n    width: var(--bs-offcanvas-width);\n    border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(100%);\n  }\n}\n@media (max-width: 767.98px) {\n  .offcanvas-md.offcanvas-top {\n    top: 0;\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(-100%);\n  }\n}\n@media (max-width: 767.98px) {\n  .offcanvas-md.offcanvas-bottom {\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(100%);\n  }\n}\n@media (max-width: 767.98px) {\n  .offcanvas-md.showing, .offcanvas-md.show:not(.hiding) {\n    transform: none;\n  }\n}\n@media (max-width: 767.98px) {\n  .offcanvas-md.showing, .offcanvas-md.hiding, .offcanvas-md.show {\n    visibility: visible;\n  }\n}\n@media (min-width: 768px) {\n  .offcanvas-md {\n    --bs-offcanvas-height: auto;\n    --bs-offcanvas-border-width: 0;\n    background-color: transparent !important;\n  }\n  .offcanvas-md .offcanvas-header {\n    display: none;\n  }\n  .offcanvas-md .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n    background-color: transparent !important;\n  }\n}\n\n@media (max-width: 991.98px) {\n  .offcanvas-lg {\n    position: fixed;\n    bottom: 0;\n    z-index: var(--bs-offcanvas-zindex);\n    display: flex;\n    flex-direction: column;\n    max-width: 100%;\n    color: var(--bs-offcanvas-color);\n    visibility: hidden;\n    background-color: var(--bs-offcanvas-bg);\n    background-clip: padding-box;\n    outline: 0;\n    transition: transform 0.3s ease-in-out;\n  }\n}\n@media (max-width: 991.98px) and (prefers-reduced-motion: reduce) {\n  .offcanvas-lg {\n    transition: none;\n  }\n}\n@media (max-width: 991.98px) {\n  .offcanvas-lg.offcanvas-start {\n    top: 0;\n    left: 0;\n    width: var(--bs-offcanvas-width);\n    border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(-100%);\n  }\n}\n@media (max-width: 991.98px) {\n  .offcanvas-lg.offcanvas-end {\n    top: 0;\n    right: 0;\n    width: var(--bs-offcanvas-width);\n    border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(100%);\n  }\n}\n@media (max-width: 991.98px) {\n  .offcanvas-lg.offcanvas-top {\n    top: 0;\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(-100%);\n  }\n}\n@media (max-width: 991.98px) {\n  .offcanvas-lg.offcanvas-bottom {\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(100%);\n  }\n}\n@media (max-width: 991.98px) {\n  .offcanvas-lg.showing, .offcanvas-lg.show:not(.hiding) {\n    transform: none;\n  }\n}\n@media (max-width: 991.98px) {\n  .offcanvas-lg.showing, .offcanvas-lg.hiding, .offcanvas-lg.show {\n    visibility: visible;\n  }\n}\n@media (min-width: 992px) {\n  .offcanvas-lg {\n    --bs-offcanvas-height: auto;\n    --bs-offcanvas-border-width: 0;\n    background-color: transparent !important;\n  }\n  .offcanvas-lg .offcanvas-header {\n    display: none;\n  }\n  .offcanvas-lg .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n    background-color: transparent !important;\n  }\n}\n\n@media (max-width: 1199.98px) {\n  .offcanvas-xl {\n    position: fixed;\n    bottom: 0;\n    z-index: var(--bs-offcanvas-zindex);\n    display: flex;\n    flex-direction: column;\n    max-width: 100%;\n    color: var(--bs-offcanvas-color);\n    visibility: hidden;\n    background-color: var(--bs-offcanvas-bg);\n    background-clip: padding-box;\n    outline: 0;\n    transition: transform 0.3s ease-in-out;\n  }\n}\n@media (max-width: 1199.98px) and (prefers-reduced-motion: reduce) {\n  .offcanvas-xl {\n    transition: none;\n  }\n}\n@media (max-width: 1199.98px) {\n  .offcanvas-xl.offcanvas-start {\n    top: 0;\n    left: 0;\n    width: var(--bs-offcanvas-width);\n    border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(-100%);\n  }\n}\n@media (max-width: 1199.98px) {\n  .offcanvas-xl.offcanvas-end {\n    top: 0;\n    right: 0;\n    width: var(--bs-offcanvas-width);\n    border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(100%);\n  }\n}\n@media (max-width: 1199.98px) {\n  .offcanvas-xl.offcanvas-top {\n    top: 0;\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(-100%);\n  }\n}\n@media (max-width: 1199.98px) {\n  .offcanvas-xl.offcanvas-bottom {\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(100%);\n  }\n}\n@media (max-width: 1199.98px) {\n  .offcanvas-xl.showing, .offcanvas-xl.show:not(.hiding) {\n    transform: none;\n  }\n}\n@media (max-width: 1199.98px) {\n  .offcanvas-xl.showing, .offcanvas-xl.hiding, .offcanvas-xl.show {\n    visibility: visible;\n  }\n}\n@media (min-width: 1200px) {\n  .offcanvas-xl {\n    --bs-offcanvas-height: auto;\n    --bs-offcanvas-border-width: 0;\n    background-color: transparent !important;\n  }\n  .offcanvas-xl .offcanvas-header {\n    display: none;\n  }\n  .offcanvas-xl .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n    background-color: transparent !important;\n  }\n}\n\n@media (max-width: 1399.98px) {\n  .offcanvas-xxl {\n    position: fixed;\n    bottom: 0;\n    z-index: var(--bs-offcanvas-zindex);\n    display: flex;\n    flex-direction: column;\n    max-width: 100%;\n    color: var(--bs-offcanvas-color);\n    visibility: hidden;\n    background-color: var(--bs-offcanvas-bg);\n    background-clip: padding-box;\n    outline: 0;\n    transition: transform 0.3s ease-in-out;\n  }\n}\n@media (max-width: 1399.98px) and (prefers-reduced-motion: reduce) {\n  .offcanvas-xxl {\n    transition: none;\n  }\n}\n@media (max-width: 1399.98px) {\n  .offcanvas-xxl.offcanvas-start {\n    top: 0;\n    left: 0;\n    width: var(--bs-offcanvas-width);\n    border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(-100%);\n  }\n}\n@media (max-width: 1399.98px) {\n  .offcanvas-xxl.offcanvas-end {\n    top: 0;\n    right: 0;\n    width: var(--bs-offcanvas-width);\n    border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(100%);\n  }\n}\n@media (max-width: 1399.98px) {\n  .offcanvas-xxl.offcanvas-top {\n    top: 0;\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(-100%);\n  }\n}\n@media (max-width: 1399.98px) {\n  .offcanvas-xxl.offcanvas-bottom {\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(100%);\n  }\n}\n@media (max-width: 1399.98px) {\n  .offcanvas-xxl.showing, .offcanvas-xxl.show:not(.hiding) {\n    transform: none;\n  }\n}\n@media (max-width: 1399.98px) {\n  .offcanvas-xxl.showing, .offcanvas-xxl.hiding, .offcanvas-xxl.show {\n    visibility: visible;\n  }\n}\n@media (min-width: 1400px) {\n  .offcanvas-xxl {\n    --bs-offcanvas-height: auto;\n    --bs-offcanvas-border-width: 0;\n    background-color: transparent !important;\n  }\n  .offcanvas-xxl .offcanvas-header {\n    display: none;\n  }\n  .offcanvas-xxl .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n    background-color: transparent !important;\n  }\n}\n\n.offcanvas {\n  position: fixed;\n  bottom: 0;\n  z-index: var(--bs-offcanvas-zindex);\n  display: flex;\n  flex-direction: column;\n  max-width: 100%;\n  color: var(--bs-offcanvas-color);\n  visibility: hidden;\n  background-color: var(--bs-offcanvas-bg);\n  background-clip: padding-box;\n  outline: 0;\n  transition: transform 0.3s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .offcanvas {\n    transition: none;\n  }\n}\n.offcanvas.offcanvas-start {\n  top: 0;\n  left: 0;\n  width: var(--bs-offcanvas-width);\n  border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n  transform: translateX(-100%);\n}\n.offcanvas.offcanvas-end {\n  top: 0;\n  right: 0;\n  width: var(--bs-offcanvas-width);\n  border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n  transform: translateX(100%);\n}\n.offcanvas.offcanvas-top {\n  top: 0;\n  right: 0;\n  left: 0;\n  height: var(--bs-offcanvas-height);\n  max-height: 100%;\n  border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n  transform: translateY(-100%);\n}\n.offcanvas.offcanvas-bottom {\n  right: 0;\n  left: 0;\n  height: var(--bs-offcanvas-height);\n  max-height: 100%;\n  border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n  transform: translateY(100%);\n}\n.offcanvas.showing, .offcanvas.show:not(.hiding) {\n  transform: none;\n}\n.offcanvas.showing, .offcanvas.hiding, .offcanvas.show {\n  visibility: visible;\n}\n\n.offcanvas-backdrop {\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: 1040;\n  width: 100vw;\n  height: 100vh;\n  background-color: #000;\n}\n.offcanvas-backdrop.fade {\n  opacity: 0;\n}\n.offcanvas-backdrop.show {\n  opacity: 0.5;\n}\n\n.offcanvas-header {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);\n}\n.offcanvas-header .btn-close {\n  padding: calc(var(--bs-offcanvas-padding-y) * 0.5) calc(var(--bs-offcanvas-padding-x) * 0.5);\n  margin-top: calc(-0.5 * var(--bs-offcanvas-padding-y));\n  margin-right: calc(-0.5 * var(--bs-offcanvas-padding-x));\n  margin-bottom: calc(-0.5 * var(--bs-offcanvas-padding-y));\n}\n\n.offcanvas-title {\n  margin-bottom: 0;\n  line-height: 1.5;\n}\n\n.offcanvas-body {\n  flex-grow: 1;\n  padding: var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);\n  overflow-y: auto;\n}\n\n.placeholder {\n  display: inline-block;\n  min-height: 1em;\n  vertical-align: middle;\n  cursor: wait;\n  background-color: currentcolor;\n  opacity: 0.5;\n}\n.placeholder.btn::before {\n  display: inline-block;\n  content: \"\";\n}\n\n.placeholder-xs {\n  min-height: 0.6em;\n}\n\n.placeholder-sm {\n  min-height: 0.8em;\n}\n\n.placeholder-lg {\n  min-height: 1.2em;\n}\n\n.placeholder-glow .placeholder {\n  animation: placeholder-glow 2s ease-in-out infinite;\n}\n\n@keyframes placeholder-glow {\n  50% {\n    opacity: 0.2;\n  }\n}\n.placeholder-wave {\n  -webkit-mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);\n  mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);\n  -webkit-mask-size: 200% 100%;\n  mask-size: 200% 100%;\n  animation: placeholder-wave 2s linear infinite;\n}\n\n@keyframes placeholder-wave {\n  100% {\n    -webkit-mask-position: -200% 0%;\n    mask-position: -200% 0%;\n  }\n}\n.clearfix::after {\n  display: block;\n  clear: both;\n  content: \"\";\n}\n\n.text-bg-primary {\n  color: #fff !important;\n  background-color: RGBA(13, 110, 253, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-secondary {\n  color: #fff !important;\n  background-color: RGBA(108, 117, 125, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-success {\n  color: #fff !important;\n  background-color: RGBA(25, 135, 84, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-info {\n  color: #000 !important;\n  background-color: RGBA(13, 202, 240, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-warning {\n  color: #000 !important;\n  background-color: RGBA(255, 193, 7, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-danger {\n  color: #fff !important;\n  background-color: RGBA(220, 53, 69, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-light {\n  color: #000 !important;\n  background-color: RGBA(248, 249, 250, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-dark {\n  color: #fff !important;\n  background-color: RGBA(33, 37, 41, var(--bs-bg-opacity, 1)) !important;\n}\n\n.link-primary {\n  color: #0d6efd !important;\n}\n.link-primary:hover, .link-primary:focus {\n  color: #0a58ca !important;\n}\n\n.link-secondary {\n  color: #6c757d !important;\n}\n.link-secondary:hover, .link-secondary:focus {\n  color: #565e64 !important;\n}\n\n.link-success {\n  color: #198754 !important;\n}\n.link-success:hover, .link-success:focus {\n  color: #146c43 !important;\n}\n\n.link-info {\n  color: #0dcaf0 !important;\n}\n.link-info:hover, .link-info:focus {\n  color: #3dd5f3 !important;\n}\n\n.link-warning {\n  color: #ffc107 !important;\n}\n.link-warning:hover, .link-warning:focus {\n  color: #ffcd39 !important;\n}\n\n.link-danger {\n  color: #dc3545 !important;\n}\n.link-danger:hover, .link-danger:focus {\n  color: #b02a37 !important;\n}\n\n.link-light {\n  color: #f8f9fa !important;\n}\n.link-light:hover, .link-light:focus {\n  color: #f9fafb !important;\n}\n\n.link-dark {\n  color: #212529 !important;\n}\n.link-dark:hover, .link-dark:focus {\n  color: #1a1e21 !important;\n}\n\n.ratio {\n  position: relative;\n  width: 100%;\n}\n.ratio::before {\n  display: block;\n  padding-top: var(--bs-aspect-ratio);\n  content: \"\";\n}\n.ratio > * {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n}\n\n.ratio-1x1 {\n  --bs-aspect-ratio: 100%;\n}\n\n.ratio-4x3 {\n  --bs-aspect-ratio: 75%;\n}\n\n.ratio-16x9 {\n  --bs-aspect-ratio: 56.25%;\n}\n\n.ratio-21x9 {\n  --bs-aspect-ratio: 42.8571428571%;\n}\n\n.fixed-top {\n  position: fixed;\n  top: 0;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n}\n\n.fixed-bottom {\n  position: fixed;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1030;\n}\n\n.sticky-top {\n  position: -webkit-sticky;\n  position: sticky;\n  top: 0;\n  z-index: 1020;\n}\n\n.sticky-bottom {\n  position: -webkit-sticky;\n  position: sticky;\n  bottom: 0;\n  z-index: 1020;\n}\n\n@media (min-width: 576px) {\n  .sticky-sm-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n  .sticky-sm-bottom {\n    position: -webkit-sticky;\n    position: sticky;\n    bottom: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 768px) {\n  .sticky-md-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n  .sticky-md-bottom {\n    position: -webkit-sticky;\n    position: sticky;\n    bottom: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 992px) {\n  .sticky-lg-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n  .sticky-lg-bottom {\n    position: -webkit-sticky;\n    position: sticky;\n    bottom: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 1200px) {\n  .sticky-xl-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n  .sticky-xl-bottom {\n    position: -webkit-sticky;\n    position: sticky;\n    bottom: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 1400px) {\n  .sticky-xxl-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n  .sticky-xxl-bottom {\n    position: -webkit-sticky;\n    position: sticky;\n    bottom: 0;\n    z-index: 1020;\n  }\n}\n.hstack {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  align-self: stretch;\n}\n\n.vstack {\n  display: flex;\n  flex: 1 1 auto;\n  flex-direction: column;\n  align-self: stretch;\n}\n\n.visually-hidden,\n.visually-hidden-focusable:not(:focus):not(:focus-within) {\n  position: absolute !important;\n  width: 1px !important;\n  height: 1px !important;\n  padding: 0 !important;\n  margin: -1px !important;\n  overflow: hidden !important;\n  clip: rect(0, 0, 0, 0) !important;\n  white-space: nowrap !important;\n  border: 0 !important;\n}\n\n.stretched-link::after {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1;\n  content: \"\";\n}\n\n.text-truncate {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.vr {\n  display: inline-block;\n  align-self: stretch;\n  width: 1px;\n  min-height: 1em;\n  background-color: currentcolor;\n  opacity: 0.25;\n}\n\n.align-baseline {\n  vertical-align: baseline !important;\n}\n\n.align-top {\n  vertical-align: top !important;\n}\n\n.align-middle {\n  vertical-align: middle !important;\n}\n\n.align-bottom {\n  vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n  vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n  vertical-align: text-top !important;\n}\n\n.float-start {\n  float: left !important;\n}\n\n.float-end {\n  float: right !important;\n}\n\n.float-none {\n  float: none !important;\n}\n\n.opacity-0 {\n  opacity: 0 !important;\n}\n\n.opacity-25 {\n  opacity: 0.25 !important;\n}\n\n.opacity-50 {\n  opacity: 0.5 !important;\n}\n\n.opacity-75 {\n  opacity: 0.75 !important;\n}\n\n.opacity-100 {\n  opacity: 1 !important;\n}\n\n.overflow-auto {\n  overflow: auto !important;\n}\n\n.overflow-hidden {\n  overflow: hidden !important;\n}\n\n.overflow-visible {\n  overflow: visible !important;\n}\n\n.overflow-scroll {\n  overflow: scroll !important;\n}\n\n.d-inline {\n  display: inline !important;\n}\n\n.d-inline-block {\n  display: inline-block !important;\n}\n\n.d-block {\n  display: block !important;\n}\n\n.d-grid {\n  display: grid !important;\n}\n\n.d-table {\n  display: table !important;\n}\n\n.d-table-row {\n  display: table-row !important;\n}\n\n.d-table-cell {\n  display: table-cell !important;\n}\n\n.d-flex {\n  display: flex !important;\n}\n\n.d-inline-flex {\n  display: inline-flex !important;\n}\n\n.d-none {\n  display: none !important;\n}\n\n.shadow {\n  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\n}\n\n.shadow-sm {\n  box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\n}\n\n.shadow-lg {\n  box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;\n}\n\n.shadow-none {\n  box-shadow: none !important;\n}\n\n.position-static {\n  position: static !important;\n}\n\n.position-relative {\n  position: relative !important;\n}\n\n.position-absolute {\n  position: absolute !important;\n}\n\n.position-fixed {\n  position: fixed !important;\n}\n\n.position-sticky {\n  position: -webkit-sticky !important;\n  position: sticky !important;\n}\n\n.top-0 {\n  top: 0 !important;\n}\n\n.top-50 {\n  top: 50% !important;\n}\n\n.top-100 {\n  top: 100% !important;\n}\n\n.bottom-0 {\n  bottom: 0 !important;\n}\n\n.bottom-50 {\n  bottom: 50% !important;\n}\n\n.bottom-100 {\n  bottom: 100% !important;\n}\n\n.start-0 {\n  left: 0 !important;\n}\n\n.start-50 {\n  left: 50% !important;\n}\n\n.start-100 {\n  left: 100% !important;\n}\n\n.end-0 {\n  right: 0 !important;\n}\n\n.end-50 {\n  right: 50% !important;\n}\n\n.end-100 {\n  right: 100% !important;\n}\n\n.translate-middle {\n  transform: translate(-50%, -50%) !important;\n}\n\n.translate-middle-x {\n  transform: translateX(-50%) !important;\n}\n\n.translate-middle-y {\n  transform: translateY(-50%) !important;\n}\n\n.border {\n  border: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;\n}\n\n.border-0 {\n  border: 0 !important;\n}\n\n.border-top {\n  border-top: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;\n}\n\n.border-top-0 {\n  border-top: 0 !important;\n}\n\n.border-end {\n  border-right: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;\n}\n\n.border-end-0 {\n  border-right: 0 !important;\n}\n\n.border-bottom {\n  border-bottom: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;\n}\n\n.border-bottom-0 {\n  border-bottom: 0 !important;\n}\n\n.border-start {\n  border-left: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;\n}\n\n.border-start-0 {\n  border-left: 0 !important;\n}\n\n.border-primary {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-primary-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-secondary {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-secondary-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-success {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-success-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-info {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-info-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-warning {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-warning-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-danger {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-danger-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-light {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-light-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-dark {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-dark-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-white {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-white-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-1 {\n  --bs-border-width: 1px;\n}\n\n.border-2 {\n  --bs-border-width: 2px;\n}\n\n.border-3 {\n  --bs-border-width: 3px;\n}\n\n.border-4 {\n  --bs-border-width: 4px;\n}\n\n.border-5 {\n  --bs-border-width: 5px;\n}\n\n.border-opacity-10 {\n  --bs-border-opacity: 0.1;\n}\n\n.border-opacity-25 {\n  --bs-border-opacity: 0.25;\n}\n\n.border-opacity-50 {\n  --bs-border-opacity: 0.5;\n}\n\n.border-opacity-75 {\n  --bs-border-opacity: 0.75;\n}\n\n.border-opacity-100 {\n  --bs-border-opacity: 1;\n}\n\n.w-25 {\n  width: 25% !important;\n}\n\n.w-50 {\n  width: 50% !important;\n}\n\n.w-75 {\n  width: 75% !important;\n}\n\n.w-100 {\n  width: 100% !important;\n}\n\n.w-auto {\n  width: auto !important;\n}\n\n.mw-100 {\n  max-width: 100% !important;\n}\n\n.vw-100 {\n  width: 100vw !important;\n}\n\n.min-vw-100 {\n  min-width: 100vw !important;\n}\n\n.h-25 {\n  height: 25% !important;\n}\n\n.h-50 {\n  height: 50% !important;\n}\n\n.h-75 {\n  height: 75% !important;\n}\n\n.h-100 {\n  height: 100% !important;\n}\n\n.h-auto {\n  height: auto !important;\n}\n\n.mh-100 {\n  max-height: 100% !important;\n}\n\n.vh-100 {\n  height: 100vh !important;\n}\n\n.min-vh-100 {\n  min-height: 100vh !important;\n}\n\n.flex-fill {\n  flex: 1 1 auto !important;\n}\n\n.flex-row {\n  flex-direction: row !important;\n}\n\n.flex-column {\n  flex-direction: column !important;\n}\n\n.flex-row-reverse {\n  flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n  flex-direction: column-reverse !important;\n}\n\n.flex-grow-0 {\n  flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n  flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n  flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n  flex-shrink: 1 !important;\n}\n\n.flex-wrap {\n  flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n  flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n  flex-wrap: wrap-reverse !important;\n}\n\n.justify-content-start {\n  justify-content: flex-start !important;\n}\n\n.justify-content-end {\n  justify-content: flex-end !important;\n}\n\n.justify-content-center {\n  justify-content: center !important;\n}\n\n.justify-content-between {\n  justify-content: space-between !important;\n}\n\n.justify-content-around {\n  justify-content: space-around !important;\n}\n\n.justify-content-evenly {\n  justify-content: space-evenly !important;\n}\n\n.align-items-start {\n  align-items: flex-start !important;\n}\n\n.align-items-end {\n  align-items: flex-end !important;\n}\n\n.align-items-center {\n  align-items: center !important;\n}\n\n.align-items-baseline {\n  align-items: baseline !important;\n}\n\n.align-items-stretch {\n  align-items: stretch !important;\n}\n\n.align-content-start {\n  align-content: flex-start !important;\n}\n\n.align-content-end {\n  align-content: flex-end !important;\n}\n\n.align-content-center {\n  align-content: center !important;\n}\n\n.align-content-between {\n  align-content: space-between !important;\n}\n\n.align-content-around {\n  align-content: space-around !important;\n}\n\n.align-content-stretch {\n  align-content: stretch !important;\n}\n\n.align-self-auto {\n  align-self: auto !important;\n}\n\n.align-self-start {\n  align-self: flex-start !important;\n}\n\n.align-self-end {\n  align-self: flex-end !important;\n}\n\n.align-self-center {\n  align-self: center !important;\n}\n\n.align-self-baseline {\n  align-self: baseline !important;\n}\n\n.align-self-stretch {\n  align-self: stretch !important;\n}\n\n.order-first {\n  order: -1 !important;\n}\n\n.order-0 {\n  order: 0 !important;\n}\n\n.order-1 {\n  order: 1 !important;\n}\n\n.order-2 {\n  order: 2 !important;\n}\n\n.order-3 {\n  order: 3 !important;\n}\n\n.order-4 {\n  order: 4 !important;\n}\n\n.order-5 {\n  order: 5 !important;\n}\n\n.order-last {\n  order: 6 !important;\n}\n\n.m-0 {\n  margin: 0 !important;\n}\n\n.m-1 {\n  margin: 0.25rem !important;\n}\n\n.m-2 {\n  margin: 0.5rem !important;\n}\n\n.m-3 {\n  margin: 1rem !important;\n}\n\n.m-4 {\n  margin: 1.5rem !important;\n}\n\n.m-5 {\n  margin: 3rem !important;\n}\n\n.m-auto {\n  margin: auto !important;\n}\n\n.mx-0 {\n  margin-right: 0 !important;\n  margin-left: 0 !important;\n}\n\n.mx-1 {\n  margin-right: 0.25rem !important;\n  margin-left: 0.25rem !important;\n}\n\n.mx-2 {\n  margin-right: 0.5rem !important;\n  margin-left: 0.5rem !important;\n}\n\n.mx-3 {\n  margin-right: 1rem !important;\n  margin-left: 1rem !important;\n}\n\n.mx-4 {\n  margin-right: 1.5rem !important;\n  margin-left: 1.5rem !important;\n}\n\n.mx-5 {\n  margin-right: 3rem !important;\n  margin-left: 3rem !important;\n}\n\n.mx-auto {\n  margin-right: auto !important;\n  margin-left: auto !important;\n}\n\n.my-0 {\n  margin-top: 0 !important;\n  margin-bottom: 0 !important;\n}\n\n.my-1 {\n  margin-top: 0.25rem !important;\n  margin-bottom: 0.25rem !important;\n}\n\n.my-2 {\n  margin-top: 0.5rem !important;\n  margin-bottom: 0.5rem !important;\n}\n\n.my-3 {\n  margin-top: 1rem !important;\n  margin-bottom: 1rem !important;\n}\n\n.my-4 {\n  margin-top: 1.5rem !important;\n  margin-bottom: 1.5rem !important;\n}\n\n.my-5 {\n  margin-top: 3rem !important;\n  margin-bottom: 3rem !important;\n}\n\n.my-auto {\n  margin-top: auto !important;\n  margin-bottom: auto !important;\n}\n\n.mt-0 {\n  margin-top: 0 !important;\n}\n\n.mt-1 {\n  margin-top: 0.25rem !important;\n}\n\n.mt-2 {\n  margin-top: 0.5rem !important;\n}\n\n.mt-3 {\n  margin-top: 1rem !important;\n}\n\n.mt-4 {\n  margin-top: 1.5rem !important;\n}\n\n.mt-5 {\n  margin-top: 3rem !important;\n}\n\n.mt-auto {\n  margin-top: auto !important;\n}\n\n.me-0 {\n  margin-right: 0 !important;\n}\n\n.me-1 {\n  margin-right: 0.25rem !important;\n}\n\n.me-2 {\n  margin-right: 0.5rem !important;\n}\n\n.me-3 {\n  margin-right: 1rem !important;\n}\n\n.me-4 {\n  margin-right: 1.5rem !important;\n}\n\n.me-5 {\n  margin-right: 3rem !important;\n}\n\n.me-auto {\n  margin-right: auto !important;\n}\n\n.mb-0 {\n  margin-bottom: 0 !important;\n}\n\n.mb-1 {\n  margin-bottom: 0.25rem !important;\n}\n\n.mb-2 {\n  margin-bottom: 0.5rem !important;\n}\n\n.mb-3 {\n  margin-bottom: 1rem !important;\n}\n\n.mb-4 {\n  margin-bottom: 1.5rem !important;\n}\n\n.mb-5 {\n  margin-bottom: 3rem !important;\n}\n\n.mb-auto {\n  margin-bottom: auto !important;\n}\n\n.ms-0 {\n  margin-left: 0 !important;\n}\n\n.ms-1 {\n  margin-left: 0.25rem !important;\n}\n\n.ms-2 {\n  margin-left: 0.5rem !important;\n}\n\n.ms-3 {\n  margin-left: 1rem !important;\n}\n\n.ms-4 {\n  margin-left: 1.5rem !important;\n}\n\n.ms-5 {\n  margin-left: 3rem !important;\n}\n\n.ms-auto {\n  margin-left: auto !important;\n}\n\n.p-0 {\n  padding: 0 !important;\n}\n\n.p-1 {\n  padding: 0.25rem !important;\n}\n\n.p-2 {\n  padding: 0.5rem !important;\n}\n\n.p-3 {\n  padding: 1rem !important;\n}\n\n.p-4 {\n  padding: 1.5rem !important;\n}\n\n.p-5 {\n  padding: 3rem !important;\n}\n\n.px-0 {\n  padding-right: 0 !important;\n  padding-left: 0 !important;\n}\n\n.px-1 {\n  padding-right: 0.25rem !important;\n  padding-left: 0.25rem !important;\n}\n\n.px-2 {\n  padding-right: 0.5rem !important;\n  padding-left: 0.5rem !important;\n}\n\n.px-3 {\n  padding-right: 1rem !important;\n  padding-left: 1rem !important;\n}\n\n.px-4 {\n  padding-right: 1.5rem !important;\n  padding-left: 1.5rem !important;\n}\n\n.px-5 {\n  padding-right: 3rem !important;\n  padding-left: 3rem !important;\n}\n\n.py-0 {\n  padding-top: 0 !important;\n  padding-bottom: 0 !important;\n}\n\n.py-1 {\n  padding-top: 0.25rem !important;\n  padding-bottom: 0.25rem !important;\n}\n\n.py-2 {\n  padding-top: 0.5rem !important;\n  padding-bottom: 0.5rem !important;\n}\n\n.py-3 {\n  padding-top: 1rem !important;\n  padding-bottom: 1rem !important;\n}\n\n.py-4 {\n  padding-top: 1.5rem !important;\n  padding-bottom: 1.5rem !important;\n}\n\n.py-5 {\n  padding-top: 3rem !important;\n  padding-bottom: 3rem !important;\n}\n\n.pt-0 {\n  padding-top: 0 !important;\n}\n\n.pt-1 {\n  padding-top: 0.25rem !important;\n}\n\n.pt-2 {\n  padding-top: 0.5rem !important;\n}\n\n.pt-3 {\n  padding-top: 1rem !important;\n}\n\n.pt-4 {\n  padding-top: 1.5rem !important;\n}\n\n.pt-5 {\n  padding-top: 3rem !important;\n}\n\n.pe-0 {\n  padding-right: 0 !important;\n}\n\n.pe-1 {\n  padding-right: 0.25rem !important;\n}\n\n.pe-2 {\n  padding-right: 0.5rem !important;\n}\n\n.pe-3 {\n  padding-right: 1rem !important;\n}\n\n.pe-4 {\n  padding-right: 1.5rem !important;\n}\n\n.pe-5 {\n  padding-right: 3rem !important;\n}\n\n.pb-0 {\n  padding-bottom: 0 !important;\n}\n\n.pb-1 {\n  padding-bottom: 0.25rem !important;\n}\n\n.pb-2 {\n  padding-bottom: 0.5rem !important;\n}\n\n.pb-3 {\n  padding-bottom: 1rem !important;\n}\n\n.pb-4 {\n  padding-bottom: 1.5rem !important;\n}\n\n.pb-5 {\n  padding-bottom: 3rem !important;\n}\n\n.ps-0 {\n  padding-left: 0 !important;\n}\n\n.ps-1 {\n  padding-left: 0.25rem !important;\n}\n\n.ps-2 {\n  padding-left: 0.5rem !important;\n}\n\n.ps-3 {\n  padding-left: 1rem !important;\n}\n\n.ps-4 {\n  padding-left: 1.5rem !important;\n}\n\n.ps-5 {\n  padding-left: 3rem !important;\n}\n\n.gap-0 {\n  gap: 0 !important;\n}\n\n.gap-1 {\n  gap: 0.25rem !important;\n}\n\n.gap-2 {\n  gap: 0.5rem !important;\n}\n\n.gap-3 {\n  gap: 1rem !important;\n}\n\n.gap-4 {\n  gap: 1.5rem !important;\n}\n\n.gap-5 {\n  gap: 3rem !important;\n}\n\n.font-monospace {\n  font-family: var(--bs-font-monospace) !important;\n}\n\n.fs-1 {\n  font-size: calc(1.375rem + 1.5vw) !important;\n}\n\n.fs-2 {\n  font-size: calc(1.325rem + 0.9vw) !important;\n}\n\n.fs-3 {\n  font-size: calc(1.3rem + 0.6vw) !important;\n}\n\n.fs-4 {\n  font-size: calc(1.275rem + 0.3vw) !important;\n}\n\n.fs-5 {\n  font-size: 1.25rem !important;\n}\n\n.fs-6 {\n  font-size: 1rem !important;\n}\n\n.fst-italic {\n  font-style: italic !important;\n}\n\n.fst-normal {\n  font-style: normal !important;\n}\n\n.fw-light {\n  font-weight: 300 !important;\n}\n\n.fw-lighter {\n  font-weight: lighter !important;\n}\n\n.fw-normal {\n  font-weight: 400 !important;\n}\n\n.fw-bold {\n  font-weight: 700 !important;\n}\n\n.fw-semibold {\n  font-weight: 600 !important;\n}\n\n.fw-bolder {\n  font-weight: bolder !important;\n}\n\n.lh-1 {\n  line-height: 1 !important;\n}\n\n.lh-sm {\n  line-height: 1.25 !important;\n}\n\n.lh-base {\n  line-height: 1.5 !important;\n}\n\n.lh-lg {\n  line-height: 2 !important;\n}\n\n.text-start {\n  text-align: left !important;\n}\n\n.text-end {\n  text-align: right !important;\n}\n\n.text-center {\n  text-align: center !important;\n}\n\n.text-decoration-none {\n  text-decoration: none !important;\n}\n\n.text-decoration-underline {\n  text-decoration: underline !important;\n}\n\n.text-decoration-line-through {\n  text-decoration: line-through !important;\n}\n\n.text-lowercase {\n  text-transform: lowercase !important;\n}\n\n.text-uppercase {\n  text-transform: uppercase !important;\n}\n\n.text-capitalize {\n  text-transform: capitalize !important;\n}\n\n.text-wrap {\n  white-space: normal !important;\n}\n\n.text-nowrap {\n  white-space: nowrap !important;\n}\n\n/* rtl:begin:remove */\n.text-break {\n  word-wrap: break-word !important;\n  word-break: break-word !important;\n}\n\n/* rtl:end:remove */\n.text-primary {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-secondary {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-success {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-info {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-warning {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-danger {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-light {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-dark {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-black {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-white {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-body {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-muted {\n  --bs-text-opacity: 1;\n  color: #6c757d !important;\n}\n\n.text-black-50 {\n  --bs-text-opacity: 1;\n  color: rgba(0, 0, 0, 0.5) !important;\n}\n\n.text-white-50 {\n  --bs-text-opacity: 1;\n  color: rgba(255, 255, 255, 0.5) !important;\n}\n\n.text-reset {\n  --bs-text-opacity: 1;\n  color: inherit !important;\n}\n\n.text-opacity-25 {\n  --bs-text-opacity: 0.25;\n}\n\n.text-opacity-50 {\n  --bs-text-opacity: 0.5;\n}\n\n.text-opacity-75 {\n  --bs-text-opacity: 0.75;\n}\n\n.text-opacity-100 {\n  --bs-text-opacity: 1;\n}\n\n.bg-primary {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-secondary {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-success {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-info {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-warning {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-danger {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-light {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-dark {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-black {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-white {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-body {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-transparent {\n  --bs-bg-opacity: 1;\n  background-color: transparent !important;\n}\n\n.bg-opacity-10 {\n  --bs-bg-opacity: 0.1;\n}\n\n.bg-opacity-25 {\n  --bs-bg-opacity: 0.25;\n}\n\n.bg-opacity-50 {\n  --bs-bg-opacity: 0.5;\n}\n\n.bg-opacity-75 {\n  --bs-bg-opacity: 0.75;\n}\n\n.bg-opacity-100 {\n  --bs-bg-opacity: 1;\n}\n\n.bg-gradient {\n  background-image: var(--bs-gradient) !important;\n}\n\n.user-select-all {\n  -webkit-user-select: all !important;\n  -moz-user-select: all !important;\n  user-select: all !important;\n}\n\n.user-select-auto {\n  -webkit-user-select: auto !important;\n  -moz-user-select: auto !important;\n  user-select: auto !important;\n}\n\n.user-select-none {\n  -webkit-user-select: none !important;\n  -moz-user-select: none !important;\n  user-select: none !important;\n}\n\n.pe-none {\n  pointer-events: none !important;\n}\n\n.pe-auto {\n  pointer-events: auto !important;\n}\n\n.rounded {\n  border-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-0 {\n  border-radius: 0 !important;\n}\n\n.rounded-1 {\n  border-radius: var(--bs-border-radius-sm) !important;\n}\n\n.rounded-2 {\n  border-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-3 {\n  border-radius: var(--bs-border-radius-lg) !important;\n}\n\n.rounded-4 {\n  border-radius: var(--bs-border-radius-xl) !important;\n}\n\n.rounded-5 {\n  border-radius: var(--bs-border-radius-2xl) !important;\n}\n\n.rounded-circle {\n  border-radius: 50% !important;\n}\n\n.rounded-pill {\n  border-radius: var(--bs-border-radius-pill) !important;\n}\n\n.rounded-top {\n  border-top-left-radius: var(--bs-border-radius) !important;\n  border-top-right-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-end {\n  border-top-right-radius: var(--bs-border-radius) !important;\n  border-bottom-right-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-bottom {\n  border-bottom-right-radius: var(--bs-border-radius) !important;\n  border-bottom-left-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-start {\n  border-bottom-left-radius: var(--bs-border-radius) !important;\n  border-top-left-radius: var(--bs-border-radius) !important;\n}\n\n.visible {\n  visibility: visible !important;\n}\n\n.invisible {\n  visibility: hidden !important;\n}\n\n@media (min-width: 576px) {\n  .float-sm-start {\n    float: left !important;\n  }\n  .float-sm-end {\n    float: right !important;\n  }\n  .float-sm-none {\n    float: none !important;\n  }\n  .d-sm-inline {\n    display: inline !important;\n  }\n  .d-sm-inline-block {\n    display: inline-block !important;\n  }\n  .d-sm-block {\n    display: block !important;\n  }\n  .d-sm-grid {\n    display: grid !important;\n  }\n  .d-sm-table {\n    display: table !important;\n  }\n  .d-sm-table-row {\n    display: table-row !important;\n  }\n  .d-sm-table-cell {\n    display: table-cell !important;\n  }\n  .d-sm-flex {\n    display: flex !important;\n  }\n  .d-sm-inline-flex {\n    display: inline-flex !important;\n  }\n  .d-sm-none {\n    display: none !important;\n  }\n  .flex-sm-fill {\n    flex: 1 1 auto !important;\n  }\n  .flex-sm-row {\n    flex-direction: row !important;\n  }\n  .flex-sm-column {\n    flex-direction: column !important;\n  }\n  .flex-sm-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n  .flex-sm-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n  .flex-sm-grow-0 {\n    flex-grow: 0 !important;\n  }\n  .flex-sm-grow-1 {\n    flex-grow: 1 !important;\n  }\n  .flex-sm-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n  .flex-sm-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n  .flex-sm-wrap {\n    flex-wrap: wrap !important;\n  }\n  .flex-sm-nowrap {\n    flex-wrap: nowrap !important;\n  }\n  .flex-sm-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n  .justify-content-sm-start {\n    justify-content: flex-start !important;\n  }\n  .justify-content-sm-end {\n    justify-content: flex-end !important;\n  }\n  .justify-content-sm-center {\n    justify-content: center !important;\n  }\n  .justify-content-sm-between {\n    justify-content: space-between !important;\n  }\n  .justify-content-sm-around {\n    justify-content: space-around !important;\n  }\n  .justify-content-sm-evenly {\n    justify-content: space-evenly !important;\n  }\n  .align-items-sm-start {\n    align-items: flex-start !important;\n  }\n  .align-items-sm-end {\n    align-items: flex-end !important;\n  }\n  .align-items-sm-center {\n    align-items: center !important;\n  }\n  .align-items-sm-baseline {\n    align-items: baseline !important;\n  }\n  .align-items-sm-stretch {\n    align-items: stretch !important;\n  }\n  .align-content-sm-start {\n    align-content: flex-start !important;\n  }\n  .align-content-sm-end {\n    align-content: flex-end !important;\n  }\n  .align-content-sm-center {\n    align-content: center !important;\n  }\n  .align-content-sm-between {\n    align-content: space-between !important;\n  }\n  .align-content-sm-around {\n    align-content: space-around !important;\n  }\n  .align-content-sm-stretch {\n    align-content: stretch !important;\n  }\n  .align-self-sm-auto {\n    align-self: auto !important;\n  }\n  .align-self-sm-start {\n    align-self: flex-start !important;\n  }\n  .align-self-sm-end {\n    align-self: flex-end !important;\n  }\n  .align-self-sm-center {\n    align-self: center !important;\n  }\n  .align-self-sm-baseline {\n    align-self: baseline !important;\n  }\n  .align-self-sm-stretch {\n    align-self: stretch !important;\n  }\n  .order-sm-first {\n    order: -1 !important;\n  }\n  .order-sm-0 {\n    order: 0 !important;\n  }\n  .order-sm-1 {\n    order: 1 !important;\n  }\n  .order-sm-2 {\n    order: 2 !important;\n  }\n  .order-sm-3 {\n    order: 3 !important;\n  }\n  .order-sm-4 {\n    order: 4 !important;\n  }\n  .order-sm-5 {\n    order: 5 !important;\n  }\n  .order-sm-last {\n    order: 6 !important;\n  }\n  .m-sm-0 {\n    margin: 0 !important;\n  }\n  .m-sm-1 {\n    margin: 0.25rem !important;\n  }\n  .m-sm-2 {\n    margin: 0.5rem !important;\n  }\n  .m-sm-3 {\n    margin: 1rem !important;\n  }\n  .m-sm-4 {\n    margin: 1.5rem !important;\n  }\n  .m-sm-5 {\n    margin: 3rem !important;\n  }\n  .m-sm-auto {\n    margin: auto !important;\n  }\n  .mx-sm-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n  .mx-sm-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n  .mx-sm-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n  .mx-sm-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n  .mx-sm-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n  .mx-sm-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n  .mx-sm-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n  .my-sm-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n  .my-sm-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n  .my-sm-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n  .my-sm-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n  .my-sm-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n  .my-sm-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n  .my-sm-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n  .mt-sm-0 {\n    margin-top: 0 !important;\n  }\n  .mt-sm-1 {\n    margin-top: 0.25rem !important;\n  }\n  .mt-sm-2 {\n    margin-top: 0.5rem !important;\n  }\n  .mt-sm-3 {\n    margin-top: 1rem !important;\n  }\n  .mt-sm-4 {\n    margin-top: 1.5rem !important;\n  }\n  .mt-sm-5 {\n    margin-top: 3rem !important;\n  }\n  .mt-sm-auto {\n    margin-top: auto !important;\n  }\n  .me-sm-0 {\n    margin-right: 0 !important;\n  }\n  .me-sm-1 {\n    margin-right: 0.25rem !important;\n  }\n  .me-sm-2 {\n    margin-right: 0.5rem !important;\n  }\n  .me-sm-3 {\n    margin-right: 1rem !important;\n  }\n  .me-sm-4 {\n    margin-right: 1.5rem !important;\n  }\n  .me-sm-5 {\n    margin-right: 3rem !important;\n  }\n  .me-sm-auto {\n    margin-right: auto !important;\n  }\n  .mb-sm-0 {\n    margin-bottom: 0 !important;\n  }\n  .mb-sm-1 {\n    margin-bottom: 0.25rem !important;\n  }\n  .mb-sm-2 {\n    margin-bottom: 0.5rem !important;\n  }\n  .mb-sm-3 {\n    margin-bottom: 1rem !important;\n  }\n  .mb-sm-4 {\n    margin-bottom: 1.5rem !important;\n  }\n  .mb-sm-5 {\n    margin-bottom: 3rem !important;\n  }\n  .mb-sm-auto {\n    margin-bottom: auto !important;\n  }\n  .ms-sm-0 {\n    margin-left: 0 !important;\n  }\n  .ms-sm-1 {\n    margin-left: 0.25rem !important;\n  }\n  .ms-sm-2 {\n    margin-left: 0.5rem !important;\n  }\n  .ms-sm-3 {\n    margin-left: 1rem !important;\n  }\n  .ms-sm-4 {\n    margin-left: 1.5rem !important;\n  }\n  .ms-sm-5 {\n    margin-left: 3rem !important;\n  }\n  .ms-sm-auto {\n    margin-left: auto !important;\n  }\n  .p-sm-0 {\n    padding: 0 !important;\n  }\n  .p-sm-1 {\n    padding: 0.25rem !important;\n  }\n  .p-sm-2 {\n    padding: 0.5rem !important;\n  }\n  .p-sm-3 {\n    padding: 1rem !important;\n  }\n  .p-sm-4 {\n    padding: 1.5rem !important;\n  }\n  .p-sm-5 {\n    padding: 3rem !important;\n  }\n  .px-sm-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n  .px-sm-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n  .px-sm-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n  .px-sm-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n  .px-sm-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n  .px-sm-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n  .py-sm-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n  .py-sm-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n  .py-sm-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n  .py-sm-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n  .py-sm-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n  .py-sm-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n  .pt-sm-0 {\n    padding-top: 0 !important;\n  }\n  .pt-sm-1 {\n    padding-top: 0.25rem !important;\n  }\n  .pt-sm-2 {\n    padding-top: 0.5rem !important;\n  }\n  .pt-sm-3 {\n    padding-top: 1rem !important;\n  }\n  .pt-sm-4 {\n    padding-top: 1.5rem !important;\n  }\n  .pt-sm-5 {\n    padding-top: 3rem !important;\n  }\n  .pe-sm-0 {\n    padding-right: 0 !important;\n  }\n  .pe-sm-1 {\n    padding-right: 0.25rem !important;\n  }\n  .pe-sm-2 {\n    padding-right: 0.5rem !important;\n  }\n  .pe-sm-3 {\n    padding-right: 1rem !important;\n  }\n  .pe-sm-4 {\n    padding-right: 1.5rem !important;\n  }\n  .pe-sm-5 {\n    padding-right: 3rem !important;\n  }\n  .pb-sm-0 {\n    padding-bottom: 0 !important;\n  }\n  .pb-sm-1 {\n    padding-bottom: 0.25rem !important;\n  }\n  .pb-sm-2 {\n    padding-bottom: 0.5rem !important;\n  }\n  .pb-sm-3 {\n    padding-bottom: 1rem !important;\n  }\n  .pb-sm-4 {\n    padding-bottom: 1.5rem !important;\n  }\n  .pb-sm-5 {\n    padding-bottom: 3rem !important;\n  }\n  .ps-sm-0 {\n    padding-left: 0 !important;\n  }\n  .ps-sm-1 {\n    padding-left: 0.25rem !important;\n  }\n  .ps-sm-2 {\n    padding-left: 0.5rem !important;\n  }\n  .ps-sm-3 {\n    padding-left: 1rem !important;\n  }\n  .ps-sm-4 {\n    padding-left: 1.5rem !important;\n  }\n  .ps-sm-5 {\n    padding-left: 3rem !important;\n  }\n  .gap-sm-0 {\n    gap: 0 !important;\n  }\n  .gap-sm-1 {\n    gap: 0.25rem !important;\n  }\n  .gap-sm-2 {\n    gap: 0.5rem !important;\n  }\n  .gap-sm-3 {\n    gap: 1rem !important;\n  }\n  .gap-sm-4 {\n    gap: 1.5rem !important;\n  }\n  .gap-sm-5 {\n    gap: 3rem !important;\n  }\n  .text-sm-start {\n    text-align: left !important;\n  }\n  .text-sm-end {\n    text-align: right !important;\n  }\n  .text-sm-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 768px) {\n  .float-md-start {\n    float: left !important;\n  }\n  .float-md-end {\n    float: right !important;\n  }\n  .float-md-none {\n    float: none !important;\n  }\n  .d-md-inline {\n    display: inline !important;\n  }\n  .d-md-inline-block {\n    display: inline-block !important;\n  }\n  .d-md-block {\n    display: block !important;\n  }\n  .d-md-grid {\n    display: grid !important;\n  }\n  .d-md-table {\n    display: table !important;\n  }\n  .d-md-table-row {\n    display: table-row !important;\n  }\n  .d-md-table-cell {\n    display: table-cell !important;\n  }\n  .d-md-flex {\n    display: flex !important;\n  }\n  .d-md-inline-flex {\n    display: inline-flex !important;\n  }\n  .d-md-none {\n    display: none !important;\n  }\n  .flex-md-fill {\n    flex: 1 1 auto !important;\n  }\n  .flex-md-row {\n    flex-direction: row !important;\n  }\n  .flex-md-column {\n    flex-direction: column !important;\n  }\n  .flex-md-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n  .flex-md-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n  .flex-md-grow-0 {\n    flex-grow: 0 !important;\n  }\n  .flex-md-grow-1 {\n    flex-grow: 1 !important;\n  }\n  .flex-md-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n  .flex-md-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n  .flex-md-wrap {\n    flex-wrap: wrap !important;\n  }\n  .flex-md-nowrap {\n    flex-wrap: nowrap !important;\n  }\n  .flex-md-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n  .justify-content-md-start {\n    justify-content: flex-start !important;\n  }\n  .justify-content-md-end {\n    justify-content: flex-end !important;\n  }\n  .justify-content-md-center {\n    justify-content: center !important;\n  }\n  .justify-content-md-between {\n    justify-content: space-between !important;\n  }\n  .justify-content-md-around {\n    justify-content: space-around !important;\n  }\n  .justify-content-md-evenly {\n    justify-content: space-evenly !important;\n  }\n  .align-items-md-start {\n    align-items: flex-start !important;\n  }\n  .align-items-md-end {\n    align-items: flex-end !important;\n  }\n  .align-items-md-center {\n    align-items: center !important;\n  }\n  .align-items-md-baseline {\n    align-items: baseline !important;\n  }\n  .align-items-md-stretch {\n    align-items: stretch !important;\n  }\n  .align-content-md-start {\n    align-content: flex-start !important;\n  }\n  .align-content-md-end {\n    align-content: flex-end !important;\n  }\n  .align-content-md-center {\n    align-content: center !important;\n  }\n  .align-content-md-between {\n    align-content: space-between !important;\n  }\n  .align-content-md-around {\n    align-content: space-around !important;\n  }\n  .align-content-md-stretch {\n    align-content: stretch !important;\n  }\n  .align-self-md-auto {\n    align-self: auto !important;\n  }\n  .align-self-md-start {\n    align-self: flex-start !important;\n  }\n  .align-self-md-end {\n    align-self: flex-end !important;\n  }\n  .align-self-md-center {\n    align-self: center !important;\n  }\n  .align-self-md-baseline {\n    align-self: baseline !important;\n  }\n  .align-self-md-stretch {\n    align-self: stretch !important;\n  }\n  .order-md-first {\n    order: -1 !important;\n  }\n  .order-md-0 {\n    order: 0 !important;\n  }\n  .order-md-1 {\n    order: 1 !important;\n  }\n  .order-md-2 {\n    order: 2 !important;\n  }\n  .order-md-3 {\n    order: 3 !important;\n  }\n  .order-md-4 {\n    order: 4 !important;\n  }\n  .order-md-5 {\n    order: 5 !important;\n  }\n  .order-md-last {\n    order: 6 !important;\n  }\n  .m-md-0 {\n    margin: 0 !important;\n  }\n  .m-md-1 {\n    margin: 0.25rem !important;\n  }\n  .m-md-2 {\n    margin: 0.5rem !important;\n  }\n  .m-md-3 {\n    margin: 1rem !important;\n  }\n  .m-md-4 {\n    margin: 1.5rem !important;\n  }\n  .m-md-5 {\n    margin: 3rem !important;\n  }\n  .m-md-auto {\n    margin: auto !important;\n  }\n  .mx-md-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n  .mx-md-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n  .mx-md-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n  .mx-md-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n  .mx-md-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n  .mx-md-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n  .mx-md-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n  .my-md-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n  .my-md-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n  .my-md-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n  .my-md-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n  .my-md-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n  .my-md-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n  .my-md-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n  .mt-md-0 {\n    margin-top: 0 !important;\n  }\n  .mt-md-1 {\n    margin-top: 0.25rem !important;\n  }\n  .mt-md-2 {\n    margin-top: 0.5rem !important;\n  }\n  .mt-md-3 {\n    margin-top: 1rem !important;\n  }\n  .mt-md-4 {\n    margin-top: 1.5rem !important;\n  }\n  .mt-md-5 {\n    margin-top: 3rem !important;\n  }\n  .mt-md-auto {\n    margin-top: auto !important;\n  }\n  .me-md-0 {\n    margin-right: 0 !important;\n  }\n  .me-md-1 {\n    margin-right: 0.25rem !important;\n  }\n  .me-md-2 {\n    margin-right: 0.5rem !important;\n  }\n  .me-md-3 {\n    margin-right: 1rem !important;\n  }\n  .me-md-4 {\n    margin-right: 1.5rem !important;\n  }\n  .me-md-5 {\n    margin-right: 3rem !important;\n  }\n  .me-md-auto {\n    margin-right: auto !important;\n  }\n  .mb-md-0 {\n    margin-bottom: 0 !important;\n  }\n  .mb-md-1 {\n    margin-bottom: 0.25rem !important;\n  }\n  .mb-md-2 {\n    margin-bottom: 0.5rem !important;\n  }\n  .mb-md-3 {\n    margin-bottom: 1rem !important;\n  }\n  .mb-md-4 {\n    margin-bottom: 1.5rem !important;\n  }\n  .mb-md-5 {\n    margin-bottom: 3rem !important;\n  }\n  .mb-md-auto {\n    margin-bottom: auto !important;\n  }\n  .ms-md-0 {\n    margin-left: 0 !important;\n  }\n  .ms-md-1 {\n    margin-left: 0.25rem !important;\n  }\n  .ms-md-2 {\n    margin-left: 0.5rem !important;\n  }\n  .ms-md-3 {\n    margin-left: 1rem !important;\n  }\n  .ms-md-4 {\n    margin-left: 1.5rem !important;\n  }\n  .ms-md-5 {\n    margin-left: 3rem !important;\n  }\n  .ms-md-auto {\n    margin-left: auto !important;\n  }\n  .p-md-0 {\n    padding: 0 !important;\n  }\n  .p-md-1 {\n    padding: 0.25rem !important;\n  }\n  .p-md-2 {\n    padding: 0.5rem !important;\n  }\n  .p-md-3 {\n    padding: 1rem !important;\n  }\n  .p-md-4 {\n    padding: 1.5rem !important;\n  }\n  .p-md-5 {\n    padding: 3rem !important;\n  }\n  .px-md-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n  .px-md-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n  .px-md-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n  .px-md-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n  .px-md-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n  .px-md-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n  .py-md-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n  .py-md-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n  .py-md-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n  .py-md-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n  .py-md-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n  .py-md-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n  .pt-md-0 {\n    padding-top: 0 !important;\n  }\n  .pt-md-1 {\n    padding-top: 0.25rem !important;\n  }\n  .pt-md-2 {\n    padding-top: 0.5rem !important;\n  }\n  .pt-md-3 {\n    padding-top: 1rem !important;\n  }\n  .pt-md-4 {\n    padding-top: 1.5rem !important;\n  }\n  .pt-md-5 {\n    padding-top: 3rem !important;\n  }\n  .pe-md-0 {\n    padding-right: 0 !important;\n  }\n  .pe-md-1 {\n    padding-right: 0.25rem !important;\n  }\n  .pe-md-2 {\n    padding-right: 0.5rem !important;\n  }\n  .pe-md-3 {\n    padding-right: 1rem !important;\n  }\n  .pe-md-4 {\n    padding-right: 1.5rem !important;\n  }\n  .pe-md-5 {\n    padding-right: 3rem !important;\n  }\n  .pb-md-0 {\n    padding-bottom: 0 !important;\n  }\n  .pb-md-1 {\n    padding-bottom: 0.25rem !important;\n  }\n  .pb-md-2 {\n    padding-bottom: 0.5rem !important;\n  }\n  .pb-md-3 {\n    padding-bottom: 1rem !important;\n  }\n  .pb-md-4 {\n    padding-bottom: 1.5rem !important;\n  }\n  .pb-md-5 {\n    padding-bottom: 3rem !important;\n  }\n  .ps-md-0 {\n    padding-left: 0 !important;\n  }\n  .ps-md-1 {\n    padding-left: 0.25rem !important;\n  }\n  .ps-md-2 {\n    padding-left: 0.5rem !important;\n  }\n  .ps-md-3 {\n    padding-left: 1rem !important;\n  }\n  .ps-md-4 {\n    padding-left: 1.5rem !important;\n  }\n  .ps-md-5 {\n    padding-left: 3rem !important;\n  }\n  .gap-md-0 {\n    gap: 0 !important;\n  }\n  .gap-md-1 {\n    gap: 0.25rem !important;\n  }\n  .gap-md-2 {\n    gap: 0.5rem !important;\n  }\n  .gap-md-3 {\n    gap: 1rem !important;\n  }\n  .gap-md-4 {\n    gap: 1.5rem !important;\n  }\n  .gap-md-5 {\n    gap: 3rem !important;\n  }\n  .text-md-start {\n    text-align: left !important;\n  }\n  .text-md-end {\n    text-align: right !important;\n  }\n  .text-md-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 992px) {\n  .float-lg-start {\n    float: left !important;\n  }\n  .float-lg-end {\n    float: right !important;\n  }\n  .float-lg-none {\n    float: none !important;\n  }\n  .d-lg-inline {\n    display: inline !important;\n  }\n  .d-lg-inline-block {\n    display: inline-block !important;\n  }\n  .d-lg-block {\n    display: block !important;\n  }\n  .d-lg-grid {\n    display: grid !important;\n  }\n  .d-lg-table {\n    display: table !important;\n  }\n  .d-lg-table-row {\n    display: table-row !important;\n  }\n  .d-lg-table-cell {\n    display: table-cell !important;\n  }\n  .d-lg-flex {\n    display: flex !important;\n  }\n  .d-lg-inline-flex {\n    display: inline-flex !important;\n  }\n  .d-lg-none {\n    display: none !important;\n  }\n  .flex-lg-fill {\n    flex: 1 1 auto !important;\n  }\n  .flex-lg-row {\n    flex-direction: row !important;\n  }\n  .flex-lg-column {\n    flex-direction: column !important;\n  }\n  .flex-lg-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n  .flex-lg-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n  .flex-lg-grow-0 {\n    flex-grow: 0 !important;\n  }\n  .flex-lg-grow-1 {\n    flex-grow: 1 !important;\n  }\n  .flex-lg-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n  .flex-lg-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n  .flex-lg-wrap {\n    flex-wrap: wrap !important;\n  }\n  .flex-lg-nowrap {\n    flex-wrap: nowrap !important;\n  }\n  .flex-lg-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n  .justify-content-lg-start {\n    justify-content: flex-start !important;\n  }\n  .justify-content-lg-end {\n    justify-content: flex-end !important;\n  }\n  .justify-content-lg-center {\n    justify-content: center !important;\n  }\n  .justify-content-lg-between {\n    justify-content: space-between !important;\n  }\n  .justify-content-lg-around {\n    justify-content: space-around !important;\n  }\n  .justify-content-lg-evenly {\n    justify-content: space-evenly !important;\n  }\n  .align-items-lg-start {\n    align-items: flex-start !important;\n  }\n  .align-items-lg-end {\n    align-items: flex-end !important;\n  }\n  .align-items-lg-center {\n    align-items: center !important;\n  }\n  .align-items-lg-baseline {\n    align-items: baseline !important;\n  }\n  .align-items-lg-stretch {\n    align-items: stretch !important;\n  }\n  .align-content-lg-start {\n    align-content: flex-start !important;\n  }\n  .align-content-lg-end {\n    align-content: flex-end !important;\n  }\n  .align-content-lg-center {\n    align-content: center !important;\n  }\n  .align-content-lg-between {\n    align-content: space-between !important;\n  }\n  .align-content-lg-around {\n    align-content: space-around !important;\n  }\n  .align-content-lg-stretch {\n    align-content: stretch !important;\n  }\n  .align-self-lg-auto {\n    align-self: auto !important;\n  }\n  .align-self-lg-start {\n    align-self: flex-start !important;\n  }\n  .align-self-lg-end {\n    align-self: flex-end !important;\n  }\n  .align-self-lg-center {\n    align-self: center !important;\n  }\n  .align-self-lg-baseline {\n    align-self: baseline !important;\n  }\n  .align-self-lg-stretch {\n    align-self: stretch !important;\n  }\n  .order-lg-first {\n    order: -1 !important;\n  }\n  .order-lg-0 {\n    order: 0 !important;\n  }\n  .order-lg-1 {\n    order: 1 !important;\n  }\n  .order-lg-2 {\n    order: 2 !important;\n  }\n  .order-lg-3 {\n    order: 3 !important;\n  }\n  .order-lg-4 {\n    order: 4 !important;\n  }\n  .order-lg-5 {\n    order: 5 !important;\n  }\n  .order-lg-last {\n    order: 6 !important;\n  }\n  .m-lg-0 {\n    margin: 0 !important;\n  }\n  .m-lg-1 {\n    margin: 0.25rem !important;\n  }\n  .m-lg-2 {\n    margin: 0.5rem !important;\n  }\n  .m-lg-3 {\n    margin: 1rem !important;\n  }\n  .m-lg-4 {\n    margin: 1.5rem !important;\n  }\n  .m-lg-5 {\n    margin: 3rem !important;\n  }\n  .m-lg-auto {\n    margin: auto !important;\n  }\n  .mx-lg-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n  .mx-lg-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n  .mx-lg-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n  .mx-lg-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n  .mx-lg-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n  .mx-lg-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n  .mx-lg-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n  .my-lg-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n  .my-lg-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n  .my-lg-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n  .my-lg-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n  .my-lg-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n  .my-lg-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n  .my-lg-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n  .mt-lg-0 {\n    margin-top: 0 !important;\n  }\n  .mt-lg-1 {\n    margin-top: 0.25rem !important;\n  }\n  .mt-lg-2 {\n    margin-top: 0.5rem !important;\n  }\n  .mt-lg-3 {\n    margin-top: 1rem !important;\n  }\n  .mt-lg-4 {\n    margin-top: 1.5rem !important;\n  }\n  .mt-lg-5 {\n    margin-top: 3rem !important;\n  }\n  .mt-lg-auto {\n    margin-top: auto !important;\n  }\n  .me-lg-0 {\n    margin-right: 0 !important;\n  }\n  .me-lg-1 {\n    margin-right: 0.25rem !important;\n  }\n  .me-lg-2 {\n    margin-right: 0.5rem !important;\n  }\n  .me-lg-3 {\n    margin-right: 1rem !important;\n  }\n  .me-lg-4 {\n    margin-right: 1.5rem !important;\n  }\n  .me-lg-5 {\n    margin-right: 3rem !important;\n  }\n  .me-lg-auto {\n    margin-right: auto !important;\n  }\n  .mb-lg-0 {\n    margin-bottom: 0 !important;\n  }\n  .mb-lg-1 {\n    margin-bottom: 0.25rem !important;\n  }\n  .mb-lg-2 {\n    margin-bottom: 0.5rem !important;\n  }\n  .mb-lg-3 {\n    margin-bottom: 1rem !important;\n  }\n  .mb-lg-4 {\n    margin-bottom: 1.5rem !important;\n  }\n  .mb-lg-5 {\n    margin-bottom: 3rem !important;\n  }\n  .mb-lg-auto {\n    margin-bottom: auto !important;\n  }\n  .ms-lg-0 {\n    margin-left: 0 !important;\n  }\n  .ms-lg-1 {\n    margin-left: 0.25rem !important;\n  }\n  .ms-lg-2 {\n    margin-left: 0.5rem !important;\n  }\n  .ms-lg-3 {\n    margin-left: 1rem !important;\n  }\n  .ms-lg-4 {\n    margin-left: 1.5rem !important;\n  }\n  .ms-lg-5 {\n    margin-left: 3rem !important;\n  }\n  .ms-lg-auto {\n    margin-left: auto !important;\n  }\n  .p-lg-0 {\n    padding: 0 !important;\n  }\n  .p-lg-1 {\n    padding: 0.25rem !important;\n  }\n  .p-lg-2 {\n    padding: 0.5rem !important;\n  }\n  .p-lg-3 {\n    padding: 1rem !important;\n  }\n  .p-lg-4 {\n    padding: 1.5rem !important;\n  }\n  .p-lg-5 {\n    padding: 3rem !important;\n  }\n  .px-lg-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n  .px-lg-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n  .px-lg-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n  .px-lg-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n  .px-lg-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n  .px-lg-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n  .py-lg-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n  .py-lg-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n  .py-lg-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n  .py-lg-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n  .py-lg-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n  .py-lg-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n  .pt-lg-0 {\n    padding-top: 0 !important;\n  }\n  .pt-lg-1 {\n    padding-top: 0.25rem !important;\n  }\n  .pt-lg-2 {\n    padding-top: 0.5rem !important;\n  }\n  .pt-lg-3 {\n    padding-top: 1rem !important;\n  }\n  .pt-lg-4 {\n    padding-top: 1.5rem !important;\n  }\n  .pt-lg-5 {\n    padding-top: 3rem !important;\n  }\n  .pe-lg-0 {\n    padding-right: 0 !important;\n  }\n  .pe-lg-1 {\n    padding-right: 0.25rem !important;\n  }\n  .pe-lg-2 {\n    padding-right: 0.5rem !important;\n  }\n  .pe-lg-3 {\n    padding-right: 1rem !important;\n  }\n  .pe-lg-4 {\n    padding-right: 1.5rem !important;\n  }\n  .pe-lg-5 {\n    padding-right: 3rem !important;\n  }\n  .pb-lg-0 {\n    padding-bottom: 0 !important;\n  }\n  .pb-lg-1 {\n    padding-bottom: 0.25rem !important;\n  }\n  .pb-lg-2 {\n    padding-bottom: 0.5rem !important;\n  }\n  .pb-lg-3 {\n    padding-bottom: 1rem !important;\n  }\n  .pb-lg-4 {\n    padding-bottom: 1.5rem !important;\n  }\n  .pb-lg-5 {\n    padding-bottom: 3rem !important;\n  }\n  .ps-lg-0 {\n    padding-left: 0 !important;\n  }\n  .ps-lg-1 {\n    padding-left: 0.25rem !important;\n  }\n  .ps-lg-2 {\n    padding-left: 0.5rem !important;\n  }\n  .ps-lg-3 {\n    padding-left: 1rem !important;\n  }\n  .ps-lg-4 {\n    padding-left: 1.5rem !important;\n  }\n  .ps-lg-5 {\n    padding-left: 3rem !important;\n  }\n  .gap-lg-0 {\n    gap: 0 !important;\n  }\n  .gap-lg-1 {\n    gap: 0.25rem !important;\n  }\n  .gap-lg-2 {\n    gap: 0.5rem !important;\n  }\n  .gap-lg-3 {\n    gap: 1rem !important;\n  }\n  .gap-lg-4 {\n    gap: 1.5rem !important;\n  }\n  .gap-lg-5 {\n    gap: 3rem !important;\n  }\n  .text-lg-start {\n    text-align: left !important;\n  }\n  .text-lg-end {\n    text-align: right !important;\n  }\n  .text-lg-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1200px) {\n  .float-xl-start {\n    float: left !important;\n  }\n  .float-xl-end {\n    float: right !important;\n  }\n  .float-xl-none {\n    float: none !important;\n  }\n  .d-xl-inline {\n    display: inline !important;\n  }\n  .d-xl-inline-block {\n    display: inline-block !important;\n  }\n  .d-xl-block {\n    display: block !important;\n  }\n  .d-xl-grid {\n    display: grid !important;\n  }\n  .d-xl-table {\n    display: table !important;\n  }\n  .d-xl-table-row {\n    display: table-row !important;\n  }\n  .d-xl-table-cell {\n    display: table-cell !important;\n  }\n  .d-xl-flex {\n    display: flex !important;\n  }\n  .d-xl-inline-flex {\n    display: inline-flex !important;\n  }\n  .d-xl-none {\n    display: none !important;\n  }\n  .flex-xl-fill {\n    flex: 1 1 auto !important;\n  }\n  .flex-xl-row {\n    flex-direction: row !important;\n  }\n  .flex-xl-column {\n    flex-direction: column !important;\n  }\n  .flex-xl-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n  .flex-xl-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n  .flex-xl-grow-0 {\n    flex-grow: 0 !important;\n  }\n  .flex-xl-grow-1 {\n    flex-grow: 1 !important;\n  }\n  .flex-xl-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n  .flex-xl-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n  .flex-xl-wrap {\n    flex-wrap: wrap !important;\n  }\n  .flex-xl-nowrap {\n    flex-wrap: nowrap !important;\n  }\n  .flex-xl-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n  .justify-content-xl-start {\n    justify-content: flex-start !important;\n  }\n  .justify-content-xl-end {\n    justify-content: flex-end !important;\n  }\n  .justify-content-xl-center {\n    justify-content: center !important;\n  }\n  .justify-content-xl-between {\n    justify-content: space-between !important;\n  }\n  .justify-content-xl-around {\n    justify-content: space-around !important;\n  }\n  .justify-content-xl-evenly {\n    justify-content: space-evenly !important;\n  }\n  .align-items-xl-start {\n    align-items: flex-start !important;\n  }\n  .align-items-xl-end {\n    align-items: flex-end !important;\n  }\n  .align-items-xl-center {\n    align-items: center !important;\n  }\n  .align-items-xl-baseline {\n    align-items: baseline !important;\n  }\n  .align-items-xl-stretch {\n    align-items: stretch !important;\n  }\n  .align-content-xl-start {\n    align-content: flex-start !important;\n  }\n  .align-content-xl-end {\n    align-content: flex-end !important;\n  }\n  .align-content-xl-center {\n    align-content: center !important;\n  }\n  .align-content-xl-between {\n    align-content: space-between !important;\n  }\n  .align-content-xl-around {\n    align-content: space-around !important;\n  }\n  .align-content-xl-stretch {\n    align-content: stretch !important;\n  }\n  .align-self-xl-auto {\n    align-self: auto !important;\n  }\n  .align-self-xl-start {\n    align-self: flex-start !important;\n  }\n  .align-self-xl-end {\n    align-self: flex-end !important;\n  }\n  .align-self-xl-center {\n    align-self: center !important;\n  }\n  .align-self-xl-baseline {\n    align-self: baseline !important;\n  }\n  .align-self-xl-stretch {\n    align-self: stretch !important;\n  }\n  .order-xl-first {\n    order: -1 !important;\n  }\n  .order-xl-0 {\n    order: 0 !important;\n  }\n  .order-xl-1 {\n    order: 1 !important;\n  }\n  .order-xl-2 {\n    order: 2 !important;\n  }\n  .order-xl-3 {\n    order: 3 !important;\n  }\n  .order-xl-4 {\n    order: 4 !important;\n  }\n  .order-xl-5 {\n    order: 5 !important;\n  }\n  .order-xl-last {\n    order: 6 !important;\n  }\n  .m-xl-0 {\n    margin: 0 !important;\n  }\n  .m-xl-1 {\n    margin: 0.25rem !important;\n  }\n  .m-xl-2 {\n    margin: 0.5rem !important;\n  }\n  .m-xl-3 {\n    margin: 1rem !important;\n  }\n  .m-xl-4 {\n    margin: 1.5rem !important;\n  }\n  .m-xl-5 {\n    margin: 3rem !important;\n  }\n  .m-xl-auto {\n    margin: auto !important;\n  }\n  .mx-xl-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n  .mx-xl-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n  .mx-xl-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n  .mx-xl-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n  .mx-xl-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n  .mx-xl-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n  .mx-xl-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n  .my-xl-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n  .my-xl-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n  .my-xl-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n  .my-xl-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n  .my-xl-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n  .my-xl-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n  .my-xl-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n  .mt-xl-0 {\n    margin-top: 0 !important;\n  }\n  .mt-xl-1 {\n    margin-top: 0.25rem !important;\n  }\n  .mt-xl-2 {\n    margin-top: 0.5rem !important;\n  }\n  .mt-xl-3 {\n    margin-top: 1rem !important;\n  }\n  .mt-xl-4 {\n    margin-top: 1.5rem !important;\n  }\n  .mt-xl-5 {\n    margin-top: 3rem !important;\n  }\n  .mt-xl-auto {\n    margin-top: auto !important;\n  }\n  .me-xl-0 {\n    margin-right: 0 !important;\n  }\n  .me-xl-1 {\n    margin-right: 0.25rem !important;\n  }\n  .me-xl-2 {\n    margin-right: 0.5rem !important;\n  }\n  .me-xl-3 {\n    margin-right: 1rem !important;\n  }\n  .me-xl-4 {\n    margin-right: 1.5rem !important;\n  }\n  .me-xl-5 {\n    margin-right: 3rem !important;\n  }\n  .me-xl-auto {\n    margin-right: auto !important;\n  }\n  .mb-xl-0 {\n    margin-bottom: 0 !important;\n  }\n  .mb-xl-1 {\n    margin-bottom: 0.25rem !important;\n  }\n  .mb-xl-2 {\n    margin-bottom: 0.5rem !important;\n  }\n  .mb-xl-3 {\n    margin-bottom: 1rem !important;\n  }\n  .mb-xl-4 {\n    margin-bottom: 1.5rem !important;\n  }\n  .mb-xl-5 {\n    margin-bottom: 3rem !important;\n  }\n  .mb-xl-auto {\n    margin-bottom: auto !important;\n  }\n  .ms-xl-0 {\n    margin-left: 0 !important;\n  }\n  .ms-xl-1 {\n    margin-left: 0.25rem !important;\n  }\n  .ms-xl-2 {\n    margin-left: 0.5rem !important;\n  }\n  .ms-xl-3 {\n    margin-left: 1rem !important;\n  }\n  .ms-xl-4 {\n    margin-left: 1.5rem !important;\n  }\n  .ms-xl-5 {\n    margin-left: 3rem !important;\n  }\n  .ms-xl-auto {\n    margin-left: auto !important;\n  }\n  .p-xl-0 {\n    padding: 0 !important;\n  }\n  .p-xl-1 {\n    padding: 0.25rem !important;\n  }\n  .p-xl-2 {\n    padding: 0.5rem !important;\n  }\n  .p-xl-3 {\n    padding: 1rem !important;\n  }\n  .p-xl-4 {\n    padding: 1.5rem !important;\n  }\n  .p-xl-5 {\n    padding: 3rem !important;\n  }\n  .px-xl-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n  .px-xl-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n  .px-xl-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n  .px-xl-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n  .px-xl-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n  .px-xl-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n  .py-xl-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n  .py-xl-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n  .py-xl-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n  .py-xl-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n  .py-xl-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n  .py-xl-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n  .pt-xl-0 {\n    padding-top: 0 !important;\n  }\n  .pt-xl-1 {\n    padding-top: 0.25rem !important;\n  }\n  .pt-xl-2 {\n    padding-top: 0.5rem !important;\n  }\n  .pt-xl-3 {\n    padding-top: 1rem !important;\n  }\n  .pt-xl-4 {\n    padding-top: 1.5rem !important;\n  }\n  .pt-xl-5 {\n    padding-top: 3rem !important;\n  }\n  .pe-xl-0 {\n    padding-right: 0 !important;\n  }\n  .pe-xl-1 {\n    padding-right: 0.25rem !important;\n  }\n  .pe-xl-2 {\n    padding-right: 0.5rem !important;\n  }\n  .pe-xl-3 {\n    padding-right: 1rem !important;\n  }\n  .pe-xl-4 {\n    padding-right: 1.5rem !important;\n  }\n  .pe-xl-5 {\n    padding-right: 3rem !important;\n  }\n  .pb-xl-0 {\n    padding-bottom: 0 !important;\n  }\n  .pb-xl-1 {\n    padding-bottom: 0.25rem !important;\n  }\n  .pb-xl-2 {\n    padding-bottom: 0.5rem !important;\n  }\n  .pb-xl-3 {\n    padding-bottom: 1rem !important;\n  }\n  .pb-xl-4 {\n    padding-bottom: 1.5rem !important;\n  }\n  .pb-xl-5 {\n    padding-bottom: 3rem !important;\n  }\n  .ps-xl-0 {\n    padding-left: 0 !important;\n  }\n  .ps-xl-1 {\n    padding-left: 0.25rem !important;\n  }\n  .ps-xl-2 {\n    padding-left: 0.5rem !important;\n  }\n  .ps-xl-3 {\n    padding-left: 1rem !important;\n  }\n  .ps-xl-4 {\n    padding-left: 1.5rem !important;\n  }\n  .ps-xl-5 {\n    padding-left: 3rem !important;\n  }\n  .gap-xl-0 {\n    gap: 0 !important;\n  }\n  .gap-xl-1 {\n    gap: 0.25rem !important;\n  }\n  .gap-xl-2 {\n    gap: 0.5rem !important;\n  }\n  .gap-xl-3 {\n    gap: 1rem !important;\n  }\n  .gap-xl-4 {\n    gap: 1.5rem !important;\n  }\n  .gap-xl-5 {\n    gap: 3rem !important;\n  }\n  .text-xl-start {\n    text-align: left !important;\n  }\n  .text-xl-end {\n    text-align: right !important;\n  }\n  .text-xl-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1400px) {\n  .float-xxl-start {\n    float: left !important;\n  }\n  .float-xxl-end {\n    float: right !important;\n  }\n  .float-xxl-none {\n    float: none !important;\n  }\n  .d-xxl-inline {\n    display: inline !important;\n  }\n  .d-xxl-inline-block {\n    display: inline-block !important;\n  }\n  .d-xxl-block {\n    display: block !important;\n  }\n  .d-xxl-grid {\n    display: grid !important;\n  }\n  .d-xxl-table {\n    display: table !important;\n  }\n  .d-xxl-table-row {\n    display: table-row !important;\n  }\n  .d-xxl-table-cell {\n    display: table-cell !important;\n  }\n  .d-xxl-flex {\n    display: flex !important;\n  }\n  .d-xxl-inline-flex {\n    display: inline-flex !important;\n  }\n  .d-xxl-none {\n    display: none !important;\n  }\n  .flex-xxl-fill {\n    flex: 1 1 auto !important;\n  }\n  .flex-xxl-row {\n    flex-direction: row !important;\n  }\n  .flex-xxl-column {\n    flex-direction: column !important;\n  }\n  .flex-xxl-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n  .flex-xxl-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n  .flex-xxl-grow-0 {\n    flex-grow: 0 !important;\n  }\n  .flex-xxl-grow-1 {\n    flex-grow: 1 !important;\n  }\n  .flex-xxl-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n  .flex-xxl-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n  .flex-xxl-wrap {\n    flex-wrap: wrap !important;\n  }\n  .flex-xxl-nowrap {\n    flex-wrap: nowrap !important;\n  }\n  .flex-xxl-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n  .justify-content-xxl-start {\n    justify-content: flex-start !important;\n  }\n  .justify-content-xxl-end {\n    justify-content: flex-end !important;\n  }\n  .justify-content-xxl-center {\n    justify-content: center !important;\n  }\n  .justify-content-xxl-between {\n    justify-content: space-between !important;\n  }\n  .justify-content-xxl-around {\n    justify-content: space-around !important;\n  }\n  .justify-content-xxl-evenly {\n    justify-content: space-evenly !important;\n  }\n  .align-items-xxl-start {\n    align-items: flex-start !important;\n  }\n  .align-items-xxl-end {\n    align-items: flex-end !important;\n  }\n  .align-items-xxl-center {\n    align-items: center !important;\n  }\n  .align-items-xxl-baseline {\n    align-items: baseline !important;\n  }\n  .align-items-xxl-stretch {\n    align-items: stretch !important;\n  }\n  .align-content-xxl-start {\n    align-content: flex-start !important;\n  }\n  .align-content-xxl-end {\n    align-content: flex-end !important;\n  }\n  .align-content-xxl-center {\n    align-content: center !important;\n  }\n  .align-content-xxl-between {\n    align-content: space-between !important;\n  }\n  .align-content-xxl-around {\n    align-content: space-around !important;\n  }\n  .align-content-xxl-stretch {\n    align-content: stretch !important;\n  }\n  .align-self-xxl-auto {\n    align-self: auto !important;\n  }\n  .align-self-xxl-start {\n    align-self: flex-start !important;\n  }\n  .align-self-xxl-end {\n    align-self: flex-end !important;\n  }\n  .align-self-xxl-center {\n    align-self: center !important;\n  }\n  .align-self-xxl-baseline {\n    align-self: baseline !important;\n  }\n  .align-self-xxl-stretch {\n    align-self: stretch !important;\n  }\n  .order-xxl-first {\n    order: -1 !important;\n  }\n  .order-xxl-0 {\n    order: 0 !important;\n  }\n  .order-xxl-1 {\n    order: 1 !important;\n  }\n  .order-xxl-2 {\n    order: 2 !important;\n  }\n  .order-xxl-3 {\n    order: 3 !important;\n  }\n  .order-xxl-4 {\n    order: 4 !important;\n  }\n  .order-xxl-5 {\n    order: 5 !important;\n  }\n  .order-xxl-last {\n    order: 6 !important;\n  }\n  .m-xxl-0 {\n    margin: 0 !important;\n  }\n  .m-xxl-1 {\n    margin: 0.25rem !important;\n  }\n  .m-xxl-2 {\n    margin: 0.5rem !important;\n  }\n  .m-xxl-3 {\n    margin: 1rem !important;\n  }\n  .m-xxl-4 {\n    margin: 1.5rem !important;\n  }\n  .m-xxl-5 {\n    margin: 3rem !important;\n  }\n  .m-xxl-auto {\n    margin: auto !important;\n  }\n  .mx-xxl-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n  .mx-xxl-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n  .mx-xxl-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n  .mx-xxl-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n  .mx-xxl-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n  .mx-xxl-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n  .mx-xxl-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n  .my-xxl-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n  .my-xxl-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n  .my-xxl-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n  .my-xxl-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n  .my-xxl-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n  .my-xxl-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n  .my-xxl-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n  .mt-xxl-0 {\n    margin-top: 0 !important;\n  }\n  .mt-xxl-1 {\n    margin-top: 0.25rem !important;\n  }\n  .mt-xxl-2 {\n    margin-top: 0.5rem !important;\n  }\n  .mt-xxl-3 {\n    margin-top: 1rem !important;\n  }\n  .mt-xxl-4 {\n    margin-top: 1.5rem !important;\n  }\n  .mt-xxl-5 {\n    margin-top: 3rem !important;\n  }\n  .mt-xxl-auto {\n    margin-top: auto !important;\n  }\n  .me-xxl-0 {\n    margin-right: 0 !important;\n  }\n  .me-xxl-1 {\n    margin-right: 0.25rem !important;\n  }\n  .me-xxl-2 {\n    margin-right: 0.5rem !important;\n  }\n  .me-xxl-3 {\n    margin-right: 1rem !important;\n  }\n  .me-xxl-4 {\n    margin-right: 1.5rem !important;\n  }\n  .me-xxl-5 {\n    margin-right: 3rem !important;\n  }\n  .me-xxl-auto {\n    margin-right: auto !important;\n  }\n  .mb-xxl-0 {\n    margin-bottom: 0 !important;\n  }\n  .mb-xxl-1 {\n    margin-bottom: 0.25rem !important;\n  }\n  .mb-xxl-2 {\n    margin-bottom: 0.5rem !important;\n  }\n  .mb-xxl-3 {\n    margin-bottom: 1rem !important;\n  }\n  .mb-xxl-4 {\n    margin-bottom: 1.5rem !important;\n  }\n  .mb-xxl-5 {\n    margin-bottom: 3rem !important;\n  }\n  .mb-xxl-auto {\n    margin-bottom: auto !important;\n  }\n  .ms-xxl-0 {\n    margin-left: 0 !important;\n  }\n  .ms-xxl-1 {\n    margin-left: 0.25rem !important;\n  }\n  .ms-xxl-2 {\n    margin-left: 0.5rem !important;\n  }\n  .ms-xxl-3 {\n    margin-left: 1rem !important;\n  }\n  .ms-xxl-4 {\n    margin-left: 1.5rem !important;\n  }\n  .ms-xxl-5 {\n    margin-left: 3rem !important;\n  }\n  .ms-xxl-auto {\n    margin-left: auto !important;\n  }\n  .p-xxl-0 {\n    padding: 0 !important;\n  }\n  .p-xxl-1 {\n    padding: 0.25rem !important;\n  }\n  .p-xxl-2 {\n    padding: 0.5rem !important;\n  }\n  .p-xxl-3 {\n    padding: 1rem !important;\n  }\n  .p-xxl-4 {\n    padding: 1.5rem !important;\n  }\n  .p-xxl-5 {\n    padding: 3rem !important;\n  }\n  .px-xxl-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n  .px-xxl-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n  .px-xxl-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n  .px-xxl-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n  .px-xxl-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n  .px-xxl-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n  .py-xxl-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n  .py-xxl-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n  .py-xxl-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n  .py-xxl-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n  .py-xxl-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n  .py-xxl-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n  .pt-xxl-0 {\n    padding-top: 0 !important;\n  }\n  .pt-xxl-1 {\n    padding-top: 0.25rem !important;\n  }\n  .pt-xxl-2 {\n    padding-top: 0.5rem !important;\n  }\n  .pt-xxl-3 {\n    padding-top: 1rem !important;\n  }\n  .pt-xxl-4 {\n    padding-top: 1.5rem !important;\n  }\n  .pt-xxl-5 {\n    padding-top: 3rem !important;\n  }\n  .pe-xxl-0 {\n    padding-right: 0 !important;\n  }\n  .pe-xxl-1 {\n    padding-right: 0.25rem !important;\n  }\n  .pe-xxl-2 {\n    padding-right: 0.5rem !important;\n  }\n  .pe-xxl-3 {\n    padding-right: 1rem !important;\n  }\n  .pe-xxl-4 {\n    padding-right: 1.5rem !important;\n  }\n  .pe-xxl-5 {\n    padding-right: 3rem !important;\n  }\n  .pb-xxl-0 {\n    padding-bottom: 0 !important;\n  }\n  .pb-xxl-1 {\n    padding-bottom: 0.25rem !important;\n  }\n  .pb-xxl-2 {\n    padding-bottom: 0.5rem !important;\n  }\n  .pb-xxl-3 {\n    padding-bottom: 1rem !important;\n  }\n  .pb-xxl-4 {\n    padding-bottom: 1.5rem !important;\n  }\n  .pb-xxl-5 {\n    padding-bottom: 3rem !important;\n  }\n  .ps-xxl-0 {\n    padding-left: 0 !important;\n  }\n  .ps-xxl-1 {\n    padding-left: 0.25rem !important;\n  }\n  .ps-xxl-2 {\n    padding-left: 0.5rem !important;\n  }\n  .ps-xxl-3 {\n    padding-left: 1rem !important;\n  }\n  .ps-xxl-4 {\n    padding-left: 1.5rem !important;\n  }\n  .ps-xxl-5 {\n    padding-left: 3rem !important;\n  }\n  .gap-xxl-0 {\n    gap: 0 !important;\n  }\n  .gap-xxl-1 {\n    gap: 0.25rem !important;\n  }\n  .gap-xxl-2 {\n    gap: 0.5rem !important;\n  }\n  .gap-xxl-3 {\n    gap: 1rem !important;\n  }\n  .gap-xxl-4 {\n    gap: 1.5rem !important;\n  }\n  .gap-xxl-5 {\n    gap: 3rem !important;\n  }\n  .text-xxl-start {\n    text-align: left !important;\n  }\n  .text-xxl-end {\n    text-align: right !important;\n  }\n  .text-xxl-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1200px) {\n  .fs-1 {\n    font-size: 2.5rem !important;\n  }\n  .fs-2 {\n    font-size: 2rem !important;\n  }\n  .fs-3 {\n    font-size: 1.75rem !important;\n  }\n  .fs-4 {\n    font-size: 1.5rem !important;\n  }\n}\n@media print {\n  .d-print-inline {\n    display: inline !important;\n  }\n  .d-print-inline-block {\n    display: inline-block !important;\n  }\n  .d-print-block {\n    display: block !important;\n  }\n  .d-print-grid {\n    display: grid !important;\n  }\n  .d-print-table {\n    display: table !important;\n  }\n  .d-print-table-row {\n    display: table-row !important;\n  }\n  .d-print-table-cell {\n    display: table-cell !important;\n  }\n  .d-print-flex {\n    display: flex !important;\n  }\n  .d-print-inline-flex {\n    display: inline-flex !important;\n  }\n  .d-print-none {\n    display: none !important;\n  }\n}\n\n/*# sourceMappingURL=bootstrap.css.map */","// stylelint-disable property-disallowed-list\n// Single side border-radius\n\n// Helper function to replace negative values with 0\n@function valid-radius($radius) {\n  $return: ();\n  @each $value in $radius {\n    @if type-of($value) == number {\n      $return: append($return, max($value, 0));\n    } @else {\n      $return: append($return, $value);\n    }\n  }\n  @return $return;\n}\n\n// scss-docs-start border-radius-mixins\n@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {\n  @if $enable-rounded {\n    border-radius: valid-radius($radius);\n  }\n  @else if $fallback-border-radius != false {\n    border-radius: $fallback-border-radius;\n  }\n}\n\n@mixin border-top-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-top-left-radius: valid-radius($radius);\n    border-top-right-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-end-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-top-right-radius: valid-radius($radius);\n    border-bottom-right-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-bottom-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-bottom-right-radius: valid-radius($radius);\n    border-bottom-left-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-start-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-top-left-radius: valid-radius($radius);\n    border-bottom-left-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-top-start-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-top-left-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-top-end-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-top-right-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-bottom-end-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-bottom-right-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-bottom-start-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-bottom-left-radius: valid-radius($radius);\n  }\n}\n// scss-docs-end border-radius-mixins\n","//\n// Headings\n//\n.h1 {\n  @extend h1;\n}\n\n.h2 {\n  @extend h2;\n}\n\n.h3 {\n  @extend h3;\n}\n\n.h4 {\n  @extend h4;\n}\n\n.h5 {\n  @extend h5;\n}\n\n.h6 {\n  @extend h6;\n}\n\n\n.lead {\n  @include font-size($lead-font-size);\n  font-weight: $lead-font-weight;\n}\n\n// Type display classes\n@each $display, $font-size in $display-font-sizes {\n  .display-#{$display} {\n    @include font-size($font-size);\n    font-family: $display-font-family;\n    font-style: $display-font-style;\n    font-weight: $display-font-weight;\n    line-height: $display-line-height;\n  }\n}\n\n//\n// Emphasis\n//\n.small {\n  @extend small;\n}\n\n.mark {\n  @extend mark;\n}\n\n//\n// Lists\n//\n\n.list-unstyled {\n  @include list-unstyled();\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n  @include list-unstyled();\n}\n.list-inline-item {\n  display: inline-block;\n\n  &:not(:last-child) {\n    margin-right: $list-inline-padding;\n  }\n}\n\n\n//\n// Misc\n//\n\n// Builds on `abbr`\n.initialism {\n  @include font-size($initialism-font-size);\n  text-transform: uppercase;\n}\n\n// Blockquotes\n.blockquote {\n  margin-bottom: $blockquote-margin-y;\n  @include font-size($blockquote-font-size);\n\n  > :last-child {\n    margin-bottom: 0;\n  }\n}\n\n.blockquote-footer {\n  margin-top: -$blockquote-margin-y;\n  margin-bottom: $blockquote-margin-y;\n  @include font-size($blockquote-footer-font-size);\n  color: $blockquote-footer-color;\n\n  &::before {\n    content: \"\\2014\\00A0\"; // em dash, nbsp\n  }\n}\n","// Lists\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n@mixin list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n","// Responsive images (ensure images don't scale beyond their parents)\n//\n// This is purposefully opt-in via an explicit class rather than being the default for all `
`s.\n// We previously tried the \"images are responsive by default\" approach in Bootstrap v2,\n// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)\n// which weren't expecting the images within themselves to be involuntarily resized.\n// See also https://github.com/twbs/bootstrap/issues/18178\n.img-fluid {\n  @include img-fluid();\n}\n\n\n// Image thumbnails\n.img-thumbnail {\n  padding: $thumbnail-padding;\n  background-color: $thumbnail-bg;\n  border: $thumbnail-border-width solid $thumbnail-border-color;\n  @include border-radius($thumbnail-border-radius);\n  @include box-shadow($thumbnail-box-shadow);\n\n  // Keep them at most 100% wide\n  @include img-fluid();\n}\n\n//\n// Figures\n//\n\n.figure {\n  // Ensures the caption's text aligns with the image.\n  display: inline-block;\n}\n\n.figure-img {\n  margin-bottom: $spacer * .5;\n  line-height: 1;\n}\n\n.figure-caption {\n  @include font-size($figure-caption-font-size);\n  color: $figure-caption-color;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n@mixin img-fluid {\n  // Part 1: Set a maximum relative to the parent\n  max-width: 100%;\n  // Part 2: Override the height to auto, otherwise images will be stretched\n  // when setting a width and height attribute on the img element.\n  height: auto;\n}\n","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-container-classes {\n  // Single container class with breakpoint max-widths\n  .container,\n  // 100% wide container at all breakpoints\n  .container-fluid {\n    @include make-container();\n  }\n\n  // Responsive containers that are 100% wide until a breakpoint\n  @each $breakpoint, $container-max-width in $container-max-widths {\n    .container-#{$breakpoint} {\n      @extend .container-fluid;\n    }\n\n    @include media-breakpoint-up($breakpoint, $grid-breakpoints) {\n      %responsive-container-#{$breakpoint} {\n        max-width: $container-max-width;\n      }\n\n      // Extend each breakpoint which is smaller or equal to the current breakpoint\n      $extend-breakpoint: true;\n\n      @each $name, $width in $grid-breakpoints {\n        @if ($extend-breakpoint) {\n          .container#{breakpoint-infix($name, $grid-breakpoints)} {\n            @extend %responsive-container-#{$breakpoint};\n          }\n\n          // Once the current breakpoint is reached, stop extending\n          @if ($breakpoint == $name) {\n            $extend-breakpoint: false;\n          }\n        }\n      }\n    }\n  }\n}\n","// Container mixins\n\n@mixin make-container($gutter: $container-padding-x) {\n  --#{$prefix}gutter-x: #{$gutter};\n  --#{$prefix}gutter-y: 0;\n  width: 100%;\n  padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n  padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n  margin-right: auto;\n  margin-left: auto;\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n//    (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n//    >> breakpoint-next(sm)\n//    md\n//    >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n//    md\n//    >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl xxl))\n//    md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n  $n: index($breakpoint-names, $name);\n  @if not $n {\n    @error \"breakpoint `#{$name}` not found in `#{$breakpoints}`\";\n  }\n  @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n//    >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n//    576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n  $min: map-get($breakpoints, $name);\n  @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width.\n// The maximum value is reduced by 0.02px to work around the limitations of\n// `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n//    >> breakpoint-max(md, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n//    767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n  $max: map-get($breakpoints, $name);\n  @return if($max and $max > 0, $max - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n//    >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n//    \"\"  (Returns a blank string)\n//    >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n//    \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n  @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n  $min: breakpoint-min($name, $breakpoints);\n  @if $min {\n    @media (min-width: $min) {\n      @content;\n    }\n  } @else {\n    @content;\n  }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n  $max: breakpoint-max($name, $breakpoints);\n  @if $max {\n    @media (max-width: $max) {\n      @content;\n    }\n  } @else {\n    @content;\n  }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n  $min: breakpoint-min($lower, $breakpoints);\n  $max: breakpoint-max($upper, $breakpoints);\n\n  @if $min != null and $max != null {\n    @media (min-width: $min) and (max-width: $max) {\n      @content;\n    }\n  } @else if $max == null {\n    @include media-breakpoint-up($lower, $breakpoints) {\n      @content;\n    }\n  } @else if $min == null {\n    @include media-breakpoint-down($upper, $breakpoints) {\n      @content;\n    }\n  }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n  $min:  breakpoint-min($name, $breakpoints);\n  $next: breakpoint-next($name, $breakpoints);\n  $max:  breakpoint-max($next, $breakpoints);\n\n  @if $min != null and $max != null {\n    @media (min-width: $min) and (max-width: $max) {\n      @content;\n    }\n  } @else if $max == null {\n    @include media-breakpoint-up($name, $breakpoints) {\n      @content;\n    }\n  } @else if $min == null {\n    @include media-breakpoint-down($next, $breakpoints) {\n      @content;\n    }\n  }\n}\n","// Row\n//\n// Rows contain your columns.\n\n@if $enable-grid-classes {\n  .row {\n    @include make-row();\n\n    > * {\n      @include make-col-ready();\n    }\n  }\n}\n\n@if $enable-cssgrid {\n  .grid {\n    display: grid;\n    grid-template-rows: repeat(var(--#{$prefix}rows, 1), 1fr);\n    grid-template-columns: repeat(var(--#{$prefix}columns, #{$grid-columns}), 1fr);\n    gap: var(--#{$prefix}gap, #{$grid-gutter-width});\n\n    @include make-cssgrid();\n  }\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n  @include make-grid-columns();\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-row($gutter: $grid-gutter-width) {\n  --#{$prefix}gutter-x: #{$gutter};\n  --#{$prefix}gutter-y: 0;\n  display: flex;\n  flex-wrap: wrap;\n  // TODO: Revisit calc order after https://github.com/react-bootstrap/react-bootstrap/issues/6039 is fixed\n  margin-top: calc(-1 * var(--#{$prefix}gutter-y)); // stylelint-disable-line function-disallowed-list\n  margin-right: calc(-.5 * var(--#{$prefix}gutter-x)); // stylelint-disable-line function-disallowed-list\n  margin-left: calc(-.5 * var(--#{$prefix}gutter-x)); // stylelint-disable-line function-disallowed-list\n}\n\n@mixin make-col-ready() {\n  // Add box sizing if only the grid is loaded\n  box-sizing: if(variable-exists(include-column-box-sizing) and $include-column-box-sizing, border-box, null);\n  // Prevent columns from becoming too narrow when at smaller grid tiers by\n  // always setting `width: 100%;`. This works because we set the width\n  // later on to override this initial width.\n  flex-shrink: 0;\n  width: 100%;\n  max-width: 100%; // Prevent `.col-auto`, `.col` (& responsive variants) from breaking out the grid\n  padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n  padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n  margin-top: var(--#{$prefix}gutter-y);\n}\n\n@mixin make-col($size: false, $columns: $grid-columns) {\n  @if $size {\n    flex: 0 0 auto;\n    width: percentage(divide($size, $columns));\n\n  } @else {\n    flex: 1 1 0;\n    max-width: 100%;\n  }\n}\n\n@mixin make-col-auto() {\n  flex: 0 0 auto;\n  width: auto;\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n  $num: divide($size, $columns);\n  margin-left: if($num == 0, 0, percentage($num));\n}\n\n// Row columns\n//\n// Specify on a parent element(e.g., .row) to force immediate children into NN\n// number of columns. Supports wrapping to new lines, but does not do a Masonry\n// style grid.\n@mixin row-cols($count) {\n  > * {\n    flex: 0 0 auto;\n    width: divide(100%, $count);\n  }\n}\n\n// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n  @each $breakpoint in map-keys($breakpoints) {\n    $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n    @include media-breakpoint-up($breakpoint, $breakpoints) {\n      // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n      .col#{$infix} {\n        flex: 1 0 0%; // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n      }\n\n      .row-cols#{$infix}-auto > * {\n        @include make-col-auto();\n      }\n\n      @if $grid-row-columns > 0 {\n        @for $i from 1 through $grid-row-columns {\n          .row-cols#{$infix}-#{$i} {\n            @include row-cols($i);\n          }\n        }\n      }\n\n      .col#{$infix}-auto {\n        @include make-col-auto();\n      }\n\n      @if $columns > 0 {\n        @for $i from 1 through $columns {\n          .col#{$infix}-#{$i} {\n            @include make-col($i, $columns);\n          }\n        }\n\n        // `$columns - 1` because offsetting by the width of an entire row isn't possible\n        @for $i from 0 through ($columns - 1) {\n          @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n            .offset#{$infix}-#{$i} {\n              @include make-col-offset($i, $columns);\n            }\n          }\n        }\n      }\n\n      // Gutters\n      //\n      // Make use of `.g-*`, `.gx-*` or `.gy-*` utilities to change spacing between the columns.\n      @each $key, $value in $gutters {\n        .g#{$infix}-#{$key},\n        .gx#{$infix}-#{$key} {\n          --#{$prefix}gutter-x: #{$value};\n        }\n\n        .g#{$infix}-#{$key},\n        .gy#{$infix}-#{$key} {\n          --#{$prefix}gutter-y: #{$value};\n        }\n      }\n    }\n  }\n}\n\n@mixin make-cssgrid($columns: $grid-columns, $breakpoints: $grid-breakpoints) {\n  @each $breakpoint in map-keys($breakpoints) {\n    $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n    @include media-breakpoint-up($breakpoint, $breakpoints) {\n      @if $columns > 0 {\n        @for $i from 1 through $columns {\n          .g-col#{$infix}-#{$i} {\n            grid-column: auto / span $i;\n          }\n        }\n\n        // Start with `1` because `0` is and invalid value.\n        // Ends with `$columns - 1` because offsetting by the width of an entire row isn't possible.\n        @for $i from 1 through ($columns - 1) {\n          .g-start#{$infix}-#{$i} {\n            grid-column-start: $i;\n          }\n        }\n      }\n    }\n  }\n}\n","//\n// Basic Bootstrap table\n//\n\n.table {\n  --#{$prefix}table-color: #{$table-color};\n  --#{$prefix}table-bg: #{$table-bg};\n  --#{$prefix}table-border-color: #{$table-border-color};\n  --#{$prefix}table-accent-bg: #{$table-accent-bg};\n  --#{$prefix}table-striped-color: #{$table-striped-color};\n  --#{$prefix}table-striped-bg: #{$table-striped-bg};\n  --#{$prefix}table-active-color: #{$table-active-color};\n  --#{$prefix}table-active-bg: #{$table-active-bg};\n  --#{$prefix}table-hover-color: #{$table-hover-color};\n  --#{$prefix}table-hover-bg: #{$table-hover-bg};\n\n  width: 100%;\n  margin-bottom: $spacer;\n  color: var(--#{$prefix}table-color);\n  vertical-align: $table-cell-vertical-align;\n  border-color: var(--#{$prefix}table-border-color);\n\n  // Target th & td\n  // We need the child combinator to prevent styles leaking to nested tables which doesn't have a `.table` class.\n  // We use the universal selectors here to simplify the selector (else we would need 6 different selectors).\n  // Another advantage is that this generates less code and makes the selector less specific making it easier to override.\n  // stylelint-disable-next-line selector-max-universal\n  > :not(caption) > * > * {\n    padding: $table-cell-padding-y $table-cell-padding-x;\n    background-color: var(--#{$prefix}table-bg);\n    border-bottom-width: $table-border-width;\n    box-shadow: inset 0 0 0 9999px var(--#{$prefix}table-accent-bg);\n  }\n\n  > tbody {\n    vertical-align: inherit;\n  }\n\n  > thead {\n    vertical-align: bottom;\n  }\n}\n\n.table-group-divider {\n  border-top: ($table-border-width * 2) solid $table-group-separator-color;\n}\n\n//\n// Change placement of captions with a class\n//\n\n.caption-top {\n  caption-side: top;\n}\n\n\n//\n// Condensed table w/ half padding\n//\n\n.table-sm {\n  // stylelint-disable-next-line selector-max-universal\n  > :not(caption) > * > * {\n    padding: $table-cell-padding-y-sm $table-cell-padding-x-sm;\n  }\n}\n\n\n// Border versions\n//\n// Add or remove borders all around the table and between all the columns.\n//\n// When borders are added on all sides of the cells, the corners can render odd when\n// these borders do not have the same color or if they are semi-transparent.\n// Therefor we add top and border bottoms to the `tr`s and left and right borders\n// to the `td`s or `th`s\n\n.table-bordered {\n  > :not(caption) > * {\n    border-width: $table-border-width 0;\n\n    // stylelint-disable-next-line selector-max-universal\n    > * {\n      border-width: 0 $table-border-width;\n    }\n  }\n}\n\n.table-borderless {\n  // stylelint-disable-next-line selector-max-universal\n  > :not(caption) > * > * {\n    border-bottom-width: 0;\n  }\n\n  > :not(:first-child) {\n    border-top-width: 0;\n  }\n}\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n// For rows\n.table-striped {\n  > tbody > tr:nth-of-type(#{$table-striped-order}) > * {\n    --#{$prefix}table-accent-bg: var(--#{$prefix}table-striped-bg);\n    color: var(--#{$prefix}table-striped-color);\n  }\n}\n\n// For columns\n.table-striped-columns {\n  > :not(caption) > tr > :nth-child(#{$table-striped-columns-order}) {\n    --#{$prefix}table-accent-bg: var(--#{$prefix}table-striped-bg);\n    color: var(--#{$prefix}table-striped-color);\n  }\n}\n\n// Active table\n//\n// The `.table-active` class can be added to highlight rows or cells\n\n.table-active {\n  --#{$prefix}table-accent-bg: var(--#{$prefix}table-active-bg);\n  color: var(--#{$prefix}table-active-color);\n}\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n  > tbody > tr:hover > * {\n    --#{$prefix}table-accent-bg: var(--#{$prefix}table-hover-bg);\n    color: var(--#{$prefix}table-hover-color);\n  }\n}\n\n\n// Table variants\n//\n// Table variants set the table cell backgrounds, border colors\n// and the colors of the striped, hovered & active tables\n\n@each $color, $value in $table-variants {\n  @include table-variant($color, $value);\n}\n\n// Responsive tables\n//\n// Generate series of `.table-responsive-*` classes for configuring the screen\n// size of where your table will overflow.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n  $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n  @include media-breakpoint-down($breakpoint) {\n    .table-responsive#{$infix} {\n      overflow-x: auto;\n      -webkit-overflow-scrolling: touch;\n    }\n  }\n}\n","// scss-docs-start table-variant\n@mixin table-variant($state, $background) {\n  .table-#{$state} {\n    $color: color-contrast(opaque($body-bg, $background));\n    $hover-bg: mix($color, $background, percentage($table-hover-bg-factor));\n    $striped-bg: mix($color, $background, percentage($table-striped-bg-factor));\n    $active-bg: mix($color, $background, percentage($table-active-bg-factor));\n    $table-border-color: mix($color, $background, percentage($table-border-factor));\n\n    --#{$prefix}table-color: #{$color};\n    --#{$prefix}table-bg: #{$background};\n    --#{$prefix}table-border-color: #{$table-border-color};\n    --#{$prefix}table-striped-bg: #{$striped-bg};\n    --#{$prefix}table-striped-color: #{color-contrast($striped-bg)};\n    --#{$prefix}table-active-bg: #{$active-bg};\n    --#{$prefix}table-active-color: #{color-contrast($active-bg)};\n    --#{$prefix}table-hover-bg: #{$hover-bg};\n    --#{$prefix}table-hover-color: #{color-contrast($hover-bg)};\n\n    color: var(--#{$prefix}table-color);\n    border-color: var(--#{$prefix}table-border-color);\n  }\n}\n// scss-docs-end table-variant\n","//\n// Labels\n//\n\n.form-label {\n  margin-bottom: $form-label-margin-bottom;\n  @include font-size($form-label-font-size);\n  font-style: $form-label-font-style;\n  font-weight: $form-label-font-weight;\n  color: $form-label-color;\n}\n\n// For use with horizontal and inline forms, when you need the label (or legend)\n// text to align with the form controls.\n.col-form-label {\n  padding-top: add($input-padding-y, $input-border-width);\n  padding-bottom: add($input-padding-y, $input-border-width);\n  margin-bottom: 0; // Override the `
` default\n  @include font-size(inherit); // Override the `` default\n  font-style: $form-label-font-style;\n  font-weight: $form-label-font-weight;\n  line-height: $input-line-height;\n  color: $form-label-color;\n}\n\n.col-form-label-lg {\n  padding-top: add($input-padding-y-lg, $input-border-width);\n  padding-bottom: add($input-padding-y-lg, $input-border-width);\n  @include font-size($input-font-size-lg);\n}\n\n.col-form-label-sm {\n  padding-top: add($input-padding-y-sm, $input-border-width);\n  padding-bottom: add($input-padding-y-sm, $input-border-width);\n  @include font-size($input-font-size-sm);\n}\n","//\n// Form text\n//\n\n.form-text {\n  margin-top: $form-text-margin-top;\n  @include font-size($form-text-font-size);\n  font-style: $form-text-font-style;\n  font-weight: $form-text-font-weight;\n  color: $form-text-color;\n}\n","//\n// General form controls (plus a few specific high-level interventions)\n//\n\n.form-control {\n  display: block;\n  width: 100%;\n  padding: $input-padding-y $input-padding-x;\n  font-family: $input-font-family;\n  @include font-size($input-font-size);\n  font-weight: $input-font-weight;\n  line-height: $input-line-height;\n  color: $input-color;\n  background-color: $input-bg;\n  background-clip: padding-box;\n  border: $input-border-width solid $input-border-color;\n  appearance: none; // Fix appearance for date inputs in Safari\n\n  // Note: This has no effect on s in some browsers, due to the limited stylability of ``s in CSS.\n  @include border-radius($input-border-radius, 0);\n\n  @include box-shadow($input-box-shadow);\n  @include transition($input-transition);\n\n  &[type=\"file\"] {\n    overflow: hidden; // prevent pseudo element button overlap\n\n    &:not(:disabled):not([readonly]) {\n      cursor: pointer;\n    }\n  }\n\n  // Customize the `:focus` state to imitate native WebKit styles.\n  &:focus {\n    color: $input-focus-color;\n    background-color: $input-focus-bg;\n    border-color: $input-focus-border-color;\n    outline: 0;\n    @if $enable-shadows {\n      @include box-shadow($input-box-shadow, $input-focus-box-shadow);\n    } @else {\n      // Avoid using mixin so we can pass custom focus shadow properly\n      box-shadow: $input-focus-box-shadow;\n    }\n  }\n\n  // Add some height to date inputs on iOS\n  // https://github.com/twbs/bootstrap/issues/23307\n  // TODO: we can remove this workaround once https://bugs.webkit.org/show_bug.cgi?id=198959 is resolved\n  &::-webkit-date-and-time-value {\n    // Multiply line-height by 1em if it has no unit\n    height: if(unit($input-line-height) == \"\", $input-line-height * 1em, $input-line-height);\n  }\n\n  // Placeholder\n  &::placeholder {\n    color: $input-placeholder-color;\n    // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.\n    opacity: 1;\n  }\n\n  // Disabled inputs\n  //\n  // HTML5 says that controls under a fieldset > legend:first-child won't be\n  // disabled if the fieldset is disabled. Due to implementation difficulty, we\n  // don't honor that edge case; we style them as disabled anyway.\n  &:disabled {\n    color: $input-disabled-color;\n    background-color: $input-disabled-bg;\n    border-color: $input-disabled-border-color;\n    // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.\n    opacity: 1;\n  }\n\n  // File input buttons theming\n  &::file-selector-button {\n    padding: $input-padding-y $input-padding-x;\n    margin: (-$input-padding-y) (-$input-padding-x);\n    margin-inline-end: $input-padding-x;\n    color: $form-file-button-color;\n    @include gradient-bg($form-file-button-bg);\n    pointer-events: none;\n    border-color: inherit;\n    border-style: solid;\n    border-width: 0;\n    border-inline-end-width: $input-border-width;\n    border-radius: 0; // stylelint-disable-line property-disallowed-list\n    @include transition($btn-transition);\n  }\n\n  &:hover:not(:disabled):not([readonly])::file-selector-button {\n    background-color: $form-file-button-hover-bg;\n  }\n}\n\n// Readonly controls as plain text\n//\n// Apply class to a readonly input to make it appear like regular plain\n// text (without any border, background color, focus indicator)\n\n.form-control-plaintext {\n  display: block;\n  width: 100%;\n  padding: $input-padding-y 0;\n  margin-bottom: 0; // match inputs if this class comes on inputs with default margins\n  line-height: $input-line-height;\n  color: $input-plaintext-color;\n  background-color: transparent;\n  border: solid transparent;\n  border-width: $input-border-width 0;\n\n  &:focus {\n    outline: 0;\n  }\n\n  &.form-control-sm,\n  &.form-control-lg {\n    padding-right: 0;\n    padding-left: 0;\n  }\n}\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n//\n// Repeated in `_input_group.scss` to avoid Sass extend issues.\n\n.form-control-sm {\n  min-height: $input-height-sm;\n  padding: $input-padding-y-sm $input-padding-x-sm;\n  @include font-size($input-font-size-sm);\n  @include border-radius($input-border-radius-sm);\n\n  &::file-selector-button {\n    padding: $input-padding-y-sm $input-padding-x-sm;\n    margin: (-$input-padding-y-sm) (-$input-padding-x-sm);\n    margin-inline-end: $input-padding-x-sm;\n  }\n}\n\n.form-control-lg {\n  min-height: $input-height-lg;\n  padding: $input-padding-y-lg $input-padding-x-lg;\n  @include font-size($input-font-size-lg);\n  @include border-radius($input-border-radius-lg);\n\n  &::file-selector-button {\n    padding: $input-padding-y-lg $input-padding-x-lg;\n    margin: (-$input-padding-y-lg) (-$input-padding-x-lg);\n    margin-inline-end: $input-padding-x-lg;\n  }\n}\n\n// Make sure textareas don't shrink too much when resized\n// https://github.com/twbs/bootstrap/pull/29124\n// stylelint-disable selector-no-qualifying-type\ntextarea {\n  &.form-control {\n    min-height: $input-height;\n  }\n\n  &.form-control-sm {\n    min-height: $input-height-sm;\n  }\n\n  &.form-control-lg {\n    min-height: $input-height-lg;\n  }\n}\n// stylelint-enable selector-no-qualifying-type\n\n.form-control-color {\n  width: $form-color-width;\n  height: $input-height;\n  padding: $input-padding-y;\n\n  &:not(:disabled):not([readonly]) {\n    cursor: pointer;\n  }\n\n  &::-moz-color-swatch {\n    border: 0 !important; // stylelint-disable-line declaration-no-important\n    @include border-radius($input-border-radius);\n  }\n\n  &::-webkit-color-swatch {\n    @include border-radius($input-border-radius);\n  }\n\n  &.form-control-sm { height: $input-height-sm; }\n  &.form-control-lg { height: $input-height-lg; }\n}\n","// stylelint-disable property-disallowed-list\n@mixin transition($transition...) {\n  @if length($transition) == 0 {\n    $transition: $transition-base;\n  }\n\n  @if length($transition) > 1 {\n    @each $value in $transition {\n      @if $value == null or $value == none {\n        @warn \"The keyword 'none' or 'null' must be used as a single argument.\";\n      }\n    }\n  }\n\n  @if $enable-transitions {\n    @if nth($transition, 1) != null {\n      transition: $transition;\n    }\n\n    @if $enable-reduced-motion and nth($transition, 1) != null and nth($transition, 1) != none {\n      @media (prefers-reduced-motion: reduce) {\n        transition: none;\n      }\n    }\n  }\n}\n","// Gradients\n\n// scss-docs-start gradient-bg-mixin\n@mixin gradient-bg($color: null) {\n  background-color: $color;\n\n  @if $enable-gradients {\n    background-image: var(--#{$prefix}gradient);\n  }\n}\n// scss-docs-end gradient-bg-mixin\n\n// scss-docs-start gradient-mixins\n// Horizontal gradient, from left to right\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n  background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);\n}\n\n// Vertical gradient, from top to bottom\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: null, $end-percent: null) {\n  background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);\n}\n\n@mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) {\n  background-image: linear-gradient($deg, $start-color, $end-color);\n}\n\n@mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n  background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);\n}\n\n@mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n  background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);\n}\n\n@mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) {\n  background-image: radial-gradient(circle, $inner-color, $outer-color);\n}\n\n@mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) {\n  background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);\n}\n// scss-docs-end gradient-mixins\n","// Select\n//\n// Replaces the browser default select with a custom one, mostly pulled from\n// https://primer.github.io/.\n\n.form-select {\n  display: block;\n  width: 100%;\n  padding: $form-select-padding-y $form-select-indicator-padding $form-select-padding-y $form-select-padding-x;\n  -moz-padding-start: subtract($form-select-padding-x, 3px); // See https://github.com/twbs/bootstrap/issues/32636\n  font-family: $form-select-font-family;\n  @include font-size($form-select-font-size);\n  font-weight: $form-select-font-weight;\n  line-height: $form-select-line-height;\n  color: $form-select-color;\n  background-color: $form-select-bg;\n  background-image: escape-svg($form-select-indicator);\n  background-repeat: no-repeat;\n  background-position: $form-select-bg-position;\n  background-size: $form-select-bg-size;\n  border: $form-select-border-width solid $form-select-border-color;\n  @include border-radius($form-select-border-radius, 0);\n  @include box-shadow($form-select-box-shadow);\n  @include transition($form-select-transition);\n  appearance: none;\n\n  &:focus {\n    border-color: $form-select-focus-border-color;\n    outline: 0;\n    @if $enable-shadows {\n      @include box-shadow($form-select-box-shadow, $form-select-focus-box-shadow);\n    } @else {\n      // Avoid using mixin so we can pass custom focus shadow properly\n      box-shadow: $form-select-focus-box-shadow;\n    }\n  }\n\n  &[multiple],\n  &[size]:not([size=\"1\"]) {\n    padding-right: $form-select-padding-x;\n    background-image: none;\n  }\n\n  &:disabled {\n    color: $form-select-disabled-color;\n    background-color: $form-select-disabled-bg;\n    border-color: $form-select-disabled-border-color;\n  }\n\n  // Remove outline from select box in FF\n  &:-moz-focusring {\n    color: transparent;\n    text-shadow: 0 0 0 $form-select-color;\n  }\n}\n\n.form-select-sm {\n  padding-top: $form-select-padding-y-sm;\n  padding-bottom: $form-select-padding-y-sm;\n  padding-left: $form-select-padding-x-sm;\n  @include font-size($form-select-font-size-sm);\n  @include border-radius($form-select-border-radius-sm);\n}\n\n.form-select-lg {\n  padding-top: $form-select-padding-y-lg;\n  padding-bottom: $form-select-padding-y-lg;\n  padding-left: $form-select-padding-x-lg;\n  @include font-size($form-select-font-size-lg);\n  @include border-radius($form-select-border-radius-lg);\n}\n","//\n// Check/radio\n//\n\n.form-check {\n  display: block;\n  min-height: $form-check-min-height;\n  padding-left: $form-check-padding-start;\n  margin-bottom: $form-check-margin-bottom;\n\n  .form-check-input {\n    float: left;\n    margin-left: $form-check-padding-start * -1;\n  }\n}\n\n.form-check-reverse {\n  padding-right: $form-check-padding-start;\n  padding-left: 0;\n  text-align: right;\n\n  .form-check-input {\n    float: right;\n    margin-right: $form-check-padding-start * -1;\n    margin-left: 0;\n  }\n}\n\n.form-check-input {\n  width: $form-check-input-width;\n  height: $form-check-input-width;\n  margin-top: ($line-height-base - $form-check-input-width) * .5; // line-height minus check height\n  vertical-align: top;\n  background-color: $form-check-input-bg;\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: contain;\n  border: $form-check-input-border;\n  appearance: none;\n  print-color-adjust: exact; // Keep themed appearance for print\n  @include transition($form-check-transition);\n\n  &[type=\"checkbox\"] {\n    @include border-radius($form-check-input-border-radius);\n  }\n\n  &[type=\"radio\"] {\n    // stylelint-disable-next-line property-disallowed-list\n    border-radius: $form-check-radio-border-radius;\n  }\n\n  &:active {\n    filter: $form-check-input-active-filter;\n  }\n\n  &:focus {\n    border-color: $form-check-input-focus-border;\n    outline: 0;\n    box-shadow: $form-check-input-focus-box-shadow;\n  }\n\n  &:checked {\n    background-color: $form-check-input-checked-bg-color;\n    border-color: $form-check-input-checked-border-color;\n\n    &[type=\"checkbox\"] {\n      @if $enable-gradients {\n        background-image: escape-svg($form-check-input-checked-bg-image), var(--#{$prefix}gradient);\n      } @else {\n        background-image: escape-svg($form-check-input-checked-bg-image);\n      }\n    }\n\n    &[type=\"radio\"] {\n      @if $enable-gradients {\n        background-image: escape-svg($form-check-radio-checked-bg-image), var(--#{$prefix}gradient);\n      } @else {\n        background-image: escape-svg($form-check-radio-checked-bg-image);\n      }\n    }\n  }\n\n  &[type=\"checkbox\"]:indeterminate {\n    background-color: $form-check-input-indeterminate-bg-color;\n    border-color: $form-check-input-indeterminate-border-color;\n\n    @if $enable-gradients {\n      background-image: escape-svg($form-check-input-indeterminate-bg-image), var(--#{$prefix}gradient);\n    } @else {\n      background-image: escape-svg($form-check-input-indeterminate-bg-image);\n    }\n  }\n\n  &:disabled {\n    pointer-events: none;\n    filter: none;\n    opacity: $form-check-input-disabled-opacity;\n  }\n\n  // Use disabled attribute in addition of :disabled pseudo-class\n  // See: https://github.com/twbs/bootstrap/issues/28247\n  &[disabled],\n  &:disabled {\n    ~ .form-check-label {\n      cursor: default;\n      opacity: $form-check-label-disabled-opacity;\n    }\n  }\n}\n\n.form-check-label {\n  color: $form-check-label-color;\n  cursor: $form-check-label-cursor;\n}\n\n//\n// Switch\n//\n\n.form-switch {\n  padding-left: $form-switch-padding-start;\n\n  .form-check-input {\n    width: $form-switch-width;\n    margin-left: $form-switch-padding-start * -1;\n    background-image: escape-svg($form-switch-bg-image);\n    background-position: left center;\n    @include border-radius($form-switch-border-radius);\n    @include transition($form-switch-transition);\n\n    &:focus {\n      background-image: escape-svg($form-switch-focus-bg-image);\n    }\n\n    &:checked {\n      background-position: $form-switch-checked-bg-position;\n\n      @if $enable-gradients {\n        background-image: escape-svg($form-switch-checked-bg-image), var(--#{$prefix}gradient);\n      } @else {\n        background-image: escape-svg($form-switch-checked-bg-image);\n      }\n    }\n  }\n\n  &.form-check-reverse {\n    padding-right: $form-switch-padding-start;\n    padding-left: 0;\n\n    .form-check-input {\n      margin-right: $form-switch-padding-start * -1;\n      margin-left: 0;\n    }\n  }\n}\n\n.form-check-inline {\n  display: inline-block;\n  margin-right: $form-check-inline-margin-end;\n}\n\n.btn-check {\n  position: absolute;\n  clip: rect(0, 0, 0, 0);\n  pointer-events: none;\n\n  &[disabled],\n  &:disabled {\n    + .btn {\n      pointer-events: none;\n      filter: none;\n      opacity: $form-check-btn-check-disabled-opacity;\n    }\n  }\n}\n","// Range\n//\n// Style range inputs the same across browsers. Vendor-specific rules for pseudo\n// elements cannot be mixed. As such, there are no shared styles for focus or\n// active states on prefixed selectors.\n\n.form-range {\n  width: 100%;\n  height: add($form-range-thumb-height, $form-range-thumb-focus-box-shadow-width * 2);\n  padding: 0; // Need to reset padding\n  background-color: transparent;\n  appearance: none;\n\n  &:focus {\n    outline: 0;\n\n    // Pseudo-elements must be split across multiple rulesets to have an effect.\n    // No box-shadow() mixin for focus accessibility.\n    &::-webkit-slider-thumb { box-shadow: $form-range-thumb-focus-box-shadow; }\n    &::-moz-range-thumb     { box-shadow: $form-range-thumb-focus-box-shadow; }\n  }\n\n  &::-moz-focus-outer {\n    border: 0;\n  }\n\n  &::-webkit-slider-thumb {\n    width: $form-range-thumb-width;\n    height: $form-range-thumb-height;\n    margin-top: ($form-range-track-height - $form-range-thumb-height) * .5; // Webkit specific\n    @include gradient-bg($form-range-thumb-bg);\n    border: $form-range-thumb-border;\n    @include border-radius($form-range-thumb-border-radius);\n    @include box-shadow($form-range-thumb-box-shadow);\n    @include transition($form-range-thumb-transition);\n    appearance: none;\n\n    &:active {\n      @include gradient-bg($form-range-thumb-active-bg);\n    }\n  }\n\n  &::-webkit-slider-runnable-track {\n    width: $form-range-track-width;\n    height: $form-range-track-height;\n    color: transparent; // Why?\n    cursor: $form-range-track-cursor;\n    background-color: $form-range-track-bg;\n    border-color: transparent;\n    @include border-radius($form-range-track-border-radius);\n    @include box-shadow($form-range-track-box-shadow);\n  }\n\n  &::-moz-range-thumb {\n    width: $form-range-thumb-width;\n    height: $form-range-thumb-height;\n    @include gradient-bg($form-range-thumb-bg);\n    border: $form-range-thumb-border;\n    @include border-radius($form-range-thumb-border-radius);\n    @include box-shadow($form-range-thumb-box-shadow);\n    @include transition($form-range-thumb-transition);\n    appearance: none;\n\n    &:active {\n      @include gradient-bg($form-range-thumb-active-bg);\n    }\n  }\n\n  &::-moz-range-track {\n    width: $form-range-track-width;\n    height: $form-range-track-height;\n    color: transparent;\n    cursor: $form-range-track-cursor;\n    background-color: $form-range-track-bg;\n    border-color: transparent; // Firefox specific?\n    @include border-radius($form-range-track-border-radius);\n    @include box-shadow($form-range-track-box-shadow);\n  }\n\n  &:disabled {\n    pointer-events: none;\n\n    &::-webkit-slider-thumb {\n      background-color: $form-range-thumb-disabled-bg;\n    }\n\n    &::-moz-range-thumb {\n      background-color: $form-range-thumb-disabled-bg;\n    }\n  }\n}\n",".form-floating {\n  position: relative;\n\n  > .form-control,\n  > .form-control-plaintext,\n  > .form-select {\n    height: $form-floating-height;\n    line-height: $form-floating-line-height;\n  }\n\n  > label {\n    position: absolute;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%; // allow textareas\n    padding: $form-floating-padding-y $form-floating-padding-x;\n    overflow: hidden;\n    text-align: start;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n    pointer-events: none;\n    border: $input-border-width solid transparent; // Required for aligning label's text with the input as it affects inner box model\n    transform-origin: 0 0;\n    @include transition($form-floating-transition);\n  }\n\n  > .form-control,\n  > .form-control-plaintext {\n    padding: $form-floating-padding-y $form-floating-padding-x;\n\n    &::placeholder {\n      color: transparent;\n    }\n\n    &:focus,\n    &:not(:placeholder-shown) {\n      padding-top: $form-floating-input-padding-t;\n      padding-bottom: $form-floating-input-padding-b;\n    }\n    // Duplicated because `:-webkit-autofill` invalidates other selectors when grouped\n    &:-webkit-autofill {\n      padding-top: $form-floating-input-padding-t;\n      padding-bottom: $form-floating-input-padding-b;\n    }\n  }\n\n  > .form-select {\n    padding-top: $form-floating-input-padding-t;\n    padding-bottom: $form-floating-input-padding-b;\n  }\n\n  > .form-control:focus,\n  > .form-control:not(:placeholder-shown),\n  > .form-control-plaintext,\n  > .form-select {\n    ~ label {\n      opacity: $form-floating-label-opacity;\n      transform: $form-floating-label-transform;\n    }\n  }\n  // Duplicated because `:-webkit-autofill` invalidates other selectors when grouped\n  > .form-control:-webkit-autofill {\n    ~ label {\n      opacity: $form-floating-label-opacity;\n      transform: $form-floating-label-transform;\n    }\n  }\n\n  > .form-control-plaintext {\n    ~ label {\n      border-width: $input-border-width 0; // Required to properly position label text - as explained above\n    }\n  }\n}\n","//\n// Base styles\n//\n\n.input-group {\n  position: relative;\n  display: flex;\n  flex-wrap: wrap; // For form validation feedback\n  align-items: stretch;\n  width: 100%;\n\n  > .form-control,\n  > .form-select,\n  > .form-floating {\n    position: relative; // For focus state's z-index\n    flex: 1 1 auto;\n    width: 1%;\n    min-width: 0; // https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size\n  }\n\n  // Bring the \"active\" form control to the top of surrounding elements\n  > .form-control:focus,\n  > .form-select:focus,\n  > .form-floating:focus-within {\n    z-index: 5;\n  }\n\n  // Ensure buttons are always above inputs for more visually pleasing borders.\n  // This isn't needed for `.input-group-text` since it shares the same border-color\n  // as our inputs.\n  .btn {\n    position: relative;\n    z-index: 2;\n\n    &:focus {\n      z-index: 5;\n    }\n  }\n}\n\n\n// Textual addons\n//\n// Serves as a catch-all element for any text or radio/checkbox input you wish\n// to prepend or append to an input.\n\n.input-group-text {\n  display: flex;\n  align-items: center;\n  padding: $input-group-addon-padding-y $input-group-addon-padding-x;\n  @include font-size($input-font-size); // Match inputs\n  font-weight: $input-group-addon-font-weight;\n  line-height: $input-line-height;\n  color: $input-group-addon-color;\n  text-align: center;\n  white-space: nowrap;\n  background-color: $input-group-addon-bg;\n  border: $input-border-width solid $input-group-addon-border-color;\n  @include border-radius($input-border-radius);\n}\n\n\n// Sizing\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .form-select,\n.input-group-lg > .input-group-text,\n.input-group-lg > .btn {\n  padding: $input-padding-y-lg $input-padding-x-lg;\n  @include font-size($input-font-size-lg);\n  @include border-radius($input-border-radius-lg);\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .form-select,\n.input-group-sm > .input-group-text,\n.input-group-sm > .btn {\n  padding: $input-padding-y-sm $input-padding-x-sm;\n  @include font-size($input-font-size-sm);\n  @include border-radius($input-border-radius-sm);\n}\n\n.input-group-lg > .form-select,\n.input-group-sm > .form-select {\n  padding-right: $form-select-padding-x + $form-select-indicator-padding;\n}\n\n\n// Rounded corners\n//\n// These rulesets must come after the sizing ones to properly override sm and lg\n// border-radius values when extending. They're more specific than we'd like\n// with the `.input-group >` part, but without it, we cannot override the sizing.\n\n// stylelint-disable-next-line no-duplicate-selectors\n.input-group {\n  &:not(.has-validation) {\n    > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),\n    > .dropdown-toggle:nth-last-child(n + 3),\n    > .form-floating:not(:last-child) > .form-control,\n    > .form-floating:not(:last-child) > .form-select {\n      @include border-end-radius(0);\n    }\n  }\n\n  &.has-validation {\n    > :nth-last-child(n + 3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),\n    > .dropdown-toggle:nth-last-child(n + 4),\n    > .form-floating:nth-last-child(n + 3) > .form-control,\n    > .form-floating:nth-last-child(n + 3) > .form-select {\n      @include border-end-radius(0);\n    }\n  }\n\n  $validation-messages: \"\";\n  @each $state in map-keys($form-validation-states) {\n    $validation-messages: $validation-messages + \":not(.\" + unquote($state) + \"-tooltip)\" + \":not(.\" + unquote($state) + \"-feedback)\";\n  }\n\n  > :not(:first-child):not(.dropdown-menu)#{$validation-messages} {\n    margin-left: -$input-border-width;\n    @include border-start-radius(0);\n  }\n\n  > .form-floating:not(:first-child) > .form-control,\n  > .form-floating:not(:first-child) > .form-select {\n    @include border-start-radius(0);\n  }\n}\n","// This mixin uses an `if()` technique to be compatible with Dart Sass\n// See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details\n\n// scss-docs-start form-validation-mixins\n@mixin form-validation-state-selector($state) {\n  @if ($state == \"valid\" or $state == \"invalid\") {\n    .was-validated #{if(&, \"&\", \"\")}:#{$state},\n    #{if(&, \"&\", \"\")}.is-#{$state} {\n      @content;\n    }\n  } @else {\n    #{if(&, \"&\", \"\")}.is-#{$state} {\n      @content;\n    }\n  }\n}\n\n@mixin form-validation-state(\n  $state,\n  $color,\n  $icon,\n  $tooltip-color: color-contrast($color),\n  $tooltip-bg-color: rgba($color, $form-feedback-tooltip-opacity),\n  $focus-box-shadow: 0 0 $input-btn-focus-blur $input-focus-width rgba($color, $input-btn-focus-color-opacity)\n) {\n  .#{$state}-feedback {\n    display: none;\n    width: 100%;\n    margin-top: $form-feedback-margin-top;\n    @include font-size($form-feedback-font-size);\n    font-style: $form-feedback-font-style;\n    color: $color;\n  }\n\n  .#{$state}-tooltip {\n    position: absolute;\n    top: 100%;\n    z-index: 5;\n    display: none;\n    max-width: 100%; // Contain to parent when possible\n    padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;\n    margin-top: .1rem;\n    @include font-size($form-feedback-tooltip-font-size);\n    line-height: $form-feedback-tooltip-line-height;\n    color: $tooltip-color;\n    background-color: $tooltip-bg-color;\n    @include border-radius($form-feedback-tooltip-border-radius);\n  }\n\n  @include form-validation-state-selector($state) {\n    ~ .#{$state}-feedback,\n    ~ .#{$state}-tooltip {\n      display: block;\n    }\n  }\n\n  .form-control {\n    @include form-validation-state-selector($state) {\n      border-color: $color;\n\n      @if $enable-validation-icons {\n        padding-right: $input-height-inner;\n        background-image: escape-svg($icon);\n        background-repeat: no-repeat;\n        background-position: right $input-height-inner-quarter center;\n        background-size: $input-height-inner-half $input-height-inner-half;\n      }\n\n      &:focus {\n        border-color: $color;\n        box-shadow: $focus-box-shadow;\n      }\n    }\n  }\n\n  // stylelint-disable-next-line selector-no-qualifying-type\n  textarea.form-control {\n    @include form-validation-state-selector($state) {\n      @if $enable-validation-icons {\n        padding-right: $input-height-inner;\n        background-position: top $input-height-inner-quarter right $input-height-inner-quarter;\n      }\n    }\n  }\n\n  .form-select {\n    @include form-validation-state-selector($state) {\n      border-color: $color;\n\n      @if $enable-validation-icons {\n        &:not([multiple]):not([size]),\n        &:not([multiple])[size=\"1\"] {\n          padding-right: $form-select-feedback-icon-padding-end;\n          background-image: escape-svg($form-select-indicator), escape-svg($icon);\n          background-position: $form-select-bg-position, $form-select-feedback-icon-position;\n          background-size: $form-select-bg-size, $form-select-feedback-icon-size;\n        }\n      }\n\n      &:focus {\n        border-color: $color;\n        box-shadow: $focus-box-shadow;\n      }\n    }\n  }\n\n  .form-control-color {\n    @include form-validation-state-selector($state) {\n      @if $enable-validation-icons {\n        width: add($form-color-width, $input-height-inner);\n      }\n    }\n  }\n\n  .form-check-input {\n    @include form-validation-state-selector($state) {\n      border-color: $color;\n\n      &:checked {\n        background-color: $color;\n      }\n\n      &:focus {\n        box-shadow: $focus-box-shadow;\n      }\n\n      ~ .form-check-label {\n        color: $color;\n      }\n    }\n  }\n  .form-check-inline .form-check-input {\n    ~ .#{$state}-feedback {\n      margin-left: .5em;\n    }\n  }\n\n  .input-group {\n    > .form-control:not(:focus),\n    > .form-select:not(:focus),\n    > .form-floating:not(:focus-within) {\n      @include form-validation-state-selector($state) {\n        @if $state == \"valid\" {\n          z-index: 3;\n        } @else if $state == \"invalid\" {\n          z-index: 4;\n        }\n      }\n    }\n  }\n}\n// scss-docs-end form-validation-mixins\n","//\n// Base styles\n//\n\n.btn {\n  // scss-docs-start btn-css-vars\n  --#{$prefix}btn-padding-x: #{$btn-padding-x};\n  --#{$prefix}btn-padding-y: #{$btn-padding-y};\n  --#{$prefix}btn-font-family: #{$btn-font-family};\n  @include rfs($btn-font-size, --#{$prefix}btn-font-size);\n  --#{$prefix}btn-font-weight: #{$btn-font-weight};\n  --#{$prefix}btn-line-height: #{$btn-line-height};\n  --#{$prefix}btn-color: #{$body-color};\n  --#{$prefix}btn-bg: transparent;\n  --#{$prefix}btn-border-width: #{$btn-border-width};\n  --#{$prefix}btn-border-color: transparent;\n  --#{$prefix}btn-border-radius: #{$btn-border-radius};\n  --#{$prefix}btn-hover-border-color: transparent;\n  --#{$prefix}btn-box-shadow: #{$btn-box-shadow};\n  --#{$prefix}btn-disabled-opacity: #{$btn-disabled-opacity};\n  --#{$prefix}btn-focus-box-shadow: 0 0 0 #{$btn-focus-width} rgba(var(--#{$prefix}btn-focus-shadow-rgb), .5);\n  // scss-docs-end btn-css-vars\n\n  display: inline-block;\n  padding: var(--#{$prefix}btn-padding-y) var(--#{$prefix}btn-padding-x);\n  font-family: var(--#{$prefix}btn-font-family);\n  @include font-size(var(--#{$prefix}btn-font-size));\n  font-weight: var(--#{$prefix}btn-font-weight);\n  line-height: var(--#{$prefix}btn-line-height);\n  color: var(--#{$prefix}btn-color);\n  text-align: center;\n  text-decoration: if($link-decoration == none, null, none);\n  white-space: $btn-white-space;\n  vertical-align: middle;\n  cursor: if($enable-button-pointers, pointer, null);\n  user-select: none;\n  border: var(--#{$prefix}btn-border-width) solid var(--#{$prefix}btn-border-color);\n  @include border-radius(var(--#{$prefix}btn-border-radius));\n  @include gradient-bg(var(--#{$prefix}btn-bg));\n  @include box-shadow(var(--#{$prefix}btn-box-shadow));\n  @include transition($btn-transition);\n\n  &:hover {\n    color: var(--#{$prefix}btn-hover-color);\n    text-decoration: if($link-hover-decoration == underline, none, null);\n    background-color: var(--#{$prefix}btn-hover-bg);\n    border-color: var(--#{$prefix}btn-hover-border-color);\n  }\n\n  .btn-check + &:hover {\n    // override for the checkbox/radio buttons\n    color: var(--#{$prefix}btn-color);\n    background-color: var(--#{$prefix}btn-bg);\n    border-color: var(--#{$prefix}btn-border-color);\n  }\n\n  &:focus-visible {\n    color: var(--#{$prefix}btn-hover-color);\n    @include gradient-bg(var(--#{$prefix}btn-hover-bg));\n    border-color: var(--#{$prefix}btn-hover-border-color);\n    outline: 0;\n    // Avoid using mixin so we can pass custom focus shadow properly\n    @if $enable-shadows {\n      box-shadow: var(--#{$prefix}btn-box-shadow), var(--#{$prefix}btn-focus-box-shadow);\n    } @else {\n      box-shadow: var(--#{$prefix}btn-focus-box-shadow);\n    }\n  }\n\n  .btn-check:focus-visible + & {\n    border-color: var(--#{$prefix}btn-hover-border-color);\n    outline: 0;\n    // Avoid using mixin so we can pass custom focus shadow properly\n    @if $enable-shadows {\n      box-shadow: var(--#{$prefix}btn-box-shadow), var(--#{$prefix}btn-focus-box-shadow);\n    } @else {\n      box-shadow: var(--#{$prefix}btn-focus-box-shadow);\n    }\n  }\n\n  .btn-check:checked + &,\n  :not(.btn-check) + &:active,\n  &:first-child:active,\n  &.active,\n  &.show {\n    color: var(--#{$prefix}btn-active-color);\n    background-color: var(--#{$prefix}btn-active-bg);\n    // Remove CSS gradients if they're enabled\n    background-image: if($enable-gradients, none, null);\n    border-color: var(--#{$prefix}btn-active-border-color);\n    @include box-shadow(var(--#{$prefix}btn-active-shadow));\n\n    &:focus-visible {\n      // Avoid using mixin so we can pass custom focus shadow properly\n      @if $enable-shadows {\n        box-shadow: var(--#{$prefix}btn-active-shadow), var(--#{$prefix}btn-focus-box-shadow);\n      } @else {\n        box-shadow: var(--#{$prefix}btn-focus-box-shadow);\n      }\n    }\n  }\n\n  &:disabled,\n  &.disabled,\n  fieldset:disabled & {\n    color: var(--#{$prefix}btn-disabled-color);\n    pointer-events: none;\n    background-color: var(--#{$prefix}btn-disabled-bg);\n    background-image: if($enable-gradients, none, null);\n    border-color: var(--#{$prefix}btn-disabled-border-color);\n    opacity: var(--#{$prefix}btn-disabled-opacity);\n    @include box-shadow(none);\n  }\n}\n\n\n//\n// Alternate buttons\n//\n\n// scss-docs-start btn-variant-loops\n@each $color, $value in $theme-colors {\n  .btn-#{$color} {\n    @if $color == \"light\" {\n      @include button-variant(\n        $value,\n        $value,\n        $hover-background: shade-color($value, $btn-hover-bg-shade-amount),\n        $hover-border: shade-color($value, $btn-hover-border-shade-amount),\n        $active-background: shade-color($value, $btn-active-bg-shade-amount),\n        $active-border: shade-color($value, $btn-active-border-shade-amount)\n      );\n    } @else if $color == \"dark\" {\n      @include button-variant(\n        $value,\n        $value,\n        $hover-background: tint-color($value, $btn-hover-bg-tint-amount),\n        $hover-border: tint-color($value, $btn-hover-border-tint-amount),\n        $active-background: tint-color($value, $btn-active-bg-tint-amount),\n        $active-border: tint-color($value, $btn-active-border-tint-amount)\n      );\n    } @else {\n      @include button-variant($value, $value);\n    }\n  }\n}\n\n@each $color, $value in $theme-colors {\n  .btn-outline-#{$color} {\n    @include button-outline-variant($value);\n  }\n}\n// scss-docs-end btn-variant-loops\n\n\n//\n// Link buttons\n//\n\n// Make a button look and behave like a link\n.btn-link {\n  --#{$prefix}btn-font-weight: #{$font-weight-normal};\n  --#{$prefix}btn-color: #{$btn-link-color};\n  --#{$prefix}btn-bg: transparent;\n  --#{$prefix}btn-border-color: transparent;\n  --#{$prefix}btn-hover-color: #{$btn-link-hover-color};\n  --#{$prefix}btn-hover-border-color: transparent;\n  --#{$prefix}btn-active-color: #{$btn-link-hover-color};\n  --#{$prefix}btn-active-border-color: transparent;\n  --#{$prefix}btn-disabled-color: #{$btn-link-disabled-color};\n  --#{$prefix}btn-disabled-border-color: transparent;\n  --#{$prefix}btn-box-shadow: none;\n  --#{$prefix}btn-focus-shadow-rgb: #{to-rgb(mix(color-contrast($primary), $primary, 15%))};\n\n  text-decoration: $link-decoration;\n  @if $enable-gradients {\n    background-image: none;\n  }\n\n  &:hover,\n  &:focus-visible {\n    text-decoration: $link-hover-decoration;\n  }\n\n  &:focus-visible {\n    color: var(--#{$prefix}btn-color);\n  }\n\n  &:hover {\n    color: var(--#{$prefix}btn-hover-color);\n  }\n\n  // No need for an active state here\n}\n\n\n//\n// Button Sizes\n//\n\n.btn-lg {\n  @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-border-radius-lg);\n}\n\n.btn-sm {\n  @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-border-radius-sm);\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n// scss-docs-start btn-variant-mixin\n@mixin button-variant(\n  $background,\n  $border,\n  $color: color-contrast($background),\n  $hover-background: if($color == $color-contrast-light, shade-color($background, $btn-hover-bg-shade-amount), tint-color($background, $btn-hover-bg-tint-amount)),\n  $hover-border: if($color == $color-contrast-light, shade-color($border, $btn-hover-border-shade-amount), tint-color($border, $btn-hover-border-tint-amount)),\n  $hover-color: color-contrast($hover-background),\n  $active-background: if($color == $color-contrast-light, shade-color($background, $btn-active-bg-shade-amount), tint-color($background, $btn-active-bg-tint-amount)),\n  $active-border: if($color == $color-contrast-light, shade-color($border, $btn-active-border-shade-amount), tint-color($border, $btn-active-border-tint-amount)),\n  $active-color: color-contrast($active-background),\n  $disabled-background: $background,\n  $disabled-border: $border,\n  $disabled-color: color-contrast($disabled-background)\n) {\n  --#{$prefix}btn-color: #{$color};\n  --#{$prefix}btn-bg: #{$background};\n  --#{$prefix}btn-border-color: #{$border};\n  --#{$prefix}btn-hover-color: #{$hover-color};\n  --#{$prefix}btn-hover-bg: #{$hover-background};\n  --#{$prefix}btn-hover-border-color: #{$hover-border};\n  --#{$prefix}btn-focus-shadow-rgb: #{to-rgb(mix($color, $border, 15%))};\n  --#{$prefix}btn-active-color: #{$active-color};\n  --#{$prefix}btn-active-bg: #{$active-background};\n  --#{$prefix}btn-active-border-color: #{$active-border};\n  --#{$prefix}btn-active-shadow: #{$btn-active-box-shadow};\n  --#{$prefix}btn-disabled-color: #{$disabled-color};\n  --#{$prefix}btn-disabled-bg: #{$disabled-background};\n  --#{$prefix}btn-disabled-border-color: #{$disabled-border};\n}\n// scss-docs-end btn-variant-mixin\n\n// scss-docs-start btn-outline-variant-mixin\n@mixin button-outline-variant(\n  $color,\n  $color-hover: color-contrast($color),\n  $active-background: $color,\n  $active-border: $color,\n  $active-color: color-contrast($active-background)\n) {\n  --#{$prefix}btn-color: #{$color};\n  --#{$prefix}btn-border-color: #{$color};\n  --#{$prefix}btn-hover-color: #{$color-hover};\n  --#{$prefix}btn-hover-bg: #{$active-background};\n  --#{$prefix}btn-hover-border-color: #{$active-border};\n  --#{$prefix}btn-focus-shadow-rgb: #{to-rgb($color)};\n  --#{$prefix}btn-active-color: #{$active-color};\n  --#{$prefix}btn-active-bg: #{$active-background};\n  --#{$prefix}btn-active-border-color: #{$active-border};\n  --#{$prefix}btn-active-shadow: #{$btn-active-box-shadow};\n  --#{$prefix}btn-disabled-color: #{$color};\n  --#{$prefix}btn-disabled-bg: transparent;\n  --#{$prefix}btn-disabled-border-color: #{$color};\n  --#{$prefix}gradient: none;\n}\n// scss-docs-end btn-outline-variant-mixin\n\n// scss-docs-start btn-size-mixin\n@mixin button-size($padding-y, $padding-x, $font-size, $border-radius) {\n  --#{$prefix}btn-padding-y: #{$padding-y};\n  --#{$prefix}btn-padding-x: #{$padding-x};\n  @include rfs($font-size, --#{$prefix}btn-font-size);\n  --#{$prefix}btn-border-radius: #{$border-radius};\n}\n// scss-docs-end btn-size-mixin\n",".fade {\n  @include transition($transition-fade);\n\n  &:not(.show) {\n    opacity: 0;\n  }\n}\n\n// scss-docs-start collapse-classes\n.collapse {\n  &:not(.show) {\n    display: none;\n  }\n}\n\n.collapsing {\n  height: 0;\n  overflow: hidden;\n  @include transition($transition-collapse);\n\n  &.collapse-horizontal {\n    width: 0;\n    height: auto;\n    @include transition($transition-collapse-width);\n  }\n}\n// scss-docs-end collapse-classes\n","// The dropdown wrapper (`