diff --git a/.gitignore b/.gitignore
index bca4779da699ad0473682f45da716ee20117a004..b2ea7be0b10236568201e0a54fa9b50492441b8e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
 !.gitignore
 .directory
+.vagrant
 .coverage
 *~
 *.aux
@@ -83,3 +84,9 @@ parsetab.py
 *.substvars
 /packaging/debian/mentat-ng/
 /packaging/debian/files
+
+# Ignore custom stuff.
+/conf/install.pip
+/chroot/
+/data/
+/var/
diff --git a/Gruntfile.js b/Gruntfile.js
index 1dea50cd8f84ee3343bd992345b17c0c9980bd7d..27c66dc06ad87bd0d2b33043a7d8e7aad94d7f94 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -219,59 +219,9 @@ module.exports = function(grunt) {
                         cwd: 'node_modules/jquery/dist/',
                         src: './jquery.min.js',
                         dest: '<%= project_paths.web_static_dir %>vendor/jquery/js/'
-                    },
-                    // ----- DataTables.net
-                    {
-                        expand: true,
-                        flatten: true,
-                        cwd: 'node_modules/datatables.net/js/',
-                        src: './*.js',
-                        dest: '<%= project_paths.web_static_dir %>vendor/datatables/js/'
-                    },
-                    {
-                        expand: true,
-                        flatten: true,
-                        cwd: 'node_modules/datatables.net-plugins/',
-                        src: [
-                            './integration/bootstrap/3/dataTables.bootstrap*.js'
-                        ],
-                        dest: '<%= project_paths.web_static_dir %>vendor/datatables/js/'
-                    },
-                    {
-                        expand: true,
-                        flatten: true,
-                        cwd: 'node_modules/datatables.net-plugins/',
-                        src: [
-                            './integration/bootstrap/3/dataTables.bootstrap.css',
-                            './integration/font-awesome/dataTables.fontAwesome.css'
-                        ],
-                        dest: '<%= project_paths.web_static_dir %>vendor/datatables/css/'
-                    },
-                    {
-                        expand: true,
-                        flatten: true,
-                        cwd: 'node_modules/datatables.net-plugins/i18n/',
-                        src: [
-                            './*.lang'
-                        ],
-                        dest: '<%= project_paths.web_static_dir %>vendor/datatables/i18n/'
-                    },
+                    }
                 ]
             }
-        },
-
-        // ---------------------------------------------------------------------
-        // Strip comments from source files
-        comments: {
-            // Strip comments from datatables localization files, otherwise they
-            // are not valid JSON files and table localization does not work.
-            dti18n: {
-                options: {
-                    singleline: true,
-                    multiline: true
-                },
-                src: [ '<%= project_paths.web_static_dir %>vendor/datatables/i18n/*.lang']
-            },
         }
     });
 
@@ -335,7 +285,7 @@ module.exports = function(grunt) {
     grunt.registerTask(
         'webui',
         '(RUN) Build and install web user interface dependencies.',
-        ['clean:webui', 'shell:pybabel_hawat', 'copy:webui', 'comments', 'minify-cldrs']
+        ['clean:webui', 'shell:pybabel_hawat', 'copy:webui', 'minify-cldrs']
     );
     grunt.registerTask(
         'default',
diff --git a/Makefile b/Makefile
index a43e296dd02bfd70b6329e55a45399e8b34f9b00..63dff67f55859711146c7a20191301fb8e6418fa 100644
--- a/Makefile
+++ b/Makefile
@@ -35,7 +35,7 @@ DIR_EVENT_CLASSES = $(shell pwd)/conf/event_classes
 BIN_FILES := $(wildcard bin/mentat-*.py)
 LIB_FILES := $(shell find $(DIR_LIB) -name '*.py' | grep -v 'test_')
 
-VENV_PYTHON ?= python3.7
+VENV_PYTHON ?= python3
 VENV_PATH   ?= venv
 
 PYTHON      = python3
@@ -49,7 +49,7 @@ CURRENT_DIR = $(shell pwd)
 DEV_SERVER      = localhost
 DEV_PORT        = 5000
 DEV_MAIL_SERVER = localhost
-DEV_MAIL_PORT   = 8025
+DEV_MAIL_PORT   = 1025
 
 #
 # Include common makefile configurations.
@@ -118,11 +118,9 @@ help:
 	@echo "  * $(GREEN)deps-postgresql$(NC): configure required PostgreSQL user accounts and databases"
 	@echo "  * $(GREEN)deps-translations$(NC): compile all available translations"
 	@echo ""
-	@echo "  * $(GREEN)run-mentat-dev$(NC): run development version of Mentat system"
 	@echo "  * $(GREEN)run-webui-dev$(NC): run development web server with development configuration on $(DEV_SERVER):$(DEV_PORT)"
-	@echo "  * $(GREEN)run-mailserver-dev$(NC): run development mail server on $(DEV_MAIL_SERVER):$(DEV_MAIL_PORT)"
-	@echo ""
-	@echo "  * $(GREEN)ctrl-mentat-dev COMMAND=cmd$(NC): execute mentat-controller.py with given command $(FAINT)cmd$(NC)"
+	@echo "  * $(GREEN)run-mailserver-sendria$(NC): run development mail server Sendria on $(DEV_MAIL_SERVER):$(DEV_MAIL_PORT)"
+	@echo "  * $(GREEN)run-mailserver-python$(NC): run python-based development mail server on $(DEV_MAIL_SERVER):$(DEV_MAIL_PORT)"
 	@echo ""
 	@echo "  * $(GREEN)clean-pycs$(NC): clean up Python compiled files"
 	@echo "  * $(GREEN)clean-build-docs$(NC): clean up documentation build directories"
@@ -215,9 +213,13 @@ venv: FORCE
 #   - download IP geolocation databases
 #   - install the project in editable mode
 #
-develop: deps install-whl-dev build-webui
+develop: deps build-webui
+
+develop-vagrant: deps-vagrant build-webui
 
-deps: deps-prerequisites deps-lwchroot deps-python deps-python-dev deps-editable deps-webui deps-geoip deps-negistry deps-postgresql translations-compile
+deps: deps-prerequisites deps-lwchroot deps-python-dev deps-python deps-editable deps-webui deps-geoip deps-negistry deps-postgresql translations-compile
+
+deps-vagrant: deps-prerequisites deps-runenv deps-python-dev deps-python deps-editable deps-webui deps-geoip-vagrant deps-negistry-vagrant deps-postgresql translations-compile
 
 clean: clean-pycs clean-build-docs clean-build-python clean-build-debian
 
@@ -272,11 +274,15 @@ deps-prerequisites: FORCE
 	@echo ""
 
 #
-# Install project`s lightweight chroot.
+# Install project`s runtime environment.
 #
 deps-lwchroot: FORCE
 	@echo "\n$(GREEN)*** Creating local lightweight chroot subdirectory structure ***$(NC)\n"
-	@./scripts/lwchroot-init.sh
+	@./conf/scripts/lwchroot-init.sh
+
+deps-runenv: FORCE
+	@echo "\n$(GREEN)*** Creating local runtime environment subdirectory structure ***$(NC)\n"
+	@./conf/scripts/init-runenv.sh
 
 #
 # Install project`s Python dependencies using pip requirements file. The dependencies
@@ -357,12 +363,23 @@ deps-geoip: FORCE
 	@geoipupdate --verbose --database-directory $(shell realpath ./chroot/usr/share/GeoIP)
 	@echo ""
 
+deps-geoip-vagrant: FORCE
+	@echo "\n$(GREEN)*** Installing IP geolocation databases ***$(NC)\n"
+	@mkdir -p $(shell realpath ./data/geoip)
+	@geoipupdate --verbose --database-directory $(shell realpath ./data/geoip)
+	@echo ""
+
 #
 # Fetch and install Negistry whois database.
 #
 deps-negistry: FORCE
 	@echo "\n$(GREEN)*** Installing Negistry whois database ***$(NC)\n"
-	@./scripts/fetch-negistry.sh --stub --target=$(shell realpath ./chroot/var/mentat/whois-negistry.json)
+	@./conf/scripts/fetch-negistry.sh --stub --target=$(shell realpath ./chroot/var/mentat/whois-negistry.json)
+	@echo ""
+
+deps-negistry-vagrant: FORCE
+	@echo "\n$(GREEN)*** Installing Negistry whois database ***$(NC)\n"
+	@./conf/scripts/fetch-negistry.sh --stub --target=/var/mentat/whois-negistry.json
 	@echo ""
 
 #
@@ -370,27 +387,22 @@ deps-negistry: FORCE
 #
 deps-postgresql: FORCE
 	@echo "\n$(GREEN)*** Installing and configuring PostgreSQL database ***$(NC)\n"
-	@./scripts/sqldb-init.sh
+	@./conf/scripts/sqldb-init.sh
 	@echo ""
 
 
 #-------------------------------------------------------------------------------
 
 
-ctrl-mentat-dev:
-	#APP_ROOT_PATH=$(shell realpath ./chroot) mentat-controller.py --command $(COMMAND)
-	mentat-controller.py --command $(COMMAND)
-
-run-mentat-dev:
-	@echo "\n$(GREEN)*** Running development version of Mentat system ***$(NC)\n"
-	#APP_ROOT_PATH=$(shell realpath ./chroot) mentat-controller.py --command start
-	mentat-controller.py --command start
-
 run-webui-dev:
 	@echo "\n$(GREEN)*** Running development web server with development configuration on $(DEV_SERVER):$(DEV_PORT) ***$(NC)\n"
 	#APP_ROOT_PATH=$(shell realpath ./chroot) hawat-cli run --host $(DEV_SERVER) --port $(DEV_PORT)
 	HAWAT_CONFIG_FILE=$(shell realpath ./hawat.local.conf) hawat-cli run --host $(DEV_SERVER) --port $(DEV_PORT)
 
+run-webui-vagrant:
+	@echo "\n$(GREEN)*** Running development web server with development configuration on $(DEV_SERVER):$(DEV_PORT) ***$(NC)\n"
+	FLASK_ENV=development HAWAT_CONFIG_FILE=$(shell realpath ./conf/mentat-hawat-dev.py.conf) hawat-cli run --host "0.0.0.0" --port $(DEV_PORT)
+
 run-mailserver-dev:
 	@echo "\n$(GREEN)*** Running development mail server on $(DEV_MAIL_SERVER):$(DEV_MAIL_PORT) ***$(NC)\n"
 	$(PYTHON) -m smtpd -n -c DebuggingServer $(DEV_MAIL_SERVER):$(DEV_MAIL_PORT)
@@ -466,6 +478,49 @@ presentations: FORCE
 		fi; \
 	done
 
+#-------------------------------------------------------------------------------
+
+data-fetch-config: FORCE
+	@echo "\n$(GREEN)*** Fetching GeoIP configuration file ***$(NC)\n"
+	@mkdir -p ./data
+	@scp mentat-alt:/etc/GeoIP.conf ./data/
+	@echo ""
+
+data-fetch-dbsnapshot: FORCE
+	@echo "\n$(GREEN)*** Fetching latest production database dump ***$(NC)\n"
+	@rm -rf ./data/var
+	@mkdir -p ./data
+	@time scp mentat-alt:/var/mentat/devsnapshots/devsnapshot-latest.tar.gz ./data/
+	@ls -alh ./data/devsnapshot-latest.tar.gz
+	@cd ./data/ && tar -xzvf ./devsnapshot-latest.tar.gz
+	@rm -f ./data/devsnapshot-latest.tar.gz
+	@mv ./data/var/mentat/devsnapshots/devsnapshot ./data/devsnapshot
+	@rm -rf ./data/var
+	@echo ""
+
+data-import-dbsnapshot: FORCE
+	@echo "\n$(GREEN)*** Importing latest production database dump ***$(NC)\n"
+
+	@sudo -u postgres pg_restore --verbose --format=d --dbname=mentat_main ./data/devsnapshot/main
+	@sudo -u postgres psql mentat_main -c "COPY reports_events ($(cat /vagrant/data/devsnapshot/main/reports_events.cols)) FROM stdin;" < ./data/devsnapshot/chunks/reports_events.dat
+	@sudo -u postgres psql mentat_main -c "COPY statistics_events ($(cat /vagrant/data/devsnapshot/main/statistics_events.cols)) FROM stdin;" < ./data/devsnapshot/chunks/statistics_events.dat
+	@sudo -u postgres psql mentat_main -c "COPY changelogs_items ($(cat /vagrant/data/devsnapshot/main/changelogs_items.cols)) FROM stdin;" < ./data/devsnapshot/chunks/changelogs_items.dat
+
+	@sudo -u postgres psql mentat_events -c "COPY events ($(cat /vagrant/data/devsnapshot/events/events.cols)) FROM stdin;" < ./data/devsnapshot/events/events.dat
+	@sudo -u postgres psql mentat_events -c "COPY events_json ($(cat /vagrant/data/devsnapshot/events/events_json.cols)) FROM stdin;" < ./data/devsnapshot/events/events_json.dat
+
+	@echo ""
+	@sudo -u postgres psql mentat_main -e -c "select count(*) as user_count, min(createtime) as from_date, max(createtime) as to_date from users;"
+	@sudo -u postgres psql mentat_main -e -c "select count(*) as group_count, min(createtime) as from_date, max(createtime) as to_date from groups;"
+	@sudo -u postgres psql mentat_main -e -c "select count(*) as filter_count, min(createtime) as from_date, max(createtime) as to_date from filters;"
+	@sudo -u postgres psql mentat_main -e -c "select count(*) as network_count, min(createtime) as from_date, max(createtime) as to_date from networks;"
+	@sudo -u postgres psql mentat_main -e -c "select count(*) as report_count, min(createtime) as from_date, max(createtime) as to_date from reports_events;"
+	@sudo -u postgres psql mentat_main -e -c "select count(*) as statistics_count, min(createtime) as from_date, max(createtime) as to_date from statistics_events;"
+	@sudo -u postgres psql mentat_main -e -c "select count(*) as changelog_count, min(createtime) as from_date, max(createtime) as to_date from changelogs_items;"
+
+	@sudo -u postgres psql mentat_events -e -c "select count(*) as event_count, min(storagetime) as from_date, max(storagetime) as to_date from events;"
+	@sudo -u postgres psql mentat_events -e -c "select count(*) as event_json_count, min(storagetime) as from_date, max(storagetime) as to_date from events_json;"
+	@echo ""
 
 #-------------------------------------------------------------------------------
 
diff --git a/Vagrantfile b/Vagrantfile
new file mode 100644
index 0000000000000000000000000000000000000000..dc762cd0d31c1de941cc2d6b1c8ee7c40201f583
--- /dev/null
+++ b/Vagrantfile
@@ -0,0 +1,45 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+Vagrant.configure('2') do |config|
+  config.vm.hostname = 'mentat-devel.local'
+  config.vm.box = 'debian/contrib-buster64'
+
+  config.vm.provider 'virtualbox' do |v|
+    v.memory = 2048
+    v.cpus = 2
+  end
+
+  # Host port 5000: Flask development server
+  config.vm.network 'forwarded_port', guest: 5000, host: 5000
+  # Host port 4443: Apache web server
+  config.vm.network 'forwarded_port', guest: 443, host: 4443
+  # Host port 1080: Sendria mailtrap service for development
+  config.vm.network 'forwarded_port', guest: 1080, host: 1080
+
+  # Create a private network, which allows host-only access to the machine
+  # using a specific IP.
+  # config.vm.network "private_network", ip: "192.168.33.10"
+
+  # Create a public network, which generally matched to bridged network.
+  # Bridged networks make the machine appear as another physical device on
+  # your network.
+  # config.vm.network "public_network"
+
+  config.vm.provision 'bootstrap_system', type: 'shell', inline: <<-SHELL
+    bash /vagrant/vagrantenv/provisioning/p01_system.sh
+  SHELL
+
+  config.vm.provision 'bootstrap_mentat', type: 'shell', inline: <<-SHELL
+    bash /vagrant/vagrantenv/provisioning/p02_mentat.sh
+  SHELL
+
+  config.vm.provision 'bootstrap_warden', type: 'shell', inline: <<-SHELL
+    bash /vagrant/vagrantenv/provisioning/p03_warden.sh
+  SHELL
+
+  # Automatically connect as 'mentat' user with ssh command.
+  # VAGRANT_COMMAND = ARGV[0]
+  # config.ssh.username = 'mentat' if VAGRANT_COMMAND == 'ssh'
+  config.ssh.extra_args = ['-t', 'cd /vagrant; bash --login']
+end
diff --git a/bin/mentat-hawat-dev.wsgi b/bin/mentat-hawat-dev.wsgi
index bf37c8e7af5d3440b3b69932033f7a6457b2f6f8..2b0ae7de970bf507cc84460853c0313fe070a4f2 100644
--- a/bin/mentat-hawat-dev.wsgi
+++ b/bin/mentat-hawat-dev.wsgi
@@ -5,6 +5,7 @@
 # Use of this source is governed by the MIT license, see LICENSE file.
 #-------------------------------------------------------------------------------
 
+
 from dotenv import load_dotenv
 
 import hawat
@@ -18,4 +19,5 @@ load_dotenv(dotenv_path = '/home/mentat/mentat-ng/.env')
 # capabilities or for purposes of testing. Please refer to the documentation
 # for more information.
 #
+
 application = hawat.create_app()
diff --git a/bin/mentat-hawat-vagrant.wsgi b/bin/mentat-hawat-vagrant.wsgi
new file mode 100644
index 0000000000000000000000000000000000000000..8ae7e84bf25afe806bd09cabfa399ef2d1671bfb
--- /dev/null
+++ b/bin/mentat-hawat-vagrant.wsgi
@@ -0,0 +1,22 @@
+#-------------------------------------------------------------------------------
+# This file is part of Mentat system (https://mentat.cesnet.cz/).
+#
+# Copyright (C) since 2011 CESNET, z.s.p.o (http://www.ces.net/)
+# Use of this source is governed by the MIT license, see LICENSE file.
+#-------------------------------------------------------------------------------
+
+
+import hawat
+
+#
+# Use prepared factory function to create application instance. The factory
+# function takes number of arguments, that can be used to fine tune configuration
+# of the application. This is can be very usefull when extending applications`
+# capabilities or for purposes of testing. Please refer to the documentation
+# for more information.
+#
+application = hawat.create_app_full(
+    config_object = 'hawat.config.DevelopmentConfig',
+    config_file   = '/etc/mentat/mentat-hawat-dev.py.conf',
+    config_env    = 'FLASK_CONFIG_FILE'
+)
diff --git a/conf/apache/maintenance/bootstrap.min.css b/conf/apache/maintenance/bootstrap.min.css
new file mode 100644
index 0000000000000000000000000000000000000000..92e3fe871295c44f8fa58ddc7ac242463f13e6bd
--- /dev/null
+++ b/conf/apache/maintenance/bootstrap.min.css
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v4.3.1 (https://getbootstrap.com/)
+ * Copyright 2011-2019 The Bootstrap Authors
+ * Copyright 2011-2019 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}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{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[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}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.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-lg-auto,.col-md,.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-md-auto,.col-sm,.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-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.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;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;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='%2328a745' d='M2.3 6.73L.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:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.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)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.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") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip{display:block}.form-control-file.is-valid~.valid-feedback,.form-control-file.is-valid~.valid-tooltip,.was-validated .form-control-file:valid~.valid-feedback,.was-validated .form-control-file:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;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;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.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' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);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 .2rem rgba(220,53,69,.25)}.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.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)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip{display:block}.form-control-file.is-invalid~.invalid-feedback,.form-control-file.is-invalid~.invalid-tooltip,.was-validated .form-control-file:invalid~.invalid-feedback,.was-validated .form-control-file:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;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:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{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{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.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}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .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}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .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}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.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:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .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{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;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:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{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")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:calc(1rem + .4rem);padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;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){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;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){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-ms-flexbox;display:flex;-ms-flex:1 0 0%;flex:1 0 0%;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card: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}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion>.card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion>.card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion>.card .card-header{margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;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){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@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:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-sm .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-md .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-lg .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-xl .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush .list-group-item:last-child{margin-bottom:-1px}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{margin-bottom:0;border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #dee2e6;border-bottom-right-radius:.3rem;border-bottom-left-radius:.3rem}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;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:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-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-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:0s .6s opacity}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;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:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive 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-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.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}.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}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;overflow-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}
+/*# sourceMappingURL=bootstrap.min.css.map */
\ No newline at end of file
diff --git a/conf/apache/maintenance/index.html b/conf/apache/maintenance/index.html
index 31906d1bbbf2250fb4378c79a3e52bc4dfa5b5e7..b68c1627d19649041d98f95f4343bfaee81a402c 100644
--- a/conf/apache/maintenance/index.html
+++ b/conf/apache/maintenance/index.html
@@ -3,7 +3,7 @@
     <head>
         <meta charset="utf-8">
             <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
-        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
+        <link rel="stylesheet" href="bootstrap.min.css">
         <title>Mentat - Under maintenance</title>
     </head>
     <body>
diff --git a/conf/apache/site_mentat_vagrant.conf b/conf/apache/site_mentat_vagrant.conf
new file mode 100644
index 0000000000000000000000000000000000000000..bc13ddc4149bb99461de897963ddfd280ed1aa72
--- /dev/null
+++ b/conf/apache/site_mentat_vagrant.conf
@@ -0,0 +1,112 @@
+#-------------------------------------------------------------------------------
+# Example APACHE web server configuration file for HAWAT - development version
+#
+# This is an example configuration for authentication based on SSO service
+# Shibboleth. Please adjust the configuration file according to your needs.
+# In most cases customization of following directives should be enough to
+# get it working properly and quickly:
+#
+#   * ServerAdmin
+#   * ServerName
+#   * SSLCertificateFile
+#   * SSLCertificateKeyFile
+#   * SSLCertificateChainFile
+#
+# This file is part of Mentat system (https://mentat.cesnet.cz/).
+#
+# Copyright (C) since 2011 CESNET, z.s.p.o (http://www.ces.net/)
+# Use of this source is governed by the MIT license, see LICENSE file.
+#-------------------------------------------------------------------------------
+
+WSGIPythonHome /var/mentat/venv
+
+<IfModule mod_ssl.c>
+    <VirtualHost _default_:443>
+        ServerAdmin webmaster@mentat.organization.org
+        ServerName mentat.organization.org
+
+        <IfModule mod_headers.c>
+                # Enforce HTTPS protocol at all times.
+                Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
+                # Deny access to content via HTML iframe.
+                Header always set X-Frame-Options DENY
+        </IfModule>
+
+        DocumentRoot /var/www
+
+        WSGIDaemonProcess hawat user=mentat group=mentat threads=5 python-home=/var/mentat/venv
+        WSGIScriptAlias /mentat /vagrant/bin/mentat-hawat-vagrant.wsgi
+
+        <Location />
+            Require all granted
+        </Location>
+
+        <Directory /vagrant/lib/hawat>
+            WSGIProcessGroup hawat
+            WSGIApplicationGroup %{GLOBAL}
+            Require all granted
+        </Directory>
+
+        <Location /mentat/auth_env/login>
+            AuthType Basic
+            AuthName "Mentat system login"
+            AuthUserFile /etc/mentat/apache/htpasswd.example
+            Require valid-user
+        </Location>
+        <Location /mentat/auth_env/register>
+            AuthType Basic
+            AuthName "Mentat system registration"
+            AuthUserFile /etc/mentat/apache/htpasswd.example
+            Require valid-user
+        </Location>
+
+        RewriteEngine on
+        # Rewrite the path when accessed without a trailing slash.
+        RewriteRule ^/mentat$ /mentat/ [R]
+        # Rewrite webserver root to mentat application.
+        RewriteRule ^/$ /mentat/ [R]
+
+
+        ErrorLog ${APACHE_LOG_DIR}/error.log
+
+        # Possible values: debug, info, notice, warn, error, crit, alert, emerg.
+        LogLevel warn
+
+        CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined
+
+        SSLEngine on
+        #SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
+
+        # Using default self-signed server certificates
+        SSLCertificateFile  /etc/ssl/certs/ssl-cert-snakeoil.pem
+        SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
+
+        # Using custom server certificates
+        #SSLCertificateFile      /etc/ssl/servercert/cert.pem
+        #SSLCertificateKeyFile   /etc/ssl/servercert/key.pem
+        #SSLCertificateChainFile /etc/ssl/servercert/chain.pem
+
+        # Enforce only strong SSL protocols. Generator as of August 2016. This
+        # tool is available at https://mozilla.github.io/server-side-tls/ssl-config-generator/
+        # Resource: https://httpd.apache.org/docs/trunk/ssl/ssl_howto.html#onlystrong
+        SSLProtocol         all -SSLv3 -TLSv1 -TLSv1.1
+        SSLCipherSuite      ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
+        SSLHonorCipherOrder on
+        SSLCompression      off
+        SSLSessionTickets   off
+
+        <FilesMatch "\.(cgi|shtml|phtml|php)$">
+                SSLOptions +StdEnvVars
+        </FilesMatch>
+        <Directory /usr/lib/cgi-bin>
+                SSLOptions +StdEnvVars
+        </Directory>
+
+        BrowserMatch "MSIE [2-6]" \
+                nokeepalive ssl-unclean-shutdown \
+                downgrade-1.0 force-response-1.0
+        # MSIE 7 and newer should be able to use keepalive
+        BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
+
+    </VirtualHost>
+</IfModule>
diff --git a/conf/core/common.json.conf b/conf/core/common.json.conf
index 4ff7a58f3ace1e4ecd045ebcc93704a3b546feec..93493b904eac7fec4da2581c06170e1772bc20ff 100644
--- a/conf/core/common.json.conf
+++ b/conf/core/common.json.conf
@@ -23,6 +23,9 @@
     "mail_return_path": "root",
     "mail_admin": "root",
     "mail_test_mode": true,
+    "mail_dev_mode": false,
+    "mail_dev_server": "localhost",
+    "mail_dev_port": 1025,
 
     #---------------------------------------------------------------------------
     # Common useful piper daemon configurations
diff --git a/conf/core/database.json.conf b/conf/core/database.json.conf
index 17a739c019c80f95a145a33f36ef9eed9bc75390..585cac30054a124267835ff96c943288c14038df 100644
--- a/conf/core/database.json.conf
+++ b/conf/core/database.json.conf
@@ -8,7 +8,9 @@
         # SQL storage connection settings.
         #
         "sqlstorage": {
-            "url": "postgresql://mentat:mentat@localhost/mentat_main",
+            # Connect to the PostgreSQL running on outer host machine.
+            # "url": "postgresql://mentat:mentat@10.0.2.2:5432/mentat_main",
+            "url": "postgresql://mentat:mentat@localhost:5432/mentat_main",
             "echo": false
         },
 
@@ -19,6 +21,8 @@
             "dbname":   "mentat_events",
             "user":     "mentat",
             "password": "mentat",
+            # Connect to the PostgreSQL running on outer host machine.
+            # "host":     "10.0.2.2",
             "host":     "localhost",
             "port":     5432
         }
diff --git a/conf/cron/mentat-backup-py.cron b/conf/cron/mentat-backup-py.cron
index 5b0dc1a605a027156c1ec118c21ebd9649f9f68b..7c17a9d7cd1aba25b99e81882ac636d55f307923 100644
--- a/conf/cron/mentat-backup-py.cron
+++ b/conf/cron/mentat-backup-py.cron
@@ -11,4 +11,4 @@
 #
 
 # Run every day at 5am.
-0 5 * * *   root /usr/local/bin/mentat-backup.py --regular
+0 5 * * *   root /var/mentat/venv/bin/mentat-backup.py --regular
diff --git a/conf/cron/mentat-cleanup-py.cron b/conf/cron/mentat-cleanup-py.cron
index 1bf0428ab8203cbd42c5f7b200e82e6cf92fb543..dfa9e4fa20dd9ba8e94304b81e8d2f077e8ef3c5 100644
--- a/conf/cron/mentat-cleanup-py.cron
+++ b/conf/cron/mentat-cleanup-py.cron
@@ -11,4 +11,4 @@
 #
 
 # Run once in every 6 hours.
-5 */6 * * *   root /usr/local/bin/mentat-cleanup.py --regular
+5 */6 * * *   root /var/mentat/venv/bin/mentat-cleanup.py --regular
diff --git a/conf/cron/mentat-informant-py.cron b/conf/cron/mentat-informant-py.cron
index 63cb4be46a706827355bfe7d8cd75748455fc8d0..6af8a0edada135e52b07e885de539af070649b14 100644
--- a/conf/cron/mentat-informant-py.cron
+++ b/conf/cron/mentat-informant-py.cron
@@ -11,4 +11,4 @@
 #
 
 # Provide periodical informational report emails about overall performance of Mentat system.
-0 7 * * *   mentat /usr/local/bin/mentat-informant.py --regular
+0 7 * * *   mentat /var/mentat/venv/bin/mentat-informant.py --regular
diff --git a/conf/cron/mentat-netmngr-py.cron b/conf/cron/mentat-netmngr-py.cron
index a9b1f3486ebedd5626de097f1f4a3d460b56ebce..bfdb3fa494ed89a3ba56aa4275a93b67579dfc52 100644
--- a/conf/cron/mentat-netmngr-py.cron
+++ b/conf/cron/mentat-netmngr-py.cron
@@ -11,4 +11,4 @@
 #
 
 # Run every day at 6am.
-0 6 * * *   mentat /usr/local/bin/mentat-netmngr.py --regular --command update --whois-file /var/mentat/whois-negistry.json --source negistry
+0 6 * * *   mentat /var/mentat/venv/bin/mentat-netmngr.py --regular --command update --whois-file /var/mentat/whois-negistry.json --source negistry
diff --git a/conf/cron/mentat-precache-py.cron b/conf/cron/mentat-precache-py.cron
index eae5e93e34b06d28ca0726664b64634495b424d3..c7bd2144920fb5b44fab32a5da770f5d793e6a31 100644
--- a/conf/cron/mentat-precache-py.cron
+++ b/conf/cron/mentat-precache-py.cron
@@ -11,4 +11,4 @@
 #
 
 # Run once in every 10 minutes.
-*/10 * * * *   mentat /usr/local/bin/mentat-precache.py --regular
+*/10 * * * *   mentat /var/mentat/venv/bin/mentat-precache.py --regular
diff --git a/conf/cron/mentat-reporter-py.cron b/conf/cron/mentat-reporter-py.cron
index 8ade5deaab5bce3eacdb53fd5ac86e238694599e..026887f0c3a33aad5801355ebe1141afd149f9a4 100644
--- a/conf/cron/mentat-reporter-py.cron
+++ b/conf/cron/mentat-reporter-py.cron
@@ -11,4 +11,4 @@
 #
 
 # Run once in every 10 minutes.
-*/10 * * * *  mentat /usr/local/bin/mentat-reporter.py --regular
+*/10 * * * *  mentat /var/mentat/venv/bin/mentat-reporter.py --regular
diff --git a/conf/cron/mentat-statistician-py.cron b/conf/cron/mentat-statistician-py.cron
index ae90661fd0621497ff74498e7a06c11d5b8afcdb..02daebd5c61c203815f70f012b59bb62976b4017 100644
--- a/conf/cron/mentat-statistician-py.cron
+++ b/conf/cron/mentat-statistician-py.cron
@@ -11,4 +11,4 @@
 #
 
 # Run once in every 5 minutes.
-*/5 * * * *  mentat /usr/local/bin/mentat-statistician.py --regular
+*/5 * * * *  mentat /var/mentat/venv/bin/mentat-statistician.py --regular
diff --git a/conf/cron/mentat-watchdog-events-py.cron b/conf/cron/mentat-watchdog-events-py.cron
index 9a5dc84929141b8aefcbd8ab6f8ca78c39d0e26c..f5974b262e38bfec5898545c9b637aca4d4f31a6 100644
--- a/conf/cron/mentat-watchdog-events-py.cron
+++ b/conf/cron/mentat-watchdog-events-py.cron
@@ -11,4 +11,4 @@
 #
 
 # Run every 15 minutes.
-*/15 * * * *   root /usr/local/bin/mentat-dbmngr.py --command=watchdog-events --regular
+*/15 * * * *   root /var/mentat/venv/bin/mentat-dbmngr.py --command=watchdog-events --regular
diff --git a/conf/cron/test-mentat-ideagen-py.cron b/conf/cron/test-mentat-ideagen-py.cron
index b30f7693c6ec70d64bb54b808dd4dbbf3778096d..3a1e654b67acd2cf1be48a2a761b6312239930dd 100644
--- a/conf/cron/test-mentat-ideagen-py.cron
+++ b/conf/cron/test-mentat-ideagen-py.cron
@@ -11,4 +11,4 @@
 #
 
 # Run once in every 2 minutes.
-*/2 * * * *  mentat /usr/local/bin/mentat-ideagen.py --random-count 20
+*/2 * * * *  mentat /var/mentat/venv/bin/mentat-ideagen.py --random-count 20
diff --git a/conf/mentat-cleanup.py.conf b/conf/mentat-cleanup.py.conf
index a32f55f8b573f9bd0a4b704804c27dc948828249..f9cd99da17bb2907a041f30e919f76810f6da8ca 100644
--- a/conf/mentat-cleanup.py.conf
+++ b/conf/mentat-cleanup.py.conf
@@ -10,10 +10,10 @@
     #---------------------------------------------------------------------------
 
     # Path to database files (for disk usage measurements).
-    #   default: "/var/lib/postgresql/12/main"
+    #   default: "/var/lib/postgresql"
     #   type:    string
     #
-    "db_path": "/var/lib/postgresql/12/main",
+    "db_path": "/var/lib/postgresql",
 
     # Perform simulation, do not remove anything (flag).
     #   default: false
diff --git a/conf/mentat-controller.py.conf b/conf/mentat-controller.py.conf
index 6fa1af338a66a80115d16a0ff164b32060515675..6d9dc24920dbba49b70373b618a99ba97ff461f0 100644
--- a/conf/mentat-controller.py.conf
+++ b/conf/mentat-controller.py.conf
@@ -52,25 +52,7 @@
         },
 
         #
