diff --git a/composer.json b/composer.json
index ae3b6ed100cda4f04a6ea58b651876b0fec1333e..d3d27bf7c75961d63b7ef7428900a797f91b6713 100644
--- a/composer.json
+++ b/composer.json
@@ -100,7 +100,7 @@
         "drupal/bootstrap": "^3.23",
         "drupal/ckeditor_indentblock": "1.0.0-beta2",
         "drupal/config_direct_save": "1.0",
-        "drupal/config_ignore": "2.2",
+        "drupal/config_ignore": "2.3",
         "drupal/config_installer": "1.8",
         "drupal/config_update": "1.5",
         "drupal/console": "1.9.7",
@@ -133,7 +133,7 @@
         "drupal/inline_entity_form": "1.0-rc8",
         "drupal/libraries": "3.0.0-alpha6",
         "drupal/link_attributes": "1.11",
-        "drupal/linkit": "5.0-beta11",
+        "drupal/linkit": "5.0-beta12",
         "drupal/magnific_popup": "1.3",
         "drupal/mathjax": "2.7",
         "drupal/media_entity_browser": "2.0-alpha3",
diff --git a/composer.lock b/composer.lock
index db544ef60d2e2e6bbb5d51343546d1862507f446..9f007417742f04fdcb94110d63debbec711ee2e0 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "36e630ed03a2077e8999ccd1f9c5558e",
+    "content-hash": "aa72e1bd58199425620bca45a714ecc4",
     "packages": [
         {
             "name": "alchemy/zippy",
@@ -2822,17 +2822,17 @@
         },
         {
             "name": "drupal/config_filter",
-            "version": "1.7.0",
+            "version": "1.8.0",
             "source": {
                 "type": "git",
                 "url": "https://git.drupalcode.org/project/config_filter.git",
-                "reference": "8.x-1.7"
+                "reference": "8.x-1.8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://ftp.drupal.org/files/projects/config_filter-8.x-1.7.zip",
-                "reference": "8.x-1.7",
-                "shasum": "dc7edf6025e6cb837414b56bdb8a4c4c83dbb1ab"
+                "url": "https://ftp.drupal.org/files/projects/config_filter-8.x-1.8.zip",
+                "reference": "8.x-1.8",
+                "shasum": "5def5f97e79d6f5af6bb7007f012443475c90bfe"
             },
             "require": {
                 "drupal/core": "^8 || ^9"
@@ -2843,8 +2843,8 @@
             "type": "drupal-module",
             "extra": {
                 "drupal": {
-                    "version": "8.x-1.7",
-                    "datestamp": "1601934753",
+                    "version": "8.x-1.8",
+                    "datestamp": "1603870062",
                     "security-coverage": {
                         "status": "covered",
                         "message": "Covered by Drupal's security advisory policy"
@@ -2888,30 +2888,27 @@
         },
         {
             "name": "drupal/config_ignore",
-            "version": "2.2.0",
+            "version": "2.3.0",
             "source": {
                 "type": "git",
                 "url": "https://git.drupalcode.org/project/config_ignore.git",
-                "reference": "8.x-2.2"
+                "reference": "8.x-2.3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://ftp.drupal.org/files/projects/config_ignore-8.x-2.2.zip",
-                "reference": "8.x-2.2",
-                "shasum": "18af5772087b90dd4b83c2c6e292d8ea2f8834e0"
+                "url": "https://ftp.drupal.org/files/projects/config_ignore-8.x-2.3.zip",
+                "reference": "8.x-2.3",
+                "shasum": "2e1f07a455275fb6637909921a8915646601fc00"
             },
             "require": {
-                "drupal/config_filter": "1.*",
-                "drupal/core": "~8.0"
+                "drupal/config_filter": "^1 || ^2",
+                "drupal/core": "^8 || ^9"
             },
             "type": "drupal-module",
             "extra": {
-                "branch-alias": {
-                    "dev-2.x": "2.x-dev"
-                },
                 "drupal": {
-                    "version": "8.x-2.2",
-                    "datestamp": "1576528386",
+                    "version": "8.x-2.3",
+                    "datestamp": "1608306489",
                     "security-coverage": {
                         "status": "covered",
                         "message": "Covered by Drupal's security advisory policy"
@@ -2920,7 +2917,7 @@
             },
             "notification-url": "https://packages.drupal.org/8/downloads",
             "license": [
-                "GPL-2.0+"
+                "GPL-2.0-or-later"
             ],
             "authors": [
                 {
@@ -2942,7 +2939,7 @@
             "description": "Ignore certain configuration during import.",
             "homepage": "http://drupal.org/project/config_ignore",
             "support": {
-                "source": "http://cgit.drupalcode.org/config_ignore",
+                "source": "https://git.drupalcode.org/project/config_ignore",
                 "issues": "http://drupal.org/project/config_ignore",
                 "irc": "irc://irc.freenode.org/drupal-contribute"
             }
@@ -5541,17 +5538,17 @@
         },
         {
             "name": "drupal/linkit",
-            "version": "5.0.0-beta11",
+            "version": "5.0.0-beta12",
             "source": {
                 "type": "git",
                 "url": "https://git.drupalcode.org/project/linkit.git",
-                "reference": "8.x-5.0-beta11"
+                "reference": "8.x-5.0-beta12"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://ftp.drupal.org/files/projects/linkit-8.x-5.0-beta11.zip",
-                "reference": "8.x-5.0-beta11",
-                "shasum": "9133a3e61deafdd6a9d5a8b31a1f42e16051ee97"
+                "url": "https://ftp.drupal.org/files/projects/linkit-8.x-5.0-beta12.zip",
+                "reference": "8.x-5.0-beta12",
+                "shasum": "9e03975b476f893112d8b12d8b8610926a4e7f2c"
             },
             "require": {
                 "drupal/core": "^8.7.7 || ^9"
@@ -5562,8 +5559,8 @@
             "type": "drupal-module",
             "extra": {
                 "drupal": {
-                    "version": "8.x-5.0-beta11",
-                    "datestamp": "1591971693",
+                    "version": "8.x-5.0-beta12",
+                    "datestamp": "1608957625",
                     "security-coverage": {
                         "status": "not-covered",
                         "message": "Beta releases are not covered by Drupal security advisories."
@@ -5575,7 +5572,7 @@
             },
             "notification-url": "https://packages.drupal.org/8/downloads",
             "license": [
-                "GPL-2.0+"
+                "GPL-2.0-or-later"
             ],
             "authors": [
                 {
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index 54ee75e8fefbc3e101db1e2c6f37047105cec3f3..107764d9cbf614101418a8d94ff7096ff86b6928 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -2911,18 +2911,18 @@
     },
     {
         "name": "drupal/config_filter",
-        "version": "1.7.0",
-        "version_normalized": "1.7.0.0",
+        "version": "1.8.0",
+        "version_normalized": "1.8.0.0",
         "source": {
             "type": "git",
             "url": "https://git.drupalcode.org/project/config_filter.git",
-            "reference": "8.x-1.7"
+            "reference": "8.x-1.8"
         },
         "dist": {
             "type": "zip",
-            "url": "https://ftp.drupal.org/files/projects/config_filter-8.x-1.7.zip",
-            "reference": "8.x-1.7",
-            "shasum": "dc7edf6025e6cb837414b56bdb8a4c4c83dbb1ab"
+            "url": "https://ftp.drupal.org/files/projects/config_filter-8.x-1.8.zip",
+            "reference": "8.x-1.8",
+            "shasum": "5def5f97e79d6f5af6bb7007f012443475c90bfe"
         },
         "require": {
             "drupal/core": "^8 || ^9"
@@ -2933,8 +2933,8 @@
         "type": "drupal-module",
         "extra": {
             "drupal": {
-                "version": "8.x-1.7",
-                "datestamp": "1601934753",
+                "version": "8.x-1.8",
+                "datestamp": "1603870062",
                 "security-coverage": {
                     "status": "covered",
                     "message": "Covered by Drupal's security advisory policy"
@@ -2979,31 +2979,28 @@
     },
     {
         "name": "drupal/config_ignore",
-        "version": "2.2.0",
-        "version_normalized": "2.2.0.0",
+        "version": "2.3.0",
+        "version_normalized": "2.3.0.0",
         "source": {
             "type": "git",
             "url": "https://git.drupalcode.org/project/config_ignore.git",
-            "reference": "8.x-2.2"
+            "reference": "8.x-2.3"
         },
         "dist": {
             "type": "zip",
-            "url": "https://ftp.drupal.org/files/projects/config_ignore-8.x-2.2.zip",
-            "reference": "8.x-2.2",
-            "shasum": "18af5772087b90dd4b83c2c6e292d8ea2f8834e0"
+            "url": "https://ftp.drupal.org/files/projects/config_ignore-8.x-2.3.zip",
+            "reference": "8.x-2.3",
+            "shasum": "2e1f07a455275fb6637909921a8915646601fc00"
         },
         "require": {
-            "drupal/config_filter": "1.*",
-            "drupal/core": "~8.0"
+            "drupal/config_filter": "^1 || ^2",
+            "drupal/core": "^8 || ^9"
         },
         "type": "drupal-module",
         "extra": {
-            "branch-alias": {
-                "dev-2.x": "2.x-dev"
-            },
             "drupal": {
-                "version": "8.x-2.2",
-                "datestamp": "1576528386",
+                "version": "8.x-2.3",
+                "datestamp": "1608306489",
                 "security-coverage": {
                     "status": "covered",
                     "message": "Covered by Drupal's security advisory policy"
@@ -3013,7 +3010,7 @@
         "installation-source": "dist",
         "notification-url": "https://packages.drupal.org/8/downloads",
         "license": [
-            "GPL-2.0+"
+            "GPL-2.0-or-later"
         ],
         "authors": [
             {
@@ -3035,7 +3032,7 @@
         "description": "Ignore certain configuration during import.",
         "homepage": "http://drupal.org/project/config_ignore",
         "support": {
-            "source": "http://cgit.drupalcode.org/config_ignore",
+            "source": "https://git.drupalcode.org/project/config_ignore",
             "issues": "http://drupal.org/project/config_ignore",
             "irc": "irc://irc.freenode.org/drupal-contribute"
         }
@@ -5707,18 +5704,18 @@
     },
     {
         "name": "drupal/linkit",
-        "version": "5.0.0-beta11",
-        "version_normalized": "5.0.0.0-beta11",
+        "version": "5.0.0-beta12",
+        "version_normalized": "5.0.0.0-beta12",
         "source": {
             "type": "git",
             "url": "https://git.drupalcode.org/project/linkit.git",
-            "reference": "8.x-5.0-beta11"
+            "reference": "8.x-5.0-beta12"
         },
         "dist": {
             "type": "zip",
-            "url": "https://ftp.drupal.org/files/projects/linkit-8.x-5.0-beta11.zip",
-            "reference": "8.x-5.0-beta11",
-            "shasum": "9133a3e61deafdd6a9d5a8b31a1f42e16051ee97"
+            "url": "https://ftp.drupal.org/files/projects/linkit-8.x-5.0-beta12.zip",
+            "reference": "8.x-5.0-beta12",
+            "shasum": "9e03975b476f893112d8b12d8b8610926a4e7f2c"
         },
         "require": {
             "drupal/core": "^8.7.7 || ^9"
@@ -5729,8 +5726,8 @@
         "type": "drupal-module",
         "extra": {
             "drupal": {
-                "version": "8.x-5.0-beta11",
-                "datestamp": "1591971693",
+                "version": "8.x-5.0-beta12",
+                "datestamp": "1608957625",
                 "security-coverage": {
                     "status": "not-covered",
                     "message": "Beta releases are not covered by Drupal security advisories."
@@ -5743,7 +5740,7 @@
         "installation-source": "dist",
         "notification-url": "https://packages.drupal.org/8/downloads",
         "license": [
-            "GPL-2.0+"
+            "GPL-2.0-or-later"
         ],
         "authors": [
             {
diff --git a/web/modules/config_filter/.docker-relay.yml b/web/modules/config_filter/.docker-relay.yml
deleted file mode 100644
index 8dddb1ea879c7f5011d3bd46373d8509867f97d6..0000000000000000000000000000000000000000
--- a/web/modules/config_filter/.docker-relay.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-# This is a simple docker-relay configuration.
-# See: https://github.com/bircher/docker-relay
-docker-relay:
-  version: 0.1.0
-
-drush:
-  container: drupal
-  cmd: 'vendor/bin/drush'
-  user: 1000
-
-composer:
-  container: drupal
-  cmd: composer
-  user: 1000
-  # This is a hack and will be done differently in future versions of docker-relay.
-  exec: ['docker-compose', 'run', '--rm', '-u', '1000', 'drupal', 'composer']
-
-php:
-  container: drupal
-  path: '.'
-  cmd: php
-  user: 1000
diff --git a/web/modules/config_filter/.docker/zz-php.ini b/web/modules/config_filter/.docker/zz-php.ini
deleted file mode 100644
index 582337f235cff06a77cf2835b292cb3f6e3b5c2b..0000000000000000000000000000000000000000
--- a/web/modules/config_filter/.docker/zz-php.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[PHP]
-variables_order = GPCS
-error_reporting = E_ALL
-date.timezone = "UTC"
-sendmail_path = "true"
diff --git a/web/modules/config_filter/.env.dist b/web/modules/config_filter/.env.dist
deleted file mode 100644
index dbc1b697b747224d8d73b351b217a69401a6e15e..0000000000000000000000000000000000000000
--- a/web/modules/config_filter/.env.dist
+++ /dev/null
@@ -1,23 +0,0 @@
-# This file is for customizing the Docker environment which is used to develop
-# Devel. If you are just using Devel on a site, you may ignore this file
-# and docker-compose.yml.
-
-# Uncomment to change versions of php and DBs and OS.
-# POSTGRES_TAG=10.5
-# MARIADB_TAG=10.3
-# PHP_TAG=7.3-dev
-
-# Uncomment to run tests against a different DB. Defaults to mysql.
-# SIMPLETEST_DB=sqlite://localhost/sites/default/files/.sqlite
-# SIMPLETEST_DB=mysql://root:password@mariadb/db
-# SIMPLETEST_DB=pgsql://root:password@postgres/db
-
-# XDebug defaults to Off in the php container.
-# Uncomment to enable XDebug. See https://wodby.com/docs/1.0/stacks/drupal/local/#xdebug.
-# When Xdebug first successfully connects back to PHPStorm, you are prompted to create a Server called devel
-# Then you are prompted to add path mappings (its mandatory).
-# PHP_XDEBUG=0
-# PHP_XDEBUG_DEFAULT_ENABLE=0
-# PHP_IDE_CONFIG=serverName=devel
-# PHP_XDEBUG_REMOTE_HOST=host.docker.internal
-# PHP_XDEBUG_REMOTE_CONNECT_BACK=0
diff --git a/web/modules/config_filter/.gitignore b/web/modules/config_filter/.gitignore
deleted file mode 100644
index 4df04f01ec95343bb46b4985fe0d6a3c697940d8..0000000000000000000000000000000000000000
--- a/web/modules/config_filter/.gitignore
+++ /dev/null
@@ -1,18 +0,0 @@
-/vendor/
-vendor
-/web/
-web
-/node_modules/
-.env
-composer.lock
-composer.dev.lock
-yarn.lock
-/.editorconfig
-/.gitattributes
-
-#PHPUnit output
-junit.xml
-.phpunit.result.cache
-
-# Ignore local overrides.
-docker-compose.override.yml
diff --git a/web/modules/config_filter/.spoons/ScriptHandler.php b/web/modules/config_filter/.spoons/ScriptHandler.php
deleted file mode 100644
index f7a01dcf8e1797e0d64c23dfb05951f84c6d18dd..0000000000000000000000000000000000000000
--- a/web/modules/config_filter/.spoons/ScriptHandler.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-namespace Spoons;
-
-use Composer\Script\Event;
-use Symfony\Component\Process\Process;
-
-/**
- * A Composer script handler.
- */
-class ScriptHandler {
-
-  /**
-   * Create a web/modules/[SLUG] dir and symlink all project files into it.
-   *
-   * @param \Composer\Script\Event $event
-   *   A Composer package event.
-   */
-  public static function createSymlinks(Event $event) {
-    $full_name = $event->getComposer()->getPackage()->getName();
-    [, $project_name] = explode('/', $full_name);
-    $cmd = "rm -rf web/modules/custom/$project_name && mkdir -p web/modules/custom/$project_name";
-    $process = new Process($cmd);
-    $process->mustRun();
-    $cmd = 'find ../../../.. -maxdepth 1 ! -name .git ! -name web ! -name vendor ! -name .idea -print | while read file; do ln -s "$file" .; done';
-    $process = new Process($cmd, "web/modules/custom/$project_name");
-    $process->mustRun();
-  }
-
-}
diff --git a/web/modules/config_filter/.travis.yml b/web/modules/config_filter/.travis.yml
deleted file mode 100644
index 595caa25aadd118254c4dede171cd5ad24ea393d..0000000000000000000000000000000000000000
--- a/web/modules/config_filter/.travis.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-language: minimal
-
-services:
-  - docker
-
-jobs:
-  include:
-    - env: DRUPAL_VERSION=8.8
-    - env: DRUPAL_VERSION=9
-
-before_script:
-  - docker-compose up -d
-  - docker-compose run -u root drupal composer require drupal/core-recommended $DRUPAL_VERSION
-  - docker-compose run -u root drupal composer si
-
-script:
-  # This is also run by grumphp, but running it individually gives more output on travis
-  - docker-compose run drupal composer phpcs
-  - docker-compose run drupal composer lint
-  # The phpunit 8 compatibility wants to write to the sites/simpletest folder
-  - docker-compose run -u root drupal composer unit
-  - docker-compose run -u root drupal composer phpstan
-
-notifications:
-  email: false
diff --git a/web/modules/config_filter/composer.dev.json b/web/modules/config_filter/composer.dev.json
deleted file mode 100644
index df67027d89078573d72369a3eb8d84b973297440..0000000000000000000000000000000000000000
--- a/web/modules/config_filter/composer.dev.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
-  "name": "drupal/config_filter",
-  "type": "drupal-module",
-  "description": "The dev composer file for Config Filter. This allows us to use docker for development but still test on the drupal infrastructure.",
-  "license": "GPL-2.0-or-later",
-  "require": {},
-  "require-dev": {
-    "composer/installers": "^1",
-    "cweagans/composer-patches": "~1.0",
-    "drupal/core-composer-scaffold": "^8.8||^9",
-    "drupal/core-recommended": "^8.8||^9",
-    "drupal/core-dev": "^8.8||^9",
-    "drush/drush": "^10",
-    "mglaman/phpstan-drupal": "^0.12",
-    "phpstan/phpstan-deprecation-rules": "^0.12",
-    "php-parallel-lint/php-parallel-lint": "^1.2",
-    "zaporylie/composer-drupal-optimizations": "^1.0",
-    "phpro/grumphp-shim": "^0.20.0"
-  },
-  "config": {
-  	"process-timeout": 36000
-  },
-  "autoload": {
-    "classmap": [".spoons/ScriptHandler.php"]
-  },
-  "scripts": {
-    "webserver": "cd web && php -S 0.0.0.0:8888 .ht.router.php",
-    "si": "drush si -v --db-url=${SIMPLETEST_DB:-mysql://root:password@mariadb/db}",
-    "phpcs": "phpcs --runtime-set ignore_warnings_on_exit 1 --runtime-set ignore_errors_on_exit 1 web/modules/custom",
-    "lint": "parallel-lint --exclude web --exclude vendor .",
-    "unit": "phpunit --verbose",
-    "phpstan": "phpstan analyse",
-    "post-update-cmd": ["Spoons\\ScriptHandler::createSymlinks"]
-  },
-  "extra": {
-    "installer-paths": {
-      "web/core": ["type:drupal-core"],
-      "web/libraries/{$name}": ["type:drupal-library"],
-      "web/modules/contrib/{$name}": ["type:drupal-module"],
-      "web/profiles/{$name}": ["type:drupal-profile"],
-      "web/themes/{$name}": ["type:drupal-theme"],
-      "drush/{$name}": ["type:drupal-drush"]
-    },
-    "drupal-scaffold": {
-      "locations": {
-        "web-root": "web/"
-      }
-    }
-  }
-}
diff --git a/web/modules/config_filter/config_filter.info.yml b/web/modules/config_filter/config_filter.info.yml
index 9f301d8c02c4231f7f24d4457ed1178bda1b3613..1cef5653b692ce194efd318144973193a3c18ad0 100644
--- a/web/modules/config_filter/config_filter.info.yml
+++ b/web/modules/config_filter/config_filter.info.yml
@@ -5,7 +5,7 @@ core: 8.x
 core_version_requirement: ^8 || ^9
 package: Config
 
-# Information added by Drupal.org packaging script on 2020-10-05
-version: '8.x-1.7'
+# Information added by Drupal.org packaging script on 2020-10-28
+version: '8.x-1.8'
 project: 'config_filter'
-datestamp: 1601934755
+datestamp: 1603870063
diff --git a/web/modules/config_filter/docker-compose.yml b/web/modules/config_filter/docker-compose.yml
deleted file mode 100644
index 8466a0f46d54c181b7846e287a25bc14f698f9e4..0000000000000000000000000000000000000000
--- a/web/modules/config_filter/docker-compose.yml
+++ /dev/null
@@ -1,76 +0,0 @@
-version: "3.1"
-
-services:
-  # More info at https://github.com/wodby/php
-  drupal:
-    image: wodby/php:${PHP_TAG-7.3-dev}
-    command: composer webserver
-    environment:
-      # We set the composer variable so that composer uses the dev file. The drupal CI can not deal with having drupal as a dev-dependency.
-      COMPOSER: composer.dev.json
-      PHP_SENDMAIL_PATH: /dev/null
-      COLUMNS: ${COLUMNS-80} # Set 80 columns for docker exec -it.
-      ## Read instructions at https://wodby.com/docs/stacks/drupal/local/#debugging-cli-requests
-      # The line below is commented out because the mere presence of that env variable loads XDebug regardless of the value.
-      # Enable XDebug when you `up` your container: PHP_XDEBUG=1 docker-compose up -d
-      # PHP_XDEBUG:
-      PHP_XDEBUG_DEFAULT_ENABLE:
-      PHP_IDE_CONFIG:
-      PHP_XDEBUG_REMOTE_HOST:
-      PHP_XDEBUG_REMOTE_CONNECT_BACK:
-      # Specify 'drupal' instead of 127.0.0.1 so that chrome service can reach it.
-      SIMPLETEST_BASE_URL: http://drupal:8888
-      SIMPLETEST_DB:
-    volumes:
-      - ./:/var/www/html:cached
-      - ./.docker/zz-php.ini:/usr/local/etc/php/conf.d/zz-php.ini
-#    ports:
-#      - '${WEB_PORT-8889}:8888'
-
-  # More info at https://github.com/wodby/mariadb
-  mariadb:
-    image: wodby/mariadb:${MARIADB_TAG-10.3}
-    stop_grace_period: 30s
-    environment:
-      MYSQL_ROOT_PASSWORD: password
-#    volumes:
-#      - mariadb-datavolume:/var/lib/mysql
-#    ports:
-#      - '3005:3306'
-
-  # More info at https://github.com/wodby/postgres
-#  postgres:
-#    image: wodby/postgres:${POSTGRES_TAG-10.5}
-#    stop_grace_period: 30s
-#    environment:
-#      POSTGRES_PASSWORD: password
-#      POSTGRES_DB: db
-#      POSTGRES_USER: root
-#    volumes:
-#      - postgres-datavolume:/var/lib/postgresql/data
-#    ports:
-#      - '5532:5432'
-
-  # https://gorannikolovski.com/blog/docker4drupal-and-functional-javascript-tests
-#  chrome:
-#    image: drupalci/webdriver-chromedriver:production
-#    ulimits:
-#      core:
-#        soft: -1
-#        hard: -1
-#    cap_add:
-#      - SYS_ADMIN
-#    volumes:
-#      - /dev/shm:/dev/shm
-#    entrypoint:
-#      - chromedriver
-#      - "--no-sandbox"
-#      - "--log-path=/tmp/chromedriver.log"
-#      - "--verbose"
-#      - "--whitelisted-ips="
-
-
-  #data volumes https://docs.docker.com/storage/volumes/
-#volumes:
-#  mariadb-datavolume:
-#  postgres-datavolume:
diff --git a/web/modules/config_filter/grumphp.yml b/web/modules/config_filter/grumphp.yml
deleted file mode 100644
index 6e3b61a889c65154ff4e07d5535b9b8d66d8ae18..0000000000000000000000000000000000000000
--- a/web/modules/config_filter/grumphp.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-grumphp:
-  git_hook_variables:
-    EXEC_GRUMPHP_COMMAND: ['docker-compose', 'run', '--rm', '--no-deps', 'drupal']
-  ascii:
-    succeeded: ~
-  tasks:
-    phpcs: ~
-    phplint: ~
-    phpstan: ~
-    phpunit: ~
diff --git a/web/modules/config_filter/phpcs.xml.dist b/web/modules/config_filter/phpcs.xml.dist
deleted file mode 100644
index f88da0b6237bb5e7220ec6c73150effbd004ebd7..0000000000000000000000000000000000000000
--- a/web/modules/config_filter/phpcs.xml.dist
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ruleset name="Module">
-  <file>.</file>
-  <arg name="extensions" value="php,module,inc,install,test,profile,theme,css,info,txt,md,yml"/>
-  <config name="drupal_core_version" value="8"/>
-
-  <!-- Initially include all Drupal and DrupalPractice sniffs. -->
-  <rule ref="vendor/drupal/coder/coder_sniffer/Drupal"/>
-  <rule ref="vendor/drupal/coder/coder_sniffer/DrupalPractice"/>
-
-  <!-- Use 's' to print the full sniff name in the report. -->
-  <!-- A '-' is prefixed to each of these, so s becomes -s, etc. -->
-  <arg value="s"/>
-  <arg value="-colors"/>
-  <arg name='report-width' value='120'/>
-
-  <!-- Ignore all files that match these patterns. They are matched against -->
-  <!-- the full file path and there is an implied wildcard at each end. -->
-  <!-- Periods must be escaped using \. -->
-  <exclude-pattern>_ignore</exclude-pattern>
-  <exclude-pattern>\.patch</exclude-pattern>
-  <exclude-pattern>interdif</exclude-pattern>
-
-  <!-- Examples for how you disable rules you do not like. -->
-  <!-- Exclude a sniff from running on specific files. -->
-  <rule ref="Drupal.Files.TxtFileLineLength.TooLong">
-    <!-- Exclude .md files from the line limit rule. -->
-    <exclude-pattern>\.md</exclude-pattern>
-  </rule>
-  <rule ref="Drupal.Commenting.DocComment.ParamNotFirst">
-    <!-- Drush commands are most readable with @command at top. -->
-    <exclude-pattern>Commands\.php</exclude-pattern>
-  </rule>
-
-  <!-- Use a rule, but exclude one of its sniffs from all files. -->
-  <rule ref="Drupal.Arrays.Array.LongLineDeclaration">
-    <!-- Method declarations should be exempt. -->
-    <severity>0</severity>
-  </rule>
-
-</ruleset>
diff --git a/web/modules/config_filter/phpstan.neon b/web/modules/config_filter/phpstan.neon
deleted file mode 100644
index c47caefcbbd22451be7cab8260652ce2dc741f38..0000000000000000000000000000000000000000
--- a/web/modules/config_filter/phpstan.neon
+++ /dev/null
@@ -1,15 +0,0 @@
-parameters:
-  level: 1
-  customRulesetUsed: true
-  reportUnmatchedIgnoredErrors: false
-  ignoreErrors:
-    # One day we might get rid of this drupal pattern
-    - '#Unsafe usage of new static\(\)\.#'
-  paths:
-    - src
-#    - tests
-  excludes_analyse:
-    - src/Tests/*
-includes:
-  - vendor/mglaman/phpstan-drupal/extension.neon
-  - vendor/phpstan/phpstan-deprecation-rules/rules.neon
diff --git a/web/modules/config_filter/phpunit.xml.dist b/web/modules/config_filter/phpunit.xml.dist
deleted file mode 100644
index 176e11fa9669ffbac0acd003791cedbf080e3cda..0000000000000000000000000000000000000000
--- a/web/modules/config_filter/phpunit.xml.dist
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!-- TODO set checkForUnintentionallyCoveredCode="true" once https://www.drupal.org/node/2626832 is resolved. -->
-<!-- PHPUnit expects functional tests to be run with either a privileged user
- or your current system user. See core/tests/README.md and
- https://www.drupal.org/node/2116263 for details.
--->
-<phpunit bootstrap="web/core/tests/bootstrap.php" colors="true"
-         beStrictAboutTestsThatDoNotTestAnything="true"
-         beStrictAboutOutputDuringTests="true"
-         beStrictAboutChangesToGlobalState="true"
-         printerClass="\Drupal\Tests\Listeners\HtmlOutputPrinter">
-  <php>
-    <!-- Set error reporting to E_ALL. -->
-    <ini name="error_reporting" value="32767"/>
-    <!-- Do not limit the amount of memory tests take to run. -->
-    <ini name="memory_limit" value="-1"/>
-    <!-- Example SIMPLETEST_BASE_URL value: http://localhost -->
-    <env name="SIMPLETEST_BASE_URL" value="http://drupal:8888"/>
-    <!-- Example SIMPLETEST_DB value: mysql://username:password@localhost/databasename#table_prefix -->
-    <env name="SIMPLETEST_DB" value="mysql://root:password@mariadb/db"/>
-    <!-- Example BROWSERTEST_OUTPUT_DIRECTORY value: /path/to/webroot/sites/simpletest/browser_output -->
-    <env name="BROWSERTEST_OUTPUT_DIRECTORY" value="/tmp"/>
-    <!-- To have browsertest output use an alternative base URL. For example if
-     SIMPLETEST_BASE_URL is an internal DDEV URL, you can set this to the
-     external DDev URL so you can follow the links directly.
-    -->
-    <env name="BROWSERTEST_OUTPUT_BASE_URL" value=""/>
-    <env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled"/>
-    <!-- Example for changing the driver class for mink tests MINK_DRIVER_CLASS value: 'Drupal\FunctionalJavascriptTests\DrupalSelenium2Driver' -->
-    <env name="MINK_DRIVER_CLASS" value=''/>
-    <!-- Example for changing the driver args to mink tests MINK_DRIVER_ARGS value: '["http://127.0.0.1:8510"]' -->
-    <env name="MINK_DRIVER_ARGS" value=''/>
-    <!-- Example for changing the driver args to phantomjs tests MINK_DRIVER_ARGS_PHANTOMJS value: '["http://127.0.0.1:8510"]' -->
-    <env name="MINK_DRIVER_ARGS_PHANTOMJS" value=''/>
-    <!-- Example for changing the driver args to webdriver tests MINK_DRIVER_ARGS_WEBDRIVER value: '["chrome", { "chromeOptions": { "w3c": false } }, "http://localhost:4444/wd/hub"]' For using the Firefox browser, replace "chrome" with "firefox" -->
-    <!-- Example from drupal.org https://dispatcher.drupalci.org/job/drupal_contrib/177251/console-->
-    <env name="MINK_DRIVER_ARGS_WEBDRIVER" value='["chrome", {"browserName":"chrome","chromeOptions":{"args":["--disable-gpu","--headless"]}}, "http://chrome:9515"]'/>
-  </php>
-  <testsuites>
-    <testsuite name="unit">
-      <directory>./src/Tests/</directory>
-    </testsuite>
-    <testsuite name="kernel">
-      <directory>./tests/src/Kernel/</directory>
-    </testsuite>
-  </testsuites>
-  <listeners>
-    <listener class="\Drupal\Tests\Listeners\DrupalListener">
-    </listener>
-    <!-- The Symfony deprecation listener has to come after the Drupal listener -->
-    <listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener">
-    </listener>
-  </listeners>
-</phpunit>
diff --git a/web/modules/config_filter/tests/modules/config_filter_split_test/config_filter_split_test.info.yml b/web/modules/config_filter/tests/modules/config_filter_split_test/config_filter_split_test.info.yml
index f071cfb42a4a11129a6a78527528ec61e8b603cc..231453b850f909f655432e46ba37b53af31cdfcd 100644
--- a/web/modules/config_filter/tests/modules/config_filter_split_test/config_filter_split_test.info.yml
+++ b/web/modules/config_filter/tests/modules/config_filter_split_test/config_filter_split_test.info.yml
@@ -6,7 +6,7 @@ package: Testing
 dependencies:
   - config_filter:config_filter
 
-# Information added by Drupal.org packaging script on 2020-10-05
-version: '8.x-1.7'
+# Information added by Drupal.org packaging script on 2020-10-28
+version: '8.x-1.8'
 project: 'config_filter'
-datestamp: 1601934755
+datestamp: 1603870063
diff --git a/web/modules/config_filter/tests/modules/config_filter_test/config_filter_test.info.yml b/web/modules/config_filter/tests/modules/config_filter_test/config_filter_test.info.yml
index 9e5a560e17380de0cd3ec567796a71aaa925f0ba..7fec84b0ed2201e791d92042e719137f64189826 100644
--- a/web/modules/config_filter/tests/modules/config_filter_test/config_filter_test.info.yml
+++ b/web/modules/config_filter/tests/modules/config_filter_test/config_filter_test.info.yml
@@ -6,7 +6,7 @@ package: Testing
 dependencies:
   - config_filter:config_filter
 
-# Information added by Drupal.org packaging script on 2020-10-05
-version: '8.x-1.7'
+# Information added by Drupal.org packaging script on 2020-10-28
+version: '8.x-1.8'
 project: 'config_filter'
-datestamp: 1601934755
+datestamp: 1603870063
diff --git a/web/modules/config_filter/tests/phpunit.xml.dist b/web/modules/config_filter/tests/phpunit.xml.dist
deleted file mode 100644
index abb466ba1c8910770eba96d78b0d2d79f52015d4..0000000000000000000000000000000000000000
--- a/web/modules/config_filter/tests/phpunit.xml.dist
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<phpunit bootstrap="core/tests/bootstrap.php" backupGlobals="false" colors="true" >
-  <php>
-    <ini name="error_reporting" value="32767"/>
-    <ini name="memory_limit" value="-1"/>
-    <env name="SIMPLETEST_DB" value="mysql://travis:@127.0.0.1/drupal"/>
-  </php>
-  <testsuites>
-    <testsuite name="tests">
-      <directory>./modules/config_filter/</directory>
-    </testsuite>
-  </testsuites>
-</phpunit>
diff --git a/web/modules/config_filter/tests/src/Kernel/ConfigStorageTestTrait.php b/web/modules/config_filter/tests/src/Kernel/ConfigStorageTestTrait.php
index b448e59ef1e3c7e5750b22a56b64167cfa867016..3a6fee528e5cf73562335e855ffc1c88214caf8d 100644
--- a/web/modules/config_filter/tests/src/Kernel/ConfigStorageTestTrait.php
+++ b/web/modules/config_filter/tests/src/Kernel/ConfigStorageTestTrait.php
@@ -108,6 +108,9 @@ protected function getExportStorage(): StorageInterface {
     // For config filter 1.x we need to trigger the write filters.
     // Set up a filtered storage with the sync storage filters.
     $memory = new MemoryStorage();
+    // Add the sync config so that filters can read from it.
+    $this->copyConfig($this->container->get('config.storage.sync'), $memory);
+    // Create a filtered storage.
     $filtered = $this->container->get('config_filter.storage_factory')->getFilteredStorage($memory, ['config.storage.sync']);
     // Then write the core export storage to this new storage.
     $this->copyConfig($unfiltered, $filtered);
diff --git a/web/modules/config_ignore/composer.json b/web/modules/config_ignore/composer.json
index 9e8ee9b9929cc1befc9c08be3ddc961aa67eaccd..1107b10fa56a04d7d9e8cd88b3131ded22264496 100644
--- a/web/modules/config_ignore/composer.json
+++ b/web/modules/config_ignore/composer.json
@@ -19,11 +19,11 @@
   "support": {
     "issues": "http://drupal.org/project/config_ignore",
     "irc": "irc://irc.freenode.org/drupal-contribute",
-    "source": "http://cgit.drupalcode.org/config_ignore"
+    "source": "https://git.drupalcode.org/project/config_ignore"
   },
-  "license": "GPL-2.0+",
+  "license": "GPL-2.0-or-later",
   "minimum-stability": "dev",
   "require": {
-    "drupal/config_filter": "1.*"
+    "drupal/config_filter": "^1 || ^2"
   }
 }
diff --git a/web/modules/config_ignore/config_ignore.info.yml b/web/modules/config_ignore/config_ignore.info.yml
index 36ffa8a057ed7b246e15cf8cc132695bc525c929..35c5d75bd93e3634701b36fac63df1ab6623cd89 100644
--- a/web/modules/config_ignore/config_ignore.info.yml
+++ b/web/modules/config_ignore/config_ignore.info.yml
@@ -1,13 +1,13 @@
 name: Config Ignore
 type: module
 description: Ignore certain configuration during import
-core: 8.x
+core_version_requirement: ^8 || ^9
 package: Config
 configure: config_ignore.settings
 dependencies:
   - config_filter:config_filter
 
-# Information added by Drupal.org packaging script on 2019-12-16
-version: '8.x-2.2'
+# Information added by Drupal.org packaging script on 2020-12-18
+version: '8.x-2.3'
 project: 'config_ignore'
-datestamp: 1576528389
+datestamp: 1608306492
diff --git a/web/modules/config_ignore/config_ignore.module b/web/modules/config_ignore/config_ignore.module
index 3ed573ad7d1381d48b1c163651ae39a717175bea..96e1efd6e543f97f7fdebcbbb6826b7a9219d2ca 100644
--- a/web/modules/config_ignore/config_ignore.module
+++ b/web/modules/config_ignore/config_ignore.module
@@ -6,9 +6,7 @@
  */
 
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Config\StorageInterface;
 use Drupal\Core\Config\StorageComparer;
-use Drupal\Core\Config\FileStorage;
 use Drupal\Core\Url;
 
 /**
@@ -18,15 +16,14 @@ function config_ignore_form_config_admin_import_form_alter(&$form, FormStateInte
 
   // Load Services that we need.
   $stock_storage_sync = \Drupal::service('config_filter.storage_factory')->getSyncWithoutExcluded(['config_ignore']);
-  $active_storage_sync = \Drupal::service('config.storage.sync');
+  $active_storage_sync = \Drupal::service('config.import_transformer')->transform(\Drupal::service('config.storage.sync'));
   $storage = \Drupal::service('config.storage');
-  $config_manager = \Drupal::service('config.manager');
 
   // Create two StorageComparer objects, one with the filter enabled and one
   // as without. We will compare them later to see what changes that has been
   // ignored.
-  $unfiltered_storage_compare = new StorageComparer($stock_storage_sync, $storage, $config_manager);
-  $filtered_storage_compare = new StorageComparer($active_storage_sync, $storage, $config_manager);
+  $unfiltered_storage_compare = new StorageComparer($stock_storage_sync, $storage);
+  $filtered_storage_compare = new StorageComparer($active_storage_sync, $storage);
   $unfiltered_storage_compare->createChangelist();
   $filtered_storage_compare->createChangelist();
 
@@ -61,7 +58,7 @@ function config_ignore_form_config_admin_import_form_alter(&$form, FormStateInte
       '#header' => ['Config name', 'Action'],
       '#caption' => t('<h3>The following configuration entities are ignored due to the <a href="@url">Config Ignore Settings</a> and therefore not displayed in the list above</h3>', [
         '@url' => Url::fromRoute('config_ignore.settings')
-          ->toString()
+          ->toString(),
       ]),
       '#rows' => $ignored_config_entities,
     ];
diff --git a/web/modules/config_ignore/src/Plugin/ConfigFilter/IgnoreFilter.php b/web/modules/config_ignore/src/Plugin/ConfigFilter/IgnoreFilter.php
index 1864db6ae99e875ff9706b093057d6ce98f51bf1..3823e926de2b56fe637b8260d1a6f084e29f9aae 100644
--- a/web/modules/config_ignore/src/Plugin/ConfigFilter/IgnoreFilter.php
+++ b/web/modules/config_ignore/src/Plugin/ConfigFilter/IgnoreFilter.php
@@ -89,8 +89,8 @@ protected function matchConfigName($config_name) {
 
     foreach ($this->configuration['ignored'] as $config_ignore_setting) {
       // Split the ignore settings so that we can ignore individual keys.
-      $ignore = explode(':', $config_ignore_setting);
-      if (fnmatch($ignore[0], $config_name)) {
+      $ignore = explode(':', $config_ignore_setting, 2);
+      if (self::wildcardMatch($ignore[0], $config_name)) {
         return TRUE;
       }
     }
@@ -118,8 +118,8 @@ protected function activeRead($name, $data) {
     $keys = [];
     foreach ($this->configuration['ignored'] as $ignored) {
       // Split the ignore settings so that we can ignore individual keys.
-      $ignored = explode(':', $ignored);
-      if (fnmatch($ignored[0], $name)) {
+      $ignored = explode(':', $ignored, 2);
+      if (self::wildcardMatch($ignored[0], $name)) {
         if (count($ignored) == 1) {
           // If one of the definitions does not have keys ignore the
           // whole config.
@@ -134,7 +134,7 @@ protected function activeRead($name, $data) {
     }
 
     $active = $this->active->read($name);
-    if (!$active) {
+    if (!$active || !$data) {
       return $data;
     }
     foreach ($keys as $key) {
@@ -177,7 +177,7 @@ protected function activeReadMultiple(array $names, array $data) {
       $filtered_data[$name] = $this->activeRead($name, $data[$name]);
     }
 
-    return $filtered_data;
+    return array_filter($filtered_data);
   }
 
   /**
@@ -239,4 +239,21 @@ public function filterGetAllCollectionNames(array $collections) {
     return array_merge($collections, $this->active->getAllCollectionNames());
   }
 
+  /**
+   * Checks if a string matches a given wildcard pattern.
+   *
+   * @param string $pattern
+   *   The wildcard pattern to me matched.
+   * @param string $string
+   *   The string to be checked.
+   *
+   * @return bool
+   *   TRUE if $string string matches the $pattern pattern.
+   */
+  protected static function wildcardMatch($pattern, $string) {
+    $pattern = '/^' . preg_quote($pattern, '/') . '$/';
+    $pattern = str_replace('\*', '.*', $pattern);
+    return (bool) preg_match($pattern, $string);
+  }
+
 }
diff --git a/web/modules/config_ignore/tests/modules/config_ignore_hook_test.info.yml b/web/modules/config_ignore/tests/modules/config_ignore_hook_test.info.yml
index 9e8bc96b10fd288866e9e06cf949aa5d49fd4fea..7d8195159bb74b98e4d534917c59b20f20e4f53f 100644
--- a/web/modules/config_ignore/tests/modules/config_ignore_hook_test.info.yml
+++ b/web/modules/config_ignore/tests/modules/config_ignore_hook_test.info.yml
@@ -1,13 +1,12 @@
 name: Config Ignore Hook Test
 type: module
 description: Module that implements all the hook from Config Ignore for testing purposes
-core: 8.x
 package: Testing
 hidden: true
 dependencies:
   - config_ignore
 
-# Information added by Drupal.org packaging script on 2019-12-16
-version: '8.x-2.2'
+# Information added by Drupal.org packaging script on 2020-12-18
+version: '8.x-2.3'
 project: 'config_ignore'
-datestamp: 1576528389
+datestamp: 1608306492
diff --git a/web/modules/config_ignore/tests/src/Functional/ConfigIgnoreBrowserTestBase.php b/web/modules/config_ignore/tests/src/Functional/ConfigIgnoreBrowserTestBase.php
index 5e47eb385dbc07adfd9b2c2b3d0bc80e0352490d..07476398bc6e5d26eac9acea2fe43fffdb372336 100644
--- a/web/modules/config_ignore/tests/src/Functional/ConfigIgnoreBrowserTestBase.php
+++ b/web/modules/config_ignore/tests/src/Functional/ConfigIgnoreBrowserTestBase.php
@@ -3,9 +3,9 @@
 namespace Drupal\Tests\config_ignore\Functional;
 
 use Drupal\Core\Config\ConfigImporter;
-use Drupal\Core\Config\FileStorage;
 use Drupal\Core\Config\StorageComparer;
 use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\config_filter\Kernel\ConfigStorageTestTrait;
 
 /**
  * Class ConfigIgnoreBrowserTestBase.
@@ -14,6 +14,8 @@
  */
 abstract class ConfigIgnoreBrowserTestBase extends BrowserTestBase {
 
+  use ConfigStorageTestTrait;
+
   /**
    * Modules to enable.
    *
@@ -21,15 +23,19 @@ abstract class ConfigIgnoreBrowserTestBase extends BrowserTestBase {
    */
   public static $modules = ['config_ignore', 'config', 'config_filter'];
 
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
   /**
    * Perform a config import from sync. folder.
    */
   public function doImport() {
     // Set up the ConfigImporter object for testing.
     $storage_comparer = new StorageComparer(
-      $this->container->get('config.storage.sync'),
-      $this->container->get('config.storage'),
-      $this->container->get('config.manager')
+      $this->getImportStorage(),
+      $this->container->get('config.storage')
     );
 
     $config_importer = new ConfigImporter(
@@ -41,7 +47,8 @@ public function doImport() {
       $this->container->get('module_handler'),
       $this->container->get('module_installer'),
       $this->container->get('theme_handler'),
-      $this->container->get('string_translation')
+      $this->container->get('string_translation'),
+      $this->container->get('extension.list.module')
     );
 
     $config_importer->reset()->import();
@@ -51,16 +58,8 @@ public function doImport() {
    * Perform a config export to sync. folder.
    */
   public function doExport() {
-    // Setup a config sync. dir with a, more or less,  know set of config
-    // entities. This is a full blown export of yaml files, written to the disk.
-    $destination = CONFIG_SYNC_DIRECTORY;
-    $destination_dir = config_get_config_directory($destination);
-    /** @var \Drupal\Core\Config\CachedStorage $source_storage */
-    $source_storage = \Drupal::service('config.storage');
-    $destination_storage = new FileStorage($destination_dir);
-    foreach ($source_storage->listAll() as $name) {
-      $destination_storage->write($name, $source_storage->read($name));
-    }
+    // Export the config using the export storage service.
+    $this->copyConfig($this->getExportStorage(), $this->getSyncFileStorage());
   }
 
 }
diff --git a/web/modules/config_ignore/tests/src/Functional/ConfigIgnoreTest.php b/web/modules/config_ignore/tests/src/Functional/ConfigIgnoreTest.php
index eeae220b7c2fcc154e4de9d65dfa4bec77a3ffe3..c7403a01d0b80a632c6178b4e1229355e5541da7 100644
--- a/web/modules/config_ignore/tests/src/Functional/ConfigIgnoreTest.php
+++ b/web/modules/config_ignore/tests/src/Functional/ConfigIgnoreTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\Tests\config_ignore\Functional;
 
 use Drupal\config_ignore\Plugin\ConfigFilter\IgnoreFilter;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
 
 /**
  * Test functionality of config_ignore module.
@@ -15,6 +16,8 @@
  */
 class ConfigIgnoreTest extends ConfigIgnoreBrowserTestBase {
 
+  use StringTranslationTrait;
+
   /**
    * Verify that the Sync. table gets update with appropriate ignore actions.
    */
@@ -62,7 +65,7 @@ public function testSettingsForm() {
     ];
 
     $this->drupalGet('admin/config/development/configuration/ignore');
-    $this->submitForm($edit, t('Save configuration'));
+    $this->submitForm($edit, $this->t('Save configuration'));
 
     $settings = $this->config('config_ignore.settings')->get('ignored_config_entities');
 
diff --git a/web/modules/config_ignore/tests/src/Kernel/IgnoreKernelTest.php b/web/modules/config_ignore/tests/src/Kernel/IgnoreKernelTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8069e557c4ef20dd8fde9d83ab50bda3021f6bfe
--- /dev/null
+++ b/web/modules/config_ignore/tests/src/Kernel/IgnoreKernelTest.php
@@ -0,0 +1,331 @@
+<?php
+
+namespace Drupal\Tests\config_ignore\Kernel;
+
+use Drupal\Component\Utility\NestedArray;
+use Drupal\Core\Config\MemoryStorage;
+use Drupal\Core\Config\StorageInterface;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\language\Entity\ConfigurableLanguage;
+use Drupal\Tests\config_filter\Kernel\ConfigStorageTestTrait;
+
+/**
+ * Test the transformations.
+ *
+ * This test is a bit more condensed and doesn't actually import the config.
+ *
+ * @group config_ignore_new
+ */
+class IgnoreKernelTest extends KernelTestBase {
+
+  use ConfigStorageTestTrait;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'system',
+    'language',
+    'config',
+    'config_test',
+    'config_ignore',
+    'config_filter',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // We install the system and config_test config so that there is something
+    // to modify and ignore for the test.
+    $this->installConfig(['system', 'config_test']);
+
+    // Set up multilingual. The config_test module comes with translations.
+    ConfigurableLanguage::createFromLangcode('de')->save();
+    ConfigurableLanguage::createFromLangcode('fr')->save();
+  }
+
+  /**
+   * Test the import transformations.
+   *
+   * @param array $modes
+   *   The import modes.
+   * @param array $patterns
+   *   An array of ignore patterns, we may refactor this to be the whole config.
+   * @param array $active
+   *   Modifications to the active config.
+   * @param array $sync
+   *   Modifications to the sync storage.
+   * @param array $expected
+   *   Modifications to the expected storage.
+   *
+   * @dataProvider importProvider
+   */
+  public function testImport(array $modes, array $patterns, array $active, array $sync, array $expected) {
+      $this->config('config_ignore.settings')->set('ignored_config_entities', $patterns)->save();
+
+      $expectedStorage = $this->setUpStorages($active, $sync, $expected);
+
+      static::assertStorageEquals($expectedStorage, $this->getImportStorage());
+  }
+
+  /**
+   * Provides the test cases for the import.
+   *
+   * @return array
+   *   The test case.
+   */
+  public function importProvider() {
+    return [
+      'empty test' => [
+        // Modes, these are not implemented yet.
+        [],
+        // The ignore config.
+        [],
+        // Modifications to the active config keyed by language.
+        [],
+        // Modifications to the sync config keyed by language.
+        [],
+        // Modifications to the expected config keyed by language.
+        [],
+      ],
+      'keep config deleted in sync' => [
+        [],
+        ['config_test.system'],
+        [],
+        [
+          // Delete the config_test.system from all languages in sync storage.
+          '' => ['config_test.system' => FALSE],
+          'de' => ['config_test.system' => FALSE],
+          'fr' => ['config_test.system' => FALSE],
+        ],
+        [],
+      ],
+      'remove translation when not ignored' => [
+        [],
+        ['config_test.system'],
+        ['de' => ['config_test.no_status.default' => ['label' => 'DE default']]],
+        [],
+        [],
+      ],
+      'do not remove translation when ignored' => [
+        [],
+        ['config_test.system'],
+        ['de' => ['config_test.system' => ['foo' => 'Neues Foo']]],
+        [],
+        ['de' => ['config_test.system' => ['foo' => 'Neues Foo']]],
+      ],
+      'do not remove translation when key is ignored' => [
+        [],
+        ['config_test.system:foo'],
+        ['de' => ['config_test.system' => ['foo' => 'Neues Foo']]],
+        [],
+        ['de' => ['config_test.system' => ['foo' => 'Neues Foo']]],
+      ],
+      'remove translation when other key is ignored' => [
+        [],
+        ['config_test.system:404'],
+        ['de' => ['config_test.system' => ['foo' => 'Neues Foo']]],
+        [],
+        [],
+      ],
+      'new translation is ignored' => [
+        ['strict'],
+        ['config_test.*'],
+        [],
+        ['se' => ['config_test.system' => ['foo' => 'Ny foo']]],
+        [],
+      ],
+      'new config is ignored' => [
+        ['strict'],
+        ['config_test.*'],
+        [
+          '' => [
+            'config_test.dynamic.exist' => ['id' => 'exist', 'label' => 'E'],
+          ],
+        ],
+        [
+          '' => [
+            'config_test.dynamic.exist' => ['id' => 'exist', 'label' => 'N'],
+            'config_test.dynamic.new' => ['id' => 'new', 'label' => 'N'],
+            'config_test.system' => ['foo' => 'ignored']
+          ],
+        ],
+        [
+          '' => [
+            'config_test.dynamic.exist' => ['id' => 'exist', 'label' => 'E'],
+          ],
+        ],
+      ],
+//      'new config is not ignored in lenient mode' => [
+//        ['lenient'],
+//        ['config_test.*'],
+//        [
+//          '' => [
+//            'config_test.dynamic.exist' => ['id' => 'exist', 'label' => 'E'],
+//          ],
+//        ],
+//        [
+//          '' => [
+//            'config_test.dynamic.exist' => ['id' => 'exist', 'label' => 'N'],
+//            'config_test.dynamic.new' => ['id' => 'new', 'label' => 'N'],
+//            'config_test.system' => ['foo' => 'ignored']
+//          ],
+//        ],
+//        [
+//          '' => [
+//            'config_test.dynamic.exist' => ['id' => 'exist', 'label' => 'E'],
+//            'config_test.dynamic.new' => ['id' => 'new', 'label' => 'N'],
+//          ],
+//        ],
+//      ],
+      'new config with only key ignored (issue 3137437)' => [
+        ['strict'],
+        ['config_test.*:label'],
+        ['' => ['config_test.dynamic.exist' => ['id' => 'exist', 'label' => 'E']]],
+        [],
+        [],
+      ],
+//      'new config with  only key ignored lenient (issue 3137437)' => [
+//        ['lenient'],
+//        ['config_test.*:label'],
+//        ['' => ['config_test.dynamic.exist' => ['id' => 'exist', 'label' => 'E']]],
+//        [],
+//        ['' => ['config_test.dynamic.exist' => ['id' => 'exist', 'label' => 'E']]],
+//      ],
+    ];
+  }
+
+  /**
+   * Test the export transformations.
+   *
+   * @param string $mode
+   *   The export mode
+   * @param array $patterns
+   *   An array of ignore patterns, we may refactor this to be the whole config.
+   * @param array $active
+   *   Modifications to the active config.
+   * @param array $sync
+   *   Modifications to the sync storage.
+   * @param array $expected
+   *   Modifications to the expected storage.
+   *
+   * @dataProvider exportProvider
+   */
+  public function testExport(array $modes, array $patterns, array $active, array $sync, array $expected) {
+    $this->config('config_ignore.settings')->set('ignored_config_entities', $patterns)->save();
+
+    $expectedStorage = $this->setUpStorages($active, $sync, $expected);
+
+    static::assertStorageEquals($expectedStorage, $this->getExportStorage());
+  }
+
+  /**
+   * Provides the test cases for the export.
+   *
+   * @return array
+   */
+  public function exportProvider() {
+    // @todo: add meaningful tests in https://www.drupal.org/project/config_ignore/issues/2857247
+    return [
+      'empty test' => [
+        // For now exporting is always off.
+        ['off'],
+        // The ignore config.
+        [],
+        // Modifications to the active config keyed by language.
+        [],
+        // Modifications to the sync config keyed by language.
+        [],
+        // Modifications to the expected config keyed by language.
+        [],
+      ],
+    ];
+  }
+
+  /**
+   * Set up the active, sync and expected storages.
+   *
+   * @param array $active
+   *   Modifications to the active config.
+   * @param array $sync
+   *   Modifications to the sync storage.
+   * @param array $expected
+   *   Modifications to the expected storage.
+   *
+   * @return \Drupal\Core\Config\StorageInterface
+   *   The expected storage.
+   */
+  protected function setUpStorages(array $active, array $sync, array $expected): StorageInterface {
+    // Copy the active config to the sync storage and the expected storage.
+    $syncStorage = $this->getSyncFileStorage();
+    $expectedStorage = new MemoryStorage();
+    $this->copyConfig($this->getActiveStorage(), $syncStorage);
+    $this->copyConfig($this->getActiveStorage(), $expectedStorage);
+
+    // Then modify the active storage by saving the config which was given.
+    foreach ($active as $lang => $configs) {
+      foreach ($configs as $name => $data) {
+        if ($lang === '') {
+          $config = $this->config($name);
+        }
+        else {
+          // Load the config override.
+          $config = \Drupal::languageManager()->getLanguageConfigOverride($lang, $name);
+        }
+
+        if ($data !== FALSE) {
+          $config->merge($data)->save();
+        }
+        else {
+          // If the data is not an array we want to delete it.
+          $config->delete();
+        }
+      }
+    }
+
+    // Apply modifications to the storages.
+    static::modifyStorage($syncStorage, $sync);
+    static::modifyStorage($expectedStorage, $expected);
+
+    return $expectedStorage;
+  }
+
+  /**
+   * Helper method to modify a config storage.
+   *
+   * @param \Drupal\Core\Config\StorageInterface $storage
+   *   The storage to modify.
+   * @param array $modifications
+   *   The modifications keyed by language.
+   */
+  protected static function modifyStorage(StorageInterface $storage, array $modifications) {
+    foreach ($modifications as $lang => $configs) {
+      $lang = $lang === '' ? StorageInterface::DEFAULT_COLLECTION : 'language.' . $lang;
+      $storage = $storage->createCollection($lang);
+      if ($configs === NULL) {
+        // If it is set to null explicitly remove everything.
+        $storage->deleteAll();
+        return;
+      }
+      foreach ($configs as $name => $data) {
+        if ($data !== FALSE) {
+          if (is_array($storage->read($name))) {
+            // Merge nested arrays if the storage already has data.
+            $data = NestedArray::mergeDeep($storage->read($name), $data);
+          }
+          $storage->write($name, $data);
+        }
+        else {
+          // A config name set to false means deleting it.
+          $storage->delete($name);
+        }
+      }
+    }
+  }
+
+}
diff --git a/web/modules/config_ignore/tests/src/Unit/PatternMatchingTest.php b/web/modules/config_ignore/tests/src/Unit/PatternMatchingTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f694dc49e8156f461d1f8b76b764570d6b4c65d5
--- /dev/null
+++ b/web/modules/config_ignore/tests/src/Unit/PatternMatchingTest.php
@@ -0,0 +1,126 @@
+<?php
+
+namespace Drupal\Tests\config_ignore\Unit;
+
+use Drupal\config_ignore\Plugin\ConfigFilter\IgnoreFilter;
+use Drupal\Core\Config\MemoryStorage;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Test the pattern matching.
+ *
+ * This is a unit test which tests the protected method, but it is much faster.
+ *
+ * @group config_ignore_new
+ */
+class PatternMatchingTest extends UnitTestCase {
+
+  /**
+   * Test the ignored config matching against names.
+   *
+   * @param array $patterns
+   *   The config of ignored names.
+   * @param array $test
+   *   An array with config names as keys and the expected outcome as value.
+   *
+   * @dataProvider patternProvider
+   */
+  public function testPatternMatching(array $patterns, array $test) {
+
+    $filter = new IgnoreFilter(['ignored' => $patterns], 'config_ignore', [], new MemoryStorage());
+
+    // In order to test much faster we access the protected method.
+    $method = new \ReflectionMethod(IgnoreFilter::class, 'matchConfigName');
+    $method->setAccessible(TRUE);
+    foreach ($test as $name => $expected) {
+      static::assertEquals($expected, $method->invoke($filter, $name), $name);
+    }
+
+    if (!in_array(TRUE, $test, TRUE) || !in_array(FALSE, $test, TRUE)) {
+      // Make sure there is always a positive and negative test.
+      $this->markAsRisky();
+    }
+  }
+
+  /**
+   * Get the ignored config and test against the names.
+   *
+   * @return array
+   *   The patterns and what should and shouldn't match.
+   */
+  public function patternProvider() {
+    // For each pattern there needs to be a positive and a negative case.
+    return [
+      'system.site ignored' => [
+        ['system.site'],
+        [
+          'system.site' => TRUE,
+          'system.performance' => FALSE,
+        ],
+      ],
+      'system ignored' => [
+        ['system.*'],
+        [
+          'system.site' => TRUE,
+          'system.performance' => TRUE,
+          'node.site' => FALSE,
+        ],
+      ],
+      'site ignored' => [
+        ['*.site'],
+        [
+          'system.site' => TRUE,
+          'system.performance' => FALSE,
+          'other.site' => TRUE,
+        ],
+      ],
+      'node ignored' => [
+        ['node.*'],
+        [
+          'system.site' => FALSE,
+          'node.settings' => TRUE,
+          'node.settings.other' => TRUE,
+        ],
+      ],
+      'middle ignored' => [
+        ['start.*.end'],
+        [
+          'start.something' => FALSE,
+          'start.something.end' => TRUE,
+          'start.something.else.end' => TRUE,
+          'start.something.ending' => FALSE,
+        ],
+      ],
+      'enforced excluded' => [
+        ['system.*', '~system.site'],
+        [
+          'system.site' => FALSE,
+          'system.performance' => TRUE,
+        ],
+      ],
+      'system sub-key ignored' => [
+        ['system.*:foo'],
+        [
+          'system.site' => TRUE,
+          'system.performance' => TRUE,
+          'node.foo' => FALSE,
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * Test the cases that are not allowed in testPatternMatching.
+   */
+  public function testEverythingAndNothing() {
+    $method = new \ReflectionMethod(IgnoreFilter::class, 'matchConfigName');
+    $method->setAccessible(TRUE);
+
+    $none = new IgnoreFilter(['ignored' => []], 'config_ignore', [], new MemoryStorage());
+    $all = new IgnoreFilter(['ignored' => ['*']], 'config_ignore', [], new MemoryStorage());
+
+    static::assertFalse($method->invoke($none, $this->randomMachineName()));
+    static::assertTrue($method->invoke($all, $this->randomMachineName()));
+  }
+
+}
diff --git a/web/modules/linkit/composer.json b/web/modules/linkit/composer.json
index 3addc0246f08b716717da49d8478752d2d556082..eb28ea2f63458db99b4096d3f0dde4945fb554dd 100644
--- a/web/modules/linkit/composer.json
+++ b/web/modules/linkit/composer.json
@@ -18,5 +18,5 @@
   "require" : {
     "drupal/core": "^8.7.7 || ^9"
   },
-  "license": "GPL-2.0+"
+  "license": "GPL-2.0-or-later"
 }
diff --git a/web/modules/linkit/linkit.info.yml b/web/modules/linkit/linkit.info.yml
index b096913a5e8444fcb287cee18b059d0d83fde27e..d06654c0d86d8a8e75ff3109af751ba0e420a004 100644
--- a/web/modules/linkit/linkit.info.yml
+++ b/web/modules/linkit/linkit.info.yml
@@ -7,7 +7,7 @@ configure: entity.linkit_profile.collection
 test_dependencies:
   - imce:imce
 
-# Information added by Drupal.org packaging script on 2020-06-12
-version: '8.x-5.0-beta11'
+# Information added by Drupal.org packaging script on 2020-12-26
+version: '8.x-5.0-beta12'
 project: 'linkit'
-datestamp: 1591971694
+datestamp: 1608957627
diff --git a/web/modules/linkit/linkit.module b/web/modules/linkit/linkit.module
index a076f0a3b66e8e32fc1d28d12de1be3c44b04aa0..a20f8520645026f64e94c9841e900d019400b1ff 100644
--- a/web/modules/linkit/linkit.module
+++ b/web/modules/linkit/linkit.module
@@ -123,8 +123,8 @@ function linkit_form_editor_link_dialog_alter(&$form, FormStateInterface $form_s
 function linkit_form_editor_link_dialog_submit(array &$form, FormStateInterface $form_state) {
   $link_element = $form_state->get('link_element');
 
-  $href = $form_state->getValue(['attributes', 'href']);
-  $href_dirty_check = $form_state->getValue(['href_dirty_check']);
+  $href = parse_url($form_state->getValue(['attributes', 'href']), PHP_URL_PATH);
+  $href_dirty_check = parse_url($form_state->getValue(['href_dirty_check']), PHP_URL_PATH);
 
   if ($href !== $href_dirty_check) {
     $form_state->unsetValue(['attributes', 'data-entity-type']);
diff --git a/web/modules/linkit/src/Plugin/Filter/LinkitFilter.php b/web/modules/linkit/src/Plugin/Filter/LinkitFilter.php
index 02850b710d608acb9986552ac07acf4cc2f8e5fb..f272303855bec983c8f5b39498a89d44ee1a031d 100644
--- a/web/modules/linkit/src/Plugin/Filter/LinkitFilter.php
+++ b/web/modules/linkit/src/Plugin/Filter/LinkitFilter.php
@@ -91,6 +91,12 @@ public function process($text, $langcode) {
           $entity_type = $element->getAttribute('data-entity-type');
           $uuid = $element->getAttribute('data-entity-uuid');
 
+          // Skip empty attributes to prevent loading of non-existing
+          // content type.
+          if ($entity_type === '' || $uuid === '') {
+            continue;
+          }
+
           // Make the substitution optional, for backwards compatibility,
           // maintaining the previous hard-coded direct file link assumptions,
           // for content created before the substitution feature.
@@ -108,7 +114,12 @@ public function process($text, $langcode) {
               ->createInstance($substitution_type)
               ->getUrl($entity);
 
-            $element->setAttribute('href', $url->getGeneratedUrl());
+            // Parse link href as url, extract query and fragment from it.
+            $href_url = parse_url($element->getAttribute('href'));
+            $anchor = empty($href_url["fragment"]) ? '' : '#' . $href_url["fragment"];
+            $query = empty($href_url["query"]) ? '' : '?' . $href_url["query"];
+
+            $element->setAttribute('href', $url->getGeneratedUrl() . $query . $anchor);
 
             // Set the appropriate title attribute.
             if ($this->settings['title'] && !$element->getAttribute('title')) {
diff --git a/web/modules/linkit/tests/linkit_test/linkit_test.info.yml b/web/modules/linkit/tests/linkit_test/linkit_test.info.yml
index f944b479a31303a34106d9e181bdffe1cb352ca5..fa43850746ed110296320c43c1ddf420d90a1c95 100644
--- a/web/modules/linkit/tests/linkit_test/linkit_test.info.yml
+++ b/web/modules/linkit/tests/linkit_test/linkit_test.info.yml
@@ -8,7 +8,7 @@ dependencies:
   - drupal:field
   - drupal:text
 
-# Information added by Drupal.org packaging script on 2020-06-12
-version: '8.x-5.0-beta11'
+# Information added by Drupal.org packaging script on 2020-12-26
+version: '8.x-5.0-beta12'
 project: 'linkit'
-datestamp: 1591971694
+datestamp: 1608957627
diff --git a/web/modules/linkit/tests/src/Functional/LinkitUpdateTest.php b/web/modules/linkit/tests/src/Functional/LinkitUpdateTest.php
index 1bf6bb1d2c659aa02aafeff74bce967f0a4d061e..2d44842e3f83ce4f2e5498fe3df2f6431944748d 100644
--- a/web/modules/linkit/tests/src/Functional/LinkitUpdateTest.php
+++ b/web/modules/linkit/tests/src/Functional/LinkitUpdateTest.php
@@ -105,13 +105,13 @@ public function testLinkitUpdate8500() {
     $this->assertNotNull($format->get('filters.linkit'), 'Linkit filter is enabled.');
 
     $htmlRestrictions = FilterFormat::load('format_1')->getHtmlRestrictions();
-    $this->assertTrue(array_key_exists("data-entity-type", $htmlRestrictions['allowed']['a']));
-    $this->assertTrue(array_key_exists("data-entity-uuid", $htmlRestrictions['allowed']['a']));
-    $this->assertTrue(array_key_exists("data-entity-substitution", $htmlRestrictions['allowed']['a']));
+    $this->assertArrayHasKey("data-entity-type", $htmlRestrictions['allowed']['a']);
+    $this->assertArrayHasKey("data-entity-uuid", $htmlRestrictions['allowed']['a']);
+    $this->assertArrayHasKey("data-entity-substitution", $htmlRestrictions['allowed']['a']);
 
     $htmlRestrictions = FilterFormat::load('format_3')->getHtmlRestrictions();
-    $this->assertTrue(array_key_exists("data-entity-type", $htmlRestrictions['allowed']['a']));
-    $this->assertTrue(array_key_exists("data-entity-uuid", $htmlRestrictions['allowed']['a']));
+    $this->assertArrayHasKey("data-entity-type", $htmlRestrictions['allowed']['a']);
+    $this->assertArrayHasKey("data-entity-uuid", $htmlRestrictions['allowed']['a']);
   }
 
 }
diff --git a/web/modules/linkit/tests/src/Kernel/LinkitFilterEntityTest.php b/web/modules/linkit/tests/src/Kernel/LinkitFilterEntityTest.php
index 285ec0104bbdcccbf71348f48ec7c5c1b9aae806..94897b37472e4d330b1d3f80e756f6238bc8187b 100644
--- a/web/modules/linkit/tests/src/Kernel/LinkitFilterEntityTest.php
+++ b/web/modules/linkit/tests/src/Kernel/LinkitFilterEntityTest.php
@@ -151,4 +151,18 @@ public function testTitleOverwritten() {
     $this->assertTrue(strpos($this->process($input)->getProcessedText(), 'Do not override') !== FALSE, 'The filer is not overwrite the provided title attribute value.');
   }
 
+  /**
+   * Tests that the linkit filter do not overwrite provided fragment and query.
+   */
+  public function testQueryAndFragments() {
+    // Create an entity.
+    $entity = EntityTest::create(['name' => $this->randomMachineName()]);
+    $entity->save();
+
+    // Make sure original query and fragment are preserved.
+    $input = '<a data-entity-type="' . $entity->getEntityTypeId() . '" data-entity-uuid="' . $entity->uuid() . '" href="unimportant/1234?query=string#fragment">Link text</a>';
+    $this->assertContains('?query=string', $this->process($input)->getProcessedText());
+    $this->assertContains('#fragment', $this->process($input)->getProcessedText());
+  }
+
 }