-        # [CHAIN A]: Message inspection module - event validations
-        #
-        {
-            "name": "mentat-inspector-b.py",
-            "exec": "mentat-inspector.py",
-            # Enable multiple instances working the same queue directory
-            #"paralel": true,
-            # In case of paralel mode, you MUST set the required number of instances
-            #"count": 3,
-            "args": [
-                # Enable debug information before daemonization
-                #"--debug"
-                # Force logging level ['debug', 'info', 'warning', 'error', 'critical']
-                #"--log-level=debug"
-            ]
-        },
-
-        #
-        # [CHAIN A|ENTRY]: Message inspection module - event classifications
+        # [CHAIN A|ENTRY]: Message inspection module - event classifications and validations
         #
         {
             "exec": "mentat-inspector.py",
diff --git a/conf/mentat-enricher.py.conf b/conf/mentat-enricher.py.conf
index db7af5777af4415443a1ed71d1decc7d8e385a85..459e5af064cc91ee040f582ad2f10575d0fffd7a 100644
--- a/conf/mentat-enricher.py.conf
+++ b/conf/mentat-enricher.py.conf
@@ -174,8 +174,8 @@
     #"pstate_dump": false,
     #"pstate_log": false,
     #"action": null,
-    #"user": "mentat",
-    #"group": "mentat",
+    "user": "mentat",
+    "group": "mentat",
 
     # This is a dummy last configuration so that the user does not have to fix
     # the commas in the whole configuration file after each change.
diff --git a/conf/mentat-hawat-dev.py.conf b/conf/mentat-hawat-dev.py.conf
new file mode 100644
index 0000000000000000000000000000000000000000..597fb8616c8b362ec704089c2dac404184e6ebfb
--- /dev/null
+++ b/conf/mentat-hawat-dev.py.conf
@@ -0,0 +1,70 @@
+# Force the debug mode.
+DEBUG = True
+
+# Debug template file loading precedence.
+#EXPLAIN_TEMPLATE_LOADING = True
+
+# Enable profiler on debug toolbar. DEBUG must be 'True' for toolbar to be visible.
+#DEBUG_TB_PROFILER_ENABLED = True
+
+# Move the application from webserver root to different location.
+#APPLICATION_ROOT = '/mentat'
+
+# Setup local secret key to be used as cryptographic salt.
+SECRET_KEY = '!!!-CHANGE-ME-ASAP-!!!-local-secret-key'
+
+# Define list of Hawat administrator accounts.
+#EMAIL_ADMINS = ['boss@domain.org', 'admin@domain.org']
+
+# Define list of Hawat administrator accounts, that receive feedback messages for reports.
+#HAWAT_REPORT_FEEDBACK_MAILS = ['admin@domain.org']
+
+# Directories with translations used in Hawat.
+BABEL_DEFAULT_LOCALE    = 'en'
+BABEL_DEFAULT_TIMEZONE  = 'UTC'
+#BABEL_DEFAULT_LOCALE   = 'cs'
+#BABEL_DEFAULT_TIMEZONE = 'Europe/Prague'
+
+# Limit for number of objects for which to automatically fetch additional data services.
+HAWAT_LIMIT_AODS = 20
+
+# Event database search query quota.
+HAWAT_SEARCH_QUERY_QUOTA = 7
+
+MAIL_SERVER = 'localhost'
+MAIL_PORT = 1025
+MAIL_DEFAULT_SENDER = 'mentat@cesnet.cz'
+
+HAWAT_LOG_DEFAULT_LEVEL = 'debug'
+HAWAT_LOG_FILE = '/var/tmp/mentat-hawat.py.log'
+HAWAT_LOG_FILE_LEVEL = 'debug'
+
+ENABLED_BLUEPRINTS = [
+    'vial.blueprints.auth',
+    'vial.blueprints.auth_api',
+    'vial.blueprints.design_bs3',
+    'vial.blueprints.devtools',
+    'vial.blueprints.changelogs',
+
+    'hawat.blueprints.auth_env',
+    'hawat.blueprints.auth_dev',
+    'hawat.blueprints.auth_pwd',
+    'hawat.blueprints.home',
+    'hawat.blueprints.reports',
+    'hawat.blueprints.events',
+    'hawat.blueprints.hosts',
+    'hawat.blueprints.timeline',
+    'hawat.blueprints.dnsr',
+    #'hawat.blueprints.pdnsr',
+    'hawat.blueprints.geoip',
+    #'hawat.blueprints.nerd',
+    'hawat.blueprints.whois',
+    'hawat.blueprints.performance',
+    'hawat.blueprints.status',
+    'hawat.blueprints.dbstatus',
+    'hawat.blueprints.users',
+    'hawat.blueprints.groups',
+    'hawat.blueprints.settings_reporting',
+    'hawat.blueprints.filters',
+    'hawat.blueprints.networks',
+]
diff --git a/conf/mentat-hawat.py.conf b/conf/mentat-hawat.py.conf
index 945804d7ae76cc04c4963d1f83eef61911e31a12..1f42ac269cf1e70ed1ae383f7cf9c14f6698c33a 100644
--- a/conf/mentat-hawat.py.conf
+++ b/conf/mentat-hawat.py.conf
@@ -20,10 +20,10 @@ SECRET_KEY = '!!!-CHANGE-ME-ASAP-!!!-local-secret-key'
 #HAWAT_REPORT_FEEDBACK_MAILS = ['admin@domain.org']
 
 # Directories with translations used in Hawat.
-BABEL_DEFAULT_LOCALE          = 'en'
-BABEL_DEFAULT_TIMEZONE        = 'UTC'
-#BABEL_DEFAULT_LOCALE         = 'cs'
-#BABEL_DEFAULT_TIMEZONE       = 'Europe/Prague'
+BABEL_DEFAULT_LOCALE    = 'en'
+BABEL_DEFAULT_TIMEZONE  = 'UTC'
+#BABEL_DEFAULT_LOCALE   = 'cs'
+#BABEL_DEFAULT_TIMEZONE = 'Europe/Prague'
 
 # Limit for number of objects for which to automatically fetch additional data services.
 HAWAT_LIMIT_AODS = 20
diff --git a/conf/mentat-informant.py.conf b/conf/mentat-informant.py.conf
index f4fb9168459a389dc1f77da895e41ae16fa71e2d..f797357353d5101112a5227a83257ce2c4600f82 100644
--- a/conf/mentat-informant.py.conf
+++ b/conf/mentat-informant.py.conf
@@ -98,6 +98,24 @@
     #
     #"mail_test_mode": false,
 
+    # Send emails in development mode (flag). Will use localhost:1025 as mail server.
+    #   default: false (set in core/common.json.conf)
+    #   type:    bool
+    #
+    #"mail_dev_mode": true,
+
+    # Hostname for development SMTP server.
+    #   default: "localhost" (set in core/common.json.conf)
+    #   type:    string
+    #
+    #"mail_dev_server": "localhost",
+
+    # Port for development SMTP server.
+    #   default: 1025 (set in core/common.json.conf)
+    #   type:    integer
+    #
+    #"mail_dev_port": 1025,
+
     #---------------------------------------------------------------------------
     # Common script configurations
     #---------------------------------------------------------------------------
diff --git a/conf/mentat-inspector-b.py.conf b/conf/mentat-inspector-b.py.conf
deleted file mode 100644
index d5c6929517a0fca5226c6cfae97c6e7074a68fcb..0000000000000000000000000000000000000000
--- a/conf/mentat-inspector-b.py.conf
+++ /dev/null
@@ -1,196 +0,0 @@
-#-------------------------------------------------------------------------------
-#
-# CONFIGURATION FILE FOR MENTAT-INSPECTOR-B.PY MODULE
-#
-# Event validation module.
-#
-# This configuration attempts to perform event validation and basic attribute
-# sanity checks.
-#
-#-------------------------------------------------------------------------------
-
-{
-    #---------------------------------------------------------------------------
-    # Custom daemon configurations
-    #---------------------------------------------------------------------------
-
-    # List of the inspection rules. The rules will be processed in
-    # following order.
-    "inspection_rules":  [
-        {
-            "name": "Check: EventTime > DetectTime",
-            "rule": "exists EventTime and exists DetectTime and EventTime > DetectTime",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "EventTime_gt_DetectTime", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: CeaseTime > DetectTime",
-            "rule": "exists CeaseTime and exists DetectTime and CeaseTime > DetectTime",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "CeaseTime_gt_DetectTime", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: WinStartTime > DetectTime",
-            "rule": "exists WinStartTime and exists DetectTime and WinStartTime > DetectTime",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "WinStartTime_gt_DetectTime", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: DetectTime > CreateTime",
-            "rule": "exists DetectTime and exists CreateTime and DetectTime > CreateTime",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "DetectTime_gt_CreateTime", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: EventTime > CeaseTime",
-            "rule": "exists EventTime and exists CeaseTime and EventTime > CeaseTime",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "EventTime_gt_CeaseTime", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: WinStartTime > WinEndTime",
-            "rule": "exists WinStartTime and exists WinEndTime and WinStartTime > WinEndTime",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "WinStartTime_gt_WinEndTime", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: WinStartTime > EventTime",
-            "rule": "exists WinStartTime and exists EventTime and WinStartTime > EventTime",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "WinStartTime_gt_EventTime", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: Source port and TCP/UDP",
-            "rule": "exists Source.Port and not (Source.Proto in ['tcp', 'udp'])",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "Used_Source_Port_and_missing_Proto", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: Target port and TCP/UDP",
-            "rule": "exists Target.Port and not (Target.Proto in ['tcp', 'udp'])",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "Used_Target_Port_and_missing_Proto", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: DetectTime too old",
-            "rule": "DetectTime < (utcnow() - 3D00:00:00)",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "DetectTime_too_old", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: DetectTime in the future",
-            "rule": "DetectTime > (utcnow() + 01:00:00)",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "DetectTime_in_the_future", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: Category Test only",
-            "rule": "Category is ['Test']",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "Category_Test_only", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: Category Unknown",
-            "rule": "not Category in ['Abusive', 'Abusive.Spam', 'Abusive.Harassment', 'Abusive.Child', 'Abusive.Sexual', 'Abusive.Violence', 'Malware', 'Malware.Virus', 'Malware.Worm', 'Malware.Trojan', 'Malware.Spyware', 'Malware.Dialer', 'Malware.Rootkit', 'Recon', 'Recon.Scanning', 'Recon.Sniffing', 'Recon.SocialEngineering', 'Recon.Searching', 'Attempt', 'Attempt.Exploit', 'Attempt.Login', 'Attempt.NewSignature', 'Intrusion', 'Intrusion.AdminCompromise', 'Intrusion.UserCompromise', 'Intrusion.AppCompromise', 'Intrusion.Botnet', 'Availability', 'Availability.DoS', 'Availability.DDoS', 'Availability.Sabotage', 'Availability.Outage', 'Information', 'Information.UnauthorizedAccess', 'Information.UnauthorizedModification', 'Fraud', 'Fraud.UnauthorizedUsage', 'Fraud.Copyright', 'Fraud.Masquerade', 'Fraud.Phishing', 'Fraud.Scam', 'Vulnerable', 'Vulnerable.Open', 'Vulnerable.Config', 'Anomaly', 'Anomaly.Traffic', 'Anomaly.Connection', 'Anomaly.Protocol', 'Anomaly.System', 'Anomaly.Application', 'Anomaly.Behaviour', 'Other', 'Test']",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "Category_unknown", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: Source Type Unknown",
-            "rule": "exists Source.Type and not Source.Type in ['Proxy', 'OriginMalware', 'OriginSandbox', 'OriginSpam', 'OriginBlacklist', 'Phishing', 'Malware', 'MITM', 'Spam', 'Backscatter', 'Open', 'Poisoned', 'FastFlux', 'Botnet', 'CC', 'Tor', 'Incomplete', 'Anonymised']",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "Source_Type_unknown", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: Target Type Unknown",
-            "rule": "exists Target.Type and not Target.Type in ['Proxy', 'OriginMalware', 'OriginSandbox', 'OriginSpam', 'Phishing', 'Malware', 'MITM', 'Spam', 'Backscatter', 'Open', 'Poisoned', 'FastFlux', 'Botnet', 'CC', 'Tor', 'Incomplete', 'Anonymised']",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "Target_Type_unknown", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: Node Type Unknown",
-            "rule": "exists Node.Type and not Node.Tag in ['Connection', 'Datagram', 'Content', 'Data', 'File', 'Flow', 'Log', 'Protocol', 'Host', 'Network', 'Correlation', 'External', 'Reporting', 'Blackhole', 'Signature', 'Statistical', 'Heuristic', 'Integrity', 'Policy', 'Honeypot', 'Tarpit', 'Recon', 'Monitor']",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "Node_Type_unknown", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: ID suspiciously short",
-            "rule": "strlen(ID) < 8",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "ID_too_short", "unique": true}}
-            ]
-        },
-        {
-            "name": "Check: Description suspiciously short or missing",
-            "rule": "strlen(Description) < 8",
-            "actions": [
-                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "Description_short_or_missing", "unique": true}}
-            ]
-        }
-    ],
-
-    # List of fallback actions, that will be performed with given message
-    # in case it does NOT match any of the inspection rules.
-    "fallback_actions": [],
-
-    #---------------------------------------------------------------------------
-    # Common piper daemon configurations
-    #---------------------------------------------------------------------------
-
-    #"queue_in_dir": "mentat-inspector-b.py",
-    "queue_out_dir": "mentat-enricher.py",
-    #"queue_in_wait": 3,
-    #"queue_out_wait": 10,
-    #"queue_out_limit": 5000,
-
-    #---------------------------------------------------------------------------
-    # Common daemon configurations
-    #---------------------------------------------------------------------------
-
-    #"no_daemon": false,
-    #"chroot-dir": null,
-    #"work_dir": "/",
-    #"pid_file": "/var/mentat/run/mentat-inspector-b.py.pid",
-    #"state_file": "/var/mentat/run/mentat-inspector-b.py.state",
-    #"umask": "0o002",
-    #"stats_interval": 300,
-    #"paralel": false,
-
-    #---------------------------------------------------------------------------
-    # Common application configurations
-    #---------------------------------------------------------------------------
-
-    #"quiet": false,
-    #"verbosity": 0,
-    #"log_file": "/var/mentat/log/mentat-inspector-b.py.log",
-    #"log_level": "info",
-    #"runlog_dir": "/var/mentat/run/mentat-inspector-b.py",
-    #"runlog_dump": false,
-    #"runlog_log": false,
-    #"pstate_file": "/var/mentat/run/mentat-inspector-b.py.pstate",
-    #"pstate_dump": false,
-    #"pstate_log": false,
-    #"action": null,
-    #"user": "mentat",
-    #"group": "mentat",
-
-    # This is a dummy last configuration so that the user does not have to fix
-    # the commas in the whole configuration file after each change.
-    "_dummy_": "_dummy_"
-}
diff --git a/conf/mentat-inspector-c.py.conf b/conf/mentat-inspector-c.py.conf
index 4841a7383dcd593e21c56d27d313dbd763d28a0f..dccd9834a23fd3e13528c9aed42396c666c6494c 100644
--- a/conf/mentat-inspector-c.py.conf
+++ b/conf/mentat-inspector-c.py.conf
@@ -150,8 +150,8 @@
     #"pstate_dump": false,
     #"pstate_log": false,
     #"action": null,
-    #"user": "mentat",
-    #"group": "mentat",
+    "user": "mentat",
+    "group": "mentat",
 
     # This is a dummy last configuration so that the user does not have to fix
     # the commas in the whole configuration file after each change.
diff --git a/conf/mentat-inspector.py.conf b/conf/mentat-inspector.py.conf
index 5a7cd6131dc24bd6a778de8450d1ea7fd1165ce7..6ba0ebc82ceca37faa904a2860706e70b42d7ca0 100644
--- a/conf/mentat-inspector.py.conf
+++ b/conf/mentat-inspector.py.conf
@@ -36,7 +36,7 @@
         },
         {
             "name": "Assign class - attempt-login-ssh",
-            "rule": "Category in ['Attempt.Login'] and (Target.Proto in ['ssh'] or Source.Proto in ['ssh'] or Target.Port in [22])",
+            "rule": "Category in ['Attempt.Login', 'Intrusion.UserCompromise'] and (Target.Proto in ['ssh'] or Source.Proto in ['ssh'] or Target.Port in [22])",
             "actions": [
                 {"action": "tag", "args": {"path": "_Mentat.EventClass", "value": "attempt-login-ssh", "overwrite": false} },
                 {"action": "tag", "args": {"path": "_Mentat.EventSeverity", "value": "medium", "overwrite": false} }
@@ -124,7 +124,7 @@
         },
         {
             "name": "Assign class - vulnerable-config-netbios",
-            "rule": "Category in ['Vulnerable.Config'] and (Source.Proto in ['netbios-ns'] or Source.Port in [137])",
+            "rule": "Category in ['Vulnerable.Config'] and (Source.Proto in ['netbios-ns', 'netbios-dgm', 'netbios-ssn'] or Source.Port in [137, 138, 139])",
             "actions": [
                 {"action": "tag", "args": {"path": "_Mentat.EventClass", "value": "vulnerable-config-netbios", "overwrite": false} },
                 {"action": "tag", "args": {"path": "_Mentat.EventSeverity", "value": "medium", "overwrite": false} }
@@ -201,23 +201,145 @@
                 {"action": "tag", "args": {"path": "_Mentat.EventClass", "value": "recon-scanning", "overwrite": false} },
                 {"action": "tag", "args": {"path": "_Mentat.EventSeverity", "value": "low", "overwrite": false} }
             ]
+        },
+        {
+            "name": "Check: EventTime > DetectTime",
+            "rule": "exists EventTime and exists DetectTime and EventTime > DetectTime",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "EventTime_gt_DetectTime", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: CeaseTime > DetectTime",
+            "rule": "exists CeaseTime and exists DetectTime and CeaseTime > DetectTime",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "CeaseTime_gt_DetectTime", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: WinStartTime > DetectTime",
+            "rule": "exists WinStartTime and exists DetectTime and WinStartTime > DetectTime",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "WinStartTime_gt_DetectTime", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: DetectTime > CreateTime",
+            "rule": "exists DetectTime and exists CreateTime and DetectTime > CreateTime",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "DetectTime_gt_CreateTime", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: EventTime > CeaseTime",
+            "rule": "exists EventTime and exists CeaseTime and EventTime > CeaseTime",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "EventTime_gt_CeaseTime", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: WinStartTime > WinEndTime",
+            "rule": "exists WinStartTime and exists WinEndTime and WinStartTime > WinEndTime",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "WinStartTime_gt_WinEndTime", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: WinStartTime > EventTime",
+            "rule": "exists WinStartTime and exists EventTime and WinStartTime > EventTime",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "WinStartTime_gt_EventTime", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: Source port and TCP/UDP",
+            "rule": "exists Source.Port and not (Source.Proto in ['tcp', 'udp'])",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "Used_Source_Port_and_missing_Proto", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: Target port and TCP/UDP",
+            "rule": "exists Target.Port and not (Target.Proto in ['tcp', 'udp'])",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "Used_Target_Port_and_missing_Proto", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: DetectTime too old",
+            "rule": "DetectTime < (utcnow() - 3D00:00:00)",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "DetectTime_too_old", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: DetectTime in the future",
+            "rule": "DetectTime > (utcnow() + 01:00:00)",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "DetectTime_in_the_future", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: Category Test only",
+            "rule": "Category is ['Test']",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "Category_Test_only", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: Category Unknown",
+            "rule": "not Category in ['Abusive', 'Abusive.Spam', 'Abusive.Harassment', 'Abusive.Child', 'Abusive.Sexual', 'Abusive.Violence', 'Malware', 'Malware.Virus', 'Malware.Worm', 'Malware.Trojan', 'Malware.Spyware', 'Malware.Dialer', 'Malware.Rootkit', 'Recon', 'Recon.Scanning', 'Recon.Sniffing', 'Recon.SocialEngineering', 'Recon.Searching', 'Attempt', 'Attempt.Exploit', 'Attempt.Login', 'Attempt.NewSignature', 'Intrusion', 'Intrusion.AdminCompromise', 'Intrusion.UserCompromise', 'Intrusion.AppCompromise', 'Intrusion.Botnet', 'Availability', 'Availability.DoS', 'Availability.DDoS', 'Availability.Sabotage', 'Availability.Outage', 'Information', 'Information.UnauthorizedAccess', 'Information.UnauthorizedModification', 'Fraud', 'Fraud.UnauthorizedUsage', 'Fraud.Copyright', 'Fraud.Masquerade', 'Fraud.Phishing', 'Fraud.Scam', 'Vulnerable', 'Vulnerable.Open', 'Vulnerable.Config', 'Anomaly', 'Anomaly.Traffic', 'Anomaly.Connection', 'Anomaly.Protocol', 'Anomaly.System', 'Anomaly.Application', 'Anomaly.Behaviour', 'Other', 'Test']",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "Category_unknown", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: Source Type Unknown",
+            "rule": "exists Source.Type and not Source.Type in ['Proxy', 'OriginMalware', 'OriginSandbox', 'OriginSpam', 'OriginBlacklist', 'Phishing', 'Malware', 'MITM', 'Spam', 'Backscatter', 'Open', 'Poisoned', 'FastFlux', 'Botnet', 'CC', 'Tor', 'Incomplete', 'Anonymised']",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "Source_Type_unknown", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: Target Type Unknown",
+            "rule": "exists Target.Type and not Target.Type in ['Proxy', 'OriginMalware', 'OriginSandbox', 'OriginSpam', 'Phishing', 'Malware', 'MITM', 'Spam', 'Backscatter', 'Open', 'Poisoned', 'FastFlux', 'Botnet', 'CC', 'Tor', 'Incomplete', 'Anonymised']",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "Target_Type_unknown", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: Node Type Unknown",
+            "rule": "exists Node.Type and not Node.Tag in ['Connection', 'Datagram', 'Content', 'Data', 'File', 'Flow', 'Log', 'Protocol', 'Host', 'Network', 'Correlation', 'External', 'Reporting', 'Blackhole', 'Signature', 'Statistical', 'Heuristic', 'Integrity', 'Policy', 'Honeypot', 'Tarpit', 'Recon', 'Monitor']",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "Node_Type_unknown", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: ID suspiciously short",
+            "rule": "strlen(ID) < 8",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "ID_too_short", "unique": true}}
+            ]
+        },
+        {
+            "name": "Check: Description suspiciously short or missing",
+            "rule": "strlen(Description) < 8",
+            "actions": [
+                {"action": "tag", "args": {"path": "_Mentat.InspectionErrors[*]", "value": "Description_short_or_missing", "unique": true}}
+            ]
         }
     ],
 
     # List of fallback actions, that will be performed with given message
     # in case it does NOT match any of the inspection rules.
-    "fallback_actions": [
-
-        {"action": "log", "args": {"label":"Fallback rule match, event did not match any of the classification rules"}}
-
-    ],
+    "fallback_actions": [],
 
     #---------------------------------------------------------------------------
     # Common piper daemon configurations
     #---------------------------------------------------------------------------
 
     #"queue_in_dir": "mentat-inspector.py",
-    "queue_out_dir": "mentat-inspector-b.py",
+    "queue_out_dir": "mentat-enricher.py",
     #"queue_in_wait": 3,
     #"queue_out_wait": 10,
     #"queue_out_limit": 5000,
@@ -250,8 +372,8 @@
     #"pstate_dump": false,
     #"pstate_log": false,
     #"action": null,
-    #"user": "mentat",
-    #"group": "mentat",
+    "user": "mentat",
+    "group": "mentat",
 
     # This is a dummy last configuration so that the user does not have to fix
     # the commas in the whole configuration file after each change.
diff --git a/conf/mentat-reporter.py.conf b/conf/mentat-reporter.py.conf
index cdf350fead57b035a72dd6cd154ce74bf9cb4e8f..800b04989bda8556c43023d3939feaccaef19e6b 100644
--- a/conf/mentat-reporter.py.conf
+++ b/conf/mentat-reporter.py.conf
@@ -132,6 +132,24 @@
     #
     #"mail_test_mode": false,
 
+    # Send emails in development mode (flag). Will use localhost:1025 as mail server.
+    #   default: false (set in core/common.json.conf)
+    #   type:    bool
+    #
+    #"mail_dev_mode": true,
+
+    # Hostname for development SMTP server.
+    #   default: "localhost" (set in core/common.json.conf)
+    #   type:    string
+    #
+    #"mail_dev_server": "localhost",
+
+    # Port for development SMTP server.
+    #   default: 1025 (set in core/common.json.conf)
+    #   type:    integer
+    #
+    #"mail_dev_port": 1025,
+
     #---------------------------------------------------------------------------
     # Common script configurations
     #---------------------------------------------------------------------------
diff --git a/conf/mentat-sampler.py.conf b/conf/mentat-sampler.py.conf
index 30dc8aa188a5cc5c840741449a526634b05a165d..036aa9a89c0af5461fbccbc69b5fd3b4aa51a771 100644
--- a/conf/mentat-sampler.py.conf
+++ b/conf/mentat-sampler.py.conf
@@ -55,8 +55,8 @@
     #"pstate_dump": false,
     #"pstate_log": false,
     #"action": null,
-    #"user": "mentat",
-    #"group": "mentat",
+    "user": "mentat",
+    "group": "mentat",
 
     # This is a dummy last configuration so that the user does not have to fix
     # the commas in the whole configuration file after each change.
diff --git a/conf/mentat-storage.py.conf b/conf/mentat-storage.py.conf
index 4e204cc49c0770605369d4bb99caef5c2de47393..77f82857a23f8a3d50b0ec93170522caadc07890 100644
--- a/conf/mentat-storage.py.conf
+++ b/conf/mentat-storage.py.conf
@@ -65,8 +65,8 @@
     #"pstate_dump": false,
     #"pstate_log": false,
     #"action": null,
-    #"user": "mentat",
-    #"group": "mentat",
+    "user": "mentat",
+    "group": "mentat",
 
     # This is a dummy last configuration so that the user does not have to fix
     # the commas in the whole configuration file after each change.
diff --git a/migrations-events/README b/conf/migrations-events/README
similarity index 100%
rename from migrations-events/README
rename to conf/migrations-events/README
diff --git a/migrations-events/alembic.ini b/conf/migrations-events/alembic.ini
similarity index 100%
rename from migrations-events/alembic.ini
rename to conf/migrations-events/alembic.ini
diff --git a/migrations-events/env.py b/conf/migrations-events/env.py
similarity index 100%
rename from migrations-events/env.py
rename to conf/migrations-events/env.py
diff --git a/migrations-events/script.py.mako b/conf/migrations-events/script.py.mako
similarity index 100%
rename from migrations-events/script.py.mako
rename to conf/migrations-events/script.py.mako
diff --git a/migrations-events/versions/.gitplaceholder b/conf/migrations-events/versions/.gitplaceholder
similarity index 100%
rename from migrations-events/versions/.gitplaceholder
rename to conf/migrations-events/versions/.gitplaceholder
diff --git a/migrations-events/versions/0f31c168a714_split_event_column_from_events_to_.py b/conf/migrations-events/versions/0f31c168a714_split_event_column_from_events_to_.py
similarity index 100%
rename from migrations-events/versions/0f31c168a714_split_event_column_from_events_to_.py
rename to conf/migrations-events/versions/0f31c168a714_split_event_column_from_events_to_.py
diff --git a/migrations-events/versions/102ae7b9979f_remove_cesnet__prefix.py b/conf/migrations-events/versions/102ae7b9979f_remove_cesnet__prefix.py
similarity index 79%
rename from migrations-events/versions/102ae7b9979f_remove_cesnet__prefix.py
rename to conf/migrations-events/versions/102ae7b9979f_remove_cesnet__prefix.py
index 9d978b97e23bbbeb57cbf082908744ec28fef186..c4bba5783965e9caf772b91748645c58e307e962 100644
--- a/migrations-events/versions/102ae7b9979f_remove_cesnet__prefix.py
+++ b/conf/migrations-events/versions/102ae7b9979f_remove_cesnet__prefix.py
@@ -47,7 +47,20 @@ def upgrade():  # pylint: disable=locally-disabled,missing-docstring
     op.execute(  # pylint: disable=locally-disabled,no-member
         "ALTER INDEX IF EXISTS enum_cesnet_inspectionerrors_lastseen_idx RENAME TO enum_inspectionerrors_lastseen_idx"
     )
-    
+
+    op.execute(  # pylint: disable=locally-disabled,no-member
+        "ALTER INDEX IF EXISTS enum_cesnet_eventclass_data_key RENAME TO enum_eventclass_data_key"
+    )
+    op.execute(  # pylint: disable=locally-disabled,no-member
+        "ALTER INDEX IF EXISTS enum_cesnet_resolvedabuses_data_key RENAME TO enum_resolvedabuses_data_key"
+    )
+    op.execute(  # pylint: disable=locally-disabled,no-member
+        "ALTER INDEX IF EXISTS enum_cesnet_eventseverity_data_key RENAME TO enum_eventseverity_data_key"
+    )
+    op.execute(  # pylint: disable=locally-disabled,no-member
+        "ALTER INDEX IF EXISTS enum_cesnet_inspectionerrors_data_key RENAME TO enum_inspectionerrors_data_key"
+    )
+
     op.execute(  # pylint: disable=locally-disabled,no-member
         "ALTER TABLE IF EXISTS events RENAME cesnet_resolvedabuses TO resolvedabuses"
     )
@@ -97,6 +110,19 @@ def downgrade():  # pylint: disable=locally-disabled,missing-docstring
         "ALTER INDEX IF EXISTS enum_inspectionerrors_lastseen_idx RENAME TO enum_cesnet_inspectionerrors_lastseen_idx"
     )
 
+    op.execute(  # pylint: disable=locally-disabled,no-member
+        "ALTER INDEX IF EXISTS enum_eventclass_data_key RENAME TO enum_cesnet_eventclass_data_key"
+    )
+    op.execute(  # pylint: disable=locally-disabled,no-member
+        "ALTER INDEX IF EXISTS enum_resolvedabuses_data_key RENAME TO enum_cesnet_resolvedabuses_data_key"
+    )
+    op.execute(  # pylint: disable=locally-disabled,no-member
+        "ALTER INDEX IF EXISTS enum_eventseverity_data_key RENAME TO enum_cesnet_eventseverity_data_key"
+    )
+    op.execute(  # pylint: disable=locally-disabled,no-member
+        "ALTER INDEX IF EXISTS enum_inspectionerrors_data_key RENAME TO enum_cesnet_inspectionerrors_data_key"
+    )
+
     op.execute(  # pylint: disable=locally-disabled,no-member
         "ALTER TABLE IF EXISTS events RENAME resolvedabuses TO cesnet_resolvedabuses"
     )
diff --git a/migrations-events/versions/3fb6b209a5cd_added_support_for_aggregated_address_.py b/conf/migrations-events/versions/3fb6b209a5cd_added_support_for_aggregated_address_.py
similarity index 100%
rename from migrations-events/versions/3fb6b209a5cd_added_support_for_aggregated_address_.py
rename to conf/migrations-events/versions/3fb6b209a5cd_added_support_for_aggregated_address_.py
diff --git a/migrations-events/versions/a9e28583cc3b_make_data_in_cesnet_eventclass_not_.py b/conf/migrations-events/versions/a9e28583cc3b_make_data_in_cesnet_eventclass_not_.py
similarity index 100%
rename from migrations-events/versions/a9e28583cc3b_make_data_in_cesnet_eventclass_not_.py
rename to conf/migrations-events/versions/a9e28583cc3b_make_data_in_cesnet_eventclass_not_.py
diff --git a/conf/requirements-dev.pip b/conf/requirements-dev.pip
index 8d7ea7ff669269ced3c2a258310d2cdce519851b..b24db6d29c90f2df3103c3740ace0deb110c3cf5 100644
--- a/conf/requirements-dev.pip
+++ b/conf/requirements-dev.pip
@@ -4,5 +4,6 @@ nose==1.3.7
 coverage==5.0.4
 pyflakes==2.1.1
 pylint==2.4.4
+sendria==2.2.2
 sphinx==2.4.4
 sphinx-rtd-theme==0.4.3
diff --git a/conf/requirements-latest-dev.pip b/conf/requirements-latest-dev.pip
index 45d3952771089153e735e771fa1ca1d7a7bd565a..a285ea718a457f37cef335ef3a58c057784942a1 100644
--- a/conf/requirements-latest-dev.pip
+++ b/conf/requirements-latest-dev.pip
@@ -4,5 +4,6 @@ nose
 coverage
 pyflakes
 pylint
+sendria
 sphinx
 sphinx-rtd-theme
diff --git a/conf/requirements.pip b/conf/requirements.pip
index fad643400fcb286e7f4bb6c616c4657f0374cf36..38278ffc935fbf1250dc645756c50db7b3dcf651 100644
--- a/conf/requirements.pip
+++ b/conf/requirements.pip
@@ -6,7 +6,7 @@ babel==2.8.0
 wtforms==2.2.1
 sqlalchemy==1.3.15
 alembic==1.4.2
-jinja2==2.10.3
+jinja2==3.0.1
 blinker==1.4
 bsddb3==6.2.7
 flask==1.1.1
diff --git a/scripts/as-dump.sh b/conf/scripts/as-dump.sh
similarity index 100%
rename from scripts/as-dump.sh
rename to conf/scripts/as-dump.sh
diff --git a/scripts/depcheck.py b/conf/scripts/depcheck.py
similarity index 100%
rename from scripts/depcheck.py
rename to conf/scripts/depcheck.py
diff --git a/conf/scripts/devsnapshot.sh b/conf/scripts/devsnapshot.sh
new file mode 100755
index 0000000000000000000000000000000000000000..2f5a5fe760b4a90896f0faa3571a826712b149b2
--- /dev/null
+++ b/conf/scripts/devsnapshot.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+# This file is part of Mentat system (https://mentat.cesnet.cz/).
+#
+# Copyright (C) since 2011 CESNET, z.s.p.o (http://www.ces.net/)
+# Use of this source is governed by the MIT license, see LICENSE file.
+#-------------------------------------------------------------------------------
+
+# Check exit status of any command and fail on error
+set -e
+
+# Source global configurations
+source /etc/default/mentat
+source /etc/mentat/scripts/lib.sh
+
+print_title '<BEGIN> CREATING DEVELOPMENT SNAPSHOT'
+
+BACKUP_DATE_FROM=`date --date="8 days ago" --iso-8601=seconds`
+BACKUP_DIR=/var/mentat/devsnapshots/devsnapshot/main
+mkdir -p $BACKUP_DIR
+chown mentat:mentat $BACKUP_DIR
+cd $BACKUP_DIR
+print_subtitle 'Dumping main tables from metadata database'
+sudo -u mentat pg_dump --clean --create --if-exists --format=d --jobs=3 --dbname=mentat_main --username=mentat --no-password --exclude-table=reports_events --exclude-table=statistics_events --exclude-table=changelogs_items --file=$BACKUP_DIR
+BACKUP_DIR=/var/mentat/devsnapshots/devsnapshot/chunks
+mkdir -p $BACKUP_DIR
+for table_name in reports_events statistics_events changelogs_items
+do
+   print_subtitle "Dumping chunk of table ${table_name} from metadata database"
+   sudo -u mentat psql mentat_main -c "COPY (SELECT * FROM ${table_name} WHERE createtime >= '${BACKUP_DATE_FROM}'::timestamptz) TO stdout" > ${BACKUP_DIR}/${table_name}.dat
+   sudo -u mentat psql mentat_main -c "COPY (SELECT string_agg(data.column_name, ',') FROM (SELECT column_name FROM information_schema.columns WHERE table_name = '${table_name}' ORDER BY ordinal_position) AS data) TO stdout" > ${BACKUP_DIR}/${table_name}.cols
+done
+
+BACKUP_DIR=/var/mentat/devsnapshots/devsnapshot/events
+BACKUP_DATE_FROM_EVENTS=`date --date="1 days ago" --iso-8601=seconds`
+mkdir -p $BACKUP_DIR
+chown mentat:mentat $BACKUP_DIR
+cd $BACKUP_DIR
+
+table_name='events'
+print_subtitle "Dumping chunk of table ${table_name} from event database"
+sudo -u mentat psql mentat_events -c "COPY (SELECT * FROM ${table_name} WHERE storagetime >= '${BACKUP_DATE_FROM_EVENTS}'::timestamptz) TO stdout" > ${BACKUP_DIR}/${table_name}.dat
+sudo -u mentat psql mentat_events -c "COPY (SELECT string_agg(data.column_name, ',') FROM (SELECT column_name FROM information_schema.columns WHERE table_name = '${table_name}' ORDER BY ordinal_position) AS data) TO stdout" > ${BACKUP_DIR}/${table_name}.cols
+
+table_name='events_json'
+print_subtitle "Dumping chunk of table ${table_name} from event database"
+sudo -u mentat psql mentat_events -c "COPY (SELECT events_json.* FROM events_json JOIN events ON events_json.id = events.id WHERE events.storagetime >= '${BACKUP_DATE_FROM_EVENTS}'::timestamptz) TO stdout" > ${BACKUP_DIR}/${table_name}.dat
+sudo -u mentat psql mentat_events -c "COPY (SELECT string_agg(data.column_name, ',') FROM (SELECT column_name FROM information_schema.columns WHERE table_name = '${table_name}' ORDER BY ordinal_position) AS data) TO stdout" > ${BACKUP_DIR}/${table_name}.cols
+
+print_subtitle "Size before packaging:"
+du -csh /var/mentat/devsnapshots/devsnapshot
+print_subtitle "Packaging created database snapshots"
+cd /var/mentat
+SNAPSHOT_FILE_NAME="/var/mentat/devsnapshots/devsnapshot-${BACKUP_DATE_FROM}.tar.gz"
+LATEST_SNAPSHOT_FILE_NAME="/var/mentat/devsnapshots/devsnapshot-latest.tar.gz"
+tar -czPf "${SNAPSHOT_FILE_NAME}" /var/mentat/devsnapshots/devsnapshot/
+rm -f "${LATEST_SNAPSHOT_FILE_NAME}"
+ln -s "${SNAPSHOT_FILE_NAME}" "${LATEST_SNAPSHOT_FILE_NAME}"
+rm -rf /var/mentat/devsnapshots/devsnapshot/
+
+print_subtitle "Created DB snapshot file:"
+ls -alh ${SNAPSHOT_FILE_NAME}
+
+find /var/mentat/devsnapshots/ -type f -mtime +7 -name '*.tar.gz' -delete
+
+print_title '<DONE> CREATING DEVELOPMENT SNAPSHOT'
diff --git a/scripts/fetch-negistry.sh b/conf/scripts/fetch-negistry.sh
similarity index 100%
rename from scripts/fetch-negistry.sh
rename to conf/scripts/fetch-negistry.sh
diff --git a/conf/scripts/init-runenv.sh b/conf/scripts/init-runenv.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f9bb0865619acb7aeaf8b68b5a0af8a23d93677b
--- /dev/null
+++ b/conf/scripts/init-runenv.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+# This file is part of Mentat system (https://mentat.cesnet.cz/).
+#
+# Copyright (C) since 2011 CESNET, z.s.p.o (http://www.ces.net/)
+# Use of this source is governed by the MIT license, see LICENSE file.
+#-------------------------------------------------------------------------------
+
+# Check exit status of any command and fail on error
+set -e
+
+# Source global configurations
+. /etc/default/mentat
+
+# Make sure required directory structure exists and has proper permissions
+mentat_dir_list=(
+    /var/mentat
+    /var/mentat/backups
+    /var/mentat/cache
+    /var/mentat/charts
+    /var/mentat/log
+    /var/mentat/reports
+    /var/mentat/reports/reporter
+    /var/mentat/reports/informant
+    /var/mentat/reports/statistician
+    /var/mentat/rrds
+    /var/mentat/run
+    /var/mentat/spool
+    /var/mentat/spool/mentat-inspector.py
+    /var/mentat/spool/mentat-inspector.py/incoming
+    /var/mentat/spool/mentat-inspector.py/pending
+    /var/mentat/spool/mentat-inspector.py/tmp
+    /var/mentat/spool/mentat-inspector.py/errors
+    /var/mentat/spool/mentat-enricher.py
+    /var/mentat/spool/mentat-enricher.py/incoming
+    /var/mentat/spool/mentat-enricher.py/pending
+    /var/mentat/spool/mentat-enricher.py/tmp
+    /var/mentat/spool/mentat-enricher.py/errors
+    /var/mentat/spool/mentat-storage.py
+    /var/mentat/spool/mentat-storage.py/incoming
+    /var/mentat/spool/mentat-storage.py/pending
+    /var/mentat/spool/mentat-storage.py/tmp
+    /var/mentat/spool/mentat-storage.py/errors
+)
+for d in "${mentat_dir_list[@]}"
+do
+    mkdir -p "$d"
+    chown "$MENTAT_USER" "$d"
+    chgrp "$MENTAT_GROUP" "$d"
+    chmod 775 "$d"
+done
diff --git a/conf/scripts/init-venv.sh b/conf/scripts/init-venv.sh
new file mode 100755
index 0000000000000000000000000000000000000000..7a3bcff88b6d4605cc1dd5e362cc4fe83f935b8f
--- /dev/null
+++ b/conf/scripts/init-venv.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+# This file is part of Mentat system (https://mentat.cesnet.cz/).
+#
+# Copyright (C) since 2011 CESNET, z.s.p.o (http://www.ces.net/)
+# Use of this source is governed by the MIT license, see LICENSE file.
+#-------------------------------------------------------------------------------
+
+# Check exit status of any command and fail on error
+set -e
+
+# Source global configurations
+. /etc/default/mentat
+
+echo -e "\n*** Initializing Python virtual environment for local development ***\n"
+echo "Requested version: $PYTHON_VERSION"
+echo "Path to binary:    `which $PYTHON_VERSION`"
+echo "Path to venv:      $MENTAT_VENV"
+echo ""
+if [ -d $MENTAT_VENV ]; then
+    echo "Virtual environment already exists in '$MENTAT_VENV'.";
+else
+    $PYTHON_VERSION -m venv $MENTAT_VENV;
+    echo "Virtual environment successfully created in '$MENTAT_VENV'.";
+fi
+
+echo -e "\n*** Upgrading 'pip' and 'wheel' within the virtual environment to latest versions ***\n"
+$MENTAT_VENV/bin/pip install --upgrade pip
+$MENTAT_VENV/bin/pip install --upgrade wheel
+echo ""
+echo "Venv path: `. $MENTAT_VENV/bin/activate && python -c 'import sys; print(sys.prefix)'`"
+echo "Python stuff versions:"
+echo ""
+$MENTAT_VENV/bin/python --version
+$MENTAT_VENV/bin/pip --version
+echo ""
+
+echo -e "\nYour development environment is ready in `. $MENTAT_VENV/bin/activate && python -c 'import sys; print(sys.prefix)'`.\n"
+echo -e "Please activate it manually with following command:\n"
+echo -e "\t$MENTAT_VENV/bin/activate\n"
+echo -e "Consider adding following alias to your ~/.bashrc file for easier environment activation:\n"
+echo -e "\talias entervenv='. venv/bin/activate'"
+echo -e "\n!!! Please keep in mind, that all makefile targets except this one ('develop') leave it up to you to activate the correct virtual environment !!!\n"
diff --git a/conf/scripts/lib-mentat.sh b/conf/scripts/lib-mentat.sh
new file mode 100755
index 0000000000000000000000000000000000000000..e65a5c8d51e24e77104a2dd7d626dc4740273c6b
--- /dev/null
+++ b/conf/scripts/lib-mentat.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+# This file is part of Mentat system (https://mentat.cesnet.cz/).
+#
+# Copyright (C) since 2011 CESNET, z.s.p.o (http://www.ces.net/)
+# Use of this source is governed by the MIT license, see LICENSE file.
+#-------------------------------------------------------------------------------
+
+COLCODE_BLACK=$(tput setaf 0)
+COLCODE_RED=$(tput setaf 1)
+COLCODE_GREEN=$(tput setaf 2)
+COLCODE_ORANGE=$(tput setaf 3)
+COLCODE_BLUE=$(tput setaf 4)
+COLCODE_PURPLE=$(tput setaf 5)
+COLCODE_CYAN=$(tput setaf 6)
+COLCODE_WHITE=$(tput setaf 7)
+COLCODE_NC=$(tput sgr0)
+
+COLCODE_B_BLACK=$(tput setab 0)
+COLCODE_B_RED=$(tput setab 1)
+COLCODE_B_GREEN=$(tput setab 2)
+COLCODE_B_ORANGE=$(tput setab 3)
+COLCODE_B_BLUE=$(tput setab 4)
+COLCODE_B_PURPLE=$(tput setab 5)
+COLCODE_B_CYAN=$(tput setab 6)
+COLCODE_B_WHITE=$(tput setab 7)
+
+COLCODE_BOLD=$(tput bold)
+COLCODE_FAINT=$(tput dim)
diff --git a/conf/scripts/lib.sh b/conf/scripts/lib.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f719af5399394663760fdcf5afd050a54124fbc2
--- /dev/null
+++ b/conf/scripts/lib.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+# Bash function library for Mentat system.
+#
+# This file is part of Mentat system (https://mentat.cesnet.cz/).
+#
+# Copyright (C) since 2011 CESNET, z.s.p.o
+# Use of this source is governed by the MIT license, see LICENSE file.
+#-------------------------------------------------------------------------------
+
+function ensure_link {
+	if [ ! -L $2 ] ; then
+		if [ -f $2 ] ; then
+			rm -f $2
+		fi
+		ln -s $1 $2
+	fi
+}
+
+function print_title {
+	echo "================================================================================"
+	echo " $1"
+	echo "================================================================================"
+	date
+}
+
+function print_subtitle {
+	echo "==========> $1"
+}
diff --git a/scripts/lwchroot-init.sh b/conf/scripts/lwchroot-init.sh
similarity index 83%
rename from scripts/lwchroot-init.sh
rename to conf/scripts/lwchroot-init.sh
index 00438e9deb4035930b001114501b49218bd318f3..85144021e9eb1940fc7c081fcabd01bb3b9381fb 100755
--- a/scripts/lwchroot-init.sh
+++ b/conf/scripts/lwchroot-init.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 #-------------------------------------------------------------------------------
-# Utility script for creating local lightweight chroot substructure.
+# Utility script for creating local lightweight chroot directory structure.
 #
 # Copyright (C) since 2011 CESNET, z.s.p.o
 # Use of this source is governed by the MIT license, see LICENSE file.
@@ -31,6 +31,6 @@ if [ ! -f .env ]; then
 	echo "FLASK_CONFIG_FILE=$(realpath ./hawat.local.conf)" >> .env
 fi
 
-if [ ! -L ./migrations-events/.env ]; then
-	ln -s $(realpath ./.env) $(realpath ./migrations-events)/.env;
-fi
\ No newline at end of file
+if [ ! -L ./conf/migrations-events/.env ]; then
+	ln -s $(realpath ./.env) $(realpath ./conf/migrations-events)/.env;
+fi
diff --git a/scripts/maintenance-mode.sh b/conf/scripts/maintenance-mode.sh
similarity index 100%
rename from scripts/maintenance-mode.sh
rename to conf/scripts/maintenance-mode.sh
diff --git a/scripts/mentat-check-alive.sh b/conf/scripts/mentat-check-alive.sh
similarity index 100%
rename from scripts/mentat-check-alive.sh
rename to conf/scripts/mentat-check-alive.sh
diff --git a/scripts/mentat-check-inspectionerrors.sh b/conf/scripts/mentat-check-inspectionerrors.sh
similarity index 100%
rename from scripts/mentat-check-inspectionerrors.sh
rename to conf/scripts/mentat-check-inspectionerrors.sh
diff --git a/scripts/mentat-check-noeventclass.sh b/conf/scripts/mentat-check-noeventclass.sh
similarity index 100%
rename from scripts/mentat-check-noeventclass.sh
rename to conf/scripts/mentat-check-noeventclass.sh
diff --git a/scripts/mentat-check-test.sh b/conf/scripts/mentat-check-test.sh
similarity index 100%
rename from scripts/mentat-check-test.sh
rename to conf/scripts/mentat-check-test.sh
diff --git a/scripts/mentat-check-volatiledescription.sh b/conf/scripts/mentat-check-volatiledescription.sh
similarity index 100%
rename from scripts/mentat-check-volatiledescription.sh
rename to conf/scripts/mentat-check-volatiledescription.sh
diff --git a/scripts/mentat-reports-order.py b/conf/scripts/mentat-reports-order.py
similarity index 100%
rename from scripts/mentat-reports-order.py
rename to conf/scripts/mentat-reports-order.py
diff --git a/scripts/sqldb-init.sh b/conf/scripts/sqldb-init.sh
similarity index 100%
rename from scripts/sqldb-init.sh
rename to conf/scripts/sqldb-init.sh
diff --git a/scripts/sqldb-maintenance.sh b/conf/scripts/sqldb-maintenance.sh
similarity index 100%
rename from scripts/sqldb-maintenance.sh
rename to conf/scripts/sqldb-maintenance.sh
diff --git a/scripts/sqldb-migrate.sh b/conf/scripts/sqldb-migrate.sh
similarity index 100%
rename from scripts/sqldb-migrate.sh
rename to conf/scripts/sqldb-migrate.sh
diff --git a/scripts/sqldb-optimize.sh b/conf/scripts/sqldb-optimize.sh
similarity index 100%
rename from scripts/sqldb-optimize.sh
rename to conf/scripts/sqldb-optimize.sh
diff --git a/conf/templates/reporter/translations/cs/LC_MESSAGES/messages.po b/conf/templates/reporter/translations/cs/LC_MESSAGES/messages.po
index 97ba36332e8bbf5523676b3a1754bed4435013d7..fcafb8f595c23c557276dddd791107ae784ae7c7 100644
--- a/conf/templates/reporter/translations/cs/LC_MESSAGES/messages.po
+++ b/conf/templates/reporter/translations/cs/LC_MESSAGES/messages.po
@@ -3,7 +3,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PROJECT VERSION\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2020-05-13 21:05+0200\n"
+"POT-Creation-Date: 2021-07-15 21:36+0200\n"
 "PO-Revision-Date: 2017-09-22 15:33+0200\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language: cs\n"
@@ -12,7 +12,7 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.7.0\n"
+"Generated-By: Babel 2.8.0\n"
 
 msgid ""
 "This report contains events with LOW severity. Please consider reviewing "
diff --git a/doc/sphinx/_doclib/administration.rst b/doc/sphinx/_doclib/administration.rst
index 3b9bc451e3a2f2fd8c35e89e81304ca7dcd92317..a601784bd09599f4aecb6c6c637f93aa4543dbec 100644
--- a/doc/sphinx/_doclib/administration.rst
+++ b/doc/sphinx/_doclib/administration.rst
@@ -201,8 +201,8 @@ To enable these scripts please configure them to be launched periodically via
     going suddenly offline.
 ``/etc/mentat/scripts/mentat-check-inspectionerrors.sh``
     Query the IDEA event database and detect list of all inspection errors along
-    with example events. One of the :ref:`section-bin-mentat-inspector` modules
-    is by default configured to perform event sanity inspection and logs errors
+    with example events. The :ref:`section-bin-mentat-inspector` module
+    is by default configured to perform event sanity inspection and logging errors
     it finds directly into the event. This script can provide summary of all
     current inspection errors, so you can go and fix malfunctioning detectors.
 ``/etc/mentat/scripts/mentat-check-noeventclass.sh``
@@ -262,7 +262,6 @@ of Mentat modules:
     2018-09-26 13:31:17,981 INFO: Status of configured Mentat real-time modules:
     2018-09-26 13:31:17,981 INFO: Real-time module 'mentat-storage.py': 'Process is running or service is OK (1)'
     2018-09-26 13:31:17,981 INFO: Real-time module 'mentat-enricher.py': 'Process is running or service is OK (1)'
-    2018-09-26 13:31:17,982 INFO: Real-time module 'mentat-inspector-b.py': 'Process is running or service is OK (1)'
     2018-09-26 13:31:17,982 INFO: Real-time module 'mentat-inspector.py': 'Process is running or service is OK (1)'
     2018-09-26 13:31:17,982 INFO: Overall real-time module status: 'All modules are running OK'
     2018-09-26 13:31:17,982 INFO: Status of configured Mentat cronjob modules:
@@ -304,10 +303,6 @@ the following as your NRPE configuration:
     command[check_mentat_inspector_a_pending_dir]=/usr/lib/nagios/plugins/check_file_count -d /var/mentat/spool/mentat-inspector.py/pending -w 100 -c 1000
     command[check_mentat_inspector_a_incoming_dir]=/usr/lib/nagios/plugins/check_file_count -d /var/mentat/spool/mentat-inspector.py/incoming -w 5000 -c 10000
 
-    command[check_mentat_inspector_b_errors_dir]=/usr/lib/nagios/plugins/check_file_count -d /var/mentat/spool/mentat-inspector-b.py/errors -w 100 -c 1000
-    command[check_mentat_inspector_b_pending_dir]=/usr/lib/nagios/plugins/check_file_count -d /var/mentat/spool/mentat-inspector-b.py/pending -w 100 -c 1000
-    command[check_mentat_inspector_b_incoming_dir]=/usr/lib/nagios/plugins/check_file_count -d /var/mentat/spool/mentat-inspector-b.py/incoming -w 5000 -c 10000
-
     command[check_mentat_enricher_errors_dir]=/usr/lib/nagios/plugins/check_file_count -d /var/mentat/spool/mentat-enricher.py/errors -w 100 -c 1000
     command[check_mentat_enricher_pending_dir]=/usr/lib/nagios/plugins/check_file_count -d /var/mentat/spool/mentat-enricher.py/pending -w 100 -c 1000
     command[check_mentat_enricher_incoming_dir]=/usr/lib/nagios/plugins/check_file_count -d /var/mentat/spool/mentat-enricher.py/incoming -w 5000 -c 10000
diff --git a/doc/sphinx/_doclib/development.rst b/doc/sphinx/_doclib/development.rst
index e40883f7320d4b14451b9b2f3a7971dc68e279c4..83888c4c4e4fd1abe4621bf6c1e1c951d869ee34 100644
--- a/doc/sphinx/_doclib/development.rst
+++ b/doc/sphinx/_doclib/development.rst
@@ -114,7 +114,7 @@ procedures:
 
 * Debian dependencies
 
-  * Debian dependencies must be specified in the ``deploy/mentat/ctrl/control.tmpl``
+  * Debian dependencies must be specified in the ``packaging/debian/control``
     file. Please study the `documentation <https://www.debian.org/doc/debian-policy/ch-controlfields.html#binary-package-control-files-debian-control>`__ to correctly
     use Debian dependency system.
 
@@ -612,6 +612,156 @@ target:
 Generated packages will be placed into ``./deploy/mentat/`` subdirectory.
 
 
+Development with Vagrant
+--------------------------------------------------------------------------------
+
+.. note::
+	This is still experimental and work in progress.
+
+You may find it more convenient to use prepared Vagrant box for local development.
+It will save you the hassle of installing all those esential development tools.
+There are only two prerequisites to start the development:
+
+1. `VirtualBox <https://www.virtualbox.org/>`__.
+2. `Vagrant <https://www.vagrantup.com/>`__
+
+Please refer to their respective official documentation on how to install these tools.
+However if you are using Debian-based distro following commands should be what you
+are looking for.
+
+.. code-block:: shell
+
+	curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
+	sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
+	sudo apt update && sudo apt install vagrant
+
+Also please take notice of the following matrix, which describes currently known vorking
+combinations of Vagrant/VirtualBox versions:
+
+.. list-table:: Title
+   :header-rows: 1
+
+   * - Vagrant↓ \ VirtualBox→
+     - 6.1.22
+     - 6.1.26
+   * - 1.8.7
+     - N
+     - N
+   * - 2.2.15
+     - ?
+     - Y
+   * - 2.2.18
+     - ?
+     - Y
+
+Prerequisites
+````````````````````````````````````````````````````````````````````````````````
+
+To make sure the provisioning is performed correctly you must ensure folowing
+prerequisites are installed:
+
+Core developers with access to CESNET`s ``mentat-alt.cesnet.cz`` development server
+can just execute following statement and be done:
+
+.. code-block:: shell
+
+	make data-fetch-config
+
+Other developers must create `MaxMind <https://dev.maxmind.com/geoip/geolite2-free-geolocation-data?lang=en>`__
+account for **GeoLite2** databases GeoLite2-ASN GeoLite2-City GeoLite2-Country. After
+the registration copy the template configuration file and enter your account ID and
+license key:
+
+.. code-block:: shell
+
+	cp ./vagrantenv/GeoIP.conf ./data/
+	vim ./data/GeoIP.conf  # and enter your credential
+
+At this point you are all set to perform standard Vagrant stuff to initialize and
+boot-up your development box and connect to it via SSH:
+
+.. code-block:: shell
+
+	time vagrant up
+	vagrant ssh
+
+After connecting to development machine you will be greeted with banner and some
+initial tips:
+
+.. code-block:: shell
+
+	# Alias to quickly enter work directory:
+	wd # Stands for 'WorkDirectory'
+	# Alias to enable Python virtual environment:
+	ve # Stands for 'VirtualEnvironment'
+
+Basically you should execute both of these aliases in succesion to end up with a prompt like this
+and be ready to work:
+
+.. code-block:: shell
+
+	(venv) !DEV! mentat@mentat-devel /vagrant $
+
+At this point your development machine is ready, however the database is completely empty. There are
+no user accounts, no abuse groups, nothing. You may run Mentat`s backend services, the user interface
+will however not be usable. First option is to populate the database with some basic fixtures:
+
+.. code-block:: shell
+
+	(venv) !DEV! mentat@mentat-devel /vagrant $ mentat-dbmngr.py --command fixtures-add
+
+Second option is to use following command to create first administrator account to start
+completely from scratch:
+
+.. code-block:: shell
+
+	(venv) !DEV! mentat@mentat-devel /vagrant $ mentat-dbmngr.py --command user-add login=superman "fullname=Clark Kent" email=kent@dailyplanet.com "organization=Daily Planet, inc." roles=user,admin
+
+Core developers with access to CESNET`s ``mentat-alt.cesnet.cz`` development server
+can fetch and import database snapshot to work with production-like data. First
+fetch the snapshot by executing following command on your host machine:
+
+.. code-block:: shell
+
+	make data-fetch-dbsnapshot
+
+When that is done execute following command from within the development Vagrant guest box:
+
+.. code-block:: shell
+
+	(venv) !DEV! mentat@mentat-devel /vagrant $ make data-fetch-dbsnapshot
+
+That is about it. When working in Vagrat box please note and keep in mind following:
+
+* By default you will be connected as user ``mentat`` with passwordless sudo privileges.
+* Default built-in user ``vagrant`` comes also with passwordless sudo privileges.
+* Users ``mentat``, ``vagrant`` and ``root`` are all superusers for local PostgreSQL database. SpTo enter database just run ``psql [dbname]``.
+* Intended workflow is to edit the source code in your favorite editor from outside of the box and running Mentat inside.
+* To access web interface from your host machine navigate to `https://localhost:4443 <https://localhost:4443>`__.
+* To access Flask`s development web interface from your host machine you must first launch it inside the guest box with ``make run-webui-dev`` and then navigate to `http://localhost:5000 <http://localhost:5000>`__.
+* For your convenience during development you may use awesome `Sendria <https://github.com/msztolcman/sendria>`__ service to view emails being send. It can be controlled via Systemd and running on startup. Just navigate from your host machine to `http://localhost:1080 <http://localhost:1080>`__.
+* To access real world data there is Warden filer preinstalled on the Vagrant box. Currently you must however perform the Warden registration process.
+
+At this point you are all set to develop Mentat locally without cluttering your personal
+workstation.
+
+.. code-block:: shell
+
+	warden-apply.sh ...
+
+	# Warden filer is not running by default.
+	(venv) !DEV! mentat@mentat-devel /vagrant $ sudo systemctl status warden_filer.service
+
+
+To refresh the development box use following Vagrant commands:
+
+.. code-block:: shell
+
+	vagrant destroy
+	vagrant box update
+	vagrant up
+
+
 Examples
 --------------------------------------------------------------------------------
 
diff --git a/doc/sphinx/_doclib/installation.rst b/doc/sphinx/_doclib/installation.rst
index 1784ef1972dfd4f8b0350fb91c53f91f587e0938..c35a803c8ae7d0e6c64860943402d912844146ec 100644
--- a/doc/sphinx/_doclib/installation.rst
+++ b/doc/sphinx/_doclib/installation.rst
@@ -220,7 +220,7 @@ Install - pip
 
 .. _section-installation-prerequisites-postgresql:
 
-Install - PostgreSQL 12
+Install - PostgreSQL 13
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 * `Documentation <https://www.postgresql.org/docs/>`__
@@ -229,10 +229,10 @@ Install - PostgreSQL 12
 .. code-block:: shell
 
     # Run these commands as root:
-    $ echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list
+    $ echo "deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list
     $ wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
     $ apt update
-    $ apt install postgresql-12 postgresql-12-ip4r postgresql-client-12 postgresql-server-dev-12 libpq-dev pgadmin4
+    $ apt install postgresql-13 postgresql-13-ip4r postgresql-client-13 postgresql-server-dev-13 libpq-dev pgadmin4
 
 
 .. _section-installation-prerequisites-yarn:
diff --git a/doc/sphinx/_doclib/migration.rst b/doc/sphinx/_doclib/migration.rst
index 5ef8ecc4cecf3f15c396a1ea2aa4f587554293ad..e71f52f4f178e947860a012e2e479a696cb1ab0e 100644
--- a/doc/sphinx/_doclib/migration.rst
+++ b/doc/sphinx/_doclib/migration.rst
@@ -182,11 +182,9 @@ sure everything is in order.
     #         processing modules by inspecting the log files. Look for obvious
     #         errors and warnings.
     tail -f /var/mentat/log/mentat-inspector.py.log
-    tail -f /var/mentat/log/mentat-inspector-b.py.log
     tail -f /var/mentat/log/mentat-enricher.py.log
     tail -f /var/mentat/log/mentat-storage.py.log
     grep ERROR /var/mentat/log/mentat-inspector.py.log
-    grep ERROR /var/mentat/log/mentat-inspector-b.py.log
     grep ERROR /var/mentat/log/mentat-enricher.py.log
     grep ERROR /var/mentat/log/mentat-storage.py.log
 
diff --git a/doc/sphinx/_doclib/upgrading.rst b/doc/sphinx/_doclib/upgrading.rst
index bcb8bace17088f85330f16a5609ab728a2035846..e096d82e0d89e4198cf5ab521da7179cb00957e4 100644
--- a/doc/sphinx/_doclib/upgrading.rst
+++ b/doc/sphinx/_doclib/upgrading.rst
@@ -43,13 +43,15 @@ to latest version:
     $ aptitude update
     $ aptitude upgrade
 
+    # Do not forget to review changes in configuration files/structure and
+    # adapt accordingly.
+
     # Step 3: To be safe activate the Python virtual environment for Mentat system:
     $ . /var/mentat/venv/bin/activate
 
     # Step 4: Make sure your database schema is up to date. Please be aware, that
     # these operations may need a lot of time to complete depending on the size
     # of your database:
-    (venv) $ time mentat-dbmngr.py --command init
     (venv) $ time hawat-cli db upgrade
     (venv) $ time /etc/mentat/scripts/sqldb-migrate.sh upgrade head
     (venv) $ time /etc/mentat/scripts/sqldb-optimize.sh
@@ -98,6 +100,21 @@ to quickly turn maintenance mode ON/OFF. Upgrading steps are then much more simp
     $ /etc/mentat/scripts/maintenance-mode.sh off
 
 
+.. _section-upgrading-mentat-2-8:
+
+Upgrading to Mentat 2.8
+--------------------------------------------------------------------------------
+
+* Rulesets for two inspectors have been merged in to one instance. That
+  concerns mentat-inspector.py, mentat-inspector-b.py.conf and
+  mentat-controller.py.conf. If you use vanilla configuration from .deb,
+  package manager will replace the old configuration files with new ones
+  automatically. If you used different installation method or made some
+  modifications into these configuration files, you are encouraged to review
+  the changes and decide whether you want to stay with split configuration
+  or also proceed with the merge.
+
+
 .. _section-upgrading-postgresql-10:
 
 Upgrading PostgreSQL from 10.x to 11.x
@@ -209,6 +226,8 @@ from version ``11.x`` to ``12.x``.
     It can take a lot of time depending on the size of the current database,
     because the data files need to be converted to new format.
 
+    Upgrade to the latest version of Mentat prior to upgrading PostgreSQL.
+
 .. code-block:: shell
 
     # Launch tmux or screen.
@@ -302,15 +321,6 @@ from version ``11.x`` to ``12.x``.
     $ systemctl restart apache2
 
 
-After these steps it is necessary to update following configuration files:
-
-``/etc/mentat/mentat-cleanup.py.conf``
-    Change configuration ``db_path`` to point to correct filesystem location. In default
-    Debian installations it should look something like this:
-
-    ``"db_path": "/var/lib/postgresql/12/main",``
-
-
 .. _section-upgrading-postgresql-12:
 
 Upgrading PostgreSQL from 12.x to 13.x
@@ -325,6 +335,8 @@ from version ``12.x`` to ``13.x``.
     It can take a lot of time depending on the size of the current database,
     because the data files need to be converted to new format.
 
+    Upgrade to the latest version of Mentat prior to upgrading PostgreSQL.
+
 .. code-block:: shell
 
     # Launch tmux or screen.
@@ -353,8 +365,8 @@ from version ``12.x`` to ``13.x``.
     $ psql mentat_events
     DROP INDEX events_detecttime_idx;
     DROP INDEX events_combined_idx;
-    DROP INDEX events_cesnet_storagetime_idx;
-    DROP INDEX events_cesnet_eventseverity_idx;
+    DROP INDEX events_storagetime_idx;
+    DROP INDEX events_eventseverity_idx;
     ALTER TABLE events_json DROP CONSTRAINT events_json_id_fkey;
     ALTER TABLE events_json DROP CONSTRAINT events_json_pkey;
     ALTER TABLE events DROP CONSTRAINT events_pkey;
@@ -422,9 +434,9 @@ from version ``12.x`` to ``13.x``.
     ALTER TABLE events_json ADD PRIMARY KEY (id);
     ALTER TABLE events_json ADD FOREIGN KEY (id) REFERENCES events(id) ON DELETE CASCADE;
     CREATE INDEX IF NOT EXISTS events_detecttime_idx ON events USING BTREE (detecttime);
-    CREATE INDEX IF NOT EXISTS events_cesnet_storagetime_idx ON events USING BTREE (cesnet_storagetime);
-    CREATE INDEX IF NOT EXISTS events_cesnet_eventseverity_idx ON events USING BTREE (cesnet_eventseverity) WHERE cesnet_eventseverity IS NOT NULL;
-    CREATE INDEX IF NOT EXISTS events_combined_idx ON events USING GIN (category, node_name, protocol, source_port, target_port, source_type, target_type, node_type, cesnet_resolvedabuses, cesnet_inspectionerrors);
+    CREATE INDEX IF NOT EXISTS events_storagetime_idx ON events USING BTREE (storagetime);
+    CREATE INDEX IF NOT EXISTS events_eventseverity_idx ON events USING BTREE (eventseverity) WHERE eventseverity IS NOT NULL;
+    CREATE INDEX IF NOT EXISTS events_combined_idx ON events USING GIN (category, node_name, protocol, source_port, target_port, source_type, target_type, node_type, resolvedabuses, inspectionerrors);
     CREATE INDEX IF NOT EXISTS events_ip_aggr_idx ON events USING GIST (source_ip_aggr_ip4, target_ip_aggr_ip4, source_ip_aggr_ip6, target_ip_aggr_ip6);
     CHECKPOINT;
 
@@ -442,15 +454,6 @@ from version ``12.x`` to ``13.x``.
     $ systemctl restart apache2
 
 
-After these steps it is necessary to update following configuration files:
-
-``/etc/mentat/mentat-cleanup.py.conf``
-    Change configuration ``db_path`` to point to correct filesystem location. In default
-    Debian installations it should look something like this:
-
-    ``"db_path": "/var/lib/postgresql/13/main",``
-
-
 .. _section-upgrading-geoip:
 
 Upgrading to authenticated version of GeoIP service
diff --git a/etc/default/mentat b/etc/default/mentat
index cbd000b42cf7c5c957ab30f8fa4036238c46eec2..4d2e4aecbab0fa7b0bca77805579c963fe5a1532 100644
--- a/etc/default/mentat
+++ b/etc/default/mentat
@@ -6,6 +6,10 @@
 # Use of this source is governed by the MIT license, see LICENSE file.
 #-------------------------------------------------------------------------------
 
+PG_MAJOR=13
+NODE_MAJOR="12"
+PYTHON_VERSION="python3"
+
 # Master switch for Debian system scripts.
 MENTAT_IS_ENABLED=yes
 #MENTAT_IS_ENABLED=no
@@ -21,7 +25,7 @@ MENTAT_GROUP=mentat
 # aware, that this variable should be an array.
 MENTAT_CHECKS_MAIL_TO=(root)
 
-# Emails for Mentat system 
+# Emails for Mentat system
 MENTAT_ADMINS_MAIL_TO=(root)
 
 # Base URL for Mentat`s web interface Hawat (with trailing slash).
diff --git a/etc/systemd/mentat.service b/etc/systemd/system/mentat.service
similarity index 100%
rename from etc/systemd/mentat.service
rename to etc/systemd/system/mentat.service
diff --git a/etc/systemd/system/sendria.service b/etc/systemd/system/sendria.service
new file mode 100644
index 0000000000000000000000000000000000000000..16a240bfd52d8c351fde3eeb3b00c3f981991fc4
--- /dev/null
+++ b/etc/systemd/system/sendria.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Sendria - Mailtrap service for development
+After=network.target
+
+[Service]
+Type=simple
+ExecStart=/var/mentat/venv/bin/python -m sendria --db /var/mentat/sendria.db --smtp-ip 127.0.0.1 --smtp-port 1025 --http-ip 0.0.0.0 --http-port 1080 --pidfile /var/run/sendria.pid --log-file /var/log/sendria.log
+Restart=always
+User=mentat
+Group=mentat
+
+[Install]
+WantedBy=multi-user.target
diff --git a/hawat.local.conf b/hawat.local.conf
index 0ccecb0e72ddd436631bae4b000d1ed83349e774..9628b947444be71b2598752c923a6f0c2df547c8 100644
--- a/hawat.local.conf
+++ b/hawat.local.conf
@@ -1,6 +1,6 @@
 SECRET_KEY = 'local-secret-key'
 MAIL_SERVER = 'localhost'
-MAIL_PORT = 8025
+MAIL_PORT = 1025
 MAIL_DEFAULT_SENDER = 'mentat@cesnet.cz'
 HAWAT_LOG_DEFAULT_LEVEL = 'debug'
 HAWAT_LOG_FILE = '/var/tmp/mentat-hawat.py.log'
diff --git a/lib/hawat/__init__.py b/lib/hawat/__init__.py
index aaa46915f558293bd366544a30e4da946336f4fa..54dc7070251cb9bb47b579b644e91e3c17800839 100644
--- a/lib/hawat/__init__.py
+++ b/lib/hawat/__init__.py
@@ -47,7 +47,6 @@ and with the use of following Python3 key libraries:
 The application frontend is built on top of following key libraries:
 
     * `jQuery <http://jquery.com/>`__
-    * `DataTables <https://datatables.net/>`__
     * `bootstrap3 <https://getbootstrap.com/docs/3.3/>`__
     * bootstrap-select
     * `font-awesome <http://fontawesome.io/>`__
@@ -84,6 +83,8 @@ from flask.cli import FlaskGroup
 
 # Expose main application factories to current namespace
 from .app import create_app, create_app_full
+assert create_app
+assert create_app_full
 
 
 @click.group(cls = FlaskGroup, create_app = create_app)
diff --git a/lib/hawat/blueprints/auth_dev/templates/registration/email_user.txt b/lib/hawat/blueprints/auth_dev/templates/registration/email_user.txt
index 0ced73c5a73cfa3033549a742da38274996ee9bf..fd0a4f9051fd07f83c3f0a07324788cd36193f86 100644
--- a/lib/hawat/blueprints/auth_dev/templates/registration/email_user.txt
+++ b/lib/hawat/blueprints/auth_dev/templates/registration/email_user.txt
@@ -24,7 +24,7 @@
 
 {{ _('After successfull activation you will be able to login and start using the system:') | wordwrap }}
 
-	{{ url_for('auth_pwd.login', _external = True ) }}
+	{{ url_for('auth.login', _external = True ) }}
 
 {{ _('Have a nice day') | wordwrap }}
 
diff --git a/lib/hawat/blueprints/auth_dev/test/__init__.py b/lib/hawat/blueprints/auth_dev/test/__init__.py
index 3eda5daa4f2bc6662d7704a340aec332215c8938..31d6fdc0fd9d735b9f4e2504022df12f5b8006a1 100644
--- a/lib/hawat/blueprints/auth_dev/test/__init__.py
+++ b/lib/hawat/blueprints/auth_dev/test/__init__.py
@@ -125,7 +125,7 @@ class AuthDevTestCase(TestRunnerMixin, RegistrationHawatTestCase):
                     'After successfull activation you will be able to login and start using the\n'
                     'system:\n'
                     '\n'
-                    '\thttp://localhost/auth_pwd/login\n'
+                    '\thttp://localhost/auth/login\n'
                     '\n'
                     'Have a nice day\n'
                     '\n'
diff --git a/lib/hawat/blueprints/auth_env/test/__init__.py b/lib/hawat/blueprints/auth_env/test/__init__.py
index 9bf4fd8eb7eb6f8511c040052bfc0660ba70bb47..46a40a5a4e20f0e095bdb2aef9767a3fd6c2a55e 100644
--- a/lib/hawat/blueprints/auth_env/test/__init__.py
+++ b/lib/hawat/blueprints/auth_env/test/__init__.py
@@ -146,7 +146,7 @@ class AuthEnvTestCase(TestRunnerMixin, RegistrationHawatTestCase):
                     'After successfull activation you will be able to login and start using the\n'
                     'system:\n'
                     '\n'
-                    '\thttp://localhost/auth_pwd/login\n'
+                    '\thttp://localhost/auth/login\n'
                     '\n'
                     'Have a nice day\n'
                     '\n'
diff --git a/lib/hawat/blueprints/auth_pwd/templates/registration/email_user.txt b/lib/hawat/blueprints/auth_pwd/templates/registration/email_user.txt
index 0ced73c5a73cfa3033549a742da38274996ee9bf..fd0a4f9051fd07f83c3f0a07324788cd36193f86 100644
--- a/lib/hawat/blueprints/auth_pwd/templates/registration/email_user.txt
+++ b/lib/hawat/blueprints/auth_pwd/templates/registration/email_user.txt
@@ -24,7 +24,7 @@
 
 {{ _('After successfull activation you will be able to login and start using the system:') | wordwrap }}
 
-	{{ url_for('auth_pwd.login', _external = True ) }}
+	{{ url_for('auth.login', _external = True ) }}
 
 {{ _('Have a nice day') | wordwrap }}
 
diff --git a/lib/hawat/blueprints/auth_pwd/test/__init__.py b/lib/hawat/blueprints/auth_pwd/test/__init__.py
index 9117bfed3b971e0a5cf925949ac03c35ddbde081..0883718683e7c375a43b5158f5d02ca219d97883 100644
--- a/lib/hawat/blueprints/auth_pwd/test/__init__.py
+++ b/lib/hawat/blueprints/auth_pwd/test/__init__.py
@@ -142,7 +142,7 @@ class AuthPwdTestCase(TestRunnerMixin, RegistrationHawatTestCase):
                     'After successfull activation you will be able to login and start using the\n'
                     'system:\n'
                     '\n'
-                    '\thttp://localhost/auth_pwd/login\n'
+                    '\thttp://localhost/auth/login\n'
                     '\n'
                     'Have a nice day\n'
                     '\n'
diff --git a/lib/hawat/blueprints/dbstatus/__init__.py b/lib/hawat/blueprints/dbstatus/__init__.py
index 7c23bad18ef0381b892266f52e13378883f72385..068ae959849d70c4f1e66d985ce4add2093fbfee 100644
--- a/lib/hawat/blueprints/dbstatus/__init__.py
+++ b/lib/hawat/blueprints/dbstatus/__init__.py
@@ -341,12 +341,13 @@ class AbstractQueryStopView(PsycopgMixin, RenderableView):  # pylint: disable=lo
         """
         Check the form for *cancel* button press and cancel the action.
         """
-        if getattr(form, vial.const.FORM_ACTION_CANCEL).data:
-            self.flash(
-                flask.Markup(self.get_message_cancel(**kwargs)),
-                vial.const.FLASH_INFO
-            )
-            return self.redirect(default_url = self.get_url_next())
+        if hasattr(form, vial.const.FORM_ACTION_CANCEL):
+            if getattr(form, vial.const.FORM_ACTION_CANCEL).data:
+                self.flash(
+                    flask.Markup(self.get_message_cancel(**kwargs)),
+                    vial.const.FLASH_INFO
+                )
+                return self.redirect(default_url = self.get_url_next())
 
         return None
 
diff --git a/lib/hawat/blueprints/groups/__init__.py b/lib/hawat/blueprints/groups/__init__.py
index 42a2a42bf58e633bad39cd95a35bd37b9b71cd92..008346575ade3c925e6fd7927822ec04884c74f2 100644
--- a/lib/hawat/blueprints/groups/__init__.py
+++ b/lib/hawat/blueprints/groups/__init__.py
@@ -40,7 +40,7 @@ import vial.acl
 import vial.menu
 from vial.utils import URLParamsBuilder
 import vial.blueprints.groups
-from vial.blueprints.groups import BLUEPRINT_NAME, ListView, EnableView, DisableView, DeleteView, AddMemberView, RejectMemberView, RemoveMemberView
+from vial.blueprints.groups import BLUEPRINT_NAME, ListView, EnableView, DisableView, DeleteView, AddMemberView, RejectMemberView, RemoveMemberView, AddManagerView, RemoveManagerView
 import hawat.const
 from hawat.blueprints.groups.forms import AdminCreateGroupForm, AdminUpdateGroupForm,\
     UpdateGroupForm
@@ -80,6 +80,16 @@ class ShowView(vial.blueprints.groups.ShowView):
             'more.remove_membership',
             endpoint = 'users.removemembership'
         )
+        action_menu.add_entry(
+            'endpoint',
+            'more.add_management',
+            endpoint = 'users.addmanagement'
+        )
+        action_menu.add_entry(
+            'endpoint',
+            'more.remove_management',
+            endpoint = 'users.removemanagement'
+        )
         action_menu.add_entry(
             'endpoint',
             'more.enable',
@@ -265,16 +275,18 @@ def get_blueprint():
         url_prefix = '/{}'.format(BLUEPRINT_NAME)
     )
 
-    hbp.register_view_class(ListView,         '/list')
-    hbp.register_view_class(CreateView,       '/create')
-    hbp.register_view_class(ShowView,         '/<int:item_id>/show')
-    hbp.register_view_class(ShowByNameView,   '/<item_id>/show_by_name')
-    hbp.register_view_class(UpdateView,       '/<int:item_id>/update')
-    hbp.register_view_class(AddMemberView,    '/<int:item_id>/add_member/<int:other_id>')
-    hbp.register_view_class(RejectMemberView, '/<int:item_id>/reject_member/<int:other_id>')
-    hbp.register_view_class(RemoveMemberView, '/<int:item_id>/remove_member/<int:other_id>')
-    hbp.register_view_class(EnableView,       '/<int:item_id>/enable')
-    hbp.register_view_class(DisableView,      '/<int:item_id>/disable')
-    hbp.register_view_class(DeleteView,       '/<int:item_id>/delete')
+    hbp.register_view_class(ListView,          '/list')
+    hbp.register_view_class(CreateView,        '/create')
+    hbp.register_view_class(ShowView,          '/<int:item_id>/show')
+    hbp.register_view_class(ShowByNameView,    '/<item_id>/show_by_name')
+    hbp.register_view_class(UpdateView,        '/<int:item_id>/update')
+    hbp.register_view_class(AddMemberView,     '/<int:item_id>/add_member/<int:other_id>')
+    hbp.register_view_class(RejectMemberView,  '/<int:item_id>/reject_member/<int:other_id>')
+    hbp.register_view_class(RemoveMemberView,  '/<int:item_id>/remove_member/<int:other_id>')
+    hbp.register_view_class(AddManagerView,    '/<int:item_id>/add_manager/<int:other_id>')
+    hbp.register_view_class(RemoveManagerView, '/<int:item_id>/remove_manager/<int:other_id>')
+    hbp.register_view_class(EnableView,        '/<int:item_id>/enable')
+    hbp.register_view_class(DisableView,       '/<int:item_id>/disable')
+    hbp.register_view_class(DeleteView,        '/<int:item_id>/delete')
 
     return hbp
diff --git a/lib/hawat/blueprints/groups/forms.py b/lib/hawat/blueprints/groups/forms.py
index 901fd30c83f79ee853d6c85752f2a01ba1e6081c..865a31da20d94b05e379dd403d144eaaf30400dd 100644
--- a/lib/hawat/blueprints/groups/forms.py
+++ b/lib/hawat/blueprints/groups/forms.py
@@ -110,19 +110,6 @@ class BaseGroupForm(vial.forms.BaseItemForm):
         ],
         description = lazy_gettext('Origin of the group record, whether it was added manually, or via some automated mechanism from data from some third party system.')
     )
-    managed = wtforms.RadioField(
-        lazy_gettext('Self management:'),
-        validators = [
-            wtforms.validators.InputRequired(),
-        ],
-        choices = [
-            (True,  lazy_gettext('Enabled')),
-            (False, lazy_gettext('Disabled'))
-        ],
-        filters = [vial.forms.str_to_bool],
-        coerce = vial.forms.str_to_bool,
-        description = lazy_gettext('Boolean flag whether the group is self managed by group managers. When enabled group managers are expected to take care of the group management tasks and they get notifications about important events like group membership requests, etc.')
-    )
     members = QuerySelectMultipleField(
         lazy_gettext('Members:'),
         query_factory = get_available_users,
diff --git a/lib/hawat/blueprints/groups/templates/groups/addmanager.html b/lib/hawat/blueprints/groups/templates/groups/addmanager.html
new file mode 100644
index 0000000000000000000000000000000000000000..cbffed2b79dff9d4934493eb1264dc88564ed9e1
--- /dev/null
+++ b/lib/hawat/blueprints/groups/templates/groups/addmanager.html
@@ -0,0 +1,16 @@
+{%- extends "_layout_confirmation.html" %}
+
+{%- block modalcontent %}
+                                <p>
+                                    {{ _('Are you really sure you want to add user') }}
+                                </p>
+                                <p class="lead text-center">
+                                    {{ other_name }}
+                                </p>
+                                <p>
+                                    {{ _('as manager to abuse group') }}
+                                </p>
+                                <p class="lead text-center">
+                                    {{ item_name }}
+                                </p>
+{% endblock modalcontent %}
diff --git a/lib/hawat/blueprints/groups/templates/groups/creatupdate.html b/lib/hawat/blueprints/groups/templates/groups/creatupdate.html
index 3acbcfd2b566847cd210d8c587ed4ba154b42a3a..a08a12bd09fd0b63b775be2111fb05bb305d5272 100644
--- a/lib/hawat/blueprints/groups/templates/groups/creatupdate.html
+++ b/lib/hawat/blueprints/groups/templates/groups/creatupdate.html
@@ -19,9 +19,6 @@
     {%- if form | attr('enabled') %}
                                 {{ macros_form.render_form_item_radiobutton(form.enabled) }}
     {%- endif %}
-    {%- if form | attr('managed') %}
-                                {{ macros_form.render_form_item_radiobutton(form.managed) }}
-    {%- endif %}
     {%- if form | attr('members') %}
                                 {{ macros_form.render_form_item_select(form.members) }}
     {%- endif %}
diff --git a/lib/hawat/blueprints/groups/templates/groups/removemanager.html b/lib/hawat/blueprints/groups/templates/groups/removemanager.html
new file mode 100644
index 0000000000000000000000000000000000000000..073516835b7f627690e2b9aded21b63710d1b5a5
--- /dev/null
+++ b/lib/hawat/blueprints/groups/templates/groups/removemanager.html
@@ -0,0 +1,16 @@
+{%- extends "_layout_confirmation.html" %}
+
+{%- block modalcontent %}
+                                <p>
+                                    {{ _('Are you really sure you want to remove user') }}
+                                </p>
+                                <p class="lead text-center">
+                                    {{ other_name }}
+                                </p>
+                                <p>
+                                    {{ _('as manager from abuse group') }}
+                                </p>
+                                <p class="lead text-center">
+                                    {{ item_name }}
+                                </p>
+{% endblock modalcontent %}
diff --git a/lib/hawat/blueprints/groups/templates/groups/show.html b/lib/hawat/blueprints/groups/templates/groups/show.html
index ac2087488ccf8af203073fc6d6b1e8d2aee97906..84ba2992181bd33a4a3435630df4a1577e808fac 100644
--- a/lib/hawat/blueprints/groups/templates/groups/show.html
+++ b/lib/hawat/blueprints/groups/templates/groups/show.html
@@ -86,14 +86,6 @@
                                                     {{ macros_site.render_label_item_state(item.enabled, True) }}
                                                 </td>
                                             </tr>
-                                            <tr>
-                                                <th>
-                                                    {{ _('Self management') }}:
-                                                </th>
-                                                <td>
-                                                    {{ macros_site.render_label_item_state(item.managed, True) }}
-                                                </td>
-                                            </tr>
                                             <tr>
                                                 <th>
                                                     {{ _('Reporting settings') }}:
diff --git a/lib/hawat/blueprints/groups/test/__init__.py b/lib/hawat/blueprints/groups/test/__init__.py
index c13b8159fcb3bc78f52e61c611a566d29f8ba9bd..a0a507083f15a4031ba87c83ec7e94b500523669 100644
--- a/lib/hawat/blueprints/groups/test/__init__.py
+++ b/lib/hawat/blueprints/groups/test/__init__.py
@@ -143,8 +143,7 @@ class GroupsCreateTestCase(TestRunnerMixin, ItemCreateVialTestCase):
     group_data_fixture = [
         ('name', 'TEST_GROUP'),
         ('description', 'Test group for unit testing purposes.'),
-        ('enabled', True),
-        ('managed', True)
+        ('enabled', True)
     ]
 
     def _attempt_fail(self):
diff --git a/lib/hawat/blueprints/networks/__init__.py b/lib/hawat/blueprints/networks/__init__.py
index 89119a2e7d050b7d3e2956b2da9cae85b2bdced4..487de9e874f8bed7987d133aaf3d9c2c1aaee9e6 100644
--- a/lib/hawat/blueprints/networks/__init__.py
+++ b/lib/hawat/blueprints/networks/__init__.py
@@ -257,10 +257,7 @@ class CreateView(HTMLMixin, SQLAlchemyMixin, ItemCreateView):  # pylint: disable
 
     @staticmethod
     def get_message_cancel(**kwargs):
-        return gettext(
-            'Canceled creating new network record for group <strong>%(parent_id)s</strong>.',
-            parent_id = flask.escape(str(kwargs['item'].group))
-        )
+        return gettext('Canceled creating new network record.')
 
     @staticmethod
     def get_item_form(item):
@@ -339,10 +336,7 @@ class CreateForView(HTMLMixin, SQLAlchemyMixin, ItemCreateForView):  # pylint: d
 
     @staticmethod
     def get_message_cancel(**kwargs):
-        return gettext(
-            'Canceled creating new network record for group <strong>%(parent_id)s</strong>.',
-            parent_id = flask.escape(str(kwargs['parent']))
-        )
+        return gettext('Canceled creating new network record.')
 
     @staticmethod
     def get_item_form(item):
diff --git a/lib/hawat/blueprints/performance/__init__.py b/lib/hawat/blueprints/performance/__init__.py
index 39e597b774af1da0ff251afa35ab4f27a5a0d7d1..da0af0808122a57061dd154a5993ef221a1eb339 100644
--- a/lib/hawat/blueprints/performance/__init__.py
+++ b/lib/hawat/blueprints/performance/__init__.py
@@ -25,7 +25,6 @@ from flask_babel import gettext, lazy_gettext
 import mentat.const
 import mentat.stats.rrd
 
-import vial.acl
 from vial.app import VialBlueprint
 from vial.view import SimpleView, FileNameView
 from vial.view.mixin import HTMLMixin
diff --git a/lib/hawat/blueprints/reports/__init__.py b/lib/hawat/blueprints/reports/__init__.py
index 08c038157a2d48f49776b1235bd8f2048f0cef91..c9543a3317fc791a7ebbce0316917608208f7b15 100644
--- a/lib/hawat/blueprints/reports/__init__.py
+++ b/lib/hawat/blueprints/reports/__init__.py
@@ -245,14 +245,6 @@ class ShowView(HTMLMixin, SQLAlchemyMixin, ItemShowView):
             icon = 'action-download',
             hidelegend = True
         )
-        action_menu.add_entry(
-            'endpoint',
-            'more.downloadcsv',
-            endpoint = 'reports.data',
-            title = lazy_gettext('Download data in CSV format (deprecated)'),
-            url = lambda **x: flask.url_for('reports.data', fileid = x['item'].label, filetype = 'csv'),
-            hidelegend = True
-        )
         action_menu.add_entry(
             'endpoint',
             'more.downloadjsonzip',
@@ -262,15 +254,6 @@ class ShowView(HTMLMixin, SQLAlchemyMixin, ItemShowView):
             icon = 'action-download-zip',
             hidelegend = True
         )
-        action_menu.add_entry(
-            'endpoint',
-            'more.downloadcsvzip',
-            endpoint = 'reports.data',
-            title = lazy_gettext('Download compressed data in CSV format (deprecated)'),
-            url = lambda **x: flask.url_for('reports.data', fileid = x['item'].label, filetype = 'csvzip'),
-            icon = 'action-download-zip',
-            hidelegend = True
-        )
         return action_menu
 
     @staticmethod
@@ -380,10 +363,6 @@ class DataView(FileIdView):
             fileext = 'json'
         elif filetype == 'jsonzip':
             fileext = 'json.zip'
-        elif filetype == 'csv':
-            fileext = 'csv'
-        elif filetype == 'csvzip':
-            fileext = 'csv.zip'
         else:
             raise ValueError("Requested invalid data file type '{}'".format(filetype))
         return 'security-report-{}.{}'.format(fileid, fileext)
diff --git a/lib/hawat/blueprints/reports/templates/reports/show.html b/lib/hawat/blueprints/reports/templates/reports/show.html
index e5a1524250243cdef795bbb21d1f930a790421ec..2215cc4476016aa05f7f2bb88a863c1408fe14a5 100644
--- a/lib/hawat/blueprints/reports/templates/reports/show.html
+++ b/lib/hawat/blueprints/reports/templates/reports/show.html
@@ -227,7 +227,7 @@
                             <div class="report-message">{{ _('This report contains fraction of data from parent summary report [{:s}], that is also available in HTML format at:').format(item.parent.label) }}</div>
                             <div class="report-message" style="margin-left:2em"><a href="{{ template_vars['report_access_url'] }}{{ item.parent.label }}/unauth">{{ template_vars['report_access_url'] }}{{ item.parent.label }}/unauth</a></div>
                         {% endif %}
-                        <div class="report-message">{{ _('Attachment files containing complete information available for each event can be downloaded above message in JSON and CSV format.') }}</div>
+                        <div class="report-message">{{ _('Attachment files containing complete information available for each event can be downloaded above message in JSON format.') }}</div>
                         {% autoescape false %}<div class="report-message">{{ _('This message was generated by an automated system. For further communication please use the contact email address <{:s}> and for easier orientation please keep the identifier [{:s}] in email subject.').format("<a href=\"mailto:{:s}?subject={:s}\">{:s}</a>", item.label).format(template_vars['contact_email'], item.label, template_vars['contact_email']) }}</div>{% endautoescape %}
                     <div class="report-message">{{ _('Thank you in advance for your cooperation') }}</div>
 
diff --git a/lib/hawat/blueprints/settings_reporting/forms.py b/lib/hawat/blueprints/settings_reporting/forms.py
index 8512b3acc4e2a0a0231f8d675b2e2a1b9b6a4b57..fbe98327c8cae883970e377db5c62d470e08b344 100644
--- a/lib/hawat/blueprints/settings_reporting/forms.py
+++ b/lib/hawat/blueprints/settings_reporting/forms.py
@@ -23,7 +23,7 @@ import wtforms
 from wtforms.ext.sqlalchemy.fields import QuerySelectField
 from babel import Locale
 
-from flask_babel import gettext, lazy_gettext
+from flask_babel import lazy_gettext
 
 import vial.const
 import vial.forms
diff --git a/lib/hawat/blueprints/users/__init__.py b/lib/hawat/blueprints/users/__init__.py
index 4e4fbff58c3d4fdf29ae952fae0b70472376d070..ab21b608c3211b5144d8571bfe24f7b707cdf416 100644
--- a/lib/hawat/blueprints/users/__init__.py
+++ b/lib/hawat/blueprints/users/__init__.py
@@ -35,7 +35,7 @@ from flask_babel import lazy_gettext
 
 import vial.blueprints.users
 from vial.blueprints.users import BLUEPRINT_NAME, ListView, ShowView, MeView,\
-    EnableView, DisableView, DeleteView, AddMembershipView, RejectMembershipView, RemoveMembershipView
+    EnableView, DisableView, DeleteView, AddMembershipView, RejectMembershipView, RemoveMembershipView, AddManagementView, RemoveManagementView
 from hawat.blueprints.users.forms import CreateUserAccountForm, UpdateUserAccountForm,\
     AdminUpdateUserAccountForm
 
@@ -143,6 +143,8 @@ def get_blueprint():
     hbp.register_view_class(AddMembershipView,    '/<int:item_id>/add_membership/<int:other_id>')
     hbp.register_view_class(RemoveMembershipView, '/<int:item_id>/remove_membership/<int:other_id>')
     hbp.register_view_class(RejectMembershipView, '/<int:item_id>/reject_membership/<int:other_id>')
+    hbp.register_view_class(AddManagementView,    '/<int:item_id>/add_management/<int:other_id>')
+    hbp.register_view_class(RemoveManagementView, '/<int:item_id>/remove_management/<int:other_id>')
     hbp.register_view_class(EnableView,           '/<int:item_id>/enable')
     hbp.register_view_class(DisableView,          '/<int:item_id>/disable')
     hbp.register_view_class(DeleteView,           '/<int:item_id>/delete')
diff --git a/lib/hawat/blueprints/users/forms.py b/lib/hawat/blueprints/users/forms.py
index 51bfe0c0918d3823705a7edffaad125105f79bee..60fe0a31743484b40d3e8dc5d7d5dc4988e80d0b 100644
--- a/lib/hawat/blueprints/users/forms.py
+++ b/lib/hawat/blueprints/users/forms.py
@@ -110,9 +110,6 @@ class BaseUserAccountForm(vial.forms.BaseItemForm):
     submit = wtforms.SubmitField(
         lazy_gettext('Submit')
     )
-    cancel = wtforms.SubmitField(
-        lazy_gettext('Cancel')
-    )
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
diff --git a/lib/hawat/blueprints/users/templates/users/addmanagement.html b/lib/hawat/blueprints/users/templates/users/addmanagement.html
new file mode 100644
index 0000000000000000000000000000000000000000..6a15228a39cb0b875b8fc2d31ba18f5a558574fc
--- /dev/null
+++ b/lib/hawat/blueprints/users/templates/users/addmanagement.html
@@ -0,0 +1,16 @@
+{%- extends "_layout_confirmation.html" %}
+
+{%- block modalcontent %}
+                                <p>
+                                    {{ _('Are you really sure you want to add user') }}
+                                </p>
+                                <p class="lead text-center">
+                                    {{ item_name }}
+                                </p>
+                                <p>
+                                    {{ _('as manager to abuse group') }}
+                                </p>
+                                <p class="lead text-center">
+                                    {{ other_name }}
+                                </p>
+{% endblock modalcontent %}
diff --git a/lib/hawat/blueprints/users/templates/users/removemanagement.html b/lib/hawat/blueprints/users/templates/users/removemanagement.html
new file mode 100644
index 0000000000000000000000000000000000000000..882d17dbbb9997fa516a44b11b2180ddfd0ecd81
--- /dev/null
+++ b/lib/hawat/blueprints/users/templates/users/removemanagement.html
@@ -0,0 +1,16 @@
+{%- extends "_layout_confirmation.html" %}
+
+{%- block modalcontent %}
+                                <p>
+                                    {{ _('Are you really sure you want to remove user') }}
+                                </p>
+                                <p class="lead text-center">
+                                    {{ item_name }}
+                                </p>
+                                <p>
+                                    {{ _('as manager from abuse group') }}
+                                </p>
+                                <p class="lead text-center">
+                                    {{ other_name }}
+                                </p>
+{% endblock modalcontent %}
diff --git a/lib/hawat/migrations/versions/4a172cd00ef0_clean_mail_to_and_add_not_null_.py b/lib/hawat/migrations/versions/4a172cd00ef0_clean_mail_to_and_add_not_null_.py
new file mode 100644
index 0000000000000000000000000000000000000000..eb717f6aee3834cf1ea842a117ef0f5226329514
--- /dev/null
+++ b/lib/hawat/migrations/versions/4a172cd00ef0_clean_mail_to_and_add_not_null_.py
@@ -0,0 +1,96 @@
+"""Clean mail_to, emails and add not null constraints
+
+Revision ID: 4a172cd00ef0
+Revises: c2b4c2af6196
+Create Date: 2021-07-20 10:46:04.138409
+
+"""
+from alembic import op
+
+
+# revision identifiers, used by Alembic.
+revision = '4a172cd00ef0'
+down_revision = 'c2b4c2af6196'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    op.execute(
+        """CREATE OR REPLACE FUNCTION alembic_4a172cd00ef0_trim_array(character varying[])
+           RETURNS character varying[]
+           AS
+           $$
+           DECLARE
+              arr ALIAS FOR $1;
+              element character varying;
+              retVal character varying[];
+           BEGIN
+              FOREACH element IN ARRAY arr
+              LOOP
+               retVal := array_append(retVal, trim(element)::varchar);
+              END LOOP;
+           RETURN retVal;
+           END;
+           $$
+           LANGUAGE plpgsql
+              STABLE
+           RETURNS NULL ON NULL INPUT;"""
+    )
+    op.execute(
+        """CREATE OR REPLACE FUNCTION alembic_4a172cd00ef0_split_strings(character varying[])
+           RETURNS character varying[]
+           AS
+           $$
+           DECLARE
+              arr ALIAS FOR $1;
+              element character varying;
+              retVal character varying[];
+           BEGIN
+              FOREACH element IN ARRAY arr
+              LOOP
+               retVal := retVal || alembic_4a172cd00ef0_trim_array(string_to_array(element, ',')::varchar[]);
+              END LOOP;
+           RETURN retVal;
+           END;
+           $$
+           LANGUAGE plpgsql
+              STABLE
+           RETURNS NULL ON NULL INPUT;"""
+    )
+
+    op.execute(
+        "UPDATE reports_events SET mail_to = alembic_4a172cd00ef0_trim_array(mail_to)"
+    )
+    op.execute(
+        "UPDATE reports_events SET mail_to = ARRAY[]::varchar[] WHERE mail_to IS NULL OR mail_to = '{None}'"
+    )
+    op.execute(
+        "ALTER TABLE reports_events ALTER COLUMN mail_to SET NOT NULL"
+    )
+
+    op.execute(
+        "UPDATE settings_reporting SET emails = alembic_4a172cd00ef0_split_strings(emails)"
+    )
+    op.execute(
+        "UPDATE settings_reporting SET emails = ARRAY[]::varchar[] WHERE emails IS NULL"
+    )
+    op.execute(
+        "ALTER TABLE settings_reporting ALTER COLUMN emails SET NOT NULL"
+    )
+
+    op.execute(
+        "DROP FUNCTION alembic_4a172cd00ef0_split_strings(character varying[])"
+    )
+    op.execute(
+        "DROP FUNCTION alembic_4a172cd00ef0_trim_array(character varying[])"
+    )
+
+
+def downgrade():
+    op.execute(
+        "ALTER TABLE reports_events ALTER COLUMN mail_to DROP NOT NULL"
+    )
+    op.execute(
+        "ALTER TABLE settings_reporting ALTER COLUMN emails DROP NOT NULL"
+    )
diff --git a/lib/hawat/migrations/versions/c2b4c2af6196_removed_groups_managed.py b/lib/hawat/migrations/versions/c2b4c2af6196_removed_groups_managed.py
new file mode 100644
index 0000000000000000000000000000000000000000..a5ba683ba98476f803d240bf1564f6405331bdf9
--- /dev/null
+++ b/lib/hawat/migrations/versions/c2b4c2af6196_removed_groups_managed.py
@@ -0,0 +1,24 @@
+"""Removed managed column from GroupModel
+
+Revision ID: c2b4c2af6196
+Revises: 0df0d44a1429
+Create Date: 2021-10-13 17:59:47.008910
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = 'c2b4c2af6196'
+down_revision = '0df0d44a1429'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():  # pylint: disable=locally-disabled,missing-docstring
+    op.drop_column('groups', 'managed')  # pylint: disable=locally-disabled,no-member
+
+
+def downgrade():  # pylint: disable=locally-disabled,missing-docstring
+    op.add_column('groups', sa.Column('managed', sa.BOOLEAN(), autoincrement=False, nullable=False, default=False, server_default='f'))
diff --git a/lib/hawat/static/css/hawat.css b/lib/hawat/static/css/hawat.css
index 1a456cc8d65c606834358ef1abaa140398b2291f..0f0252296fcab1987bd71c3b45b4f0b7a0466822 100644
--- a/lib/hawat/static/css/hawat.css
+++ b/lib/hawat/static/css/hawat.css
@@ -120,13 +120,6 @@ body {
     padding-left: 1em !important;
 }
 
-/*
- * Fix for wrong indentation of search field in datatables.
- * */
-#DataTables_Table_0_filter {
-    text-align: right;
-}
-
 /*
  * Implement hover functionality for list group items.
  * */
diff --git a/lib/hawat/static/js/hawat-jquery.js b/lib/hawat/static/js/hawat-jquery.js
index 3476fc2b9a389600c0a0076c6da59b484b49fda8..bf2343e7fcb834e7558b23eca71a7fa66d13b7f0 100644
--- a/lib/hawat/static/js/hawat-jquery.js
+++ b/lib/hawat/static/js/hawat-jquery.js
@@ -80,6 +80,11 @@ $(function() {
         $('#datetimepicker-from-2').data("DateTimePicker").maxDate(e.date);
     });
 
+    // Disable built-in JS form validation in case the form`s cancel button is clicked.`
+    $('input[type="submit"][value="Cancel"]').click(function(){
+        $(this).parents('form:first').attr('novalidate', 'novalidate');
+    });
+
     // Initialize linked date and datetime picker components.
     $('#datetimepicker-hm-from').datetimepicker({
         locale: GLOBAL_LOCALE,
diff --git a/lib/hawat/templates/registration/email_user.txt b/lib/hawat/templates/registration/email_user.txt
index 0ced73c5a73cfa3033549a742da38274996ee9bf..fd0a4f9051fd07f83c3f0a07324788cd36193f86 100644
--- a/lib/hawat/templates/registration/email_user.txt
+++ b/lib/hawat/templates/registration/email_user.txt
@@ -24,7 +24,7 @@
 
 {{ _('After successfull activation you will be able to login and start using the system:') | wordwrap }}
 
-	{{ url_for('auth_pwd.login', _external = True ) }}
+	{{ url_for('auth.login', _external = True ) }}
 
 {{ _('Have a nice day') | wordwrap }}
 
diff --git a/lib/hawat/test/runner.py b/lib/hawat/test/runner.py
index f9086c8c2c52240ce21a95af60af77241b983526..8e8ea2e7a6ddc01edc148b5a2fa9902b5bb95810 100644
--- a/lib/hawat/test/runner.py
+++ b/lib/hawat/test/runner.py
@@ -37,7 +37,7 @@ def _config_testapp_hawat(app_config):
     app_config['LOG_FILE'] = '/var/tmp/mentat-hawat-utest.log'
     app_config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://mentat:mentat@localhost/mentat_utest'
     app_config['MAIL_SERVER'] = 'localhost'
-    app_config['MAIL_PORT'] = 8025
+    app_config['MAIL_PORT'] = 1025
     app_config['MAIL_DEFAULT_SENDER'] = 'root@unittest'
     app_config['EMAIL_ADMINS'] = ['admin@unittest']
     app_config['MODELS'] = {
diff --git a/lib/hawat/translations/cs/LC_MESSAGES/messages.po b/lib/hawat/translations/cs/LC_MESSAGES/messages.po
index e1fa72f46dd45f76b4727f1449adef8862516fd6..cba0886f547ce43730e9ca16ad3dbe38fe6478d7 100644
--- a/lib/hawat/translations/cs/LC_MESSAGES/messages.po
+++ b/lib/hawat/translations/cs/LC_MESSAGES/messages.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PROJECT VERSION\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2021-07-15 01:18+0200\n"
+"POT-Creation-Date: 2021-07-15 21:35+0200\n"
 "PO-Revision-Date: 2017-09-22 15:33+0200\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language: cs\n"
@@ -365,7 +365,7 @@ msgstr "Zastavení hledání <strong>%(item_id)s</strong> bylo přerušeno."
 
 #: ../hawat/blueprints/dbstatus/__init__.py:455
 #: ../hawat/blueprints/users/__init__.py:107
-#: ../vial/blueprints/users/__init__.py:1000
+#: ../vial/blueprints/users/__init__.py:1185
 msgid "Object management"
 msgstr "Správa objektů"
 
@@ -373,14 +373,14 @@ msgstr "Správa objektů"
 msgid "Object management dashboards"
 msgstr "Dasboard správy objektů"
 
-#: ../hawat/blueprints/dbstatus/__init__.py:549
+#: ../hawat/blueprints/dbstatus/__init__.py:547
 #, python-format
 msgid "View details of user account &quot;%(item)s&quot;"
 msgstr "Zobrazit detaily uživatelského účtu &quot;%(item)s&quot;"
 
-#: ../hawat/blueprints/dbstatus/__init__.py:554
-#: ../hawat/blueprints/dbstatus/__init__.py:596
-#: ../hawat/blueprints/dbstatus/__init__.py:635
+#: ../hawat/blueprints/dbstatus/__init__.py:552
+#: ../hawat/blueprints/dbstatus/__init__.py:594
+#: ../hawat/blueprints/dbstatus/__init__.py:633
 #: ../hawat/blueprints/groups/__init__.py:66
 #: ../hawat/blueprints/reports/__init__.py:237
 #: ../vial/blueprints/changelogs/__init__.py:87
@@ -389,31 +389,31 @@ msgstr "Zobrazit detaily uživatelského účtu &quot;%(item)s&quot;"
 msgid "More actions"
 msgstr "Více akcí"
 
-#: ../hawat/blueprints/dbstatus/__init__.py:560
+#: ../hawat/blueprints/dbstatus/__init__.py:558
 #: ../vial/blueprints/users/__init__.py:478
 #, python-format
 msgid "Update details of user account &quot;%(item)s&quot;"
 msgstr "Aktualizovat detaily uživatelského účtu &quot;%(item)s&quot;"
 
-#: ../hawat/blueprints/dbstatus/__init__.py:567
+#: ../hawat/blueprints/dbstatus/__init__.py:565
 #: ../vial/blueprints/users/__init__.py:901
 #, python-format
 msgid "Disable user account &quot;%(item)s&quot;"
 msgstr "Deaktivovat uživatelský účet &quot;%(item)s&quot;"
 
-#: ../hawat/blueprints/dbstatus/__init__.py:574
+#: ../hawat/blueprints/dbstatus/__init__.py:572
 #: ../vial/blueprints/users/__init__.py:824
 #, python-format
 msgid "Enable user account &quot;%(item)s&quot;"
 msgstr "Aktivovat uživatelský účet &quot;%(item)s&quot;"
 
-#: ../hawat/blueprints/dbstatus/__init__.py:581
+#: ../hawat/blueprints/dbstatus/__init__.py:579
 #: ../vial/blueprints/users/__init__.py:952
 #, python-format
 msgid "Delete user account &quot;%(item)s&quot;"
 msgstr "Smazat uživatelský účet &quot;%(item)s&quot;"
 
-#: ../hawat/blueprints/dbstatus/__init__.py:591
+#: ../hawat/blueprints/dbstatus/__init__.py:589
 #: ../hawat/blueprints/dbstatus/templates/dbstatus/dashboard.html:392
 #: ../hawat/blueprints/dbstatus/templates/dbstatus/dashboard.html:434
 #: ../hawat/blueprints/dbstatus/templates/dbstatus/dashboard.html:479
@@ -437,7 +437,7 @@ msgstr "Zobrazit detaily skupiny &quot;%(item)s&quot;"
 msgid "Update details of group &quot;%(item)s&quot;"
 msgstr "Aktualizovat detaily skupiny &quot;%(item)s&quot;"
 
-#: ../hawat/blueprints/dbstatus/__init__.py:608
+#: ../hawat/blueprints/dbstatus/__init__.py:606
 #: ../vial/blueprints/groups/__init__.py:782
 #, python-format
 msgid "Disable group &quot;%(item)s&quot;"
@@ -455,7 +455,7 @@ msgstr "Aktivovat group &quot;%(item)s&quot;"
 msgid "Delete group &quot;%(item)s&quot;"
 msgstr "Smazat skupinu &quot;%(item)s&quot;"
 
-#: ../hawat/blueprints/dbstatus/__init__.py:630
+#: ../hawat/blueprints/dbstatus/__init__.py:628
 #: ../hawat/blueprints/filters/__init__.py:270
 #, python-format
 msgid "View details of reporting filter &quot;%(item)s&quot;"
@@ -467,25 +467,25 @@ msgstr "Zobrazit detaily reportovacího filtru &quot;%(item)s&quot;"
 msgid "Update details of reporting filter &quot;%(item)s&quot;"
 msgstr "Aktualizovat detaily reportovacího filtru &quot;%(item)s&quot;"
 
-#: ../hawat/blueprints/dbstatus/__init__.py:647
+#: ../hawat/blueprints/dbstatus/__init__.py:645
 #: ../hawat/blueprints/filters/__init__.py:679
 #, python-format
 msgid "Disable reporting filter &quot;%(item)s&quot;"
 msgstr "Deaktivovat reportovací filtr &quot;%(item)s&quot;"
 
-#: ../hawat/blueprints/dbstatus/__init__.py:653
+#: ../hawat/blueprints/dbstatus/__init__.py:651
 #: ../hawat/blueprints/filters/__init__.py:624
 #, python-format
 msgid "Enable reporting filter &quot;%(item)s&quot;"
 msgstr "Aktivovat reportovací filtr &quot;%(item)s&quot;"
 
-#: ../hawat/blueprints/dbstatus/__init__.py:659
+#: ../hawat/blueprints/dbstatus/__init__.py:657
 #: ../hawat/blueprints/filters/__init__.py:736
 #, python-format
 msgid "Delete reporting filter &quot;%(item)s&quot;"
 msgstr "Smazat reportovací filtr &quot;%(item)s&quot;"
 
-#: ../hawat/blueprints/dbstatus/__init__.py:672
+#: ../hawat/blueprints/dbstatus/__init__.py:670
 msgid "Database status overview"
 msgstr ""
 
@@ -793,12 +793,11 @@ msgstr ""
 "pro tyto skupiny nejsou generovány vůbec. Toto nastavení by mělo být "
 "VELMI ojedinělé."
 
-#: ../hawat/blueprints/dbstatus/templates/dbstatus/dashboard.html:673
-#: ../hawat/blueprints/dbstatus/templates/dbstatus/dashboard.html:674
+#: ../hawat/blueprints/dbstatus/templates/dbstatus/dashboard.html:636
+#: ../hawat/blueprints/dbstatus/templates/dbstatus/dashboard.html:637
 msgid "Groups with custom emails"
 msgstr "Skupiny s vlastními emaily"
 
-#: ../hawat/blueprints/dbstatus/templates/dbstatus/dashboard.html:673
 msgid ""
 "This panel contains list of groups with custom target report emails. "
 "Reports for these groups are being send to different that standard email "
@@ -2930,7 +2929,7 @@ msgstr "Hledání v databázi měst"
 msgid "My groups"
 msgstr "Moje skupiny"
 
-#: ../hawat/blueprints/groups/__init__.py:245
+#: ../hawat/blueprints/groups/__init__.py:255
 #, python-format
 msgid "View details of abuse group <strong>%(name)s</strong>"
 msgstr "Zobrazit detaily abuse skupiny <strong>%(name)s</strong>"
@@ -2963,19 +2962,6 @@ msgstr ""
 msgid "Self management:"
 msgstr "Samospráva:"
 
-#: ../hawat/blueprints/groups/forms.py:124
-#: ../vial/blueprints/groups/forms.py:66
-msgid ""
-"Boolean flag whether the group is self managed by group managers. When "
-"enabled group managers are expected to take care of the group management "
-"tasks and they get notifications about important events like group "
-"membership requests, etc."
-msgstr ""
-"Příznak, zda skupina je spravována samostatně označenými správci skupiny."
-" Pokud je aktivován očekává se od správců skupiny, že se budou o správu "
-"skupiny starat sami a k tomuto účelu budou od systému dostávat hlášení o "
-"důležitých událostech jako žádosti o členství atd."
-
 #: ../hawat/blueprints/groups/forms.py:127
 #: ../vial/blueprints/groups/forms.py:69
 msgid "Members:"
@@ -3038,11 +3024,18 @@ msgstr ""
 msgid "System-wide unique name for the group."
 msgstr "Jméno skupiny unikátní v rámci celého systému."
 
+#: ../hawat/blueprints/groups/templates/groups/addmanager.html:5
 #: ../hawat/blueprints/groups/templates/groups/addmember.html:5
+#: ../hawat/blueprints/users/templates/users/addmanagement.html:5
 #: ../hawat/blueprints/users/templates/users/addmembership.html:5
 msgid "Are you really sure you want to add user"
 msgstr "Jste si jisti, že chcete přidat uživatele"
 
+#: ../hawat/blueprints/groups/templates/groups/addmanager.html:11
+#: ../hawat/blueprints/users/templates/users/addmanagement.html:11
+msgid "as manager to abuse group"
+msgstr ""
+
 #: ../hawat/blueprints/groups/templates/groups/addmember.html:11
 #: ../hawat/blueprints/users/templates/users/addmembership.html:11
 msgid "to abuse group"
@@ -3066,11 +3059,18 @@ msgstr "Jste si jisti, že chcete odmítnou žádost uživatele"
 msgid "for abuse group"
 msgstr "o členství ve skupině"
 
+#: ../hawat/blueprints/groups/templates/groups/removemanager.html:5
 #: ../hawat/blueprints/groups/templates/groups/removemember.html:5
+#: ../hawat/blueprints/users/templates/users/removemanagement.html:5
 #: ../hawat/blueprints/users/templates/users/removemembership.html:5
 msgid "Are you really sure you want to remove user"
 msgstr "Jste si jisti, že chcete odebrat uživatele"
 
+#: ../hawat/blueprints/groups/templates/groups/removemanager.html:11
+#: ../hawat/blueprints/users/templates/users/removemanagement.html:11
+msgid "as manager from abuse group"
+msgstr ""
+
 #: ../hawat/blueprints/groups/templates/groups/removemember.html:11
 #: ../hawat/blueprints/users/templates/users/removemembership.html:11
 msgid "from abuse group"
@@ -3390,12 +3390,8 @@ msgstr ""
 #: ../hawat/blueprints/networks/__init__.py:262
 #: ../hawat/blueprints/networks/__init__.py:344
 #, python-format
-msgid ""
-"Canceled creating new network record for group "
-"<strong>%(parent_id)s</strong>."
-msgstr ""
-"Vytvoření nového síťového záznamu pro skupinu "
-"<strong>%(parent_id)s</strong> bylo zrušeno."
+msgid "Canceled creating new network record."
+msgstr "Vytvoření nového síťového záznamu bylo zrušeno."
 
 #: ../hawat/blueprints/networks/__init__.py:292
 #, python-format
@@ -3716,35 +3712,27 @@ msgstr "Zobrazit detaily reportu událostí &quot;%(item)s&quot;"
 msgid "Search for all events related to report &quot;%(item)s&quot;"
 msgstr "Hledat všechny události související s reportem &quot;%(item)s&quot;"
 
-#: ../hawat/blueprints/reports/__init__.py:243
+#: ../hawat/blueprints/reports/__init__.py:239
 msgid "Download data in JSON format"
 msgstr "Stáhnout data ve formátu JSON"
 
-#: ../hawat/blueprints/reports/__init__.py:252
-msgid "Download data in CSV format (deprecated)"
-msgstr "Stáhnout data ve formátu CSV (zavržené)"
-
-#: ../hawat/blueprints/reports/__init__.py:260
+#: ../hawat/blueprints/reports/__init__.py:248
 msgid "Download compressed data in JSON format"
 msgstr "Stáhnout data v komprimovaném formátu JSON"
 
-#: ../hawat/blueprints/reports/__init__.py:269
-msgid "Download compressed data in CSV format (deprecated)"
-msgstr "Stáhnout data v komprimovaném formátu CSV (zavržené)"
-
-#: ../hawat/blueprints/reports/__init__.py:367
+#: ../hawat/blueprints/reports/__init__.py:340
 msgid "Event report data"
 msgstr "Data reportu událostí"
 
-#: ../hawat/blueprints/reports/__init__.py:408
+#: ../hawat/blueprints/reports/__init__.py:377
 msgid "Reporting"
 msgstr "Reportování"
 
-#: ../hawat/blueprints/reports/__init__.py:412
+#: ../hawat/blueprints/reports/__init__.py:381
 msgid "Event reporting dashboards"
 msgstr "Dashboardy reportingu událostí"
 
-#: ../hawat/blueprints/reports/__init__.py:486
+#: ../hawat/blueprints/reports/__init__.py:455
 #, python-format
 msgid "Delete event report &quot;%(item)s&quot;"
 msgstr "Smazat report &quot;%(item)s&quot;"
@@ -4197,10 +4185,9 @@ msgstr ""
 #: ../hawat/blueprints/reports/templates/reports/show.html:230
 msgid ""
 "Attachment files containing complete information available for each event"
-" can be downloaded above message in JSON and CSV format."
-msgstr ""
-"Soubory s kompletními informacemi dostupnými ke každé události lze získat"
-" nad zprávou ve formátu JSON nebo CSV."
+" can be downloaded above message in JSON format."
+msgstr "Soubory s kompletními informacemi dostupnými ke každé události lze získat"
+" nad zprávou ve formátu JSON."
 
 #: ../hawat/blueprints/reports/templates/reports/show.html:231
 msgid ""
@@ -4976,11 +4963,11 @@ msgstr "základní"
 msgid "advanced"
 msgstr "pokročilý"
 
-#: ../mentat/reports/event.py:51
+#: ../mentat/reports/event.py:50
 msgid "[{:s}] {:s} - Notice about possible problems in your network"
 msgstr "[{:s}] {:s} - Upozornění na možné problémy ve Vaší síti"
 
-#: ../mentat/reports/event.py:54
+#: ../mentat/reports/event.py:53
 msgid "[{:s}] {:s} - Notice about possible problems regarding host {:s}"
 msgstr "[{:s}] {:s} - Upozornění na možné problémy týkající se hostitele {:s}"
 
@@ -5490,7 +5477,79 @@ msgstr ""
 "Odebrání uživatele <strong>%(user_id)s</strong> jako člena ze skupiny "
 "<strong>%(group_id)s</strong> bylo zrušeno."
 
-#: ../vial/blueprints/groups/__init__.py:750
+#: ../vial/blueprints/groups/__init__.py:741
+msgid "Add group manager"
+msgstr ""
+
+#: ../vial/blueprints/groups/__init__.py:752
+#: ../vial/blueprints/users/__init__.py:841
+#, python-format
+msgid ""
+"Add user &quot;%(user_id)s&quot; to group &quot;%(group_id)s&quot; as "
+"manager"
+msgstr ""
+
+#: ../vial/blueprints/groups/__init__.py:796
+#: ../vial/blueprints/users/__init__.py:885
+#, python-format
+msgid ""
+"User <strong>%(user_id)s</strong> was successfully added as a manager to "
+"group <strong>%(group_id)s</strong>."
+msgstr ""
+
+#: ../vial/blueprints/groups/__init__.py:804
+#: ../vial/blueprints/users/__init__.py:893
+#, python-format
+msgid ""
+"Unable to add user <strong>%(user_id)s</strong> as a manager to group "
+"<strong>%(group_id)s</strong>."
+msgstr ""
+
+#: ../vial/blueprints/groups/__init__.py:812
+#: ../vial/blueprints/users/__init__.py:901
+#, python-format
+msgid ""
+"Canceled adding user <strong>%(user_id)s</strong> as a manager to group "
+"<strong>%(group_id)s</strong>."
+msgstr ""
+
+#: ../vial/blueprints/groups/__init__.py:830
+msgid "Remove group manager"
+msgstr ""
+
+#: ../vial/blueprints/groups/__init__.py:841
+#: ../vial/blueprints/users/__init__.py:930
+#, python-format
+msgid ""
+"Remove user &quot;%(user_id)s&quot; from group &quot;%(group_id)s&quot; "
+"as manager"
+msgstr ""
+
+#: ../vial/blueprints/groups/__init__.py:882
+#: ../vial/blueprints/users/__init__.py:971
+#, python-format
+msgid ""
+"User <strong>%(user_id)s</strong> was successfully removed as a manager "
+"from group <strong>%(group_id)s</strong>."
+msgstr ""
+
+#: ../vial/blueprints/groups/__init__.py:890
+#: ../vial/blueprints/users/__init__.py:979
+#, python-format
+msgid ""
+"Unable to remove user <strong>%(user_id)s</strong> as a manager from "
+"group <strong>%(group_id)s</strong>."
+msgstr ""
+
+#: ../vial/blueprints/groups/__init__.py:898
+#: ../vial/blueprints/users/__init__.py:987
+#, python-format
+msgid ""
+"Canceled removing user <strong>%(user_id)s</strong> as a manager from "
+"group <strong>%(group_id)s</strong>."
+msgstr ""
+
+#: ../vial/blueprints/groups/__init__.py:931
 #, python-format
 msgid "Group <strong>%(item_id)s</strong> was successfully enabled."
 msgstr "Skupina <strong>%(item_id)s</strong> byla úspěšně aktivována."
@@ -5547,14 +5606,6 @@ msgid ""
 "of the strings."
 msgstr ""
 
-#: ../vial/blueprints/groups/forms.py:204
-msgid "Self-managed"
-msgstr ""
-
-#: ../vial/blueprints/groups/forms.py:205
-msgid "Not self-managed"
-msgstr ""
-
 #: ../vial/blueprints/groups/forms.py:208
 msgid "Search for groups with particular state."
 msgstr ""
@@ -5617,98 +5668,106 @@ msgstr "Vytvořit nový uživatelský účet"
 msgid "User account <strong>%(item_id)s</strong> was successfully created."
 msgstr "Uživatelský účet <strong>%(item_id)s</strong> byl úspěšně vytvořen."
 
-#: ../vial/blueprints/users/__init__.py:436
+#: ../vial/blueprints/users/__init__.py:446
 msgid "Unable to create new user account."
 msgstr "Nelze vytvořit nový uživatelský účet."
 
-#: ../vial/blueprints/users/__init__.py:440
+#: ../vial/blueprints/users/__init__.py:450
 msgid "Canceled creating new user account."
 msgstr "Vytváření nového uživatelského účtu bylo zrušeno."
 
-#: ../vial/blueprints/users/__init__.py:472
+#: ../vial/blueprints/users/__init__.py:482
 msgid "Update user account details"
 msgstr "Aktualizovat detaily uživatelského účtu"
 
-#: ../vial/blueprints/users/__init__.py:500
+#: ../vial/blueprints/users/__init__.py:510
 #, python-format
 msgid "User account <strong>%(item_id)s</strong> was successfully updated."
 msgstr "Uživatelský účet <strong>%(item_id)s</strong> byl úspěšně aktualizován."
 
-#: ../vial/blueprints/users/__init__.py:507
+#: ../vial/blueprints/users/__init__.py:517
 #, python-format
 msgid "Unable to update user account <strong>%(item_id)s</strong>."
 msgstr "Nelze aktualizovat uživatelský účet <strong>%(item_id)s</strong>."
 
-#: ../vial/blueprints/users/__init__.py:514
+#: ../vial/blueprints/users/__init__.py:524
 #, python-format
 msgid "Canceled updating user account <strong>%(item_id)s</strong>."
 msgstr "Aktualizace uživatelského účtu <strong>%(item_id)s</strong> byla zrušena."
 
-#: ../vial/blueprints/users/__init__.py:558
+#: ../vial/blueprints/users/__init__.py:568
 msgid "Add group membership"
 msgstr "Přidat členství"
 
-#: ../vial/blueprints/users/__init__.py:651
+#: ../vial/blueprints/users/__init__.py:661
 msgid "Reject group membership"
 msgstr "Odmítnout členství"
 
-#: ../vial/blueprints/users/__init__.py:734
+#: ../vial/blueprints/users/__init__.py:744
 msgid "Remove group membership"
 msgstr "Odebrat členství"
 
-#: ../vial/blueprints/users/__init__.py:839
+#: ../vial/blueprints/users/__init__.py:830
+msgid "Add group management"
+msgstr ""
+
+#: ../vial/blueprints/users/__init__.py:919
+msgid "Remove group management"
+msgstr ""
+
+#: ../vial/blueprints/users/__init__.py:1024
 #, python-format
 msgid "User account <strong>%(item_id)s</strong> was successfully enabled."
 msgstr "Uživatelský účet <strong>%(item_id)s</strong> byl úspěšně aktivován."
 
-#: ../vial/blueprints/users/__init__.py:846
+#: ../vial/blueprints/users/__init__.py:1031
 #, python-format
 msgid "Unable to enable user account <strong>%(item_id)s</strong>."
 msgstr "Nelze aktivovat uživatelský účet <strong>%(item_id)s</strong>."
 
-#: ../vial/blueprints/users/__init__.py:853
+#: ../vial/blueprints/users/__init__.py:1038
 #, python-format
 msgid "Canceled enabling user account <strong>%(item_id)s</strong>."
 msgstr "Aktivace uživatelského účtu <strong>%(item_id)s</strong> byla přerušena."
 
-#: ../vial/blueprints/users/__init__.py:865
+#: ../vial/blueprints/users/__init__.py:1050
 #, python-format
 msgid "[%(app_name)s] Account activation - %(item_id)s"
 msgstr ""
 
-#: ../vial/blueprints/users/__init__.py:916
+#: ../vial/blueprints/users/__init__.py:1101
 #, python-format
 msgid "User account <strong>%(item_id)s</strong> was successfully disabled."
 msgstr "Uživatelský účet <strong>%(item_id)s</strong> byl úspěšně deaktivován."
 
-#: ../vial/blueprints/users/__init__.py:923
+#: ../vial/blueprints/users/__init__.py:1108
 #, python-format
 msgid "Unable to disable user account <strong>%(item_id)s</strong>."
 msgstr "Nelze deaktivovat uživatelský účet <strong>%(item_id)s</strong>."
 
-#: ../vial/blueprints/users/__init__.py:930
+#: ../vial/blueprints/users/__init__.py:1115
 #, python-format
 msgid "Canceled disabling user account <strong>%(item_id)s</strong>."
 msgstr "Deaktivace uživatelského účtu <strong>%(item_id)s</strong> byla přerušena."
 
-#: ../vial/blueprints/users/__init__.py:967
+#: ../vial/blueprints/users/__init__.py:1152
 #, python-format
 msgid ""
 "User account <strong>%(item_id)s</strong> was successfully and "
 "permanently deleted."
 msgstr "Uživatelský účet <strong>%(item_id)s</strong> byl úspěšně a trvale smazán."
 
-#: ../vial/blueprints/users/__init__.py:974
+#: ../vial/blueprints/users/__init__.py:1159
 #, python-format
 msgid "Unable to delete user account <strong>%(item_id)s</strong>."
 msgstr "Nelze smazat uživatelský účet <strong>%(item_id)s</strong>."
 
-#: ../vial/blueprints/users/__init__.py:981
+#: ../vial/blueprints/users/__init__.py:1166
 #, python-format
 msgid "Canceled deleting user account <strong>%(item_id)s</strong>."
 msgstr "Mazání uživatelského účtu <strong>%(item_id)s</strong> bylo zrušeno."
 
-#: ../vial/blueprints/users/__init__.py:993
+#: ../vial/blueprints/users/__init__.py:1178
 msgid "User account management"
 msgstr "Správa uživatelských účtů"
 
@@ -5914,26 +5973,26 @@ msgstr "Registrace uživatelského účtu byla zrušena"
 msgid "Please use different login, the \"%(item)s\" is already taken."
 msgstr "Prosím použijte jiný login, \"%(item)s\" již existuje."
 
-#: ../vial/view/__init__.py:1948 ../vial/view/__init__.py:1986
-#: ../vial/view/__init__.py:2013
+#: ../vial/view/__init__.py:1953 ../vial/view/__init__.py:2001
+#: ../vial/view/__init__.py:2033
 #, python-format
 msgid "[%(app_name)s] Account registration - %(item_id)s"
 msgstr "[%(app_name)s] Registrace uživatelského účtu - %(item_id)s"
 
-#: ../vial/view/__init__.py:2154 ../vial/view/__init__.py:2353
-#: ../vial/view/__init__.py:2556
+#: ../vial/view/__init__.py:2174 ../vial/view/__init__.py:2373
+#: ../vial/view/__init__.py:2576
 msgid "No changes detected, no update needed."
 msgstr "Nebyly zjištěny žádné změny, aktualizace není nutná."
 
-#: ../vial/view/__init__.py:2211 ../vial/view/__init__.py:2216
+#: ../vial/view/__init__.py:2231 ../vial/view/__init__.py:2236
 msgid "Delete"
 msgstr "Smazat"
 
-#: ../vial/view/__init__.py:2409 ../vial/view/__init__.py:2414
+#: ../vial/view/__init__.py:2429 ../vial/view/__init__.py:2434
 msgid "Disable"
 msgstr "Deaktivovat"
 
-#: ../vial/view/__init__.py:2445 ../vial/view/__init__.py:2450
+#: ../vial/view/__init__.py:2465 ../vial/view/__init__.py:2470
 msgid "Enable"
 msgstr "Aktivovat"
 
@@ -6888,6 +6947,22 @@ msgstr "Neplatná hodnota %(val)s parametru pre renderování snippetů."
 #~ msgid "json"
 #~ msgstr "json"
 
+#~ msgid "Download data in CSV format (deprecated)"
+#~ msgstr "Stáhnout data ve formátu CSV (zavržené)"
+
+#~ msgid "Download compressed data in CSV format (deprecated)"
+#~ msgstr "Stáhnout data v komprimovaném formátu CSV (zavržené)"
+
+#~ msgid ""
+#~ "Attachment files containing complete "
+#~ "information available for each event can"
+#~ " be downloaded above message in JSON"
+#~ " and CSV format."
+#~ msgstr ""
+#~ "Soubory s kompletními informacemi dostupnými"
+#~ " ke každé události lze získat nad "
+#~ "zprávou ve formátu JSON nebo CSV."
+
 #~ msgid "csv"
 #~ msgstr "csv"
 
diff --git a/lib/mentat/__init__.py b/lib/mentat/__init__.py
index 7d2af1fd3f9c93a7d615c214f65f31ecfa568c7d..44fbd1326ba9638143b318a07434b688b0768a6a 100644
--- a/lib/mentat/__init__.py
+++ b/lib/mentat/__init__.py
@@ -20,4 +20,4 @@ open-source project.
 
 __author__  = "Jan Mach <jan.mach@cesnet.cz>"
 __credits__ = "Pavel Kácha <pavel.kacha@cesnet.cz>, Andrea Kropáčová <andrea.kropacova@cesnet.cz>"
-__version__ = "2.7.20"
+__version__ = "2.8.110"
diff --git a/lib/mentat/const.py b/lib/mentat/const.py
index a7fec6b16153d5de7d0521b88c84c31788e92730..922a0839b4d3af31fbf5d016c151289fa011c536 100644
--- a/lib/mentat/const.py
+++ b/lib/mentat/const.py
@@ -71,6 +71,8 @@ DFLT_INTERVAL_RUNLOG = 60
 
 DFLT_QUEUE_SIZE_LIMIT = 5000
 """Default limit for number of messages in the queue."""
+DFLT_QUEUE_IN_PERMS = 0o775
+"""Default interval in seconds for checking the input queue for new messages."""
 DFLT_QUEUE_IN_CHECK_INTERVAL = 3
 """Default interval in seconds for checking the input queue for new messages."""
 DFLT_QUEUE_OUT_CHECK_INTERVAL = 10
diff --git a/lib/mentat/daemon/component/filer.py b/lib/mentat/daemon/component/filer.py
index 58989bda3d80c2efc49291108154a8d0bfe87f34..90816c8bba00fd1184c1476eb77766eecdb171e5 100644
--- a/lib/mentat/daemon/component/filer.py
+++ b/lib/mentat/daemon/component/filer.py
@@ -22,6 +22,7 @@ __credits__ = "Pavel Kácha <pavel.kacha@cesnet.cz>, Andrea Kropáčová <andrea
 
 import os
 import traceback
+import shutil
 
 #
 # Custom libraries.
@@ -75,6 +76,7 @@ class FilerDaemonComponent(pyzenkit.zendaemon.ZenDaemonComponent):  # pylint: di
 
         # Initialize internal variables
         self.queue_in_dir    = None
+        self.queue_in_perms  = None
         self.queue_out_dir   = None
         self.queue_out_limit = None
         self.queue_out_wait  = None
@@ -120,27 +122,18 @@ class FilerDaemonComponent(pyzenkit.zendaemon.ZenDaemonComponent):  # pylint: di
         Perform component setup.
         """
         self.queue_in_dir    = daemon.cc(daemon.CORE_FILEQUEUE).get(mentat.dirq.DirectoryQueue.CONFIG_DIR_QUEUE)
+        self.queue_in_perms  = daemon.cc(daemon.CORE_FILEQUEUE).get(mentat.dirq.DirectoryQueue.CONFIG_QUEUE_PERMS)
         self.queue_out_dir   = daemon.cc(daemon.CORE_FILEQUEUE).get(mentat.dirq.DirectoryQueue.CONFIG_DIR_NEXT_QUEUE)
         self.queue_out_limit = daemon.cc(daemon.CORE_FILEQUEUE).get(self.CONFIG_QUEUE_OUT_LIMIT)
         self.queue_out_wait  = daemon.cc(daemon.CORE_FILEQUEUE).get(self.CONFIG_QUEUE_OUT_WAIT)
 
-        # Attempt to create queue directories
-        if not os.path.isdir(self.queue_in_dir):
-            daemon.logger.debug(
-                "[STATUS] Component '{}': Preparing inbound message queue directory '{}'".format(
-                    self.cid,
-                    self.queue_in_dir
-                )
-            )
-            os.makedirs(self.queue_in_dir)
-        if self.queue_out_dir and not os.path.isdir(self.queue_out_dir):
-            daemon.logger.debug(
-                "[STATUS] Component '{}': Preparing outbound message queue directory '{}'".format(
-                    self.cid,
-                    self.queue_out_dir
-                )
-            )
-            os.makedirs(self.queue_out_dir)
+        # Make sure input queue directory exists
+        self._prepare_workdir(daemon, self.queue_in_dir, daemon.c(daemon.CONFIG_USER), daemon.c(daemon.CONFIG_GROUP), self.queue_in_perms)
+        self._check_workdir_writability(daemon, self.queue_in_dir)
+
+        # Make sure output queue directory is accessible and writeble
+        if self.queue_out_dir:
+            self._check_workdir_writability(daemon, self.queue_out_dir)
 
         self.dirq          = mentat.dirq.DirectoryQueue(**daemon.cc(daemon.CORE_FILEQUEUE))
         self.status        = self.STATUS_RUNNING
@@ -188,6 +181,38 @@ class FilerDaemonComponent(pyzenkit.zendaemon.ZenDaemonComponent):  # pylint: di
                 )
             )
 
+    def _prepare_workdir(self, daemon, dir_name, user = None, group = None, perms = None):
+        if not os.path.isdir(dir_name):
+            daemon.logger.info(
+                "[STATUS] Component '{}': Preparing work directory '{}' ({}:{},{})".format(
+                    self.cid, dir_name, str(user), str(group), str(oct(perms))
+                )
+            )
+            try:
+                os.makedirs(dir_name)
+                if perms:
+                    os.chmod(dir_name, perms)
+                if user or group:
+                    shutil.chown(dir_name, user = user[0], group = group[0])
+            except:
+                msg = "Unable to create work directory '{}' with 'UID:{},GID:{},PERMS:{}' as current effective user 'EUID:{},EGID:{}': '{}'".format(
+                    dir_name, str(user), str(group), str(oct(perms)), os.geteuid(), os.getegid(), traceback.format_exc()
+                )
+                daemon.logger.error("[STATUS] Component '{}': {}".format(self.cid, msg))
+                raise pyzenkit.zendaemon.ZenDaemonComponentException(msg)
+
+    def _check_workdir_writability(self, daemon, dir_name):
+        if not os.path.isdir(dir_name):
+            msg = "Work directory '{}' does not exist".format(dir_name)
+            daemon.logger.error("[STATUS] Component '{}': {}".format(self.cid, msg))
+            raise pyzenkit.zendaemon.ZenDaemonComponentException(msg)
+        if not os.access(dir_name, os.W_OK):
+            msg = "Work directory '{}' is not writable for current effective user 'EUID:{},EGID:{}'".format(
+                dir_name, os.geteuid(), os.getegid()
+            )
+            daemon.logger.error("[STATUS] Component '{}': {}".format(self.cid, msg))
+            raise pyzenkit.zendaemon.ZenDaemonComponentException(msg)
+
     #---------------------------------------------------------------------------
 
     def cbk_event_start(self, daemon, args):
diff --git a/lib/mentat/daemon/component/test_filer.py b/lib/mentat/daemon/component/test_filer.py
index d61ee1e0c7da9811151e6b0a8096395c3411525d..bef5173eaf1b6819d951f85ad4934c7f00994a4e 100644
--- a/lib/mentat/daemon/component/test_filer.py
+++ b/lib/mentat/daemon/component/test_filer.py
@@ -69,15 +69,18 @@ class TestMentatDaemonFiler(DaemonComponentTestCase):
     def _get_daemon_mock(self):
         return self._build_daemon_mock(
             [
-                3
+                None,
+                None,
+                3,
             ],
             # daemon.cc(daemon.CORE_FILEQUEUE)
             [
-                {"dir_next_queue": DIRD, "dir_queue": DIRQ, "queue_out_limit": 100, "queue_out_wait": 3 },
-                {"dir_next_queue": DIRD, "dir_queue": DIRQ, "queue_out_limit": 100, "queue_out_wait": 3 },
-                {"dir_next_queue": DIRD, "dir_queue": DIRQ, "queue_out_limit": 100, "queue_out_wait": 3 },
-                {"dir_next_queue": DIRD, "dir_queue": DIRQ, "queue_out_limit": 100, "queue_out_wait": 3 },
-                {"dir_next_queue": DIRD, "dir_queue": DIRQ, "queue_out_limit": 100, "queue_out_wait": 3 },
+                {"dir_next_queue": DIRD, "dir_queue": DIRQ, "queue_out_limit": 100, "queue_out_wait": 3, "queue_perms": 0o775 },
+                {"dir_next_queue": DIRD, "dir_queue": DIRQ, "queue_out_limit": 100, "queue_out_wait": 3, "queue_perms": 0o775 },
+                {"dir_next_queue": DIRD, "dir_queue": DIRQ, "queue_out_limit": 100, "queue_out_wait": 3, "queue_perms": 0o775 },
+                {"dir_next_queue": DIRD, "dir_queue": DIRQ, "queue_out_limit": 100, "queue_out_wait": 3, "queue_perms": 0o775 },
+                {"dir_next_queue": DIRD, "dir_queue": DIRQ, "queue_out_limit": 100, "queue_out_wait": 3, "queue_perms": 0o775 },
+                {"dir_next_queue": DIRD, "dir_queue": DIRQ, "queue_out_limit": 100, "queue_out_wait": 3, "queue_perms": 0o775 },
             ]
         )
 
diff --git a/lib/mentat/daemon/component/test_parser.py b/lib/mentat/daemon/component/test_parser.py
index c0045e8de5d19e8120b7ca66d0fd6e1ec7955365..2918938611e62259a7e4d1cfd0f3619ed40af10d 100644
--- a/lib/mentat/daemon/component/test_parser.py
+++ b/lib/mentat/daemon/component/test_parser.py
@@ -104,6 +104,7 @@ class TestMentatDaemonParser(unittest.TestCase):
         ])
 
         result_b = self.obj.cbk_event_message_update(daemon, result_a[1])
+        self.assertEqual(result_b[0], daemon.FLAG_CONTINUE)
         #pprint(result_b)
         #pprint(daemon.mock_calls)
 
diff --git a/lib/mentat/daemon/piper.py b/lib/mentat/daemon/piper.py
index 2638fc16652d29cb9395e42bddc07b4e5d8e3801..5a22dca84424f8f25838fdb9a9235a6485432be5 100644
--- a/lib/mentat/daemon/piper.py
+++ b/lib/mentat/daemon/piper.py
@@ -126,6 +126,7 @@ class PiperDaemon(mentat.daemon.base.MentatBaseDaemon):
 
     # List of possible configuration keys.
     CONFIG_QUEUE_IN_DIR    = 'queue_in_dir'
+    CONFIG_QUEUE_IN_PERMS  = 'queue_in_perms'
     CONFIG_QUEUE_IN_WAIT   = 'queue_in_wait'
     CONFIG_QUEUE_OUT_DIR   = 'queue_out_dir'
     CONFIG_QUEUE_OUT_LIMIT = 'queue_out_limit'
@@ -209,6 +210,7 @@ class PiperDaemon(mentat.daemon.base.MentatBaseDaemon):
         """
         cfgs = (
             (self.CONFIG_QUEUE_IN_DIR,    self.name),
+            (self.CONFIG_QUEUE_IN_PERMS,  mentat.const.DFLT_QUEUE_IN_PERMS),
             (self.CONFIG_QUEUE_IN_WAIT,   mentat.const.DFLT_QUEUE_IN_CHECK_INTERVAL),
             (self.CONFIG_QUEUE_OUT_DIR,   None),
             (self.CONFIG_QUEUE_OUT_LIMIT, mentat.const.DFLT_QUEUE_SIZE_LIMIT),
@@ -246,8 +248,11 @@ class PiperDaemon(mentat.daemon.base.MentatBaseDaemon):
         ccfg[mentat.dirq.DirectoryQueue.CONFIG_DIR_NEXT_QUEUE] = self._get_queue_dir_path(
             self.c(self.CONFIG_QUEUE_OUT_DIR)
         )
+        ccfg[mentat.dirq.DirectoryQueue.CONFIG_QUEUE_PERMS] = self.c(self.CONFIG_QUEUE_IN_PERMS)
         ccfg[mentat.daemon.component.filer.FilerDaemonComponent.CONFIG_QUEUE_OUT_LIMIT] = self.c(self.CONFIG_QUEUE_OUT_LIMIT)
         ccfg[mentat.daemon.component.filer.FilerDaemonComponent.CONFIG_QUEUE_OUT_WAIT]  = self.c(self.CONFIG_QUEUE_OUT_WAIT)
+        ccfg[self.CONFIG_USER]  = self.c(self.CONFIG_USER)
+        ccfg[self.CONFIG_GROUP] = self.c(self.CONFIG_GROUP)
         self.config[self.CORE][self.CORE_FILEQUEUE] = ccfg
 
     def _get_queue_dir_path(self, queue_dir):
diff --git a/lib/mentat/daemon/test_piper.py b/lib/mentat/daemon/test_piper.py
index 05e9cf5598f380bf9371681039491801f36daba6..8b173fdc0355cff8d726d76a9312d512dcae88e0 100644
--- a/lib/mentat/daemon/test_piper.py
+++ b/lib/mentat/daemon/test_piper.py
@@ -19,7 +19,7 @@ __credits__ = "Pavel Kácha <pavel.kacha@cesnet.cz>, Andrea Kropáčová <andrea
 
 import unittest
 
-import mentat.daemon.piper
+#import mentat.daemon.piper
 
 
 class TestMentatBackupScript(unittest.TestCase):
diff --git a/lib/mentat/datatype/sqldb.py b/lib/mentat/datatype/sqldb.py
index 7c10979767c80be0ea06729084d20e1038688763..e595bf3ca94f74530c89f12df44569e0c15c4e21 100644
--- a/lib/mentat/datatype/sqldb.py
+++ b/lib/mentat/datatype/sqldb.py
@@ -353,7 +353,6 @@ class GroupModel(MODEL):
     source      = sqlalchemy.Column(sqlalchemy.String(50), nullable = False)
     description = sqlalchemy.Column(sqlalchemy.String, nullable = False)
     enabled     = sqlalchemy.Column(sqlalchemy.Boolean, nullable = False, default = True)
-    managed     = sqlalchemy.Column(sqlalchemy.Boolean, nullable = False, default = False)
 
     members = sqlalchemy.orm.relationship('UserModel', secondary = _asoc_group_members, back_populates = 'memberships', order_by = 'UserModel.fullname')
     members_wanted = sqlalchemy.orm.relationship('UserModel', secondary = _asoc_group_members_wanted, back_populates = 'memberships_wanted', order_by = 'UserModel.fullname')
@@ -409,7 +408,6 @@ class GroupModel(MODEL):
             'source':         str(self.source),
             'description':    str(self.description),
             'enabled':        bool(self.enabled),
-            'managed':        bool(self.managed),
             'members':        [(x.id, x.login) for x in self.members],
             'members_wanted': [(x.id, x.login) for x in self.members_wanted],
             'managers':       [(x.id, x.login) for x in self.managers],
@@ -602,13 +600,13 @@ class SettingsReportingModel(MODEL):  # pylint: disable=locally-disabled,too-few
     group_id = sqlalchemy.Column(sqlalchemy.Integer, sqlalchemy.ForeignKey('groups.id', onupdate = "CASCADE", ondelete = "CASCADE"), nullable = False)
     group = sqlalchemy.orm.relationship('GroupModel', back_populates = 'settings_rep')
 
-    emails_low         = sqlalchemy.Column(sqlalchemy.dialects.postgresql.ARRAY(sqlalchemy.String, dimensions = 1))
-    emails_medium      = sqlalchemy.Column(sqlalchemy.dialects.postgresql.ARRAY(sqlalchemy.String, dimensions = 1))
-    emails_high        = sqlalchemy.Column(sqlalchemy.dialects.postgresql.ARRAY(sqlalchemy.String, dimensions = 1))
-    emails_critical    = sqlalchemy.Column(sqlalchemy.dialects.postgresql.ARRAY(sqlalchemy.String, dimensions = 1))
-    mode               = sqlalchemy.Column(sqlalchemy.Enum(*REPORTING_MODES, name='reporting_modes'))
-    locale             = sqlalchemy.Column(sqlalchemy.String)
-    timezone           = sqlalchemy.Column(sqlalchemy.String)
+    emails_low = sqlalchemy.Column(sqlalchemy.dialects.postgresql.ARRAY(sqlalchemy.String, dimensions = 1), default = [], nullable = False)
+    emails_medium = sqlalchemy.Column(sqlalchemy.dialects.postgresql.ARRAY(sqlalchemy.String, dimensions = 1), default = [], nullable = False)
+    emails_high = sqlalchemy.Column(sqlalchemy.dialects.postgresql.ARRAY(sqlalchemy.String, dimensions = 1), default = [], nullable = False)
+    emails_critical = sqlalchemy.Column(sqlalchemy.dialects.postgresql.ARRAY(sqlalchemy.String, dimensions = 1), default = [], nullable = False)
+    mode = sqlalchemy.Column(sqlalchemy.Enum(*REPORTING_MODES, name='reporting_modes'))
+    locale = sqlalchemy.Column(sqlalchemy.String)
+    timezone = sqlalchemy.Column(sqlalchemy.String)
 
     redirect = sqlalchemy.Column(sqlalchemy.Boolean)
 
@@ -623,10 +621,10 @@ class SettingsReportingModel(MODEL):  # pylint: disable=locally-disabled,too-few
             'id':                 int(self.id),
             'createtime':         str(self.createtime),
             'group':              str(self.group),
-            'emails_low':         [str(x) for x in self.emails_low] if self.emails_low is not None else None,
-            'emails_medium':      [str(x) for x in self.emails_medium] if self.emails_medium is not None else None,
-            'emails_high':        [str(x) for x in self.emails_high] if self.emails_high is not None else None,
-            'emails_critical':    [str(x) for x in self.emails_critical] if self.emails_critical is not None else None,
+            'emails_low':         [str(x) for x in self.emails_low],
+            'emails_medium':      [str(x) for x in self.emails_medium],
+            'emails_high':        [str(x) for x in self.emails_high],
+            'emails_critical':    [str(x) for x in self.emails_critical],
             'mode':               str(self.mode) if self.mode is not None else None,
             'locale':             str(self.locale) if self.locale is not None else None,
             'timezone':           str(self.timezone) if self.timezone is not None else None,
@@ -642,10 +640,10 @@ def setrepmodel_from_typeddict(structure, defaults = None):
         defaults = {}
 
     sqlobj = SettingsReportingModel()
-    sqlobj.emails_low         = structure.get('rep_emails_low', None)
-    sqlobj.emails_medium      = structure.get('rep_emails_medium', None)
-    sqlobj.emails_high        = structure.get('rep_emails_high', None)
-    sqlobj.emails_critical    = structure.get('rep_emails_critical', None)
+    sqlobj.emails_low         = structure.get('rep_emails_low', [])
+    sqlobj.emails_medium      = structure.get('rep_emails_medium', [])
+    sqlobj.emails_high        = structure.get('rep_emails_high', [])
+    sqlobj.emails_critical    = structure.get('rep_emails_critical', [])
     sqlobj.mode               = structure.get('rep_mode', None)
     sqlobj.redirect           = structure.get('rep_redirect', None)
 
@@ -784,7 +782,7 @@ class EventReportModel(MODEL):
     # Number of relapsed events.
     evcount_rlp     = sqlalchemy.Column(sqlalchemy.Integer)
 
-    mail_to  = sqlalchemy.Column(sqlalchemy.dialects.postgresql.ARRAY(sqlalchemy.String, dimensions = 1))
+    mail_to  = sqlalchemy.Column(sqlalchemy.dialects.postgresql.ARRAY(sqlalchemy.String, dimensions = 1), default = [], nullable = False)
     mail_dt  = sqlalchemy.Column(sqlalchemy.DateTime)
     mail_res = sqlalchemy.Column(sqlalchemy.String)
 
diff --git a/lib/mentat/datatype/test_sqldb.py b/lib/mentat/datatype/test_sqldb.py
index 364f49ed929b175fa354b21cae8c4450ecad4527..af4be1ff54204618476e59649b11ea83e8a64657 100644
--- a/lib/mentat/datatype/test_sqldb.py
+++ b/lib/mentat/datatype/test_sqldb.py
@@ -298,10 +298,14 @@ class TestMentatDatatypeSqldb(unittest.TestCase):
 
         group1 = GroupModel(name = 'abuse@cesnet.cz',  source = 'manual', description = 'CESNET, z.s.p.o.')
 
-        network1 = NetworkModel(group = group1, netname = 'NET1', source = 'manual', network = '192.168.0.0/24', description = 'Descr.')  # pylint: disable=locally-disabled,unused-variable
-        network2 = NetworkModel(group = group1, netname = 'NET2', source = 'manual', network = '10.0.0.0/8')  # pylint: disable=locally-disabled,unused-variable
-        network3 = NetworkModel(group = group1, netname = 'NET3', source = 'manual', network = '::1/128')  # pylint: disable=locally-disabled,unused-variable
-        network4 = NetworkModel(group = group1, netname = 'NET4', source = 'manual', network = '2001:ff::/64')  # pylint: disable=locally-disabled,unused-variable
+        network1 = NetworkModel(group = group1, netname = 'NET1', source = 'manual', network = '192.168.0.0/24', description = 'Descr.')
+        self.assertIsNotNone(network1)
+        network2 = NetworkModel(group = group1, netname = 'NET2', source = 'manual', network = '10.0.0.0/8')
+        self.assertIsNotNone(network2)
+        network3 = NetworkModel(group = group1, netname = 'NET3', source = 'manual', network = '::1/128')
+        self.assertIsNotNone(network3)
+        network4 = NetworkModel(group = group1, netname = 'NET4', source = 'manual', network = '2001:ff::/64')
+        self.assertIsNotNone(network4)
 
         self.session.add(group1)
         self.session.commit()
@@ -360,8 +364,10 @@ class TestMentatDatatypeSqldb(unittest.TestCase):
 
         group1 = GroupModel(name = 'abuse@cesnet.cz',  source = 'manual', description = 'CESNET, z.s.p.o.')
 
-        filter1 = FilterModel(group = group1, name = 'FLT1', type = 'basic', filter = 'Source.IP4 == 127.0.0.1', description = 'DESC1')  # pylint: disable=locally-disabled,unused-variable
-        filter2 = FilterModel(group = group1, name = 'FLT2', type = 'advanced', filter = 'Source.IP4 == 127.0.0.2', description = 'DESC2')  # pylint: disable=locally-disabled,unused-variable
+        filter1 = FilterModel(group = group1, name = 'FLT1', type = 'basic', filter = 'Source.IP4 == 127.0.0.1', description = 'DESC1')
+        self.assertIsNotNone(filter1)
+        filter2 = FilterModel(group = group1, name = 'FLT2', type = 'advanced', filter = 'Source.IP4 == 127.0.0.2', description = 'DESC2')
+        self.assertIsNotNone(filter2)
 
         self.session.add(group1)
         self.session.commit()
diff --git a/lib/mentat/dirq.py b/lib/mentat/dirq.py
index 8f0f38f705f138f094ec6c9960bda9da80bf5737..7a86f34905a41c39529da5289814bdf33f342b1e 100644
--- a/lib/mentat/dirq.py
+++ b/lib/mentat/dirq.py
@@ -61,6 +61,9 @@ class DirectoryQueue:
 
     CONFIG_DIR_QUEUE      = 'dir_queue'
     CONFIG_DIR_NEXT_QUEUE = 'dir_next_queue'
+    CONFIG_USER           = 'user'
+    CONFIG_GROUP          = 'group'
+    CONFIG_QUEUE_PERMS    = 'queue_perms'
 
 
     def __init__(self, dir_queue, **kwargs):
@@ -86,6 +89,9 @@ class DirectoryQueue:
             self.STAT_CNT_DISPATCHED: 0,
             self.STAT_CNT_DUPLICATED: 0,
         }
+        self.user  = kwargs.get(self.CONFIG_USER,        None)
+        self.group = kwargs.get(self.CONFIG_GROUP,       None)
+        self.perms = kwargs.get(self.CONFIG_QUEUE_PERMS, None)
 
         self._prepare_queue_dir(self.dir_queue)
 
@@ -121,12 +127,8 @@ class DirectoryQueue:
         Prepare given queue directory.
         """
         if not os.path.isdir(dir_queue):
-            try:
-                os.makedirs(dir_queue)
-            except:
-                raise DirectoryQueueException("Unable to create queue directory '{}': '{}'".format(dir_queue, traceback.format_exc()))
-        if not os.access(dir_queue, os.W_OK):
-            raise DirectoryQueueException("Queue directory '{}' must be writable".format(dir_queue))
+            self._prepare_queue_workdir(dir_queue, self.user, self.group, self.perms)
+        self._check_writability(dir_queue)
 
         for subd in (os.path.join(dir_queue, self.SUBDIR_INCOMING),
                      os.path.join(dir_queue, self.SUBDIR_PENDING),
@@ -135,12 +137,30 @@ class DirectoryQueue:
             if not subd:
                 continue
             if not os.path.isdir(subd):
-                try:
-                    os.mkdir(subd)
-                except:
-                    raise DirectoryQueueException("Unable to create queue subdirectory '{}': '{}'".format(subd, traceback.format_exc()))
-            if not os.access(subd, os.W_OK):
-                raise DirectoryQueueException("Queue subdirectory '{}' must be writable".format(subd))
+                self._prepare_queue_workdir(subd, self.user, self.group, self.perms)
+            self._check_writability(subd)
+
+    def _prepare_queue_workdir(self, dir_name, user = None, group = None, perms = None):
+        try:
+            os.makedirs(dir_name)
+            if perms:
+                os.chmod(dir_name, perms)
+            if user or group:
+                shutil.chown(dir_name, user = user[0], group = group[0])
+        except:
+            raise DirectoryQueueException(
+                "Unable to create queue directory '{}' with 'UID:{},GID:{},PERMS:{}' as current effective user 'EUID:{},EGID:{}': '{}'".format(
+                    dir_name, str(user), str(group), str(oct(perms)), os.geteuid(), os.getegid(), traceback.format_exc()
+                )
+            )
+
+    def _check_writability(self, dir_name):
+        if not os.access(dir_name, os.W_OK):
+            raise DirectoryQueueException(
+                "Queue directory '{}' is not writable for current effective user 'EUID:{},EGID:{}'".format(
+                    dir_name, os.geteuid(), os.getegid()
+                )
+            )
 
     def _generate_id(self, device=0, inode=0, suffix='msg'):
         """
@@ -171,7 +191,7 @@ class DirectoryQueue:
             mf = open("{}.meta".format(file_tgt), 'w')
             json.dump(metadata, mf, sort_keys = True, indent = 4)
             mf.close()
-        except OSError as e:
+        except OSError:
             pass
 
     #---------------------------------------------------------------------------
diff --git a/lib/mentat/fixtures.py b/lib/mentat/fixtures.py
new file mode 100644
index 0000000000000000000000000000000000000000..a797c71e6bcfc4dad97b8c67a2b695d4c520cbb6
--- /dev/null
+++ b/lib/mentat/fixtures.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#-------------------------------------------------------------------------------
+# This file is part of Mentat system (https://mentat.cesnet.cz/).
+#
+# Copyright (C) since 2011 CESNET, z.s.p.o (http://www.ces.net/)
+# Use of this source is governed by the MIT license, see LICENSE file.
+#-------------------------------------------------------------------------------
+
+
+"""
+Mentat system management and inspection library.
+"""
+
+
+__author__ = "Jan Mach <jan.mach@cesnet.cz>"
+__credits__ = "Pavel Kácha <pavel.kacha@cesnet.cz>, Andrea Kropáčová <andrea.kropacova@cesnet.cz>"
+
+
+from mentat.datatype.sqldb import UserModel, GroupModel, NetworkModel,\
+    FilterModel, SettingsReportingModel
+
+
+class MentatFixtures():
+    """
+    Class representing Mentat real-time module configuration for control utility.
+    """
+    def __init__(self, eventservice, sqlservice, logservice):
+        self.eventservice = eventservice
+        self.sqlservice   = sqlservice
+        self.logservice   = logservice
+
+    def import_to_db(self):
+        """
+        Import data fixtures into database.
+        """
+        account_user = UserModel(
+            login = 'user',
+            fullname = 'Demo User',
+            email = 'user@bogus-domain.org',
+            organization = 'BOGUS DOMAIN, a.l.e.',
+            roles = ['user'],
+            enabled = True
+        )
+        account_developer = UserModel(
+            login = 'developer',
+            fullname = 'Demo Developer',
+            email = 'developer@bogus-domain.org',
+            organization = 'BOGUS DOMAIN, a.l.e.',
+            roles = ['user', 'developer'],
+            enabled = True
+        )
+        account_maintainer = UserModel(
+            login = 'maintainer',
+            fullname = 'Demo Maintainer',
+            email = 'maintainer@bogus-domain.org',
+            organization = 'BOGUS DOMAIN, a.l.e.',
+            roles = ['user', 'maintainer'],
+            enabled = True
+        )
+        account_admin = UserModel(
+            login = 'admin',
+            fullname = 'Demo Admin',
+            email = 'admin@bogus-domain.org',
+            organization = 'BOGUS DOMAIN, a.l.e.',
+            roles = ['user', 'admin'],
+            enabled = True
+        )
+        group = GroupModel(
+            name = 'DEMO_GROUP',
+            source = 'manual',
+            description = 'Demo Group',
+            enabled = True
+        )
+        group.members.append(account_user)
+        group.members.append(account_developer)
+        group.members.append(account_maintainer)
+        group.members.append(account_admin)
+
+        group.managers.append(account_maintainer)
+        group.managers.append(account_admin)
+
+        SettingsReportingModel(
+            group = group,
+            emails = ['abuse@bogus-domain.org'],
+            redirect = True
+        )
+
+        NetworkModel(
+            group = group,
+            netname = 'NETNAME1',
+            source = 'manual',
+            network = '192.168.0.0/24',
+            description = 'First demonstration IPv4 network'
+        )
+        NetworkModel(
+            group = group,
+            netname = 'NETNAME2',
+            source = 'manual',
+            network = '195.113.144.0/24',
+            description = 'Second demonstration IPv4 network'
+        )
+        NetworkModel(
+            group = group,
+            netname = 'NETNAME3',
+            source = 'manual',
+            network = '2001::/16',
+            description = 'First demonstration IPv6 network'
+        )
+
+        FilterModel(
+            group = group,
+            name = 'Filter Queeg',
+            type = 'advanced',
+            filter = 'Node.Name == "cz.cesnet.queeg"',
+            description = 'Filter out all messages originating from cz.cesnet.queeg detection node'
+        )
+
+        for dbobject in [account_user, account_developer, account_maintainer, account_admin, group]:
+            try:
+                self.sqlservice.session.add(dbobject)
+                self.sqlservice.session.commit()
+                self.logservice.info("Added demo object to database: '%s'", str(dbobject))
+            except Exception as exc:
+                self.sqlservice.session.rollback()
+                self.logservice.info("Unable to add demo object to database: '%s' (%s)", str(dbobject), str(exc))
+
+    def remove_from_db(self):
+        """
+        Remove data fixtures from database.
+        """
+        q_account_user = self.sqlservice.session.query(UserModel).filter(UserModel.login == 'user')
+        q_account_developer = self.sqlservice.session.query(UserModel).filter(UserModel.login == 'developer')
+        q_account_maintainer = self.sqlservice.session.query(UserModel).filter(UserModel.login == 'maintainer')
+        q_account_admin = self.sqlservice.session.query(UserModel).filter(UserModel.login == 'admin')
+        q_group = self.sqlservice.session.query(GroupModel).filter(GroupModel.name == 'DEMO_GROUP')
+        self.sqlservice.session.commit()
+
+        for q_dbobject in [q_account_user, q_account_developer, q_account_maintainer, q_account_admin, q_group]:
+            try:
+                dbobject = q_dbobject.first()
+                if dbobject:
+                    self.sqlservice.session.delete(dbobject)
+                    self.sqlservice.session.commit()
+                    self.logservice.info("Deleted demo object from database: '%s'", str(dbobject))
+            except Exception as exc:
+                self.sqlservice.session.rollback()
+                self.logservice.info("Unable to remove demo object from database: '%s'", str(exc))
+
diff --git a/lib/mentat/idea/internal.py b/lib/mentat/idea/internal.py
index 529439d412d7807b3ecaef9f4dfa86434747b035..733c0b38e36d0a57c6482343cc62372aae403f78 100644
--- a/lib/mentat/idea/internal.py
+++ b/lib/mentat/idea/internal.py
@@ -514,7 +514,7 @@ class IdeaGhost(Idea):
 
         try:
             return cls(idea_raw)
-        except Exception as exc:
+        except Exception:
             print("Record:")
             pprint.pprint(record)
             print("IDEA raw:")
diff --git a/lib/mentat/module/cleanup.py b/lib/mentat/module/cleanup.py
index cfe196e860c4f6ff2403e5548be2771c310741cc..8e3b9afd201e412683ff90d46215a2e8da689c96 100644
--- a/lib/mentat/module/cleanup.py
+++ b/lib/mentat/module/cleanup.py
@@ -51,7 +51,7 @@ Custom command line options
 ``--db-path dir-name``
     Path to database files (for disk usage measurements).
 
-    *Type:* ``string``, *default:* ``/var/lib/postgresql/10/main``
+    *Type:* ``string``, *default:* ``/var/lib/postgresql``
 
 ``--simulate``
     Perform simulation, do not remove anything (*flag*).
@@ -235,7 +235,7 @@ class MentatCleanupScript(mentat.script.fetcher.FetcherScript):
         :rtype: dict
         """
         cfgs = (
-            (self.CONFIG_DB_PATH,  '/var/lib/postgresql/11/main'),
+            (self.CONFIG_DB_PATH,  '/var/lib/postgresql'),
             (self.CONFIG_SIMULATE, False),
             (self.CONFIG_EVENTS,   []),
             (self.CONFIG_TABLES,   []),
diff --git a/lib/mentat/module/controller.py b/lib/mentat/module/controller.py
index 0d6b6a808142468321564dc7b9591676934d8ae8..f0c0356306736e29113b027c4e85ff72839483fc 100644
--- a/lib/mentat/module/controller.py
+++ b/lib/mentat/module/controller.py
@@ -60,7 +60,7 @@ Usage examples
     # Work with particular modules.
     mentat-controller.py --command start --target mentat-storage.py
     mentat-controller.py --command stop --target mentat-enricher.py mentat-inspector.py
-    mentat-controller.py --command signal-usr1 --target mentat-inspector-b.py
+    mentat-controller.py --command signal-usr1 --target mentat-inspector.py
 
 
 Available script commands
@@ -540,7 +540,7 @@ class MentatControllerScript(mentat.script.base.MentatBaseScript):
         status = self.get_system_status()
         self.retc = status['result'][0]  # pylint: disable=locally-disabled,attribute-defined-outside-init
 
-        if self.retc == mentat.system.STATUS_CJ_ENABLED:
+        if self.retc == mentat.system.STATUS_CJ_DISABLED:
             self.logger.info("System shutdown seems successful")
             return self.RESULT_SUCCESS
 
diff --git a/lib/mentat/module/dbmngr.py b/lib/mentat/module/dbmngr.py
index e6c6f8c2da75c4d55a8ae9b907fc0c882c95fc64..3a4c889d6e90a67ce90f7ee7ac10a01991ab7932 100644
--- a/lib/mentat/module/dbmngr.py
+++ b/lib/mentat/module/dbmngr.py
@@ -142,8 +142,8 @@ import pyzenkit.zenscript
 import mentat.script.fetcher
 import mentat.const
 
-from mentat.datatype.sqldb import UserModel, GroupModel, NetworkModel,\
-    FilterModel, SettingsReportingModel
+from mentat.datatype.sqldb import UserModel
+from mentat.fixtures import MentatFixtures
 
 
 class MentatDbmngrScript(mentat.script.fetcher.FetcherScript):
@@ -301,96 +301,7 @@ class MentatDbmngrScript(mentat.script.fetcher.FetcherScript):
         """
         self.logger.info("Populating main database with demonstration objects.")
 
-        account_user = UserModel(
-            login = 'user',
-            fullname = 'Demo User',
-            email = 'user@bogus-domain.org',
-            organization = 'BOGUS DOMAIN, a.l.e.',
-            roles = ['user'],
-            enabled = True
-        )
-        account_developer = UserModel(
-            login = 'developer',
-            fullname = 'Demo Developer',
-            email = 'developer@bogus-domain.org',
-            organization = 'BOGUS DOMAIN, a.l.e.',
-            roles = ['user', 'developer'],
-            enabled = True
-        )
-        account_maintainer = UserModel(
-            login = 'maintainer',
-            fullname = 'Demo Maintainer',
-            email = 'maintainer@bogus-domain.org',
-            organization = 'BOGUS DOMAIN, a.l.e.',
-            roles = ['user', 'maintainer'],
-            enabled = True
-        )
-        account_admin = UserModel(
-            login = 'admin',
-            fullname = 'Demo Admin',
-            email = 'admin@bogus-domain.org',
-            organization = 'BOGUS DOMAIN, a.l.e.',
-            roles = ['user', 'admin'],
-            enabled = True
-        )
-        group = GroupModel(
-            name = 'DEMO_GROUP',
-            source = 'manual',
-            description = 'Demo Group',
-            enabled = True
-        )
-        group.members.append(account_user)
-        group.members.append(account_developer)
-        group.members.append(account_maintainer)
-        group.members.append(account_admin)
-
-        group.managers.append(account_maintainer)
-        group.managers.append(account_admin)
-
-        SettingsReportingModel(
-            group = group,
-            emails = ['abuse@bogus-domain.org'],
-            redirect = True
-        )
-
-        NetworkModel(
-            group = group,
-            netname = 'NETNAME1',
-            source = 'manual',
-            network = '192.168.0.0/24',
-            description = 'First demonstration IPv4 network'
-        )
-        NetworkModel(
-            group = group,
-            netname = 'NETNAME2',
-            source = 'manual',
-            network = '195.113.144.0/24',
-            description = 'Second demonstration IPv4 network'
-        )
-        NetworkModel(
-            group = group,
-            netname = 'NETNAME3',
-            source = 'manual',
-            network = '2001::/16',
-            description = 'First demonstration IPv6 network'
-        )
-
-        FilterModel(
-            group = group,
-            name = 'Filter Queeg',
-            type = 'advanced',
-            filter = 'Node.Name == "cz.cesnet.queeg"',
-            description = 'Filter out all messages originating from cz.cesnet.queeg detection node'
-        )
-
-        for dbobject in [account_user, account_developer, account_maintainer, account_admin, group]:
-            try:
-                self.sqlservice.session.add(dbobject)
-                self.sqlservice.session.commit()
-                self.logger.info("Added demo object to database: '%s'", str(dbobject))
-            except Exception as exc:
-                self.sqlservice.session.rollback()
-                self.logger.info("Unable to add demo object to database: '%s' (%s)", str(dbobject), str(exc))
+        MentatFixtures(self.eventservice, self.sqlservice, self.logger).import_to_db()
 
         return self.RESULT_SUCCESS
 
@@ -403,23 +314,7 @@ class MentatDbmngrScript(mentat.script.fetcher.FetcherScript):
         """
         self.logger.info("Removing demonstration objects from main database.")
 
-        q_account_user = self.sqlservice.session.query(UserModel).filter(UserModel.login == 'user')
-        q_account_developer = self.sqlservice.session.query(UserModel).filter(UserModel.login == 'developer')
-        q_account_maintainer = self.sqlservice.session.query(UserModel).filter(UserModel.login == 'maintainer')
-        q_account_admin = self.sqlservice.session.query(UserModel).filter(UserModel.login == 'admin')
-        q_group = self.sqlservice.session.query(GroupModel).filter(GroupModel.name == 'DEMO_GROUP')
-        self.sqlservice.session.commit()
-
-        for q_dbobject in [q_account_user, q_account_developer, q_account_maintainer, q_account_admin, q_group]:
-            try:
-                dbobject = q_dbobject.first()
-                if dbobject:
-                    self.sqlservice.session.delete(dbobject)
-                    self.sqlservice.session.commit()
-                    self.logger.info("Deleted demo object from database: '%s'", str(dbobject))
-            except Exception as exc:
-                self.sqlservice.session.rollback()
-                self.logger.info("Unable to remove demo object from database: '%s'", str(exc))
+        MentatFixtures(self.eventservice, self.sqlservice, self.logger).remove_from_db()
 
         return self.RESULT_SUCCESS
 
diff --git a/lib/mentat/plugin/app/mailer.py b/lib/mentat/plugin/app/mailer.py
index 9b36a66321e7f69967e769eb6fb12bcf2f682170..3f740e7c9233481121aadd6b06172ba91950b692 100644
--- a/lib/mentat/plugin/app/mailer.py
+++ b/lib/mentat/plugin/app/mailer.py
@@ -32,6 +32,7 @@ __author__  = "Jan Mach <jan.mach@cesnet.cz>"
 __credits__ = "Pavel Kácha <pavel.kacha@cesnet.cz>, Andrea Kropáčová <andrea.kropacova@cesnet.cz>"
 
 
+import smtplib
 import weakref
 from subprocess import Popen, PIPE
 
@@ -61,6 +62,9 @@ class MailerPlugin(pyzenkit.baseapp.ZenAppPlugin):
     CONFIG_MAIL_RETURN_PATH = 'mail_return_path'
     CONFIG_MAIL_ADMIN       = 'mail_admin'
     CONFIG_MAIL_TEST_MODE   = 'mail_test_mode'
+    CONFIG_MAIL_DEV_MODE    = 'mail_dev_mode'
+    CONFIG_MAIL_DEV_SERVER  = 'mail_dev_server'
+    CONFIG_MAIL_DEV_PORT    = 'mail_dev_port'
 
     def __init__(self, settings = None):
         """
@@ -93,8 +97,11 @@ class MailerPlugin(pyzenkit.baseapp.ZenAppPlugin):
         arggroup_plugin.add_argument('--mail-reply-to',    type = str, default = None, help = 'reply to email address (repeatable)', action='append')
         arggroup_plugin.add_argument('--mail-return-path', type = str, default = None, help = 'return address for undeliverable emails')
         arggroup_plugin.add_argument('--mail-admin',       type = str, default = None, help = 'admin email address (repeatable)', action='append')
+        arggroup_plugin.add_argument('--mail-dev-server',  type = str, default = None, help = 'development SMTP server hostname')
+        arggroup_plugin.add_argument('--mail-dev-port',    type = int, default = None, help = 'development SMTP server port')
 
         arggroup_plugin.add_argument('--mail-test-mode', help = 'send emails in test mode (flag)', action = 'store_true', default = None)
+        arggroup_plugin.add_argument('--mail-dev-mode',  help = 'send emails in development mode (flag)', action = 'store_true', default = None)
 
         return argparser
 
@@ -111,7 +118,10 @@ class MailerPlugin(pyzenkit.baseapp.ZenAppPlugin):
             self.CONFIG_MAIL_REPLY_TO:    None,
             self.CONFIG_MAIL_RETURN_PATH: None,
             self.CONFIG_MAIL_ADMIN:       'root',
-            self.CONFIG_MAIL_TEST_MODE:   False
+            self.CONFIG_MAIL_TEST_MODE:   False,
+            self.CONFIG_MAIL_DEV_MODE:    False,
+            self.CONFIG_MAIL_DEV_SERVER:  None,
+            self.CONFIG_MAIL_DEV_PORT:    None
         })
         return config
 
@@ -155,6 +165,22 @@ class MailerPlugin(pyzenkit.baseapp.ZenAppPlugin):
         with Popen(["/usr/sbin/sendmail", "-t", "-oi", "-f", envelope_from], stdin=PIPE) as proc:
             proc.communicate(bytes(email.as_string(), 'UTF-8'))
 
+    @staticmethod
+    def mail_smtplib(email, server, port):
+        """
+        Send given email via smtplib.
+
+        :param mentat.emails.base.BaseEmail email: Email object.
+        """
+        envelope_from = email.get_header(
+            'return-path',
+            email.get_header('from')
+        )
+        server = server or 'localhost'
+        port   = port or 25
+        with smtplib.SMTP(server, port) as smtp:
+            smtp.send_message(email, from_addr = envelope_from)
+
     #---------------------------------------------------------------------------
 
     def email_send(self, email_class, email_headers, email_params, flag_redirect = False):
@@ -225,6 +251,14 @@ class MailerPlugin(pyzenkit.baseapp.ZenAppPlugin):
 
         self.get_application().logger.info("Sending email: '{}'".format(str(email_headers)))
         msg = email_class(email_headers, **email_params)
-        self.mail_sendmail(msg)
+
+        if self.get_application().c(self.CONFIG_MAIL_DEV_MODE):
+            self.mail_smtplib(
+                msg,
+                self.get_application().c(self.CONFIG_MAIL_DEV_SERVER),
+                self.get_application().c(self.CONFIG_MAIL_DEV_PORT)
+            )
+        else:
+            self.mail_sendmail(msg)
 
         return msg
diff --git a/lib/mentat/reports/event.py b/lib/mentat/reports/event.py
index 317caedf9cc626647361e7cacb9a8588d36fd3a6..3773a28310cfaaa8e2cf48691b101ee5ce2abeaf 100644
--- a/lib/mentat/reports/event.py
+++ b/lib/mentat/reports/event.py
@@ -23,7 +23,6 @@ import os
 import json
 import datetime
 import zipfile
-import csv
 from copy import deepcopy
 
 #
@@ -66,79 +65,6 @@ def json_default(val):
         return val.isoformat()
     return str(val)
 
-def csv_dict(idea):
-    """
-    Convert selected attributes of given IDEA message into flat dictionary suitable for CSV dump. This is a legacy feature from old version of Mentat system and due to its shortcomings is planned to be removed in the future. It was implemented only for the purposes of compatibility and transition from old version of Mentat system to new one.
-    """
-    dump = {}
-
-    dtime = jpath_value(idea, 'DetectTime')
-    ctime = jpath_value(idea, 'CreateTime')
-    if not ctime:
-        ctime = dtime
-    anlzr = jpath_value(idea, 'Node[#].SW')
-    dtctr = jpath_value(idea, 'Node[#].Name')
-    descr = jpath_value(idea, 'Description')
-    if not descr:
-        descr = jpath_value(idea, 'Note')
-    categ = jpath_values(idea, 'Category')
-
-    sip   = jpath_values(idea, 'Source.IP4') + jpath_values(idea, 'Source.IP6')
-    sport = jpath_values(idea, 'Source.Port')
-    tport = jpath_values(idea, 'Target.Port')
-    sproto = jpath_values(idea, 'Source.Proto')
-    tproto = jpath_values(idea, 'Target.Proto')
-
-    concnt = jpath_value(idea, 'ConnCount')
-    note   = jpath_value(idea, 'Note')
-    impact = jpath_value(idea, '_Mentat.Impact')
-
-    #---
-
-    dump['date_gmt']       = str(ctime)
-    dump['detected_gmt']   = str(dtime)
-    dump['analyzer']       = anlzr or '-'
-    dump['detector']       = dtctr or '-'
-    dump['classification'] = descr or '-'
-    dump['con_cnt']        = concnt or '-'
-    dump['date_ts']        = int(ctime.timestamp())
-    dump['detected_ts']    = int(dtime.timestamp())
-    dump['note']           = note or '-'
-    dump['impact']         = impact or '-'
-    dump['src_host']       = '-'
-
-    if categ:
-        dump['categories'] = ','.join([str(x) for x in categ])
-    else:
-        dump['categories'] = '-'
-
-    if sip:
-        dump['src_ip'] = ','.join([str(x) for x in sip])
-    else:
-        dump['src_ip'] = '-'
-
-    if sport:
-        dump['src_port'] = ','.join([str(x) for x in sport])
-    else:
-        dump['src_port'] = '-'
-
-    if tport:
-        dump['tgt_port'] = ','.join([str(x) for x in tport])
-    else:
-        dump['tgt_port'] = '-'
-
-    if sproto:
-        dump['src_proto'] = ','.join([str(x) for x in sproto])
-    else:
-        dump['src_proto'] = '-'
-
-    if tproto:
-        dump['tgt_proto'] = ','.join([str(x) for x in tproto])
-    else:
-        dump['tgt_proto'] = '-'
-
-    return dump
-
 
 class EventReporter(BaseReporter):
     """
@@ -391,15 +317,11 @@ class EventReporter(BaseReporter):
             mentat.stats.idea.evaluate_events(events_all)
         )
 
-        # Save report data to disk in various formats.
+        # Save report data to disk in JSON format.
         self._save_to_json_files(
             events_all,
             'security-report-{}.json'.format(report.label)
         )
-        self._save_to_csv_files(
-            events_all,
-            'security-report-{}.csv'.format(report.label)
-        )
 
         report.structured_data = self.prepare_structured_data(events.get('regular_aggr', {}), events.get('relapsed_aggr', {}), settings)
 
@@ -468,15 +390,11 @@ class EventReporter(BaseReporter):
                 mentat.stats.idea.evaluate_events(events_all)
             )
 
-            # Save report data to disk in various formats.
+            # Save report data to disk in JSON format.
             self._save_to_json_files(
                 events_all,
                 'security-report-{}.json'.format(report.label)
             )
-            self._save_to_csv_files(
-                events_all,
-                'security-report-{}.csv'.format(report.label)
-            )
 
             report.structured_data = self.prepare_structured_data({src: events_regular_aggr}, {src: events_relapsed_aggr}, settings)
 
@@ -889,43 +807,6 @@ class EventReporter(BaseReporter):
 
         return filepath, zipfilepath
 
-    def _save_to_csv_files(self, data, filename):
-        """
-        Helper method for saving given data into given CSV file. This method can
-        be used for saving report data attachments to disk.
-
-        :param dict data: Data to be serialized.
-        :param str filename: Name of the target CSV file.
-        :return: Paths to the created files.
-        :rtype: tuple
-        """
-        dirpath = mentat.const.construct_report_dirpath(self.reports_dir, filename)
-        filepath = os.path.join(dirpath, filename)
-
-        while True:
-            try:
-                with open(filepath, 'w', newline='') as csvf:
-                    fieldnames = ['date_gmt', 'detected_gmt', 'analyzer', 'detector', 'classification', 'categories', 'src_ip', 'src_host', 'src_port', 'tgt_port', 'src_proto', 'tgt_proto', 'con_cnt', 'date_ts', 'detected_ts', 'note', 'impact']
-                    csvwriter = csv.DictWriter(
-                        csvf,
-                        fieldnames = fieldnames,
-                        quoting = csv.QUOTE_MINIMAL,
-                        delimiter = ';'
-                    )
-
-                    csvwriter.writeheader()
-                    for event in data:
-                        csvwriter.writerow(csv_dict(event))
-                break
-            except FileNotFoundError:
-                os.makedirs(dirpath)
-
-        zipfilepath = "{}.zip".format(filepath)
-        with zipfile.ZipFile(zipfilepath, mode = 'w') as zipf:
-            zipf.write(filepath, compress_type = zipfile.ZIP_DEFLATED)
-
-        return filepath, zipfilepath
-
     def _save_to_files(self, data, filename):
         """
         Helper method for saving given data into given file. This method can be
diff --git a/lib/mentat/reports/test_event.py b/lib/mentat/reports/test_event.py
index 2638dd4fa9ed3aaec52f86766be2584688ae1897..8a7a405c8fc06a0941eb552ec25e03c3871361e3 100644
--- a/lib/mentat/reports/test_event.py
+++ b/lib/mentat/reports/test_event.py
@@ -201,14 +201,7 @@ class TestMentatReportsEvent(unittest.TestCase):
         self.sqlstorage.database_drop()
         self.eventstorage.database_drop()
 
-    def test_01_csv_dict(self):
-        """
-        Test :py:func:`mentat.reports.event.csv_dict` function.
-        """
-        #pprint([mentat.reports.event.csv_dict(x) for x in self.ideas_obj])
-        self.assertTrue([mentat.reports.event.csv_dict(x) for x in self.ideas_obj])
-
-    def test_02_save_to_json_files(self):
+    def test_01_save_to_json_files(self):
         """
         Test :py:func:`mentat.reports.event.EventReporter._save_to_json_files` function.
         """
@@ -254,53 +247,7 @@ class TestMentatReportsEvent(unittest.TestCase):
         os.unlink(report_path)
         os.unlink("{}.zip".format(report_path))
 
-    def test_03_save_to_csv_files(self):
-        """
-        Test :py:func:`mentat.reports.event.EventReporter._save_to_csv_files` function.
-        """
-        self.maxDiff = None
-
-        # Test saving file without timestamp information.
-        report_file = 'utest-security-report.csv'
-        report_path = os.path.join(REPORTS_DIR, report_file)
-
-        self.assertEqual(
-            self.reporter._save_to_csv_files( # pylint: disable=locally-disabled,protected-access
-                self.ideas_obj,
-                report_file
-            ),
-            (report_path, "{}.zip".format(report_path))
-        )
-        self.assertTrue(
-            os.path.isfile(report_path)
-        )
-        self.assertTrue(
-            os.path.isfile("{}.zip".format(report_path))
-        )
-        os.unlink(report_path)
-        os.unlink("{}.zip".format(report_path))
-
-        # Test saving file with timestamp information.
-        report_file = 'utest-security-report-M20180726SL-HT9TC.csv'
-        report_path = os.path.join(REPORTS_DIR, '20180726', report_file)
-
-        self.assertEqual(
-            self.reporter._save_to_csv_files( # pylint: disable=locally-disabled,protected-access
-                self.ideas_obj,
-                report_file
-            ),
-            (report_path, "{}.zip".format(report_path))
-        )
-        self.assertTrue(
-            os.path.isfile(report_path)
-        )
-        self.assertTrue(
-            os.path.isfile("{}.zip".format(report_path))
-        )
-        os.unlink(report_path)
-        os.unlink("{}.zip".format(report_path))
-
-    def test_04_save_to_files(self):
+    def test_02_save_to_files(self):
         """
         Test :py:func:`mentat.reports.event.EventReporter._save_to_files` function.
         """
@@ -346,7 +293,7 @@ class TestMentatReportsEvent(unittest.TestCase):
         os.unlink(report_path)
         os.unlink("{}.zip".format(report_path))
 
-    def test_05_filter_events(self):
+    def test_03_filter_events(self):
         """
         Test :py:class:`mentat.reports.event.EventReporter.filter_events` function.
         """
@@ -384,7 +331,7 @@ class TestMentatReportsEvent(unittest.TestCase):
         self.assertEqual(list(sorted(aggr.keys())), ['anomaly-traffic'])
         self.assertEqual(list(aggr['anomaly-traffic'].keys()), ['10.0.2.1', '10.0.0.0/22'])
 
-    def test_06_fetch_severity_events(self):
+    def test_04_fetch_severity_events(self):
         """
         Test :py:class:`mentat.reports.event.EventReporter.fetch_severity_events` function.
         """
@@ -417,7 +364,7 @@ class TestMentatReportsEvent(unittest.TestCase):
         )
         self.assertEqual(list(map(lambda x: x['ID'], events)), [])
 
-    def test_07_j2t_idea_path_valueset(self):
+    def test_05_j2t_idea_path_valueset(self):
         """
         Test :py:class:`mentat.reports.event.EventReporter.j2t_idea_path_valueset` function.
         """
@@ -450,7 +397,7 @@ class TestMentatReportsEvent(unittest.TestCase):
             ['https', 'ssh']
         )
 
-    def test_08_render_report_summary(self):
+    def test_06_render_report_summary(self):
         """
         Test :py:class:`mentat.reports.event.EventReporter.render_report_summary` function.
         """
@@ -491,7 +438,7 @@ class TestMentatReportsEvent(unittest.TestCase):
         self.assertTrue(report_txt)
         self.assertEqual(report_txt.split('\n')[0], 'Vážení kolegové.')
 
-    def test_09_render_report_extra(self):
+    def test_07_render_report_extra(self):
         """
         Test :py:class:`mentat.reports.event.EventReporter.render_report_extra` function.
         """
diff --git a/lib/mentat/script/fetcher.py b/lib/mentat/script/fetcher.py
index f5c1773cd53bb0f484e13602298df5f516213d3f..82b0424350daee85ca6caf0898a0e51cf8e6613b 100644
--- a/lib/mentat/script/fetcher.py
+++ b/lib/mentat/script/fetcher.py
@@ -25,8 +25,6 @@ import time
 #
 # Custom libraries.
 #
-import pyzenkit.baseapp
-import pyzenkit.zenscript
 import mentat.const
 import mentat.script.base
 import mentat.plugin.app.eventstorage
diff --git a/lib/mentat/services/dnsr.py b/lib/mentat/services/dnsr.py
index 28fd6b79ea2775ac1f243433942f6ab179726049..334678bf63ef6068aecf2c5886dcfe8d3210cf49 100644
--- a/lib/mentat/services/dnsr.py
+++ b/lib/mentat/services/dnsr.py
@@ -71,8 +71,8 @@ class DnsService:
                     res = res[:-1] # trim trailing '.'
                 result.append({'type': 'PTR', 'value': res})
         except dns.exception.Timeout as exc:
-            raise RuntimeError("DNS query for {} timed out".format(ipaddr))
-        except dns.exception.DNSException as exc:
+            raise RuntimeError("DNS query for {} timed out".format(ipaddr)) from exc
+        except dns.exception.DNSException:
             pass
         return result
 
@@ -88,8 +88,8 @@ class DnsService:
                     res = str(res)
                     result.append({'type': qtype, 'value': res})
         except dns.exception.Timeout as exc:
-            raise RuntimeError("DNS query for {} timed out".format(hname))
-        except dns.exception.DNSException as exc:
+            raise RuntimeError("DNS query for {} timed out".format(hname)) from exc
+        except dns.exception.DNSException:
             pass
         return result
 
diff --git a/lib/mentat/stats/idea.py b/lib/mentat/stats/idea.py
index fbe0443a5c5d1ab9df4ed3086f8b29837682cbbf..8825c2b342894134c8b911684b62b9c4feafcc47 100644
--- a/lib/mentat/stats/idea.py
+++ b/lib/mentat/stats/idea.py
@@ -90,7 +90,7 @@ LIST_STAT_GROUPS = (
 """List of statistical groups. The statistics will be calculated separatelly for these."""
 
 LIST_AGGREGATIONS = (
-    [ST_SKEY_IPS,        ('Source.IP4',),                                                KEY_UNKNOWN],
+    [ST_SKEY_IPS,        ('Source.IP4', 'Source.IP6'),                                   KEY_UNKNOWN],
     #[ST_SKEY_IP4S,      ('Source.IP4',),                                                KEY_UNKNOWN],
     #[ST_SKEY_IP6S,      ('Source.IP6',),                                                KEY_UNKNOWN],
     [ST_SKEY_ANALYZERS,  ('Node[#].SW',),                                                KEY_UNKNOWN],
@@ -820,9 +820,9 @@ def _include_event_to_stats(stats, event, recurring = False, skip = None):
         if skip and rule[0] in skip:
             continue
 
+        values = []
         for jpath in rule[1]:
-            values = jpath_values(event, jpath)
-            if values: break
+            values = values + jpath_values(event, jpath)
         reg[rule[0]] = values
 
         if not values:
diff --git a/lib/mentat/stats/rrd.py b/lib/mentat/stats/rrd.py
index 7ec4f0a3451f7cd69604cdf235f4120878d4e217..b347605721e44bdac09eed59185ff5bbb9e02e54 100644
--- a/lib/mentat/stats/rrd.py
+++ b/lib/mentat/stats/rrd.py
@@ -1020,7 +1020,7 @@ class RrdStats:
 
         try:
             rrdargs = chspec['def_args'] + chspec['draw_args']
-            result = rrdtool.graphv(
+            rrdtool.graph(
                 chspec['path_chart'],
                 '--width',            '{}'.format(DFLT_WIDTH),
                 '--height',           '{}'.format(DFLT_HEIGHT),
@@ -1054,7 +1054,7 @@ class RrdStats:
 
         try:
             rrdargs = chspec['def_args'] + chspec['draw_args']
-            result = rrdtool.graphv(
+            rrdtool.graph(
                 chspec['path_schart'],
                 '--width',  '{}'.format(DFLT_SPARK_WIDTH),
                 '--height', '{}'.format(DFLT_SPARK_HEIGHT),
diff --git a/lib/mentat/stats/test_idea.py b/lib/mentat/stats/test_idea.py
index a990fbb905fc436b5a33dbafe1f734416264eeae..255c1021c29beb61d0070f80fb310e65664a9197 100644
--- a/lib/mentat/stats/test_idea.py
+++ b/lib/mentat/stats/test_idea.py
@@ -397,7 +397,8 @@ class TestMentatStatsIdea(unittest.TestCase):
                 '192.168.0.2-192.168.0.5': 3,
                 '192.168.0.200': 1,
                 '192.172.0.109': 1,
-                '192.172.0.200': 1
+                '192.172.0.200': 1,
+                '2001:db8::ff00:42:0/112': 3
             },
             'list_ids': ['msg01', 'msg02', 'msg03', 'msg04', 'msg05', 'msg06'],
             'severities': {'__unknown__': 6}
@@ -427,7 +428,7 @@ class TestMentatStatsIdea(unittest.TestCase):
                 'detectorsws': {'__REST__': 3,
                                 'cz.cesnet.holly/Beekeeper': 1,
                                 'org.example.kippo/Kippo': 2},
-                'ips': {'192.168.0.0/25': 3, '192.168.0.2-192.168.0.5': 3, '__REST__': 6},
+                'ips': {'192.168.0.0/25': 3, '192.168.0.2-192.168.0.5': 3, '__REST__': 9},
                 'severities': {'__unknown__': 6}
             }
         )
@@ -455,7 +456,7 @@ class TestMentatStatsIdea(unittest.TestCase):
                                 'org.example.dionaea/Kippo': 1,
                                 'org.example.kippo/Kippo': 2,
                                 'org.example.labrea/LaBrea': 1},
-                'ips': {'192.168.0.0/25': 3, '__REST__': 9},
+                'ips': {'192.168.0.0/25': 3, '__REST__': 12},
                 'severities': {'__unknown__': 6}
             }
         )
@@ -696,7 +697,8 @@ class TestMentatStatsIdea(unittest.TestCase):
                         '192.168.0.2-192.168.0.5': 9,
                         '192.168.0.200': 3,
                         '192.172.0.109': 3,
-                        '192.172.0.200': 3},
+                        '192.172.0.200': 3,
+                        '2001:db8::ff00:42:0/112': 9},
                 'severities': {'__unknown__': 18}
             }
         )
diff --git a/lib/mentat/stats/test_rrd.py b/lib/mentat/stats/test_rrd.py
index 31dadd1ec3155f3997ad28da6bc68c55eb434c9e..7281c174d03946ffaf700ee0faddc5934f7a25cd 100644
--- a/lib/mentat/stats/test_rrd.py
+++ b/lib/mentat/stats/test_rrd.py
@@ -321,6 +321,8 @@ class TestMentatStatsRrd(unittest.TestCase):
         self.test_04_update()
 
         result = self.stats.lookup()
+        self.assertIsInstance(result, list)
+        self.assertTrue(result)     # Not empty
 
     def test_08_generate(self):
         """
diff --git a/lib/vial/blueprints/auth_dev/forms.py b/lib/vial/blueprints/auth_dev/forms.py
index 20ca5d7accb6be5b82b8328b3aa7d8740fa69101..ed55ef4dcebb382d124cefe822ce7599540309f5 100644
--- a/lib/vial/blueprints/auth_dev/forms.py
+++ b/lib/vial/blueprints/auth_dev/forms.py
@@ -38,9 +38,6 @@ class LoginForm(flask_wtf.FlaskForm):
     submit = wtforms.SubmitField(
         lazy_gettext('Login')
     )
-    cancel = wtforms.SubmitField(
-        lazy_gettext('Cancel')
-    )
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
diff --git a/lib/vial/blueprints/auth_dev/templates/registration/email_user.txt b/lib/vial/blueprints/auth_dev/templates/registration/email_user.txt
index 7deac37bcd7423fc31bce59bab175bd679fd547f..a3f2d82c948afb81c0bcc7c5e85c8fab05589f90 100644
--- a/lib/vial/blueprints/auth_dev/templates/registration/email_user.txt
+++ b/lib/vial/blueprints/auth_dev/templates/registration/email_user.txt
@@ -23,7 +23,7 @@
 
 {{ _('After successfull activation you will be able to login and start using the system:') | wordwrap }}
 
-	{{ url_for('auth_pwd.login', _external = True ) }}
+	{{ url_for('auth.login', _external = True ) }}
 
 {{ _('Have a nice day') | wordwrap }}
 
diff --git a/lib/vial/blueprints/auth_env/templates/auth_env/registration/email_user.txt b/lib/vial/blueprints/auth_env/templates/auth_env/registration/email_user.txt
index 7deac37bcd7423fc31bce59bab175bd679fd547f..a3f2d82c948afb81c0bcc7c5e85c8fab05589f90 100644
--- a/lib/vial/blueprints/auth_env/templates/auth_env/registration/email_user.txt
+++ b/lib/vial/blueprints/auth_env/templates/auth_env/registration/email_user.txt
@@ -23,7 +23,7 @@
 
 {{ _('After successfull activation you will be able to login and start using the system:') | wordwrap }}
 
-	{{ url_for('auth_pwd.login', _external = True ) }}
+	{{ url_for('auth.login', _external = True ) }}
 
 {{ _('Have a nice day') | wordwrap }}
 
diff --git a/lib/vial/blueprints/auth_pwd/forms.py b/lib/vial/blueprints/auth_pwd/forms.py
index c8079f23bf32946b901101a5be8bcd3c238fb096..c588b75baa6799c826e846c3bdbf8baca1d5deaf 100644
--- a/lib/vial/blueprints/auth_pwd/forms.py
+++ b/lib/vial/blueprints/auth_pwd/forms.py
@@ -16,14 +16,12 @@ This module contains custom developer login form for Hawat.
 __author__ = "Honza Mach <honza.mach.ml@gmail.com>"
 
 
-import pytz
-
 import wtforms
 import flask_wtf
 from wtforms.ext.sqlalchemy.fields import QuerySelectMultipleField
 from flask_babel import lazy_gettext
 
-from vial.forms import check_login, check_email, check_unique_login, get_available_groups
+from vial.forms import check_login, check_unique_login, get_available_groups
 from vial.blueprints.users.forms import BaseUserAccountForm
 
 
@@ -49,9 +47,6 @@ class LoginForm(flask_wtf.FlaskForm):
     submit = wtforms.SubmitField(
         lazy_gettext('Login')
     )
-    cancel = wtforms.SubmitField(
-        lazy_gettext('Cancel')
-    )
 
 
 class RegisterUserAccountForm(BaseUserAccountForm):
diff --git a/lib/vial/blueprints/auth_pwd/templates/registration/email_user.txt b/lib/vial/blueprints/auth_pwd/templates/registration/email_user.txt
index 7deac37bcd7423fc31bce59bab175bd679fd547f..a3f2d82c948afb81c0bcc7c5e85c8fab05589f90 100644
--- a/lib/vial/blueprints/auth_pwd/templates/registration/email_user.txt
+++ b/lib/vial/blueprints/auth_pwd/templates/registration/email_user.txt
@@ -23,7 +23,7 @@
 
 {{ _('After successfull activation you will be able to login and start using the system:') | wordwrap }}
 
-	{{ url_for('auth_pwd.login', _external = True ) }}
+	{{ url_for('auth.login', _external = True ) }}
 
 {{ _('Have a nice day') | wordwrap }}
 
diff --git a/lib/vial/blueprints/design_bs3/templates/_layout_login.html b/lib/vial/blueprints/design_bs3/templates/_layout_login.html
index 8561d430f749ca3efe605696daf723583d47c912..bbe4f9269becd50f24ed24b37f8b5a480b0eee6c 100644
--- a/lib/vial/blueprints/design_bs3/templates/_layout_login.html
+++ b/lib/vial/blueprints/design_bs3/templates/_layout_login.html
@@ -17,7 +17,6 @@
                                 {{ form.csrf_token }}
                                 {%- endif %}
 
-                                {{ form.cancel(class_='btn btn-default') }}
                                 {{ form.submit(class_='btn btn-primary') }}
                             <fieldset>
                         </form>
diff --git a/lib/vial/blueprints/design_bs3/templates/_layout_registration.html b/lib/vial/blueprints/design_bs3/templates/_layout_registration.html
index f61dbc43b7f61e0ad23a48419ad30c0cb994b47a..0c42620c35387cc942d510116b6eabf758634a46 100644
--- a/lib/vial/blueprints/design_bs3/templates/_layout_registration.html
+++ b/lib/vial/blueprints/design_bs3/templates/_layout_registration.html
@@ -19,7 +19,6 @@
                                 {{ form.csrf_token }}
                                 {%- endif %}
 
-                                {{ form.cancel(class_='btn btn-default') }}
                                 {{ form.submit(class_='btn btn-primary') }}
                             <fieldset>
                         </form>
diff --git a/lib/vial/blueprints/groups/__init__.py b/lib/vial/blueprints/groups/__init__.py
index 88db86123aa8d7e1f1a8a1be5f4d96f1474d0721..b7d31eb2c624a0cdd7d5f87c7aafbc0d3095d31a 100644
--- a/lib/vial/blueprints/groups/__init__.py
+++ b/lib/vial/blueprints/groups/__init__.py
@@ -140,10 +140,6 @@ class ListView(HTMLMixin, SQLAlchemyMixin, ItemListView):
                 query = query.filter(model.enabled == True)
             elif form_args['state'] == 'disabled':
                 query = query.filter(model.enabled == False)
-            elif form_args['state'] == 'managed':
-                query = query.filter(model.managed == True)
-            elif form_args['state'] == 'notmanaged':
-                query = query.filter(model.managed == False)
         # Adjust query based on record source selection.
         if 'source' in form_args and form_args['source']:
             query = query\
@@ -275,6 +271,16 @@ class ShowView(HTMLMixin, SQLAlchemyMixin, ItemShowView):
             'more.remove_membership',
             endpoint = 'users.removemembership'
         )
+        action_menu.add_entry(
+            'endpoint',
+            'more.add_management',
+            endpoint = 'users.addmanagement'
+        )
+        action_menu.add_entry(
+            'endpoint',
+            'more.remove_management',
+            endpoint = 'users.removemanagement'
+        )
         action_menu.add_entry(
             'endpoint',
             'more.enable',
@@ -659,8 +665,6 @@ class RemoveMemberView(HTMLMixin, SQLAlchemyMixin, ItemObjectRelationView):  # p
             group_id = flask.escape(str(kwargs['item']))
         )
 
-    #---------------------------------------------------------------------------
-
     @property
     def dbmodel(self):
         return self.get_model(vial.const.MODEL_GROUP)
@@ -691,8 +695,6 @@ class RemoveMemberView(HTMLMixin, SQLAlchemyMixin, ItemObjectRelationView):  # p
     def change_item(cls, **kwargs):
         kwargs['item'].members.remove(kwargs['other'])
 
-    #---------------------------------------------------------------------------
-
     @staticmethod
     def get_message_success(**kwargs):
         return gettext(
@@ -718,6 +720,181 @@ class RemoveMemberView(HTMLMixin, SQLAlchemyMixin, ItemObjectRelationView):  # p
         )
 
 
+class AddManagerView(HTMLMixin, SQLAlchemyMixin, ItemObjectRelationView):  # pylint: disable=locally-disabled,too-many-ancestors
+    """
+    View for adding group managers.
+    """
+    methods = ['GET','POST']
+
+    authentication = True
+
+    @classmethod
+    def get_view_name(cls):
+        return 'addmanager'
+
+    @classmethod
+    def get_view_title(cls, **kwargs):
+        return gettext('Add group manager')
+
+    @classmethod
+    def get_view_icon(cls):
+        return 'action-add-manager'
+
+    @classmethod
+    def get_menu_legend(cls, **kwargs):
+        return lazy_gettext(
+            'Add user &quot;%(user_id)s&quot; to group &quot;%(group_id)s&quot; as manager',
+            user_id  = flask.escape(str(kwargs['other'])),
+            group_id = flask.escape(str(kwargs['item']))
+        )
+
+    @property
+    def dbmodel(self):
+        return self.get_model(vial.const.MODEL_GROUP)
+
+    @property
+    def dbchlogmodel(self):
+        return self.get_model(vial.const.MODEL_ITEM_CHANGELOG)
+
+    @property
+    def dbmodel_other(self):
+        return self.get_model(vial.const.MODEL_USER)
+
+    @classmethod
+    def authorize_item_action(cls, **kwargs):
+        permission_m = flask_principal.Permission(
+            vial.acl.ManagementNeed(kwargs['item'].id)
+        )
+        return vial.acl.PERMISSION_POWER.can() or permission_m.can()
+
+    @classmethod
+    def validate_item_change(cls, **kwargs):  # pylint: disable=locally-disabled,unused-argument
+        # Reject item change in case given item is already manager.
+        if kwargs['other'] in kwargs['item'].managers:
+            return False
+        return True
+
+    @classmethod
+    def change_item(cls, **kwargs):
+        kwargs['item'].managers.append(kwargs['other'])
+        if kwargs['other'].is_state_disabled():
+            kwargs['other'].set_state_enabled()
+            flask.current_app.send_infomail(
+                'users.enable',
+                account = kwargs['other']
+            )
+
+    @staticmethod
+    def get_message_success(**kwargs):
+        return gettext(
+            'User <strong>%(user_id)s</strong> was successfully added as a manager to group <strong>%(group_id)s</strong>.',
+            user_id  = flask.escape(str(kwargs['other'])),
+            group_id = flask.escape(str(kwargs['item']))
+        )
+
+    @staticmethod
+    def get_message_failure(**kwargs):
+        return gettext(
+            'Unable to add user <strong>%(user_id)s</strong> as a manager to group <strong>%(group_id)s</strong>.',
+            user_id  = flask.escape(str(kwargs['other'])),
+            group_id = flask.escape(str(kwargs['item']))
+        )
+
+    @staticmethod
+    def get_message_cancel(**kwargs):
+        return gettext(
+            'Canceled adding user <strong>%(user_id)s</strong> as a manager to group <strong>%(group_id)s</strong>.',
+            user_id  = flask.escape(str(kwargs['other'])),
+            group_id = flask.escape(str(kwargs['item']))
+        )
+
+
+class RemoveManagerView(HTMLMixin, SQLAlchemyMixin, ItemObjectRelationView):  # pylint: disable=locally-disabled,too-many-ancestors
+    """
+    View for removing group managers.
+    """
+    methods = ['GET','POST']
+
+    authentication = True
+
+    @classmethod
+    def get_view_name(cls):
+        return 'removemanager'
+
+    @classmethod
+    def get_view_title(cls, **kwargs):
+        return gettext('Remove group manager')
+
+    @classmethod
+    def get_view_icon(cls):
+        return 'action-rem-manager'
+
+    @classmethod
+    def get_menu_legend(cls, **kwargs):
+        return lazy_gettext(
+            'Remove user &quot;%(user_id)s&quot; from group &quot;%(group_id)s&quot; as manager',
+            user_id  = flask.escape(str(kwargs['other'])),
+            group_id = flask.escape(str(kwargs['item']))
+        )
+
+    @property
+    def dbmodel(self):
+        return self.get_model(vial.const.MODEL_GROUP)
+
+    @property
+    def dbchlogmodel(self):
+        return self.get_model(vial.const.MODEL_ITEM_CHANGELOG)
+
+    @property
+    def dbmodel_other(self):
+        return self.get_model(vial.const.MODEL_USER)
+
+    @classmethod
+    def authorize_item_action(cls, **kwargs):
+        permission_m = flask_principal.Permission(
+            vial.acl.ManagementNeed(kwargs['item'].id)
+        )
+        return vial.acl.PERMISSION_POWER.can() or permission_m.can()
+
+    @classmethod
+    def validate_item_change(cls, **kwargs):  # pylint: disable=locally-disabled,unused-argument
+        # Reject item change in case given item is not already manager.
+        if kwargs['other'] not in kwargs['item'].managers:
+            return False
+        return True
+
+    @classmethod
+    def change_item(cls, **kwargs):
+        try:
+            kwargs['item'].managers.remove(kwargs['other'])
+        except ValueError:
+            pass
+
+    @staticmethod
+    def get_message_success(**kwargs):
+        return gettext(
+            'User <strong>%(user_id)s</strong> was successfully removed as a manager from group <strong>%(group_id)s</strong>.',
+            user_id  = flask.escape(str(kwargs['other'])),
+            group_id = flask.escape(str(kwargs['item']))
+        )
+
+    @staticmethod
+    def get_message_failure(**kwargs):
+        return gettext(
+            'Unable to remove user <strong>%(user_id)s</strong> as a manager from group <strong>%(group_id)s</strong>.',
+            user_id  = flask.escape(str(kwargs['other'])),
+            group_id = flask.escape(str(kwargs['item']))
+        )
+
+    @staticmethod
+    def get_message_cancel(**kwargs):
+        return gettext(
+            'Canceled removing user <strong>%(user_id)s</strong> as a manager from group <strong>%(group_id)s</strong>.',
+            user_id  = flask.escape(str(kwargs['other'])),
+            group_id = flask.escape(str(kwargs['item']))
+        )
+
+
 class EnableView(HTMLMixin, SQLAlchemyMixin, ItemEnableView):  # pylint: disable=locally-disabled,too-many-ancestors
     """
     View for enabling existing groups.
@@ -914,16 +1091,18 @@ def get_blueprint():
         url_prefix = '/{}'.format(BLUEPRINT_NAME)
     )
 
-    hbp.register_view_class(ListView,         '/list')
-    hbp.register_view_class(CreateView,       '/create')
-    hbp.register_view_class(ShowView,         '/<int:item_id>/show')
-    hbp.register_view_class(ShowByNameView,   '/<item_id>/show_by_name')
-    hbp.register_view_class(UpdateView,       '/<int:item_id>/update')
-    hbp.register_view_class(AddMemberView,    '/<int:item_id>/add_member/<int:other_id>')
-    hbp.register_view_class(RejectMemberView, '/<int:item_id>/reject_member/<int:other_id>')
-    hbp.register_view_class(RemoveMemberView, '/<int:item_id>/remove_member/<int:other_id>')
-    hbp.register_view_class(EnableView,       '/<int:item_id>/enable')
-    hbp.register_view_class(DisableView,      '/<int:item_id>/disable')
-    hbp.register_view_class(DeleteView,       '/<int:item_id>/delete')
+    hbp.register_view_class(ListView,          '/list')
+    hbp.register_view_class(CreateView,        '/create')
+    hbp.register_view_class(ShowView,          '/<int:item_id>/show')
+    hbp.register_view_class(ShowByNameView,    '/<item_id>/show_by_name')
+    hbp.register_view_class(UpdateView,        '/<int:item_id>/update')
+    hbp.register_view_class(AddMemberView,     '/<int:item_id>/add_member/<int:other_id>')
+    hbp.register_view_class(RejectMemberView,  '/<int:item_id>/reject_member/<int:other_id>')
+    hbp.register_view_class(RemoveMemberView,  '/<int:item_id>/remove_member/<int:other_id>')
+    hbp.register_view_class(AddManagerView,    '/<int:item_id>/add_manager/<int:other_id>')
+    hbp.register_view_class(RemoveManagerView, '/<int:item_id>/remove_manager/<int:other_id>')
+    hbp.register_view_class(EnableView,        '/<int:item_id>/enable')
+    hbp.register_view_class(DisableView,       '/<int:item_id>/disable')
+    hbp.register_view_class(DeleteView,        '/<int:item_id>/delete')
 
     return hbp
diff --git a/lib/vial/blueprints/groups/forms.py b/lib/vial/blueprints/groups/forms.py
index 5de09e03094011162fa503e18bd2901c97a4b466..53ce5ff20a17931551741e0048a56e1b521666a7 100644
--- a/lib/vial/blueprints/groups/forms.py
+++ b/lib/vial/blueprints/groups/forms.py
@@ -52,19 +52,6 @@ class BaseGroupForm(vial.forms.BaseItemForm):
         ],
         description = lazy_gettext('Origin of the group record, whether it was added manually, or via some automated mechanism from data from some third party system.')
     )
-    managed = wtforms.RadioField(
-        lazy_gettext('Self management:'),
-        validators = [
-            wtforms.validators.InputRequired(),
-        ],
-        choices = [
-            (True,  lazy_gettext('Enabled')),
-            (False, lazy_gettext('Disabled'))
-        ],
-        filters = [vial.forms.str_to_bool],
-        coerce = vial.forms.str_to_bool,
-        description = lazy_gettext('Boolean flag whether the group is self managed by group managers. When enabled group managers are expected to take care of the group management tasks and they get notifications about important events like group membership requests, etc.')
-    )
     members = QuerySelectMultipleField(
         lazy_gettext('Members:'),
         query_factory = vial.forms.get_available_users,
@@ -200,9 +187,7 @@ class GroupSearchForm(vial.forms.BaseSearchForm):
         choices = [
             ('', lazy_gettext('Nothing selected')),
             ('enabled',  lazy_gettext('Enabled')),
-            ('disabled', lazy_gettext('Disabled')),
-            ('managed',  lazy_gettext('Self-managed')),
-            ('notmanaged', lazy_gettext('Not self-managed'))
+            ('disabled', lazy_gettext('Disabled'))
         ],
         default = '',
         description = lazy_gettext('Search for groups with particular state.')
diff --git a/lib/vial/blueprints/groups/templates/groups/creatupdate.html b/lib/vial/blueprints/groups/templates/groups/creatupdate.html
index 3acbcfd2b566847cd210d8c587ed4ba154b42a3a..a08a12bd09fd0b63b775be2111fb05bb305d5272 100644
--- a/lib/vial/blueprints/groups/templates/groups/creatupdate.html
+++ b/lib/vial/blueprints/groups/templates/groups/creatupdate.html
@@ -19,9 +19,6 @@
     {%- if form | attr('enabled') %}
                                 {{ macros_form.render_form_item_radiobutton(form.enabled) }}
     {%- endif %}
-    {%- if form | attr('managed') %}
-                                {{ macros_form.render_form_item_radiobutton(form.managed) }}
-    {%- endif %}
     {%- if form | attr('members') %}
                                 {{ macros_form.render_form_item_select(form.members) }}
     {%- endif %}
diff --git a/lib/vial/blueprints/groups/templates/groups/show.html b/lib/vial/blueprints/groups/templates/groups/show.html
index 74129aa8b04cd4fa1685e83d7d704a8a87639579..fdf42a305d999da0e774b650289bc97f05e13193 100644
--- a/lib/vial/blueprints/groups/templates/groups/show.html
+++ b/lib/vial/blueprints/groups/templates/groups/show.html
@@ -68,14 +68,6 @@
                                                     {{ macros_site.render_label_item_state(item.enabled, True) }}
                                                 </td>
                                             </tr>
-                                            <tr>
-                                                <th>
-                                                    {{ _('Self management') }}:
-                                                </th>
-                                                <td>
-                                                    {{ macros_site.render_label_item_state(item.managed, True) }}
-                                                </td>
-                                            </tr>
                                         </tbody>
                                     </table>
                                 </div>
diff --git a/lib/vial/blueprints/groups/test/__init__.py b/lib/vial/blueprints/groups/test/__init__.py
index 5e51ec2f87f71c8566bde33a8996796dd8d6d3df..a45d1e9d35de4e63af58bb2d86693987421d1821 100644
--- a/lib/vial/blueprints/groups/test/__init__.py
+++ b/lib/vial/blueprints/groups/test/__init__.py
@@ -147,8 +147,7 @@ class GroupsCreateTestCase(TestRunnerMixin, ItemCreateVialTestCase):
     group_data_fixture = [
         ('name', 'TEST_GROUP'),
         ('description', 'Test group for unit testing purposes.'),
-        ('enabled', True),
-        ('managed', True)
+        ('enabled', True)
     ]
 
     def _attempt_fail(self):
diff --git a/lib/vial/blueprints/users/__init__.py b/lib/vial/blueprints/users/__init__.py
index bbfaa6334c9d4b7f2feb115638616823f0e662a4..fd84e20cf89b79a7e246e45ae757eb9107b2774a 100644
--- a/lib/vial/blueprints/users/__init__.py
+++ b/lib/vial/blueprints/users/__init__.py
@@ -153,7 +153,7 @@ class ListView(HTMLMixin, SQLAlchemyMixin, ItemListView):
             query = query\
                 .join(model.memberships)\
                 .filter(model.memberships.any(id = form_args['membership'].id))
-        # Adjust query based on user membership selection.
+        # Adjust query based on user management selection.
         if 'management' in form_args and form_args['management']:
             query = query\
                 .join(model.managements)\
@@ -272,6 +272,16 @@ class ShowView(HTMLMixin, SQLAlchemyMixin, ItemShowView):
             'more.remove_member',
             endpoint = 'groups.removemember'
         )
+        action_menu.add_entry(
+            'endpoint',
+            'more.add_manager',
+            endpoint = 'groups.addmanager'
+        )
+        action_menu.add_entry(
+            'endpoint',
+            'more.remove_manager',
+            endpoint = 'groups.removemanager'
+        )
         action_menu.add_entry(
             'endpoint',
             'more.enable',
@@ -803,6 +813,181 @@ class RemoveMembershipView(HTMLMixin, SQLAlchemyMixin, ItemObjectRelationView):
         )
 
 
+class AddManagementView(HTMLMixin, SQLAlchemyMixin, ItemObjectRelationView):  # pylint: disable=locally-disabled,too-many-ancestors
+    """
+    View for adding group managements.
+    """
+    methods = ['GET','POST']
+
+    authentication = True
+
+    @classmethod
+    def get_view_name(cls):
+        return 'addmanagement'
+
+    @classmethod
+    def get_view_title(cls, **kwargs):
+        return gettext('Add group management')
+
+    @classmethod
+    def get_view_icon(cls):
+        return 'action-add-manager'
+
+    @classmethod
+    def get_menu_legend(cls, **kwargs):
+        return lazy_gettext(
+            'Add user &quot;%(user_id)s&quot; to group &quot;%(group_id)s&quot; as manager',
+            user_id  = flask.escape(str(kwargs['item'])),
+            group_id = flask.escape(str(kwargs['other']))
+        )
+
+    @property
+    def dbmodel(self):
+        return self.get_model(vial.const.MODEL_USER)
+
+    @property
+    def dbmodel_other(self):
+        return self.get_model(vial.const.MODEL_GROUP)
+
+    @property
+    def dbchlogmodel(self):
+        return self.get_model(vial.const.MODEL_ITEM_CHANGELOG)
+
+    @classmethod
+    def authorize_item_action(cls, **kwargs):
+        permission_m = flask_principal.Permission(
+            vial.acl.ManagementNeed(kwargs['other'].id)
+        )
+        return vial.acl.PERMISSION_POWER.can() or permission_m.can()
+
+    @classmethod
+    def validate_item_change(cls, **kwargs):  # pylint: disable=locally-disabled,unused-argument
+        # Reject item change in case given item is already manager.
+        if kwargs['other'] in kwargs['item'].managements:
+            return False
+        return True
+
+    @classmethod
+    def change_item(cls, **kwargs):
+        kwargs['item'].managements.append(kwargs['other'])
+        if kwargs['item'].is_state_disabled():
+            kwargs['item'].set_state_enabled()
+            flask.current_app.send_infomail(
+                'users.enable',
+                account = kwargs['item']
+            )
+
+    @staticmethod
+    def get_message_success(**kwargs):
+        return gettext(
+            'User <strong>%(user_id)s</strong> was successfully added as a manager to group <strong>%(group_id)s</strong>.',
+            user_id  = flask.escape(str(kwargs['item'])),
+            group_id = flask.escape(str(kwargs['other']))
+        )
+
+    @staticmethod
+    def get_message_failure(**kwargs):
+        return gettext(
+            'Unable to add user <strong>%(user_id)s</strong> as a manager to group <strong>%(group_id)s</strong>.',
+            user_id  = flask.escape(str(kwargs['item'])),
+            group_id = flask.escape(str(kwargs['other']))
+        )
+
+    @staticmethod
+    def get_message_cancel(**kwargs):
+        return gettext(
+            'Canceled adding user <strong>%(user_id)s</strong> as a manager to group <strong>%(group_id)s</strong>.',
+            user_id  = flask.escape(str(kwargs['item'])),
+            group_id = flask.escape(str(kwargs['other']))
+        )
+
+
+class RemoveManagementView(HTMLMixin, SQLAlchemyMixin, ItemObjectRelationView):  # pylint: disable=locally-disabled,too-many-ancestors
+    """
+    View for removing group managements.
+    """
+    methods = ['GET','POST']
+
+    authentication = True
+
+    @classmethod
+    def get_view_name(cls):
+        return 'removemanagement'
+
+    @classmethod
+    def get_view_title(cls, **kwargs):
+        return gettext('Remove group management')
+
+    @classmethod
+    def get_view_icon(cls):
+        return 'action-rem-manager'
+
+    @classmethod
+    def get_menu_legend(cls, **kwargs):
+        return lazy_gettext(
+            'Remove user &quot;%(user_id)s&quot; from group &quot;%(group_id)s&quot; as manager',
+            user_id  = flask.escape(str(kwargs['item'])),
+            group_id = flask.escape(str(kwargs['other']))
+        )
+
+    @property
+    def dbmodel(self):
+        return self.get_model(vial.const.MODEL_USER)
+
+    @property
+    def dbmodel_other(self):
+        return self.get_model(vial.const.MODEL_GROUP)
+
+    @property
+    def dbchlogmodel(self):
+        return self.get_model(vial.const.MODEL_ITEM_CHANGELOG)
+
+    @classmethod
+    def authorize_item_action(cls, **kwargs):
+        permission_m = flask_principal.Permission(
+            vial.acl.ManagementNeed(kwargs['other'].id)
+        )
+        return vial.acl.PERMISSION_POWER.can() or permission_m.can()
+
+    @classmethod
+    def validate_item_change(cls, **kwargs):  # pylint: disable=locally-disabled,unused-argument
+        # Reject item change in case given item is not already manager.
+        if kwargs['other'] not in kwargs['item'].managements:
+            return False
+        return True
+
+    @classmethod
+    def change_item(cls, **kwargs):
+        try:
+            kwargs['item'].managements.remove(kwargs['other'])
+        except ValueError:
+            pass
+
+    @staticmethod
+    def get_message_success(**kwargs):
+        return gettext(
+            'User <strong>%(user_id)s</strong> was successfully removed as a manager from group <strong>%(group_id)s</strong>.',
+            user_id  = flask.escape(str(kwargs['item'])),
+            group_id = flask.escape(str(kwargs['other']))
+        )
+
+    @staticmethod
+    def get_message_failure(**kwargs):
+        return gettext(
+            'Unable to remove user <strong>%(user_id)s</strong> as a manager from group <strong>%(group_id)s</strong>.',
+            user_id  = flask.escape(str(kwargs['item'])),
+            group_id = flask.escape(str(kwargs['other']))
+        )
+
+    @staticmethod
+    def get_message_cancel(**kwargs):
+        return gettext(
+            'Canceled removing user <strong>%(user_id)s</strong> as a manager from group <strong>%(group_id)s</strong>.',
+            user_id  = flask.escape(str(kwargs['item'])),
+            group_id = flask.escape(str(kwargs['other']))
+        )
+
+
 class EnableView(HTMLMixin, SQLAlchemyMixin, ItemEnableView):  # pylint: disable=locally-disabled,too-many-ancestors
     """
     View for enabling existing user accounts.
@@ -1036,6 +1221,8 @@ def get_blueprint():
     hbp.register_view_class(AddMembershipView,    '/<int:item_id>/add_membership/<int:other_id>')
     hbp.register_view_class(RemoveMembershipView, '/<int:item_id>/remove_membership/<int:other_id>')
     hbp.register_view_class(RejectMembershipView, '/<int:item_id>/reject_membership/<int:other_id>')
+    hbp.register_view_class(AddManagementView,    '/<int:item_id>/add_management/<int:other_id>')
+    hbp.register_view_class(RemoveManagementView, '/<int:item_id>/remove_management/<int:other_id>')
     hbp.register_view_class(EnableView,           '/<int:item_id>/enable')
     hbp.register_view_class(DisableView,          '/<int:item_id>/disable')
     hbp.register_view_class(DeleteView,           '/<int:item_id>/delete')
diff --git a/lib/vial/blueprints/users/forms.py b/lib/vial/blueprints/users/forms.py
index 4cc6525570f6d42b38f2a3e067235d339ff99b12..0994537eca6768a43951ab04a6f72e2ed49296a2 100644
--- a/lib/vial/blueprints/users/forms.py
+++ b/lib/vial/blueprints/users/forms.py
@@ -61,9 +61,6 @@ class BaseUserAccountForm(vial.forms.BaseItemForm):
     submit = wtforms.SubmitField(
         lazy_gettext('Submit')
     )
-    cancel = wtforms.SubmitField(
-        lazy_gettext('Cancel')
-    )
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
diff --git a/lib/vial/const.py b/lib/vial/const.py
index 17ada15522e5c8c9c42e8fec8cd025f8c99edd98..2635720f758ff8dc2a31ecc19710e5926499aa71 100644
--- a/lib/vial/const.py
+++ b/lib/vial/const.py
@@ -265,6 +265,8 @@ ICONS = {
     'action-add-member':   '<i class="fas fa-fw fa-user-plus"></i>',
     'action-rej-member':   '<i class="fas fa-fw fa-user-minus"></i>',
     'action-rem-member':   '<i class="fas fa-fw fa-user-times"></i>',
+    'action-add-manager':  '<i class="fas fa-fw fa-user-plus"></i>',
+    'action-rem-manager':  '<i class="fas fa-fw fa-user-times"></i>',
     'action-save':         '<i class="fas fa-fw fa-save"></i>',
     'action-download':     '<i class="fas fa-fw fa-file-download"></i>',
     'action-download-zip': '<i class="fas fa-fw fa-file-archive"></i>',
diff --git a/lib/vial/jsglue.py b/lib/vial/jsglue.py
index 87118d98086ef8bf18a40585a727b764ea0ea512..bde129dc2eef24fdb8a162390d527be9041f3466 100644
--- a/lib/vial/jsglue.py
+++ b/lib/vial/jsglue.py
@@ -17,7 +17,7 @@
 import re, json
 
 from jinja2 import Markup
-from flask import current_app, make_response, url_for
+from flask import make_response, url_for
 
 
 JSGLUE_JS_PATH = '/jsglue.js'
diff --git a/lib/vial/test/fixtures.py b/lib/vial/test/fixtures.py
index 5f9d1e5f04af5763723ee193934db577b17a2f37..3dcf3dc623db3ae7a4823ff770570d02cfc8effd 100644
--- a/lib/vial/test/fixtures.py
+++ b/lib/vial/test/fixtures.py
@@ -58,6 +58,7 @@ def get_fixtures_db(app):
 
     group_a = _gen_group(DEMO_GROUP_A, 'Demo Group A')
     group_b = _gen_group(DEMO_GROUP_B, 'Demo Group B')
+    assert group_b      # Deliberately empty group
 
     group_a.members.append(account_user)
     group_a.members.append(account_developer)
diff --git a/lib/vial/test/runner.py b/lib/vial/test/runner.py
index 093b10bd50fae6db8ed01c985ca5f1eab813ad88..01180cc8776d574c14c90e615e441d97a109ae86 100644
--- a/lib/vial/test/runner.py
+++ b/lib/vial/test/runner.py
@@ -33,7 +33,7 @@ def _config_testapp_vial(app_config):
     app_config['LOG_FILE'] = '/var/tmp/vial-utest.log'
     app_config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://mentat:mentat@localhost/mentat_utest'
     app_config['MAIL_SERVER'] = 'localhost'
-    app_config['MAIL_PORT'] = 8025
+    app_config['MAIL_PORT'] = 1025
     app_config['MAIL_DEFAULT_SENDER'] = 'root@unittest'
     app_config['EMAIL_ADMINS'] = ['admin@unittest']
     app_config['MODELS'] = {
diff --git a/lib/vial/view/__init__.py b/lib/vial/view/__init__.py
index 7affc3f5568e566ab5d8084059557a37d232589d..dee54ac699bf7f998ba8d632018a9e609a8f4beb 100644
--- a/lib/vial/view/__init__.py
+++ b/lib/vial/view/__init__.py
@@ -1309,10 +1309,7 @@ class ItemShowView(RenderableView):  # pylint: disable=locally-disabled,abstract
         action_menu.add_entry(
             'endpoint',
             'list',
-            endpoint = '{}.{}'.format(
-                cls.module_name,
-                cls.get_view_endpoint_name().replace('show', 'list')
-            ),
+            endpoint = '{}.list'.format(cls.module_name),
             paramlist = []
         )
         action_menu.add_entry(
@@ -1422,14 +1419,15 @@ class ItemActionView(RenderableView):  # pylint: disable=locally-disabled,abstra
         """
         *Hook method*. Check the form for *cancel* button press and cancel the action.
         """
-        if getattr(form, vial.const.FORM_ACTION_CANCEL).data:
-            self.flash(
-                flask.Markup(self.get_message_cancel(**kwargs)),
-                vial.const.FLASH_INFO
-            )
-            return self.redirect(
-                default_url = self.get_url_next()
-            )
+        if hasattr(form, vial.const.FORM_ACTION_CANCEL):
+            if getattr(form, vial.const.FORM_ACTION_CANCEL).data:
+                self.flash(
+                    flask.Markup(self.get_message_cancel(**kwargs)),
+                    vial.const.FLASH_INFO
+                )
+                return self.redirect(
+                    default_url = self.get_url_next()
+                )
 
         return None
 
@@ -1592,10 +1590,7 @@ class ItemCreateView(ItemActionView):  # pylint: disable=locally-disabled,abstra
         breadcrumbs_menu.add_entry(
             'endpoint',
             'list',
-            endpoint = '{}.{}'.format(
-                cls.module_name,
-                cls.get_view_endpoint_name().replace('create', 'list')
-            ),
+            endpoint = '{}.list'.format(cls.module_name)
         )
         breadcrumbs_menu.add_entry(
             'endpoint',
@@ -1942,6 +1937,11 @@ class BaseRegisterView(ItemCreateView):  # pylint: disable=locally-disabled,abst
         Send information about new account registration to system
         admins. Use default locale for email content translations.
         """
+        flask.current_app.logger.info(
+            "Attempting to send information about registration of new account '{}' to system admins @: '{}'.".format(
+                account.login, ', '.join(flask.current_app.config['EMAIL_ADMINS'])
+            )
+        )
         mail_locale = flask.current_app.config['BABEL_DEFAULT_LOCALE']
         with force_locale(mail_locale):
             msg = flask_mail.Message(
@@ -1962,17 +1962,20 @@ class BaseRegisterView(ItemCreateView):  # pylint: disable=locally-disabled,abst
     @classmethod
     def inform_managers(cls, account, form_data):
         """
-        Send information about new account registration to the user.
+        Send information about new account registration to the group managers.
         Use manager`s locale for email content translations.
         """
         for group in account.memberships_wanted:
-            if not group.managed:
-                return
+            flask.current_app.logger.info(
+                "Attempting to send information about registration of new account '{}' to managers of group '{}'.".format(
+                    account.login, group.name
+                )
+            )
 
             if not group.managers:
-                flask.current_app.logger.error(
-                    "Group '{}' is marked as self-managed, but there are no managers.".format(
-                        group.name
+                flask.current_app.logger.info(
+                    "Unable to send information about registration of new account '{}' to managers of group '{}': there are no managers configured.".format(
+                        account.login, group.name
                     )
                 )
                 return
@@ -1998,6 +2001,11 @@ class BaseRegisterView(ItemCreateView):  # pylint: disable=locally-disabled,abst
                         justification = form_data['justification']
                     )
                     flask.current_app.mailer.send(msg)
+                    flask.current_app.logger.info(
+                        "Sent information about registration of new account '{}' to manager '{}' of group '{}'.".format(
+                            account.login, manager.email, group.name
+                        )
+                    )
 
     @classmethod
     def inform_user(cls, account, form_data):
@@ -2091,18 +2099,12 @@ class ItemUpdateView(ItemActionView):  # pylint: disable=locally-disabled,abstra
         breadcrumbs_menu.add_entry(
             'endpoint',
             'list',
-            endpoint = '{}.{}'.format(
-                cls.module_name,
-                cls.get_view_endpoint_name().replace('update', 'list')
-            )
+            endpoint = '{}.list'.format(cls.module_name)
         )
         breadcrumbs_menu.add_entry(
             'endpoint',
             'show',
-            endpoint = '{}.{}'.format(
-                cls.module_name,
-                cls.get_view_endpoint_name().replace('update', 'show')
-            )
+            endpoint = '{}.show'.format(cls.module_name)
         )
         breadcrumbs_menu.add_entry(
             'endpoint',
diff --git a/package.json b/package.json
index 8f21e53e5df75450caba0d7623f85e71929e0924..2450f6ab38dcfcd4b911c79ff35ca304966dd36a 100644
--- a/package.json
+++ b/package.json
@@ -37,8 +37,6 @@
         "cldr-segments-modern": "^34.0.0",
         "cldr-units-modern": "^34.0.0",
         "d3": "3.5.17",
-        "datatables.net": "^1.10.16",
-        "datatables.net-plugins": "^1.10.15",
         "eonasdan-bootstrap-datetimepicker": "^4.17.47",
         "globalize": "^1.4.0",
         "iana-tz-data": "^2018.5.0",
diff --git a/packaging/debian/control b/packaging/debian/control
index 2714f817271d57b3ef0942544eb4aab7f6b4aacb..26f8e69af318cb0565a31271a694daeea0a1f784 100644
--- a/packaging/debian/control
+++ b/packaging/debian/control
@@ -6,8 +6,9 @@ Build-Depends: debhelper (>= 9)
 
 Package: mentat-ng
 Architecture: all
-Depends: sudo, adduser, python3, python3-venv, libpython3-dev, libpq-dev,
- rrdtool, librrd-dev, libdb5.3, libdb5.3-dev
+Depends: sudo, adduser, python3, python3-venv, libpython3-dev, python3-setuptools,
+ python3-pip, libpq-dev, rrdtool, librrd-dev, libdb5.3, libdb5.3-dev,
+ init-system-helpers (>= 1.50)
 Homepage: https://mentat.cesnet.cz/
 Description: Mentat - SIEM for network operators
  Next generation of Mentat SIEM system for network operators
@@ -17,12 +18,12 @@ Description: Mentat - SIEM for network operators
  .
  For more information please visit our web page:
  .
- * https://mentat.cesnet.cz/
+  * https://mentat.cesnet.cz/
  .
  Documentation is available online:
  .
- * https://alchemist.cesnet.cz/mentat/doc/production/html/manual.html
+  * https://alchemist.cesnet.cz/mentat/doc/production/html/manual.html
  .
  To report a bug please use our issue tracking system:
  .
- * https://homeproj.cesnet.cz/projects/mentat
+  * https://homeproj.cesnet.cz/projects/mentat
diff --git a/packaging/debian/postinst b/packaging/debian/postinst
index 124b28a3deb6f70016e337e892f99578c7e56efc..b6285700ceb2392e4b5e9fa1d93cf6695fe56f9b 100755
--- a/packaging/debian/postinst
+++ b/packaging/debian/postinst
@@ -6,12 +6,15 @@
 # Use of this source is governed by the MIT license, see LICENSE file.
 #-------------------------------------------------------------------------------
 
+# Check exit status of any command and fail on error
+set -e
+
 # Source global configurations
 . /etc/default/mentat
 
 # Add restricted mentat user
-if ! getent passwd mentat > /dev/null 2>&1; then
-    adduser --quiet --system --home /var/mentat/spool --no-create-home --disabled-login --group mentat
+if ! getent passwd ${MENTAT_USER} > /dev/null 2>&1; then
+    adduser --quiet --system --home /var/mentat/spool --no-create-home --disabled-login --group ${MENTAT_USER}
 fi
 
 if ! [ -d "${MENTAT_VENV}" ]; then
@@ -27,93 +30,10 @@ ${MENTAT_VENV}/bin/pip install -r /etc/mentat/requirements.pip
 # Install Mentat system itself.
 ${MENTAT_VENV}/bin/pip install -r /etc/mentat/install.pip --upgrade --no-deps
 
-mentat_bin_list=(
-    hawat-cli
-    mentat-backup.py
-    mentat-cleanup.py
-    mentat-controller.py
-    mentat-dbmngr.py
-    mentat-enricher.py
-    mentat-hawat.py
-    mentat-hawat.wsgi
-    mentat-ideagen.py
-    mentat-informant.py
-    mentat-inspector.py
-    mentat-netmngr.py
-    mentat-precache.py
-    mentat-reporter.py
-    mentat-sampler.py
-    mentat-statistician.py
-    mentat-storage.py
-)
-for b in "${mentat_bin_list[@]}"
-do
-    if [ -f "/usr/local/bin/${b}" ]; then
-        rm -f "/usr/local/bin/${b}"
-    fi
-    if [ ! -L "/usr/local/bin/${b}" ]; then
-        ln -s "${MENTAT_VENV}/bin/${b}" "/usr/local/bin/${b}"
-    fi
-done
-
-
-# Make sure required directory structure exists and has proper permissions
-mentat_dir_list=(
-    /var/mentat
-    /var/mentat/backups
-    /var/mentat/cache
-    /var/mentat/charts
-    /var/mentat/log
-    /var/mentat/reports
-    /var/mentat/reports/reporter
-    /var/mentat/reports/informant
-    /var/mentat/reports/statistician
-    /var/mentat/rrds
-    /var/mentat/run
-    /var/mentat/spool
-    /var/mentat/spool/mentat-inspector.py
-    /var/mentat/spool/mentat-inspector.py/incoming
-    /var/mentat/spool/mentat-inspector.py/pending
-    /var/mentat/spool/mentat-inspector.py/tmp
-    /var/mentat/spool/mentat-inspector.py/errors
-    /var/mentat/spool/mentat-inspector-b.py
-    /var/mentat/spool/mentat-inspector-b.py/incoming
-    /var/mentat/spool/mentat-inspector-b.py/pending
-    /var/mentat/spool/mentat-inspector-b.py/tmp
-    /var/mentat/spool/mentat-inspector-b.py/errors
-    /var/mentat/spool/mentat-enricher.py
-    /var/mentat/spool/mentat-enricher.py/incoming
-    /var/mentat/spool/mentat-enricher.py/pending
-    /var/mentat/spool/mentat-enricher.py/tmp
-    /var/mentat/spool/mentat-enricher.py/errors
-    /var/mentat/spool/mentat-storage.py
-    /var/mentat/spool/mentat-storage.py/incoming
-    /var/mentat/spool/mentat-storage.py/pending
-    /var/mentat/spool/mentat-storage.py/tmp
-    /var/mentat/spool/mentat-storage.py/errors
-)
-for d in "${mentat_dir_list[@]}"
-do
-    mkdir -p "$d"
-    chown "$MENTAT_USER" "$d"
-    chgrp "$MENTAT_GROUP" "$d"
-    chmod 775 "$d"
-done
-
-# Make sure all configuration files have proper ownerships
-find /etc/mentat/ -exec chown root:root {} \;
-
-# Make sure all configuration directories have proper permissions
-find /etc/mentat/ -type d -exec chmod 755 {} \;
-
-# Make sure all configuration files have proper permissions
-find /etc/mentat/ -name "*.conf*" -exec chmod 644 {} \;
-find /etc/mentat/ -name "*.json*" -exec chmod 644 {} \;
-find /etc/mentat/cron/ -name "*.cron" -exec chmod 644 {} \;
+/etc/mentat/scripts/init-runenv.sh
 
-# Make sure all executable scripts have proper permissions
-find /etc/mentat/scripts/ -name "*.py" -exec chmod 755 {} \;
-find /etc/mentat/scripts/ -name "*.sh" -exec chmod 755 {} \;
+# Update the init scripts
+update-rc.d mentat defaults-disabled
 
 # Create PostgreSQL database
 /etc/mentat/scripts/sqldb-init.sh
diff --git a/packaging/debian/postrm b/packaging/debian/postrm
new file mode 100755
index 0000000000000000000000000000000000000000..c119adbcc1282c1db18aaa8a1f1210853d695f8e
--- /dev/null
+++ b/packaging/debian/postrm
@@ -0,0 +1,14 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+# This file is part of Mentat system (https://mentat.cesnet.cz/).
+#
+# Copyright (C) since 2011 CESNET, z.s.p.o (http://www.ces.net/)
+# Use of this source is governed by the MIT license, see LICENSE file.
+#-------------------------------------------------------------------------------
+
+# Check exit status of any command and fail on error
+set -e
+
+if [ "$1" = purge ]; then
+    update-rc.d mentat remove
+fi
diff --git a/packaging/debian/rules b/packaging/debian/rules
index 039dd4a5f11519e5a0f2cb1aabd3582f344b1dc5..94ddf99fe88dd1c08f4c5f4b62f3dfec463d04e7 100755
--- a/packaging/debian/rules
+++ b/packaging/debian/rules
@@ -17,14 +17,30 @@ binary:
 	mkdir -p debian/mentat-ng
 	mkdir -p debian/mentat-ng/etc/mentat
 	mkdir -p debian/mentat-ng/usr/share/bash-completion/completions
+	mkdir -p debian/mentat-ng/lib/systemd/system
 
 	cp -r ../conf/* debian/mentat-ng/etc/mentat/
-	cp -r ../scripts debian/mentat-ng/etc/mentat/
-	cp -r ../migrations-events debian/mentat-ng/etc/mentat/
 	cp -r ../etc/bash_completion.d/* debian/mentat-ng/usr/share/bash-completion/completions
 	cp -r ../etc/default debian/mentat-ng/etc/
 	cp -r ../etc/init.d debian/mentat-ng/etc/
-	cp -r ../etc/systemd debian/mentat-ng/etc/
+	cp ../etc/systemd/system/mentat.service debian/mentat-ng/lib/systemd/system
+
+	if [ -L 'debian/mentat-ng/etc/mentat/migrations-events/.env' ]; then rm -f 'debian/mentat-ng/etc/mentat/migrations-events/.env'; fi
+
+	# Make sure all configuration files have proper ownerships
+	find debian/mentat-ng/etc/mentat/ -exec chown root:root {} \;
+
+	# Make sure all configuration directories have proper permissions
+	find debian/mentat-ng/etc/mentat/ -type d -exec chmod 755 {} \;
+
+	# Make sure all configuration files have proper permissions
+	find debian/mentat-ng/etc/mentat/ -name "*.conf*" -exec chmod 644 {} \;
+	find debian/mentat-ng/etc/mentat/ -name "*.json*" -exec chmod 644 {} \;
+	find debian/mentat-ng/etc/mentat/cron/ -name "*.cron" -exec chmod 644 {} \;
+
+	# Make sure all executable scripts have proper permissions
+	find debian/mentat-ng/etc/mentat/scripts/ -name "*.py" -exec chmod 755 {} \;
+	find debian/mentat-ng/etc/mentat/scripts/ -name "*.sh" -exec chmod 755 {} \;
 
 ifeq ($(BUILD_SUITE),production)
 	echo "mentat-ng" > debian/mentat-ng/etc/mentat/install.pip
diff --git a/vagrantenv/GeoIP.conf b/vagrantenv/GeoIP.conf
new file mode 100644
index 0000000000000000000000000000000000000000..b766cd2f7b93724dc87fa005a83366acfdc68db2
--- /dev/null
+++ b/vagrantenv/GeoIP.conf
@@ -0,0 +1,39 @@
+# GeoIP.conf file for `geoipupdate` program, for versions >= 3.1.1.
+# Used to update GeoIP databases from https://www.maxmind.com.
+# For more information about this config file, visit the docs at
+# https://dev.maxmind.com/geoip/geoipupdate/.
+
+# `AccountID` is from your MaxMind account.
+AccountID your-account-id-here
+
+# `LicenseKey` is from your MaxMind account
+LicenseKey your-license-key-here
+
+# `EditionIDs` is from your MaxMind account.
+EditionIDs GeoLite2-ASN GeoLite2-City GeoLite2-Country
+
+# The remaining settings are OPTIONAL.
+
+# The directory to store the database files. Defaults to /usr/share/GeoIP
+# DatabaseDirectory /usr/share/GeoIP
+
+# The server to use. Defaults to "updates.maxmind.com".
+# Host updates.maxmind.com
+
+# The proxy host name or IP address. You may optionally specify a
+# port number, e.g., 127.0.0.1:8888. If no port number is specified, 1080
+# will be used.
+# Proxy 127.0.0.1:8888
+
+# The user name and password to use with your proxy server.
+# ProxyUserPassword username:password
+
+# Whether to preserve modification times of files downloaded from the server.
+# Defaults to "0".
+# PreserveFileTimes 0
+
+# The lock file to use. This ensures only one geoipupdate process can run at a
+# time.
+# Note: Once created, this lockfile is not removed from the filesystem.
+# Defaults to ".geoipupdate.lock" under the DatabaseDirectory.
+# LockFile /usr/share/GeoIP/.geoipupdate.lock
diff --git a/vagrantenv/postfix.main.cf b/vagrantenv/postfix.main.cf
new file mode 100644
index 0000000000000000000000000000000000000000..9f7d7468053fc37ca41ddc985b1c942d61e271d5
--- /dev/null
+++ b/vagrantenv/postfix.main.cf
@@ -0,0 +1,46 @@
+# See /usr/share/postfix/main.cf.dist for a commented, more complete version
+
+
+# Debian specific:  Specifying a file name will cause the first
+# line of that file to be used as the name.  The Debian default
+# is /etc/mailname.
+#myorigin = /etc/mailname
+
+smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
+biff = no
+
+# appending .domain is the MUA's job.
+append_dot_mydomain = no
+
+# Uncomment the next line to generate "delayed mail" warnings
+#delay_warning_time = 4h
+
+readme_directory = no
+
+# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on
+# fresh installs.
+compatibility_level = 2
+
+
+
+# TLS parameters
+smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
+smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
+smtpd_use_tls=yes
+smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
+smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
+
+# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
+# information on enabling SSL in the smtp client.
+
+# http://www.postfix.org/STANDARD_CONFIGURATION_README.html
+smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
+myhostname = buster.lan
+alias_maps = hash:/etc/aliases
+alias_database = hash:/etc/aliases
+relayhost = 127.0.0.1:1025
+mydestination =
+mailbox_size_limit = 0
+recipient_delimiter = +
+inet_interfaces = loopback-only
+inet_protocols = all
diff --git a/vagrantenv/provisioning/p01_system.sh b/vagrantenv/provisioning/p01_system.sh
new file mode 100644
index 0000000000000000000000000000000000000000..86d528769f2c3f8842aa1f34f5d0a057bd4238e5
--- /dev/null
+++ b/vagrantenv/provisioning/p01_system.sh
@@ -0,0 +1,73 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+# Initial provisioning of Vagrant environment suitable for Mentat development.
+#
+# Copyright (C) since 2011 CESNET, z.s.p.o
+# Use of this source is governed by the MIT license, see LICENSE file.
+#-------------------------------------------------------------------------------
+
+
+source /vagrant/etc/default/mentat
+source /vagrant/conf/scripts/lib.sh
+
+print_title '<BEGIN> PROVISIONING BASE SYSTEM'
+
+print_subtitle 'Configuring timezone and locales'
+echo "Europe/Prague" > /etc/timezone
+dpkg-reconfigure -f noninteractive tzdata && \
+  sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
+  sed -i -e 's/# cs_CZ.UTF-8 UTF-8/cs_CZ.UTF-8 UTF-8/' /etc/locale.gen && \
+  echo 'LANG="en_US.UTF-8"'>/etc/default/locale && \
+  dpkg-reconfigure --frontend=noninteractive locales && \
+  update-locale LANG=en_US.UTF-8
+
+print_subtitle 'Preparing system for development'
+chmod g+w /vagrant
+
+print_subtitle 'Linking configuration files'
+ensure_link /vagrant/vagrantenv/system/.bashrc /root/.bashrc
+ensure_link /vagrant/vagrantenv/system/.bashrc /home/vagrant/.bashrc
+ensure_link /vagrant/data/GeoIP.conf /etc/GeoIP.conf
+ensure_link /vagrant/data/geoip /usr/share/GeoIP
+
+print_subtitle 'Installing essential dependencies'
+apt-get update -qq \
+  && DEBIAN_FRONTEND=noninteractive apt-get -yq dist-upgrade \
+  && DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \
+    sudo \
+    bash-completion \
+    build-essential \
+    gnupg2 \
+    rsync \
+    tmux \
+    curl \
+    wget \
+    less \
+    git \
+    vim \
+    mc \
+    net-tools \
+    openssl \
+    ssl-cert \
+    locales \
+  && apt-get clean \
+  && rm -rf /tmp/* /var/tmp/*
+
+print_subtitle 'Installing third party package repository - PostgreSQL'
+if [ ! -f /etc/apt/sources.list.d/pgdg.list ] ; then
+  curl -sSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
+  echo 'deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main' $PG_MAJOR > /etc/apt/sources.list.d/pgdg.list
+fi
+
+print_subtitle 'Installing third party package repository - NodeJS'
+if [ ! -f /etc/apt/sources.list.d/nodesource.list ] ; then
+  curl -sL https://deb.nodesource.com/setup_$NODE_MAJOR.x | bash -
+fi
+
+print_subtitle 'Installing third party package repository - Yarn'
+if [ ! -f /etc/apt/sources.list.d/yarn.list ] ; then
+  curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
+  echo 'deb http://dl.yarnpkg.com/debian/ stable main' > /etc/apt/sources.list.d/yarn.list
+fi
+
+print_title '<DONE> PROVISIONING BASE SYSTEM'
diff --git a/vagrantenv/provisioning/p02_mentat.sh b/vagrantenv/provisioning/p02_mentat.sh
new file mode 100644
index 0000000000000000000000000000000000000000..9406af9d5057cf7b07ebdf640295f126eca717ae
--- /dev/null
+++ b/vagrantenv/provisioning/p02_mentat.sh
@@ -0,0 +1,133 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+# Initial provisioning of Vagrant environment suitable for Mentat development.
+#
+# Copyright (C) since 2011 CESNET, z.s.p.o
+# Use of this source is governed by the MIT license, see LICENSE file.
+#-------------------------------------------------------------------------------
+
+source /vagrant/etc/default/mentat
+source /vagrant/conf/scripts/lib.sh
+
+print_title '<BEGIN> PROVISIONING MENTAT SYSTEM'
+
+print_subtitle 'Installing application dependencies'
+apt-get update -qq \
+  && DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \
+    python3 \
+    python3-dev \
+    python3-setuptools \
+    python3-pip \
+    python3-venv \
+    libpython3-dev \
+    postgresql-13 \
+    postgresql-13-ip4r \
+    postgresql-client-13 \
+    postgresql-server-dev-13 \
+    libpq-dev \
+    nodejs \
+    yarn \
+    rrdtool \
+    librrd-dev \
+    libdb5.3 \
+    libdb5.3-dev \
+    postfix \
+    mailutils \
+    apache2 \
+    libapache2-mod-wsgi-py3 \
+    init-system-helpers \
+    fakeroot \
+    devscripts \
+    debhelper \
+    lintian \
+  && apt-get clean \
+  && rm -rf /tmp/* /var/tmp/*
+
+print_subtitle 'Installing Grunt task runner'
+if [ ! -f /usr/bin/grunt ] && [ ! -e /usr/bin/grunt ] ; then
+  npm install -g grunt-cli
+fi
+
+print_subtitle 'Installing GeoIPupdate tool'
+if [ ! -f /usr/bin/geoipupdate ] && [ ! -e /usr/bin/geoipupdate ] ; then
+  wget -O /tmp/geoipupdate_4.6.0_linux_amd64.deb https://github.com/maxmind/geoipupdate/releases/download/v4.6.0/geoipupdate_4.6.0_linux_amd64.deb && \
+    dpkg -i /tmp/geoipupdate_4.6.0_linux_amd64.deb && \
+    rm -f /tmp/geoipupdate_4.6.0_linux_amd64.deb
+fi
+
+print_subtitle 'Creating Mentat user for development'
+if ! getent passwd ${MENTAT_USER} > /dev/null 2>&1; then
+    useradd -m -s /bin/bash -U ${MENTAT_USER} --groups sudo
+    cp -pr /home/vagrant/.ssh /home/${MENTAT_USER}/
+    chown -R ${MENTAT_USER}:${MENTAT_USER} /home/${MENTAT_USER}
+    echo "%${MENTAT_USER} ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/mentat
+    usermod -a -G mentat vagrant
+    usermod -a -G vagrant mentat
+fi
+
+print_subtitle 'Linking configuration files'
+ensure_link /vagrant/vagrantenv/system/.bashrc /home/mentat/.bashrc
+ensure_link /vagrant/etc/default/mentat /etc/default/mentat
+ensure_link /vagrant/conf /etc/mentat
+
+print_subtitle 'Preparing Python virtual environment'
+/etc/mentat/scripts/init-venv.sh
+source ${MENTAT_VENV}/bin/activate
+
+print_subtitle 'Preparing application runtime environment'
+/etc/mentat/scripts/init-runenv.sh
+
+print_subtitle 'Preparing development environment'
+cd /vagrant/ && make develop-vagrant
+
+print_subtitle 'Configuring email services for development'
+ensure_link /vagrant/vagrantenv/postfix.main.cf /etc/postfix/main.cf
+systemctl restart postfix.service
+
+ensure_link /vagrant/etc/systemd/system/sendria.service /etc/systemd/system/sendria.service
+mkdir -p /var/sendria
+chown mentat:mentat /var/sendria
+touch /var/log/sendria.log
+chown -R mentat:mentat /var/log/sendria.log
+systemctl daemon-reload
+systemctl start sendria.service
+systemctl enable sendria.service
+
+print_subtitle 'Tweaking database users'
+for dbuname in root mentat vagrant watchdog
+do
+  sudo -u postgres psql -c "SELECT usename FROM pg_catalog.pg_user;" | grep $dbuname > /dev/null
+  if [ $? -ne 0 ]; then
+      echo "Creating default PostgreSQL user '$dbuname'"
+      sudo -u postgres psql -c "CREATE USER $dbuname WITH SUPERUSER CREATEDB ENCRYPTED PASSWORD '$dbuname';"
+  fi
+done
+#sudo -u mentat ${MENTAT_VENV}/bin/python /vagrant/bin/mentat-dbmngr.py --command user-add login=admin "fullname=Developer Admin" email=root "organization=CESNET, z.s.p.o." roles=user,admin
+
+print_subtitle 'Bootstraping database schema and configuration'
+sudo -u mentat ${MENTAT_VENV}/bin/python /vagrant/bin/mentat-dbmngr.py --command init
+sudo -u mentat bash -c "source ${MENTAT_VENV}/bin/activate ; hawat-cli db stamp head"
+sudo -u mentat bash -c "source ${MENTAT_VENV}/bin/activate ; /etc/mentat/scripts/sqldb-migrate.sh stamp head"
+/etc/mentat/scripts/sqldb-optimize.sh
+
+print_subtitle 'Pregenerating application data'
+sudo -u mentat ${MENTAT_VENV}/bin/python /vagrant/bin/mentat-precache.py --allow-empty
+
+print_subtitle 'Configuring Apache to serve development server'
+if [ ! -L /etc/apache2/sites-enabled/site_mentat_vagrant.conf ] ; then
+  ensure_link /vagrant/conf/apache/site_mentat_vagrant.conf /etc/apache2/sites-available/site_mentat_vagrant.conf
+  sed -i.bak s/APACHE_RUN_USER=www-data/APACHE_RUN_USER=mentat/g /etc/apache2/envvars
+  sed -i.bak s/APACHE_RUN_GROUP=www-data/APACHE_RUN_GROUP=mentat/g /etc/apache2/envvars
+  rm -f /etc/apache2/envvars.bak
+
+  a2enmod rewrite
+  a2enmod ssl
+  a2enmod wsgi
+  a2dissite 000-default.conf
+  a2dissite default-ssl.conf
+  a2ensite site_mentat_vagrant.conf
+
+  systemctl restart apache2.service
+fi
+
+print_title '<DONE> PROVISIONING MENTAT SYSTEM'
diff --git a/vagrantenv/provisioning/p03_warden.sh b/vagrantenv/provisioning/p03_warden.sh
new file mode 100644
index 0000000000000000000000000000000000000000..56e85cf3a818611763b9b348a3e40b25224d54dd
--- /dev/null
+++ b/vagrantenv/provisioning/p03_warden.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+# Initial provisioning of Vagrant environment suitable for Mentat development.
+#
+# Copyright (C) since 2011 CESNET, z.s.p.o
+# Use of this source is governed by the MIT license, see LICENSE file.
+#-------------------------------------------------------------------------------
+
+source /vagrant/etc/default/mentat
+source /vagrant/conf/scripts/lib.sh
+
+print_title '<BEGIN> PROVISIONING WARDEN SYSTEM'
+
+print_subtitle 'Fetching Warden client library'
+if [ ! -d /opt/warden3 ] ; then
+  git clone https://homeproj.cesnet.cz/git/warden.git/ /opt/warden3
+fi
+
+print_subtitle 'Installing Warden client library'
+mkdir -p /etc/warden_client/warden_filer
+mkdir -p /run/warden_filer
+mkdir -p /var/lib/warden_filer
+chown -R mentat:mentat /run/warden_filer
+chown -R mentat:mentat /var/lib/warden_filer
+ensure_link /opt/warden3/warden_client/warden_client.py /usr/local/bin/warden_client.py
+ensure_link /opt/warden3/warden_filer/warden_filer.py /usr/local/bin/warden_filer.py
+ensure_link /opt/warden3/warden_ra/warden_apply.sh /usr/local/bin/warden_apply.sh
+chmod a+x /usr/local/bin/warden_client.py
+chmod a+x /usr/local/bin/warden_filer.py
+chmod a+x /usr/local/bin/warden_apply.sh
+ensure_link /vagrant/vagrantenv/warden/warden_filer /etc/default/warden_filer
+ensure_link /vagrant/vagrantenv/warden/warden_filer.cfg /etc/warden_client/warden_filer.cfg
+ensure_link /vagrant/vagrantenv/warden/warden_filer_receiver.service /etc/systemd/system/warden_filer_receiver.service
+systemctl daemon-reload
+
+print_title '<DONE> PROVISIONING WARDEN SYSTEM'
diff --git a/vagrantenv/system/.bashrc b/vagrantenv/system/.bashrc
new file mode 100644
index 0000000000000000000000000000000000000000..535c53017f4b2d6e421119d4bd77523167528b7f
--- /dev/null
+++ b/vagrantenv/system/.bashrc
@@ -0,0 +1,133 @@
+# ~/.bashrc: executed by bash(1) for non-login shells.
+# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
+# for examples
+
+# If not running interactively, don't do anything
+case $- in
+    *i*) ;;
+      *) return;;
+esac
+
+# don't put duplicate lines or lines starting with space in the history.
+# See bash(1) for more options
+HISTCONTROL=ignoreboth
+
+# append to the history file, don't overwrite it
+shopt -s histappend
+
+# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
+HISTSIZE=1000
+HISTFILESIZE=2000
+
+# check the window size after each command and, if necessary,
+# update the values of LINES and COLUMNS.
+shopt -s checkwinsize
+
+# If set, the pattern "**" used in a pathname expansion context will
+# match all files and zero or more directories and subdirectories.
+#shopt -s globstar
+
+# make less more friendly for non-text input files, see lesspipe(1)
+[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
+
+# set variable identifying the chroot you work in (used in the prompt below)
+if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
+    debian_chroot=$(cat /etc/debian_chroot)
+fi
+
+# set a fancy prompt (non-color, unless we know we "want" color)
+case "$TERM" in
+    xterm-color|*-256color) color_prompt=yes;;
+esac
+
+# uncomment for a colored prompt, if the terminal has the capability; turned
+# off by default to not distract the user: the focus in a terminal window
+# should be on the output of commands, not on the prompt
+#force_color_prompt=yes
+
+if [ -n "$force_color_prompt" ]; then
+    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
+	# We have color support; assume it's compliant with Ecma-48
+	# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
+	# a case would tend to support setf rather than setaf.)
+	color_prompt=yes
+    else
+	color_prompt=
+    fi
+fi
+
+if [ "$color_prompt" = yes ]; then
+    # export GIT_PS1_SHOWDIRTYSTATE=1
+    # export GIT_PS1_SHOWSTASHSTATE=1
+    # export GIT_PS1_SHOWUNTRACKEDFILES=1
+    # export GIT_PS1_SHOWUPSTREAM="auto verbose"
+
+    if [[ ${EUID} == 0 ]] ; then
+       PS1='\[\033[01;34m\]!DEV!\[\033[00m\] ${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\h\[\033[01;34m\] \W \$\[\033[00m\] '
+       #PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\h\[\033[01;34m\]:\[\033[01;34m\]\w\[\033[00m\]\[\033[01;33m\]$(__git_ps1 " [%s]")\[\033[00m\]\$ '
+    else
+       PS1='\[\033[01;34m\]!DEV!\[\033[00m\] ${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\] \[\033[01;34m\]\w \$\[\033[00m\] '
+       #PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\[\033[01;33m\]$(__git_ps1 " [%s]")\[\033[00m\]\$ '
+    fi
+else
+    PS1='!DEV! ${debian_chroot:+($debian_chroot)}\u@\h \w \$ '
+fi
+unset color_prompt force_color_prompt
+
+# If this is an xterm set the title to user@host:dir
+case "$TERM" in
+xterm*|rxvt*)
+    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
+    ;;
+*)
+    ;;
+esac
+
+# enable color support of ls and also add handy aliases
+if [ -x /usr/bin/dircolors ]; then
+    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
+    alias ls='ls --color=auto'
+    #alias dir='dir --color=auto'
+    #alias vdir='vdir --color=auto'
+
+    alias grep='grep --color=auto'
+    alias fgrep='fgrep --color=auto'
+    alias egrep='egrep --color=auto'
+fi
+
+# colored GCC warnings and errors
+#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
+
+# some more aliases
+alias ll='ls -alF'
+alias la='ls -A'
+alias l='ls -CF'
+alias cd..='cd ..'
+alias ..='cd ..'
+alias ...='cd ../..'
+alias ....='cd ../../..'
+alias sm='sudo su mentat'
+alias sv='sudo su vagrant'
+alias wd='cd /vagrant/'
+alias ve='source /var/mentat/venv/bin/activate'
+
+# enable programmable completion features (you don't need to enable
+# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
+# sources /etc/bash.bashrc).
+if ! shopt -oq posix; then
+  if [ -f /usr/share/bash-completion/bash_completion ]; then
+    . /usr/share/bash-completion/bash_completion
+  elif [ -f /etc/bash_completion ]; then
+    . /etc/bash_completion
+  fi
+fi
+
+## Display banner and print some usefull statistics to anyone that connects via SSH:
+if [ ! -z "$SSH_CONNECTION" ]; then
+    echo ""
+    echo ""
+    if [ -x /vagrant/vagrantenv/system/login-banner.sh ]; then
+        /vagrant/vagrantenv/system/login-banner.sh
+    fi
+    echo ""
+fi
diff --git a/vagrantenv/system/login-banner.sh b/vagrantenv/system/login-banner.sh
new file mode 100755
index 0000000000000000000000000000000000000000..5fa379a69f887df707f74aa99f5d0e75ccf8264c
--- /dev/null
+++ b/vagrantenv/system/login-banner.sh
@@ -0,0 +1,32 @@
+echo ""
+echo "                 ███╗   ███╗███████╗███╗   ██╗████████╗ █████╗ ████████╗"
+echo "                 ████╗ ████║██╔════╝████╗  ██║╚══██╔══╝██╔══██╗╚══██╔══╝"
+echo "                 ██╔████╔██║█████╗  ██╔██╗ ██║   ██║   ███████║   ██║"
+echo "                 ██║╚██╔╝██║██╔══╝  ██║╚██╗██║   ██║   ██╔══██║   ██║"
+echo "                 ██║ ╚═╝ ██║███████╗██║ ╚████║   ██║   ██║  ██║   ██║"
+echo "                 ╚═╝     ╚═╝╚══════╝╚═╝  ╚═══╝   ╚═╝   ╚═╝  ╚═╝   ╚═╝"
+echo "                        Copyright (C) since 2011 CESNET, z.s.p.o"
+echo ""
+echo "                      Welcome to Mentat development environment"
+echo "    https://alchemist.cesnet.cz/mentat/doc/development/html/_doclib/development.html"
+echo ""
+echo "    Development repository located at:  /vagrant/"
+echo "    Configuration files located at:     /etc/mentat/"
+echo "    Variable files located at:          /var/mentat/"
+echo "    Web interface located at:           https://localhost:4443"
+echo "    Flask web interface located at:     http://localhost:5000"
+echo "    Sendria web interface located at:   http://localhost:1080"
+echo ""
+echo "    Tips:"
+echo "      Use command alias 'sm' to quickly sudo su to mentat system user"
+echo "      Use command alias 'sv' to quickly sudo su to vagrant system user"
+echo "      Use command alias 'wd' to quickly change to project's work directory."
+echo "      Use command alias 've' to activate project's virtual environment."
+echo ""
+echo "    Launching:"
+echo "      mentat-controller.py --command start    # Mentat backend system"
+echo "      make run-webui-dev                      # Flask's web interface (5000)"
+echo ""
+echo "    Documentation:"
+echo "      https://alchemist.cesnet.cz/mentat/doc/development/html/_doclib/development.html#development-with-vagrant"
+echo ""
diff --git a/vagrantenv/warden/warden_filer b/vagrantenv/warden/warden_filer
new file mode 100644
index 0000000000000000000000000000000000000000..d4633a2d41c76e8fe7063ca00ac398f7ecc7ac9d
--- /dev/null
+++ b/vagrantenv/warden/warden_filer
@@ -0,0 +1,2 @@
+#!/bin/bash
+PYTHONPATH="/usr/local/bin"
diff --git a/vagrantenv/warden/warden_filer.cfg b/vagrantenv/warden/warden_filer.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..54d076bd939c8d4230c9c94d0a08c8ee1e43fb2e
--- /dev/null
+++ b/vagrantenv/warden/warden_filer.cfg
@@ -0,0 +1,26 @@
+// For all options see documentation
+{
+    // Warden config can be also referenced as:
+    // "warden": "/path/to/warden_client.cfg"
+    "warden": {
+        "url": "https://warden-hub.cesnet.cz/warden3",
+        "cafile": "/etc/ssl/certs/ca-certificates.crt",
+        "keyfile": "/etc/warden/warden_client/warden_filer/key.pem",
+        "certfile": "/etc/warden/warden_client/warden_filer/cert.pem",
+        "timeout": 30,
+        "send_events_limit": 2000,
+        "get_events_limit": 2000,
+        "errlog": {"level": "debug"},
+        "filelog": {"level": "debug", "file": "/var/log/warden_filer.log"},
+        "idstore": "/var/lib/warden_filer/warden_filer.id",
+        "name": "cz.cesnet.vagrant"
+    },
+    "receiver": {
+        "dir": "/var/mentat/spool/mentat-inspector.py",
+        "pid_file": "/run/warden_filer/receiver.pid",
+        "uid": 1001,
+        "gid": 1001,
+        "file_limit": 5000,
+        "limit_wait_time": 20
+    }
+}
diff --git a/vagrantenv/warden/warden_filer_receiver.service b/vagrantenv/warden/warden_filer_receiver.service
new file mode 100644
index 0000000000000000000000000000000000000000..42054c5ec8fd101ca52441f81bee50a8d4d9fd62
--- /dev/null
+++ b/vagrantenv/warden/warden_filer_receiver.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=Warden Filer - receiver
+After=syslog.target network.target remote-fs.target nss-lookup.target
+
+[Service]
+Type=forking
+EnvironmentFile=/etc/default/warden_filer
+PIDFile=/run/warden_filer/receiver.pid
+ExecStart=/usr/local/bin/warden_filer.py -c "/etc/warden_client/warden_filer.cfg" --pid_file "/run/warden_filer/receiver.pid" --daemon receiver
+ExecStartPre=/bin/mkdir -p /run/warden_filer/
+ExecStartPre=/bin/chown -R mentat:mentat /run/warden_filer/
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
diff --git a/yarn.lock b/yarn.lock
index a2cd2edb8b4cc67498adf72c6c0ab9571c684155..80d7cd873069b60185d1122c13812281a142065c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -55,11 +55,6 @@ ajv@^6.5.5:
     json-schema-traverse "^0.4.1"
     uri-js "^4.2.2"
 
-ansi-regex@*:
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
-  integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
-
 ansi-regex@^2.0.0:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
@@ -633,18 +628,6 @@ dashdash@^1.12.0:
   dependencies:
     assert-plus "^1.0.0"
 
-datatables.net-plugins@^1.10.15:
-  version "1.10.20"
-  resolved "https://registry.yarnpkg.com/datatables.net-plugins/-/datatables.net-plugins-1.10.20.tgz#c89f6bed3fa7e6605cbeaa35d60f223659e84c8c"
-  integrity sha512-rnhNmRHe9UEzvM7gtjBay1QodkWUmxLUhHNbmJMYhhUggjtm+BRSlE0PRilkeUkwckpNWzq+0fPd7/i0fpQgzA==
-
-datatables.net@^1.10.16:
-  version "1.10.20"
-  resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-1.10.20.tgz#9d65ecc3c83cbe7baa4fa5a053405c8fe42c1350"
-  integrity sha512-4E4S7tTU607N3h0fZPkGmAtr9mwy462u+VJ6gxYZ8MxcRIjZqHy3Dv1GNry7i3zQCktTdWbULVKBbkAJkuHEnQ==
-  dependencies:
-    jquery ">=1.7"
-
 date-time@^1.0.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/date-time/-/date-time-1.1.0.tgz#18876d0bda4c19fe70dd3bf4b034f281b12a40b6"
@@ -1554,7 +1537,7 @@ iferr@^0.1.5:
   resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501"
   integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE=
 
-imurmurhash@*, imurmurhash@^0.1.4:
+imurmurhash@^0.1.4:
   version "0.1.4"
   resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
   integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
@@ -1757,7 +1740,7 @@ isstream@0.1.x, isstream@~0.1.2:
   resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
   integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
 
-jquery@>=1.7, "jquery@>=1.7.1 <4.0.0", "jquery@^1.8.3 || ^2.0 || ^3.0", jquery@^3.3.1:
+"jquery@>=1.7.1 <4.0.0", "jquery@^1.8.3 || ^2.0 || ^3.0", jquery@^3.3.1:
   version "3.4.1"
   resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2"
   integrity sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==