From a25c2ffc9d10c1c90ac50925dde9c0f2738ef40b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 16 May 2021 01:35:13 +0100
Subject: [PATCH 001/212] webserver: Use SIGKILL instead of SIGTERM to kill the
 container

See https://github.com/SergioBenitez/Rocket/issues/180.
---
 configuration/services/webserver.nix | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/configuration/services/webserver.nix b/configuration/services/webserver.nix
index e1c396d..2eb860a 100644
--- a/configuration/services/webserver.nix
+++ b/configuration/services/webserver.nix
@@ -29,6 +29,9 @@
         ];
         ExposedPorts = { "3002" = { }; };
         User = "${uid}:${gid}";
+
+        # Will become SIGTERM with the next rocket release
+        StopSignal = "SIGKILL";
       };
     };
 

From b8bf3bd3a219300a9a8fd1868e28776806785c55 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 16 May 2021 23:07:18 +0100
Subject: [PATCH 002/212] minecraft: Clean up use of pkgs.lib

---
 configuration/services/minecraft.nix | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/configuration/services/minecraft.nix b/configuration/services/minecraft.nix
index c3831aa..9b77c09 100644
--- a/configuration/services/minecraft.nix
+++ b/configuration/services/minecraft.nix
@@ -1,4 +1,4 @@
-{ config, pkgs, ... }:
+{ config, pkgs, lib, ... }:
 
 let
   minecraft-server-args = [
@@ -52,7 +52,7 @@ let
 
 in {
   nixpkgs.config.allowUnfreePredicate = pkg:
-    builtins.elem (pkgs.lib.getName pkg) [ "forge-server" ];
+    builtins.elem (lib.getName pkg) [ "forge-server" ];
 
   virtualisation.oci-containers.containers.minecraft-voor-kia = let
     properties = ./configs/minecraft/voor-kia/server.properties;

From 5f8899d542e43b63e2d3e59642f2691013ad237e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 17 May 2021 00:00:34 +0100
Subject: [PATCH 003/212] nginx: Make VM testing easier by binding virtualHosts
 to localhost

---
 configuration/default.nix | 8 +++++---
 flake.nix                 | 6 +++++-
 modules/default.nix       | 9 ++++++++-
 3 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index 72c955d..49668dd 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -54,6 +54,7 @@
     recommendedGzipSettings = true;
     recommendedProxySettings = true;
     clientMaxBodySize = "10G";
+    domain = "tlater.net";
 
     virtualHosts = let
       host = port: extra:
@@ -62,10 +63,11 @@
           enableACME = true;
           locations."/" = { proxyPass = "http://127.0.0.1:${toString port}"; };
         } // extra;
+      domain = config.services.nginx.domain;
     in {
-      "tlater.net" = host 3002 { serverAliases = [ "www.tlater.net" ]; };
-      "gitea.tlater.net" = host 3000 { };
-      "nextcloud.tlater.net" = host 3001 { };
+      "${domain}" = host 3002 { serverAliases = [ "www.${domain}" ]; };
+      "gitea.${domain}" = host 3000 { };
+      "nextcloud.${domain}" = host 3001 { };
     };
   };
 
diff --git a/flake.nix b/flake.nix
index a9baf34..78a3cfb 100644
--- a/flake.nix
+++ b/flake.nix
@@ -68,12 +68,16 @@
             (import ./modules)
 
             (import ./configuration)
-            ({ ... }: {
+            ({ lib, ... }: {
               users.users.tlater.password = "insecure";
 
               # Disable graphical tty so -curses works
               boot.kernelParams = [ "nomodeset" ];
 
+              # Sets the base domain for nginx to localhost so that we
+              # can easily test locally with the VM.
+              services.nginx.domain = lib.mkOverride 99 "localhost";
+
               # # Set up VM settings to match real VPS
               # virtualisation.memorySize = 3941;
               # virtualisation.cores = 2;
diff --git a/modules/default.nix b/modules/default.nix
index 0bc1f1c..1fd86fc 100644
--- a/modules/default.nix
+++ b/modules/default.nix
@@ -1,5 +1,12 @@
-{ ... }:
+{ lib, ... }:
+
+with lib;
 
 {
   imports = [ ./virtualisation/pods.nix ];
+
+  options.services.nginx.domain = mkOption {
+    type = types.str;
+    description = "The base domain name to append to virtual domain names";
+  };
 }

From 343c7fcc36b78badfa7f9910bfa101124c0fb990 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 17 May 2021 00:02:03 +0100
Subject: [PATCH 004/212] nginx: Don't override extra options in the host
 helper

---
 configuration/default.nix | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index 49668dd..a12aceb 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -1,4 +1,4 @@
-{ config, pkgs, ... }:
+{ config, pkgs, lib, ... }:
 
 {
   imports = [
@@ -58,11 +58,11 @@
 
     virtualHosts = let
       host = port: extra:
-        {
+        lib.recursiveUpdate {
           forceSSL = true;
           enableACME = true;
           locations."/" = { proxyPass = "http://127.0.0.1:${toString port}"; };
-        } // extra;
+        } extra;
       domain = config.services.nginx.domain;
     in {
       "${domain}" = host 3002 { serverAliases = [ "www.${domain}" ]; };

From 4c9493249064abfd2d5d535d02939e0e001a5089 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 17 May 2021 00:18:51 +0100
Subject: [PATCH 005/212] webserver: Use SIGKILL instead of SIGTERM

---
 configuration/services/webserver.nix | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/configuration/services/webserver.nix b/configuration/services/webserver.nix
index e1c396d..c1966a5 100644
--- a/configuration/services/webserver.nix
+++ b/configuration/services/webserver.nix
@@ -34,6 +34,10 @@
 
     ports = [ "3002:3002" ];
     volumes = [ "tlaternet-mail:/srv/mail" ];
-    extraOptions = [ "--hostname=tlater.net" ];
+    extraOptions = [
+      "--hostname=tlater.net"
+      # Rocket 0.4 doesn't support SIGTERM anyway, so SIGKILL is the cleanest exit possible.
+      "--stop-signal=SIGKILL"
+    ];
   };
 }

From 7c0d02690f37fca92437c508fdb8e0949b94a404 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 8 Jun 2021 23:31:47 +0100
Subject: [PATCH 006/212] Upgrade to NixOS 21.05

---
 flake.lock | 8 ++++----
 flake.nix  | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/flake.lock b/flake.lock
index 03e3f45..2a74dda 100644
--- a/flake.lock
+++ b/flake.lock
@@ -53,16 +53,16 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1621088295,
-        "narHash": "sha256-hn8Rk6o5nRbWK/GE+z2OK8DIDIgGxCmVkaXpNYkald0=",
+        "lastModified": 1622922048,
+        "narHash": "sha256-nTyKxe0n7l/4HSmYaIN+63WQrvHrTJY6drSwP7bMqhU=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "17d3dab8647a31a00d8a11433a56cc12d84b5ab4",
+        "rev": "5de44c15758465f8ddf84d541ba300b48e56eda4",
         "type": "github"
       },
       "original": {
         "owner": "nixos",
-        "ref": "nixos-20.09",
+        "ref": "nixos-21.05",
         "repo": "nixpkgs",
         "type": "github"
       }
diff --git a/flake.nix b/flake.nix
index 78a3cfb..55c8d2a 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,7 +2,7 @@
   description = "tlater.net host configuration";
 
   inputs = {
-    nixpkgs.url = "github:nixos/nixpkgs/nixos-20.09";
+    nixpkgs.url = "github:nixos/nixpkgs/nixos-21.05";
     nixos-hardware.url = "github:nixos/nixos-hardware/master";
     flake-utils.url = "github:numtide/flake-utils";
     tlaternet-webserver = {

From e3f0095b473cba0e321897dd38d097e382976482 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 8 Jun 2021 23:34:37 +0100
Subject: [PATCH 007/212] flake.lock: Update

Flake input changes:

* Updated 'flake-utils': 'github:numtide/flake-utils/b543720b25df6ffdfcf9227afafc5b8c1fabfae8' -> 'github:numtide/flake-utils/7d706970d94bc5559077eb1a6600afddcd25a7c8'
* Updated 'nixos-hardware': 'github:nixos/nixos-hardware/c4399b921fa7ff5f93ee10b3521b56b722ed74d8' -> 'github:nixos/nixos-hardware/fccbee72df707c3fb074854668deee6e1ff02351'
---
 flake.lock | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/flake.lock b/flake.lock
index 2a74dda..b2d4187 100644
--- a/flake.lock
+++ b/flake.lock
@@ -2,11 +2,11 @@
   "nodes": {
     "flake-utils": {
       "locked": {
-        "lastModified": 1620759905,
-        "narHash": "sha256-WiyWawrgmyN0EdmiHyG2V+fqReiVi8bM9cRdMaKQOFg=",
+        "lastModified": 1622445595,
+        "narHash": "sha256-m+JRe6Wc5OZ/mKw2bB3+Tl0ZbtyxxxfnAWln8Q5qs+Y=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "b543720b25df6ffdfcf9227afafc5b8c1fabfae8",
+        "rev": "7d706970d94bc5559077eb1a6600afddcd25a7c8",
         "type": "github"
       },
       "original": {
@@ -37,11 +37,11 @@
     },
     "nixos-hardware": {
       "locked": {
-        "lastModified": 1620983891,
-        "narHash": "sha256-E2OKVgGo/cUqDsrIeYGVx64b4cxgzd7+bX33NHL0rbA=",
+        "lastModified": 1623143341,
+        "narHash": "sha256-a8NjpJVvJkb3ehu/KP1OaWwlRexom2D7lQEH5uCO9yA=",
         "owner": "nixos",
         "repo": "nixos-hardware",
-        "rev": "c4399b921fa7ff5f93ee10b3521b56b722ed74d8",
+        "rev": "fccbee72df707c3fb074854668deee6e1ff02351",
         "type": "github"
       },
       "original": {

From 797ae2cfec8b81c7cfb25cfe9b81f330c30a1022 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 25 Jul 2021 19:19:29 +0100
Subject: [PATCH 008/212] voor-kia: Update dimension mods

---
 pkgs/minecraft/voor-kia/mods.json | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/pkgs/minecraft/voor-kia/mods.json b/pkgs/minecraft/voor-kia/mods.json
index 76bfd99..db5efa7 100644
--- a/pkgs/minecraft/voor-kia/mods.json
+++ b/pkgs/minecraft/voor-kia/mods.json
@@ -457,15 +457,15 @@
   },
   {
     "project": "the-bumblezone-forge",
-    "id": "3201726",
-    "filename": "the_bumblezone-1.16.5-2.2.14.jar",
-    "sha256": "b1f478dcd2fffdf8d52dd4ea4760c170bf9b50ef2b6b5ede97b0921ad9602e90"
+    "id": "3389654",
+    "filename": "the_bumblezone-1.16.5-2.4.9-forge.jar",
+    "sha256": "51b2b5860ee391df2ea76c235c6614b34225312ebadaca4893c8ff16b0e9242a"
   },
   {
     "project": "the-undergarden",
-    "id": "3176785",
-    "filename": "The_Undergarden-1.16.5-0.4.5.jar",
-    "sha256": "a48b6d6a6075ecb3ddaff7877796a996d38f94810f8eb2ae1d0f0612d9827808"
+    "id": "3361666",
+    "filename": "The_Undergarden-1.16.5-0.5.4.jar",
+    "sha256": "b596836a5c1d50cf1c65c50ea728b0e295965cf9a4091a8eb1caac517aad5c50"
   },
   {
     "project": "towers-of-the-wild",

From 7c24369cb9ffb89797c2246d2b9ef4db1481e537 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 25 Jul 2021 19:31:46 +0100
Subject: [PATCH 009/212] voor-kia: Update forge minecraft version

---
 pkgs/minecraft/forge-server.nix | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/pkgs/minecraft/forge-server.nix b/pkgs/minecraft/forge-server.nix
index a3cbb1f..d91c5e6 100644
--- a/pkgs/minecraft/forge-server.nix
+++ b/pkgs/minecraft/forge-server.nix
@@ -3,12 +3,12 @@
 
 let
   name = "forge-server";
-  version = "1.16.5-36.1.1";
+  version = "1.16.5-36.1.65";
   mirror = "https://files.minecraftforge.net/maven/net/minecraftforge/forge";
   src = fetchurl {
     url = "${mirror}/${version}/forge-${version}-installer.jar";
     # Forge doesn't seem to like newer shas
-    sha1 = "78e5bd0b19f05136bb25bf3c5be9b64a1d0e850e";
+    sha1 = "9aedcd5e64bfc12483b9c51bc4cf18e551ad054a";
   };
 
   unpackCmd = "mkdir -p src; cp $curSrc src/forge-${version}-installer.jar";
@@ -40,7 +40,7 @@ let
 
     outputHashAlgo = "sha256";
     outputHashMode = "recursive";
-    outputHash = "CzzQhnN+DBgOJAa9MlNhT338VcDLy2ULMTMCecmxMQ4=";
+    outputHash = "lHAuKgwD2gzTb+n3pLgpXsDGYSLF/EYlGy0TfCoU5uQ=";
   };
 
 in stdenv.mkDerivation rec {

From d94145bf349c4539ca53647b2a46885f557571c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 25 Jul 2021 22:21:29 +0100
Subject: [PATCH 010/212] voor-kia: Add mod update script

---
 flake.nix                                  |  17 +-
 pkgs/build-support/fetchFromCurseForge.nix |   6 +-
 pkgs/minecraft/voor-kia/mods.json          | 425 ++++++++++++---------
 pkgs/minecraft/voor-kia/update-mods.py     | 151 ++++++++
 4 files changed, 425 insertions(+), 174 deletions(-)
 create mode 100644 pkgs/minecraft/voor-kia/update-mods.py

diff --git a/flake.nix b/flake.nix
index 55c8d2a..fba329c 100644
--- a/flake.nix
+++ b/flake.nix
@@ -90,7 +90,22 @@
       in {
         devShell = with pkgs;
           mkShell {
-            buildInputs = [ nixfmt git-lfs ];
+            buildInputs = [
+              nixfmt
+              git-lfs
+
+              # For the minecraft mod update script
+              (python3.withPackages (pypkgs:
+                with pypkgs; [
+                  requests
+
+                  ipython
+                  python-language-server
+                  pyls-black
+                  pyls-isort
+                  pyls-mypy
+                ]))
+            ];
             shellHook = ''
               export QEMU_OPTS="-m 3941 -smp 2 -curses"
               export QEMU_NET_OPTS="hostfwd=::3022-:2222,hostfwd=::3080-:80,hostfwd=::3443-:443,hostfwd=::3021-:2221,hostfwd=::25565-:25565"
diff --git a/pkgs/build-support/fetchFromCurseForge.nix b/pkgs/build-support/fetchFromCurseForge.nix
index 4fde62e..5d4f232 100644
--- a/pkgs/build-support/fetchFromCurseForge.nix
+++ b/pkgs/build-support/fetchFromCurseForge.nix
@@ -10,11 +10,11 @@ let
   #
   # Note that if it's zero-prefixed we need to remove the zeroes. It's
   # really an odd one...
-  a = head (match "0*([[:digit:]]+)" (substring 0 4 id));
-  b = head (match "0*([[:digit:]]+)" (substring 4 7 id));
+  a = head (match "0*([[:digit:]]+)" (substring 0 4 (toString id)));
+  b = head (match "0*([[:digit:]]+)" (substring 4 7 (toString id)));
 
   url = "https://media.forgecdn.net/files/${a}/${b}/${filename}";
-  otherArgs = removeAttrs args [ "project" "id" "filename" ];
+  otherArgs = removeAttrs args [ "project" "project_id" "id" "filename" ];
 
 in fetchurl (otherArgs // {
   inherit url;
diff --git a/pkgs/minecraft/voor-kia/mods.json b/pkgs/minecraft/voor-kia/mods.json
index db5efa7..43adbd0 100644
--- a/pkgs/minecraft/voor-kia/mods.json
+++ b/pkgs/minecraft/voor-kia/mods.json
@@ -1,512 +1,597 @@
 [
   {
     "project": "ai-improvements",
-    "id": "3031978",
+    "id": 3031978,
     "filename": "AI-Improvements-1.16.2-0.3.0.jar",
-    "sha256": "47526292ea2f11dd18a8da8863b40ba81a93601f03aa4abcc742ac62ea599c69"
+    "sha256": "47526292ea2f11dd18a8da8863b40ba81a93601f03aa4abcc742ac62ea599c69",
+    "project_id": 233019
   },
   {
     "project": "alexs-mobs",
-    "id": "3230693",
+    "id": 3230693,
     "filename": "alexsmobs-1.7.1.jar",
-    "sha256": "e8066d512f53b80a796e5b83db27246aa5fe4b055929475e7efe5ff6dd090f42"
+    "sha256": "e8066d512f53b80a796e5b83db27246aa5fe4b055929475e7efe5ff6dd090f42",
+    "project_id": 426558
   },
   {
     "project": "apotheosis",
-    "id": "3095843",
+    "id": 3095843,
     "filename": "Apotheosis-1.16.3-4.4.1.jar",
-    "sha256": "de5ed7501bc17196cca7bddabace3464cbdbf8afba63385d260804ad013ba836"
+    "sha256": "de5ed7501bc17196cca7bddabace3464cbdbf8afba63385d260804ad013ba836",
+    "project_id": 313970
   },
   {
     "project": "appleskin",
-    "id": "3035787",
+    "id": 3035787,
     "filename": "AppleSkin-mc1.16.2-forge-1.0.14.jar",
-    "sha256": "e0d39f6b138e853d6171bd51fa158545d68cab5e718a01feb919d37964e5eb4f"
+    "sha256": "e0d39f6b138e853d6171bd51fa158545d68cab5e718a01feb919d37964e5eb4f",
+    "project_id": 248787
   },
   {
     "project": "architectury-forge",
-    "id": "3208686",
+    "id": 3208686,
     "filename": "architectury-1.7.117-forge.jar",
-    "sha256": "6cdbdb32b958ca5cec46c92eaa3c5d2c33404b20f5080bc7c612ba7e3fa4bf57"
+    "sha256": "6cdbdb32b958ca5cec46c92eaa3c5d2c33404b20f5080bc7c612ba7e3fa4bf57",
+    "project_id": 419699
   },
   {
     "project": "artifacts",
-    "id": "3208854",
+    "id": 3208854,
     "filename": "Artifacts-1.16.5-2.8.1.jar",
-    "sha256": "6c74163a75a2303b3fce04c098efad6de0c345059e279a7e5858a1200779d423"
+    "sha256": "6c74163a75a2303b3fce04c098efad6de0c345059e279a7e5858a1200779d423",
+    "project_id": 312353
   },
   {
     "project": "attributefix",
-    "id": "3170246",
+    "id": 3170246,
     "filename": "AttributeFix-1.16.5-10.0.1.jar",
-    "sha256": "8492d282ca55c1e01fad6fd4ae8bd66e418128ccf9044a150af7b4526e02d906"
+    "sha256": "8492d282ca55c1e01fad6fd4ae8bd66e418128ccf9044a150af7b4526e02d906",
+    "project_id": 280510
   },
   {
     "project": "autoreglib",
-    "id": "3128555",
+    "id": 3128555,
     "filename": "AutoRegLib-1.6-47.jar",
-    "sha256": "bacb22ec651ca70462e0128d6e6e800cee69b125cd078b9cf6d3a45de3e403fc"
+    "sha256": "bacb22ec651ca70462e0128d6e6e800cee69b125cd078b9cf6d3a45de3e403fc",
+    "project_id": 250363
   },
   {
     "project": "bedspreads",
-    "id": "3118466",
+    "id": 3118466,
     "filename": "bedspreads-forge-1.16.4-5.1.0.1.jar",
-    "sha256": "7844407085109d10ba87faf21816fb89fc411ff82ea7f0b761e2bd4f987987d2"
+    "sha256": "7844407085109d10ba87faf21816fb89fc411ff82ea7f0b761e2bd4f987987d2",
+    "project_id": 308653
   },
   {
     "project": "better-burning",
-    "id": "3181436",
+    "id": 3181436,
     "filename": "BetterBurning-1.16.5-6.0.2.jar",
-    "sha256": "e81297506876a623e9e770222d6c053eb33ac5451a3905454c2befd69115ae19"
+    "sha256": "e81297506876a623e9e770222d6c053eb33ac5451a3905454c2befd69115ae19",
+    "project_id": 353434
   },
   {
     "project": "yungs-better-caves",
-    "id": "3170047",
+    "id": 3170047,
     "filename": "BetterCaves-Forge-1.16.4-1.1.1.jar",
-    "sha256": "f5bc8ba0f46acab08e79f95e8ff980b2629fd678ea25e9068d2d96823c1ba983"
+    "sha256": "f5bc8ba0f46acab08e79f95e8ff980b2629fd678ea25e9068d2d96823c1ba983",
+    "project_id": 340583
   },
   {
     "project": "yungs-better-mineshafts-forge",
-    "id": "3175671",
+    "id": 3175671,
     "filename": "BetterMineshafts-Forge-1.16.4-2.0.1.jar",
-    "sha256": "a640f45962f8a1abc60f83c8632e558b541b6ba0238d6297912814dec2d0bdc7"
+    "sha256": "a640f45962f8a1abc60f83c8632e558b541b6ba0238d6297912814dec2d0bdc7",
+    "project_id": 389665
   },
   {
     "project": "yungs-better-portals",
-    "id": "3221299",
+    "id": 3221299,
     "filename": "BetterPortals-1.16.4-0.3.1.jar",
-    "sha256": "a86ddf3cbc066d15562e4136717d061861dfb77a2da7b4f112a2b290073c47d9"
+    "sha256": "a86ddf3cbc066d15562e4136717d061861dfb77a2da7b4f112a2b290073c47d9",
+    "project_id": 443723
   },
   {
     "project": "bookshelf",
-    "id": "3170154",
+    "id": 3170154,
     "filename": "Bookshelf-1.16.5-10.0.1.jar",
-    "sha256": "33bade36884a25cbf3bac3bdd2e762a2c5fcc1840f613ab5aaaf57642ffc0c68"
+    "sha256": "33bade36884a25cbf3bac3bdd2e762a2c5fcc1840f613ab5aaaf57642ffc0c68",
+    "project_id": 228525
   },
   {
     "project": "bad-wither-no-cookie-reloaded",
-    "id": "3101531",
+    "id": 3101531,
     "filename": "bwncr-1.16.4-3.9.16.jar",
-    "sha256": "91c4df24466b958d36d41ce886e5d8b0839a07b73d58248a0dcb84a67279b81f"
+    "sha256": "91c4df24466b958d36d41ce886e5d8b0839a07b73d58248a0dcb84a67279b81f",
+    "project_id": 261251
   },
   {
     "project": "oh-the-biomes-youll-go",
-    "id": "3197729",
+    "id": 3197729,
     "filename": "byg-1.1.10.jar",
-    "sha256": "28db347d22ea27167cdbf107180b01b53003d98739189a66ef6c1e4f21e4b436"
+    "sha256": "28db347d22ea27167cdbf107180b01b53003d98739189a66ef6c1e4f21e4b436",
+    "project_id": 247560
   },
   {
     "project": "callable-horses",
-    "id": "3090832",
+    "id": 3090832,
     "filename": "callablehorses-1.16.3-1.2.1.4.jar",
-    "sha256": "639778fd58667aa560d333a2490352e34c1c32e897d9f8204e52df305ca5e879"
+    "sha256": "639778fd58667aa560d333a2490352e34c1c32e897d9f8204e52df305ca5e879",
+    "project_id": 331746
   },
   {
     "project": "citadel",
-    "id": "3198842",
+    "id": 3198842,
     "filename": "citadel-1.6.1.jar",
-    "sha256": "e13434097199a926a565a109b5c7b82b5e0308efa88dbc2a4d030d78d8f1ac37"
+    "sha256": "e13434097199a926a565a109b5c7b82b5e0308efa88dbc2a4d030d78d8f1ac37",
+    "project_id": 331936
   },
   {
     "project": "cloth-config-forge",
-    "id": "3203817",
+    "id": 3203817,
     "filename": "cloth-config-4.10.13-forge.jar",
-    "sha256": "d47bf12ed961fac529064254931308d1ca20d08f411718563827141175daf32b"
+    "sha256": "d47bf12ed961fac529064254931308d1ca20d08f411718563827141175daf32b",
+    "project_id": 348521
   },
   {
     "project": "clumps",
-    "id": "3205705",
+    "id": 3205705,
     "filename": "Clumps-6.0.0.17.jar",
-    "sha256": "a9535cf8df267bb2e2ffb46a278aa67f4b6e447d0bc1140205f98257dc108d58"
+    "sha256": "a9535cf8df267bb2e2ffb46a278aa67f4b6e447d0bc1140205f98257dc108d58",
+    "project_id": 256717
   },
   {
     "project": "codechicken-lib-1-8",
-    "id": "3175750",
+    "id": 3175750,
     "filename": "CodeChickenLib-1.16.4-3.5.1.408-universal.jar",
-    "sha256": "6b88e5f13ceb642734d3f3168da706a80ae2a2d538ba8dd958eb73b3d8911ab3"
+    "sha256": "6b88e5f13ceb642734d3f3168da706a80ae2a2d538ba8dd958eb73b3d8911ab3",
+    "project_id": 242818
   },
   {
     "project": "cooking-for-blockheads",
-    "id": "3098223",
+    "id": 3098223,
     "filename": "CookingForBlockheads_1.16.3-9.2.2.jar",
-    "sha256": "5b15a1e4bac72160ed1ef1042c2cef5eeca5d8dbfecb6620511caa1cf644adaa"
+    "sha256": "5b15a1e4bac72160ed1ef1042c2cef5eeca5d8dbfecb6620511caa1cf644adaa",
+    "project_id": 231484
   },
   {
     "project": "cosmetic-armor-reworked",
-    "id": "3205904",
+    "id": 3205904,
     "filename": "CosmeticArmorReworked-1.16.5-v1b.jar",
-    "sha256": "6535b9077d0b64c2cc3392c145f558492c47280eb4a38672c6b6a4897fee7ec7"
+    "sha256": "6535b9077d0b64c2cc3392c145f558492c47280eb4a38672c6b6a4897fee7ec7",
+    "project_id": 237307
   },
   {
     "project": "crafting-station",
-    "id": "3084325",
+    "id": 3084325,
     "filename": "craftingstation-4.1.1.jar",
-    "sha256": "a3516650a1c5e76b47b9efd69a4cfa9cda4f85250bf217fa7186f74ef375a7e4"
+    "sha256": "a3516650a1c5e76b47b9efd69a4cfa9cda4f85250bf217fa7186f74ef375a7e4",
+    "project_id": 318551
   },
   {
     "project": "create",
-    "id": "3167531",
+    "id": 3167531,
     "filename": "create-mc1.16.3_v0.3e.jar",
-    "sha256": "8c24ee59c3d1c74fb2047564d0aa6935862b2b85fb478dadf19798f7cc08944f"
+    "sha256": "8c24ee59c3d1c74fb2047564d0aa6935862b2b85fb478dadf19798f7cc08944f",
+    "project_id": 328085
   },
   {
     "project": "creativecore",
-    "id": "3128357",
+    "id": 3128357,
     "filename": "CreativeCore_v2.0.10_mc1.16.4.jar",
-    "sha256": "85210df1f6abe5befc7afbb9150e5639f885c229ba3018bd6f40fd142468f377"
+    "sha256": "85210df1f6abe5befc7afbb9150e5639f885c229ba3018bd6f40fd142468f377",
+    "project_id": 257814
   },
   {
     "project": "curios",
-    "id": "3186427",
+    "id": 3186427,
     "filename": "curios-forge-1.16.5-4.0.4.0.jar",
-    "sha256": "4d6d63c432e24d295a410ec9eb24054123094db4913e76f564adfa188cf59d29"
+    "sha256": "4d6d63c432e24d295a410ec9eb24054123094db4913e76f564adfa188cf59d29",
+    "project_id": 309927
   },
   {
     "project": "dank-storage",
-    "id": "3161863",
+    "id": 3161863,
     "filename": "dankstorage-3.14.jar",
-    "sha256": "2ff74a22f0a90f9daed9a0632133b14868ad47500f378326f2a0faedc6029684"
+    "sha256": "2ff74a22f0a90f9daed9a0632133b14868ad47500f378326f2a0faedc6029684",
+    "project_id": 335673
   },
   {
     "project": "decorative-blocks",
-    "id": "3166283",
+    "id": 3166283,
     "filename": "decorative_blocks-1.16.4-1.7.2.jar",
-    "sha256": "f12dbfe76e36cdec65b8a575fc671f0291323a0de5ff420ff196d16bd19e6f84"
+    "sha256": "f12dbfe76e36cdec65b8a575fc671f0291323a0de5ff420ff196d16bd19e6f84",
+    "project_id": 362528
   },
   {
     "project": "doggy-talents",
-    "id": "3203941",
+    "id": 3203941,
     "filename": "DoggyTalents-1.16.4-2.0.1.3.jar",
-    "sha256": "59d8c5f058ef329bf6363fa8d300da3e876c523f9cc6229e0524317207442489"
+    "sha256": "59d8c5f058ef329bf6363fa8d300da3e876c523f9cc6229e0524317207442489",
+    "project_id": 271050
   },
   {
     "project": "easy-piglins",
-    "id": "3169792",
+    "id": 3169792,
     "filename": "easy_piglins-1.16.5-1.0.0.jar",
-    "sha256": "b048630085695a5e8846cc2b8cc1bb6f1bcb59f0077ab63394a803c905df1006"
+    "sha256": "b048630085695a5e8846cc2b8cc1bb6f1bcb59f0077ab63394a803c905df1006",
+    "project_id": 419372
   },
   {
     "project": "easy-villagers",
-    "id": "3171686",
+    "id": 3171686,
     "filename": "easy_villagers-1.16.4-1.1.28.jar",
-    "sha256": "3b8eff14b2b83f5cfe178f03076fa37c49add5dc05836b3151c7077f65a96dff"
+    "sha256": "3b8eff14b2b83f5cfe178f03076fa37c49add5dc05836b3151c7077f65a96dff",
+    "project_id": 400514
   },
   {
     "project": "enchantment-descriptions",
-    "id": "3191059",
+    "id": 3191059,
     "filename": "EnchantmentDescriptions-1.16.5-7.0.2.jar",
-    "sha256": "890db07c51b07fb5921c8ae9e6352987c705625ca27f3d23bdfd313115a6a94b"
+    "sha256": "890db07c51b07fb5921c8ae9e6352987c705625ca27f3d23bdfd313115a6a94b",
+    "project_id": 250419
   },
   {
     "project": "ender-storage-1-8",
-    "id": "3175751",
+    "id": 3175751,
     "filename": "EnderStorage-1.16.4-2.7.1.166-universal.jar",
-    "sha256": "fbb861b85858f7a118a442d5577a53e5415c1f1b6ba7c4ade942d5512706f40d"
+    "sha256": "fbb861b85858f7a118a442d5577a53e5415c1f1b6ba7c4ade942d5512706f40d",
+    "project_id": 245174
   },
   {
     "project": "extended-lights-mod",
-    "id": "3144281",
+    "id": 3144281,
     "filename": "extlights-3.3.jar",
-    "sha256": "7f210f8e8bc451df301a6a2c22f81e434dd1835699444e5c0ed2bb2620847a6b"
+    "sha256": "7f210f8e8bc451df301a6a2c22f81e434dd1835699444e5c0ed2bb2620847a6b",
+    "project_id": 335051
   },
   {
     "project": "extrastorage",
-    "id": "3179402",
+    "id": 3179402,
     "filename": "ExtraStorage-1.16.4-1.3.1.jar",
-    "sha256": "30a78eb59482d393c7471a3b834e49e2dc6a70998be8ece9ba2c487abb5c92a5"
+    "sha256": "30a78eb59482d393c7471a3b834e49e2dc6a70998be8ece9ba2c487abb5c92a5",
+    "project_id": 410168
   },
   {
     "project": "farming-for-blockheads",
-    "id": "3098206",
+    "id": 3098206,
     "filename": "FarmingForBlockheads_1.16.3-7.2.1.jar",
-    "sha256": "2225906be3306bb1066b58ebb97b998ebb679ef7fc2dcab6be53129675c44867"
+    "sha256": "2225906be3306bb1066b58ebb97b998ebb679ef7fc2dcab6be53129675c44867",
+    "project_id": 261924
   },
   {
     "project": "fast-leaf-decay",
-    "id": "3052146",
+    "id": 3052146,
     "filename": "FastLeafDecay-v25.jar",
-    "sha256": "0abd12217bd7e83d5427a4aca6acec27241bb4a7272ef79958a692bd60fe1d86"
+    "sha256": "0abd12217bd7e83d5427a4aca6acec27241bb4a7272ef79958a692bd60fe1d86",
+    "project_id": 230976
   },
   {
     "project": "fastworkbench",
-    "id": "3171218",
+    "id": 3171218,
     "filename": "FastWorkbench-1.16.4-4.5.0.jar",
-    "sha256": "0f4dc32d33512193a3f53ef4e2432bce921ffc047590e1734d3763b8dbd0a547"
+    "sha256": "0f4dc32d33512193a3f53ef4e2432bce921ffc047590e1734d3763b8dbd0a547",
+    "project_id": 288885
   },
   {
     "project": "fishing-real",
-    "id": "3074201",
+    "id": 3074201,
     "filename": "fishingreal-1.16.3-1.0.0.jar",
-    "sha256": "1c2f868ee221e59407f6c8f1ec07fa7ccca49a819559dad818713a6778291fc5"
+    "sha256": "1c2f868ee221e59407f6c8f1ec07fa7ccca49a819559dad818713a6778291fc5",
+    "project_id": 348834
   },
   {
     "project": "hardcore-revival",
-    "id": "3066098",
+    "id": 3066098,
     "filename": "HardcoreRevival_1.16.3-5.2.0.jar",
-    "sha256": "c7d20cad7f9d5e9dd36252c3735568b8e7a9a214bc543356b8429b6748f5ae49"
+    "sha256": "c7d20cad7f9d5e9dd36252c3735568b8e7a9a214bc543356b8429b6748f5ae49",
+    "project_id": 274036
   },
   {
     "project": "ice-and-fire-dragons",
-    "id": "3162719",
+    "id": 3162719,
     "filename": "iceandfire-2.1.5-1.16.4.jar",
-    "sha256": "eb67d6808d9ae4d32b92d26a9a4561549e5e3fbeacf23ed614b19786c2172c76"
+    "sha256": "eb67d6808d9ae4d32b92d26a9a4561549e5e3fbeacf23ed614b19786c2172c76",
+    "project_id": 264231
   },
   {
     "project": "ichunutil",
-    "id": "3062089",
+    "id": 3062089,
     "filename": "iChunUtil-1.16.3-10.0.0.jar",
-    "sha256": "015b4cb31362e323ccdd84e3f865137bd7c32a8a1adcb9f9b77c4e6301a56a25"
+    "sha256": "015b4cb31362e323ccdd84e3f865137bd7c32a8a1adcb9f9b77c4e6301a56a25",
+    "project_id": 229060
   },
   {
     "project": "iron-chests",
-    "id": "3105315",
+    "id": 3105315,
     "filename": "ironchest-1.16.4-11.2.10.jar",
-    "sha256": "5208572a3f07647ca3cfed9f7414957acd0059b7f708d2518f4c73c98beae6be"
+    "sha256": "5208572a3f07647ca3cfed9f7414957acd0059b7f708d2518f4c73c98beae6be",
+    "project_id": 228756
   },
   {
     "project": "iron-furnaces",
-    "id": "3152441",
+    "id": 3152441,
     "filename": "ironfurnaces-1.16.4-2.5.6.jar",
-    "sha256": "042dcb6eca515f814b2093a600cca23a42fef71e4dbaf53b301369018ac5f288"
+    "sha256": "042dcb6eca515f814b2093a600cca23a42fef71e4dbaf53b301369018ac5f288",
+    "project_id": 237664
   },
   {
     "project": "jei",
-    "id": "3192904",
+    "id": 3192904,
     "filename": "jei-1.16.4-7.6.1.71.jar",
-    "sha256": "a4f1cc91214605b7d9b840a4a8ffd910c0eccc9db7f6ce82964bba9f3ca661e5"
+    "sha256": "a4f1cc91214605b7d9b840a4a8ffd910c0eccc9db7f6ce82964bba9f3ca661e5",
+    "project_id": 238222
   },
   {
     "project": "jei-integration",
-    "id": "3202331",
+    "id": 3202331,
     "filename": "jeiintegration_1.16.5-7.0.1.15.jar",
-    "sha256": "0b45fe2858a8e9f97bf10fb218975a48a7d228ca27d274194c4dfaa91534bdfd"
+    "sha256": "0b45fe2858a8e9f97bf10fb218975a48a7d228ca27d274194c4dfaa91534bdfd",
+    "project_id": 265917
   },
   {
     "project": "just-enough-resources-jer",
-    "id": "3066754",
+    "id": 3066754,
     "filename": "JustEnoughResources-1.16.3-0.12.0.100.jar",
-    "sha256": "d09fe055704075044e76e38c315ef410b8fc3587b1e24e500d540b57365ceb66"
+    "sha256": "d09fe055704075044e76e38c315ef410b8fc3587b1e24e500d540b57365ceb66",
+    "project_id": 240630
   },
   {
     "project": "kiwi",
-    "id": "3103509",
+    "id": 3103509,
     "filename": "Kiwi-1.16.3-3.4.1.jar",
-    "sha256": "8e03a2109cb60117f6020a8943a19dc354a2cf2e1b83a0523169fece4ef06757"
+    "sha256": "8e03a2109cb60117f6020a8943a19dc354a2cf2e1b83a0523169fece4ef06757",
+    "project_id": 303657
   },
   {
     "project": "lollipop",
-    "id": "3209431",
+    "id": 3209431,
     "filename": "Lollipop-1.16.4-3.2.6.jar",
-    "sha256": "5eb4c5c6947cfdcd26014a3209aff91653fe13044436dbfd0c310bcbf8abf701"
+    "sha256": "5eb4c5c6947cfdcd26014a3209aff91653fe13044436dbfd0c310bcbf8abf701",
+    "project_id": 347954
   },
   {
     "project": "lotta-terracotta",
-    "id": "3186253",
+    "id": 3186253,
     "filename": "lottaterracotta-1.16.5-1.3.1.jar",
-    "sha256": "8a5879733d8c35129c999d6524f0b7c1b49482076e1104c0c873f70267ea22d5"
+    "sha256": "8a5879733d8c35129c999d6524f0b7c1b49482076e1104c0c873f70267ea22d5",
+    "project_id": 351060
   },
   {
     "project": "macaws-doors",
-    "id": "3182357",
+    "id": 3182357,
     "filename": "mcw-doors-1.0.2-mc1.16.5.jar",
-    "sha256": "cea684ad9bf1fa75ba2685b3e521b2e1806f428681f7d929e3f937b161fb397e"
+    "sha256": "cea684ad9bf1fa75ba2685b3e521b2e1806f428681f7d929e3f937b161fb397e",
+    "project_id": 378646
   },
   {
     "project": "macaws-furniture",
-    "id": "3182349",
+    "id": 3182349,
     "filename": "mcw-furniture-2.0.1-mc1.16.5.jar",
-    "sha256": "7f81b95c128ce97f3c41e29a4e98618c591f96321b53b718b5c3b6b8d3cb619e"
+    "sha256": "7f81b95c128ce97f3c41e29a4e98618c591f96321b53b718b5c3b6b8d3cb619e",
+    "project_id": 359540
   },
   {
     "project": "metal-barrels",
-    "id": "3055811",
+    "id": 3055811,
     "filename": "metalbarrels-3.3a.jar",
-    "sha256": "9bec62579ec71be41a303519e3b7944df0f3ee23a5b03ac7c0d0b27fe7c66150"
+    "sha256": "9bec62579ec71be41a303519e3b7944df0f3ee23a5b03ac7c0d0b27fe7c66150",
+    "project_id": 324985
   },
   {
     "project": "pams-harvestcraft-2-crops",
-    "id": "3076451",
+    "id": 3076451,
     "filename": "pamhc2crops-1.16.3-1.0.1.jar",
-    "sha256": "d987b59e46c36c3461ee913729e9eb3d808e3e2c71499ef6e517c1b3f55ee093"
+    "sha256": "d987b59e46c36c3461ee913729e9eb3d808e3e2c71499ef6e517c1b3f55ee093",
+    "project_id": 361385
   },
   {
     "project": "pams-harvestcraft-2-food-core",
-    "id": "3190867",
+    "id": 3190867,
     "filename": "pamhc2foodcore-1.16.3-1.0.2.jar",
-    "sha256": "e4414d35013e746e5b06256a08dd957a814b17cebcb035899a84a3692d08b544"
+    "sha256": "e4414d35013e746e5b06256a08dd957a814b17cebcb035899a84a3692d08b544",
+    "project_id": 372534
   },
   {
     "project": "pams-harvestcraft-2-food-extended",
-    "id": "3190664",
+    "id": 3190664,
     "filename": "pamhc2foodextended-1.16.3-1.0.1.jar",
-    "sha256": "58a97f94f7087c2e66c9a6b2f33a328619bc544f46134597d3f612387b165668"
+    "sha256": "58a97f94f7087c2e66c9a6b2f33a328619bc544f46134597d3f612387b165668",
+    "project_id": 402231
   },
   {
     "project": "pams-harvestcraft-2-trees",
-    "id": "3117043",
+    "id": 3117043,
     "filename": "pamhc2trees-1.16.3-1.0.0.jar",
-    "sha256": "0b18c28cec6212d5256a9abaea13cbac502d329f70797d17a3523d8a662846ce"
+    "sha256": "0b18c28cec6212d5256a9abaea13cbac502d329f70797d17a3523d8a662846ce",
+    "project_id": 365460
   },
   {
     "project": "passable-foliage",
-    "id": "3103676",
+    "id": 3103676,
     "filename": "PassableFoliage-1.16.4-2.2.0.jar",
-    "sha256": "be727b1e5dc0412404af84145180b00222274c1f7d31f5bfed5bc716e6146eeb"
+    "sha256": "be727b1e5dc0412404af84145180b00222274c1f7d31f5bfed5bc716e6146eeb",
+    "project_id": 379887
   },
   {
     "project": "performant",
-    "id": "3285916",
+    "id": 3285916,
     "filename": "performant-1.16.2-5-3.54m.jar",
-    "sha256": "N8eUXJtIdbNRqZHLZ2gdj9HgpMYu7tAhMnG5Dw2dgqk="
+    "sha256": "N8eUXJtIdbNRqZHLZ2gdj9HgpMYu7tAhMnG5Dw2dgqk=",
+    "project_id": 354143
   },
   {
     "project": "placebo",
-    "id": "3172794",
+    "id": 3172794,
     "filename": "Placebo-1.16.4-4.4.1.jar",
-    "sha256": "c57663a0b37260ca0cfaa6a4fb710d58f35866f029e92412b2332587a27d8f5d"
+    "sha256": "c57663a0b37260ca0cfaa6a4fb710d58f35866f029e92412b2332587a27d8f5d",
+    "project_id": 283644
   },
   {
     "project": "platter",
-    "id": "3115114",
+    "id": 3115114,
     "filename": "Platter-1.16-1.0.0.jar",
-    "sha256": "6e4aee987ac4efa41a1b9cc26a4e4588c79a56bb200402b9fee71e43ab45a533"
+    "sha256": "6e4aee987ac4efa41a1b9cc26a4e4588c79a56bb200402b9fee71e43ab45a533",
+    "project_id": 381581
   },
   {
     "project": "powah",
-    "id": "3209434",
+    "id": 3209434,
     "filename": "Powah-1.16.4-2.3.12.jar",
-    "sha256": "83806e56f79cb01382a6f105ffee8bba131afe52b04909138452eaffd0f87d49"
+    "sha256": "83806e56f79cb01382a6f105ffee8bba131afe52b04909138452eaffd0f87d49",
+    "project_id": 352656
   },
   {
     "project": "quark-oddities",
-    "id": "3088871",
+    "id": 3088871,
     "filename": "QuarkOddities-1.16.3.jar",
-    "sha256": "5eafd942f2eb9b13edde3bff451ee968c1d0fe549c8decd2f8551e59a079711d"
+    "sha256": "5eafd942f2eb9b13edde3bff451ee968c1d0fe549c8decd2f8551e59a079711d",
+    "project_id": 301051
   },
   {
     "project": "quark",
-    "id": "3208541",
+    "id": 3208541,
     "filename": "Quark-r2.4-305.jar",
-    "sha256": "02c6788bc39963b436de77e315808cd05ca09fddf8adeb27be5f5874cfd59b73"
+    "sha256": "02c6788bc39963b436de77e315808cd05ca09fddf8adeb27be5f5874cfd59b73",
+    "project_id": 243121
   },
   {
     "project": "refined-storage",
-    "id": "3196167",
+    "id": 3196167,
     "filename": "refinedstorage-1.9.12.jar",
-    "sha256": "dbe279c56a44decbbfcaf2b1d8aed84988a5ddb62b0c20ec8777e90ecb58e346"
+    "sha256": "dbe279c56a44decbbfcaf2b1d8aed84988a5ddb62b0c20ec8777e90ecb58e346",
+    "project_id": 243076
   },
   {
     "project": "repair-chests",
-    "id": "3111984",
+    "id": 3111984,
     "filename": "RepairChests-1.16.4-1.6.jar",
-    "sha256": "e93bfbadf085764e0f458ab7a77a6c1f7620039390ffa7f60f08914d09124468"
+    "sha256": "e93bfbadf085764e0f458ab7a77a6c1f7620039390ffa7f60f08914d09124468",
+    "project_id": 401644
   },
   {
     "project": "redstone-gauges-and-switches",
-    "id": "3179484",
+    "id": 3179484,
     "filename": "rsgauges-1.16.4-1.2.8.jar",
-    "sha256": "dcac66fb8d65080d5326310c173e215437e0fa15405721f494f6da27e125b785"
+    "sha256": "dcac66fb8d65080d5326310c173e215437e0fa15405721f494f6da27e125b785",
+    "project_id": 296686
   },
   {
     "project": "snow-real-magic",
-    "id": "3196605",
+    "id": 3196605,
     "filename": "SnowRealMagic-1.16.4-2.3.1.jar",
-    "sha256": "f588ae017f68f85dbdc26374282a0ad728ad44496577001314a2b2e5f22ef33b"
+    "sha256": "f588ae017f68f85dbdc26374282a0ad728ad44496577001314a2b2e5f22ef33b",
+    "project_id": 308663
   },
   {
     "project": "snow-under-trees",
-    "id": "3152350",
+    "id": 3152350,
     "filename": "snowundertrees-1.16.4-v1.1.3.jar",
-    "sha256": "6fb11fc0ff8542780796d481cc69549718dc6759b80bec43835003ebd33b8235"
+    "sha256": "6fb11fc0ff8542780796d481cc69549718dc6759b80bec43835003ebd33b8235",
+    "project_id": 353942
   },
   {
     "project": "spice-of-life-carrot-edition",
-    "id": "3174886",
+    "id": 3174886,
     "filename": "solcarrot-1.16.3-1.9.9.jar",
-    "sha256": "541ef38547ec17fb7cc485474747623d2dcc963a788c5ea300b39e31612e9022"
+    "sha256": "541ef38547ec17fb7cc485474747623d2dcc963a788c5ea300b39e31612e9022",
+    "project_id": 277616
   },
   {
     "project": "spark",
-    "id": "3245792",
+    "id": 3245792,
     "filename": "spark-forge.jar",
-    "sha256": "9BSMsIoiLWFFQje2jhnVqFNiFTXKITTAlIuDxUOgtds="
+    "sha256": "9BSMsIoiLWFFQje2jhnVqFNiFTXKITTAlIuDxUOgtds=",
+    "project_id": 361579
   },
   {
     "project": "storage-drawers",
-    "id": "3180569",
+    "id": 3180569,
     "filename": "StorageDrawers-1.16.3-8.2.2.jar",
-    "sha256": "e8775a6bd6b4c61f2df6efe22294d41e390b1aef79d744233948cc1e2bb07651"
+    "sha256": "e8775a6bd6b4c61f2df6efe22294d41e390b1aef79d744233948cc1e2bb07651",
+    "project_id": 223852
   },
   {
     "project": "supplementaries",
-    "id": "3281805",
+    "id": 3281805,
     "filename": "supplementaries-1.16.5-0.12.1.jar",
-    "sha256": "sOjCHEhL1x/jF4D/HuYiKdXvFIZyPFeKk0ihY6SUqcI="
+    "sha256": "sOjCHEhL1x/jF4D/HuYiKdXvFIZyPFeKk0ihY6SUqcI=",
+    "project_id": 412082
   },
   {
     "project": "sweet-concrete",
-    "id": "3186255",
+    "id": 3186255,
     "filename": "sweetconcrete-1.16.5-1.7.1.jar",
-    "sha256": "6333aeb7dbdf3d2c5365bc7679ef91d0eec1c6d1ac6ff2f86c19139abbb02afe"
+    "sha256": "6333aeb7dbdf3d2c5365bc7679ef91d0eec1c6d1ac6ff2f86c19139abbb02afe",
+    "project_id": 351052
   },
   {
     "project": "swingthroughgrass",
-    "id": "3103028",
+    "id": 3103028,
     "filename": "swingthroughgrass-1.16.4-1.5.3.jar",
-    "sha256": "d47132c8e97989f6f1b4c3c2c0736bf9e16e9a72970b3953fc80dcf8b1a4e31d"
+    "sha256": "d47132c8e97989f6f1b4c3c2c0736bf9e16e9a72970b3953fc80dcf8b1a4e31d",
+    "project_id": 264353
   },
   {
     "project": "the-bumblezone-forge",
-    "id": "3389654",
+    "id": 3389654,
     "filename": "the_bumblezone-1.16.5-2.4.9-forge.jar",
-    "sha256": "51b2b5860ee391df2ea76c235c6614b34225312ebadaca4893c8ff16b0e9242a"
+    "sha256": "51b2b5860ee391df2ea76c235c6614b34225312ebadaca4893c8ff16b0e9242a",
+    "project_id": 362479
   },
   {
     "project": "the-undergarden",
-    "id": "3361666",
+    "id": 3361666,
     "filename": "The_Undergarden-1.16.5-0.5.4.jar",
-    "sha256": "b596836a5c1d50cf1c65c50ea728b0e295965cf9a4091a8eb1caac517aad5c50"
+    "sha256": "b596836a5c1d50cf1c65c50ea728b0e295965cf9a4091a8eb1caac517aad5c50",
+    "project_id": 379849
   },
   {
     "project": "towers-of-the-wild",
-    "id": "3103750",
+    "id": 3103750,
     "filename": "towers_of_the_wild-1.16.4-2.0.1.jar",
-    "sha256": "fcd0e3f808569f0e547313a1ea3563c9a5d2fa8fbb638678eed6e46c1d8cfaf1"
+    "sha256": "fcd0e3f808569f0e547313a1ea3563c9a5d2fa8fbb638678eed6e46c1d8cfaf1",
+    "project_id": 386415
   },
   {
     "project": "travelers-backpack",
-    "id": "3171745",
+    "id": 3171745,
     "filename": "TravelersBackpack-1.16.4-5.3.8.jar",
-    "sha256": "cd15a1bef4388bfc492c96dab510d32fff17cd921a06393bbb7ab25f6f25fc88"
+    "sha256": "cd15a1bef4388bfc492c96dab510d32fff17cd921a06393bbb7ab25f6f25fc88",
+    "project_id": 321117
   },
   {
     "project": "the-weirding-gadget",
-    "id": "3116235",
+    "id": 3116235,
     "filename": "weirdinggadget-1.16.(2-4)-2.2.7.jar",
-    "sha256": "fe9b2d4f39020a4239a19ea0e7229beec29eb8f1ef2b2b198b9aa5aad0b13318"
+    "sha256": "fe9b2d4f39020a4239a19ea0e7229beec29eb8f1ef2b2b198b9aa5aad0b13318",
+    "project_id": 258914
   },
   {
     "project": "wither-skeleton-tweaks",
-    "id": "3172803",
+    "id": 3172803,
     "filename": "Wither-Skeleton-Tweaks-1.16.4-5.3.0.jar",
-    "sha256": "e6375312aeb188cda4951a4c4935343a64785303129dbb47f49f59768d0865d3"
+    "sha256": "e6375312aeb188cda4951a4c4935343a64785303129dbb47f49f59768d0865d3",
+    "project_id": 255902
   },
   {
     "project": "xaeros-minimap",
-    "id": "3200201",
+    "id": 3200201,
     "filename": "Xaeros_Minimap_21.3.0.2_Forge_1.16.5.jar",
-    "sha256": "d477b6838bc27bfc759dc8601582683fdc7d425736656d304a1cbae4d932c6f0"
+    "sha256": "d477b6838bc27bfc759dc8601582683fdc7d425736656d304a1cbae4d932c6f0",
+    "project_id": 263420
   },
   {
     "project": "xaeros-world-map",
-    "id": "3200214",
+    "id": 3200214,
     "filename": "XaerosWorldMap_1.12.0.2_Forge_1.16.5.jar",
-    "sha256": "d4cc27d1646ce8bb5411261b31f1a13b11b7ad709fe7d9be43c4c7c8caa529f1"
+    "sha256": "d4cc27d1646ce8bb5411261b31f1a13b11b7ad709fe7d9be43c4c7c8caa529f1",
+    "project_id": 317780
   },
   {
     "project": "yungs-api",
-    "id": "3186128",
+    "id": 3186128,
     "filename": "YungsApi-1.16.4-Forge-4.jar",
-    "sha256": "5a78eec5576ed162def18849bb604d5c69ec73b8715ab28ad41174ad0a673304"
+    "sha256": "5a78eec5576ed162def18849bb604d5c69ec73b8715ab28ad41174ad0a673304",
+    "project_id": 421850
   }
 ]
diff --git a/pkgs/minecraft/voor-kia/update-mods.py b/pkgs/minecraft/voor-kia/update-mods.py
new file mode 100644
index 0000000..0af0b09
--- /dev/null
+++ b/pkgs/minecraft/voor-kia/update-mods.py
@@ -0,0 +1,151 @@
+import argparse
+import json
+import hashlib
+from copy import deepcopy
+from enum import Enum
+from typing import Dict, Generator, NamedTuple, Optional, Union
+
+import requests
+
+
+API = "https://addons-ecs.forgesvc.net/api/v2"
+
+
+class ModLoader(Enum):
+    FORGE = 1
+    FABRIC = 4
+
+
+class File(NamedTuple):
+    id: int
+    gameVersion: str
+    name: str
+    modLoader: Optional[ModLoader]
+
+    @classmethod
+    def from_json(cls, f: Dict[str, Union[str, int]]):
+        modLoader = f.get("modLoader", None)
+
+        assert isinstance(f["gameVersion"], str)
+        assert isinstance(f["projectFileId"], int)
+        assert isinstance(f["projectFileName"], str)
+        if modLoader is not None:
+            assert isinstance(modLoader, int)
+
+        return cls(
+            f["projectFileId"],
+            f["gameVersion"],
+            f["projectFileName"],
+            ModLoader(modLoader) if modLoader is not None else None,
+        )
+
+
+class CurseAPI:
+    def __init__(self):
+        self._session = requests.Session()
+        self._session.headers[
+            "User-Agent"
+        ] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0"
+
+    def get_latest_files(self, mod_id: int) -> Generator[File, None, None]:
+        res = self._session.get(f"{API}/addon/{mod_id}")
+        res.raise_for_status()
+
+        latest_files = res.json().get("gameVersionLatestFiles", None)
+
+        if latest_files is None:
+            return (_ for _ in [])
+        else:
+            return (File.from_json(f) for f in latest_files)
+
+    def get_file_url(self, mod_id: int, file_id: int) -> str:
+        res = self._session.get(f"{API}/addon/{mod_id}/file/{file_id}/download-url")
+        res.raise_for_status()
+        return res.text.rstrip("\n")
+
+    def download_file(self, mod_id: int, file_id: int) -> bytes:
+        url = self.get_file_url(mod_id, file_id)
+        file_ = self._session.get(url)
+        file_.raise_for_status()
+        return file_.content
+
+
+def main():
+    parser = argparse.ArgumentParser()
+    parser.add_argument("version", help="The minecraft version to limit updates to")
+    parser.add_argument(
+        "--mod-loader", choices=["none", "forge", "fabric"], default="forge"
+    )
+    args = parser.parse_args()
+
+    if args.mod_loader == "forge":
+        mod_loader = ModLoader.FORGE
+    elif args.mod_loader == "fabric":
+        mod_loader = ModLoader.FABRIC
+    else:
+        raise AssertionError("Unreachable")
+
+    update(args.version, mod_loader)
+
+
+def update(version: str, mod_loader: ModLoader):
+    with open("./mods.json") as mods_json:
+        mods = json.load(mods_json)
+
+    curse = CurseAPI()
+    new_mods = []
+
+    for mod in mods:
+        print(f"Checking for updates to {mod['project']}...")
+
+        try:
+            latest_files = list(curse.get_latest_files(mod["project_id"]))
+        except requests.HTTPError as err:
+            print(f"WARNING: Could not access curse API for {mod['project']}: {err}")
+            latest_files = [_ for _ in []]
+
+        def compatible(file_: File) -> bool:
+            file_version = file_.gameVersion.split(".")
+            target_version = version.split(".")
+
+            # We assume that major + minor version are compatible;
+            # this seems to generally be true, but check the output
+            # for possible mistakes.
+            #
+            # The patch version is completely ignored since mod
+            # authors generally don't register versions properly
+            # enough to match this.
+            #
+            # Being more strict than this usually results in
+            # technically compatible mods with no available versions.
+            return (
+                (file_.modLoader is None or file_.modLoader == mod_loader)
+                and file_version[0] == target_version[0]
+                and file_version[1] == target_version[1]
+            )
+
+        latest = max(filter(compatible, latest_files), key=lambda f: f.gameVersion)
+
+        if latest is None:
+            print(f"WARNING: No compatible files found for {mod['project']}")
+            print(
+                f"Versions available: {[(f.name, f.gameVersion) for f in latest_files]}"
+            )
+            new_mods.append(mod)
+        elif latest.id != mod["id"]:
+            print(f"Updating {mod['project']}...")
+            contents = curse.download_file(mod["project_id"], latest.id)
+            sha256 = hashlib.sha256(contents).hexdigest()
+
+            new_mod = deepcopy(mod)
+            new_mod.update({"filename": latest.name, "id": latest.id, "sha256": sha256})
+            new_mods.append(new_mod)
+        else:
+            new_mods.append(mod)
+
+    with open("temp.json", "w") as out:
+        json.dump(new_mods, out, sort_keys=True, indent=2)
+
+
+if __name__ == "__main__":
+    main()

From bb37fddff6151dec3ce2e3f84550fb40e85041a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 26 Jul 2021 00:26:42 +0100
Subject: [PATCH 011/212] voor-kia: Update minecraft mods

---
 pkgs/minecraft/forge-server.nix   |   6 +-
 pkgs/minecraft/voor-kia/mods.json | 703 +++++++++++++++---------------
 2 files changed, 365 insertions(+), 344 deletions(-)

diff --git a/pkgs/minecraft/forge-server.nix b/pkgs/minecraft/forge-server.nix
index d91c5e6..22df91f 100644
--- a/pkgs/minecraft/forge-server.nix
+++ b/pkgs/minecraft/forge-server.nix
@@ -3,12 +3,12 @@
 
 let
   name = "forge-server";
-  version = "1.16.5-36.1.65";
+  version = "1.16.5-36.2.2";
   mirror = "https://files.minecraftforge.net/maven/net/minecraftforge/forge";
   src = fetchurl {
     url = "${mirror}/${version}/forge-${version}-installer.jar";
     # Forge doesn't seem to like newer shas
-    sha1 = "9aedcd5e64bfc12483b9c51bc4cf18e551ad054a";
+    sha1 = "e97821e5431bdcaa46e12048769922e2cdb5e2e1";
   };
 
   unpackCmd = "mkdir -p src; cp $curSrc src/forge-${version}-installer.jar";
@@ -40,7 +40,7 @@ let
 
     outputHashAlgo = "sha256";
     outputHashMode = "recursive";
-    outputHash = "lHAuKgwD2gzTb+n3pLgpXsDGYSLF/EYlGy0TfCoU5uQ=";
+    outputHash = "VuUGc5JnzcRhDt9aaGrU+yUrJILVdU2vzv1PxLwdAig=";
   };
 
 in stdenv.mkDerivation rec {
diff --git a/pkgs/minecraft/voor-kia/mods.json b/pkgs/minecraft/voor-kia/mods.json
index 43adbd0..8ca36a4 100644
--- a/pkgs/minecraft/voor-kia/mods.json
+++ b/pkgs/minecraft/voor-kia/mods.json
@@ -1,597 +1,618 @@
 [
   {
-    "project": "ai-improvements",
-    "id": 3031978,
     "filename": "AI-Improvements-1.16.2-0.3.0.jar",
-    "sha256": "47526292ea2f11dd18a8da8863b40ba81a93601f03aa4abcc742ac62ea599c69",
-    "project_id": 233019
+    "id": 3031978,
+    "project": "ai-improvements",
+    "project_id": 233019,
+    "sha256": "47526292ea2f11dd18a8da8863b40ba81a93601f03aa4abcc742ac62ea599c69"
   },
   {
+    "filename": "alexsmobs-1.11.1.jar",
+    "id": 3371504,
     "project": "alexs-mobs",
-    "id": 3230693,
-    "filename": "alexsmobs-1.7.1.jar",
-    "sha256": "e8066d512f53b80a796e5b83db27246aa5fe4b055929475e7efe5ff6dd090f42",
-    "project_id": 426558
+    "project_id": 426558,
+    "sha256": "4daf19a04317c5a399d38c2c397ead8cce9a9eb6c09fdb5bd7bd6dec8c911167"
   },
   {
+    "filename": "Apotheosis-1.16.4-4.6.1.jar",
+    "id": 3332235,
     "project": "apotheosis",
-    "id": 3095843,
-    "filename": "Apotheosis-1.16.3-4.4.1.jar",
-    "sha256": "de5ed7501bc17196cca7bddabace3464cbdbf8afba63385d260804ad013ba836",
-    "project_id": 313970
+    "project_id": 313970,
+    "sha256": "a15e9faf743d237063221c0d9ab0b75acf86ba5c3bfde08a42922c3b108bca80"
   },
   {
+    "filename": "appleskin-forge-mc1.16.x-2.1.0.jar",
+    "id": 3395800,
     "project": "appleskin",
-    "id": 3035787,
-    "filename": "AppleSkin-mc1.16.2-forge-1.0.14.jar",
-    "sha256": "e0d39f6b138e853d6171bd51fa158545d68cab5e718a01feb919d37964e5eb4f",
-    "project_id": 248787
+    "project_id": 248787,
+    "sha256": "d98f34b1a97a66ea5e33eda7e744f1382d325c7de51db57285d1a0888c0e8496"
   },
   {
+    "filename": "architectury-1.20.28-forge.jar",
+    "id": 3385660,
     "project": "architectury-forge",
-    "id": 3208686,
-    "filename": "architectury-1.7.117-forge.jar",
-    "sha256": "6cdbdb32b958ca5cec46c92eaa3c5d2c33404b20f5080bc7c612ba7e3fa4bf57",
-    "project_id": 419699
+    "project_id": 419699,
+    "sha256": "0a89b6a6d12596bf288411fd740cbc44f3fe63c3f4665f7fd3f46f65f52cf138"
   },
   {
+    "filename": "Artifacts-1.16.5-2.10.0.jar",
+    "id": 3374317,
     "project": "artifacts",
-    "id": 3208854,
-    "filename": "Artifacts-1.16.5-2.8.1.jar",
-    "sha256": "6c74163a75a2303b3fce04c098efad6de0c345059e279a7e5858a1200779d423",
-    "project_id": 312353
+    "project_id": 312353,
+    "sha256": "70e2945f8200f7ad3cb46436a998acd37ebec318d08e7a578ca39e8115414b1c"
   },
   {
+    "filename": "AttributeFix-1.16.5-10.1.3.jar",
+    "id": 3348562,
     "project": "attributefix",
-    "id": 3170246,
-    "filename": "AttributeFix-1.16.5-10.0.1.jar",
-    "sha256": "8492d282ca55c1e01fad6fd4ae8bd66e418128ccf9044a150af7b4526e02d906",
-    "project_id": 280510
+    "project_id": 280510,
+    "sha256": "aabf99d65e4ccfc08a67dc378f447eef613ac50924587a33aef68d4467e1a7c0"
   },
   {
+    "filename": "AutoRegLib-1.6-49.jar",
+    "id": 3326041,
     "project": "autoreglib",
-    "id": 3128555,
-    "filename": "AutoRegLib-1.6-47.jar",
-    "sha256": "bacb22ec651ca70462e0128d6e6e800cee69b125cd078b9cf6d3a45de3e403fc",
-    "project_id": 250363
+    "project_id": 250363,
+    "sha256": "2760b765dccf1fad36e74f747ee9b1a2923e2d09eb281c72258c15bb4ed427d5"
   },
   {
+    "filename": "bedspreads-forge-1.16.5-5.1.0.2.jar",
+    "id": 3258439,
     "project": "bedspreads",
-    "id": 3118466,
-    "filename": "bedspreads-forge-1.16.4-5.1.0.1.jar",
-    "sha256": "7844407085109d10ba87faf21816fb89fc411ff82ea7f0b761e2bd4f987987d2",
-    "project_id": 308653
+    "project_id": 308653,
+    "sha256": "fa823abf9efef6818079d1c0cf123e9edccdac81fddf09b2ef931f21f4c58e9d"
   },
   {
+    "filename": "BetterBurning-1.16.5-6.0.7.jar",
+    "id": 3348573,
     "project": "better-burning",
-    "id": 3181436,
-    "filename": "BetterBurning-1.16.5-6.0.2.jar",
-    "sha256": "e81297506876a623e9e770222d6c053eb33ac5451a3905454c2befd69115ae19",
-    "project_id": 353434
+    "project_id": 353434,
+    "sha256": "4b089ce99e48cf72bf817cbc26a0e23b297b5b451bbd80b46091cd5a290524ff"
   },
   {
+    "filename": "BetterCaves-Forge-1.16.4-1.1.2.jar",
+    "id": 3307879,
     "project": "yungs-better-caves",
-    "id": 3170047,
-    "filename": "BetterCaves-Forge-1.16.4-1.1.1.jar",
-    "sha256": "f5bc8ba0f46acab08e79f95e8ff980b2629fd678ea25e9068d2d96823c1ba983",
-    "project_id": 340583
+    "project_id": 340583,
+    "sha256": "5182379427440bb4198790856c01f28c085365cc37ad3a05a9cd82dfdf068454"
   },
   {
+    "filename": "BetterMineshafts-Forge-1.16.4-2.0.4.jar",
+    "id": 3344719,
     "project": "yungs-better-mineshafts-forge",
-    "id": 3175671,
-    "filename": "BetterMineshafts-Forge-1.16.4-2.0.1.jar",
-    "sha256": "a640f45962f8a1abc60f83c8632e558b541b6ba0238d6297912814dec2d0bdc7",
-    "project_id": 389665
+    "project_id": 389665,
+    "sha256": "19b9b7f87da2bb76574e9f3e3d18d445189a4627cfd0d8188ae88eb681b578b8"
   },
   {
+    "filename": "BetterPortals-1.16.4-0.3.7.jar",
+    "id": 3396844,
     "project": "yungs-better-portals",
-    "id": 3221299,
-    "filename": "BetterPortals-1.16.4-0.3.1.jar",
-    "sha256": "a86ddf3cbc066d15562e4136717d061861dfb77a2da7b4f112a2b290073c47d9",
-    "project_id": 443723
+    "project_id": 443723,
+    "sha256": "4695da7e9212d79c9fc8350e9b4ec2600631ff858ee10d146d4a69f20dfc9c6e"
   },
   {
+    "filename": "Bookshelf-1.16.5-10.2.15.jar",
+    "id": 3402183,
     "project": "bookshelf",
-    "id": 3170154,
-    "filename": "Bookshelf-1.16.5-10.0.1.jar",
-    "sha256": "33bade36884a25cbf3bac3bdd2e762a2c5fcc1840f613ab5aaaf57642ffc0c68",
-    "project_id": 228525
+    "project_id": 228525,
+    "sha256": "0674174797835d3371d1421cbf6232276451edca0b6f16b85bb3519e65622ea4"
   },
   {
-    "project": "bad-wither-no-cookie-reloaded",
-    "id": 3101531,
     "filename": "bwncr-1.16.4-3.9.16.jar",
-    "sha256": "91c4df24466b958d36d41ce886e5d8b0839a07b73d58248a0dcb84a67279b81f",
-    "project_id": 261251
+    "id": 3101531,
+    "project": "bad-wither-no-cookie-reloaded",
+    "project_id": 261251,
+    "sha256": "91c4df24466b958d36d41ce886e5d8b0839a07b73d58248a0dcb84a67279b81f"
   },
   {
+    "filename": "byg-1.2.9.jar",
+    "id": 3337158,
     "project": "oh-the-biomes-youll-go",
-    "id": 3197729,
-    "filename": "byg-1.1.10.jar",
-    "sha256": "28db347d22ea27167cdbf107180b01b53003d98739189a66ef6c1e4f21e4b436",
-    "project_id": 247560
+    "project_id": 247560,
+    "sha256": "13007c914d142b4e19f92213970edf22094ad9f48e1e7e7c27e1355eb7248086"
   },
   {
-    "project": "callable-horses",
-    "id": 3090832,
     "filename": "callablehorses-1.16.3-1.2.1.4.jar",
-    "sha256": "639778fd58667aa560d333a2490352e34c1c32e897d9f8204e52df305ca5e879",
-    "project_id": 331746
+    "id": 3090832,
+    "project": "callable-horses",
+    "project_id": 331746,
+    "sha256": "639778fd58667aa560d333a2490352e34c1c32e897d9f8204e52df305ca5e879"
   },
   {
+    "filename": "citadel-1.7.2-1.16.5.jar",
+    "id": 3390028,
     "project": "citadel",
-    "id": 3198842,
-    "filename": "citadel-1.6.1.jar",
-    "sha256": "e13434097199a926a565a109b5c7b82b5e0308efa88dbc2a4d030d78d8f1ac37",
-    "project_id": 331936
+    "project_id": 331936,
+    "sha256": "c9b727acc3fc53ecfa7e33016c30eecfce407cb4690acba25375c64a76b7af17"
   },
   {
+    "filename": "cloth-config-4.11.26-forge.jar",
+    "id": 3311352,
     "project": "cloth-config-forge",
-    "id": 3203817,
-    "filename": "cloth-config-4.10.13-forge.jar",
-    "sha256": "d47bf12ed961fac529064254931308d1ca20d08f411718563827141175daf32b",
-    "project_id": 348521
+    "project_id": 348521,
+    "sha256": "815ba5d61416d9bbd53b830509b9f3d74d59c1720cf9a6b002a3e66eb1453196"
   },
   {
+    "filename": "Clumps-6.0.0.25.jar",
+    "id": 3348509,
     "project": "clumps",
-    "id": 3205705,
-    "filename": "Clumps-6.0.0.17.jar",
-    "sha256": "a9535cf8df267bb2e2ffb46a278aa67f4b6e447d0bc1140205f98257dc108d58",
-    "project_id": 256717
+    "project_id": 256717,
+    "sha256": "1039d9ae78873107ee82c799e586c71dfe284d5bb58f89895a3a510f8f33c765"
   },
   {
+    "filename": "flywheel-1.16-0.2.0.jar",
+    "id": 3406855,
+    "project": "flywheel",
+    "project_id": 486392,
+    "sha256": "7abc741d731b207ab3e1c6776786af6cd2150d57c140090285293a593e82b669"
+  },
+  {
+    "filename": "expandability-2.0.1-forge.jar",
+    "id": 3277762,
+    "project": "expandability",
+    "project_id": 465066,
+    "sha256": "0959cffb3a545730e6b2e1377bb89b59ff96e7f9142f54cc8035ab4fa2fc76e1"
+  },
+  {
+    "filename": "CodeChickenLib-1.16.5-4.0.2.429-universal.jar",
+    "id": 3398096,
     "project": "codechicken-lib-1-8",
-    "id": 3175750,
-    "filename": "CodeChickenLib-1.16.4-3.5.1.408-universal.jar",
-    "sha256": "6b88e5f13ceb642734d3f3168da706a80ae2a2d538ba8dd958eb73b3d8911ab3",
-    "project_id": 242818
+    "project_id": 242818,
+    "sha256": "0254c780c5f20653cab34f6bc8178b1de1ce44de082dcd42ff1e1ee9ba9d5e3a"
   },
   {
+    "filename": "CookingForBlockheads_1.16.5-9.3.3.jar",
+    "id": 3368022,
     "project": "cooking-for-blockheads",
-    "id": 3098223,
-    "filename": "CookingForBlockheads_1.16.3-9.2.2.jar",
-    "sha256": "5b15a1e4bac72160ed1ef1042c2cef5eeca5d8dbfecb6620511caa1cf644adaa",
-    "project_id": 231484
+    "project_id": 231484,
+    "sha256": "6adc6a882c2647ecda2345321ec77572a7f0a3fcdeadae24fa5dc71f0e5af9bb"
   },
   {
+    "filename": "CosmeticArmorReworked-1.16.5-v4.jar",
+    "id": 3398000,
     "project": "cosmetic-armor-reworked",
-    "id": 3205904,
-    "filename": "CosmeticArmorReworked-1.16.5-v1b.jar",
-    "sha256": "6535b9077d0b64c2cc3392c145f558492c47280eb4a38672c6b6a4897fee7ec7",
-    "project_id": 237307
+    "project_id": 237307,
+    "sha256": "83a24d226acd7c86b94b4a8eac716b8a306c96e7d76a1a06bdcc2e2be9df9b21"
   },
   {
-    "project": "crafting-station",
-    "id": 3084325,
     "filename": "craftingstation-4.1.1.jar",
-    "sha256": "a3516650a1c5e76b47b9efd69a4cfa9cda4f85250bf217fa7186f74ef375a7e4",
-    "project_id": 318551
+    "id": 3084325,
+    "project": "crafting-station",
+    "project_id": 318551,
+    "sha256": "a3516650a1c5e76b47b9efd69a4cfa9cda4f85250bf217fa7186f74ef375a7e4"
   },
   {
+    "filename": "create-mc1.16.5_v0.3.2c.jar",
+    "id": 3406857,
     "project": "create",
-    "id": 3167531,
-    "filename": "create-mc1.16.3_v0.3e.jar",
-    "sha256": "8c24ee59c3d1c74fb2047564d0aa6935862b2b85fb478dadf19798f7cc08944f",
-    "project_id": 328085
+    "project_id": 328085,
+    "sha256": "5cec00aa769b9edf9c85235742d593b00eefd4f3f0ed93cac412d633c23c6558"
   },
   {
+    "filename": "CreativeCore_v2.2.0_mc1.16.5.jar",
+    "id": 3338971,
     "project": "creativecore",
-    "id": 3128357,
-    "filename": "CreativeCore_v2.0.10_mc1.16.4.jar",
-    "sha256": "85210df1f6abe5befc7afbb9150e5639f885c229ba3018bd6f40fd142468f377",
-    "project_id": 257814
+    "project_id": 257814,
+    "sha256": "8155f7a84695a68fd2e8b8f6fab0377b9d78cfbab9d8c125e6a9b58238d1eacc"
   },
   {
+    "filename": "curios-forge-1.16.5-4.0.5.2.jar",
+    "id": 3343065,
     "project": "curios",
-    "id": 3186427,
-    "filename": "curios-forge-1.16.5-4.0.4.0.jar",
-    "sha256": "4d6d63c432e24d295a410ec9eb24054123094db4913e76f564adfa188cf59d29",
-    "project_id": 309927
+    "project_id": 309927,
+    "sha256": "08d7558df6c621fca29758c349b95b137d2977cf1f3f61323fff4d85630d0641"
   },
   {
+    "filename": "dankstorage-3.16.jar",
+    "id": 3250771,
     "project": "dank-storage",
-    "id": 3161863,
-    "filename": "dankstorage-3.14.jar",
-    "sha256": "2ff74a22f0a90f9daed9a0632133b14868ad47500f378326f2a0faedc6029684",
-    "project_id": 335673
+    "project_id": 335673,
+    "sha256": "bd5734d8ee8caf3a20574699d91f95b9e53df6b4d13f196f087d3f4bfe867621"
   },
   {
-    "project": "decorative-blocks",
-    "id": 3166283,
     "filename": "decorative_blocks-1.16.4-1.7.2.jar",
-    "sha256": "f12dbfe76e36cdec65b8a575fc671f0291323a0de5ff420ff196d16bd19e6f84",
-    "project_id": 362528
+    "id": 3166283,
+    "project": "decorative-blocks",
+    "project_id": 362528,
+    "sha256": "f12dbfe76e36cdec65b8a575fc671f0291323a0de5ff420ff196d16bd19e6f84"
   },
   {
+    "filename": "DoggyTalents-1.16.5-2.0.1.10.jar",
+    "id": 3399830,
     "project": "doggy-talents",
-    "id": 3203941,
-    "filename": "DoggyTalents-1.16.4-2.0.1.3.jar",
-    "sha256": "59d8c5f058ef329bf6363fa8d300da3e876c523f9cc6229e0524317207442489",
-    "project_id": 271050
+    "project_id": 271050,
+    "sha256": "dab81029d8e1155749ec7144b39e578980456fd8b59461e218ed930d72e80cbd"
   },
   {
+    "filename": "easy_piglins-1.16.5-1.0.2.jar",
+    "id": 3309363,
     "project": "easy-piglins",
-    "id": 3169792,
-    "filename": "easy_piglins-1.16.5-1.0.0.jar",
-    "sha256": "b048630085695a5e8846cc2b8cc1bb6f1bcb59f0077ab63394a803c905df1006",
-    "project_id": 419372
+    "project_id": 419372,
+    "sha256": "66ac62e343203ed217a27a9038155192d4b3ee87908f7000347c5ee50526e5b5"
   },
   {
+    "filename": "easy_villagers-1.16.5-1.0.11.jar",
+    "id": 3327024,
     "project": "easy-villagers",
-    "id": 3171686,
-    "filename": "easy_villagers-1.16.4-1.1.28.jar",
-    "sha256": "3b8eff14b2b83f5cfe178f03076fa37c49add5dc05836b3151c7077f65a96dff",
-    "project_id": 400514
+    "project_id": 400514,
+    "sha256": "845e937a59e1c3b2423aff0129248b82ae9bdd3a618f43645cc7be6fe974c183"
   },
   {
+    "filename": "EnchantmentDescriptions-1.16.5-7.0.14.jar",
+    "id": 3363585,
     "project": "enchantment-descriptions",
-    "id": 3191059,
-    "filename": "EnchantmentDescriptions-1.16.5-7.0.2.jar",
-    "sha256": "890db07c51b07fb5921c8ae9e6352987c705625ca27f3d23bdfd313115a6a94b",
-    "project_id": 250419
+    "project_id": 250419,
+    "sha256": "60405ac61dbfb1e3c5d90479c2248f3e9408ca1089c524cefd021760c152f50c"
   },
   {
+    "filename": "EnderStorage-1.16.5-2.8.0.168-universal.jar",
+    "id": 3361748,
     "project": "ender-storage-1-8",
-    "id": 3175751,
-    "filename": "EnderStorage-1.16.4-2.7.1.166-universal.jar",
-    "sha256": "fbb861b85858f7a118a442d5577a53e5415c1f1b6ba7c4ade942d5512706f40d",
-    "project_id": 245174
+    "project_id": 245174,
+    "sha256": "31725d5af63fda688f38c7546a1e210332339fadd5fedc3144f9fb0b643bf8d2"
   },
   {
-    "project": "extended-lights-mod",
-    "id": 3144281,
     "filename": "extlights-3.3.jar",
-    "sha256": "7f210f8e8bc451df301a6a2c22f81e434dd1835699444e5c0ed2bb2620847a6b",
-    "project_id": 335051
+    "id": 3144281,
+    "project": "extended-lights-mod",
+    "project_id": 335051,
+    "sha256": "7f210f8e8bc451df301a6a2c22f81e434dd1835699444e5c0ed2bb2620847a6b"
   },
   {
+    "filename": "ExtraStorage-1.16.5-1.4.1.jar",
+    "id": 3336746,
     "project": "extrastorage",
-    "id": 3179402,
-    "filename": "ExtraStorage-1.16.4-1.3.1.jar",
-    "sha256": "30a78eb59482d393c7471a3b834e49e2dc6a70998be8ece9ba2c487abb5c92a5",
-    "project_id": 410168
+    "project_id": 410168,
+    "sha256": "0c3ecafbcc4c7f8a91479d389add57d0db2943cf182352065535d6b5511bce4f"
   },
   {
+    "filename": "FarmingForBlockheads_1.16.5-7.3.1.jar",
+    "id": 3332379,
     "project": "farming-for-blockheads",
-    "id": 3098206,
-    "filename": "FarmingForBlockheads_1.16.3-7.2.1.jar",
-    "sha256": "2225906be3306bb1066b58ebb97b998ebb679ef7fc2dcab6be53129675c44867",
-    "project_id": 261924
+    "project_id": 261924,
+    "sha256": "94668c62457b655cf4bb2ff651adc43a2c2379e1ee4d545c57ff0d01c45db61e"
   },
   {
-    "project": "fast-leaf-decay",
-    "id": 3052146,
     "filename": "FastLeafDecay-v25.jar",
-    "sha256": "0abd12217bd7e83d5427a4aca6acec27241bb4a7272ef79958a692bd60fe1d86",
-    "project_id": 230976
+    "id": 3052146,
+    "project": "fast-leaf-decay",
+    "project_id": 230976,
+    "sha256": "0abd12217bd7e83d5427a4aca6acec27241bb4a7272ef79958a692bd60fe1d86"
   },
   {
+    "filename": "FastWorkbench-1.16.4-4.5.1.jar",
+    "id": 3245271,
     "project": "fastworkbench",
-    "id": 3171218,
-    "filename": "FastWorkbench-1.16.4-4.5.0.jar",
-    "sha256": "0f4dc32d33512193a3f53ef4e2432bce921ffc047590e1734d3763b8dbd0a547",
-    "project_id": 288885
+    "project_id": 288885,
+    "sha256": "99488d96c13fb062fc7d1281957d72f69fca0f1fa07f54c480337282a5092f23"
   },
   {
-    "project": "fishing-real",
-    "id": 3074201,
     "filename": "fishingreal-1.16.3-1.0.0.jar",
-    "sha256": "1c2f868ee221e59407f6c8f1ec07fa7ccca49a819559dad818713a6778291fc5",
-    "project_id": 348834
+    "id": 3074201,
+    "project": "fishing-real",
+    "project_id": 348834,
+    "sha256": "1c2f868ee221e59407f6c8f1ec07fa7ccca49a819559dad818713a6778291fc5"
   },
   {
+    "filename": "HardcoreRevival_1.16.5-6.0.1.jar",
+    "id": 3344257,
     "project": "hardcore-revival",
-    "id": 3066098,
-    "filename": "HardcoreRevival_1.16.3-5.2.0.jar",
-    "sha256": "c7d20cad7f9d5e9dd36252c3735568b8e7a9a214bc543356b8429b6748f5ae49",
-    "project_id": 274036
+    "project_id": 274036,
+    "sha256": "4a76642dd343070261f9151a37c2deb7e2c9efc031d4127f91b8b6d9b7614670"
   },
   {
+    "filename": "iceandfire-2.1.8-1.16.5.jar",
+    "id": 3361256,
     "project": "ice-and-fire-dragons",
-    "id": 3162719,
-    "filename": "iceandfire-2.1.5-1.16.4.jar",
-    "sha256": "eb67d6808d9ae4d32b92d26a9a4561549e5e3fbeacf23ed614b19786c2172c76",
-    "project_id": 264231
+    "project_id": 264231,
+    "sha256": "37d849bc66e32b1de6ff52c2002714a49673b08f4fd84f36a7e1a6fdbf20f69e"
   },
   {
+    "filename": "iChunUtil-1.16.5-10.4.1.jar",
+    "id": 3346209,
     "project": "ichunutil",
-    "id": 3062089,
-    "filename": "iChunUtil-1.16.3-10.0.0.jar",
-    "sha256": "015b4cb31362e323ccdd84e3f865137bd7c32a8a1adcb9f9b77c4e6301a56a25",
-    "project_id": 229060
+    "project_id": 229060,
+    "sha256": "d5a1be183d5f68ff520ddfa6a5db55dfe7d76f327fa98fd0a82209330815b5d9"
   },
   {
+    "filename": "ironchest-1.16.5-11.2.13.jar",
+    "id": 3405717,
     "project": "iron-chests",
-    "id": 3105315,
-    "filename": "ironchest-1.16.4-11.2.10.jar",
-    "sha256": "5208572a3f07647ca3cfed9f7414957acd0059b7f708d2518f4c73c98beae6be",
-    "project_id": 228756
+    "project_id": 228756,
+    "sha256": "535b48cc3f12acacf42c2daff8709e45131d34bcc218a05203f62ce091e92a11"
   },
   {
+    "filename": "ironfurnaces-1.16.5-2.6.9.jar",
+    "id": 3387531,
     "project": "iron-furnaces",
-    "id": 3152441,
-    "filename": "ironfurnaces-1.16.4-2.5.6.jar",
-    "sha256": "042dcb6eca515f814b2093a600cca23a42fef71e4dbaf53b301369018ac5f288",
-    "project_id": 237664
+    "project_id": 237664,
+    "sha256": "f9347a04dece94e645b581091f94cd33396e93a91209eb55cc6933e09196b0a1"
   },
   {
+    "filename": "jei-1.16.5-7.7.1.116.jar",
+    "id": 3401260,
     "project": "jei",
-    "id": 3192904,
-    "filename": "jei-1.16.4-7.6.1.71.jar",
-    "sha256": "a4f1cc91214605b7d9b840a4a8ffd910c0eccc9db7f6ce82964bba9f3ca661e5",
-    "project_id": 238222
+    "project_id": 238222,
+    "sha256": "d2c8b8e08646e060a053cb9eaba70229540a7fc0204287e561dfd91bbff2c29b"
   },
   {
-    "project": "jei-integration",
-    "id": 3202331,
     "filename": "jeiintegration_1.16.5-7.0.1.15.jar",
-    "sha256": "0b45fe2858a8e9f97bf10fb218975a48a7d228ca27d274194c4dfaa91534bdfd",
-    "project_id": 265917
+    "id": 3202331,
+    "project": "jei-integration",
+    "project_id": 265917,
+    "sha256": "0b45fe2858a8e9f97bf10fb218975a48a7d228ca27d274194c4dfaa91534bdfd"
   },
   {
+    "filename": "JustEnoughResources-1.16.5-0.12.1.121.jar",
+    "id": 3336760,
     "project": "just-enough-resources-jer",
-    "id": 3066754,
-    "filename": "JustEnoughResources-1.16.3-0.12.0.100.jar",
-    "sha256": "d09fe055704075044e76e38c315ef410b8fc3587b1e24e500d540b57365ceb66",
-    "project_id": 240630
+    "project_id": 240630,
+    "sha256": "1fa5dce078ff98fb172ca658aa7c70345fb8af969c506d5125b419da93448d61"
   },
   {
+    "filename": "Kiwi-1.16.5-3.5.2.jar",
+    "id": 3377053,
     "project": "kiwi",
-    "id": 3103509,
-    "filename": "Kiwi-1.16.3-3.4.1.jar",
-    "sha256": "8e03a2109cb60117f6020a8943a19dc354a2cf2e1b83a0523169fece4ef06757",
-    "project_id": 303657
+    "project_id": 303657,
+    "sha256": "1a175d5f6ca5329c5ef92c853b3112a6a4d4284b7896aeb4b60c21381f2c8caf"
   },
   {
+    "filename": "Lollipop-1.16.5-3.2.9.jar",
+    "id": 3232534,
     "project": "lollipop",
-    "id": 3209431,
-    "filename": "Lollipop-1.16.4-3.2.6.jar",
-    "sha256": "5eb4c5c6947cfdcd26014a3209aff91653fe13044436dbfd0c310bcbf8abf701",
-    "project_id": 347954
+    "project_id": 347954,
+    "sha256": "bba84ef5f76510595f1ee693f650d4ee4202cea290b4139233ca26060a14e12b"
   },
   {
+    "filename": "lottaterracotta-1.16.5-1.3.2.jar",
+    "id": 3364628,
     "project": "lotta-terracotta",
-    "id": 3186253,
-    "filename": "lottaterracotta-1.16.5-1.3.1.jar",
-    "sha256": "8a5879733d8c35129c999d6524f0b7c1b49482076e1104c0c873f70267ea22d5",
-    "project_id": 351060
+    "project_id": 351060,
+    "sha256": "2a305378e261dee335fb680b4ac1cc362bed0b599a9fce6e248decbe1fa56c84"
   },
   {
+    "filename": "mcw-doors-1.0.3-mc1.16.5.jar",
+    "id": 3340793,
     "project": "macaws-doors",
-    "id": 3182357,
-    "filename": "mcw-doors-1.0.2-mc1.16.5.jar",
-    "sha256": "cea684ad9bf1fa75ba2685b3e521b2e1806f428681f7d929e3f937b161fb397e",
-    "project_id": 378646
+    "project_id": 378646,
+    "sha256": "fb23ffda5f8407a01bbb8a1ec5b08dff1a8772a6e7a726dd085920be62337982"
   },
   {
-    "project": "macaws-furniture",
-    "id": 3182349,
     "filename": "mcw-furniture-2.0.1-mc1.16.5.jar",
-    "sha256": "7f81b95c128ce97f3c41e29a4e98618c591f96321b53b718b5c3b6b8d3cb619e",
-    "project_id": 359540
+    "id": 3182349,
+    "project": "macaws-furniture",
+    "project_id": 359540,
+    "sha256": "7f81b95c128ce97f3c41e29a4e98618c591f96321b53b718b5c3b6b8d3cb619e"
   },
   {
-    "project": "metal-barrels",
-    "id": 3055811,
     "filename": "metalbarrels-3.3a.jar",
-    "sha256": "9bec62579ec71be41a303519e3b7944df0f3ee23a5b03ac7c0d0b27fe7c66150",
-    "project_id": 324985
+    "id": 3055811,
+    "project": "metal-barrels",
+    "project_id": 324985,
+    "sha256": "9bec62579ec71be41a303519e3b7944df0f3ee23a5b03ac7c0d0b27fe7c66150"
   },
   {
+    "filename": "pamhc2crops-1.16.3-1.0.2.jar",
+    "id": 3276350,
     "project": "pams-harvestcraft-2-crops",
-    "id": 3076451,
-    "filename": "pamhc2crops-1.16.3-1.0.1.jar",
-    "sha256": "d987b59e46c36c3461ee913729e9eb3d808e3e2c71499ef6e517c1b3f55ee093",
-    "project_id": 361385
+    "project_id": 361385,
+    "sha256": "5ebb51293d3e56ccf93875b7a4943577d78c1ee79401115230bb28cebbc7e832"
   },
   {
-    "project": "pams-harvestcraft-2-food-core",
-    "id": 3190867,
     "filename": "pamhc2foodcore-1.16.3-1.0.2.jar",
-    "sha256": "e4414d35013e746e5b06256a08dd957a814b17cebcb035899a84a3692d08b544",
-    "project_id": 372534
+    "id": 3190867,
+    "project": "pams-harvestcraft-2-food-core",
+    "project_id": 372534,
+    "sha256": "e4414d35013e746e5b06256a08dd957a814b17cebcb035899a84a3692d08b544"
   },
   {
+    "filename": "pamhc2foodextended-1.16.3-1.0.2.jar",
+    "id": 3260454,
     "project": "pams-harvestcraft-2-food-extended",
-    "id": 3190664,
-    "filename": "pamhc2foodextended-1.16.3-1.0.1.jar",
-    "sha256": "58a97f94f7087c2e66c9a6b2f33a328619bc544f46134597d3f612387b165668",
-    "project_id": 402231
+    "project_id": 402231,
+    "sha256": "886ec5e6dca66382b99765b0033d17e270b792171a75dd8eb41fcfd86a5641e9"
   },
   {
+    "filename": "pamhc2trees-1.16.3-1.0.1.jar",
+    "id": 3281234,
     "project": "pams-harvestcraft-2-trees",
-    "id": 3117043,
-    "filename": "pamhc2trees-1.16.3-1.0.0.jar",
-    "sha256": "0b18c28cec6212d5256a9abaea13cbac502d329f70797d17a3523d8a662846ce",
-    "project_id": 365460
+    "project_id": 365460,
+    "sha256": "e0f38f6a61e1da87981a249d520f2a8e43c4cefd29693076caf74ab8c5fe697f"
   },
   {
+    "filename": "PassableFoliage-1.16.5-2.3.1.jar",
+    "id": 3378277,
     "project": "passable-foliage",
-    "id": 3103676,
-    "filename": "PassableFoliage-1.16.4-2.2.0.jar",
-    "sha256": "be727b1e5dc0412404af84145180b00222274c1f7d31f5bfed5bc716e6146eeb",
-    "project_id": 379887
+    "project_id": 379887,
+    "sha256": "b18d228f6c8e34b8de54a0b0aa257e1be1eef7b65f8b7f75b3186e46f1b2118b"
   },
   {
+    "filename": "performant-1.16.2-5-3.72m.jar",
+    "id": 3401152,
     "project": "performant",
-    "id": 3285916,
-    "filename": "performant-1.16.2-5-3.54m.jar",
-    "sha256": "N8eUXJtIdbNRqZHLZ2gdj9HgpMYu7tAhMnG5Dw2dgqk=",
-    "project_id": 354143
+    "project_id": 354143,
+    "sha256": "cb3ef5fbedc6c9d7a0e379f7da400e22893a82425f27bd00bfd62e8cd8b35e20"
   },
   {
+    "filename": "Placebo-1.16.4-4.5.0.jar",
+    "id": 3331459,
     "project": "placebo",
-    "id": 3172794,
-    "filename": "Placebo-1.16.4-4.4.1.jar",
-    "sha256": "c57663a0b37260ca0cfaa6a4fb710d58f35866f029e92412b2332587a27d8f5d",
-    "project_id": 283644
+    "project_id": 283644,
+    "sha256": "4a1bebf13a3dde1870fee6da242598f9a1c8005161fdd795052506e0c38fd5da"
   },
   {
-    "project": "platter",
-    "id": 3115114,
     "filename": "Platter-1.16-1.0.0.jar",
-    "sha256": "6e4aee987ac4efa41a1b9cc26a4e4588c79a56bb200402b9fee71e43ab45a533",
-    "project_id": 381581
+    "id": 3115114,
+    "project": "platter",
+    "project_id": 381581,
+    "sha256": "6e4aee987ac4efa41a1b9cc26a4e4588c79a56bb200402b9fee71e43ab45a533"
   },
   {
+    "filename": "Powah-1.16.5-2.3.16.jar",
+    "id": 3232535,
     "project": "powah",
-    "id": 3209434,
-    "filename": "Powah-1.16.4-2.3.12.jar",
-    "sha256": "83806e56f79cb01382a6f105ffee8bba131afe52b04909138452eaffd0f87d49",
-    "project_id": 352656
+    "project_id": 352656,
+    "sha256": "78b652caa055f67f0479bac9a44e3ed67704bf4e59a48d06c7fd3cfe9ecb2b72"
   },
   {
-    "project": "quark-oddities",
-    "id": 3088871,
     "filename": "QuarkOddities-1.16.3.jar",
-    "sha256": "5eafd942f2eb9b13edde3bff451ee968c1d0fe549c8decd2f8551e59a079711d",
-    "project_id": 301051
+    "id": 3088871,
+    "project": "quark-oddities",
+    "project_id": 301051,
+    "sha256": "5eafd942f2eb9b13edde3bff451ee968c1d0fe549c8decd2f8551e59a079711d"
   },
   {
+    "filename": "Quark-r2.4-316.jar",
+    "id": 3394265,
     "project": "quark",
-    "id": 3208541,
-    "filename": "Quark-r2.4-305.jar",
-    "sha256": "02c6788bc39963b436de77e315808cd05ca09fddf8adeb27be5f5874cfd59b73",
-    "project_id": 243121
+    "project_id": 243121,
+    "sha256": "e5cea2e0aa0c229913dfb2735cc52c3889ad8d448bc1bdd64aa0dda3077b3676"
   },
   {
+    "filename": "refinedstorage-1.9.15.jar",
+    "id": 3400575,
     "project": "refined-storage",
-    "id": 3196167,
-    "filename": "refinedstorage-1.9.12.jar",
-    "sha256": "dbe279c56a44decbbfcaf2b1d8aed84988a5ddb62b0c20ec8777e90ecb58e346",
-    "project_id": 243076
+    "project_id": 243076,
+    "sha256": "d49fc8ff38b973517e60bc5d17a1e98bc8b4c6870ec58d3df7a36ac780474180"
   },
   {
+    "filename": "RepairChests-1.16.5-1.7.jar",
+    "id": 3211620,
     "project": "repair-chests",
-    "id": 3111984,
-    "filename": "RepairChests-1.16.4-1.6.jar",
-    "sha256": "e93bfbadf085764e0f458ab7a77a6c1f7620039390ffa7f60f08914d09124468",
-    "project_id": 401644
+    "project_id": 401644,
+    "sha256": "d25687ae8c7a9caf7491b506852eb7a6edc827230794dca4ddd45628b5674df9"
   },
   {
+    "filename": "rsgauges-1.16.4-1.2.11.jar",
+    "id": 3390492,
     "project": "redstone-gauges-and-switches",
-    "id": 3179484,
-    "filename": "rsgauges-1.16.4-1.2.8.jar",
-    "sha256": "dcac66fb8d65080d5326310c173e215437e0fa15405721f494f6da27e125b785",
-    "project_id": 296686
+    "project_id": 296686,
+    "sha256": "65e6e7a7fac64130de455b8b8e3ec1a16ee48411df0ab3963790038019f69a25"
   },
   {
+    "filename": "selene-1.16.5-1.5.jar",
+    "id": 3392984,
+    "project": "selene",
+    "project_id": 499980,
+    "sha256": "0138b5a0591f60bc9ac6da73cd7501f123a1c32822a0289447f0c8a7ee8bdfa9"
+  },
+  {
+    "filename": "SnowRealMagic-1.16.4-2.5.8.jar",
+    "id": 3391417,
     "project": "snow-real-magic",
-    "id": 3196605,
-    "filename": "SnowRealMagic-1.16.4-2.3.1.jar",
-    "sha256": "f588ae017f68f85dbdc26374282a0ad728ad44496577001314a2b2e5f22ef33b",
-    "project_id": 308663
+    "project_id": 308663,
+    "sha256": "153ba7328acbc0818361bb6f84fe4546aa1e9ddcd350ab5b6c97c6f7209b36b5"
   },
   {
+    "filename": "snowundertrees-1.16.5-v1.1.4.jar",
+    "id": 3247710,
     "project": "snow-under-trees",
-    "id": 3152350,
-    "filename": "snowundertrees-1.16.4-v1.1.3.jar",
-    "sha256": "6fb11fc0ff8542780796d481cc69549718dc6759b80bec43835003ebd33b8235",
-    "project_id": 353942
+    "project_id": 353942,
+    "sha256": "66cf77b4f9b654648e890fe6c55a3be9b3693f1be505d1c1e7b6ff1b91a1a54d"
   },
   {
+    "filename": "SoL-Carrot-1.16.5-1.10.0.jar",
+    "id": 3355731,
     "project": "spice-of-life-carrot-edition",
-    "id": 3174886,
-    "filename": "solcarrot-1.16.3-1.9.9.jar",
-    "sha256": "541ef38547ec17fb7cc485474747623d2dcc963a788c5ea300b39e31612e9022",
-    "project_id": 277616
+    "project_id": 277616,
+    "sha256": "b92f394d72b58e59e14d6cc337edf93d79617b02169ac44a3ec2a68820543d3a"
   },
   {
-    "project": "spark",
-    "id": 3245792,
     "filename": "spark-forge.jar",
-    "sha256": "9BSMsIoiLWFFQje2jhnVqFNiFTXKITTAlIuDxUOgtds=",
-    "project_id": 361579
+    "id": 3337641,
+    "project": "spark",
+    "project_id": 361579,
+    "sha256": "a162f9caf81073429bcb8df4844ef8eb43828c57d2956f55675499bc004e4802"
   },
   {
+    "filename": "StorageDrawers-1.16.3-8.3.0.jar",
+    "id": 3402515,
     "project": "storage-drawers",
-    "id": 3180569,
-    "filename": "StorageDrawers-1.16.3-8.2.2.jar",
-    "sha256": "e8775a6bd6b4c61f2df6efe22294d41e390b1aef79d744233948cc1e2bb07651",
-    "project_id": 223852
+    "project_id": 223852,
+    "sha256": "79ab53ab8d46aa517025fc4ecbb05b8492daff5f252aa4884ba46e8fefc3b794"
   },
   {
+    "filename": "supplementaries-1.16.5-0.14.5.jar",
+    "id": 3392977,
     "project": "supplementaries",
-    "id": 3281805,
-    "filename": "supplementaries-1.16.5-0.12.1.jar",
-    "sha256": "sOjCHEhL1x/jF4D/HuYiKdXvFIZyPFeKk0ihY6SUqcI=",
-    "project_id": 412082
+    "project_id": 412082,
+    "sha256": "6fefb8ce994642bf0acdde8d6cc19fc55dc82161602b2e424acb72d58361ca03"
   },
   {
+    "filename": "sweetconcrete-1.16.5-1.7.2.jar",
+    "id": 3364624,
     "project": "sweet-concrete",
-    "id": 3186255,
-    "filename": "sweetconcrete-1.16.5-1.7.1.jar",
-    "sha256": "6333aeb7dbdf3d2c5365bc7679ef91d0eec1c6d1ac6ff2f86c19139abbb02afe",
-    "project_id": 351052
+    "project_id": 351052,
+    "sha256": "6836f7f2a6f04edf6fe1efd4a6341c3c486c6c1ff824a858927375a45a121e33"
   },
   {
-    "project": "swingthroughgrass",
-    "id": 3103028,
     "filename": "swingthroughgrass-1.16.4-1.5.3.jar",
-    "sha256": "d47132c8e97989f6f1b4c3c2c0736bf9e16e9a72970b3953fc80dcf8b1a4e31d",
-    "project_id": 264353
+    "id": 3103028,
+    "project": "swingthroughgrass",
+    "project_id": 264353,
+    "sha256": "d47132c8e97989f6f1b4c3c2c0736bf9e16e9a72970b3953fc80dcf8b1a4e31d"
   },
   {
+    "filename": "the_bumblezone-1.16.5-2.4.10-forge.jar",
+    "id": 3404007,
     "project": "the-bumblezone-forge",
-    "id": 3389654,
-    "filename": "the_bumblezone-1.16.5-2.4.9-forge.jar",
-    "sha256": "51b2b5860ee391df2ea76c235c6614b34225312ebadaca4893c8ff16b0e9242a",
-    "project_id": 362479
+    "project_id": 362479,
+    "sha256": "71fb56ddca8d5f671b1c5e588b60e352bb80fba135aab74056b4daa0ed44cefd"
   },
   {
-    "project": "the-undergarden",
-    "id": 3361666,
     "filename": "The_Undergarden-1.16.5-0.5.4.jar",
-    "sha256": "b596836a5c1d50cf1c65c50ea728b0e295965cf9a4091a8eb1caac517aad5c50",
-    "project_id": 379849
+    "id": 3361666,
+    "project": "the-undergarden",
+    "project_id": 379849,
+    "sha256": "b596836a5c1d50cf1c65c50ea728b0e295965cf9a4091a8eb1caac517aad5c50"
   },
   {
-    "project": "towers-of-the-wild",
-    "id": 3103750,
     "filename": "towers_of_the_wild-1.16.4-2.0.1.jar",
-    "sha256": "fcd0e3f808569f0e547313a1ea3563c9a5d2fa8fbb638678eed6e46c1d8cfaf1",
-    "project_id": 386415
+    "id": 3103750,
+    "project": "towers-of-the-wild",
+    "project_id": 386415,
+    "sha256": "fcd0e3f808569f0e547313a1ea3563c9a5d2fa8fbb638678eed6e46c1d8cfaf1"
   },
   {
+    "filename": "TravelersBackpack-1.16.5-5.4.2.jar",
+    "id": 3316664,
     "project": "travelers-backpack",
-    "id": 3171745,
-    "filename": "TravelersBackpack-1.16.4-5.3.8.jar",
-    "sha256": "cd15a1bef4388bfc492c96dab510d32fff17cd921a06393bbb7ab25f6f25fc88",
-    "project_id": 321117
+    "project_id": 321117,
+    "sha256": "e07aad8653f037ad96639a602fa260684f89757c905d6a47e1193154d274875e"
   },
   {
-    "project": "the-weirding-gadget",
-    "id": 3116235,
     "filename": "weirdinggadget-1.16.(2-4)-2.2.7.jar",
-    "sha256": "fe9b2d4f39020a4239a19ea0e7229beec29eb8f1ef2b2b198b9aa5aad0b13318",
-    "project_id": 258914
+    "id": 3116235,
+    "project": "the-weirding-gadget",
+    "project_id": 258914,
+    "sha256": "fe9b2d4f39020a4239a19ea0e7229beec29eb8f1ef2b2b198b9aa5aad0b13318"
   },
   {
-    "project": "wither-skeleton-tweaks",
-    "id": 3172803,
     "filename": "Wither-Skeleton-Tweaks-1.16.4-5.3.0.jar",
-    "sha256": "e6375312aeb188cda4951a4c4935343a64785303129dbb47f49f59768d0865d3",
-    "project_id": 255902
+    "id": 3172803,
+    "project": "wither-skeleton-tweaks",
+    "project_id": 255902,
+    "sha256": "e6375312aeb188cda4951a4c4935343a64785303129dbb47f49f59768d0865d3"
   },
   {
+    "filename": "Xaeros_Minimap_21.14.1_Forge_1.16.5.jar",
+    "id": 3405505,
     "project": "xaeros-minimap",
-    "id": 3200201,
-    "filename": "Xaeros_Minimap_21.3.0.2_Forge_1.16.5.jar",
-    "sha256": "d477b6838bc27bfc759dc8601582683fdc7d425736656d304a1cbae4d932c6f0",
-    "project_id": 263420
+    "project_id": 263420,
+    "sha256": "97278ddc89fe70b81387fc2ae45d986eb07e373b49977de5d358b8addf1103a2"
   },
   {
+    "filename": "XaerosWorldMap_1.16.0_Forge_1.16.5.jar",
+    "id": 3405517,
     "project": "xaeros-world-map",
-    "id": 3200214,
-    "filename": "XaerosWorldMap_1.12.0.2_Forge_1.16.5.jar",
-    "sha256": "d4cc27d1646ce8bb5411261b31f1a13b11b7ad709fe7d9be43c4c7c8caa529f1",
-    "project_id": 317780
+    "project_id": 317780,
+    "sha256": "b4bceb6ebebf9a6c67a2e750e98d5cf2c1fe53fc66e487a79ac0d7a0664a8a12"
   },
   {
+    "filename": "YungsApi-1.16.4-Forge-11.jar",
+    "id": 3386962,
     "project": "yungs-api",
-    "id": 3186128,
-    "filename": "YungsApi-1.16.4-Forge-4.jar",
-    "sha256": "5a78eec5576ed162def18849bb604d5c69ec73b8715ab28ad41174ad0a673304",
-    "project_id": 421850
+    "project_id": 421850,
+    "sha256": "d280edabd1f83ff45831e8c79dfdc5e9ca17158fa2ed1d05025afcea23ad83a9"
   }
-]
+]
\ No newline at end of file

From 7f3ef18ff851a41b967202ded1105b86b3670f1d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 26 Jul 2021 01:49:18 +0100
Subject: [PATCH 012/212] voor-kia: Add client mods

---
 lib/minecraft.nix                          | 21 ++++++
 pkgs/build-support/fetchFromCurseForge.nix |  5 +-
 pkgs/default.nix                           |  1 +
 pkgs/minecraft/voor-kia-client.nix         |  8 ++
 pkgs/minecraft/voor-kia/client-mods.json   | 86 ++++++++++++++++++++++
 pkgs/minecraft/voor-kia/update-mods.py     |  8 +-
 6 files changed, 125 insertions(+), 4 deletions(-)
 create mode 100644 pkgs/minecraft/voor-kia-client.nix
 create mode 100644 pkgs/minecraft/voor-kia/client-mods.json

diff --git a/lib/minecraft.nix b/lib/minecraft.nix
index 87d5402..ef50b3d 100644
--- a/lib/minecraft.nix
+++ b/lib/minecraft.nix
@@ -27,4 +27,25 @@
         cp * $out/mods
       '';
     };
+
+  mkModpackZip = { name, version, mods }:
+    pkgs.stdenv.mkDerivation {
+      inherit name version;
+      srcs = map pkgs.local.fetchFromCurseForge mods;
+
+      sourceRoot = "src/";
+      preUnpack = "mkdir -p src/";
+      unpackCmd = "cp $curSrc src/";
+
+      buildInputs = [ pkgs.zip];
+
+      buildPhase = ''
+        zip voor-kia-mods.zip *.jar
+      '';
+
+      installPhase = ''
+        mkdir -p $out/
+        cp voor-kia-mods.zip $out/
+      '';
+    };
 }
diff --git a/pkgs/build-support/fetchFromCurseForge.nix b/pkgs/build-support/fetchFromCurseForge.nix
index 5d4f232..e3e5b51 100644
--- a/pkgs/build-support/fetchFromCurseForge.nix
+++ b/pkgs/build-support/fetchFromCurseForge.nix
@@ -12,12 +12,15 @@ let
   # really an odd one...
   a = head (match "0*([[:digit:]]+)" (substring 0 4 (toString id)));
   b = head (match "0*([[:digit:]]+)" (substring 4 7 (toString id)));
+  encoded-filename = replaceStrings [ " " ] [ "%20" ] filename;
 
-  url = "https://media.forgecdn.net/files/${a}/${b}/${filename}";
+  url = "https://media.forgecdn.net/files/${a}/${b}/${encoded-filename}";
   otherArgs = removeAttrs args [ "project" "project_id" "id" "filename" ];
 
 in fetchurl (otherArgs // {
   inherit url;
   # Rename files to avoid names incompatible with the nix store
   name = "${project}.jar";
+  # Avoid accidental URL globbing
+  curlOpts = "--globoff";
 })
diff --git a/pkgs/default.nix b/pkgs/default.nix
index 0748ae6..88a0112 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -12,4 +12,5 @@ in {
 
   # Minecraft modpacks
   voor-kia = callPackage ./minecraft/voor-kia.nix { };
+  voor-kia-client = callPackage ./minecraft/voor-kia-client.nix { };
 }
diff --git a/pkgs/minecraft/voor-kia-client.nix b/pkgs/minecraft/voor-kia-client.nix
new file mode 100644
index 0000000..8d0c687
--- /dev/null
+++ b/pkgs/minecraft/voor-kia-client.nix
@@ -0,0 +1,8 @@
+{ lib, local-lib, stdenv }:
+
+local-lib.minecraft.mkModpackZip {
+  name = "voor-kia-client";
+  version = "1.1";
+  mods = (builtins.fromJSON (builtins.readFile ./voor-kia/mods.json))
+    ++ (builtins.fromJSON (builtins.readFile ./voor-kia/client-mods.json));
+}
diff --git a/pkgs/minecraft/voor-kia/client-mods.json b/pkgs/minecraft/voor-kia/client-mods.json
new file mode 100644
index 0000000..960f7ab
--- /dev/null
+++ b/pkgs/minecraft/voor-kia/client-mods.json
@@ -0,0 +1,86 @@
+[
+  {
+    "filename": "AmbientSounds_v3.1.9_mc1.16.5.jar",
+    "id": 3334857,
+    "project": "ambientsounds",
+    "project_id": 254284,
+    "sha256": "c8ed21587fe96745695aa9a8f23b6effbcc6a5c5340aed11b8515c0e0aa2c310"
+  },
+  {
+    "filename": "BackTools-1.16.5-10.1.0.jar",
+    "id": 3224955,
+    "project": "back-tools",
+    "project_id": 229061,
+    "sha256": "cd5ed82919dd8acf2874c7edadba5bacfaffa898e572f8574241329e4478518e"
+  },
+  {
+    "filename": "BetterAdvancements-1.16.5-0.1.1.111.jar",
+    "id": 3400299,
+    "project": "better-advancements",
+    "project_id": 272515,
+    "sha256": "83c159f83bebc1d0f72c9de465bdcbeb2b02a56b88dcaa6661fe54df50a9aab5"
+  },
+  {
+    "filename": "Controlling-7.0.0.23.jar",
+    "id": 3348514,
+    "project": "controlling",
+    "project_id": 250398,
+    "sha256": "627308ed0b4fc1fdcc75113db8412c0684c3a774d1c6a07ae993543e605f5655"
+  },
+  {
+    "filename": "EntityCulling-1.16.5-2.1.6.jar",
+    "id": 3328602,
+    "project": "entity-culling",
+    "project_id": 409087,
+    "sha256": "eede3bfc68f48acb3e06fec2ea280510287cd5d492a02b8ace8e0dda742d7342"
+  },
+  {
+    "filename": "ftb-library-forge-1605.3.1-build.48.jar",
+    "id": 3373833,
+    "project": "ftb-library-forge",
+    "project_id": 404465,
+    "sha256": "f4f87f464796ee6ff7c80fb1fbc5753ac191138b6aa6b1a30c1b55252b3bf0a8"
+  },
+  {
+    "filename": "InventoryHud_[1.16.2-1.16.5].forge-3.3.0.jar",
+    "id": 3296748,
+    "project": "inventory-hud-forge",
+    "project_id": 357540,
+    "sha256": "2b3a4f02fe84b717c9273ea14cea0912267c2c093fc2cdfcde2b6f032c9762e7"
+  },
+  {
+    "filename": "MouseTweaks-2.14-mc1.16.2.jar",
+    "id": 3202662,
+    "project": "mouse-tweaks",
+    "project_id": 60089,
+    "sha256": "9d7e1aaee9f814c26d896e084e6e86930ab99e19fe547a1d350a6e25e4267092"
+  },
+  {
+    "filename": "namepain-1.4.0 forge-1.16.x.jar",
+    "id": 3356725,
+    "project": "name-pain",
+    "project_id": 366263,
+    "sha256": "5cc9e83b6d06810cbfcc155ddcfbe417cd4553a2665025affd1b71bee0138f68"
+  },
+  {
+    "filename": "overloadedarmorbar-5.1.0.jar",
+    "id": 3055679,
+    "project": "overloaded-armor-bar",
+    "project_id": 314002,
+    "sha256": "8aff59f170ef2c7598dc0f2367842f4384e57c13111507468da32498fc0ac4ea"
+  },
+  {
+    "filename": "shutupexperimentalsettings-1.0.3.jar",
+    "id": 3188120,
+    "project": "shutup-experimental-settings",
+    "project_id": 407174,
+    "sha256": "22ce84a0d424c2d48e483cb873909ac5c8c322bc793d09365ad44b901f43de62"
+  },
+  {
+    "filename": "Toast-Control-1.16.4-4.3.1.jar",
+    "id": 3172881,
+    "project": "toast-control",
+    "project_id": 271740,
+    "sha256": "b1cb36b7615c846f08c72423b2b52417b55eea91ca812bb7629a8f3060f5efae"
+  }
+]
\ No newline at end of file
diff --git a/pkgs/minecraft/voor-kia/update-mods.py b/pkgs/minecraft/voor-kia/update-mods.py
index 0af0b09..df32d86 100644
--- a/pkgs/minecraft/voor-kia/update-mods.py
+++ b/pkgs/minecraft/voor-kia/update-mods.py
@@ -1,6 +1,7 @@
 import argparse
 import json
 import hashlib
+import pathlib
 from copy import deepcopy
 from enum import Enum
 from typing import Dict, Generator, NamedTuple, Optional, Union
@@ -76,6 +77,7 @@ def main():
     parser.add_argument(
         "--mod-loader", choices=["none", "forge", "fabric"], default="forge"
     )
+    parser.add_argument("--infile", type=pathlib.Path)
     args = parser.parse_args()
 
     if args.mod_loader == "forge":
@@ -85,11 +87,11 @@ def main():
     else:
         raise AssertionError("Unreachable")
 
-    update(args.version, mod_loader)
+    update(args.infile, args.version, mod_loader)
 
 
-def update(version: str, mod_loader: ModLoader):
-    with open("./mods.json") as mods_json:
+def update(infile: pathlib.Path, version: str, mod_loader: ModLoader):
+    with open(infile) as mods_json:
         mods = json.load(mods_json)
 
     curse = CurseAPI()

From f05148587024dea492cbd0244e6b07de77dee4fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 28 Jul 2021 23:44:11 +0100
Subject: [PATCH 013/212] voor-kia: Downgrade citadel because of an
 incompatibility with iceandfire

See https://github.com/Alex-the-666/Citadel/issues/40
---
 pkgs/minecraft/voor-kia/mods.json | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/pkgs/minecraft/voor-kia/mods.json b/pkgs/minecraft/voor-kia/mods.json
index 8ca36a4..d88f16f 100644
--- a/pkgs/minecraft/voor-kia/mods.json
+++ b/pkgs/minecraft/voor-kia/mods.json
@@ -119,11 +119,11 @@
     "sha256": "639778fd58667aa560d333a2490352e34c1c32e897d9f8204e52df305ca5e879"
   },
   {
-    "filename": "citadel-1.7.2-1.16.5.jar",
-    "id": 3390028,
+    "filename": "citadel-1.7.1-1.16.5.jar",
+    "id": 3346836,
     "project": "citadel",
     "project_id": 331936,
-    "sha256": "c9b727acc3fc53ecfa7e33016c30eecfce407cb4690acba25375c64a76b7af17"
+    "sha256": "2977c084dcbd23c4fa1ea00ea152f1792b38781eff8f0234de4d67b1ee35b849"
   },
   {
     "filename": "cloth-config-4.11.26-forge.jar",
@@ -615,4 +615,4 @@
     "project_id": 421850,
     "sha256": "d280edabd1f83ff45831e8c79dfdc5e9ca17158fa2ed1d05025afcea23ad83a9"
   }
-]
\ No newline at end of file
+]

From a98f3261de0700346251978b2ea48b56690d6b2a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Thu, 29 Jul 2021 01:33:47 +0100
Subject: [PATCH 014/212] voor-kia: Downgrade supplementaries due to graphics
 bugs

See https://github.com/MehVahdJukaar/Supplementaries/issues/86
---
 pkgs/minecraft/voor-kia/mods.json | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/pkgs/minecraft/voor-kia/mods.json b/pkgs/minecraft/voor-kia/mods.json
index d88f16f..3687c80 100644
--- a/pkgs/minecraft/voor-kia/mods.json
+++ b/pkgs/minecraft/voor-kia/mods.json
@@ -490,11 +490,11 @@
     "sha256": "65e6e7a7fac64130de455b8b8e3ec1a16ee48411df0ab3963790038019f69a25"
   },
   {
-    "filename": "selene-1.16.5-1.5.jar",
-    "id": 3392984,
+    "filename": "selene-1.16.5-1.3.jar",
+    "id": 3377212,
     "project": "selene",
     "project_id": 499980,
-    "sha256": "0138b5a0591f60bc9ac6da73cd7501f123a1c32822a0289447f0c8a7ee8bdfa9"
+    "sha256": "49a08a86b9f63170fb1a9bf9c81d6a91157eecfbf150ac04bb010207a0133485"
   },
   {
     "filename": "SnowRealMagic-1.16.4-2.5.8.jar",
@@ -532,11 +532,11 @@
     "sha256": "79ab53ab8d46aa517025fc4ecbb05b8492daff5f252aa4884ba46e8fefc3b794"
   },
   {
-    "filename": "supplementaries-1.16.5-0.14.5.jar",
-    "id": 3392977,
+    "filename": "supplementaries-1.16.5-0.14.3.jar",
+    "id": 3377218,
     "project": "supplementaries",
     "project_id": 412082,
-    "sha256": "6fefb8ce994642bf0acdde8d6cc19fc55dc82161602b2e424acb72d58361ca03"
+    "sha256": "42e91d1c58b9bd292263410e75971de8a59ce0c1f2d7979a2222591fc55eba28"
   },
   {
     "filename": "sweetconcrete-1.16.5-1.7.2.jar",

From d86a338b6c2930fbe276f90622398f615ce8da85 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 31 Jul 2021 00:05:09 +0100
Subject: [PATCH 015/212] voor-kia: Add overworld-two

Worldgen optimization mod; should be very useful!
---
 pkgs/minecraft/voor-kia/mods.json | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/pkgs/minecraft/voor-kia/mods.json b/pkgs/minecraft/voor-kia/mods.json
index 3687c80..96d0231 100644
--- a/pkgs/minecraft/voor-kia/mods.json
+++ b/pkgs/minecraft/voor-kia/mods.json
@@ -391,6 +391,13 @@
     "project_id": 324985,
     "sha256": "9bec62579ec71be41a303519e3b7944df0f3ee23a5b03ac7c0d0b27fe7c66150"
   },
+  {
+    "filename": "overworld_two-1.0-Forge-1.16.4.jar",
+    "id": 3149167,
+    "project": "overworld-two-forge",
+    "project_id": 431157,
+    "sha256": "4995b774537ab31de6b98eb15aad3fbbfe6d3aa4e57108a9b3fe3abbe3d8da59"
+  },
   {
     "filename": "pamhc2crops-1.16.3-1.0.2.jar",
     "id": 3276350,

From 5e1340428ece56f83487d0ff6ea95b03e0808e0d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 31 Jul 2021 20:10:02 +0100
Subject: [PATCH 016/212] voor-kia: Downgrade create to fix shader bugs

See https://github.com/Jozufozu/Flywheel/issues/13
---
 pkgs/minecraft/voor-kia/mods.json | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/pkgs/minecraft/voor-kia/mods.json b/pkgs/minecraft/voor-kia/mods.json
index 96d0231..794a1ab 100644
--- a/pkgs/minecraft/voor-kia/mods.json
+++ b/pkgs/minecraft/voor-kia/mods.json
@@ -140,11 +140,11 @@
     "sha256": "1039d9ae78873107ee82c799e586c71dfe284d5bb58f89895a3a510f8f33c765"
   },
   {
-    "filename": "flywheel-1.16-0.2.0.jar",
-    "id": 3406855,
+    "filename": "flywheel-1.16-0.1.1.jar",
+    "id": 3389159,
     "project": "flywheel",
     "project_id": 486392,
-    "sha256": "7abc741d731b207ab3e1c6776786af6cd2150d57c140090285293a593e82b669"
+    "sha256": "ac0cc92d6ef491cc88ca3fbc3cb2c3180fe58ad1ce1c6f91dcfb996324d7331e"
   },
   {
     "filename": "expandability-2.0.1-forge.jar",
@@ -182,11 +182,11 @@
     "sha256": "a3516650a1c5e76b47b9efd69a4cfa9cda4f85250bf217fa7186f74ef375a7e4"
   },
   {
-    "filename": "create-mc1.16.5_v0.3.2c.jar",
-    "id": 3406857,
+    "filename": "create-mc1.16.5_v0.3.2b.jar",
+    "id": 3386319,
     "project": "create",
     "project_id": 328085,
-    "sha256": "5cec00aa769b9edf9c85235742d593b00eefd4f3f0ed93cac412d633c23c6558"
+    "sha256": "7b0180bf62abe862f7dcb83a4281447b00fd7a26d488cfc17e4d6f590782cc8f"
   },
   {
     "filename": "CreativeCore_v2.2.0_mc1.16.5.jar",

From cd55c50224c74a59c62320900e03513395f6cb09 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 20 Aug 2021 23:34:08 +0100
Subject: [PATCH 017/212] Update ice and fire config

Yes, they completely changed the config format and didn't take into
account the user's changes.

I guess I shouldn't be expecting much from minecraft mod authors, but
damn.
---
 .../voor-kia/config/iceandfire-common.toml    | 822 ++++++++++--------
 1 file changed, 450 insertions(+), 372 deletions(-)

diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire-common.toml b/configuration/services/configs/minecraft/voor-kia/config/iceandfire-common.toml
index 2fbe215..3ebb545 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire-common.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire-common.toml
@@ -1,374 +1,452 @@
+[Generation]
 
-[general]
-	#How fast amphitheres fly.
-	#Range: 0.0 ~ 3.0
-	"Amphithere Flight Speed" = 1.75
-	#how long(in ticks) a siren has to wait after failing to lure in a player
-	#Range: 100 ~ 24000
-	"Siren Time Between Songs" = 2000
-	#Troll attack strength
-	#Range: 1.0 ~ 10000.0
-	"Troll Attack Strength" = 10.0
-	#Maximum cyclops health
-	#Range: 1.0 ~ 10000.0
-	"Cyclops Max Health" = 150.0
-	#Dread Lich spawn weight. Lower = lower chance to spawn
-	#Range: 1 ~ 10000
-	"Lich Spawn Weight" = 2
-	#Whether or not sea serpents can break weak blocks in their way
-	"Sea Serpent Griefing" = false
-	#True if pixie villages are allowed to spawn
-	"Spawn Pixies" = true
-	#How many blocks away can cyclopes detect sheep. Note that increasing this could cause lag.
-	#Range: 1 ~ 10000
-	"Cyclopes Sheep Search Length" = 17
-	#A double check to see if the game can spawn death worms. Higher number = lower chance to spawn.
-	#Range: 0 ~ 10000
-	"Death Worm Spawn Check Chance" = 3
-	#Maximum cockatrice health
-	#Range: 1.0 ~ 10000.0
-	"Cockatrice Health" = 40.0
-	#True if gorgon temples are allowed to spawn
-	"Spawn Gorgons" = true
-	#True if hippocampi are allowed to spawn
-	"Spawn Hippocampus" = true
-	#Damage dealt from a successful ice breath attack. Attack Damage is scaled to by age, so a stage 5 dragon will deal 5x as much as this number
-	#Range: 0.0 ~ 10000.0
-	"Dragon Attack Damage(Ice breath)" = 2.5
-	#How high dragons can fly, in Y height.
-	#Range: > 100
-	"Max Dragon Flight Height" = 128
-	#True if cockatrices are allowed to spawn
-	"Spawn Cockatrices" = true
-	#True if tamed dragons go to sleep at night.
-	"Tamed Dragons Sleep" = true
-	#True if ghosts can rarely spawn from brutal PvP deaths.
-	"Ghost Spawn from PvP deaths" = true
-	#Whether or not cyclops can break logs or leaves in their way
-	"Cyclops Griefing" = false
-	#Disable this to remove easter egg with tinkers installed.
-	Weezer = true
-	#True if dragons can despawn. Note that if this is false there may be SERIOUS lag issues.
-	"Dragons Despawn" = true
-	#True if hippogryphs are allowed to spawn
-	"Spawn Hippogryphs" = true
-	#True if dread liches are allowed to spawn
-	"Spawn Liches" = true
-	#One out of this number chance per chunk to generate a mausoleum.
-	#Range: 1 ~ 10000
-	"Mausoleum Gen Chance" = 5000
-	#Whether to generate copper ore or not
-	"Generate Copper Ore" = false
-	#A more intelligent dragon pathfinding system, but is also laggier. Turn this on if you think dragons are too stupid.
-	"Intelligent Dragon Pathfinding" = false
-	#Cockatrice spawn weight. Lower = lower chance to spawn
-	#Range: 1 ~ 10000
-	"Cockatrice Spawn Weight" = 4
-	#True to make the screen pink when sirens attract players
-	"Use Siren Shader" = true
-	#Enable this if your server is being bombarded with moved wrongly or moved too fast console messages. REQUIRES RESTART!
-	"Dragon Moved Wrongly Error Fix" = false
-	#Blocks that a dragon can break, but won't spawn drops for. Use the format like "minecraft:stone" or "rats:block_of_cheese" 
-	noDropBreakBlocks = ["minecraft:stone", "minecraft:dirt", "minecraft:grass_block"]
-	#How many blocks away can death worms spot potential prey. Note that increasing this could cause lag
-	#Range: 1 ~ 10000
-	"Death Worm Target Search Length" = 64
-	#How far away stymphalian birds will consider other birds to be in the same flock.
-	#Range: 1 ~ 10000
-	"Stymphalian Bird Flock Length" = 40
-	#How many maximum individuals a myrmex colony can have.
-	#Range: 10 ~ 10000
-	"Myrmex Colony Max Size" = 80
-	#1 out of this number chance per block that gold will generate in dragon lairs.
-	#Range: 1 ~ 10000
-	"Dragon Den Gold Amount" = 4
-	#Whether to generate dragon skeletons or not
-	"Generate Dragon Skeletons" = true
-	#1 out of this number chance per chunk for generation
-	#Range: 1 ~ 10000
-	"Spawn Cyclops Cave Chance" = 1000
-	#True if myrmex colonies are allowed to spawn
-	"Spawn Myrmex" = true
-	#Default attack strength of a dragonsteel sword.
-	#Range: 5.0 ~ 2.147483647E9
-	"Dragonsteel Sword Base Attack Strength" = 25.0
-	#Whether to generate dragon caves or not
-	"Generate Dragon Caves" = true
-	#How high stymphalian birds can fly, in Y height.
-	#Range: > 10
-	"Max Stymphalian Bird Flight Height" = 80
-	#Whitelist mob spawn (troll, hippogryph, etc) dimensions. Use the format like "minecraft:the_nether" or "rats:ratlantis" 
-	blacklistDimensions = ["minecraft:overworld"]
-	#1 out of this number chance per chunk for generation
-	#Range: 1 ~ 10000
-	"Spawn Sea Serpent Chance" = 2500
-	#Default sea serpent health, this is scaled to the sea serpent's particular size
-	#Range: 1.0 ~ 10000.0
-	"Sea Serpent Base Health" = 20.0
-	#True if chickens lay rotten eggs.
-	"Chickens Lay Rotten Eggs" = true
-	#size of pixie villages
-	#Range: 1 ~ 10000
-	"Pixie Village Size" = 5
-	#Maximum amphithere health
-	#Range: 1.0 ~ 10000.0
-	"Amphithere Max Health" = 50.0
-	#How many ticks it takes while riding an untamed amphithere to tame it.
-	#Range: 1 ~ 10000
-	"Amphithere Tame Time" = 400
-	#True if dragons can break blocks if they get stuck. Turn this off if your dragons randomly explode.
-	"Dragons Dig When Stuck" = true
-	#True if siren islands are allowed to spawn
-	"Spawn Sirens" = true
-	#True if tamed dragons can follow the griefing rules.
-	"Tamed Dragon Griefing" = true
-	#Default deathworm attack strength, this is scaled to the worm's particular size
-	#Range: 1.0 ~ 10000.0
-	"Death Worm Base Attack Strength" = 3.0
-	#Maximum hydra health
-	#Range: 1.0 ~ 10000.0
-	"Hydra Max Health" = 250.0
-	#Maximum gorgon health
-	#Range: 1.0 ~ 10000.0
-	"Gorgon Max Health" = 100.0
-	#Whether to generate silver ore or not
-	"Generate Silver Ore" = true
-	#Turning this to true simplifies the dragon's pathfinding process, making them dumber when finding a path, but better for servers with many loaded dragons.
-	"Experimental Dragon path Finder" = false
-	#1 out of this number chance per chunk for generation
-	#Range: 1 ~ 10000
-	"Generate Dragon Skeleton Chance" = 300
-	#True if villagers should run away and hide from dragons and other hostile Ice and Fire mobs.
-	"Villagers Fear Dragons" = true
-	#1 out of this number chance per 6000 ticks for a chicken to lay a cockatrice egg.
-	#Range: > 1
-	"Cockatrice chicken Search Length" = 30
-	#True if cyclops caves are allowed to spawn
-	"Spawn Cyclopes Caves" = true
-	#True if hydra caves are allowed to generate
-	"Generate Hydra Caves" = true
-	#Default armor value of dragonsteel chestplate.
-	#Range: > 7
-	"Dragonsteel Base Armor" = 12
-	#How many blocks away can dragons wander from their defined "home" position.
-	#Range: 1 ~ 10000
-	"Dragon Wander From Home Distance" = 40
-	#True if using blacklists, false if using whitelists for dragons and structure gen.
-	"Use Dimension Blacklist" = false
-	#Default deathworm health, this is scaled to the worm's particular size
-	#Range: 1.0 ~ 10000.0
-	"Death Worm Base Health" = 10.0
-	#Change this to slow down or speed up dragon or amphithere flight.
-	#Range: 0.0 ~ 2.0
-	"Dragon Flight Speed Modifier" = 1.0
-	#1 out of this number chance per chunk for generation
-	#Range: 1 ~ 10000
-	"Spawn Wandering Cyclops Chance" = 300
-	#1 out of this number chance per chunk for generation
-	#Range: 1 ~ 10000
-	"Spawn Gorgon Chance" = 10000
-	#Default durability value of dragonsteel sword.
-	#Range: > 1
-	"Dragonsteel Base Durability" = 8000
-	#How many blocks away can stymphalian birds spot potential prey. Note that increasing this could cause lag.
-	#Range: 1 ~ 10000
-	"Stymphalian Bird Target Search Length" = 64
-	#True if stymphalian birds are allowed to target and attack animals
-	"Stymphalian Birds Target Animals" = false
-	#How many ticks it takes for a Myrmex to move from a larva to a pupa, and from a pupa to an adult.
-	#Range: 1 ~ 100000
-	"Myrmex Hatch Length" = 35000
-	#Whether to generate graveyards or not
-	"Generate Graveyards" = true
-	#True if trolls are allowed to spawn
-	"Spawn Trolls" = true
-	#True if amphitheres are allowed to spawn
-	"Spawn Amphitheres" = true
-	#Whether to generate sapphire ore or not
-	"Generate Sapphire Ore" = true
-	#Maximum ghost health.
-	#Range: 1.0 ~ 10000.0
-	"Ghost Max Health" = 30.0
-	#How far away dangerous structures(dragon roosts, cyclops caves, etc.) must be from spawn(0, 0).
-	#Range: 1 ~ 10000
-	"Dangerous World Gen Dist From Spawn" = 2000
-	#Damage dealt from a successful lightning breath attack. Attack Damage is scaled to by age, so a stage 5 dragon will deal 5x as much as this number
-	#Range: 0.0 ~ 10000.0
-	"Dragon Attack Damage(Lightning breath)" = 3.5
-	#One out of this number chance per chunk to generate a myrmex hive.
-	#Range: 1 ~ 10000
-	"Myrmex Colony Gen Chance" = 1500
-	#Hippogryph spawn weight. Lower = lower chance to spawn.
-	#Range: 1 ~ 10000
-	"Hippogryph Spawn Weight" = 1
-	#1 out of this number chance per chunk for generation
-	#Range: 1 ~ 10000
-	"Generate Dragon Roost Chance" = 1000
-	#Maximum ghost attack strength.
-	#Range: 0.0 ~ 10000.0
-	"Ghost Attack Strength" = 3.0
-	#One out of this number chance per chunk to generate a hydra cave.
-	#Range: 1 ~ 10000
-	"Hydra Caves Gen Chance" = 1000
-	#Every interval of this number in ticks, dragon allowed to break blocks.
-	#Range: 0 ~ 10000
-	"Dragon Block Break Cooldown" = 5
-	#True if stymphalian birds are allowed to spawn
-	"Spawn Stymphalian Birds" = true
-	#True if dragons can drop their blood on death.
-	"Dragons Drop Blood" = true
-	#Every interval of this number in ticks, dragon hunger decreases.
-	#Range: 1 ~ 10000
-	"Dragon Hunger Tick Rate" = 3000
-	#True if trolls are allowed to drop their weapon on death.
-	"Trolls Drop Weapon" = true
-	#Troll spawn weight. Lower = lower chance to spawn
-	#Range: 1 ~ 10000
-	"Troll Spawn Weight" = 4
-	#Glacier Spawn Weight. Higher number = more common
-	#Range: 1 ~ 10000
-	"Glacier Spawn Weight" = 4
-	#1 out of this number chance per chunk for generation
-	#Range: 1 ~ 10000
-	"Generate Dragon Cave Chance" = 200
-	#Dragon griefing - 2 is no griefing, 1 is breaking weak blocks, 0 is default
-	#Range: 0 ~ 2
-	"Dragon Griefing" = 2
-	#A double check to see if the game can spawn cockatrices. Higher number = lower chance to spawn.
-	#Range: 0 ~ 10000
-	"Cockatrice Spawn Check Chance" = 1000
-	#True if pixies are allowed to steal from players
-	"Pixies Steal Items" = true
-	#True if dragons can drop their heart on death.
-	"Dragons Drop Heart" = true
-	#True if wild deathworms are allowed to target and attack monsters
-	"Death Worms Target Monsters" = true
-	#How far away dangerous structures(dragon roosts, cyclops caves, etc.) must be from the last generated structure.
-	#Range: 1 ~ 10000
-	"Dangerous World Gen Dist Seperation" = 1000
-	#True if dragons fire/ice charges create secondary explosions that launch blocks everywhere. Turn this to true if you like unfair explosions. Or lag.
-	"Explosive Dragon Breath" = false
-	#Maximum threads to use for dragon/myrmex pathfinding. Increase this number if pathing is slow and you have many cores.
-	#Range: > 1
-	"Dragon Pathfinding Threads" = 3
-	#Base Myrmex(worker) attack strength
-	#Range: 1.0 ~ 10000.0
-	"Myrmex Base Attack Strength" = 3.0
-	#How far away dragons will detect gold blocks being destroyed or chests being opened
-	#Range: 0 ~ 10000
-	"Dragon Gold Search Length" = 30
-	#True if stymphalian birds can drop items registered in the ore dictionary to ingotCopper, ingotBronze, nuggetCopper, nuggetBronze.
-	"Stymphalian Birds drop ore dict items" = true
-	#True if animals should run away and hide from dragons and other hostile Ice and Fire mobs.
-	"Animals Fear Dragons" = true
-	#Stymphalian bird feather attack strength.
-	#Range: 0.0 ~ 10000.0
-	"Stymphalian Bird Feather Attack Strength" = 1.0
-	#Blocks that a dragon cannot break. Use the format like "minecraft:chest" or "rats:block_of_cheese" 
-	blacklistedBreakBlocks = []
-	#1 out of this number chance per chunk for generation
-	#Range: 1 ~ 10000
-	"Spawn Hippocampus Chance" = 400
-	#Amphithere spawn weight. Lower = lower chance to spawn
-	#Range: 1 ~ 10000
-	"Amphithere Spawn Weight" = 500
-	#Dragon Flute Distance - how many chunks away is the dragon flute effective?
-	#Range: 0 ~ 10000
-	"Dragon Flute Distance" = 4
-	#The percentage chance for a block to drop as an item when a dragon breaks it.
-	#Range: 0.0 ~ 1.0
-	"Dragon Block Breaking Drop Chance" = 0.10000000149011612
-	#Damage dealt from a successful fire breath attack. Attack Damage is scaled to by age, so a stage 5 dragon will deal 5x as much as this number
-	#Range: 0.0 ~ 10000.0
-	"Dragon Attack Damage(Fire breath)" = 2.0
-	#How many blocks away can ampitheres detect villagers being hurt. Note that increasing this could cause lag.
-	#Range: 1 ~ 10000
-	"Amphithere Villager Search Length" = 64
-	#Deathworm spawn weight. Lower = lower chance to spawn
-	#Range: 1 ~ 10000
-	"Death Worm Spawn Weight" = 100
-	#Percentage of critical strike that will disarm with easter egg tinkers material.
-	#Range: 0.0 ~ 1.0
-	"Easter Egg Tinkers Tool Disarm chance" = 0.20000000298023224
-	#Whether to generate amethyst ore or not
-	"Generate Amethyst Ore" = true
-	#Ratio of Stone(this number) to Ores in Dragon Caves
-	#Range: 1 ~ 10000
-	"Dragon Cave Ore Ratio" = 45
-	#1 out of this number chance per chunk for generation
-	#Range: 1 ~ 10000
-	"Spawn Stymhphalian Bird Chance" = 500
-	#A double check to see if the game can spawn trolls. Higher number = lower chance to spawn.
-	#Range: 0 ~ 10000
-	"Troll Spawn Check Chance" = 0
-	#1/this number chance for a stymphalian feather to turn into an item before despawning. Zero means never.
-	#Range: 0 ~ 10000
-	"Stymphalian Bird Feather Drop Chance" = 25
-	#How long it takes(in ticks) for a dragon egg to hatch
-	#Range: > 1
-	"Dragon Egg Hatch Time" = 7200
-	#Cyclops attack strength
-	#Range: 1.0 ~ 10000.0
-	"Cyclops Attack Strength" = 15.0
-	#how long(in ticks) can a siren use its sing effect on a player, without a cooldown.
-	#Range: 100 ~ 24000
-	"Siren Max Sing Time" = 12000
-	#Max dragon health. Health is scaled to this
-	#Range: 1.0 ~ 100000.0
-	"Dragon Health" = 500.0
-	#How many blocks away can dragons spot potential prey. Note that increasing this could cause lag.
-	#Range: 1 ~ 10000
-	"Dragon Target Search Length" = 128
-	#How many ticks it takes for a Myrmex Queen to produce an egg.
-	#Range: 1 ~ 10000
-	"Myrmex Gestation Length" = 2500
-	#Whether to generate glacier biomes or not
-	"Generate Glaciers" = true
-	#True if wandering cyclopes are allowed to spawn
-	"Spawn Wandering Cyclopes" = true
-	#Maximum siren health
-	#Range: 1.0 ~ 10000.0
-	"Siren Max Health" = 50.0
-	#True if dragons can drop their skull on death.
-	"Dragons Drop Skull" = true
-	#True if sea serpents are allowed to spawn
-	"Spawn Sea Serpents" = true
-	#Maximum nodes for dragons/myrmex to path too. Decrease this is dragon pathfinding is super slow or intensive.
-	#Range: > 1
-	"Dragon Max Pathfinding Nodes" = 5000
-	#True if the summon crystal can load chunks to find dragons.
-	"Chunk Load Summon Crystal" = true
-	#Amount of damage done with cyclops bite attack.
-	#Range: 1.0 ~ 10000.0
-	"Cyclops Bite Strength" = 40.0
-	#Amphithere attack strength
-	#Range: 1.0 ~ 10000.0
-	"Amphithere Attack Strength" = 7.0
-	#Graveyard rarity.
-	#Range: 2 ~ 10000
-	"Graveyard Chance" = 5000
-	#Max dragon attack damage. Attack Damage is scaled to this
-	#Range: 1 ~ 10000
-	"Dragon Attack Damage" = 17
-	#1 out of this number chance per chunk for generation
-	#Range: 1 ~ 10000
-	"Spawn Sirens Chance" = 400
-	#Maximum troll health
-	#Range: 1.0 ~ 10000.0
-	"Troll Max Health" = 50.0
-	#Default sea serpent attack strength, this is scaled to the sea serpent's particular size
-	#Range: 1.0 ~ 10000.0
-	"Sea Serpent Base Attack Strength" = 4.0
-	#Whether to generate dragon roosts or not
-	"Generate Dragon Roosts" = true
-	#True if mausoleums are allowed to generate
-	"Generate Mausoleums" = true
-	#Dragon Flap Noise Distance - Larger number, further away you can hear it
-	#Range: 0 ~ 10000
-	"Dragon Flap Noise Distance" = 4
-	#True if deathworms are allowed to spawn
-	"Spawn Death Worms" = true
-	#1 out of this number chance per chunk for generation
-	#Range: 1 ~ 10000
-	"Spawn Pixies Chance" = 800
+    [Generation.Dimensions]
+        #True if using blacklists, false if using whitelists for dragons and structure gen.
+        "Use Dimension Blacklist" = false
+        #Whitelist dragon gen dimensions. Use the format like "minecraft:the_nether" or "rats:ratlantis" 
+        whitelistDimensionsDragons = ["minecraft:overworld"]
+        #Whitelisted feature(cyclops caves, hydra dens, etc) gen dimensions. Use the format like "minecraft:the_nether" or "rats:ratlantis" 
+        whitelistDimensionsFeature = ["minecraft:overworld"]
+        #Whitelist mob spawn (troll, hippogryph, etc) dimensions. Use the format like "minecraft:the_nether" or "rats:ratlantis" 
+        whitelistDimensionsMobs = ["minecraft:overworld"]
+        #Blacklisted dragon gen dimensions. Use the format like "minecraft:the_nether" or "rats:ratlantis" 
+        blacklistDimensionsDragons = ["minecraft:the_nether", "minecraft:the_end"]
+        #Blacklisted feature(cyclops caves, hydra dens, etc) gen dimensions. Use the format like "minecraft:the_nether" or "rats:ratlantis" 
+        blacklistDimensionsFeature = ["minecraft:the_nether", "minecraft:the_end"]
+        #Blacklisted mob spawn (troll, hippogryph, etc) dimensions. Use the format like "minecraft:the_nether" or "rats:ratlantis" 
+        blacklistDimensionsMobs = ["minecraft:the_nether", "minecraft:the_end"]
+
+    [Generation.Ores]
+        #Whether to generate copper ore or not
+        "Generate Copper Ore" = false
+        #Whether to generate silver ore or not
+        "Generate Silver Ore" = true
+        #Whether to generate sapphire ore or not
+        "Generate Sapphire Ore" = true
+        #Whether to generate amethyst ore or not
+        "Generate Amethyst Ore" = true
+
+    [Generation.Dragon]
+        #Whether to generate dragon skeletons or not
+        "Generate Dragon Skeletons" = true
+        #1 out of this number chance per chunk for generation
+        #Range: 1 ~ 10000
+        "Generate Dragon Skeleton Chance" = 300
+        #Whether to generate dragon caves or not
+        "Generate Dragon Caves" = true
+        #1 out of this number chance per chunk for generation
+        #Range: 1 ~ 10000
+        "Generate Dragon Cave Chance" = 200
+        #Whether to generate dragon roosts or not
+        "Generate Dragon Roosts" = true
+        #1 out of this number chance per chunk for generation
+        #Range: 1 ~ 10000
+        "Generate Dragon Roost Chance" = 1000
+        #1 out of this number chance per block that gold will generate in dragon lairs.
+        #Range: 1 ~ 10000
+        "Dragon Den Gold Amount" = 4
+        #Ratio of Stone(this number) to Ores in Dragon Caves
+        #Range: 1 ~ 10000
+        "Dragon Cave Ore Ratio" = 45
+
+    [Generation.Structures-Features]
+        #How far away dangerous structures(dragon roosts, cyclops caves, etc.) must be from spawn(0, 0).
+        #Range: 1 ~ 10000
+        "Dangerous World Gen Dist From Spawn" = 2000
+        #How far away dangerous structures(dragon roosts, cyclops caves, etc.) must be from the last generated structure.
+        #Range: 1 ~ 10000
+        "Dangerous World Gen Dist Seperation" = 500
+        #Whether to generate glacier biomes or not
+        "Generate Glaciers" = true
+        #Glacier Spawn Weight. Higher number = more common
+        #Range: 1 ~ 10000
+        "Glacier Spawn Weight" = 4
+        #True if mausoleums are allowed to generate
+        "Generate Mausoleums" = true
+        #One out of this number chance per chunk to generate a mausoleum.
+        #Range: 1 ~ 10000
+        "Mausoleum Gen Chance" = 5000
+        #Whether to generate graveyards or not
+        "Generate Graveyards" = true
+        #Graveyard rarity.
+        #Range: 2 ~ 10000
+        "Graveyard Chance" = 100
+
+[Dragons]
+
+    [Dragons.Griefing]
+        #Dragon griefing - 2 is no griefing, 1 is breaking weak blocks, 0 is default
+        #Range: 0 ~ 2
+        "Dragon Griefing" = 2
+        #True if tamed dragons can follow the griefing rules.
+        "Tamed Dragon Griefing" = false
+        #The percentage chance for a block to drop as an item when a dragon breaks it.
+        #Range: 0.0 ~ 1.0
+        "Dragon Block Breaking Drop Chance" = 0.10000000149011612
+        #Blocks that a dragon cannot break. Use the format like "minecraft:chest" or "rats:block_of_cheese" 
+        blacklistedBreakBlocks = []
+        #Blocks that a dragon can break, but won't spawn drops for. Use the format like "minecraft:stone" or "rats:block_of_cheese" 
+        noDropBreakBlocks = ["minecraft:stone", "minecraft:dirt", "minecraft:grass_block"]
+
+    [Dragons.Attributes]
+        #How long it takes(in ticks) for a dragon egg to hatch
+        #Range: > 1
+        "Dragon Egg Hatch Time" = 7200
+        #Dragon Flap Noise Distance - Larger number, further away you can hear it
+        #Range: 0 ~ 10000
+        "Dragon Flap Noise Distance" = 4
+        #Dragon Flute Distance - how many chunks away is the dragon flute effective?
+        #Range: 0 ~ 10000
+        "Dragon Flute Distance" = 4
+        #Max dragon health. Health is scaled to this
+        #Range: 1.0 ~ 100000.0
+        "Dragon Health" = 500.0
+        #Max dragon attack damage. Attack Damage is scaled to this
+        #Range: 1 ~ 10000
+        "Dragon Attack Damage" = 17
+        #Damage dealt from a successful fire breath attack. Attack Damage is scaled to by age, so a stage 5 dragon will deal 5x as much as this number
+        #Range: 0.0 ~ 10000.0
+        "Dragon Attack Damage(Fire breath)" = 2.0
+        #Damage dealt from a successful ice breath attack. Attack Damage is scaled to by age, so a stage 5 dragon will deal 5x as much as this number
+        #Range: 0.0 ~ 10000.0
+        "Dragon Attack Damage(Ice breath)" = 2.5
+        #Damage dealt from a successful lightning breath attack. Attack Damage is scaled to by age, so a stage 5 dragon will deal 5x as much as this number
+        #Range: 0.0 ~ 10000.0
+        "Dragon Attack Damage(Lightning breath)" = 3.5
+        #Change this to slow down or speed up dragon or amphithere flight.
+        #Range: 0.0 ~ 2.0
+        "Dragon Flight Speed Modifier" = 1.0
+        #Enable this if your server is being bombarded with moved wrongly or moved too fast console messages. REQUIRES RESTART!
+        "Dragon Moved Wrongly Error Fix" = false
+
+    [Dragons.Behaviour]
+        #How high dragons can fly, in Y height.
+        #Range: > 100
+        "Max Dragon Flight Height" = 128
+        #How far away dragons will detect gold blocks being destroyed or chests being opened
+        #Range: 0 ~ 10000
+        "Dragon Gold Search Length" = 30
+        #True if dragons can despawn. Note that if this is false there may be SERIOUS lag issues.
+        "Dragons Despawn" = true
+        #True if tamed dragons go to sleep at night.
+        "Tamed Dragons Sleep" = true
+        #True if dragons can break blocks if they get stuck. Turn this off if your dragons randomly explode.
+        "Dragons Dig When Stuck" = true
+        #True if dragons can drop their skull on death.
+        "Dragons Drop Skull" = true
+        #True if dragons can drop their heart on death.
+        "Dragons Drop Heart" = true
+        #True if dragons can drop their blood on death.
+        "Dragons Drop Blood" = true
+        #True if dragons fire/ice charges create secondary explosions that launch blocks everywhere. Turn this to true if you like unfair explosions. Or lag.
+        "Explosive Dragon Breath" = false
+        #How many blocks away can dragons spot potential prey. Note that increasing this could cause lag.
+        #Range: 1 ~ 10000
+        "Dragon Target Search Length" = 128
+        #How many blocks away can dragons wander from their defined "home" position.
+        #Range: 1 ~ 10000
+        "Dragon Wander From Home Distance" = 40
+        #Every interval of this number in ticks, dragon hunger decreases.
+        #Range: 1 ~ 10000
+        "Dragon Hunger Tick Rate" = 3000
+        #Every interval of this number in ticks, dragon allowed to break blocks.
+        #Range: 0 ~ 10000
+        "Dragon Block Break Cooldown" = 5
+        #True if villagers should run away and hide from dragons and other hostile Ice and Fire mobs.
+        "Villagers Fear Dragons" = true
+        #True if animals should run away and hide from dragons and other hostile Ice and Fire mobs.
+        "Animals Fear Dragons" = true
+        #A more intelligent dragon pathfinding system, but is also laggier. Turn this on if you think dragons are too stupid.
+        "Intelligent Dragon Pathfinding" = false
+
+[Mobs]
+
+    [Mobs.Pixies]
+        #True if pixie villages are allowed to spawn
+        "Spawn Pixies" = true
+        #1 out of this number chance per chunk for generation
+        #Range: 1 ~ 10000
+        "Spawn Pixies Chance" = 800
+        #size of pixie villages
+        #Range: 1 ~ 10000
+        "Pixie Village Size" = 5
+        #True if pixies are allowed to steal from players
+        "Pixies Steal Items" = true
+
+    [Mobs.Cyclops]
+        #True if cyclops caves are allowed to spawn
+        "Spawn Cyclopes Caves" = true
+        #1 out of this number chance per chunk for generation
+        #Range: 1 ~ 10000
+        "Spawn Cyclops Cave Chance" = 1000
+        #True if wandering cyclopes are allowed to spawn
+        "Spawn Wandering Cyclopes" = true
+        #1 out of this number chance per chunk for generation
+        #Range: 1 ~ 10000
+        "Spawn Wandering Cyclops Chance" = 300
+        #Maximum cyclops health
+        #Range: 1.0 ~ 10000.0
+        "Cyclops Max Health" = 150.0
+        #How many blocks away can cyclopes detect sheep. Note that increasing this could cause lag.
+        #Range: 1 ~ 10000
+        "Cyclopes Sheep Search Length" = 17
+        #Cyclops attack strength
+        #Range: 1.0 ~ 10000.0
+        "Cyclops Attack Strength" = 15.0
+        #Amount of damage done with cyclops bite attack.
+        #Range: 1.0 ~ 10000.0
+        "Cyclops Bite Strength" = 40.0
+        #Whether or not cyclops can break logs or leaves in their way
+        "Cyclops Griefing" = false
+
+    [Mobs.Sirens]
+        #Maximum siren health
+        #Range: 1.0 ~ 10000.0
+        "Siren Max Health" = 50.0
+        #True if siren islands are allowed to spawn
+        "Spawn Sirens" = true
+        #True to make the screen pink when sirens attract players
+        "Use Siren Shader" = true
+        #1 out of this number chance per chunk for generation
+        #Range: 1 ~ 10000
+        "Spawn Sirens Chance" = 400
+        #how long(in ticks) can a siren use its sing effect on a player, without a cooldown.
+        #Range: 100 ~ 24000
+        "Siren Max Sing Time" = 12000
+        #how long(in ticks) a siren has to wait after failing to lure in a player
+        #Range: 100 ~ 24000
+        "Siren Time Between Songs" = 2000
+
+    [Mobs.DeathWorms]
+        #How many blocks away can death worms spot potential prey. Note that increasing this could cause lag
+        #Range: 1 ~ 10000
+        "Death Worm Target Search Length" = 64
+        #Default deathworm health, this is scaled to the worm's particular size
+        #Range: 1.0 ~ 10000.0
+        "Death Worm Base Health" = 10.0
+        #Default deathworm attack strength, this is scaled to the worm's particular size
+        #Range: 1.0 ~ 10000.0
+        "Death Worm Base Attack Strength" = 3.0
+        #True if deathworms are allowed to spawn
+        "Spawn Death Worms" = true
+        #True if wild deathworms are allowed to target and attack monsters
+        "Death Worms Target Monsters" = true
+        #Deathworm spawn weight. Higher = lower chance to spawn
+        #Range: 1 ~ 10000
+        "Death Worm Spawn Weight" = 100
+        #A double check to see if the game can spawn death worms. Higher number = lower chance to spawn.
+        #Range: 0 ~ 10000
+        "Death Worm Spawn Check Chance" = 3
+
+    [Mobs.Cockatrice]
+        #Maximum cockatrice health
+        #Range: 1.0 ~ 10000.0
+        "Cockatrice Health" = 40.0
+        #1 out of this number chance per 6000 ticks for a chicken to lay a cockatrice egg.
+        #Range: > 1
+        "Cockatrice chicken Search Length" = 30
+        #True if chickens lay rotten eggs.
+        "Chickens Lay Rotten Eggs" = true
+        #True if cockatrices are allowed to spawn
+        "Spawn Cockatrices" = true
+        #Cockatrice spawn weight. Lower = lower chance to spawn
+        #Range: 1 ~ 10000
+        "Cockatrice Spawn Weight" = 4
+        #A double check to see if the game can spawn cockatrices. Higher number = lower chance to spawn.
+        #Range: 0 ~ 10000
+        "Cockatrice Spawn Check Chance" = 1000
+
+    [Mobs.Stymphalians]
+        #How many blocks away can stymphalian birds spot potential prey. Note that increasing this could cause lag.
+        #Range: 1 ~ 10000
+        "Stymphalian Bird Target Search Length" = 64
+        #1/this number chance for a stymphalian feather to turn into an item before despawning. Zero means never.
+        #Range: 0 ~ 10000
+        "Stymphalian Bird Feather Drop Chance" = 25
+        #Stymphalian bird feather attack strength.
+        #Range: 0.0 ~ 10000.0
+        "Stymphalian Bird Feather Attack Strength" = 1.0
+        #How far away stymphalian birds will consider other birds to be in the same flock.
+        #Range: 1 ~ 10000
+        "Stymphalian Bird Flock Length" = 40
+        #How high stymphalian birds can fly, in Y height.
+        #Range: > 10
+        "Max Stymphalian Bird Flight Height" = 80
+        #True if stymphalian birds are allowed to spawn
+        "Spawn Stymphalian Birds" = true
+        #True if stymphalian birds can drop items registered in the ore dictionary to ingotCopper, ingotBronze, nuggetCopper, nuggetBronze.
+        "Stymphalian Birds drop ore dict items" = true
+        #True if stymphalian birds are allowed to target and attack animals
+        "Stymphalian Birds Target Animals" = false
+        #1 out of this number chance per chunk for generation
+        #Range: 1 ~ 10000
+        "Spawn Stymhphalian Bird Chance" = 500
+
+    [Mobs.Trolls]
+        #True if trolls are allowed to spawn
+        "Spawn Trolls" = true
+        #True if trolls are allowed to drop their weapon on death.
+        "Trolls Drop Weapon" = true
+        #Troll spawn weight. Lower = lower chance to spawn
+        #Range: 1 ~ 10000
+        "Troll Spawn Weight" = 40
+        #A double check to see if the game can spawn trolls. Higher number = lower chance to spawn.
+        #Range: 0 ~ 10000
+        "Troll Spawn Check Chance" = 10
+        #Maximum troll health
+        #Range: 1.0 ~ 10000.0
+        "Troll Max Health" = 50.0
+        #Troll attack strength
+        #Range: 1.0 ~ 10000.0
+        "Troll Attack Strength" = 10.0
+
+    [Mobs.Myrmex]
+        #True if myrmex colonies are allowed to spawn
+        "Spawn Myrmex" = true
+        #How many ticks it takes for a Myrmex Queen to produce an egg.
+        #Range: 1 ~ 10000
+        "Myrmex Gestation Length" = 2500
+        #How many ticks it takes for a Myrmex to move from a larva to a pupa, and from a pupa to an adult.
+        #Range: 1 ~ 100000
+        "Myrmex Hatch Length" = 35000
+        #One out of this number chance per chunk to generate a myrmex hive.
+        #Range: 1 ~ 10000
+        "Myrmex Colony Gen Chance" = 1500
+        #How many maximum individuals a myrmex colony can have.
+        #Range: 10 ~ 10000
+        "Myrmex Colony Max Size" = 80
+        #Base Myrmex(worker) attack strength
+        #Range: 1.0 ~ 10000.0
+        "Myrmex Base Attack Strength" = 3.0
+        #The maximum radius myrmex area allowed to wander/forage
+        #Range: 100 ~ 20000
+        "Myrmex Maximum Wnader Radius" = 4000
+
+    [Mobs.Amphitheres]
+        #True if amphitheres are allowed to spawn
+        "Spawn Amphitheres" = true
+        #Amphithere spawn weight. Lower = lower chance to spawn
+        #Range: 1 ~ 10000
+        "Amphithere Spawn Weight" = 50
+        #How many blocks away can ampitheres detect villagers being hurt. Note that increasing this could cause lag.
+        #Range: 1 ~ 10000
+        "Amphithere Villager Search Length" = 64
+        #How many ticks it takes while riding an untamed amphithere to tame it.
+        #Range: 1 ~ 10000
+        "Amphithere Tame Time" = 400
+        #How fast amphitheres fly.
+        #Range: 0.0 ~ 3.0
+        "Amphithere Flight Speed" = 1.75
+        #Maximum amphithere health
+        #Range: 1.0 ~ 10000.0
+        "Amphithere Max Health" = 50.0
+        #Amphithere attack strength
+        #Range: 1.0 ~ 10000.0
+        "Amphithere Attack Strength" = 7.0
+
+    [Mobs.SeaSerpents]
+        #True if sea serpents are allowed to spawn
+        "Spawn Sea Serpents" = true
+        #1 out of this number chance per chunk for generation
+        #Range: 1 ~ 10000
+        "Spawn Sea Serpent Chance" = 2500
+        #Whether or not sea serpents can break weak blocks in their way
+        "Sea Serpent Griefing" = false
+        #Default sea serpent health, this is scaled to the sea serpent's particular size
+        #Range: 1.0 ~ 10000.0
+        "Sea Serpent Base Health" = 20.0
+        #Default sea serpent attack strength, this is scaled to the sea serpent's particular size
+        #Range: 1.0 ~ 10000.0
+        "Sea Serpent Base Attack Strength" = 4.0
+
+    [Mobs.Hippocampus]
+        #True if hippocampi are allowed to spawn
+        "Spawn Hippocampus" = true
+        #1 out of this number chance per chunk for generation
+        #Range: 1 ~ 10000
+        "Spawn Hippocampus Chance" = 200
+        #Change this to slow down or speed up hippocampus swimming.
+        #Range: 0.0 ~ 2.0
+        "Hippocampus Swim Speed Modifier" = 1.0
+
+    [Mobs.Hippogryph]
+        #True if hippogryphs are allowed to spawn
+        "Spawn Hippogryphs" = true
+        #Hippogryph spawn weight. Lower = lower chance to spawn.
+        #Range: 1 ~ 10000
+        "Hippogryph Spawn Weight" = 1
+        #Change this to slow down or speed up hippogryph flight.
+        #Range: 0.0 ~ 2.0
+        "Hippogryph Flight Speed Modifier" = 1.0
+
+    [Mobs.Gorgons]
+        #True if gorgon temples are allowed to spawn
+        "Spawn Gorgons" = true
+        #1 out of this number chance per chunk for generation
+        #Range: 1 ~ 10000
+        "Spawn Gorgon Chance" = 10000
+        #Maximum gorgon health
+        #Range: 1.0 ~ 10000.0
+        "Gorgon Max Health" = 100.0
+
+    [Mobs.Others]
+        #True if dread liches are allowed to spawn
+        "Spawn Liches" = true
+        #Dread Lich spawn weight. Lower = lower chance to spawn
+        #Range: 1 ~ 10000
+        "Lich Spawn Weight" = 2
+        #Maximum hydra health
+        #Range: 1.0 ~ 10000.0
+        "Hydra Max Health" = 250.0
+        #True if hydra caves are allowed to generate
+        "Generate Hydra Caves" = true
+        #One out of this number chance per chunk to generate a hydra cave.
+        #Range: 1 ~ 10000
+        "Hydra Caves Gen Chance" = 1000
+        #Maximum ghost health.
+        #Range: 1.0 ~ 10000.0
+        "Ghost Max Health" = 30.0
+        #Maximum ghost attack strength.
+        #Range: 0.0 ~ 10000.0
+        "Ghost Attack Strength" = 3.0
+        #True if ghosts can rarely spawn from brutal PvP deaths.
+        "Ghost Spawn from PvP deaths" = true
+        #Villager Scribe House generation weight. Lower = lower chance to spawn
+        #Range: 30 ~ 10000
+        "Villager Scribe House Weight" = 30
+
+[Items]
+    #Default attack strength of a dragonsteel sword.
+    #Range: 5.0 ~ 2.147483647E9
+    "Dragonsteel Sword Base Attack Strength" = 25.0
+    #Default armor value of dragonsteel chestplate.
+    #Range: > 7
+    "Dragonsteel Base Armor" = 12
+    #Default durability value of dragonsteel tools.
+    #Range: > 1
+    "Dragonsteel Base Durability" = 8000
+    #Default durability value of dragonsteel equipment.
+    #Range: > 1
+    "Dragonsteel Base Durability Equipment" = 8000
+    #Disable this to remove easter egg with tinkers installed.
+    Weezer = true
+    #Percentage of critical strike that will disarm with easter egg tinkers material.
+    #Range: 0.0 ~ 1.0
+    "Easter Egg Tinkers Tool Disarm chance" = 0.20000000298023224
+    #True if the summon crystal can load chunks to find dragons.
+    "Chunk Load Summon Crystal" = true
+    #True if the dragon bone fire sword ignites attackers.
+    "Dragon Bone Fire Abilities" = true
+    #True if the dragon bone ice sword freezes attackers.
+    "Dragon Bone Ice Abilities" = true
+    #True if the dragon bone lightning sword strikes attackers.
+    "Dragon Bone Lightning Abilities" = true
+
+[Pathfinding]
+    #Maximum threads to use for dragon/myrmex pathfinding. Increase this number if pathing is slow and you have many cores.
+    #Range: > 1
+    "Dragon Pathfinding Threads" = 3
+    #Maximum nodes for dragons/myrmex to path too. Decrease this is dragon pathfinding is super slow or intensive.
+    #Range: > 1
+    "Dragon Max Pathfinding Nodes" = 5000
 

From 196ad863c4e989a524a5bddf56f02f46a6c03aba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 20 Aug 2021 23:21:30 +0100
Subject: [PATCH 018/212] Update supplementaries config

---
 .../config/supplementaries-registry.toml      | 31 ++++++++++---------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/configuration/services/configs/minecraft/voor-kia/config/supplementaries-registry.toml b/configuration/services/configs/minecraft/voor-kia/config/supplementaries-registry.toml
index a53af66..f38da67 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/supplementaries-registry.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/supplementaries-registry.toml
@@ -1,18 +1,17 @@
+#Here are configs that need reloading to take effect
+[initialization]
 
-#all these don't actually disable blocks anymore, they just remove their recipe and remove them from the creative tabs(like all other mods do)
-#to access server configuration go into /saves/serverconfigs
-[general]
-    #enable creative tab
-    creative_tab = false
-    #set to false to disable custom dispenser behaviors (filling jars) if for some reason they are causing trouble
-    dispensers = true
-    #creates a creative tab full of filled jars
-    jar_tab = false
+    [initialization.general]
+        #Enable Creative Tab
+        creative_tab = false
+        #Set to false to disable custom dispenser behaviors (i.e: filling jars) if for some reason they are causing trouble
+        dispensers = true
+        #Creates a creative tab full of filled jars
+        jar_tab = false
+        #Enables custom Configured config screen
+        custom_configured_screen = true
 
-#Enable and disable blocks / entities
-[registration]
-
-    [registration.blocks]
+    [initialization.blocks]
         planter = true
         clock_block = false
         pedestal = true
@@ -62,9 +61,13 @@
         bomb = true
         crimson_lantern = true
         magma_cream_block = true
+        goblet = true
+        raked_gravel = true
+        statue = true
+        iron_gate = true
         #WIP
         laser_block = false
         flag = false
 
-    [registration.entities]
+    [initialization.entities]
         firefly = true

From 544036d4e4272436d0f606b35ca4f2e65e641745 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 20 Aug 2021 23:38:45 +0100
Subject: [PATCH 019/212] Update miscellaneous minecraft configs

Largely sensible changes, no complete rewrites without taking user
configuration into account like ice and fire.
---
 .../minecraft/voor-kia/config/alexsmobs.toml  |  301 +++--
 .../voor-kia/config/apotheosis/deadly.cfg     |  225 +---
 .../config/apotheosis/enchantments.cfg        |   45 +
 .../voor-kia/config/apotheosis/names.cfg      |  137 +--
 .../voor-kia/config/apotheosis/village.cfg    |    6 +-
 .../voor-kia/config/appleskin-client.toml     |    9 +
 .../voor-kia/config/artifacts-common.toml     |   56 +-
 .../voor-kia/config/attributefix-common.toml  |  239 +---
 .../voor-kia/config/betterburning-common.toml |   16 +-
 .../voor-kia/config/byg/byg-world.toml        |  109 +-
 .../voor-kia/config/citadel-common.toml       |    3 +
 .../config/cookingforblockheads-common.toml   |    3 +
 .../config/cosmeticarmorreworked-common.toml  |    4 +
 .../voor-kia/config/create-common.toml        |  220 ++--
 .../voor-kia/config/ironfurnaces.toml         |   16 +-
 .../voor-kia/config/jeresources-common.toml   |    1 +
 .../voor-kia/config/jeresources.toml          |    1 +
 .../voor-kia/config/pamhc2crops.toml          |    6 +-
 .../voor-kia/config/pamhc2trees.toml          |    6 -
 .../voor-kia/config/performant-common.toml    |   25 +-
 .../voor-kia/config/quark-common.toml         | 1076 ++++++++---------
 .../voor-kia/config/snowrealmagic-common.toml |    7 +
 .../the_bumblezone-mod_compatibility.toml     |   48 +-
 .../config/travelersbackpack-common.toml      |    1 +
 .../defaultconfigs/solcarrot-server.toml      |   18 +-
 25 files changed, 1226 insertions(+), 1352 deletions(-)

diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs.toml b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs.toml
index 88c5b8a..0226397 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs.toml
@@ -4,6 +4,12 @@
 	polarBearsAttackSeals = true
 	#Whether bone serpents are neutral or hostile.
 	neutralBoneSerpents = false
+	#Makes eagles teleport back to their owner if they get stuck during controlled flight. Useful for when playing with the Optifine mod, since this mod is the fault of many issues with the falconry system.
+	falconryTeleportsBack = false
+	#List of dimensions in which spawning void worms via mysterious worm items is allowed.
+	voidWormSpawnDimensions = ["minecraft:the_end"]
+	#True if straddleboard enchants are enabled.
+	straddleboardEnchants = true
 	#Whether Crimson Mosquitoes can transform into Warped Moscos if attacking a Mungus or any listed creature.
 	warpedMoscoTransformation = true
 	#Whether wild raccoons steal food from chests.
@@ -29,8 +35,19 @@
 	#0 = no mungus biome transformation. 1 = mungus changes blocks, but not chunk's biome. 2 = mungus transforms blocks and biome of chunk.
 	#Range: 0 ~ 2
 	mungusBiomeTransformationType = 2
+	#Max Health of the void worm boss.
+	#Range: 0.0 ~ 1000000.0
+	voidWormMaxHealth = 160.0
+	#All void worm damage is scaled to this.
+	#Range: 0.0 ~ 100.0
+	voidWormDamageModifier = 1.0
+	#Whether the void worm boss is summonable or not, via the mysterious worm item.
+	voidWormSummonable = true
 	#List of all mungus mushrooms, biome transformations and surface blocks. Each is seperated by a |. Add an entry with a block registry name, biome registry name, and block registry name(for the ground).
 	mungusBiomeMatches = ["minecraft:red_mushroom|minecraft:mushroom_fields|minecraft:mycelium", "minecraft:brown_mushroom|minecraft:mushroom_fields|minecraft:mycelium", "minecraft:crimson_fungus|minecraft:crimson_forest|minecraft:crimson_nylium", "minecraft:warped_fungus|minecraft:warped_forest|minecraft:warped_nylium"]
+	#Percent chance for leafcutter ants to break leaves blocks when harvesting. Set to zero so that they can not break any blocks.
+	#Range: 0.0 ~ 1.0
+	leafcutterAntBreakLeavesChance = 0.2
 	#Whether to disable certain aspects of the Lava Vision Potion. Enable if issues with shaders persist.
 	shadersCompat = false
 	#List of extra(non mungus) mobs that will trigger a crimson mosquito to become a warped mosquito. Ex: "minecraft:mooshroom", "alexsmobs:warped_toad"
@@ -38,14 +55,27 @@
 	#1 out of this number chance for leaves to drop a banana when broken. Fortune is automatically factored in
 	#Range: > 0
 	bananaChance = 200
+	#Max number of ant entities allowed inside a leafcutter anthill.
+	#Range: 2 ~ 100000
+	leafcutterAntColonySize = 20
 	#Whether soul vulture spawns should be restricted solely to the nether fossil structure or to whatever biome is specified in their respective biome config.
 	soulVultureSpawnOnFossil = true
+	#Makes Tarantula Hawks fireproof, perfect if you also want these guys to spawn in the nether.
+	fireproofTarantulaHawk = false
+	#Percent chance for fungus to grow per each leaf a leafcutter ant returns to the colony.
+	#Range: 0.0 ~ 1.0
+	leafcutterAntFungusGrowChance = 0.3
 	#Whether fish oil gives players a special levitation effect.
 	fishOilMeme = true
 	#Whether mimicubes spawns should be restricted solely to the end city structure or to whatever biome is specified in their respective biome config.
 	mimicubeSpawnInEndCity = true
 	#Whether bananas should drop from blocks tagged with #alexsmobs:drops_bananas
 	bananasDropFromLeaves = true
+	#Relative volume of cachalot whales compared to other animals. Note that irl they are the loudest animal. Turn this down if you find their clicks annoying.
+	#Range: 0.0 ~ 10.0
+	cachalotVolume = 3.0
+	#Whether emu should target skeletons.
+	emuTargetSkeletons = true
 	#Lava Opacity for the Lava Vision Potion.
 	#Range: 0.01 ~ 1.0
 	lavaVisionOpacity = 0.65
@@ -53,6 +83,12 @@
 	spidersAttackFlies = true
 	#Whether wolves should target moose mobs.
 	wolvesAttackMoose = true
+	#Percent chance for emu leggings to dodge projectile attacks.
+	#Range: 0.0 ~ 1.0
+	emuPantsDodgeChance = 0.45
+	#How many feedings of leaves does a leafcutter colony need in order to regain a worker ant, if below half the max members.
+	#Range: 2 ~ 100000
+	leafcutterAntRepopulateFeedings = 25
 	#Whether wandering traders offer items like acacia blossoms, mosquito larva, crocodile egg, etc.
 	wanderingTraderOffers = true
 
@@ -63,12 +99,9 @@
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
 		alligatorSnappingTurtleSpawnRolls = 1
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		straddlerSpawnWeight = 85
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		hummingbirdSpawnWeight = 39
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		frilledSharkSpawnRolls = 0
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
 		stradpoleSpawnRolls = 3
@@ -77,28 +110,13 @@
 		mantisShrimpSpawnWeight = 15
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
-		roadrunnerSpawnRolls = 1
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
 		lobsterSpawnRolls = 0
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
-		gusterSpawnWeight = 35
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		endergradeSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		elephantSpawnWeight = 30
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
 		spectreSpawnWeight = 10
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
 		endergradeSpawnWeight = 10
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		hammerheadSharkSpawnWeight = 8
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
 		sealSpawnRolls = 0
@@ -107,13 +125,7 @@
 		sunbirdSpawnRolls = 15
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
-		straddlerSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
 		shoebillSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		gazelleSpawnRolls = 0
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
 		sunbirdSpawnWeight = 2
@@ -122,49 +134,25 @@
 		raccoonSpawnWeight = 10
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
-		mantisShrimpSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		mungusSpawnWeight = 4
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
 		mungusSpawnRolls = 1
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		crocSpawnRolls = 1
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
 		mimicubeSpawnWeight = 40
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
 		blobfishSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		stradpoleSpawnWeight = 10
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		mooseSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		spectreSpawnRolls = 5
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		caveCentipedeSpawnRolls = 1
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
 		crowSpawnRolls = 0
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
-		grizzlyBearSpawnWeight = 8
+		tasmanianDevilSpawnWeight = 10
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
-		blobfishSpawnWeight = 30
+		grizzlyBearSpawnWeight = 8
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
 		elephantSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		raccoonSpawnRolls = 0
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
 		caveCentipedeSpawnWeight = 8
@@ -173,28 +161,22 @@
 		shoebillSpawnWeight = 10
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
-		warpedToadSpawnWeight = 80
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		crowSpawnWeight = 10
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
 		sealSpawnWeight = 30
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
-		komodoDragonSpawnWeight = 4
+		baldEagleSpawnWeight = 15
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
-		flySpawnWeight = 3
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		snowLeopardSpawnRolls = 0
+		kangarooSpawnWeight = 25
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
 		rattlesnakeSpawnWeight = 12
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
 		soulVultureSpawnWeight = 30
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		enderiophageSpawnRolls = 2
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
 		mooseSpawnWeight = 15
@@ -203,18 +185,15 @@
 		warpedMoscoSpawnRolls = 1000
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
-		komodoDragonSpawnRolls = 1
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		crocodileSpawnWeight = 40
+		platypusSpawnRolls = 0
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		tarantulaHawkSpawnRolls = 1
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
 		soulVultureSpawnRolls = 0
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
-		gusterSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
 		orcaSpawnRolls = 6
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
@@ -228,9 +207,6 @@
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
 		mimicubeSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		cockroachSpawnRolls = 0
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn. NOTE: By default the warped mosco doesn't spawn in any biomes.
 		#Range: 0 ~ 1000
 		warpedMoscoSpawnWeight = 1
@@ -240,24 +216,15 @@
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
 		gazelleSpawnWeight = 40
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		rattlesnakeSpawnRolls = 0
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
 		gorillaSpawnWeight = 50
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		roadrunnerSpawnWeight = 15
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
 		flySpawnRolls = 1
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
-		lobsterSpawnWeight = 7
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		capuchinMonkeySpawnRolls = 0
+		platypusSpawnWeight = 30
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
 		warpedToadSpawnRolls = 0
@@ -270,6 +237,156 @@
 		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
 		#Range: 0 ~ 1000
 		orcaSpawnWeight = 2
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		mimicOctopusSpawnWeight = 9
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		tigerSpawnRolls = 0
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		dropbearSpawnRolls = 1
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		crimsonMosquitoSpawnWeight = 15
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		straddlerSpawnWeight = 85
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		hummingbirdSpawnWeight = 39
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		roadrunnerSpawnRolls = 1
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		gusterSpawnWeight = 35
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		endergradeSpawnRolls = 0
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		elephantSpawnWeight = 30
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		tasmanianDevilSpawnRolls = 0
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		hammerheadSharkSpawnWeight = 8
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		straddlerSpawnRolls = 0
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		voidWormSpawnRolls = 0
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		gazelleSpawnRolls = 0
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		mantisShrimpSpawnRolls = 0
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		mungusSpawnWeight = 4
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		voidWormSpawnWeight = 0
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		crocSpawnRolls = 1
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		stradpoleSpawnWeight = 10
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		mooseSpawnRolls = 0
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		spectreSpawnRolls = 5
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		caveCentipedeSpawnRolls = 1
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		blobfishSpawnWeight = 30
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		baldEagleSpawnRolls = 0
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		tigerSpawnWeight = 100
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		raccoonSpawnRolls = 0
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		warpedToadSpawnWeight = 80
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		frilledSharkSpawnWeight = 11
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		emuSpawnWeight = 20
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		kangarooSpawnRolls = 0
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		crowSpawnWeight = 10
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		mimicOctopusSpawnRolls = 0
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		komodoDragonSpawnWeight = 4
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		flySpawnWeight = 3
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		snowLeopardSpawnRolls = 0
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		cachalotWhaleSpawnRolls = 0
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		cachalotWhaleSpawnWeight = 2
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		komodoDragonSpawnRolls = 1
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		emuSpawnRolls = 0
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		tarantulaHawkSpawnWeight = 6
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		crocodileSpawnWeight = 40
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		gusterSpawnRolls = 0
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		cockroachSpawnRolls = 0
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		rattlesnakeSpawnRolls = 0
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		roadrunnerSpawnWeight = 15
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		lobsterSpawnWeight = 7
+		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
+		#Range: > 0
+		capuchinMonkeySpawnRolls = 0
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		dropbearSpawnWeight = 19
+		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
+		#Range: 0 ~ 1000
+		enderiophageSpawnWeight = 4
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
 		hummingbirdSpawnRolls = 1
@@ -282,7 +399,17 @@
 		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
 		#Range: > 0
 		hammerheadSharkSpawnRolls = 1
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		crimsonMosquitoSpawnWeight = 15
+
+		[general.spawning.uniqueSpawning]
+			#Delay (in ticks) between attempts to spawn beached cachalot whales. Default is a single day. Works like wandering traders.
+			#Range: > 0
+			beachedCachalotWhaleSpawnDelay = 24000
+			#Percent chance for leafcutter anthills to spawn as world gen in each chunk. Set to zero to disable spawning.
+			#Range: 0.0 ~ 1.0
+			leafcutterAnthillSpawnChance = 0.004999999888241291
+			#Whether to enable beached cachalot whales to spawn on beaches during thunder storms.
+			beachedCachalotWhales = true
+			#Percent chance increase for each failed attempt to spawn a beached cachalot whale. Higher value = more spawns.
+			#Range: 0 ~ 100
+			beachedCachalotWhaleSpawnChance = 5
 
diff --git a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/deadly.cfg b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/deadly.cfg
index 643a089..8b1b5e8 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/deadly.cfg
+++ b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/deadly.cfg
@@ -1,24 +1,22 @@
 # Configuration file
 
 affixes {
-    # The 1/n chance that a naturally spawned mob will be granted an affix item. [range: 1 ~ 500000, default: 250]
+    # A list of type overrides for the affix loot system.  Format is <itemname>|<type>.  Types are SWORD, RANGED, PICKAXE, SHOVEL, AXE, SHIELD [default: [minecraft:stick|SWORD]]
+    S:"Equipment Type Overrides" <
+        minecraft:stick|SWORD
+     >
+
+    # The 1/n chance that a naturally spawned mob will be granted an affix item. 0 to disable. [range: 0 ~ 500000, default: 125]
     I:"Random Affix Chance"=250
 }
 
 
 bosses {
-    # A list of potions (registry names) that bosses cannot generate with. [default: [forbidden_arcanus:spectral_vision]]
     S:"Blacklisted Potions" <
         forbidden_arcanus:spectral_vision
      >
-
-    # The block that spawns in a 5x5 underneath world-generated bosses. [default: minecraft:red_sandstone]
     S:"Boss Filler Block"=minecraft:red_sandstone
-
-    # The rarity offset for boss item generation.  400 guarantees uncommon, 700 guarantees rare, 800 guarantees epic, 950 guarantees mythic. [range: 0 ~ 999, default: 475]
     I:"Boss Rarity Offset"=475
-
-    # The possible mob types for bosses.  Format is weight@entity, entity is a registry name. [default: [3@minecraft:zombie], [3@minecraft:skeleton], [2@minecraft:husk], [2@minecraft:stray], [1@minecraft:wither_skeleton], [1@minecraft:pillager]]
     S:"Boss Spawner Mobs" <
         3@minecraft:zombie
         3@minecraft:skeleton
@@ -27,65 +25,32 @@ bosses {
         1@minecraft:wither_skeleton
         1@minecraft:pillager
      >
-
-    # The percent chance a boss has fire resistance. [range: 0.0 ~ 3.4028235E38, default: 1.0]
     S:"Fire Resistance"=1.0
-
-    # The max amount of extra damage bosses do, in half hearts. [range: 0.0 ~ 2.14748365E9, default: 4.5]
     S:"Max Damage Bonus"=4.5
-
-    # The max amount boss health is multiplied by.  Base hp * factor = final hp. [range: 0.0 ~ 2.14748365E9, default: 8.0]
     S:"Max Health Multiplier"=8.0
-
-    # The max amount of knockback resist bosses have. [range: 0.0 ~ 2.14748365E9, default: 1.0]
     S:"Max Knockback Resist"=1.0
-
-    # The max regeneration level of bosses. [range: 0 ~ 2147483647, default: 2]
     I:"Max Regen Level"=2
-
-    # The max resistance level of bosses. [range: 0 ~ 2147483647, default: 3]
     I:"Max Resistance Level"=3
-
-    # The max amount boss speed is multiplied by.  Base speed * factor = final speed. [range: 0.0 ~ 2.14748365E9, default: 1.4]
     S:"Max Speed Multiplier"=1.4
-
-    # The min amount of extra damage bosses do, in half hearts. [range: 0.0 ~ 2.14748365E9, default: 2.0]
     S:"Min Damage Bonus"=2.0
-
-    # The min amount boss health is multiplied by.  Base hp * factor = final hp. [range: 0.0 ~ 2.14748365E9, default: 4.0]
     S:"Min Health Multiplier"=4.0
-
-    # The min amount of knockback resist bosses have. [range: 0.0 ~ 2.14748365E9, default: 0.65]
     S:"Min Knockback Resist"=0.65
-
-    # The min regeneration level of bosses. [range: 0 ~ 2147483647, default: 0]
     I:"Min Regen Level"=0
-
-    # The min resistance level of bosses. [range: 0 ~ 2147483647, default: 0]
     I:"Min Resistance Level"=0
-
-    # The min amount boss speed is multiplied by.  Base speed * factor = final speed. [range: 0.0 ~ 2.14748365E9, default: 1.1]
     S:"Min Speed Multiplier"=1.1
-
-    # The chance a gear piece will be randomly enchanted. [range: 0.0 ~ 2.14748365E9, default: 0.45]
     S:"Random Enchantment Chance"=0.45
-
-    # The chance a boss will have extra random potion effects. [range: 0.0 ~ 2.14748365E9, default: 0.65]
     S:"Random Potion Chance"=0.65
 
-    # The 1/n chance that a naturally spawned mob that can see the sky is transformed into a boss. [range: 1 ~ 500000, default: 600]
+    # The 1/n chance that a naturally spawned mob that can see the sky is transformed into a boss.  0 to disable. [range: 0 ~ 500000, default: 85]
     I:"Surface Boss Chance"=600
 
     # If a lightning bolt strikes when a surface boss spawn occurs. [default: true]
     B:"Surface Boss Lightning"=true
-
-    # The percent chance a boss has water breathing. [range: 0.0 ~ 3.4028235E38, default: 1.0]
     S:"Water Breathing"=1.0
 }
 
 
 "brutal spawners" {
-    # The potion effects applied to all brutal mobs.  Format is potion@level, potion is a registry name. [default: [minecraft:resistance@2], [minecraft:fire_resistance@1], [minecraft:regeneration@1], [minecraft:speed@2], [minecraft:water_breathing@1], [minecraft:strength@1]]
     S:"Brutal Potion Effects" <
         minecraft:resistance@2
         minecraft:fire_resistance@1
@@ -94,8 +59,6 @@ bosses {
         minecraft:water_breathing@1
         minecraft:strength@1
      >
-
-    # The possible spawn entries for brutal spawners.  Format is weight@entity, entity is a registry name.  apotheosis:random is a special name, used to generate a spawner that spawns any mob. [default: [3@minecraft:zombie], [3@minecraft:skeleton], [2@minecraft:husk], [2@minecraft:stray], [1@minecraft:spider]]
     S:"Brutal Spawner Mobs" <
         3@minecraft:zombie
         3@minecraft:skeleton
@@ -107,17 +70,30 @@ bosses {
 
 
 frequencies {
-    # The chance (per chunk) for a boss to try spawning. [range: 0.0 ~ 1.0, default: 0.07]
     S:"Boss Chance"=0.07
-
-    # The chance (per chunk) for a brutal spawner to try spawning. [range: 0.0 ~ 1.0, default: 0.18]
     S:"Brutal Spawner Chance"=0.18
-
-    # The chance (per chunk) for a swarm spawner to try spawning. [range: 0.0 ~ 1.0, default: 0.2]
     S:"Swarm Spawner Chance"=0.2
 }
 
 
+frequency {
+    # The number of generation attempts (per chunk) for boss dungeons. [range: 0 ~ 50000, default: 8]
+    I:"Boss Dungeon"=8
+
+    # The number of generation attempts (per chunk) for boss dungeon variant 2. [range: 0 ~ 50000, default: 8]
+    I:"Boss Dungeon Variant 2"=8
+
+    # The number of generation attempts (per chunk) for ore troves. [range: 0 ~ 50000, default: 8]
+    I:"Ore Troves"=8
+
+    # The number of generation attempts (per chunk) for rogue spawners. [range: 0 ~ 50000, default: 4]
+    I:"Rogue Spawners"=4
+
+    # The 1/n chance (per chunk) that a tome tower may attempt generation. 0 = disabled, lower = more chances. [range: 0 ~ 50000, default: 125]
+    I:"Tome Tower"=125
+}
+
+
 general {
     # The biomes that the deadly module will not generate in. [default: [minecraft:warm_ocean], [minecraft:lukewarm_ocean], [minecraft:cold_ocean], [minecraft:frozen_ocean], [minecraft:deep_warm_ocean], [minecraft:deep_frozen_ocean], [minecraft:deep_lukewarm_ocean], [minecraft:deep_cold_ocean], [minecraft:ocean], [minecraft:deep_ocean]]
     S:"Generation Biome Blacklist" <
@@ -137,236 +113,97 @@ general {
     S:"Generation Dimension Whitelist" <
         overworld
      >
+
+    # The 1/n chance that a rogue spawner will generate with a CHEST_VALUABLE instead of it's default chest.  0 to disable. [range: 0 ~ 80000, default: 9]
+    I:"Spawner Rare Loot Chance"=9
 }
 
 
 "random spawners" {
-    #  [range: 0 ~ 50, default: 1]
     I:"alexsmobs:bone_serpent"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"alexsmobs:bone_serpent_part"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"alexsmobs:guster"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"alexsmobs:mimicube"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"alexsmobs:soul_vulture"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"alexsmobs:straddler"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"alexsmobs:warped_mosco"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"artifacts:mimic"=1
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:blaze"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:cave_spider"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:creeper"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:drowned"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:elder_guardian"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:ender_dragon"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:enderman"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:endermite"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:evoker"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:ghast"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:giant"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:guardian"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:hoglin"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:husk"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:illusioner"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:magma_cube"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:phantom"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:piglin"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:piglin_brute"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:pillager"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:ravager"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:shulker"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:silverfish"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:skeleton"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:slime"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:spider"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:stray"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:vex"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:vindicator"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:witch"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:wither"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:wither_skeleton"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:zoglin"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:zombie"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:zombie_villager"=8
-
-    #  [range: 0 ~ 50, default: 8]
     I:"minecraft:zombified_piglin"=8
-
-    #  [range: 0 ~ 50, default: 1]
     I:"quark:forgotten"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"quark:wraith"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"quark:wrapped"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"undergarden:brute"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"undergarden:forgotten_guardian"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"undergarden:masticator"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"undergarden:muncher"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"undergarden:nargoyle"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"undergarden:rotbeast"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"undergarden:rotdweller"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"undergarden:rotling"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"undergarden:rotwalker"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"undergarden:sploogie"=1
-
-    #  [range: 0 ~ 50, default: 1]
     I:"undergarden:stoneborn"=1
 }
 
 
 "spawner stats: brutal spawners" {
-    # The maximum delay between spawns [range: 1 ~ 32767, default: 400]
     I:"Max Delay"=400
-
-    # The maximum number of nearby entities (when hit, the spawner turns off). [range: 1 ~ 32767, default: 6]
     I:"Max Nearby Entities"=6
-
-    # The minimum delay between spawns [range: 1 ~ 32767, default: 200]
     I:"Min Delay"=200
-
-    # The required distance a player must be within for this spawner to work. [range: 1 ~ 32767, default: 16]
     I:"Player Range"=16
-
-    # The number of mobs that will spawn. [range: 1 ~ 32767, default: 6]
     I:"Spawn Count"=6
-
-    # The delay before first spawn on this spawner. [range: 1 ~ 32767, default: 20]
     I:"Spawn Delay"=20
-
-    # The spawn range. [range: 1 ~ 32767, default: 4]
     I:"Spawn Range"=4
 }
 
 
 "spawner stats: swarm spawners" {
-    # The maximum delay between spawns [range: 1 ~ 32767, default: 300]
     I:"Max Delay"=300
-
-    # The maximum number of nearby entities (when hit, the spawner turns off). [range: 1 ~ 32767, default: 32]
     I:"Max Nearby Entities"=32
-
-    # The minimum delay between spawns [range: 1 ~ 32767, default: 75]
     I:"Min Delay"=75
-
-    # The required distance a player must be within for this spawner to work. [range: 1 ~ 32767, default: 8]
     I:"Player Range"=8
-
-    # The number of mobs that will spawn. [range: 1 ~ 32767, default: 8]
     I:"Spawn Count"=8
-
-    # The delay before first spawn on this spawner. [range: 1 ~ 32767, default: 20]
     I:"Spawn Delay"=20
-
-    # The spawn range. [range: 1 ~ 32767, default: 6]
     I:"Spawn Range"=6
 }
 
 
 "swarm spawners" {
-    # The possible spawn entries for swarm spawners.  Format is weight@entity, entity is a registry name. [default: [4@minecraft:zombie], [2@minecraft:skeleton], [5@minecraft:spider], [8@minecraft:cave_spider], [1@minecraft:creeper]]
     S:"Swarm Spawner Mobs" <
         4@minecraft:zombie
         2@minecraft:skeleton
@@ -377,3 +214,9 @@ general {
 }
 
 
+wanderer {
+    # If the wandering trader may sell affix loot items as a rare trade. [default: true]
+    B:"Affix Trades"=true
+}
+
+
diff --git a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/enchantments.cfg b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/enchantments.cfg
index 03e565b..0144ba8 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/enchantments.cfg
+++ b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/enchantments.cfg
@@ -375,6 +375,36 @@
 }
 
 
+"create:capacity" {
+    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 7]
+    I:"Max Level"=7
+
+    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
+    S:"Max Power Function"=
+
+    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
+    I:"Min Level"=1
+
+    # A function to determine the min enchanting power. [default: ]
+    S:"Min Power Function"=
+}
+
+
+"create:potato_recovery" {
+    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 7]
+    I:"Max Level"=7
+
+    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
+    S:"Max Power Function"=
+
+    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
+    I:"Min Level"=1
+
+    # A function to determine the min enchanting power. [default: ]
+    S:"Min Power Function"=
+}
+
+
 "minecraft:aqua_affinity" {
     # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
     I:"Max Level"=1
@@ -960,3 +990,18 @@
 }
 
 
+"the_bumblezone:comb_cutter" {
+    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
+    I:"Max Level"=1
+
+    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
+    S:"Max Power Function"=
+
+    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
+    I:"Min Level"=1
+
+    # A function to determine the min enchanting power. [default: ]
+    S:"Min Power Function"=
+}
+
+
diff --git a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/names.cfg b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/names.cfg
index c097ac8..127f4c8 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/names.cfg
+++ b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/names.cfg
@@ -3,14 +3,12 @@
 armors {
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: byg:ametrine_helmet, byg:ametrine_chestplate, byg:ametrine_leggings, byg:ametrine_boots
-    # Repair Material: byg:ametrine_gems
     #  [default: ]
     S:AMETRINE <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: minecraft:chainmail_helmet, minecraft:chainmail_chestplate, minecraft:chainmail_leggings, minecraft:chainmail_boots
-    # Repair Material: minecraft:iron_ingot
     #  [default: [Chainmail], [Chain], [Chain Link], [Scale]]
     S:CHAIN <
         Chainmail
@@ -21,14 +19,18 @@ armors {
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: undergarden:cloggrum_helmet, undergarden:cloggrum_chestplate, undergarden:cloggrum_leggings, undergarden:cloggrum_boots
-    # Repair Material: undergarden:cloggrum_ingot
     #  [default: ]
     S:CLOGGRUM <
      >
 
+    # A list of material-based prefix names for this material group. May be empty.
+    # Items in this group: create:copper_backtank, create:diving_helmet, create:diving_boots
+    #  [default: ]
+    S:COPPER <
+     >
+
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: minecraft:diamond_helmet, minecraft:diamond_chestplate, minecraft:diamond_leggings, minecraft:diamond_boots
-    # Repair Material: minecraft:diamond
     #  [default: [Diamond], [Zircon], [Gemstone], [Jewel], [Crystal]]
     S:DIAMOND <
         Diamond
@@ -40,14 +42,12 @@ armors {
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: undergarden:froststeel_helmet, undergarden:froststeel_chestplate, undergarden:froststeel_leggings, undergarden:froststeel_boots
-    # Repair Material: undergarden:froststeel_ingot
     #  [default: ]
     S:FROSTSTEEL <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: minecraft:golden_helmet, minecraft:golden_chestplate, minecraft:golden_leggings, minecraft:golden_boots
-    # Repair Material: minecraft:gold_ingot
     #  [default: [Golden], [Gold], [Gilt], [Auric], [Ornate]]
     S:GOLD <
         Golden
@@ -59,7 +59,6 @@ armors {
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: minecraft:iron_helmet, minecraft:iron_chestplate, minecraft:iron_leggings, minecraft:iron_boots
-    # Repair Material: minecraft:iron_ingot
     #  [default: [Iron], [Steel], [Ferrous], [Rusty], [Wrought Iron]]
     S:IRON <
         Iron
@@ -70,8 +69,7 @@ armors {
      >
 
     # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: minecraft:leather_helmet, minecraft:leather_chestplate, minecraft:leather_leggings, minecraft:leather_boots, quark:backpack, quark:forgotten_hat
-    # Repair Material: minecraft:leather
+    # Items in this group: minecraft:leather_helmet, minecraft:leather_chestplate, minecraft:leather_leggings, minecraft:leather_boots, quark:forgotten_hat, quark:backpack
     #  [default: [Leather], [Rawhide], [Lamellar], [Cow Skin]]
     S:LEATHER <
         Leather
@@ -82,14 +80,12 @@ armors {
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: undergarden:masticated_chestplate
-    # Repair Material: undergarden:masticator_scales
     #  [default: ]
     S:MASTICATED <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: minecraft:netherite_helmet, minecraft:netherite_chestplate, minecraft:netherite_leggings, minecraft:netherite_boots
-    # Repair Material: minecraft:netherite_ingot
     #  [default: [Burnt], [Embered], [Fiery], [Hellborn], [Flameforged]]
     S:NETHERITE <
         Burnt
@@ -101,7 +97,6 @@ armors {
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: minecraft:turtle_helmet
-    # Repair Material: minecraft:scute
     #  [default: [Tortollan], [Very Tragic], [Environmental], [Organic]]
     S:TURTLE <
         Tortollan
@@ -112,301 +107,276 @@ armors {
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: undergarden:utheric_helmet, undergarden:utheric_chestplate, undergarden:utheric_leggings, undergarden:utheric_boots
-    # Repair Material: undergarden:utherium_ingot
     #  [default: ]
     S:UTHERIC <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: alexsmobs:centipede_leggings
-    # Repair Material: alexsmobs:centipede_leg
     #  [default: ]
     S:alexsmobs_centipede_leggings <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: alexsmobs:crocodile_chestplate
-    # Repair Material: alexsmobs:crocodile_scute
     #  [default: ]
     S:alexsmobs_crocodile_chestplate <
      >
 
+    # A list of material-based prefix names for this material group. May be empty.
+    # Items in this group: alexsmobs:emu_leggings
+    #  [default: ]
+    S:alexsmobs_emu_leggings <
+     >
+
+    # A list of material-based prefix names for this material group. May be empty.
+    # Items in this group: alexsmobs:fedora
+    #  [default: ]
+    S:alexsmobs_fedora <
+     >
+
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: alexsmobs:frontier_cap
-    # Repair Material: alexsmobs:raccoon_tail
     #  [default: ]
     S:alexsmobs_frontier_cap <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: alexsmobs:moose_headgear
-    # Repair Material: alexsmobs:moose_antler
     #  [default: ]
     S:alexsmobs_moose_headgear <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: alexsmobs:roadrunner_boots
-    # Repair Material: alexsmobs:roadrunner_feather
     #  [default: ]
     S:alexsmobs_roadrunner_boots <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: alexsmobs:sombrero
-    # Repair Material: minecraft:hay_block
     #  [default: ]
     S:alexsmobs_sombrero <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: alexsmobs:spiked_turtle_shell
-    # Repair Material: null
     #  [default: ]
     S:alexsmobs_spiked_turtle_shell <
      >
 
+    # A list of material-based prefix names for this material group. May be empty.
+    # Items in this group: alexsmobs:tarantula_hawk_elytra
+    #  [default: ]
+    S:alexsmobs_tarantula_hawk_elytra <
+     >
+
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:armor_amythest_helmet, iceandfire:armor_amythest_chestplate, iceandfire:armor_amythest_leggings, iceandfire:armor_amythest_boots
-    # Repair Material: iceandfire:dragonscales_amythest
     #  [default: ]
     S:iceandfire_armor_amythest_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:armor_black_helmet, iceandfire:armor_black_chestplate, iceandfire:armor_black_leggings, iceandfire:armor_black_boots
-    # Repair Material: iceandfire:dragonscales_black
     #  [default: ]
     S:iceandfire_armor_black_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:armor_blue_helmet, iceandfire:armor_blue_chestplate, iceandfire:armor_blue_leggings, iceandfire:armor_blue_boots
-    # Repair Material: iceandfire:dragonscales_blue
     #  [default: ]
     S:iceandfire_armor_blue_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:armor_bronze_helmet, iceandfire:armor_bronze_chestplate, iceandfire:armor_bronze_leggings, iceandfire:armor_bronze_boots
-    # Repair Material: iceandfire:dragonscales_bronze
     #  [default: ]
     S:iceandfire_armor_bronze_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:armor_copper_helmet, iceandfire:armor_copper_chestplate, iceandfire:armor_copper_leggings, iceandfire:armor_copper_boots
-    # Repair Material: iceandfire:dragonscales_copper
     #  [default: ]
     S:iceandfire_armor_copper_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:armor_copper_metal_helmet, iceandfire:armor_copper_metal_chestplate, iceandfire:armor_copper_metal_leggings, iceandfire:armor_copper_metal_boots
-    # Repair Material: null
     #  [default: ]
     S:iceandfire_armor_copper_metal_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:armor_electric_helmet, iceandfire:armor_electric_chestplate, iceandfire:armor_electric_leggings, iceandfire:armor_electric_boots
-    # Repair Material: iceandfire:dragonscales_electric
     #  [default: ]
     S:iceandfire_armor_electric_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:armor_gray_helmet, iceandfire:armor_gray_chestplate, iceandfire:armor_gray_leggings, iceandfire:armor_gray_boots
-    # Repair Material: iceandfire:dragonscales_gray
     #  [default: ]
     S:iceandfire_armor_gray_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:armor_green_helmet, iceandfire:armor_green_chestplate, iceandfire:armor_green_leggings, iceandfire:armor_green_boots
-    # Repair Material: iceandfire:dragonscales_green
     #  [default: ]
     S:iceandfire_armor_green_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:armor_red_helmet, iceandfire:armor_red_chestplate, iceandfire:armor_red_leggings, iceandfire:armor_red_boots
-    # Repair Material: iceandfire:dragonscales_red
     #  [default: ]
     S:iceandfire_armor_red_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:armor_sapphire_helmet, iceandfire:armor_sapphire_chestplate, iceandfire:armor_sapphire_leggings, iceandfire:armor_sapphire_boots
-    # Repair Material: iceandfire:dragonscales_sapphire
     #  [default: ]
     S:iceandfire_armor_sapphire_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:armor_silver_helmet, iceandfire:armor_silver_chestplate, iceandfire:armor_silver_leggings, iceandfire:armor_silver_boots
-    # Repair Material: iceandfire:dragonscales_silver
     #  [default: ]
     S:iceandfire_armor_silver_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:armor_silver_metal_helmet, iceandfire:armor_silver_metal_chestplate, iceandfire:armor_silver_metal_leggings, iceandfire:armor_silver_metal_boots
-    # Repair Material: iceandfire:silver_ingot
     #  [default: ]
     S:iceandfire_armor_silver_metal_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:armor_white_helmet, iceandfire:armor_white_chestplate, iceandfire:armor_white_leggings, iceandfire:armor_white_boots
-    # Repair Material: iceandfire:dragonscales_white
     #  [default: ]
     S:iceandfire_armor_white_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:blindfold
-    # Repair Material: minecraft:string
     #  [default: ]
     S:iceandfire_blindfold <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:deathworm_red_helmet, iceandfire:deathworm_red_chestplate, iceandfire:deathworm_red_leggings, iceandfire:deathworm_red_boots
-    # Repair Material: iceandfire:deathworm_chitin_white
     #  [default: ]
     S:iceandfire_deathworm_red_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:deathworm_white_helmet, iceandfire:deathworm_white_chestplate, iceandfire:deathworm_white_leggings, iceandfire:deathworm_white_boots
-    # Repair Material: iceandfire:deathworm_chitin_red
     #  [default: ]
     S:iceandfire_deathworm_white_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:deathworm_yellow_helmet, iceandfire:deathworm_yellow_chestplate, iceandfire:deathworm_yellow_leggings, iceandfire:deathworm_yellow_boots
-    # Repair Material: iceandfire:deathworm_chitin_yellow
     #  [default: ]
     S:iceandfire_deathworm_yellow_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:dragonsteel_fire_helmet, iceandfire:dragonsteel_fire_chestplate, iceandfire:dragonsteel_fire_leggings, iceandfire:dragonsteel_fire_boots
-    # Repair Material: iceandfire:dragonsteel_fire_ingot
     #  [default: ]
     S:iceandfire_dragonsteel_fire_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:dragonsteel_ice_helmet, iceandfire:dragonsteel_ice_chestplate, iceandfire:dragonsteel_ice_leggings, iceandfire:dragonsteel_ice_boots
-    # Repair Material: iceandfire:dragonsteel_ice_ingot
     #  [default: ]
     S:iceandfire_dragonsteel_ice_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:dragonsteel_lightning_helmet, iceandfire:dragonsteel_lightning_chestplate, iceandfire:dragonsteel_lightning_leggings, iceandfire:dragonsteel_lightning_boots
-    # Repair Material: iceandfire:dragonsteel_lightning_ingot
     #  [default: ]
     S:iceandfire_dragonsteel_lightning_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:earplugs
-    # Repair Material: minecraft:oak_button
     #  [default: ]
     S:iceandfire_earplugs <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:forest_troll_leather_helmet, iceandfire:forest_troll_leather_chestplate, iceandfire:forest_troll_leather_leggings, iceandfire:forest_troll_leather_boots
-    # Repair Material: iceandfire:troll_leather_forest
     #  [default: ]
     S:iceandfire_forest_troll_leather_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:frost_troll_leather_helmet, iceandfire:frost_troll_leather_chestplate, iceandfire:frost_troll_leather_leggings, iceandfire:frost_troll_leather_boots
-    # Repair Material: iceandfire:troll_leather_frost
     #  [default: ]
     S:iceandfire_frost_troll_leather_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:mountain_troll_leather_helmet, iceandfire:mountain_troll_leather_chestplate, iceandfire:mountain_troll_leather_leggings, iceandfire:mountain_troll_leather_boots
-    # Repair Material: iceandfire:troll_leather_mountain
     #  [default: ]
     S:iceandfire_mountain_troll_leather_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:myrmex_desert_helmet, iceandfire:myrmex_desert_chestplate, iceandfire:myrmex_desert_leggings, iceandfire:myrmex_desert_boots
-    # Repair Material: iceandfire:myrmex_desert_chitin
     #  [default: ]
     S:iceandfire_myrmex_desert_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:myrmex_jungle_helmet, iceandfire:myrmex_jungle_chestplate, iceandfire:myrmex_jungle_leggings, iceandfire:myrmex_jungle_boots
-    # Repair Material: iceandfire:myrmex_jungle_chitin
     #  [default: ]
     S:iceandfire_myrmex_jungle_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:sheep_helmet, iceandfire:sheep_chestplate, iceandfire:sheep_leggings, iceandfire:sheep_boots
-    # Repair Material: minecraft:white_wool
     #  [default: ]
     S:iceandfire_sheep_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:tide_blue_helmet, iceandfire:tide_blue_chestplate, iceandfire:tide_blue_leggings, iceandfire:tide_blue_boots
-    # Repair Material: iceandfire:sea_serpent_scales_blue
     #  [default: ]
     S:iceandfire_tide_blue_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:tide_bronze_helmet, iceandfire:tide_bronze_chestplate, iceandfire:tide_bronze_leggings, iceandfire:tide_bronze_boots
-    # Repair Material: iceandfire:sea_serpent_scales_bronze
     #  [default: ]
     S:iceandfire_tide_bronze_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:tide_deepblue_helmet, iceandfire:tide_deepblue_chestplate, iceandfire:tide_deepblue_leggings, iceandfire:tide_deepblue_boots
-    # Repair Material: iceandfire:sea_serpent_scales_deepblue
     #  [default: ]
     S:iceandfire_tide_deepblue_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:tide_green_helmet, iceandfire:tide_green_chestplate, iceandfire:tide_green_leggings, iceandfire:tide_green_boots
-    # Repair Material: iceandfire:sea_serpent_scales_green
     #  [default: ]
     S:iceandfire_tide_green_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:tide_purple_helmet, iceandfire:tide_purple_chestplate, iceandfire:tide_purple_leggings, iceandfire:tide_purple_boots
-    # Repair Material: iceandfire:sea_serpent_scales_purple
     #  [default: ]
     S:iceandfire_tide_purple_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:tide_red_helmet, iceandfire:tide_red_chestplate, iceandfire:tide_red_leggings, iceandfire:tide_red_boots
-    # Repair Material: iceandfire:sea_serpent_scales_red
     #  [default: ]
     S:iceandfire_tide_red_helmet <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:tide_teal_helmet, iceandfire:tide_teal_chestplate, iceandfire:tide_teal_leggings, iceandfire:tide_teal_boots
-    # Repair Material: iceandfire:sea_serpent_scales_teal
     #  [default: ]
     S:iceandfire_tide_teal_helmet <
      >
@@ -414,7 +384,7 @@ armors {
 
 
 entity {
-    # A list of name pieces, which can be spliced together to create full names.  May be empty only if names is not empty. [default: [Grab], [Thar], [Ger], [Ald], [Mas], [On], [O], [Din], [Thor], [Jon], [Ath], [Burb], [En], [A], [E], [I], [U], [Hab], [Bloo], [Ena], [Dit], [Aph], [Ern], [Bor], [Dav], [Id], [Toast], [Son], [Dottir], [For], [Wen], [Lob], [Ed], [Die], [Van], [Y], [Zap], [Ear], [Ben], [Don], [Bran], [Gro], [Jen], [Bob], [Ette], [Ere], [Man], [Qua], [Bro], [Cree], [Per], [Skel], [Ton], [Zom], [Bie], [Wolf], [End], [Er], [Pig], [Sil], [Ver], [Fish], [Cow], [Chic], [Ken], [Sheep], [Squid], [Hell]]
+    # A list of name pieces, which can be spliced together to create full names.  May be empty only if names is not empty. [default: [Dark], [Osto], [Grab], [Thar], [Ger], [Ald], [Mas], [On], [O], [Din], [Thor], [Jon], [Ath], [Burb], [En], [A], [E], [I], [U], [Hab], [Bloo], [Ena], [Dit], [Aph], [Ern], [Bor], [Dav], [Id], [Toast], [Son], [Dottir], [For], [Wen], [Lob], [Ed], [Die], [Van], [Y], [Zap], [Ear], [Ben], [Don], [Bran], [Gro], [Jen], [Bob], [Ette], [Ere], [Man], [Qua], [Bro], [Cree], [Per], [Skel], [Ton], [Zom], [Bie], [Wolf], [End], [Er], [Pig], [Sil], [Ver], [Fish], [Cow], [Chic], [Ken], [Sheep], [Squid], [Hell]]
     S:"Name Parts" <
         Grab
         Thar
@@ -486,7 +456,7 @@ entity {
         Hell
      >
 
-    # A list of full names, which are used in the generation of boss names. May be empty only if name parts is not empty. [default: [Albert], [Andrew], [Anderson], [Andy], [Allan], [Arthur], [Aaron], [Allison], [Arielle], [Amanda], [Anne], [Annie], [Amy], [Alana], [Brandon], [Brady], [Bernard], [Ben], [Benjamin], [Bob], [Bobette], [Brooke], [Brandy], [Beatrice], [Bea], [Bella], [Becky], [Carlton], [Carl], [Calvin], [Cameron], [Carson], [Chase], [Cassandra], [Cassie], [Cas], [Carol], [Carly], [Cherise], [Charlotte], [Cheryl], [Chasity], [Danny], [Drake], [Daniel], [Derrel], [David], [Dave], [Donovan], [Don], [Donald], [Drew], [Derrick], [Darla], [Donna], [Dora], [Danielle], [Edward], [Elliot], [Ed], [Edson], [Elton], [Eddison], [Earl], [Eric], [Ericson], [Eddie], [Ediovany], [Emma], [Elizabeth], [Eliza], [Esperanza], [Esper], [Esmeralda], [Emi], [Emily], [Elaine], [Fernando], [Ferdinand], [Fred], [Feddie], [Fredward], [Frank], [Franklin], [Felix], [Felicia], [Fran], [Greg], [Gregory], [George], [Gerald], [Gina], [Geraldine], [Gabby], [Hendrix], [Henry], [Hobbes], [Herbert], [Heath], [Henderson], [Helga], [Hera], [Helen], [Helena], [Hannah], [Ike], [Issac], [Israel], [Ismael], [Irlanda], [Isabelle], [Irene], [Irenia], [Jimmy], [Jim], [Justin], [Jacob], [Jake], [Jon], [Johnson], [Jonny], [Jonathan], [Josh], [Joshua], [Julian], [Jesus], [Jericho], [Jeb], [Jess], [Joan], [Jill], [Jillian], [Jessica], [Jennifer], [Jenny], [Jen], [Judy], [Kenneth], [Kenny], [Ken], [Keith], [Kevin], [Karen], [Kassandra], [Kassie], [Leonard], [Leo], [Leroy], [Lee], [Lenny], [Luke], [Lucas], [Liam], [Lorraine], [Latasha], [Lauren], [Laquisha], [Livia], [Lydia], [Lila], [Lilly], [Lillian], [Lilith], [Lana], [Mason], [Mike], [Mickey], [Mario], [Manny], [Mark], [Marcus], [Martin], [Marty], [Matthew], [Matt], [Max], [Maximillian], [Marth], [Mia], [Marriah], [Maddison], [Maddie], [Marissa], [Miranda], [Mary], [Martha], [Melonie], [Melody], [Mel], [Minnie], [Nathan], [Nathaniel], [Nate], [Ned], [Nick], [Norman], [Nicholas], [Natasha], [Nicki], [Nora], [Nelly], [Nina], [Orville], [Oliver], [Orlando], [Owen], [Olsen], [Odin], [Olaf], [Ortega], [Olivia], [Patrick], [Pat], [Paul], [Perry], [Pinnochio], [Patrice], [Patricia], [Pennie], [Petunia], [Patti], [Pernelle], [Quade], [Quincy], [Quentin], [Quinn], [Roberto], [Robbie], [Rob], [Robert], [Roy], [Roland], [Ronald], [Richard], [Rick], [Ricky], [Rose], [Rosa], [Rhonda], [Rebecca], [Roberta], [Sparky], [Shiloh], [Stephen], [Steve], [Saul], [Sheen], [Shane], [Sean], [Sampson], [Samuel], [Sammy], [Stefan], [Sasha], [Sam], [Susan], [Suzy], [Shelby], [Samantha], [Sheila], [Sharon], [Sally], [Stephanie], [Sandra], [Sandy], [Sage], [Tim], [Thomas], [Thompson], [Tyson], [Tyler], [Tom], [Tyrone], [Timmothy], [Tamara], [Tabby], [Tabitha], [Tessa], [Tiara], [Tyra], [Uriel], [Ursala], [Uma], [Victor], [Vincent], [Vince], [Vance], [Vinny], [Velma], [Victoria], [Veronica], [Wilson], [Wally], [Wallace], [Will], [Wilard], [William], [Wilhelm], [Xavier], [Xandra], [Young], [Yvonne], [Yolanda], [Zach], [Zachary]]
+    # A list of full names, which are used in the generation of boss names. May be empty only if name parts is not empty. [default: [Darko], [Shadows], [Kat], [Jank], [Albert], [Andrew], [Anderson], [Andy], [Allan], [Arthur], [Aaron], [Allison], [Arielle], [Amanda], [Anne], [Annie], [Amy], [Alana], [Brandon], [Brady], [Bernard], [Ben], [Benjamin], [Bob], [Bobette], [Brooke], [Brandy], [Beatrice], [Bea], [Bella], [Becky], [Carlton], [Carl], [Calvin], [Cameron], [Carson], [Chase], [Cassandra], [Cassie], [Cas], [Carol], [Carly], [Cherise], [Charlotte], [Cheryl], [Chasity], [Danny], [Drake], [Daniel], [Derrel], [David], [Dave], [Donovan], [Don], [Donald], [Drew], [Derrick], [Darla], [Donna], [Dora], [Danielle], [Edward], [Elliot], [Ed], [Edson], [Elton], [Eddison], [Earl], [Eric], [Ericson], [Eddie], [Ediovany], [Emma], [Elizabeth], [Eliza], [Esperanza], [Esper], [Esmeralda], [Emi], [Emily], [Elaine], [Fernando], [Ferdinand], [Fred], [Feddie], [Fredward], [Frank], [Franklin], [Felix], [Felicia], [Fran], [Greg], [Gregory], [George], [Gerald], [Gina], [Geraldine], [Gabby], [Hendrix], [Henry], [Hobbes], [Herbert], [Heath], [Henderson], [Helga], [Hera], [Helen], [Helena], [Hannah], [Ike], [Issac], [Israel], [Ismael], [Irlanda], [Isabelle], [Irene], [Irenia], [Jimmy], [Jim], [Justin], [Jacob], [Jake], [Jon], [Johnson], [Jonny], [Jonathan], [Josh], [Joshua], [Julian], [Jesus], [Jericho], [Jeb], [Jess], [Joan], [Jill], [Jillian], [Jessica], [Jennifer], [Jenny], [Jen], [Judy], [Kenneth], [Kenny], [Ken], [Keith], [Kevin], [Karen], [Kassandra], [Kassie], [Leonard], [Leo], [Leroy], [Lee], [Lenny], [Luke], [Lucas], [Liam], [Lorraine], [Latasha], [Lauren], [Laquisha], [Livia], [Lydia], [Lila], [Lilly], [Lillian], [Lilith], [Lana], [Mason], [Mike], [Mickey], [Mario], [Manny], [Mark], [Marcus], [Martin], [Marty], [Matthew], [Matt], [Max], [Maximillian], [Marth], [Mia], [Marriah], [Maddison], [Maddie], [Marissa], [Miranda], [Mary], [Martha], [Melonie], [Melody], [Mel], [Minnie], [Nathan], [Nathaniel], [Nate], [Ned], [Nick], [Norman], [Nicholas], [Natasha], [Nicki], [Nora], [Nelly], [Nina], [Orville], [Oliver], [Orlando], [Owen], [Olsen], [Odin], [Olaf], [Ortega], [Olivia], [Patrick], [Pat], [Paul], [Perry], [Pinnochio], [Patrice], [Patricia], [Pennie], [Petunia], [Patti], [Pernelle], [Quade], [Quincy], [Quentin], [Quinn], [Roberto], [Robbie], [Rob], [Robert], [Roy], [Roland], [Ronald], [Richard], [Rick], [Ricky], [Rose], [Rosa], [Rhonda], [Rebecca], [Roberta], [Sparky], [Shiloh], [Stephen], [Steve], [Saul], [Sheen], [Shane], [Sean], [Sampson], [Samuel], [Sammy], [Stefan], [Sasha], [Sam], [Susan], [Suzy], [Shelby], [Samantha], [Sheila], [Sharon], [Sally], [Stephanie], [Sandra], [Sandy], [Sage], [Tim], [Thomas], [Thompson], [Tyson], [Tyler], [Tom], [Tyrone], [Timmothy], [Tamara], [Tabby], [Tabitha], [Tessa], [Tiara], [Tyra], [Uriel], [Ursala], [Uma], [Victor], [Vincent], [Vince], [Vance], [Vinny], [Velma], [Victoria], [Veronica], [Wilson], [Wally], [Wallace], [Will], [Wilard], [William], [Wilhelm], [Xavier], [Xandra], [Young], [Yvonne], [Yolanda], [Zach], [Zachary]]
     S:Names <
         Albert
         Andrew
@@ -795,7 +765,7 @@ entity {
         Zachary
      >
 
-    # A list of prefixes, which are used in the generation of boss names. May be empty. [default: [Sir], [Mister], [Madam], [Doctor], [Father], [Mother]]
+    # A list of prefixes, which are used in the generation of boss names. May be empty. [default: [Sir], [Mister], [Madam], [Doctor], [Father], [Mother], [Poppa]]
     S:Prefixes <
         Sir
         Mister
@@ -805,7 +775,7 @@ entity {
         Mother
      >
 
-    # A list of suffixes, which are used in the generation of boss names. A suffix is always preceeded by "The". May be empty. [default: [Mighty], [Supreme], [Superior], [Ultimate], [Lame], [Wimpy], [Curious], [Sneaky], [Pathetic], [Crying], [Eagle], [Errant], [Unholy], [Questionable], [Mean], [Hungry], [Thirsty], [Feeble], [Wise], [Sage], [Magical], [Mythical], [Legendary], [Not Very Nice], [Jerk], [Doctor], [Misunderstood], [Angry], [Knight], [Bishop], [Godly], [Special], [Toasty], [Shiny], [Shimmering], [Light], [Dark], [Odd-Smelling], [Funky], [Rock Smasher], [Son of Herobrine], [Cracked], [Sticky], [§kAlien§r], [Baby], [Manly], [Rough], [Scary], [Undoubtable], [Honest], [Non-Suspicious], [Boring], [Odd], [Lazy], [Super], [Nifty], [Ogre Slayer], [Pig Thief], [Dirt Digger], [Really Cool], [Doominator], [... Something]]
+    # A list of suffixes, which are used in the generation of boss names. A suffix is always preceeded by "The". May be empty. [default: [Mighty], [Supreme], [Superior], [Ultimate], [Lame], [Wimpy], [Curious], [Sneaky], [Pathetic], [Crying], [Eagle], [Errant], [Unholy], [Questionable], [Mean], [Hungry], [Thirsty], [Feeble], [Wise], [Sage], [Magical], [Mythical], [Legendary], [Not Very Nice], [Jerk], [Doctor], [Misunderstood], [Angry], [Knight], [Bishop], [Godly], [Special], [Toasty], [Shiny], [Shimmering], [Light], [Dark], [Odd-Smelling], [Funky], [Rock Smasher], [Son of Herobrine], [Cracked], [Sticky], [§kAlien§r], [Baby], [Manly], [Rough], [Scary], [Undoubtable], [Honest], [Non-Suspicious], [Boring], [Odd], [Lazy], [Super], [Nifty], [Ogre Slayer], [Pig Thief], [Dirt Digger], [Really Cool], [Doominator], [... Something], [Extra-Fishy], [Gorilla Slaughterer], [Marbles Winner]]
     S:Suffixes <
         Mighty
         Supreme
@@ -956,6 +926,19 @@ items {
         Miner
      >
 
+    # A list of root names for shields, used in the generation of item names. May not be empty. [default: [Shield], [Defender], [Ardent Defender], [Greatshield], [Blockade], [Bulwark], [Tower Shield], [Protector], [Aegis]]
+    S:shields <
+        Shield
+        Defender
+        Ardent Defender
+        Greatshield
+        Blockade
+        Bulwark
+        Tower Shield
+        Protector
+        Aegis
+     >
+
     # A list of root names for shovels, used in the generation of item names. May not be empty. [default: [Shovel], [Spade], [Digger], [Excavator], [Trowel], [Scoop]]
     S:shovels <
         Shovel
@@ -995,14 +978,12 @@ items {
 tools {
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: undergarden:cloggrum_battleaxe, undergarden:cloggrum_sword, undergarden:cloggrum_pickaxe, undergarden:cloggrum_axe, undergarden:cloggrum_shovel, undergarden:cloggrum_hoe
-    # Repair Material: undergarden:cloggrum_ingot
     #  [default: ]
     S:CLOGGRUM <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: minecraft:diamond_sword, minecraft:diamond_shovel, minecraft:diamond_pickaxe, minecraft:diamond_axe, minecraft:diamond_hoe
-    # Repair Material: minecraft:diamond
     #  [default: [Diamond], [Zircon], [Gemstone], [Jewel], [Crystal]]
     S:DIAMOND <
         Diamond
@@ -1014,21 +995,18 @@ tools {
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: undergarden:forgotten_sword, undergarden:forgotten_pickaxe, undergarden:forgotten_axe, undergarden:forgotten_shovel, undergarden:forgotten_hoe
-    # Repair Material: undergarden:forgotten_ingot
     #  [default: ]
     S:FORGOTTEN <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: undergarden:froststeel_sword, undergarden:froststeel_pickaxe, undergarden:froststeel_axe, undergarden:froststeel_shovel, undergarden:froststeel_hoe
-    # Repair Material: undergarden:froststeel_ingot
     #  [default: ]
     S:FROSTSTEEL <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: minecraft:golden_sword, minecraft:golden_shovel, minecraft:golden_pickaxe, minecraft:golden_axe, minecraft:golden_hoe
-    # Repair Material: minecraft:gold_ingot
     #  [default: [Golden], [Gold], [Gilt], [Auric], [Ornate]]
     S:GOLD <
         Golden
@@ -1040,7 +1018,6 @@ tools {
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: minecraft:iron_sword, minecraft:iron_shovel, minecraft:iron_pickaxe, minecraft:iron_axe, minecraft:iron_hoe
-    # Repair Material: minecraft:iron_ingot
     #  [default: [Iron], [Steel], [Ferrous], [Rusty], [Wrought Iron]]
     S:IRON <
         Iron
@@ -1052,7 +1029,6 @@ tools {
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: minecraft:netherite_sword, minecraft:netherite_shovel, minecraft:netherite_pickaxe, minecraft:netherite_axe, minecraft:netherite_hoe
-    # Repair Material: minecraft:netherite_ingot
     #  [default: [Burnt], [Embered], [Fiery], [Hellborn], [Flameforged]]
     S:NETHERITE <
         Burnt
@@ -1064,21 +1040,14 @@ tools {
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: byg:pendorite_axe, byg:pendorite_pickaxe, byg:pendorite_sword, byg:pendorite_battleaxe, byg:pendorite_shovel, byg:pendorite_hoe
-    # Repair Material: byg:pendorite_scraps
     #  [default: ]
     S:PENDORITE <
      >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: create:deforester
-    # Repair Material: create:refined_radiance
-    #  [default: ]
     S:RADIANT <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: minecraft:stone_sword, minecraft:stone_shovel, minecraft:stone_pickaxe, minecraft:stone_axe, minecraft:stone_hoe
-    # Repair Material: null
     #  [default: [Stone], [Rock], [Marble], [Cobblestone]]
     S:STONE <
         Stone
@@ -1089,14 +1058,12 @@ tools {
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: undergarden:utheric_sword, undergarden:utheric_pickaxe, undergarden:utheric_axe, undergarden:utheric_shovel, undergarden:utheric_hoe
-    # Repair Material: undergarden:utherium_ingot
     #  [default: ]
     S:UTHERIC <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: minecraft:wooden_sword, minecraft:wooden_shovel, minecraft:wooden_pickaxe, minecraft:wooden_axe, minecraft:wooden_hoe
-    # Repair Material: null
     #  [default: [Wooden], [Wood], [Hardwood], [Balsa Wood], [Mahogany], [Plywood]]
     S:WOOD <
         Wooden
@@ -1109,140 +1076,120 @@ tools {
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:amphithere_macuahuitl
-    # Repair Material: iceandfire:amphithere_feather
     #  [default: ]
     S:iceandfire_amphithere_macuahuitl <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:copper_sword, iceandfire:copper_shovel, iceandfire:copper_pickaxe, iceandfire:copper_axe, iceandfire:copper_hoe
-    # Repair Material: null
     #  [default: ]
     S:iceandfire_copper_sword <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:dragonbone_sword, iceandfire:dragonbone_shovel, iceandfire:dragonbone_pickaxe, iceandfire:dragonbone_axe, iceandfire:dragonbone_hoe
-    # Repair Material: iceandfire:dragonbone
     #  [default: ]
     S:iceandfire_dragonbone_sword <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:dragonbone_sword_fire
-    # Repair Material: iceandfire:dragonbone
     #  [default: ]
     S:iceandfire_dragonbone_sword_fire <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:dragonbone_sword_ice
-    # Repair Material: iceandfire:dragonbone
     #  [default: ]
     S:iceandfire_dragonbone_sword_ice <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:dragonbone_sword_lightning
-    # Repair Material: null
     #  [default: ]
     S:iceandfire_dragonbone_sword_lightning <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:dragonsteel_fire_sword, iceandfire:dragonsteel_fire_pickaxe, iceandfire:dragonsteel_fire_axe, iceandfire:dragonsteel_fire_shovel, iceandfire:dragonsteel_fire_hoe
-    # Repair Material: iceandfire:dragonsteel_fire_ingot
     #  [default: ]
     S:iceandfire_dragonsteel_fire_sword <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:dragonsteel_ice_sword, iceandfire:dragonsteel_ice_pickaxe, iceandfire:dragonsteel_ice_axe, iceandfire:dragonsteel_ice_shovel, iceandfire:dragonsteel_ice_hoe
-    # Repair Material: iceandfire:dragonsteel_ice_ingot
     #  [default: ]
     S:iceandfire_dragonsteel_ice_sword <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:dragonsteel_lightning_sword, iceandfire:dragonsteel_lightning_pickaxe, iceandfire:dragonsteel_lightning_axe, iceandfire:dragonsteel_lightning_shovel, iceandfire:dragonsteel_lightning_hoe
-    # Repair Material: iceandfire:dragonsteel_lightning_ingot
     #  [default: ]
     S:iceandfire_dragonsteel_lightning_sword <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:dread_knight_sword
-    # Repair Material: iceandfire:dread_shard
     #  [default: ]
     S:iceandfire_dread_knight_sword <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:dread_queen_sword
-    # Repair Material: null
     #  [default: ]
     S:iceandfire_dread_queen_sword <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:dread_sword
-    # Repair Material: iceandfire:dread_shard
     #  [default: ]
     S:iceandfire_dread_sword <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:ghost_sword
-    # Repair Material: null
     #  [default: ]
     S:iceandfire_ghost_sword <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:hippocampus_slapper
-    # Repair Material: iceandfire:shiny_scales
     #  [default: ]
     S:iceandfire_hippocampus_slapper <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:hippogryph_sword
-    # Repair Material: iceandfire:hippogryph_talon
     #  [default: ]
     S:iceandfire_hippogryph_sword <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:myrmex_desert_sword, iceandfire:myrmex_desert_sword_venom, iceandfire:myrmex_desert_shovel, iceandfire:myrmex_desert_pickaxe, iceandfire:myrmex_desert_axe, iceandfire:myrmex_desert_hoe, iceandfire:myrmex_jungle_sword, iceandfire:myrmex_jungle_sword_venom, iceandfire:myrmex_jungle_shovel, iceandfire:myrmex_jungle_pickaxe, iceandfire:myrmex_jungle_axe, iceandfire:myrmex_jungle_hoe
-    # Repair Material: iceandfire:myrmex_desert_chitin
     #  [default: ]
     S:iceandfire_myrmex_desert_sword <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:silver_sword, iceandfire:silver_shovel, iceandfire:silver_pickaxe, iceandfire:silver_axe, iceandfire:silver_hoe
-    # Repair Material: iceandfire:silver_ingot
     #  [default: ]
     S:iceandfire_silver_sword <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:stymphalian_bird_dagger
-    # Repair Material: iceandfire:stymphalian_bird_feather
     #  [default: ]
     S:iceandfire_stymphalian_bird_dagger <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: iceandfire:troll_weapon_axe, iceandfire:troll_weapon_column, iceandfire:troll_weapon_column_forest, iceandfire:troll_weapon_column_frost, iceandfire:troll_weapon_hammer, iceandfire:troll_weapon_trunk, iceandfire:troll_weapon_trunk_frost
-    # Repair Material: minecraft:stone
     #  [default: ]
     S:iceandfire_troll_weapon_axe <
      >
 
     # A list of material-based prefix names for this material group. May be empty.
     # Items in this group: wstweaks:lava_blade, wstweaks:blaze_blade
-    # Repair Material: minecraft:nether_star
     #  [default: ]
     S:wstweaks_lava_blade <
      >
diff --git a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/village.cfg b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/village.cfg
index ead9ef8..109b3e5 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/village.cfg
+++ b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/village.cfg
@@ -1,7 +1,11 @@
 # Configuration file
 
 wanderer {
-    # If new trades are added to the wandering merchant. [default: true]
+    # If the generic trade list will be cleared before datapack loaded trades are added. [default: false]
+    B:"Clear Generic Trades"=false
+
+    # If the rare trade list will be cleared before datapack loaded trades are added. [default: false]
+    B:"Clear Rare Trades"=false
     B:"Enable New Trades"=true
 }
 
diff --git a/configuration/services/configs/minecraft/voor-kia/config/appleskin-client.toml b/configuration/services/configs/minecraft/voor-kia/config/appleskin-client.toml
index eff69f3..b171cd8 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/appleskin-client.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/appleskin-client.toml
@@ -4,12 +4,21 @@
 	showFoodValuesHudOverlay = true
 	#If true, shows your food exhaustion as a progress bar behind the hunger bars
 	showFoodExhaustionHudUnderlay = true
+	#Alpha value of the flashing icons at their most visible point (1.0 = fully opaque, 0.0 = fully transparent)
+	#Range: 0.0 ~ 1.0
+	maxHudOverlayFlashAlpha = 0.65
+	#If true, health/hunger overlay will shake to match Minecraft's icon animations
+	showVanillaAnimationsOverlay = true
 	#If true, adds a line that shows your hunger, saturation, and exhaustion level in the F3 debug overlay
 	showFoodStatsInDebugOverlay = true
 	#If true, shows the hunger and saturation values of food in its tooltip while holding SHIFT
 	showFoodValuesInTooltip = true
 	#If true, shows the hunger and saturation values of food in its tooltip automatically (without needing to hold SHIFT)
 	showFoodValuesInTooltipAlways = true
+	#If true, shows estimated health restored by food on the health bar
+	showFoodHealthHudOverlay = true
 	#If true, shows your current saturation level overlayed on the hunger bar
 	showSaturationHudOverlay = true
+	#If true, enables the hunger/saturation/health overlays for food in your off-hand
+	showFoodValuesHudOverlayWhenOffhand = true
 
diff --git a/configuration/services/configs/minecraft/voor-kia/config/artifacts-common.toml b/configuration/services/configs/minecraft/voor-kia/config/artifacts-common.toml
index 120dae9..5977567 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/artifacts-common.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/artifacts-common.toml
@@ -1,30 +1,36 @@
+#Affects how common artifacts are (does not affect mimics)
+#When this is 1, the default artifact spawn rates will be used
+#Values higher that 1 will decrease spawn rates while values lower than 1 will increase spawn rates
+#Doubling this value will (roughly) halve the chance a container contains an artifact
+#Setting this to 10000 will completely prevent artifacts from spawning
+#When set to 0, every container that can contain artifacts will contain an artifact
+#Range: 0.0 ~ 10000.0
+artifact_rarity = 1.0
 
-#To disable items or to change the frequency at which artifacts appear, override the loot tables from this mod with a datapack
-#Cosmetic slots are disabled by default, they can be enabled using the Curios config, see https://github.com/TheIllusiveC4/Curios/wiki/How-to-Use:-Users#creating-a-new-slot-type
 [campsite]
-	#Probability for an ore vein to generate underneath a campsite
-	#Range: 0 ~ 100
-	campsite_ore_chance = 25
+	#The maximum y-level at which a campsite can generate
+	#Range: 1 ~ 255
+	max_y = 45
+	#Whether to use wooden chests from other mods when generating campsites
+	#(keeping this enabled may make it easier to distinguish them from mimics)
+	use_modded_chests = true
+	#List of biome IDs in which campsites are not allowed to generate
+	#End and nether biomes are excluded by default
+	#To blacklist all biomes from a single mod, use "modid:*"
+	biome_blacklist = ["minecraft:void", "undergarden:*", "the_bumblezone:*"]
+	#Probability for a container of a campsite to be replaced by a mimic
+	#Range: 0.0 ~ 1.0
+	mimic_chance = 0.3
 	#The minimum y-level at which a campsite can generate
 	#Range: 1 ~ 255
-	campsite_min_y = 1
-	#The maximum y-level at which a campsite can generate
-	#Range: 0 ~ 255
-	campsite_max_y = 45
-	#Whether to use wooden chests from other mods when generating campsites, may make it easier to distinguish them from mimics
-	use_modded_chests = true
-	#Probability for a container of a campsite to be replaced by a mimic
-	#Range: 0 ~ 100
-	campsite_mimic_chance = 30
-	#List of biome IDs in which campsites are not allowed to generate. End and nether biomes are excluded by default.
-	# To blacklist all biomes from a single mod, use 'modid:*'
-	biome_blacklist = ["minecraft:void", "undergarden:*", "the_bumblezone:*"]
-	#Per-chunk probability (as a percentage) a campsite is attempted to be generated. Not every attempt succeeds, this also depends on the density and shape of caves
-	#Range: 0 ~ 100
-	campsite_chance = 8
-
-[items]
-	#Cooldown in ticks for the Everlasting Beef and Eternal Steak items
-	#Range: > 0
-	eternal_food_cooldown = 300
+	min_y = 1
+	#Probability for an ore vein to generate underneath a campsite
+	#Range: 0.0 ~ 1.0
+	ore_chance = 0.25
+	#Rarity of campsites generating in the world
+	#The chance a campsite generates in a specific chunk is 1/rarity
+	#A rarity of 1 will generate a campsite in every chunk, while 10000 will generate no campsites
+	#Not every attempt at generating a campsite succeeds, this also depends on the density and shape of caves
+	#Range: 1 ~ 10000
+	rarity = 12
 
diff --git a/configuration/services/configs/minecraft/voor-kia/config/attributefix-common.toml b/configuration/services/configs/minecraft/voor-kia/config/attributefix-common.toml
index 9b63d3a..b13b887 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/attributefix-common.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/attributefix-common.toml
@@ -2,10 +2,10 @@
 #Values for the minecraft:generic.max_health attribute.
 [minecraft_generic_max_health]
 	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	min = 1.0
 	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	max = 65536.0
 	#Whether or not this attribute should be modified.
 	enabled = true
@@ -13,10 +13,10 @@
 #Values for the minecraft:generic.follow_range attribute.
 [minecraft_generic_follow_range]
 	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	min = 4.9E-324
 	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	max = 65536.0
 	#Whether or not this attribute should be modified.
 	enabled = true
@@ -24,10 +24,10 @@
 #Values for the minecraft:generic.knockback_resistance attribute.
 [minecraft_generic_knockback_resistance]
 	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	min = 4.9E-324
 	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	max = 65536.0
 	#Whether or not this attribute should be modified.
 	enabled = true
@@ -35,10 +35,10 @@
 #Values for the minecraft:generic.movement_speed attribute.
 [minecraft_generic_movement_speed]
 	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	min = 4.9E-324
 	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	max = 65536.0
 	#Whether or not this attribute should be modified.
 	enabled = true
@@ -46,10 +46,10 @@
 #Values for the minecraft:generic.flying_speed attribute.
 [minecraft_generic_flying_speed]
 	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	min = 4.9E-324
 	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	max = 65536.0
 	#Whether or not this attribute should be modified.
 	enabled = true
@@ -57,10 +57,10 @@
 #Values for the minecraft:generic.attack_damage attribute.
 [minecraft_generic_attack_damage]
 	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	min = 4.9E-324
 	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	max = 65536.0
 	#Whether or not this attribute should be modified.
 	enabled = true
@@ -68,10 +68,10 @@
 #Values for the minecraft:generic.attack_knockback attribute.
 [minecraft_generic_attack_knockback]
 	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	min = 4.9E-324
 	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	max = 65536.0
 	#Whether or not this attribute should be modified.
 	enabled = true
@@ -79,10 +79,10 @@
 #Values for the minecraft:generic.attack_speed attribute.
 [minecraft_generic_attack_speed]
 	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	min = 4.9E-324
 	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	max = 65536.0
 	#Whether or not this attribute should be modified.
 	enabled = true
@@ -90,10 +90,10 @@
 #Values for the minecraft:generic.armor attribute.
 [minecraft_generic_armor]
 	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	min = 4.9E-324
 	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	max = 65536.0
 	#Whether or not this attribute should be modified.
 	enabled = true
@@ -101,10 +101,10 @@
 #Values for the minecraft:generic.armor_toughness attribute.
 [minecraft_generic_armor_toughness]
 	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	min = 4.9E-324
 	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	max = 65536.0
 	#Whether or not this attribute should be modified.
 	enabled = true
@@ -112,10 +112,10 @@
 #Values for the minecraft:generic.luck attribute.
 [minecraft_generic_luck]
 	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	min = 4.9E-324
 	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	max = 65536.0
 	#Whether or not this attribute should be modified.
 	enabled = true
@@ -123,10 +123,10 @@
 #Values for the minecraft:zombie.spawn_reinforcements attribute.
 [minecraft_zombie_spawn_reinforcements]
 	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	min = 4.9E-324
 	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	max = 65536.0
 	#Whether or not this attribute should be modified.
 	enabled = true
@@ -134,197 +134,10 @@
 #Values for the minecraft:horse.jump_strength attribute.
 [minecraft_horse_jump_strength]
 	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	min = 4.9E-324
 	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the doggytalents:generic.jump_power attribute.
-[doggytalents_generic_jump_power]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the doggytalents:generic.crit_chance attribute.
-[doggytalents_generic_crit_chance]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the doggytalents:generic.crit_bonus attribute.
-[doggytalents_generic_crit_bonus]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the forge:swim_speed attribute.
-[forge_swim_speed]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the forge:nametag_distance attribute.
-[forge_nametag_distance]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the forge:entity_gravity attribute.
-[forge_entity_gravity]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the forge:reach_distance attribute.
-[forge_reach_distance]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the apotheosis:draw_speed attribute.
-[apotheosis_draw_speed]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the apotheosis:snipe_damage attribute.
-[apotheosis_snipe_damage]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the apotheosis:fire_damage attribute.
-[apotheosis_fire_damage]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the apotheosis:cold_damage attribute.
-[apotheosis_cold_damage]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the apotheosis:life_steal attribute.
-[apotheosis_life_steal]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the apotheosis:piercing_damage attribute.
-[apotheosis_piercing_damage]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the apotheosis:current_hp_damage attribute.
-[apotheosis_current_hp_damage]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the apotheosis:crit_chance attribute.
-[apotheosis_crit_chance]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the apotheosis:crit_damage attribute.
-[apotheosis_crit_damage]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the apotheosis:overhealing attribute.
-[apotheosis_overhealing]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: 4.9E-324 ~ 1.7976931348623157E308
+	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
 	max = 65536.0
 	#Whether or not this attribute should be modified.
 	enabled = true
diff --git a/configuration/services/configs/minecraft/voor-kia/config/betterburning-common.toml b/configuration/services/configs/minecraft/voor-kia/config/betterburning-common.toml
index 9be5b51..d159303 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/betterburning-common.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/betterburning-common.toml
@@ -11,6 +11,20 @@
 	#What is the % chance skeletons will shoot flaming arrows while on fire?
 	#Range: 0.0 ~ 1.0
 	flameArrowSkeletonChance = 0.7
+	#How long should Soulfire burn players if they try to punch it out?
+	#Range: > 0
+	soulfireHitBurnTime = 2
+	#Can players put out fire with bottled water?
+	extinguishWithBottledWater = true
+	#Should the fire/burning HUD overlay be hidden if the player has fire immunity?
+	hideFireOverlayWhenImmune = true
+	#Should skeletons shoot flaming arrows while on fire?
+	flameArrowSkeletons = true
+	#Should players be able to put out fire blocks by punching them?
+	punchOutFlames = true
+	#How long should Fire burn players if they try to punch it out?
+	#Range: > 0
+	fireHitBurnTime = 1
 	#Should fire damage spread between mobs when they hurt eachother? Zombies already do this and won't be changed.
 	fireDamageSpreads = true
 	#What is the % chance that fire damage will spread between mobs?
@@ -18,6 +32,4 @@
 	fireDamageSpreadChance = 0.3
 	#Should having fire resistance stop things from being on fire visually?
 	fireResistanceExtinguish = true
-	#Should skeletons shoot flaming arrows while on fire?
-	flameArrowSkeletons = true
 
diff --git a/configuration/services/configs/minecraft/voor-kia/config/byg/byg-world.toml b/configuration/services/configs/minecraft/voor-kia/config/byg/byg-world.toml
index 2813df8..235c77b 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/byg/byg-world.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/byg/byg-world.toml
@@ -1,26 +1,4 @@
 
-[The_End]
-	#
-	#Does BYG control The End?
-	ControlEnd = true
-	#
-	#End Biome Size.
-	#Default: 3
-	#Range: 0 ~ 10
-	IslandBiomeSize = 3
-	#
-	#End Biome Size
-	#Default: 3
-	#Range: 0 ~ 10
-	EndBiomeSize = 3
-
-	[The_End.Void]
-		#
-		#Void Biome(where small end islands generate in vanilla) size.
-		#Default: 3
-		#Range: 0 ~ 10
-		VoidBiomeSize = 2
-
 [Overworld]
 
 	[Overworld.Ores]
@@ -129,6 +107,28 @@
 			#Generate Rocky Stone?
 			GenerateRockyStone = true
 
+[The_End]
+	#
+	#Does BYG control The End?
+	ControlEnd = true
+	#
+	#End Biome Size.
+	#Default: 3
+	#Range: 0 ~ 10
+	IslandBiomeSize = 3
+	#
+	#End Biome Size
+	#Default: 3
+	#Range: 0 ~ 10
+	EndBiomeSize = 3
+
+	[The_End.Void]
+		#
+		#Void Biome(where small end islands generate in vanilla) size.
+		#Default: 3
+		#Range: 0 ~ 10
+		VoidBiomeSize = 2
+
 [The_Nether]
 	#
 	#Is the list of biomes a blacklist or whitelist?
@@ -151,3 +151,68 @@
 	#Default: ""
 	BlacklistNether = ""
 
+#End related settings
+[end]
+	#Does BYG control The End?
+	#This only applies when making NEW worlds!
+	#Is not guaranteed to work in specific world types.
+	#You can find more info here in regards to specific world types: https://github.com/CorgiTaco/BYG/wiki/Enabling-BYG-Nether-&-End-Biomes
+	#For existing worlds, follow the steps listed here: https://wiki.griefed.de/SCP/edit-world.
+	controlEnd = true
+	#End Biome Size
+	#Default: 3
+	#Range: 1-10
+	endBiomeSize = 3
+	#Void Biome Size
+	#Default: 2
+	#Range: 1-10
+	voidBiomeSize = 2
+
+#Nether related settings
+[nether]
+	#Does BYG control The Nether?
+	#This only applies when making NEW worlds!
+	#Is not guaranteed to work in specific world types.
+	#You can find more info here in regards to specific world types: https://github.com/CorgiTaco/BYG/wiki/Enabling-BYG-Nether-&-End-Biomes
+	#For existing worlds, follow the steps listed here: https://wiki.griefed.de/SCP/edit-world.
+	controlNether = true
+	#Nether Biome Size
+	#Default: 3
+	#Range: 1-10
+	netherBiomeSize = 3
+
+#BYG uses a prefix system for its ore spawns.
+# Prefix Guide:
+# "#" - Biome category representable.
+# "$" - Biome dictionary representable.
+# "," - Creates a new condition, separate from the previous.
+# "ALL" - Spawn in all biomes(no condition).
+# "!" - Negates/flips/does the reverse of the condition.
+# "" - No prefix serves as a biome ID OR Mod ID representable.
+#
+# Here are a few examples:
+#1. "byg#THE_END, $OCEAN" would mean that the ore may spawn in biomes with the name space "byg" AND in the "END" biome category, OR all biomes in the "OCEAN" dictionary.
+#2. "byg:guiana_shield, #MESA" would mean that the ore may spawn in the "byg:guiana_shield" OR all biomes in the "MESA" category.
+#3. "byg#ICY$MOUNTAIN" would mean that the ore may only spawn in biomes from byg in the "ICY" category and "MOUNTAIN" dictionary type.
+#4. "!byg#DESERT" would mean that the ore may only spawn in biomes that are NOT from byg and NOT in the "DESERT" category.
+#5. "ALL", spawn everywhere. 
+#6. "" Don't spawn anywhere.
+[ores]
+	#What biome(s) does Ametrine spawn in? Default: "byg:shattered_viscal_isles".
+	ametrineSpawns = "byg:shattered_viscal_isles"
+	#What biome(s) does Budding Ametrine spawn in? Default: "byg:shattered_viscal_isles".
+	buddingAmetrineSpawns = "byg:shattered_viscal_isles"
+	#What biome(s) does Pendorite spawn in? Default: "byg:forest_fault".
+	pendoriteSpawns = "byg:forest_fault"
+	#What biome(s) does Therium spawn in? Default: "byg#THE_END".
+	theriumSpawns = "byg#THEEND"
+
+#See the explanation for ores for configuring stones.
+[stones]
+	#What biome(s) does Rocky Stone spawn in? Default: "!#THEEND#NETHER".
+	rockyStoneSpawns = "!#THEEND#NETHER"
+	#What biome(s) does Scoria Stone spawn in? Default: "!#THEEND#NETHER".
+	scoriaStoneSpawns = "!#THEEND#NETHER"
+	#What biome(s) does Soap Stone spawn in? Default: "!#THEEND#NETHER".
+	soapStoneSpawns = "!#THEEND#NETHER"
+
diff --git a/configuration/services/configs/minecraft/voor-kia/config/citadel-common.toml b/configuration/services/configs/minecraft/voor-kia/config/citadel-common.toml
index e4832f0..af71d32 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/citadel-common.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/citadel-common.toml
@@ -2,4 +2,7 @@
 [general]
 	#True if citadel tracks entity properties(freezing, stone mobs, etc) on server. Turn this to false to solve some server lag, may break some stuff.
 	"Track Entities" = true
+	#Multiplies the count of entities spawned by this number. 0 = no entites added on chunk gen, 2 = twice as many entities added on chunk gen. Useful for many mods that add a lot of creatures, namely animals, to the spawn lists.
+	#Range: 0.0 ~ 100000.0
+	chunkGenSpawnModifier = 1.0
 
diff --git a/configuration/services/configs/minecraft/voor-kia/config/cookingforblockheads-common.toml b/configuration/services/configs/minecraft/voor-kia/config/cookingforblockheads-common.toml
index d336dc2..a6c1d69 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/cookingforblockheads-common.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/cookingforblockheads-common.toml
@@ -17,4 +17,7 @@ ovenFuelTimeMultiplier = 0.33000001311302185
 ovenCookTimeMultiplier = 1.0
 #Set this to true if you'd like the oven to only accept cooking oil as fuel (requires Pam's Harvestcraft)
 ovenRequiresCookingOil = false
+#Ex Compressum compatibility. Multiplier applied to the milk per tick for Compressed Cow in a Jar.
+#Range: 0.0 ~ 3.4028234663852886E38
+compressedCowJarMilkMultiplier = 9.0
 
diff --git a/configuration/services/configs/minecraft/voor-kia/config/cosmeticarmorreworked-common.toml b/configuration/services/configs/minecraft/voor-kia/config/cosmeticarmorreworked-common.toml
index 90bfda0..bb30134 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/cosmeticarmorreworked-common.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/cosmeticarmorreworked-common.toml
@@ -1,6 +1,10 @@
 
 #These settings affects both server and client
 [Common]
+	#Whether or not to disable the RecipeBook in the CosmeticArmorInventory
+	CosArmorDisableRecipeBook = false
 	#Whether or not to keep items in cosmetic armor slots in the event of player death
 	CosArmorKeepThroughDeath = false
+	#Whether or not to disable the coshat command
+	CosArmorDisableCosHatCommand = false
 
diff --git a/configuration/services/configs/minecraft/voor-kia/config/create-common.toml b/configuration/services/configs/minecraft/voor-kia/config/create-common.toml
index aeb7acf..c01195c 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/create-common.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/create-common.toml
@@ -1,166 +1,136 @@
 
 [worldgen]
 
-	#
+	# 
 	#Modify Create's impact on your terrain
-	[worldgen.v1]
-		#
+	[worldgen.v2]
+		# 
 		#Prevents all worldgen added by Create from taking effect
 		disableWorldGen = false
-		#
-		#Forward caught TileEntityExceptions to the log at debug level.
-		logTeErrors = false
 
-		[worldgen.v1.copper_ore]
-			#No comment
+		[worldgen.v2.copper_ore]
+			# 
 			#Range: > 0
 			minHeight = 40
-			#No comment
-			#Range: > 0
-			clusterCount = 2
-			#No comment
-			#Range: > 0
-			maxHeight = 86
-			#
-			#Whether to spawn this in your World
-			enable = true
-			#No comment
-			#Range: > 0
-			clusterSize = 18
-
-		[worldgen.v1.weathered_limestone]
-			#No comment
-			#Range: > 0
-			minHeight = 10
-			#No comment
-			#Range: 0.0 ~ 1.0
-			clusterChance = 0.03125
-			#No comment
-			#Range: > 0
-			maxHeight = 30
-			#
-			#Whether to spawn this in your World
-			enable = true
-			#No comment
-			#Range: > 0
-			clusterSize = 128
-
-		[worldgen.v1.zinc_ore]
-			#No comment
-			#Range: > 0
-			minHeight = 15
-			#No comment
-			#Range: > 0
-			clusterCount = 4
-			#No comment
-			#Range: > 0
-			maxHeight = 70
-			#
-			#Whether to spawn this in your World
-			enable = true
-			#No comment
-			#Range: > 0
-			clusterSize = 14
-
-		[worldgen.v1.zinc_ore_desert]
-			#No comment
-			#Range: > 0
-			minHeight = 10
-			#No comment
-			#Range: > 0
-			clusterCount = 5
-			#No comment
+			# 
 			#Range: > 0
 			maxHeight = 85
-			#
-			#Whether to spawn this in your World
-			enable = true
-			#No comment
+			# 
 			#Range: > 0
-			clusterSize = 17
+			clusterSize = 18
+			# 
+			#Amount of clusters generated per Chunk.
+			#  >1 to spawn multiple.
+			#  <1 to make it a chance.
+			#  0 to disable.
+			#Range: 0.0 ~ 512.0
+			frequency = 2.0
 
-		[worldgen.v1.limestone]
-			#No comment
+		[worldgen.v2.weathered_limestone]
+			# 
+			#Range: > 0
+			minHeight = 10
+			# 
+			#Range: > 0
+			maxHeight = 30
+			# 
+			#Range: > 0
+			clusterSize = 128
+			# 
+			#Amount of clusters generated per Chunk.
+			#  >1 to spawn multiple.
+			#  <1 to make it a chance.
+			#  0 to disable.
+			#Range: 0.0 ~ 512.0
+			frequency = 0.015625
+
+		[worldgen.v2.zinc_ore]
+			# 
+			#Range: > 0
+			minHeight = 15
+			# 
+			#Range: > 0
+			maxHeight = 70
+			# 
+			#Range: > 0
+			clusterSize = 14
+			# 
+			#Amount of clusters generated per Chunk.
+			#  >1 to spawn multiple.
+			#  <1 to make it a chance.
+			#  0 to disable.
+			#Range: 0.0 ~ 512.0
+			frequency = 4.0
+
+		[worldgen.v2.limestone]
+			# 
 			#Range: > 0
 			minHeight = 30
-			#No comment
-			#Range: 0.0 ~ 1.0
-			clusterChance = 0.03125
-			#No comment
+			# 
 			#Range: > 0
 			maxHeight = 70
-			#
-			#Whether to spawn this in your World
-			enable = true
-			#No comment
+			# 
 			#Range: > 0
 			clusterSize = 128
+			# 
+			#Amount of clusters generated per Chunk.
+			#  >1 to spawn multiple.
+			#  <1 to make it a chance.
+			#  0 to disable.
+			#Range: 0.0 ~ 512.0
+			frequency = 0.015625
 
-		[worldgen.v1.dolomite]
-			#No comment
+		[worldgen.v2.dolomite]
+			# 
 			#Range: > 0
 			minHeight = 20
-			#No comment
-			#Range: 0.0 ~ 1.0
-			clusterChance = 0.015625
-			#No comment
+			# 
 			#Range: > 0
 			maxHeight = 70
-			#
-			#Whether to spawn this in your World
-			enable = true
-			#No comment
+			# 
 			#Range: > 0
 			clusterSize = 128
+			# 
+			#Amount of clusters generated per Chunk.
+			#  >1 to spawn multiple.
+			#  <1 to make it a chance.
+			#  0 to disable.
+			#Range: 0.0 ~ 512.0
+			frequency = 0.015625
 
-		[worldgen.v1.copper_ore_ocean]
-			#No comment
+		[worldgen.v2.gabbro]
+			# 
 			#Range: > 0
 			minHeight = 20
-			#No comment
-			#Range: > 0
-			clusterCount = 4
-			#No comment
-			#Range: > 0
-			maxHeight = 55
-			#
-			#Whether to spawn this in your World
-			enable = true
-			#No comment
-			#Range: > 0
-			clusterSize = 15
-
-		[worldgen.v1.gabbro]
-			#No comment
-			#Range: > 0
-			minHeight = 20
-			#No comment
-			#Range: 0.0 ~ 1.0
-			clusterChance = 0.015625
-			#No comment
+			# 
 			#Range: > 0
 			maxHeight = 70
-			#
-			#Whether to spawn this in your World
-			enable = true
-			#No comment
+			# 
 			#Range: > 0
 			clusterSize = 128
+			# 
+			#Amount of clusters generated per Chunk.
+			#  >1 to spawn multiple.
+			#  <1 to make it a chance.
+			#  0 to disable.
+			#Range: 0.0 ~ 512.0
+			frequency = 0.015625
 
-		[worldgen.v1.scoria]
-			#No comment
+		[worldgen.v2.scoria]
+			# 
 			#Range: > 0
 			minHeight = 0
-			#No comment
-			#Range: 0.0 ~ 1.0
-			clusterChance = 0.03125
-			#No comment
+			# 
 			#Range: > 0
 			maxHeight = 10
-			#
-			#Whether to spawn this in your World
-			enable = true
-			#No comment
+			# 
 			#Range: > 0
 			clusterSize = 128
+			# 
+			#Amount of clusters generated per Chunk.
+			#  >1 to spawn multiple.
+			#  <1 to make it a chance.
+			#  0 to disable.
+			#Range: 0.0 ~ 512.0
+			frequency = 0.03125
 
diff --git a/configuration/services/configs/minecraft/voor-kia/config/ironfurnaces.toml b/configuration/services/configs/minecraft/voor-kia/config/ironfurnaces.toml
index abe46ad..df164ab 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/ironfurnaces.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/ironfurnaces.toml
@@ -80,6 +80,16 @@
 		#Range: 2 ~ 72000
 		speed = 180
 
+	[furnaces.furance_xp_drop]
+		# This value indicates when the furnace should 'overload' and spit out the xp stored. 
+		# Default: 10, Recipes
+		#Range: 1 ~ 500
+		value = 10
+		# This value indicates when the furnace should 'overload' and spit out the xp stored. 
+		# Default: 100000, Single recipe uses
+		#Range: 1 ~ 1000000
+		value_two = 100000
+
 	[furnaces.emerald_furnace]
 		# Number of ticks to complete one smelting operation.
 		# 200 ticks is what a regular furnace takes.
@@ -97,7 +107,7 @@
 	[furnaces.rainbow_furnace]
 		# Number of ticks to complete one smelting operation.
 		# 200 ticks is what a regular furnace takes.
-		# Default: 200
+		# Default: 20
 		#Range: 2 ~ 72000
 		speed = 200
 
@@ -123,6 +133,10 @@
 [misc]
 
 	[misc.misc]
+		# Enable or disable the Rainbow Content
+		rainbow = true
 		# Given or not given the Rainbow Coal to our champion
 		coal = false
+		# Show furnace settings errors in chat, used for debugging
+		errors = false
 
diff --git a/configuration/services/configs/minecraft/voor-kia/config/jeresources-common.toml b/configuration/services/configs/minecraft/voor-kia/config/jeresources-common.toml
index f733dfd..0dd954f 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/jeresources-common.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/jeresources-common.toml
@@ -7,4 +7,5 @@ showDevData = false
 enchantsBlacklist = ["flimflam", "soulBound"]
 hiddenTabs = []
 dimensionsBlacklist = [-11]
+disableLootManagerReloading = false
 
diff --git a/configuration/services/configs/minecraft/voor-kia/config/jeresources.toml b/configuration/services/configs/minecraft/voor-kia/config/jeresources.toml
index 39ad778..a4f9f5b 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/jeresources.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/jeresources.toml
@@ -1,3 +1,4 @@
+disableLootManagerReloading = false
 hiddenTabs = []
 #Range: 1 ~ 4
 itemsPerRow = 4
diff --git a/configuration/services/configs/minecraft/voor-kia/config/pamhc2crops.toml b/configuration/services/configs/minecraft/voor-kia/config/pamhc2crops.toml
index 72008e8..0f5a672 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/pamhc2crops.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/pamhc2crops.toml
@@ -4,10 +4,10 @@
 	"Enable fern blocks dropping seeds" = false
 	#Disable/enable tall grass blocks dropping seeds.
 	"Enable tall grass blocks dropping seeds" = false
+	#Disable/enable right-click harvesting of crops.
+	"Enable both for right-click harvesting for crops" = true
 	#Disable/enable grass blocks dropping seeds.
 	"Enable grass blocks dropping seeds" = false
-	#Disable/enable right-click harvesting of crops.
-	"Enable right-click harvesting for crops" = true
 
 ["Dimensions Settings"]
 	#Enter a dimension id to whitelist feature generation
@@ -46,5 +46,5 @@
 
 ["Right-click Harvesting Settings"]
 	#Disable/enable right-click harvesting of crops
-	"Enable right-click harvesting for crops" = true
+	"Enable both for right-click harvesting for crops" = true
 
diff --git a/configuration/services/configs/minecraft/voor-kia/config/pamhc2trees.toml b/configuration/services/configs/minecraft/voor-kia/config/pamhc2trees.toml
index 920fcfa..d04d4fe 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/pamhc2trees.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/pamhc2trees.toml
@@ -6,8 +6,6 @@
 	"Enable tall grass blocks dropping seeds" = false
 	#Disable/enable grass blocks dropping seeds.
 	"Enable grass blocks dropping seeds" = false
-	#Disable/enable right-click harvesting of crops.
-	"Enable right-click harvesting for crops" = true
 
 ["Dimensions Settings"]
 	#Enter a dimension id to whitelist feature generation
@@ -126,7 +124,3 @@
 	#Should paperbark trees generate in world
 	"Generate paperbark trees" = true
 
-["Right-click Harvesting Settings"]
-	#Disable/enable right-click harvesting of crops
-	"Enable right-click harvesting for crops" = true
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/performant-common.toml b/configuration/services/configs/minecraft/voor-kia/config/performant-common.toml
index f74a808..07a2e01 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/performant-common.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/performant-common.toml
@@ -44,32 +44,41 @@ displayTooLargePackets = true
 	#Entity spawn interval setting, determines how frequently entities are spawned overall. 1 = Vanilla default, default = 10
 	#Range: 1 ~ 1000
 	spawnInterval = 10
+	#List of entities excluded from beeing affected by dynamic entity updates: e.g. format :  ["minecraft:zombie", "minecraft:creeper"]
+	excludedTickDistanceMobs = []
 	#Fix leash lag from entities on a leash, default = true
 	fixLeash = true
+	#Enable multithreading support for entities, requires fastCollisions to be enabled. default = true
+	multiEntities = true
+	#Disables block changes notifying all entity paths in the world, to possibly adjust their paths, disable with IE, incompat, default = true
+	disableNotifyOnBlockChange = true
 	#Slower updating of armor stands, default = true
 	slowArmorStands = true
 	#Enables improved entity collision and movement calculations for any non item entity, default = true
 	fastCollisions = true
 	#Enables less laggy entity item pickup, default = true
 	noLagItemPickup = true
-	#Enable multithreading support for entities, requires fastCollisions to be enabled. default = true
-	multiEntities = true
-	#Disables block changes notifying all entity paths in the world, to possibly adjust their paths, disable with IE, incompat, default = true
-	disableNotifyOnBlockChange = true
+	#Enables dynamic update distance, it will reduces entity updates when far away from the player, respecting the entities own update range. default = true. Requires restart
+	enableDynamicEntityUpdates = true
 	#Enables fast itemstack comparisons
 	fastItemCompare = true
 	#Entity density setting, determines how many entities are spawned overall. 1 = Vanilla default, 0.1 e.g 10x less than vanilla. 10 = 10x more than vanilla, default = 1
 	#Range: 0.01 ~ 100.0
 	entityDensity = 1.0
+	#Enables dynamic entity rendering, stops non-visible entities from beeing rendered but can sometimes cause a slight phasing-in delay. Usually a large boost to fps, default = true. Require restart
+	enableDynamicEntityRendering = true
 	#Enable fast inventory advancement triggers, many advancements based on items tend to lag the players, default = true
 	fastInventoryAdvancement = true
 	#Adapt entity speed to tps, makes entities struggle less with lag. default = true
 	adaptiveSpeed = true
+	#Entity dynamic update distance setting, reduces the entities own update range from players at which entities get slowed down, in chunks(16blocks). The higher you set this, the closer to the player entities will get slower updates. Default = 0
+	#Range: 0 ~ 1000
+	entityUpdateDistanceReduction = 0
 	#Enable faster pathfinding, default = true
 	fastPathFinding = true
 
 ["Entity AI Settings"]
-	#Sets the tick interval in which non-running AI tasks are rechecked. Vanilla default is 1(starting with 1.13+), this mods suggested default is 4(as it was in 1.12)
+	#Sets the tick interval in which non-running AI tasks are rechecked. Vanilla default is 1(starting with 1.13+), this mods suggested default is 4(as it was in vanilla 1.12)
 	#Range: 1 ~ 500
 	goalselectorrate = 4
 	#Enables a slower updated AI Fox find shelter goal, which causes too much load. default = true
@@ -115,9 +124,15 @@ displayTooLargePackets = true
 	disableConfigReload = false
 	#Enable printing of world/chunk saves for debugging purposes, those normally happen every 5minutes. default = false
 	printWorldSaves = false
+	#Set the watchdog timeout for the integrated server in miliseconds, -1 Disables it. 1 second = 1000 miliseconds, default = 180000
+	#Range: -1 ~ 500000
+	singlePlayerWatchDogTimeout = 180000
 	#Set the ingame disconnect timeout for disconnecting players. Default = 60sec
 	#Range: 15 ~ 400
 	disconnectTimeout = 60
+	#Set the maximum allowed amount of same sounds playing at the same time. Lowers e.g. lag of flowing water and other cases where a sound is repeated a lot at once. Default = 10
+	#Range: 1 ~ 4000
+	maxSameSounds = 10
 	#List of mobs disallowed from spawning: e.g. format :  ["minecraft:zombie", "minecraft:creeper"]
 	forbiddenMobs = []
 
diff --git a/configuration/services/configs/minecraft/voor-kia/config/quark-common.toml b/configuration/services/configs/minecraft/voor-kia/config/quark-common.toml
index 7e648cb..8a6398b 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/quark-common.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/quark-common.toml
@@ -1,36 +1,26 @@
 
 [general]
+	#Allowed values: (0,)
+	"Advancement Visibility Depth" = 2
 	"'q' Button on the Right" = false
-	#
 	#Allowed values: (0,)
 	"Piston Push Limit" = 12
-	#
 	#Set to true to make the quark big worldgen features such as stone clusters or underground biomes generate as spheres rather than unique shapes. It's faster, but won't look as cool
 	"Use Fast Worldgen" = false
 	"Enable 'q' Button" = true
-	#
 	#A list of screens that don't play well with quark's buttons. Use "Print Screen Classnames" to find the names of any others you'd want to add.
 	"Ignored Screens" = ["blusunrize.immersiveengineering.client.gui.CraftingTableScreen", "com.tfar.craftingstation.client.CraftingStationScreen", "com.refinedmods.refinedstorage.screen.grid.GridScreen", "appeng.client.gui.implementations.CraftingTermScreen", "appeng.client.gui.implementations.PatternTermScreen", "com.blakebr0.extendedcrafting.client.screen.EliteTableScreen", "com.blakebr0.extendedcrafting.client.screen.EliteAutoTableScreen", "com.blakebr0.extendedcrafting.client.screen.UltimateTableScreen", "com.blakebr0.extendedcrafting.client.screen.UltimateAutoTableScreen", "me.desht.modularrouters.client.gui.filter.GuiFilterScreen", "com.resourcefulbees.resourcefulbees.client.gui.screen.CentrifugeScreen", "com.resourcefulbees.resourcefulbees.client.gui.screen.MechanicalCentrifugeScreen", "com.resourcefulbees.resourcefulbees.client.gui.screen.CentrifugeMultiblockScreen"]
 	"Use Anti Overlap" = true
-	#
-	#Quark messes with the Stonecutter to allow any item that can be used in it to be shift clicked in. Set this to false to turn it off.
-	"Hack Stonecutter Shift Click" = true
-	#
 	#Enables quark network profiling features. Do not enable this unless requested to.
 	"Enable Network Profiling" = false
-	#
 	#Quark replaces the Piston logic to allow for its piston features to work. If you're having troubles, try turning this off.
 	"Use Piston Logic Replacement" = true
-	#
 	#Set to true if you need to find the class name for a screen that's causing problems
 	"Print Screen Classnames" = false
-	#
 	#Blocks that Quark should treat as Shulker Boxes.
 	"Shulker Boxes" = ["minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box", "minecraft:light_gray_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box", "minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box"]
-	#
 	#Set to true to enable a system that debugs quark's worldgen features. This should ONLY be used if you're asked to by a dev.
 	"Enable Worldgen Watchdog" = false
-	#
 	#Should Quark treat anything with 'shulker_box' in its item identifier as a shulker box?
 	"Interpret Shulker Box Like Blocks" = true
 
@@ -52,6 +42,7 @@
 	"Weather Sensor" = true
 	"Ender Watcher" = true
 	"Endermites Form Shulkers" = true
+	"Jukebox Automation" = true
 	"Chains Connect Blocks" = true
 	"Color Slime" = true
 	"Dispensers Place Blocks" = true
@@ -67,7 +58,6 @@
 		Blacklist = ["minecraft:water", "minecraft:lava", "minecraft:fire"]
 
 	[automation.chain_linkage]
-		#
 		#Can vehicle-linking chains be used for crafting chain armor?
 		"Crafts Armor" = true
 
@@ -83,6 +73,7 @@
 		Chance = 0.005
 
 	[automation.pistons_move_tile_entities]
+		"Enable Chests Moving Together" = true
 		"Render Blacklist" = ["psi:programmer", "botania:starfield"]
 		"Movement Blacklist" = ["minecraft:spawner", "integrateddynamics:cable", "randomthings:blockbreaker", "minecraft:ender_chest", "minecraft:enchanting_table", "minecraft:trapped_chest", "quark:spruce_trapped_chest", "quark:birch_trapped_chest", "quark:jungle_trapped_chest", "quark:acacia_trapped_chest", "quark:dark_oak_trapped_chest", "endergetic:bolloom_bud"]
 		"Delayed Update List" = ["minecraft:dispenser", "minecraft:dropper"]
@@ -91,49 +82,30 @@
 		"Change Name" = true
 
 	[automation.feeding_trough]
-		#
 		#The chance (between 0 and 1) for an animal to enter love mode when eating from the trough
 		#Allowed values: (0,1]
 		"Love Chance" = 0.333333333
-		#
 		#How long, in game ticks, between animals being able to eat from the trough
 		#Allowed values: [1,)
 		Cooldown = 30
-		#
 		#The maximum amount of animals allowed around the trough's range for an animal to enter love mode
 		"Max Animals" = 32
 		Range = 10.0
 
 [building]
-	"Duskbound Blocks" = true
-	"Bamboo Mat" = true
 	"Cobblestone Bricks" = true
-	"More Brick Types" = true
-	"Gold Bars" = true
-	"Soul Sandstone" = true
 	"Burn Vines" = true
 	"Quilted Wool" = true
-	"Compressed Blocks" = true
-	Stools = true
-	Thatch = true
+	"Celebratory Lamps" = true
 	"Variant Chests" = true
-	"Variant Ladders" = true
 	Hedges = true
 	"Vertical Slabs" = true
-	Shingles = true
 	"Nether Brick Fence Gate" = true
-	"Item Frames" = true
-	"Stained Planks" = true
-	"Wooden Posts" = true
-	"Leaf Carpet" = true
 	"Lit Lamp" = true
 	"Vertical Planks" = true
-	Midori = true
 	"Tie Leads To Fences" = true
 	"Shallow Dirt" = true
 	"More Stone Variants" = true
-	"Framed Glass" = true
-	"Tallow And Candles" = true
 	Turf = true
 	"Paper Decor" = true
 	Rope = true
@@ -142,10 +114,39 @@
 	"More Potted Plants" = true
 	Grate = true
 	"Variant Bookshelves" = true
+	"Duskbound Blocks" = true
+	"Bamboo Mat" = true
+	"More Brick Types" = true
+	"Gold Bars" = true
+	"Soul Sandstone" = true
+	"Compressed Blocks" = true
+	Stools = true
+	Thatch = true
+	"Variant Ladders" = true
+	Shingles = true
+	"Item Frames" = true
+	"Stained Planks" = true
+	"Wooden Posts" = true
+	"Leaf Carpet" = true
+	Midori = true
+	"Framed Glass" = true
+	"Tallow And Candles" = true
+
+	[building.thatch]
+		#Allowed values: [0,1]
+		"Fall Damage Multiplier" = 0.5
+
+	[building.item_frames]
+		"Glass Item Frames Update Maps" = true
+
+	[building.cobblestone_bricks]
+		"Enable Basalt Bricks" = true
+		"Enable Netherrack Bricks" = true
+		"Enable Dirt Bricks" = true
+		"Enable Blackstone Bricks" = true
 
 	[building.rope]
 		"Enable Dispenser Behavior" = true
-		#
 		#Set to true to allow ropes to move Tile Entities even if Pistons Push TEs is disabled.
 		#Note that ropes will still use the same blacklist.
 		"Force Enable Move Tile Entities" = false
@@ -156,11 +157,6 @@
 		"Enable Chiseled Bricks" = true
 		"Enable Pavement" = true
 
-	[building.thatch]
-		#
-		#Allowed values: [0,1]
-		"Fall Damage Multiplier" = 0.5
-
 	[building.variant_ladders]
 		"Change Names" = true
 		"Enable Iron Ladder" = true
@@ -182,56 +178,49 @@
 		"Enable Blaze Lantern" = true
 		"Enable Bamboo Block" = true
 		"Enable Berry Sack" = true
-		#
 		#Allowed values: [0,)
 		"Bamboo Bundle Fuel Time" = 500
 		"Enable Golden Apple Crate" = true
 		"Enable Sugar Cane Block" = true
 		"Enable Bonded Leather" = true
-		#
 		#Allowed values: [0,)
 		"Blaze Lantern Fuel Time" = 24000
-		#
 		#Allowed values: [0,)
 		"Charcoal Block Fuel Time" = 16000
-		#
 		#Allowed values: [0,)
 		"Stick Block Fuel Time" = 900
 
 	[building.variant_chests]
+		"Enable Reverting Wooden Chests" = true
 		"Replace Worldgen Chests" = true
-		#
 		#Chests to put in each structure. The format per entry is "structure=chest", where "structure" is a structure ID, and "chest" is a block ID, which must correspond to a standard chest block.
 		"Structure Chests" = ["minecraft:village_plains=quark:oak_chest", "minecraft:igloo=quark:spruce_chest", "minecraft:village_snowy=quark:spruce_chest", "minecraft:village_taiga=quark:spruce_chest", "minecraft:desert_pyramid=quark:birch_chest", "minecraft:jungle_pyramid=quark:jungle_chest", "minecraft:village_desert=quark:jungle_chest", "minecraft:village_savanna=quark:acacia_chest", "minecraft:mansion=quark:dark_oak_chest", "minecraft:pillager_outpost=quark:dark_oak_chest", "minecraft:ruined_portal=quark:crimson_chest", "minecraft:bastion_remnant=quark:crimson_chest", "minecraft:fortress=quark:nether_brick_chest", "minecraft:endcity=quark:purpur_chest", "bettermineshafts:mineshaft=quark:oak_chest", "cobbler:shulker_factory=quark:purpur_chest", "conjurer_illager:theatre=quark:dark_oak_chest", "dungeoncrawl:dungeon=quark:oak_chest", "dungeons_plus:bigger_dungeon=quark:oak_chest", "dungeons_plus:end_ruins=quark:purpur_chest", "dungeons_plus:leviathan=quark:jungle_chest", "dungeons_plus:snowy_temple=quark:spruce_chest", "dungeons_plus:soul_prison=quark:warped_chest", "dungeons_plus:tower=quark:oak_chest", "dungeons_plus:warped_garden=quark:warped__chest", "hunterillager:hunterhouse=quark:oak_chest", "iceandfire:gorgon_temple=quark:jungle_chest", "pandoras_creatures:end_prison=quark:purpur_chest", "repurposed_structures:fortress_jungle=quark:jungle_chest", "repurposed_structures:igloo_grassy=quark:oak_chest", "repurposed_structures:igloo_stone=quark:spruce_chest", "repurposed_structures:mineshaft_birch=quark:birch_chest", "repurposed_structures:mineshaft_desert=quark:jungle_chest", "repurposed_structures:mineshaft_end=quark:purpur_chest", "repurposed_structures:mineshaft_icy=quark:spruce_chest", "repurposed_structures:mineshaft_jungle=quark:jungle_chest", "repurposed_structures:mineshaft_nether=quark:nether_brick_chest", "repurposed_structures:mineshaft_ocean=quark:prismarine_chest", "repurposed_structures:mineshaft_savanna=quark:acacia_chest", "repurposed_structures:mineshaft_stone=quark:spruce_chest", "repurposed_structures:mineshaft_swamp_or_dark_forest=quark:dark_oak_chest", "repurposed_structures:mineshaft_taiga=quark:spruce_chest", "repurposed_structures:outpost_badlands=quark:dark_oak_chest", "repurposed_structures:outpost_birch=quark:birch_chest", "repurposed_structures:outpost_crimson=quark:crimson_chest", "repurposed_structures:outpost_desert=quark:jungle_chest", "repurposed_structures:outpost_giant_tree_taiga=quark:spruce_chest", "repurposed_structures:outpost_icy=quark:spruce_chest", "repurposed_structures:outpost_jungle=quark:jungle_chest", "repurposed_structures:outpost_nether_brick=quark:nether_brick_chest", "repurposed_structures:outpost_snowy=quark:spruce_chest", "repurposed_structures:outpost_warped=quark:warped_chest", "repurposed_structures:pyramid_badlands=quark:dark_oak_chest", "repurposed_structures:pyramid_nether=quark:nether_brick_chest", "repurposed_structures:ruined_portal_end=quark:purpur_chest", "repurposed_structures:shipwreck_crimson=quark:crimson_chest", "repurposed_structures:shipwreck_end=quark:purpur_chest", "repurposed_structures:shipwreck_nether_bricks=quark:nether_brick_chest", "repurposed_structures:shipwreck_warped=quark:warped_chest", "repurposed_structures:stronghold_nether=quark:nether_brick_chest", "repurposed_structures:stronghold_stonebrick=quark:oak_chest", "repurposed_structures:temple_nether_basalt=quark:nether_brick_chest", "repurposed_structures:temple_nether_crimson=quark:crimson_chest", "repurposed_structures:temple_nether_soul=quark:warped_chest", "repurposed_structures:temple_nether_warped=quark:warped_chest", "repurposed_structures:temple_nether_wasteland=quark:nether_brick_chest", "repurposed_structures:village_badlands=quark:dark_oak_chest", "repurposed_structures:village_birch=quark:birch_chest", "repurposed_structures:village_crimson=quark:crimson_chest", "repurposed_structures:village_dark_oak=quark:dark_oak_chest", "repurposed_structures:village_giant_taiga=quark:spruce_chest", "repurposed_structures:village_jungle=quark:jungle_chest", "repurposed_structures:village_mountains=quark:spruce_chest", "repurposed_structures:village_oak=quark:oak_chest", "repurposed_structures:village_swamp=quark:oak_chest", "repurposed_structures:village_warped=quark:warped_chest", "valhelsia_structures:castle=quark:spruce_chest", "valhelsia_structures:castle_ruin=quark:oak_chest", "valhelsia_structures:desert_house=quark:spruce_chest", "valhelsia_structures:forge=quark:spruce_chest", "valhelsia_structures:player_house=quark:oak_chest", "valhelsia_structures:small_castle=quark:oak_chest", "valhelsia_structures:small_dungeon=quark:oak_chest", "valhelsia_structures:tower_ruin=quark:spruce_chest"]
 
 	[building.more_brick_types]
 		"Enable Magma Bricks" = true
 		"Enable Sandy Bricks" = true
-		#
 		#This also comes with a utility recipe for Red Nether Bricks
 		"Enable Blue Nether Bricks" = true
 		"Enable Blackstone Variant Bricks" = true
 		"Enable Charred Nether Bricks" = true
 		"Enable Snow Bricks" = true
-		#
 		#This also includes Red Sandstone Bricks and Soul Sandstone Bricks
 		"Enable Sandstone Bricks" = true
 
 	[building.tallow_and_candles]
 		"Candles Fall" = true
-		#
 		#Allowed values: [0,)
 		"Tallow Burn Time" = 200
-		#
 		#Allowed values: [0,)
 		"Max Drop" = 3
-		#
 		#Allowed values: [0,15]
 		"Enchant Power" = 1.0
-		#
 		#Allowed values: [0,)
 		"Min Drop" = 1
 
+	[building.celebratory_lamps]
+		"Light Level" = 15
+
 	[building.variant_bookshelves]
 		"Change Names" = true
 
@@ -245,7 +234,6 @@
 	"Easy Transfering" = true
 
 	[management.inventory_sorting]
-		#
 		#Play a click when sorting inventories using keybindings
 		"Satisfying Click" = true
 		"Enable Chests" = true
@@ -260,6 +248,7 @@
 
 [tools]
 	Pickarang = true
+	"Ambient Discs" = true
 	"Seed Pouch" = true
 	"Pathfinder Maps" = true
 	"Bottled Cloud" = true
@@ -268,10 +257,13 @@
 	"Slime In A Bucket" = true
 	Camera = true
 	Trowel = true
+	Abacus = true
+
+	[tools.ambient_discs]
+		"Drop On Spider Kill" = true
 
 	[tools.trowel]
-		#
-		#Amount of blocks placed is this value + 1. Default is 255 (4 stacks).
+		#Amount of blocks placed is this value + 1.
 		#Set to 0 to make the Trowel unbreakable
 		#Allowed values: [0,)
 		"Trowel Max Durability" = 255
@@ -281,34 +273,26 @@
 		"Cloud Level Bottom" = 127
 
 	[tools.ancient_tomes]
-		#
+		"Normal Upgrade Cost" = 10
+		"Valid Enchantments" = ["minecraft:feather_falling", "minecraft:thorns", "minecraft:sharpness", "minecraft:smite", "minecraft:bane_of_arthropods", "minecraft:knockback", "minecraft:fire_aspect", "minecraft:looting", "minecraft:sweeping", "minecraft:efficiency", "minecraft:unbreaking", "minecraft:fortune", "minecraft:power", "minecraft:punch", "minecraft:luck_of_the_sea", "minecraft:lure", "minecraft:loyalty", "minecraft:riptide", "minecraft:impaling", "minecraft:piercing"]
+		"Item Quality" = 2
 		#Set to 0 to not generate in Underwater Ruins
 		"Underwater Ruin Weight" = 0
-		#
 		#Set to 0 to not generate in Woodland Mansions
 		"Woodland Mansion Weight" = 15
-		"Valid Enchantments" = ["minecraft:feather_falling", "minecraft:thorns", "minecraft:sharpness", "minecraft:smite", "minecraft:bane_of_arthropods", "minecraft:knockback", "minecraft:fire_aspect", "minecraft:looting", "minecraft:sweeping", "minecraft:efficiency", "minecraft:unbreaking", "minecraft:fortune", "minecraft:power", "minecraft:punch", "minecraft:luck_of_the_sea", "minecraft:lure", "minecraft:loyalty", "minecraft:riptide", "minecraft:impaling", "minecraft:piercing"]
-		#
 		#Set to 0 to not generate in Dungeons
 		"Dungeon Weight" = 20
-		"Item Quality" = 2
-		"Apply Cost" = 35
-		#
+		"Limit Break Upgrade Cost" = 30
 		#Set to 0 to not generate in Stronghold Libraries
 		"Library Weight" = 30
-		#
 		#Set to 0 to not generate in Nether Fortresses
 		"Nether Fortress Weight" = 0
-		#
 		#Set to 0 to not generate in Bastions
 		"Bastion Weight" = 25
-		#
 		#Set to 0 to not generate in Monster Boxes
 		"Monster Box Weight" = 5
-		"Merge Cost" = 35
 
 	[tools.pathfinder_maps]
-		#
 		#In this section you can add custom Pathfinder Maps. This works for both vanilla and modded biomes.
 		#Each custom map must be on its own line.
 		#The format for a custom map is as follows:
@@ -325,6 +309,8 @@
 		#Here's an example of a map to locate Ice Mountains:
 		#minecraft:ice_mountains,2,8,14,7FE4FF,Ice Mountains Pathfinder Map
 		Customs = []
+		"Search Radius" = 6400
+		"Search Distance Increment" = 8
 		"Xp From Trade" = 5
 
 	[tools.seed_pouch]
@@ -341,28 +327,20 @@
 		"Nether Fortress Weight" = 8
 
 	[tools.pickarang]
-		#
 		#22.5 is ender chests, 25.0 is monster boxes, 50 is obsidian. Most things are below 5.
 		"Max Hardness" = 20.0
-		#
 		#2 is Iron, 3 is Diamond.
 		"Harvest Level" = 3
-		#
 		#2 is Iron, 3 is Diamond.
 		"Netherite Harvest Level" = 3
-		#
 		#How long it takes before the pickarang starts returning to the player if it doesn't hit anything.
 		Timeout = 20
-		#
 		#Set to -1 to have the Pickarang be unbreakable.
 		Durability = 800
-		#
 		#Set this to true to disable the short cooldown between throwing pickarangs.
 		"No Cooldown" = false
-		#
 		#Set to -1 to have the Flamerang be unbreakable.
 		"Netherite Durability" = 1040
-		#
 		#Set this to true to use the recipe without the Heart of Diamond, even if the Heart of Diamond is enabled.
 		"Never Use Heart Of Diamond" = false
 
@@ -395,17 +373,17 @@
 	"Snow Golem Player Heads" = true
 	"Glass Shard" = true
 	"Campfires Boost Elytra" = true
+	"More Banner Layers" = true
+	"Better Elytra Rocket" = true
 
 	[tweaks.sign_editing]
 		"Requires Empty Hand" = false
 
 	[tweaks.pat_the_dogs]
-		#
 		#How many ticks it takes for a dog to want affection after being pet/tamed; leave -1 to disable
 		"Dogs Want Love" = -1
 
 	[tweaks.automatic_recipe_unlock]
-		#
 		#A list of recipe names that should NOT be added in by default
 		"Ignored Recipes" = []
 		"Disable Recipe Book" = false
@@ -418,7 +396,6 @@
 		"Pike Range" = 5.0
 
 	[tweaks.infinity_bucket]
-		#
 		#Set this to false to prevent dispensers from using infinite water buckets
 		"Allow Dispensers To Use" = true
 		Cost = 10
@@ -428,45 +405,32 @@
 		Chance = 0.1
 
 	[tweaks.utility_recipes]
-		#
 		#Can you craft four chests at once using logs?
 		"Logs To Chests" = true
-		#
 		#Can other stone-like materials be used for crafting stone tools?
 		"Better Stone Tool Crafting" = true
-		#
 		#Can a dispenser be crafted by adding a bow to a dropper?
 		"Enable Dispenser" = true
-		#
 		#Can cookies, paper, and bread be crafted in a 2x2 crafting table?
 		"Bent Recipes" = true
-		#
 		#Can Rotten Flesh and Poisonous Potatoes be composted?
 		"Compostable Toxins" = true
-		#
 		#Can bones be smelted down to bone meal?
 		"Bone Meal Utility" = true
-		#
 		#Can any wool color be dyed?
 		"Dye Any Wool" = true
-		#
 		#Can Coral be crafted into dye?
 		"Coral To Dye" = true
-		#
 		#Can torches can be used as fuel in furnaces?
 		"Torches Burn" = true
-		#
 		#Can a repeater be crafted with the pattern for a redstone torch?
 		"Enable Repeater" = true
-		#
 		#Can you craft a minecart around blocks which can be placed inside?
 		"Enable Minecarts" = true
-		#
 		#Does Dragon Breath return a bottle when used as a reagent or material?
 		"Effective Dragon Breath" = true
 
 	[tweaks.reacharound_placing]
-		#
 		#Allowed values: [0,1]
 		Leniency = 0.5
 		Whitelist = []
@@ -475,43 +439,33 @@
 
 	[tweaks.improved_sleeping]
 		"Enable Afk" = true
-		#
 		#Allowed values: (0,)
 		"Afk Time" = 2400
-		#
 		#Allowed values: (0,1]
 		"Percent Req" = 0.5
 
 	[tweaks.emotes]
-		#
 		#The enabled default emotes. Remove from this list to disable them. You can also re-order them, if you feel like it.
 		"Enabled Emotes" = ["no", "yes", "wave", "salute", "cheer", "clap", "think", "point", "shrug", "headbang", "weep", "facepalm"]
-		#
 		#Enable this to make custom emotes read the file every time they're triggered so you can edit on the fly.
 		#DO NOT ship enabled this in a modpack, please.
 		"Custom Emote Debug" = false
-		#
 		#The list of Custom Emotes to be loaded.
 		#Watch the tutorial on Custom Emotes to learn how to make your own: https://youtu.be/ourHUkan6aQ
 		"Custom Emotes" = []
 
 	[tweaks.simple_harvest]
-		#
 		#Can players harvest crops with empty hand clicks?
 		"Empty Hand Harvest" = true
-		#
 		#Does harvesting crops with a hoe cost durability?
 		"Harvesting Costs Durability" = false
-		#
 		#Should Quark look for (nonvanilla) crops, and handle them?
 		"Do Harvesting Search" = true
-		#
 		#Which crops can be harvested?
 		#Format is: "harvestState[,afterHarvest]", i.e. "minecraft:wheat[age=7]" or "minecraft:cocoa[age=2,facing=north],minecraft:cocoa[age=0,facing=north]"
 		"Harvestable Blocks" = ["minecraft:wheat[age=7]", "minecraft:carrots[age=7]", "minecraft:potatoes[age=7]", "minecraft:beetroots[age=3]", "minecraft:nether_wart[age=3]", "minecraft:cocoa[age=2,facing=north],minecraft:cocoa[age=0,facing=north]", "minecraft:cocoa[age=2,facing=south],minecraft:cocoa[age=0,facing=south]", "minecraft:cocoa[age=2,facing=east],minecraft:cocoa[age=0,facing=east]", "minecraft:cocoa[age=2,facing=west],minecraft:cocoa[age=0,facing=west]"]
 
 	[tweaks.enhanced_ladders]
-		#
 		#Allowed values: (,0]
 		"Fall Speed" = -0.2
 
@@ -526,10 +480,13 @@
 		"Max Speed" = 1.0
 
 	[tweaks.replace_scaffolding]
-		#
 		#How many times the algorithm for finding out where a block would be placed is allowed to turn. If you set this to large values (> 3) it may start producing weird effects.
 		"Max Bounces" = 1
 
+	[tweaks.more_banner_layers]
+		#Allowed values: [1,16]
+		"Layer Limit" = 16
+
 [world]
 	"New Stone Types" = true
 	"Lush Underground Biome" = true
@@ -556,10 +513,10 @@
 	"Overgrown Underground Biome" = true
 	"Cave Roots" = true
 	"Spider Nest Underground Biome" = true
+	Deepslate = true
 	"Monster Box" = true
 
 	[world.monster_box]
-		#
 		#The chance for the monster box generator to try and place one in a chunk, 1 is 100%
 		#This can be higher than 100% if you want multiple per chunk, , 0 is 0%
 		"Chance Per Chunk" = 0.8
@@ -568,7 +525,6 @@
 		"Max Y" = 30
 		"Max Mob Count" = 8
 		"Enable Extra Loot Table" = true
-		#
 		#How many blocks to search vertically from a position before trying to place a block. Higher means you'll get more boxes in open spaces.
 		"Search Range" = 6
 
@@ -577,44 +533,43 @@
 			"Is Blacklist" = false
 
 	[world.cave_crystal_underground_biome]
-		#
 		#The chance that a crystal can grow, this is on average 1 in X world ticks, set to a higher value to make them grow slower. Minimum is 1, for every tick. Set to 0 to disable growth.
 		"Cave Crystal Growth Chance" = 5
-		"Crystals Grow In Lava" = false
-		#
 		#Allowed values: [0,1]
-		"Crystal Spawn Chance" = 0.025
+		"Crystal Chance" = 0.16
+		#Allowed values: [0,1]
+		"Crystal Cluster On Sides Chance" = 0.6
+		#Allowed values: [0,1]
+		"Crystal Cluster Chance" = 0.2
+		#Allowed values: [0,1]
+		"Double Crystal Chance" = 0.2
+		"Enable Collateral Movement" = true
+		"Enable Beacon Redirection" = true
 		"Crystals Craft Runes" = true
 
 		[world.cave_crystal_underground_biome.biome_settings]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 42
-			#
 			#Allowed values: [0,)
 			Rarity = 400
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 0
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 22
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 64
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 18
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 8
 
 			[world.cave_crystal_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["ocean"]
+				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+				# jungle, spooky, dead, lush, mushroom, magical, rare,
+				# plateau, modified, ocean, river, water, mesa, forest,
+				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+				# beach, void, overworld, nether, end]
+				"Biome Types" = ["ocean"]
 				"Is Blacklist" = true
 
 			[world.cave_crystal_underground_biome.biome_settings.dimensions]
@@ -624,6 +579,7 @@
 	[world.speleothems]
 		"Tries Per Chunk In Nether" = 4
 		"Speleothems Per Chunk In Nether" = 12
+		"Small Speleothems Increase Fall Damage" = true
 		"Speleothems Per Chunk" = 12
 		"Max Ylevel" = 55
 		"Tries Per Chunk" = 60
@@ -635,34 +591,28 @@
 	[world.sandstone_underground_biome]
 
 		[world.sandstone_underground_biome.biome_settings]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 26
-			#
 			#Allowed values: [0,)
 			Rarity = 80
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 0
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 14
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 64
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 14
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 6
 
 			[world.sandstone_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["desert"]
+				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+				# jungle, spooky, dead, lush, mushroom, magical, rare,
+				# plateau, modified, ocean, river, water, mesa, forest,
+				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+				# beach, void, overworld, nether, end]
+				"Biome Types" = ["sandy"]
 				"Is Blacklist" = false
 
 			[world.sandstone_underground_biome.biome_settings.dimensions]
@@ -672,28 +622,35 @@
 	[world.spiral_spires]
 		Radius = 15
 		Rarity = 200
-		#
 		#Set to 0 to turn off Myalite Conduits
 		"Myalite Conduit Distance" = 24
 		"Renewable Myalite" = true
 
 		[world.spiral_spires.biomes]
-			Biomes = ["minecraft:end_highlands"]
-			"Is Blacklist" = false
+
+			[world.spiral_spires.biomes.types]
+				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+				# jungle, spooky, dead, lush, mushroom, magical, rare,
+				# plateau, modified, ocean, river, water, mesa, forest,
+				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+				# beach, void, overworld, nether, end]
+				"Biome Types" = []
+				"Is Blacklist" = true
+
+			[world.spiral_spires.biomes.biomes]
+				Biomes = ["minecraft:end_highlands"]
+				"Is Blacklist" = false
 
 		[world.spiral_spires.dimensions]
 			Dimensions = ["minecraft:the_end"]
 			"Is Blacklist" = false
 
 	[world.nether_obsidian_spikes]
-		#
 		#The chance for a chunk to contain spikes (1 is 100%, 0 is 0%)
 		"Chance Per Chunk" = 0.1
 		"Big Spike Spawners" = true
-		#
 		#Should a chunk have spikes, how many would the generator try to place
 		"Tries Per Chunk" = 4
-		#
 		#The chance for a spike to be big (1 is 100%, 0 is 0%)
 		"Big Spike Chance" = 0.03
 
@@ -712,50 +669,40 @@
 			"Is Blacklist" = false
 
 		[world.biotite.ore_settings]
-			#
 			#Allowed values: [0,255]
 			"Max Height" = 64
-			#
 			#Allowed values: [0,)
 			"Cluster Count" = 16
-			#
 			#Allowed values: [0,255]
 			"Min Height" = 1
-			#
 			#Allowed values: [0,)
 			"Cluster Size" = 14
 
 	[world.crevices]
 
 		[world.crevices.spawn_settings]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 60
-			#
 			#Allowed values: [0,)
 			Rarity = 120
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 15
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 20
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 50
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 4
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 1
 
 			[world.crevices.spawn_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["ocean", "beach"]
+				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+				# jungle, spooky, dead, lush, mushroom, magical, rare,
+				# plateau, modified, ocean, river, water, mesa, forest,
+				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+				# beach, void, overworld, nether, end]
+				"Biome Types" = ["ocean", "beach"]
 				"Is Blacklist" = true
 
 			[world.crevices.spawn_settings.dimensions]
@@ -787,16 +734,12 @@
 		[world.new_stone_types.marble]
 
 			[world.new_stone_types.marble.oregen]
-				#
 				#Allowed values: [0,255]
-				"Max Height" = 256
-				#
+				"Max Height" = 255
 				#Allowed values: [0,)
 				"Cluster Count" = 10
-				#
 				#Allowed values: [0,255]
 				"Min Height" = 0
-				#
 				#Allowed values: [0,)
 				"Cluster Size" = 33
 
@@ -807,16 +750,12 @@
 		[world.new_stone_types.limestone]
 
 			[world.new_stone_types.limestone.oregen]
-				#
 				#Allowed values: [0,255]
-				"Max Height" = 256
-				#
+				"Max Height" = 255
 				#Allowed values: [0,)
 				"Cluster Count" = 10
-				#
 				#Allowed values: [0,255]
 				"Min Height" = 0
-				#
 				#Allowed values: [0,)
 				"Cluster Size" = 33
 
@@ -827,16 +766,12 @@
 		[world.new_stone_types.myalite]
 
 			[world.new_stone_types.myalite.oregen]
-				#
 				#Allowed values: [0,255]
-				"Max Height" = 256
-				#
+				"Max Height" = 255
 				#Allowed values: [0,)
 				"Cluster Count" = 10
-				#
 				#Allowed values: [0,255]
 				"Min Height" = 0
-				#
 				#Allowed values: [0,)
 				"Cluster Size" = 33
 
@@ -847,16 +782,12 @@
 		[world.new_stone_types.voidstone]
 
 			[world.new_stone_types.voidstone.oregen]
-				#
 				#Allowed values: [0,255]
-				"Max Height" = 256
-				#
+				"Max Height" = 255
 				#Allowed values: [0,)
 				"Cluster Count" = 10
-				#
 				#Allowed values: [0,255]
 				"Min Height" = 0
-				#
 				#Allowed values: [0,)
 				"Cluster Size" = 33
 
@@ -867,16 +798,12 @@
 		[world.new_stone_types.slate]
 
 			[world.new_stone_types.slate.oregen]
-				#
 				#Allowed values: [0,255]
-				"Max Height" = 256
-				#
+				"Max Height" = 255
 				#Allowed values: [0,)
 				"Cluster Count" = 10
-				#
 				#Allowed values: [0,255]
 				"Min Height" = 0
-				#
 				#Allowed values: [0,)
 				"Cluster Size" = 33
 
@@ -887,16 +814,12 @@
 		[world.new_stone_types.jasper]
 
 			[world.new_stone_types.jasper.oregen]
-				#
 				#Allowed values: [0,255]
-				"Max Height" = 256
-				#
+				"Max Height" = 255
 				#Allowed values: [0,)
 				"Cluster Count" = 10
-				#
 				#Allowed values: [0,255]
 				"Min Height" = 0
-				#
 				#Allowed values: [0,)
 				"Cluster Size" = 33
 
@@ -908,163 +831,202 @@
 		"Enabled Wrapped" = true
 
 		[world.spider_nest_underground_biome.biome_settings]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 26
-			#
 			#Allowed values: [0,)
 			Rarity = 80
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 0
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 14
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 64
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 14
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 6
 
 			[world.spider_nest_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["plains"]
+				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+				# jungle, spooky, dead, lush, mushroom, magical, rare,
+				# plateau, modified, ocean, river, water, mesa, forest,
+				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+				# beach, void, overworld, nether, end]
+				"Biome Types" = ["plains"]
 				"Is Blacklist" = false
 
 			[world.spider_nest_underground_biome.biome_settings.dimensions]
 				Dimensions = ["minecraft:overworld"]
 				"Is Blacklist" = false
 
+	[world.deepslate]
+		"Sheet Height Variance" = 6
+		"Sheet Y Start" = 0
+		"Sheet Height" = 18
+
+		[world.deepslate.dimensions]
+			Dimensions = ["minecraft:overworld"]
+			"Is Blacklist" = false
+
 	[world.blossom_trees]
 
 		[world.blossom_trees.orange]
 			Rarity = 100
 
+			[world.blossom_trees.orange.biome_config]
+
+				[world.blossom_trees.orange.biome_config.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["savanna"]
+					"Is Blacklist" = false
+
+				[world.blossom_trees.orange.biome_config.biomes]
+					Biomes = []
+					"Is Blacklist" = true
+
 			[world.blossom_trees.orange.dimensions]
 				Dimensions = ["minecraft:overworld"]
 				"Is Blacklist" = false
 
-			[world.blossom_trees.orange.biome_types]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["savanna"]
-				"Is Blacklist" = false
-
 		[world.blossom_trees.red]
 			Rarity = 30
 
+			[world.blossom_trees.red.biome_config]
+
+				[world.blossom_trees.red.biome_config.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["mesa"]
+					"Is Blacklist" = false
+
+				[world.blossom_trees.red.biome_config.biomes]
+					Biomes = []
+					"Is Blacklist" = true
+
 			[world.blossom_trees.red.dimensions]
 				Dimensions = ["minecraft:overworld"]
 				"Is Blacklist" = false
 
-			[world.blossom_trees.red.biome_types]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["mesa"]
-				"Is Blacklist" = false
-
 		[world.blossom_trees.pink]
 			Rarity = 100
 
+			[world.blossom_trees.pink.biome_config]
+
+				[world.blossom_trees.pink.biome_config.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["mountain"]
+					"Is Blacklist" = false
+
+				[world.blossom_trees.pink.biome_config.biomes]
+					Biomes = []
+					"Is Blacklist" = true
+
 			[world.blossom_trees.pink.dimensions]
 				Dimensions = ["minecraft:overworld"]
 				"Is Blacklist" = false
 
-			[world.blossom_trees.pink.biome_types]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["extreme_hills"]
-				"Is Blacklist" = false
-
 		[world.blossom_trees.blue]
 			Rarity = 200
 
+			[world.blossom_trees.blue.biome_config]
+
+				[world.blossom_trees.blue.biome_config.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["snowy"]
+					"Is Blacklist" = false
+
+				[world.blossom_trees.blue.biome_config.biomes]
+					Biomes = []
+					"Is Blacklist" = true
+
 			[world.blossom_trees.blue.dimensions]
 				Dimensions = ["minecraft:overworld"]
 				"Is Blacklist" = false
 
-			[world.blossom_trees.blue.biome_types]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["icy"]
-				"Is Blacklist" = false
-
 		[world.blossom_trees.yellow]
 			Rarity = 200
 
+			[world.blossom_trees.yellow.biome_config]
+
+				[world.blossom_trees.yellow.biome_config.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["plains"]
+					"Is Blacklist" = false
+
+				[world.blossom_trees.yellow.biome_config.biomes]
+					Biomes = []
+					"Is Blacklist" = true
+
 			[world.blossom_trees.yellow.dimensions]
 				Dimensions = ["minecraft:overworld"]
 				"Is Blacklist" = false
 
-			[world.blossom_trees.yellow.biome_types]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["plains"]
-				"Is Blacklist" = false
-
 		[world.blossom_trees.lavender]
 			Rarity = 100
 
+			[world.blossom_trees.lavender.biome_config]
+
+				[world.blossom_trees.lavender.biome_config.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["swamp"]
+					"Is Blacklist" = false
+
+				[world.blossom_trees.lavender.biome_config.biomes]
+					Biomes = []
+					"Is Blacklist" = true
+
 			[world.blossom_trees.lavender.dimensions]
 				Dimensions = ["minecraft:overworld"]
 				"Is Blacklist" = false
 
-			[world.blossom_trees.lavender.biome_types]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["swamp"]
-				"Is Blacklist" = false
-
 	[world.mega_caves]
 
 		[world.mega_caves.spawn_settings]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 80
-			#
 			#Allowed values: [0,)
 			Rarity = 800
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 10
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 30
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 20
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 25
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 10
 
 			[world.mega_caves.spawn_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["ocean", "beach"]
+				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+				# jungle, spooky, dead, lush, mushroom, magical, rare,
+				# plateau, modified, ocean, river, water, mesa, forest,
+				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+				# beach, void, overworld, nether, end]
+				"Biome Types" = ["ocean", "beach"]
 				"Is Blacklist" = true
 
 			[world.mega_caves.spawn_settings.dimensions]
@@ -1076,42 +1038,34 @@
 			"Is Blacklist" = false
 
 	[world.elder_prismarine_underground_biome]
-		#
 		#Allowed values: [0,1]
 		"Lantern Chance" = 0.0085
-		#
 		#Allowed values: [0,1]
 		"Water Chance" = 0.25
 
 		[world.elder_prismarine_underground_biome.biome_settings]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 26
-			#
 			#Allowed values: [0,)
 			Rarity = 200
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 0
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 14
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 64
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 14
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 6
 
 			[world.elder_prismarine_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["ocean"]
+				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+				# jungle, spooky, dead, lush, mushroom, magical, rare,
+				# plateau, modified, ocean, river, water, mesa, forest,
+				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+				# beach, void, overworld, nether, end]
+				"Biome Types" = ["ocean"]
 				"Is Blacklist" = false
 
 			[world.elder_prismarine_underground_biome.biome_settings.dimensions]
@@ -1119,44 +1073,36 @@
 				"Is Blacklist" = false
 
 	[world.glowshroom_underground_biome]
-		#
 		#Allowed values: [0,1]
 		"Glowshroom Spawn Chance" = 0.0625
-		#
 		#Allowed values: (0,)
 		"Glowshroom Growth Rate" = 20
 		"Enable Danger Sight" = true
 		"Enable Huge Glowshrooms" = true
 
 		[world.glowshroom_underground_biome.biome_settings]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 26
-			#
 			#Allowed values: [0,)
 			Rarity = 80
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 0
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 14
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 64
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 14
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 6
 
 			[world.glowshroom_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["extreme_hills", "mushroom"]
+				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+				# jungle, spooky, dead, lush, mushroom, magical, rare,
+				# plateau, modified, ocean, river, water, mesa, forest,
+				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+				# beach, void, overworld, nether, end]
+				"Biome Types" = ["mountain", "mushroom"]
 				"Is Blacklist" = false
 
 			[world.glowshroom_underground_biome.biome_settings.dimensions]
@@ -1164,323 +1110,330 @@
 				"Is Blacklist" = false
 
 	[world.big_stone_clusters]
-		#
 		#Blocks that stone clusters can replace. If you want to make it so it only replaces in one dimension,
 		#do "block|dimension", as we do for netherrack and end stone by default.
 		"Blocks To Replace" = ["minecraft:stone", "minecraft:andesite", "minecraft:diorite", "minecraft:granite", "minecraft:netherrack|minecraft:the_nether", "minecraft:end_stone|minecraft:the_end", "quark:marble", "quark:limestone", "quark:jasper", "quark:slate", "quark:basalt"]
 
 		[world.big_stone_clusters.marble]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 14
-			#
 			#Allowed values: [0,)
 			Rarity = 4
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 20
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 9
 			Enabled = true
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 80
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 14
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 9
 
 			[world.big_stone_clusters.marble.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["plains"]
-				"Is Blacklist" = false
+
+				[world.big_stone_clusters.marble.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["plains"]
+					"Is Blacklist" = false
+
+				[world.big_stone_clusters.marble.biomes.biomes]
+					Biomes = []
+					"Is Blacklist" = true
 
 			[world.big_stone_clusters.marble.dimensions]
 				Dimensions = ["minecraft:overworld"]
 				"Is Blacklist" = false
 
 		[world.big_stone_clusters.limestone]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 14
-			#
 			#Allowed values: [0,)
 			Rarity = 4
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 20
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 9
 			Enabled = true
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 80
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 14
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 9
 
 			[world.big_stone_clusters.limestone.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["swamp", "ocean"]
-				"Is Blacklist" = false
+
+				[world.big_stone_clusters.limestone.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["swamp", "ocean"]
+					"Is Blacklist" = false
+
+				[world.big_stone_clusters.limestone.biomes.biomes]
+					Biomes = []
+					"Is Blacklist" = true
 
 			[world.big_stone_clusters.limestone.dimensions]
 				Dimensions = ["minecraft:overworld"]
 				"Is Blacklist" = false
 
 		[world.big_stone_clusters.granite]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 14
-			#
 			#Allowed values: [0,)
 			Rarity = 4
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 20
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 9
 			Enabled = true
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 80
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 14
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 9
 
 			[world.big_stone_clusters.granite.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["extreme_hills"]
-				"Is Blacklist" = false
+
+				[world.big_stone_clusters.granite.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["mountain"]
+					"Is Blacklist" = false
+
+				[world.big_stone_clusters.granite.biomes.biomes]
+					Biomes = []
+					"Is Blacklist" = true
 
 			[world.big_stone_clusters.granite.dimensions]
 				Dimensions = ["minecraft:overworld"]
 				"Is Blacklist" = false
 
 		[world.big_stone_clusters.myalite]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 20
-			#
 			#Allowed values: [0,)
 			Rarity = 100
 			"Generate In Air" = true
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 58
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 6
 			Enabled = true
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 62
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 40
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 10
 
 			[world.big_stone_clusters.myalite.biomes]
-				Biomes = ["minecraft:end_highlands"]
-				"Is Blacklist" = false
+
+				[world.big_stone_clusters.myalite.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = []
+					"Is Blacklist" = true
+
+				[world.big_stone_clusters.myalite.biomes.biomes]
+					Biomes = ["minecraft:end_highlands"]
+					"Is Blacklist" = false
 
 			[world.big_stone_clusters.myalite.dimensions]
 				Dimensions = ["minecraft:the_end"]
 				"Is Blacklist" = false
 
 		[world.big_stone_clusters.voidstone]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 19
-			#
 			#Allowed values: [0,)
 			Rarity = 20
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 0
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 6
 			Enabled = true
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 40
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 19
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 6
 
 			[world.big_stone_clusters.voidstone.biomes]
-				Biomes = ["minecraft:end_highlands", "minecraft:end_midlands", "minecraft:end_barrens"]
-				"Is Blacklist" = false
+
+				[world.big_stone_clusters.voidstone.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = []
+					"Is Blacklist" = true
+
+				[world.big_stone_clusters.voidstone.biomes.biomes]
+					Biomes = ["minecraft:end_highlands", "minecraft:end_midlands", "minecraft:end_barrens"]
+					"Is Blacklist" = false
 
 			[world.big_stone_clusters.voidstone.dimensions]
 				Dimensions = ["minecraft:the_end"]
 				"Is Blacklist" = false
 
 		[world.big_stone_clusters.andesite]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 14
-			#
 			#Allowed values: [0,)
 			Rarity = 4
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 20
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 9
 			Enabled = true
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 80
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 14
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 9
 
 			[world.big_stone_clusters.andesite.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["forest"]
-				"Is Blacklist" = false
+
+				[world.big_stone_clusters.andesite.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["forest"]
+					"Is Blacklist" = false
+
+				[world.big_stone_clusters.andesite.biomes.biomes]
+					Biomes = []
+					"Is Blacklist" = true
 
 			[world.big_stone_clusters.andesite.dimensions]
 				Dimensions = ["minecraft:overworld"]
 				"Is Blacklist" = false
 
 		[world.big_stone_clusters.slate]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 14
-			#
 			#Allowed values: [0,)
 			Rarity = 4
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 20
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 9
 			Enabled = true
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 80
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 14
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 9
 
 			[world.big_stone_clusters.slate.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["icy"]
-				"Is Blacklist" = false
+
+				[world.big_stone_clusters.slate.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["snowy"]
+					"Is Blacklist" = false
+
+				[world.big_stone_clusters.slate.biomes.biomes]
+					Biomes = []
+					"Is Blacklist" = true
 
 			[world.big_stone_clusters.slate.dimensions]
 				Dimensions = ["minecraft:overworld"]
 				"Is Blacklist" = false
 
 		[world.big_stone_clusters.diorite]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 14
-			#
 			#Allowed values: [0,)
 			Rarity = 4
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 20
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 9
 			Enabled = true
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 80
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 14
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 9
 
 			[world.big_stone_clusters.diorite.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["savanna", "jungle", "mushroom"]
-				"Is Blacklist" = false
+
+				[world.big_stone_clusters.diorite.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["savanna", "jungle", "mushroom"]
+					"Is Blacklist" = false
+
+				[world.big_stone_clusters.diorite.biomes.biomes]
+					Biomes = []
+					"Is Blacklist" = true
 
 			[world.big_stone_clusters.diorite.dimensions]
 				Dimensions = ["minecraft:overworld"]
 				"Is Blacklist" = false
 
 		[world.big_stone_clusters.jasper]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 14
-			#
 			#Allowed values: [0,)
 			Rarity = 4
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 20
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 9
 			Enabled = true
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 80
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 14
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 9
 
 			[world.big_stone_clusters.jasper.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["mesa", "desert"]
-				"Is Blacklist" = false
+
+				[world.big_stone_clusters.jasper.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["mesa", "sandy"]
+					"Is Blacklist" = false
+
+				[world.big_stone_clusters.jasper.biomes.biomes]
+					Biomes = []
+					"Is Blacklist" = true
 
 			[world.big_stone_clusters.jasper.dimensions]
 				Dimensions = ["minecraft:overworld"]
@@ -1489,34 +1442,28 @@
 	[world.overgrown_underground_biome]
 
 		[world.overgrown_underground_biome.biome_settings]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 26
-			#
 			#Allowed values: [0,)
 			Rarity = 80
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 0
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 14
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 64
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 14
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 6
 
 			[world.overgrown_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["forest"]
+				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+				# jungle, spooky, dead, lush, mushroom, magical, rare,
+				# plateau, modified, ocean, river, water, mesa, forest,
+				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+				# beach, void, overworld, nether, end]
+				"Biome Types" = ["forest"]
 				"Is Blacklist" = false
 
 			[world.overgrown_underground_biome.biome_settings.dimensions]
@@ -1526,34 +1473,28 @@
 	[world.permafrost_underground_biome]
 
 		[world.permafrost_underground_biome.biome_settings]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 26
-			#
 			#Allowed values: [0,)
 			Rarity = 80
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 0
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 14
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 64
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 14
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 6
 
 			[world.permafrost_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["icy"]
+				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+				# jungle, spooky, dead, lush, mushroom, magical, rare,
+				# plateau, modified, ocean, river, water, mesa, forest,
+				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+				# beach, void, overworld, nether, end]
+				"Biome Types" = ["snowy"]
 				"Is Blacklist" = false
 
 			[world.permafrost_underground_biome.biome_settings.dimensions]
@@ -1563,34 +1504,28 @@
 	[world.lush_underground_biome]
 
 		[world.lush_underground_biome.biome_settings]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 26
-			#
 			#Allowed values: [0,)
 			Rarity = 80
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 0
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 14
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 64
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 14
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 6
 
 			[world.lush_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["jungle"]
+				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+				# jungle, spooky, dead, lush, mushroom, magical, rare,
+				# plateau, modified, ocean, river, water, mesa, forest,
+				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+				# beach, void, overworld, nether, end]
+				"Biome Types" = ["jungle"]
 				"Is Blacklist" = false
 
 			[world.lush_underground_biome.biome_settings.dimensions]
@@ -1600,34 +1535,28 @@
 	[world.brimstone_underground_biome]
 
 		[world.brimstone_underground_biome.biome_settings]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 26
-			#
 			#Allowed values: [0,)
 			Rarity = 80
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 0
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 14
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 64
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 14
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 6
 
 			[world.brimstone_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["mesa"]
+				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+				# jungle, spooky, dead, lush, mushroom, magical, rare,
+				# plateau, modified, ocean, river, water, mesa, forest,
+				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+				# beach, void, overworld, nether, end]
+				"Biome Types" = ["mesa"]
 				"Is Blacklist" = false
 
 			[world.brimstone_underground_biome.biome_settings.dimensions]
@@ -1636,19 +1565,25 @@
 
 	[world.big_dungeon]
 		"Loot Table" = "minecraft:chests/simple_dungeon"
-		#
 		#The chance that a big dungeon spawn candidate will be allowed to spawn. 0.2 is 20%, which is the same as the Pillager Outpost.
 		"Spawn Chance" = 0.1
 		"Max Rooms" = 10
 		"Chest Chance" = 0.5
 
-		[world.big_dungeon.biome_types]
-			#
-			#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-			# icy, the_end, beach, forest, ocean, desert, river, swamp,
-			# mushroom, nether]
-			"Biome Categories" = ["ocean", "beach", "nether", "the_end"]
-			"Is Blacklist" = true
+		[world.big_dungeon.biome_config]
+
+			[world.big_dungeon.biome_config.types]
+				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+				# jungle, spooky, dead, lush, mushroom, magical, rare,
+				# plateau, modified, ocean, river, water, mesa, forest,
+				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+				# beach, void, overworld, nether, end]
+				"Biome Types" = ["ocean", "beach", "nether", "end"]
+				"Is Blacklist" = true
+
+			[world.big_dungeon.biome_config.biomes]
+				Biomes = []
+				"Is Blacklist" = true
 
 	[world.chorus_vegetation]
 		"Teleport Duplication Chance" = 0.01
@@ -1677,50 +1612,40 @@
 			"Is Blacklist" = false
 
 		[world.underground_clay.ore_settings]
-			#
 			#Allowed values: [0,255]
 			"Max Height" = 60
-			#
 			#Allowed values: [0,)
 			"Cluster Count" = 3
-			#
 			#Allowed values: [0,255]
 			"Min Height" = 20
-			#
 			#Allowed values: [0,)
 			"Cluster Size" = 20
 
 	[world.slime_underground_biome]
 
 		[world.slime_underground_biome.biome_settings]
-			#
 			#Allowed values: [0,)
 			"Horizontal Size" = 26
-			#
 			#Allowed values: [0,)
 			Rarity = 120
-			#
 			#Allowed values: [0,255]
 			"Min Y Level" = 0
-			#
 			#Allowed values: [0,)
 			"Horizontal Variation" = 14
-			#
 			#Allowed values: [0,255]
 			"Max Y Level" = 64
-			#
 			#Allowed values: [0,)
 			"Vertical Size" = 14
-			#
 			#Allowed values: [0,)
 			"Vertical Variation" = 6
 
 			[world.slime_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["swamp"]
+				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+				# jungle, spooky, dead, lush, mushroom, magical, rare,
+				# plateau, modified, ocean, river, water, mesa, forest,
+				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+				# beach, void, overworld, nether, end]
+				"Biome Types" = ["swamp"]
 				"Is Blacklist" = false
 
 			[world.slime_underground_biome.biome_settings.dimensions]
@@ -1740,23 +1665,27 @@
 		"Max Y Level" = 32
 
 		[mobs.toretoise.spawn_config]
-			#
 			#Allowed values: (0,)
 			"Spawn Weight" = 100
-			#
 			#Allowed values: [1,)
 			"Min Group Size" = 1
-			#
 			#Allowed values: [1,)
 			"Max Group Size" = 1
 
 			[mobs.toretoise.spawn_config.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["none", "nether", "the_end"]
-				"Is Blacklist" = true
+
+				[mobs.toretoise.spawn_config.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["void", "nether", "end"]
+					"Is Blacklist" = true
+
+				[mobs.toretoise.spawn_config.biomes.biomes]
+					Biomes = []
+					"Is Blacklist" = true
 
 		[mobs.toretoise.dimensions]
 			Dimensions = ["minecraft:overworld"]
@@ -1766,83 +1695,109 @@
 		"Enable Brewing" = true
 
 		[mobs.crabs.spawn_config]
-			#
 			#Allowed values: (0,)
 			"Spawn Weight" = 5
-			#
 			#Allowed values: [1,)
 			"Min Group Size" = 1
-			#
 			#Allowed values: [1,)
 			"Max Group Size" = 3
 
 			[mobs.crabs.spawn_config.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["beach"]
-				"Is Blacklist" = false
+
+				[mobs.crabs.spawn_config.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["beach"]
+					"Is Blacklist" = false
+
+				[mobs.crabs.spawn_config.biomes.biomes]
+					Biomes = []
+					"Is Blacklist" = true
 
 	[mobs.foxhound]
-		#
 		#The chance coal will tame a foxhound
 		"Tame Chance" = 0.05
 
 		[mobs.foxhound.lesser_spawn_config]
-			#
 			#Allowed values: (0,)
 			"Spawn Weight" = 2
 			"Max Cost" = 0.7
-			#
 			#Allowed values: [1,)
 			"Min Group Size" = 1
 			"Spawn Cost" = 0.15
-			#
 			#Allowed values: [1,)
 			"Max Group Size" = 1
 
 			[mobs.foxhound.lesser_spawn_config.biomes]
-				Biomes = ["minecraft:soul_sand_valley"]
-				"Is Blacklist" = false
+
+				[mobs.foxhound.lesser_spawn_config.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = []
+					"Is Blacklist" = true
+
+				[mobs.foxhound.lesser_spawn_config.biomes.biomes]
+					Biomes = ["minecraft:soul_sand_valley"]
+					"Is Blacklist" = false
 
 		[mobs.foxhound.spawn_config]
-			#
 			#Allowed values: (0,)
 			"Spawn Weight" = 30
-			#
 			#Allowed values: [1,)
 			"Min Group Size" = 1
-			#
 			#Allowed values: [1,)
 			"Max Group Size" = 2
 
 			[mobs.foxhound.spawn_config.biomes]
-				Biomes = ["minecraft:nether_wastes", "minecraft:basalt_deltas"]
-				"Is Blacklist" = false
+
+				[mobs.foxhound.spawn_config.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = []
+					"Is Blacklist" = true
+
+				[mobs.foxhound.spawn_config.biomes.biomes]
+					Biomes = ["minecraft:nether_wastes", "minecraft:basalt_deltas"]
+					"Is Blacklist" = false
 
 	[mobs.wraith]
-		#
 		#List of sound sets to use with wraiths.
 		#Three sounds must be provided per entry, separated by | (in the format idle|hurt|death). Leave blank for no sound (i.e. if a mob has no ambient noise)
 		"Wraith Sounds" = ["entity.sheep.ambient|entity.sheep.hurt|entity.sheep.death", "entity.cow.ambient|entity.cow.hurt|entity.cow.death", "entity.pig.ambient|entity.pig.hurt|entity.pig.death", "entity.chicken.ambient|entity.chicken.hurt|entity.chicken.death", "entity.horse.ambient|entity.horse.hurt|entity.horse.death", "entity.cat.ambient|entity.cat.hurt|entity.cat.death", "entity.wolf.ambient|entity.wolf.hurt|entity.wolf.death", "entity.villager.ambient|entity.villager.hurt|entity.villager.death", "entity.polar_bear.ambient|entity.polar_bear.hurt|entity.polar_bear.death", "entity.zombie.ambient|entity.zombie.hurt|entity.zombie.death", "entity.skeleton.ambient|entity.skeleton.hurt|entity.skeleton.death", "entity.spider.ambient|entity.spider.hurt|entity.spider.death", "|entity.creeper.hurt|entity.creeper.death", "entity.endermen.ambient|entity.endermen.hurt|entity.endermen.death", "entity.zombie_pig.ambient|entity.zombie_pig.hurt|entity.zombie_pig.death", "entity.witch.ambient|entity.witch.hurt|entity.witch.death", "entity.blaze.ambient|entity.blaze.hurt|entity.blaze.death", "entity.llama.ambient|entity.llama.hurt|entity.llama.death", "|quark:entity.stoneling.cry|quark:entity.stoneling.die", "quark:entity.frog.idle|quark:entity.frog.hurt|quark:entity.frog.die"]
 
 		[mobs.wraith.spawn_config]
-			#
 			#Allowed values: (0,)
 			"Spawn Weight" = 8
 			"Max Cost" = 0.7
-			#
 			#Allowed values: [1,)
 			"Min Group Size" = 1
 			"Spawn Cost" = 0.15
-			#
 			#Allowed values: [1,)
 			"Max Group Size" = 3
 
 			[mobs.wraith.spawn_config.biomes]
-				Biomes = ["minecraft:soul_sand_valley"]
-				"Is Blacklist" = false
+
+				[mobs.wraith.spawn_config.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = []
+					"Is Blacklist" = true
+
+				[mobs.wraith.spawn_config.biomes.biomes]
+					Biomes = ["minecraft:soul_sand_valley"]
+					"Is Blacklist" = false
 
 	[mobs.stonelings]
 		"Cautious Stonelings" = true
@@ -1851,30 +1806,33 @@
 		"Tamable Stonelings" = true
 
 		[mobs.stonelings.spawn_config]
-			#
 			#Allowed values: (0,)
 			"Spawn Weight" = 80
-			#
 			#Allowed values: [1,)
 			"Min Group Size" = 1
-			#
 			#Allowed values: [1,)
 			"Max Group Size" = 1
 
 			[mobs.stonelings.spawn_config.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["none", "nether", "the_end"]
-				"Is Blacklist" = true
+
+				[mobs.stonelings.spawn_config.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["void", "nether", "end"]
+					"Is Blacklist" = true
+
+				[mobs.stonelings.spawn_config.biomes.biomes]
+					Biomes = []
+					"Is Blacklist" = true
 
 		[mobs.stonelings.dimensions]
 			Dimensions = ["minecraft:overworld"]
 			"Is Blacklist" = false
 
 	[mobs.forgotten]
-		#
 		#1 in this many Skeletons that spawn under the threshold are replaced with Forgotten.
 		"Forgotten Spawn Rate" = 0.05
 		"Max Height For Spawn" = 20
@@ -1884,23 +1842,27 @@
 		"Enable Big Funny" = false
 
 		[mobs.frogs.spawn_config]
-			#
 			#Allowed values: (0,)
 			"Spawn Weight" = 40
-			#
 			#Allowed values: [1,)
 			"Min Group Size" = 1
-			#
 			#Allowed values: [1,)
 			"Max Group Size" = 3
 
 			[mobs.frogs.spawn_config.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["swamp"]
-				"Is Blacklist" = false
+
+				[mobs.frogs.spawn_config.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["swamp"]
+					"Is Blacklist" = false
+
+				[mobs.frogs.spawn_config.biomes.biomes]
+					Biomes = []
+					"Is Blacklist" = true
 
 [client]
 	"Greener Grass" = true
@@ -1913,7 +1875,6 @@
 	"Chest Searching" = true
 
 	[client.usage_ticker]
-		#
 		#Switch the armor display to the off hand side and the hand display to the main hand side
 		Invert = false
 		"Shift Right" = 0
@@ -1925,7 +1886,6 @@
 	[client.variant_animal_textures]
 		"Enable Shiny Llama" = true
 		"Every Bee Is L G B T" = false
-		#
 		#The chance for an animal to have a special "Shiny" skin, like a shiny pokemon. This is 1 in X. Set to 0 to disable.
 		"Shiny Animal Chance" = 2048
 		"Enable Pig" = true
@@ -1939,10 +1899,8 @@
 		"Shulker Box Use Colors" = true
 		"Attribute Tooltips" = true
 		"Enchanting Tooltips" = true
-		#
 		#The value of each shank of food. Tweak this when using mods like Hardcore Hunger which change that value.
 		"Food Divisor" = 2
-		#
 		#A list of additional stacks to display on each enchantment
 		#The format is as follows:
 		#enchant_id=item1,item2,item3...
@@ -1959,14 +1917,14 @@
 
 	[client.greener_grass]
 		"Leaves List" = ["minecraft:spruce_leaves", "minecraft:birch_leaves", "minecraft:oak_leaves", "minecraft:jungle_leaves", "minecraft:acacia_leaves", "minecraft:dark_oak_leaves", "atmospheric:rosewood_leaves", "atmospheric:morado_leaves", "atmospheric:yucca_leaves", "autumnity:maple_leaves", "environmental:willow_leaves", "environmental:hanging_willow_leaves", "minecraft:vine"]
-		"Green Shift" = 30
-		"Blue Shift" = -30
 		"Block List" = ["minecraft:large_fern", "minecraft:tall_grass", "minecraft:grass_block", "minecraft:fern", "minecraft:grass", "minecraft:potted_fern", "minecraft:sugar_cane", "environmental:giant_tall_grass"]
-		"Alpha Grass" = false
-		"Absolute Values" = false
-		"Red Shift" = -30
 		"Affect Leaves" = true
 
+		[client.greener_grass.color_matrix]
+			R = [0.89, 0.0, 0.0]
+			B = [0.0, 0.0, 0.89]
+			G = [0.0, 1.11, 0.0]
+
 [oddities]
 	"Totem Of Holding" = true
 	Backpack = true
@@ -1976,87 +1934,64 @@
 	Pipes = true
 
 	[oddities.totem_of_holding]
-		#
 		#Set this to false to remove the behaviour where totems destroy themselves if the player dies again.
 		"Dark Souls Mode" = true
 		"Spawn Totem on PVP Kill" = false
-		#
 		#Set this to true to make it so that if a totem is destroyed, the items it holds are destroyed alongside it rather than dropped
 		"Destroy Lost Items" = false
 		"Enable Soul Compass" = true
-		#
 		#Set this to false to only allow the owner of a totem to collect its items rather than any player
 		"Allow Anyone To Collect" = true
 
 	[oddities.magnets]
 		"Magnetic Blacklist" = ["minecraft:tripwire_hook"]
 		"Magnetic Whitelist" = ["minecraft:chipped_anvil", "minecraft:damaged_anvil"]
-		#
 		#Any items you place in this list will be derived so that any block made of it will become magnetizable
 		"Magnetic Derivation List" = ["minecraft:iron_ingot"]
 
 	[oddities.matrix_enchanting]
-		#
 		#Set to false to disable the ability to influence enchantment outcomes with candles (requires the Tallow and Candles module enabled)
 		"Allow Influencing" = true
-		#
 		#A list of enchantment IDs you don't want the enchantment table to be able to create
 		"Disallowed Enchantments" = []
-		#
 		#The maximum enchanting power the matrix enchanter can accept
 		"Max Bookshelves" = 15
-		#
 		#How much to multiply the frequency of pieces where at least one of the same type has been generated
 		"Dupe Multiplier" = 1.4
-		#
 		#How much the min level requirement for adding a new piece to a book should increase per each bookshelf being used
 		"Min Level Scale Factor Book" = 2.0
-		#
 		#At which piece count the calculation for the min level should default to increasing one per piece rather than using the scale factor
 		"Min Level Cutoff" = 10
-		#
 		#Should this be X, the price of a piece increase by 1 every X pieces you generate
 		"Piece Price Scale" = 9
-		#
 		#Matrix Enchanting can be done with water instead of air around the enchanting table. Set this to false to disable this behaviour.
 		"Allow Underwater Enchanting" = true
-		#
 		#How many pieces you can generate without any bookshelves
 		"Base Max Piece Count" = 3
-		#
 		#How much each candle influences an enchantment. This works as a multiplier to its weight
 		"Influence Power" = 0.125
-		#
 		#Set to false to disable the tooltip for items with pending enchantments
 		"Show Tooltip" = true
-		#
 		#Set to false to disable the ability to create Enchanted Books
 		"Allow Books" = true
-		#
+		#If you set this to false, the vanilla Enchanting Table will no longer automatically convert to the Matrix Enchanting table. You'll have to add a recipe for the Matrix Enchanting Table to make use of this.
+		"Automatically Convert" = true
 		#The higher this is, the better enchantments you'll get on books
 		"Book Enchantability" = 12
-		#
 		#An array of influences each candle should apply. This list must be 16 elements long, and is in order of wool colors.
 		"Influences List" = ["minecraft:unbreaking", "minecraft:fire_protection", "minecraft:knockback,minecraft:punch", "minecraft:feather_falling", "minecraft:looting,minecraft:fortune,minecraft:luck_of_the_sea", "minecraft:blast_protection", "minecraft:silk_touch,minecraft:channeling", "minecraft:bane_of_arthropods", "minecraft:protection", "minecraft:respiration,minecraft:loyalty,minecraft:infinity", "minecraft:sweeping,minecraft:multishot", "minecraft:efficiency,minecraft:sharpness,minecraft:lure,minecraft:power,minecraft:impaling,minecraft:quick_charge", "minecraft:aqua_affinity,minecraft:depth_strider,minecraft:riptide", "minecraft:thorns,minecraft:piercing", "minecraft:fire_aspect,minecraft:flame", "minecraft:smite,minecraft:projectile_protection"]
-		#
 		#How many pieces a single Lapis can generate
 		"Charge Per Lapis" = 4
-		#
 		#How many pieces you can generate without any bookshelves (for Books)
 		"Base Max Piece Count Book" = 1
-		#
 		#How much to multiply the frequency of pieces where incompatible pieces have been generated
 		"Incompatible Multiplier" = 0.0
-		#
 		#How much the min level requirement for adding a new piece should increase for each piece added (up until the value of Min Level Cutoff)
 		"Min Level Scale Factor" = 1.5
-		#
 		#Set this to true to allow treasure enchantments to be rolled as pieces
 		"Allow Treasures" = false
-		#
 		#By default, enchantment rarities are fuzzed a bit to feel better with the new system. Set this to false to override this behaviour.
 		"Normalize Rarity" = true
-		#
 		#The max amount of candles that can influence a single enchantment
 		"Influence Max" = 4
 
@@ -2064,7 +1999,6 @@
 		"Enable Ravager Hide" = true
 		"Base Ravager Hide Drop" = 1
 		"Extra Chance Per Looting" = 0.5
-		#
 		#Set this to true to allow the backpacks to be unequipped even with items in them
 		"Super Op Mode" = false
 
@@ -2072,17 +2006,15 @@
 		"Max Items" = 640
 
 	[oddities.pipes]
-		#
 		#Set to 0 if you don't want pipes to have a max amount of items
 		"Max Pipe Items" = 16
-		#
 		#When items eject or are absorbed by pipes, should they make sounds?
 		"Do Pipes Whoosh" = true
-		#
 		#How long it takes for an item to cross a pipe. Bigger = slower.
 		"Pipe Speed" = 5
 
 [experimental]
+	Shiba = false
 	"Adjustable Chat" = false
 	"Narrator Readout" = false
 	"Overlay Shader" = false
@@ -2094,7 +2026,6 @@
 		"Vertical Shift" = 0
 
 	[experimental.custom_underground_biome]
-		#
 		#The format for these definitions is:
 		#dimensions;isDimensionBlacklist;biomeTypews;isBiomeBlacklist;rarity;minY..maxY;horizontalSize,verticalSize;horizontalVariation,verticalVariation;floorBlocks@weight;ceilingBlocks@weight;wallBlocks@weight;mimicInside
 		#That's a lot to take in, so here's an example. This would be for the default config of the Slime underground biome. (Spaces are allowed.)
@@ -2102,25 +2033,44 @@
 		"Biome Definitions" = []
 
 	[experimental.game_nerfs]
-		#
 		#Makes Mending act like the Unmending mod
 		#https://www.curseforge.com/minecraft/mc-mods/unmending
 		"Nerf Mending" = true
-		#
 		#Makes Iron Golems not drop Iron Ingots
 		"Disable Iron Farms" = true
-		#
 		#Makes Sheep not drop Wool when killed
 		"Disable Wool Drops" = true
-		#
 		#Makes Boats not glide on ice
 		"Disable Ice Roads" = true
-		#
 		#Resets all villager discounts when zombified to prevent reducing prices to ridiculous levels
 		"Nerf Villager Discount" = true
 
+	[experimental.shiba]
+
+		[experimental.shiba.spawn_config]
+			#Allowed values: (0,)
+			"Spawn Weight" = 40
+			#Allowed values: [1,)
+			"Min Group Size" = 1
+			#Allowed values: [1,)
+			"Max Group Size" = 3
+
+			[experimental.shiba.spawn_config.biomes]
+
+				[experimental.shiba.spawn_config.biomes.types]
+					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
+					# jungle, spooky, dead, lush, mushroom, magical, rare,
+					# plateau, modified, ocean, river, water, mesa, forest,
+					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
+					# beach, void, overworld, nether, end]
+					"Biome Types" = ["mountain"]
+					"Is Blacklist" = false
+
+				[experimental.shiba.spawn_config.biomes.biomes]
+					Biomes = []
+					"Is Blacklist" = true
+
 	[experimental.overlay_shader]
-		#
 		#Sets the name of the shader to load on a regular basis. This can load any shader the Camera module can (and requires the Camera module enabled to apply said logic).
 		#Some useful shaders include 'desaturate', 'oversaturate', 'bumpy'
 		#Colorblind simulation shaders are available in the form of 'deuteranopia', 'protanopia', 'tritanopia', and 'achromatopsia'
diff --git a/configuration/services/configs/minecraft/voor-kia/config/snowrealmagic-common.toml b/configuration/services/configs/minecraft/voor-kia/config/snowrealmagic-common.toml
index 405ed11..06d5d7c 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/snowrealmagic-common.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/snowrealmagic-common.toml
@@ -1,8 +1,11 @@
 placeSnowInBlock = true
 snowGravity = true
 snowAlwaysReplaceable = true
+#Unavailable if TerraForged mod installed
 snowAccumulationDuringSnowstorm = true
+#Unavailable if TerraForged mod installed
 snowAccumulationDuringSnowfall = false
+#Unavailable if TerraForged mod installed
 thinnerBoundingBox = true
 snowMakingIce = true
 snowOnIce = false
@@ -15,4 +18,8 @@ replaceWorldFeature = true
 sustainGrassIfLayerMoreThanOne = true
 #If you want to uninstall this mod, you probably want to make snow-covered blocks back to normal via random tick.
 retainOriginalBlocks = false
+#9 = Unlimited
+#Range: 1 ~ 9
+snowAccumulationMaxLayers = 8
+advancedBlockInteraction = true
 
diff --git a/configuration/services/configs/minecraft/voor-kia/config/the_bumblezone-mod_compatibility.toml b/configuration/services/configs/minecraft/voor-kia/config/the_bumblezone-mod_compatibility.toml
index 10b259c..5f599b6 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/the_bumblezone-mod_compatibility.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/the_bumblezone-mod_compatibility.toml
@@ -19,8 +19,8 @@
 		# 
 		#-----------------------------------------------------
 		#
-		# Spawn Productive Bees in The Bumblezone alongside regular
-		# bees at a 1/15th chance when spawning regular bees.
+		# Spawn Productive Bees in The Bumblezone and from Honey Brood Blocks
+		# alongside regular bees at a 1/15th chance when spawning regular bees.
 		#
 		spawnProductiveBeesBeesMob = true
 		# 
@@ -111,6 +111,12 @@
 		# 
 		#-----------------------------------------------------
 		#
+		# Add new trades to Buzzier Bees's Beekeeper Villager.
+		#
+		allowBuzzierBeesTradeCompat = true
+		# 
+		#-----------------------------------------------------
+		#
 		# How rare are powerful candles in Bee Dungeons. 
 		# Higher numbers means more rare.
 		# Default rate is 2.
@@ -162,6 +168,12 @@
 		# 
 		#-----------------------------------------------------
 		#
+		# Add new trades to Resourceful Bees's Beekeeper Villager.
+		#
+		allowResorucefulBeesTradeCompat = true
+		# 
+		#-----------------------------------------------------
+		#
 		# How much of Bee Dungeons is made of ore-based honeycombs.
 		# 0 is no or honeycombs, 1 is max ore honeycombs, and default is 0.3D
 		#
@@ -189,8 +201,8 @@
 		# 
 		#-----------------------------------------------------
 		#
-		# Spawn Resourceful Bees in The Bumblezone alongside regular
-		# bees at a 1/15th chance when spawning regular bees.
+		# Spawn Resourceful Bees in The Bumblezone and from Honey Brood Blocks
+		# alongside regular bees at a 1/15th chance when spawning regular bees.
 		#
 		spawnResourcefulBeesBeesMob = true
 		# 
@@ -220,3 +232,31 @@
 		#
 		allowPotionOfBeesCompat = true
 
+	["Mod Compatibility Options"."Pokecube Options"]
+		# 
+		#-----------------------------------------------------
+		#
+		# Spawn Pokecube's bee-like pokemon in The Bumblezone and from Honey Brood Blocks.
+		#
+		spawnPokecubeBeePokemon = true
+
+	["Mod Compatibility Options"."Charm Options"]
+		# 
+		#-----------------------------------------------------
+		#
+		# Spawn Charm Candles in Spider Infested Bee Dungeons.
+		#
+		allowCCandlesSpiderBeeDungeon = true
+		# 
+		#-----------------------------------------------------
+		#
+		# Add new trades to Charm's Beekeeper Villager.
+		#
+		allowCharmTradeCompat = true
+		# 
+		#-----------------------------------------------------
+		#
+		# Spawn Charm Candles in Bee Dungeons.
+		#
+		allowCCandlesBeeDungeon = true
+
diff --git a/configuration/services/configs/minecraft/voor-kia/config/travelersbackpack-common.toml b/configuration/services/configs/minecraft/voor-kia/config/travelersbackpack-common.toml
index 9e9421d..44a5e95 100644
--- a/configuration/services/configs/minecraft/voor-kia/config/travelersbackpack-common.toml
+++ b/configuration/services/configs/minecraft/voor-kia/config/travelersbackpack-common.toml
@@ -7,6 +7,7 @@
 	enableEmptyTankButton = true
 	enableBackpackAbilities = true
 	#If true, backpack can only be worn by placing it in curios 'Back' slot
+	#WARNING - Remember to TAKE OFF BACKPACK BEFORE enabling or disabling this integration!! - if not you'll lose your backpack
 	curiosIntegration = false
 	enableSleepingBagSpawnPoint = false
 
diff --git a/configuration/services/configs/minecraft/voor-kia/defaultconfigs/solcarrot-server.toml b/configuration/services/configs/minecraft/voor-kia/defaultconfigs/solcarrot-server.toml
index b4e8837..86ba950 100644
--- a/configuration/services/configs/minecraft/voor-kia/defaultconfigs/solcarrot-server.toml
+++ b/configuration/services/configs/minecraft/voor-kia/defaultconfigs/solcarrot-server.toml
@@ -1,26 +1,26 @@
 
 [milestones]
-	#Number of hearts you start out with.
-	#Range: 0 ~ 1000
-	baseHearts = 7
 	#Number of hearts you gain for reaching a new milestone.
 	#Range: 0 ~ 1000
 	heartsPerMilestone = 1
-	#A list of numbers of unique foods you need to eat to unlock each milestone, in ascending order.
+	#A list of numbers of unique foods you need to eat to unlock each milestone, in ascending order. Naturally, adding more milestones lets you earn more hearts.
 	milestones = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80]
+	#Number of hearts you start out with.
+	#Range: 0 ~ 1000
+	baseHearts = 7
 
 [filtering]
+	#The minimum hunger value foods need to provide in order to count for milestones, in half drumsticks.
+	#Range: 0 ~ 1000
+	minimumFoodValue = 4
 	#Foods in this list won't affect the player's health nor show up in the food book.
 	blacklist = []
 	#When this list contains anything, the blacklist is ignored and instead only foods from here count.
 	whitelist = []
-	#The minimum hunger value foods need to provide in order to count for milestones, in half drumsticks.
-	#Range: 0 ~ 1000
-	minimumFoodValue = 4
 
 [miscellaneous]
-	#Whether or not to reset the food list on death, effectively losing all bonus hearts.
-	resetOnDeath = false
 	#If true, eating foods outside of survival mode (e.g. creative/adventure) is not tracked and thus does not contribute towards progression.
 	limitProgressionToSurvival = true
+	#Whether or not to reset the food list on death, effectively losing all bonus hearts.
+	resetOnDeath = false
 

From b17ac84693ee25f2f12fcccce060d5a5fbea8157 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 20 Aug 2021 23:41:28 +0100
Subject: [PATCH 020/212] Add new minecraft mod configuration files

---
 .../config/alexsmobs/bald_eagle_spawns.json   |  21 ++
 .../cachalot_whale_beached_spawns.json        |  16 +
 .../alexsmobs/cachalot_whale_spawns.json      |  42 +++
 .../config/alexsmobs/dropbear_spawns.json     |  18 ++
 .../voor-kia/config/alexsmobs/emu_spawns.json |  28 ++
 .../config/alexsmobs/enderiophage_spawns.json |  31 ++
 .../alexsmobs/frilled_shark_spawns.json       |  32 ++
 .../config/alexsmobs/kangaroo_spawns.json     |  28 ++
 .../alexsmobs/leafcutter_anthill_spawns.json  |  26 ++
 .../alexsmobs/mimic_octopus_spawns.json       |  26 ++
 .../config/alexsmobs/platypus_spawns.json     |  28 ++
 .../alexsmobs/tarantula_hawk_spawns.json      |  16 +
 .../alexsmobs/tasmanian_devil_spawns.json     |  36 +++
 .../config/alexsmobs/tiger_spawns.json        |  42 +++
 .../config/alexsmobs/void_worm_spawns.json    |   3 +
 .../voor-kia/config/apotheosis/affixes.cfg    | 212 ++++++++++++++
 .../config/betterportals/1_16/README.txt      |  69 +++++
 .../config/betterportals/1_16/monoliths.json  |  55 ++++
 .../config/betterportals/1_16/rifts.json      |  30 ++
 .../voor-kia/config/byg/byg-nether.toml       |  15 +
 .../config/hardcorerevival-common.toml        |  34 +++
 .../iceandfire/amethyst_gen_biomes.json       |  28 ++
 .../config/iceandfire/amphithere_biomes.json  |  16 +
 .../config/iceandfire/cockatrice_biomes.json  |  28 ++
 .../iceandfire/cyclops_cave_biomes.json       |  28 ++
 .../config/iceandfire/deathworm_biomes.json   |  16 +
 .../iceandfire/desert_myrmex_biomes.json      |  16 +
 .../config/iceandfire/fire_dragon_biomes.json |  73 +++++
 .../fire_dragon_skeleton_biomes.json          |  16 +
 .../config/iceandfire/fire_lily_biomes.json   |  16 +
 .../iceandfire/forest_troll_biomes.json       |  28 ++
 .../iceandfire/gorgon_temple_biomes.json      |  28 ++
 .../config/iceandfire/graveyard_biomes.json   |  31 ++
 .../config/iceandfire/hippocampus_biomes.json |  28 ++
 .../config/iceandfire/hippogryph_biomes.json  |  52 ++++
 .../iceandfire/hippogryph_black_biomes.json   |  16 +
 .../iceandfire/hippogryph_brown_biomes.json   |  28 ++
 .../hippogryph_chestnut_biomes.json           |  16 +
 .../iceandfire/hippogryph_creamy_biomes.json  |  16 +
 .../hippogryph_dark_brown_biomes.json         |  28 ++
 .../iceandfire/hippogryph_gray_biomes.json    |  16 +
 .../iceandfire/hippogryph_white_biomes.json   |  40 +++
 .../config/iceandfire/hydra_cave_biomes.json  |  28 ++
 .../config/iceandfire/ice_dragon_biomes.json  |  40 +++
 .../ice_dragon_skeleton_biomes.json           |  28 ++
 .../config/iceandfire/ice_lily_biomes.json    |  28 ++
 .../iceandfire/jungle_myrmex_biomes.json      |  16 +
 .../iceandfire/lightning_dragon_biomes.json   |  40 +++
 .../lightning_dragon_skeleton_biomes.json     |  28 ++
 .../iceandfire/lightning_lily_biomes.json     |  28 ++
 .../config/iceandfire/mausoleum_biomes.json   |  28 ++
 .../iceandfire/mountain_troll_biomes.json     |  28 ++
 .../config/iceandfire/ore_gen_biomes.json     |  11 +
 .../iceandfire/pixie_village_biomes.json      |  73 +++++
 .../iceandfire/sapphire_gen_biomes.json       |  28 ++
 .../config/iceandfire/sea_serpent_biomes.json |  28 ++
 .../config/iceandfire/siren_biomes.json       |  28 ++
 .../config/iceandfire/snowy_troll_biomes.json |  16 +
 .../iceandfire/stymphalian_bird_biomes.json   |  28 ++
 .../iceandfire/wandering_cyclops_biomes.json  |  28 ++
 .../voor-kia/config/overworldtwo.json         |   5 +
 .../config/supplementaries-common.toml        | 274 ++++++++++++++++++
 62 files changed, 2183 insertions(+)
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/bald_eagle_spawns.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cachalot_whale_beached_spawns.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cachalot_whale_spawns.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/dropbear_spawns.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/emu_spawns.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/enderiophage_spawns.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/frilled_shark_spawns.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/kangaroo_spawns.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/leafcutter_anthill_spawns.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mimic_octopus_spawns.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/platypus_spawns.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tarantula_hawk_spawns.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tasmanian_devil_spawns.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tiger_spawns.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/void_worm_spawns.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/apotheosis/affixes.cfg
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/README.txt
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/monoliths.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/rifts.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/byg/byg-nether.toml
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/hardcorerevival-common.toml
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/amethyst_gen_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/amphithere_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/cockatrice_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/cyclops_cave_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/deathworm_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/desert_myrmex_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_dragon_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_dragon_skeleton_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_lily_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/forest_troll_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/gorgon_temple_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/graveyard_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippocampus_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_black_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_brown_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_chestnut_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_creamy_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_dark_brown_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_gray_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_white_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hydra_cave_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_dragon_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_dragon_skeleton_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_lily_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/jungle_myrmex_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_dragon_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_dragon_skeleton_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_lily_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/mausoleum_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/mountain_troll_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/ore_gen_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/pixie_village_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/sapphire_gen_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/sea_serpent_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/siren_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/snowy_troll_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/stymphalian_bird_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/wandering_cyclops_biomes.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/overworldtwo.json
 create mode 100644 configuration/services/configs/minecraft/voor-kia/config/supplementaries-common.toml

diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/bald_eagle_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/bald_eagle_spawns.json
new file mode 100644
index 0000000..e2ade4f
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/bald_eagle_spawns.json
@@ -0,0 +1,21 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "mountain"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "forest"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cachalot_whale_beached_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cachalot_whale_beached_spawns.json
new file mode 100644
index 0000000..cfb150a
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cachalot_whale_beached_spawns.json
@@ -0,0 +1,16 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "beach"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cachalot_whale_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cachalot_whale_spawns.json
new file mode 100644
index 0000000..15f385f
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cachalot_whale_spawns.json
@@ -0,0 +1,42 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "ocean"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "cold"
+      }
+    ],
+    [
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:lukewarm_ocean"
+      }
+    ],
+    [
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:deep_ocean"
+      }
+    ],
+    [
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:deep_lukewarm_ocean"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/dropbear_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/dropbear_spawns.json
new file mode 100644
index 0000000..6abab58
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/dropbear_spawns.json
@@ -0,0 +1,18 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:nether_wastes"
+      }
+    ],
+    [
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "biomesoplenty:crystalline_chasm"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/emu_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/emu_spawns.json
new file mode 100644
index 0000000..7de7826
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/emu_spawns.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "mesa"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "savanna"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/enderiophage_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/enderiophage_spawns.json
new file mode 100644
index 0000000..427b044
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/enderiophage_spawns.json
@@ -0,0 +1,31 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "end"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": true,
+        "value": "minecraft:the_end"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": true,
+        "value": "minecraft:end_barrens"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": true,
+        "value": "minecraft:end_highlands"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": true,
+        "value": "minecraft:small_end_islands"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/frilled_shark_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/frilled_shark_spawns.json
new file mode 100644
index 0000000..696a296
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/frilled_shark_spawns.json
@@ -0,0 +1,32 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:deep_ocean"
+      }
+    ],
+    [
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:deep_lukewarm_ocean"
+      }
+    ],
+    [
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:deep_cold_ocean"
+      }
+    ],
+    [
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:deep_frozen_ocean"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/kangaroo_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/kangaroo_spawns.json
new file mode 100644
index 0000000..7de7826
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/kangaroo_spawns.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "mesa"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "savanna"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/leafcutter_anthill_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/leafcutter_anthill_spawns.json
new file mode 100644
index 0000000..feabd66
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/leafcutter_anthill_spawns.json
@@ -0,0 +1,26 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "jungle"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": true,
+        "value": "minecraft:bamboo_jungle"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": true,
+        "value": "minecraft:bamboo_jungle_hills"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mimic_octopus_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mimic_octopus_spawns.json
new file mode 100644
index 0000000..5c1d0ef
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mimic_octopus_spawns.json
@@ -0,0 +1,26 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "ocean"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "hot"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": true,
+        "value": "minecraft:deep_warm_ocean"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/platypus_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/platypus_spawns.json
new file mode 100644
index 0000000..8b1a91c
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/platypus_spawns.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "river"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "cold"
+      }
+    ],
+    [
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "biomesoplenty:tundra_bog"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tarantula_hawk_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tarantula_hawk_spawns.json
new file mode 100644
index 0000000..7f73edd
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tarantula_hawk_spawns.json
@@ -0,0 +1,16 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "desert"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tasmanian_devil_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tasmanian_devil_spawns.json
new file mode 100644
index 0000000..c0342a8
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tasmanian_devil_spawns.json
@@ -0,0 +1,36 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "savanna"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "forest"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "cold"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": true,
+        "value": "minecraft:jungle_egde"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": true,
+        "value": "minecraft:modified_jungle_edge"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tiger_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tiger_spawns.json
new file mode 100644
index 0000000..f62ca32
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tiger_spawns.json
@@ -0,0 +1,42 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:bamboo_jungle"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:bamboo_jungle_hills"
+      }
+    ],
+    [
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "biomesoplenty:bamboo_blossom_grove"
+      }
+    ],
+    [
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "biomesoplenty:cherry_blossom_grove"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/void_worm_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/void_worm_spawns.json
new file mode 100644
index 0000000..333b7b9
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/void_worm_spawns.json
@@ -0,0 +1,3 @@
+{
+  "biomes": []
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/affixes.cfg b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/affixes.cfg
new file mode 100644
index 0000000..031011a
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/affixes.cfg
@@ -0,0 +1,212 @@
+# Configuration file
+
+armor {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
+    I:Weight=5
+}
+
+
+armor_toughness {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
+    I:Weight=5
+}
+
+
+arrow_catcher {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 1]
+    I:Weight=1
+}
+
+
+attack_speed {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
+    I:Weight=5
+}
+
+
+cleave {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 3]
+    I:Weight=3
+}
+
+
+cold_damage {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
+    I:Weight=5
+}
+
+
+crit_chance {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 2]
+    I:Weight=2
+}
+
+
+crit_damage {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 3]
+    I:Weight=3
+}
+
+
+current_hp_damage {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 2]
+    I:Weight=2
+}
+
+
+damage_chain {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 1]
+    I:Weight=1
+}
+
+
+disengage {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 3]
+    I:Weight=3
+}
+
+
+draw_speed {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
+    I:Weight=5
+}
+
+
+eldritch_block {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 1]
+    I:Weight=1
+}
+
+
+enchantability {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 3]
+    I:Weight=3
+}
+
+
+execute {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
+    I:Weight=5
+}
+
+
+fire_damage {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
+    I:Weight=5
+}
+
+
+life_steal {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 3]
+    I:Weight=3
+}
+
+
+loot_pinata {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 2]
+    I:Weight=2
+}
+
+
+magic_arrow {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 1]
+    I:Weight=1
+}
+
+
+max_crit {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 1]
+    I:Weight=1
+}
+
+
+max_health {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
+    I:Weight=5
+}
+
+
+movement_speed {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
+    I:Weight=5
+}
+
+
+omnitool {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 2]
+    I:Weight=2
+}
+
+
+overheal {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 4]
+    I:Weight=4
+}
+
+
+piercing {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 0]
+    I:Weight=0
+}
+
+
+radius_mining {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 2]
+    I:Weight=2
+}
+
+
+reach_distance {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 3]
+    I:Weight=3
+}
+
+
+shield_damage {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 3]
+    I:Weight=3
+}
+
+
+shield_speed {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
+    I:Weight=5
+}
+
+
+snare_hit {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 1]
+    I:Weight=1
+}
+
+
+snipe_damage {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 3]
+    I:Weight=3
+}
+
+
+spectral_shot {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 2]
+    I:Weight=2
+}
+
+
+spiked_shield {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 2]
+    I:Weight=2
+}
+
+
+teleport_drops {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 2]
+    I:Weight=2
+}
+
+
+torch_placement {
+    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 4]
+    I:Weight=4
+}
+
+
diff --git a/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/README.txt b/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/README.txt
new file mode 100644
index 0000000..e0446b4
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/README.txt
@@ -0,0 +1,69 @@
+######################################################
+# README for the rifts.json and monoliths.json files #
+######################################################
+NOTE -- EDITING THE rifts.json and monoliths.json FILES REQUIRES A MINECRAFT RESTART TO UPDATE!
+Each of these JSON files contains the 'variants' property, which is a list of all the rifts and monoliths to spawn, respectively.
+
+Each dimensional rift in rifts.json is an object with the following properties:
+ - blockSelector: A BlockSetSelector describing the blocks this rift is made of.
+       See the bottom of this README for documentation on BlockSetSelectors.
+ - fluidColor: The color of ANY DIMENSIONAL PLASMA IN THIS DIMENSION. Keep in mind this hue is added to the base purple hue
+   - red: Any hex string from 00 to FF.
+   - green: Any hex string from 00 to FF.
+   - blue: Any hex string from 00 to FF.
+   - alpha: Any hex string from 00 to FF.
+ - minY: The minimum y-coordinate a rift can spawn at.
+ - maxY: The maximum y-coordinate a rift can spawn at.
+ - playerTeleportedMinY: The minimum y-coordinate a player can be teleported to in the target dimension.
+ - playerTeleportedMaxY: The maximum y-coordinate a player can be teleported to in the target dimension.
+ - spawnDimension: The dimension this rift will spawn in. This MUST be distinct for each variant! In other words - only ONE variant per dimension!
+ - targetDimension: The dimension this rift will teleport you to. This does not have to be distinct for each variant.
+ - spawnChance: The chance of a Rift spawning.
+ - spawnPlatformBlock: Sometimes, when teleporting the player, a small 3x3 platform is generated for the player to stand on.
+       This is the block the platform will be made of. Should be a block that matches the target dimension well.
+
+Each monolith in monoliths.json is an object with the following properties:
+ - stairSelector: A BlockSetSelector describing the stairs on the perimeter of this monolith.
+ - cornerSelector: A BlockSetSelector describing the blocks on the corners of this monolith.
+ - insideSelector: A BlockSetSelector describing the blocks making up the inside of this monolith.
+ - fenceSelector: A BlockSetSelector describing the fences used in this monolith.
+ - powerBlock: The block required to power this monolith.
+ - decorationBlock: The block in the four corners of the power grid at the center of this monolith.
+ - beamStopBlocks: A list of blocks through which the beams of ANY RECLAIMERS PLACED IN THIS DIMENSION cannot pass.
+ - unpoweredBeamColor: The color of the beam of ANY RECLAIMER IN THIS DIMENSION, when UNPOWERED.
+   - red: Any hex string from 00 to FF.
+   - green: Any hex string from 00 to FF.
+   - blue: Any hex string from 00 to FF.
+   - alpha: Any hex string from 00 to FF.
+ - poweredBeamColor: The color of the beam of ANY RECLAIMER IN THIS DIMENSION, when POWERED.
+   - red: Any hex string from 00 to FF.
+   - green: Any hex string from 00 to FF.
+   - blue: Any hex string from 00 to FF.
+   - alpha: Any hex string from 00 to FF.
+ - minY: The minimum y-coordinate this monolith can spawn at.
+ - maxY: The maximum y-coordinate this monolith can spawn at.
+ - playerTeleportedMinY: The minimum y-coordinate a player can be teleported to in the target dimension.
+ - playerTeleportedMaxY: The maximum y-coordinate a player can be teleported to in the target dimension.
+ - spawnDimension: The dimension this monolith will spawn in. This MUST be distinct for each variant! In other words - only ONE variant per dimension!
+ - targetDimension: The dimension this monolith will teleport you to. This does not have to be distinct for each variant.
+ - spawnChance: The chance of a Monolith spawning.
+
+BlockSetSelector information:
+A BlockSetSelector describes a set of blocks and the probability of each block being chosen.
+Each BlockSetSelector has the following two fields:
+   - entries: An object where each entry's key is a block, and each value is that block's probability of being chosen.
+        The total sum of all probabilities SHOULD NOT exceed 1.0!
+   - defaultBlock: The block used for any leftover probability ranges.
+        For example, if the total sum of all the probabilities of the entries is 0.6, then
+        there is a 0.4 chance of the defaultBlock being selected.
+
+Here's an example BlockSetSelector:
+"entries": {
+  "minecraft:cobblestone": 0.25,
+  "minecraft:air": 0.2,
+  "minecraft:stonebrick[variant=stonebrick]": 0.1
+},
+"defaultBlock": "minecraft:planks[variant=oak]"
+
+For each block, this selector has a 25% chance of returning cobblestone, 20% chance of choosing air,
+10% chance of choosing stone bricks, and a 100 - (25 + 20 + 10) = 45% chance of choosing oak planks (since it's the default block).
diff --git a/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/monoliths.json b/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/monoliths.json
new file mode 100644
index 0000000..71b85ba
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/monoliths.json
@@ -0,0 +1,55 @@
+{
+  "variants": [
+    {
+      "stairSelector": {
+        "entries": {
+          "minecraft:blackstone_stairs[facing=north,half=bottom,shape=straight,waterlogged=false]": 0.5,
+          "minecraft:polished_blackstone_brick_stairs[facing=north,half=bottom,shape=straight,waterlogged=false]": 0.5
+        },
+        "defaultBlock": "minecraft:blackstone_stairs[facing=north,half=bottom,shape=straight,waterlogged=false]"
+      },
+      "cornerSelector": {
+        "entries": {},
+        "defaultBlock": "minecraft:chiseled_polished_blackstone"
+      },
+      "insideSelector": {
+        "entries": {
+          "minecraft:cracked_polished_blackstone_bricks": 0.2
+        },
+        "defaultBlock": "minecraft:polished_blackstone_bricks"
+      },
+      "fenceSelector": {
+        "entries": {
+          "minecraft:polished_blackstone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]": 0.33,
+          "minecraft:blackstone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]": 0.33,
+          "minecraft:polished_blackstone_brick_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]": 0.33
+        },
+        "defaultBlock": "minecraft:blackstone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]"
+      },
+      "powerBlock": "minecraft:gold_block",
+      "decorationBlock": "minecraft:yellow_glazed_terracotta[facing=north]",
+      "beamStopBlocks": [
+        "minecraft:obsidian"
+      ],
+      "unpoweredBeamColor": {
+        "red": "14",
+        "green": "0c",
+        "blue": "24",
+        "alpha": "FF"
+      },
+      "poweredBeamColor": {
+        "red": "FF",
+        "green": "DC",
+        "blue": "73",
+        "alpha": "FF"
+      },
+      "minY": 35,
+      "maxY": 70,
+      "playerTeleportedMinY": 11,
+      "playerTeleportedMaxY": 30,
+      "spawnChance": 0.1,
+      "spawnDimension": "minecraft:the_nether",
+      "targetDimension": "minecraft:overworld"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/rifts.json b/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/rifts.json
new file mode 100644
index 0000000..644a9b4
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/rifts.json
@@ -0,0 +1,30 @@
+{
+  "variants": [
+    {
+      "blockSelector": {
+        "entries": {
+          "minecraft:obsidian": 0.1,
+          "minecraft:crying_obsidian": 0.05,
+          "minecraft:gilded_blackstone": 0.05,
+          "minecraft:blackstone": 0.1,
+          "minecraft:netherrack": 0.7
+        },
+        "defaultBlock": "minecraft:cave_air"
+      },
+      "fluidColor": {
+        "red": "19",
+        "green": "00",
+        "blue": "20",
+        "alpha": "FC"
+      },
+      "minY": 10,
+      "maxY": 15,
+      "playerTeleportedMinY": 100,
+      "playerTeleportedMaxY": 120,
+      "spawnChance": 0.05,
+      "spawnDimension": "minecraft:overworld",
+      "targetDimension": "minecraft:the_nether",
+      "spawnPlatformBlock": "minecraft:netherrack"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/byg/byg-nether.toml b/configuration/services/configs/minecraft/voor-kia/config/byg/byg-nether.toml
new file mode 100644
index 0000000..763a12d
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/byg/byg-nether.toml
@@ -0,0 +1,15 @@
+
+[The_Nether]
+	#
+	#Is the list of biomes a blacklist or whitelist?
+	#When this list is a blacklist, the values in the list will not be in world generation.
+	#When this list is a whitelist, Adding a biome several times gives it more weight in generation and it must contain at least 1 value.
+	#When set to true, datapack biomes will work automatically! When set to false, you will need to manually add datapack entries.
+	#Default: true
+	isBlacklistNether = true
+	#
+	#This works as a whitelist or blacklist depending on the "isBlacklistNether" value.
+	#NO SPACES AFTER COMMAS!
+	#Default: ""
+	BlacklistNether = ""
+
diff --git a/configuration/services/configs/minecraft/voor-kia/config/hardcorerevival-common.toml b/configuration/services/configs/minecraft/voor-kia/config/hardcorerevival-common.toml
new file mode 100644
index 0000000..e0f6a28
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/hardcorerevival-common.toml
@@ -0,0 +1,34 @@
+
+[general]
+	#If true, knocked out players will glow, making them visible through blocks.
+	glowOnKnockout = true
+	#The time in ticks in which a player can still be rescued from death. Set to 0 to disable the timer.
+	#Range: > 0
+	ticksUntilDeath = 2400
+	#If true, the timer until death continues even if the player logs out.
+	continueTimerWhileOffline = false
+
+[rescue]
+	#The distance at which a player can rescue another.
+	#Range: 0.0 ~ 3.4028234663852886E38
+	rescueDistance = 5.0
+	#The time in ticks it takes to rescue a player.
+	#Range: > 0
+	rescueActionTicks = 40
+	#The amount of health to respawn with when a player was rescued, out of 20.
+	#Range: > 1
+	rescueRespawnHealth = 1
+	#The food level to respawn with when a player was rescued, out of 20.
+	#Range: > 0
+	rescueRespawnFoodLevel = 5
+	#Effects applied to a player when rescued, in the format "effect|duration|amplifier"
+	rescueRespawnEffects = ["minecraft:hunger|600|0", "minecraft:weakness|1200|0"]
+
+[restrictions]
+	#If true, knocked out players are still able to punch nearby enemies.
+	allowUnarmedMelee = false
+	#If true, knocked out players are still able to fire bows.
+	allowBows = false
+	#If true, knocked out players are still able to fire pistols from Mr Crayfish's Gun Mod.
+	allowPistols = false
+
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/amethyst_gen_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/amethyst_gen_biomes.json
new file mode 100644
index 0000000..a74daf4
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/amethyst_gen_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "savanna"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "savanna"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/amphithere_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/amphithere_biomes.json
new file mode 100644
index 0000000..ab82bf2
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/amphithere_biomes.json
@@ -0,0 +1,16 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "jungle"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/cockatrice_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/cockatrice_biomes.json
new file mode 100644
index 0000000..a74daf4
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/cockatrice_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "savanna"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "savanna"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/cyclops_cave_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/cyclops_cave_biomes.json
new file mode 100644
index 0000000..38e6e45
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/cyclops_cave_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "beach"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "beach"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/deathworm_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/deathworm_biomes.json
new file mode 100644
index 0000000..7f73edd
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/deathworm_biomes.json
@@ -0,0 +1,16 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "desert"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/desert_myrmex_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/desert_myrmex_biomes.json
new file mode 100644
index 0000000..7f73edd
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/desert_myrmex_biomes.json
@@ -0,0 +1,16 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "desert"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_dragon_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_dragon_biomes.json
new file mode 100644
index 0000000..0473537
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_dragon_biomes.json
@@ -0,0 +1,73 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "hot"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "jungle"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "mesa"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "savanna"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "plains"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "wet"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "cold"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "jungle"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "mesa"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "savanna"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "forest"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_dragon_skeleton_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_dragon_skeleton_biomes.json
new file mode 100644
index 0000000..7f73edd
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_dragon_skeleton_biomes.json
@@ -0,0 +1,16 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "desert"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_lily_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_lily_biomes.json
new file mode 100644
index 0000000..53b1af0
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_lily_biomes.json
@@ -0,0 +1,16 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "hot"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/forest_troll_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/forest_troll_biomes.json
new file mode 100644
index 0000000..f2356ca
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/forest_troll_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "forest"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "forest"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/gorgon_temple_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/gorgon_temple_biomes.json
new file mode 100644
index 0000000..38e6e45
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/gorgon_temple_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "beach"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "beach"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/graveyard_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/graveyard_biomes.json
new file mode 100644
index 0000000..343fa29
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/graveyard_biomes.json
@@ -0,0 +1,31 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "ocean"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": true,
+        "value": "ocean"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "beach"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": true,
+        "value": "beach"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippocampus_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippocampus_biomes.json
new file mode 100644
index 0000000..3fba906
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippocampus_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "ocean"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "ocean"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_biomes.json
new file mode 100644
index 0000000..21e99bd
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_biomes.json
@@ -0,0 +1,52 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "mesa"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "mountain"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "hills"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "extreme_hills"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_black_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_black_biomes.json
new file mode 100644
index 0000000..eac1949
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_black_biomes.json
@@ -0,0 +1,16 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:desert_hills"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_brown_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_brown_biomes.json
new file mode 100644
index 0000000..8b33d39
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_brown_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "mountains"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "extreme_hills"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_chestnut_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_chestnut_biomes.json
new file mode 100644
index 0000000..21211b2
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_chestnut_biomes.json
@@ -0,0 +1,16 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:wooded_mountains"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_creamy_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_creamy_biomes.json
new file mode 100644
index 0000000..48b78bd
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_creamy_biomes.json
@@ -0,0 +1,16 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:savanna_plateau"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_dark_brown_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_dark_brown_biomes.json
new file mode 100644
index 0000000..3bdc692
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_dark_brown_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:taiga_mountains"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:taiga_hills"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_gray_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_gray_biomes.json
new file mode 100644
index 0000000..718a68a
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_gray_biomes.json
@@ -0,0 +1,16 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:dark_forest_hills"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_white_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_white_biomes.json
new file mode 100644
index 0000000..ac739b4
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_white_biomes.json
@@ -0,0 +1,40 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:snowy_mountains"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:snowy_taiga_hills"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "REGISTRY_NAME",
+        "negate": false,
+        "value": "minecraft:snowy_taiga_mountains"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hydra_cave_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hydra_cave_biomes.json
new file mode 100644
index 0000000..b696ee0
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hydra_cave_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "swamp"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "swamp"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_dragon_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_dragon_biomes.json
new file mode 100644
index 0000000..196b79b
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_dragon_biomes.json
@@ -0,0 +1,40 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "icy"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "snowy"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "cold"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_dragon_skeleton_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_dragon_skeleton_biomes.json
new file mode 100644
index 0000000..6d766c7
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_dragon_skeleton_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "snowy"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "icy"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_lily_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_lily_biomes.json
new file mode 100644
index 0000000..6d766c7
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_lily_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "snowy"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "icy"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/jungle_myrmex_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/jungle_myrmex_biomes.json
new file mode 100644
index 0000000..ab82bf2
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/jungle_myrmex_biomes.json
@@ -0,0 +1,16 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "jungle"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_dragon_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_dragon_biomes.json
new file mode 100644
index 0000000..d5109e2
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_dragon_biomes.json
@@ -0,0 +1,40 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "jungle"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "mesa"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "savanna"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_dragon_skeleton_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_dragon_skeleton_biomes.json
new file mode 100644
index 0000000..a74daf4
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_dragon_skeleton_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "savanna"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "savanna"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_lily_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_lily_biomes.json
new file mode 100644
index 0000000..a74daf4
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_lily_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "savanna"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "savanna"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/mausoleum_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/mausoleum_biomes.json
new file mode 100644
index 0000000..6d766c7
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/mausoleum_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "snowy"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "icy"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/mountain_troll_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/mountain_troll_biomes.json
new file mode 100644
index 0000000..8b33d39
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/mountain_troll_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "mountains"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "extreme_hills"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ore_gen_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ore_gen_biomes.json
new file mode 100644
index 0000000..fda5d7f
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ore_gen_biomes.json
@@ -0,0 +1,11 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/pixie_village_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/pixie_village_biomes.json
new file mode 100644
index 0000000..6110f7b
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/pixie_village_biomes.json
@@ -0,0 +1,73 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "rare"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "magical"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "dense"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "forest"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "mountain"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "hills"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "wet"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "hot"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "cold"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": true,
+        "value": "dry"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": true,
+        "value": "taiga"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/sapphire_gen_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/sapphire_gen_biomes.json
new file mode 100644
index 0000000..6d766c7
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/sapphire_gen_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "snowy"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "icy"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/sea_serpent_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/sea_serpent_biomes.json
new file mode 100644
index 0000000..3fba906
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/sea_serpent_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "ocean"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "ocean"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/siren_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/siren_biomes.json
new file mode 100644
index 0000000..3fba906
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/siren_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "ocean"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "ocean"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/snowy_troll_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/snowy_troll_biomes.json
new file mode 100644
index 0000000..e4db8f7
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/snowy_troll_biomes.json
@@ -0,0 +1,16 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "snowy"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/stymphalian_bird_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/stymphalian_bird_biomes.json
new file mode 100644
index 0000000..b696ee0
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/stymphalian_bird_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "swamp"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "swamp"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/wandering_cyclops_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/wandering_cyclops_biomes.json
new file mode 100644
index 0000000..8d890df
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/wandering_cyclops_biomes.json
@@ -0,0 +1,28 @@
+{
+  "biomes": [
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "plains"
+      }
+    ],
+    [
+      {
+        "type": "BIOME_DICT",
+        "negate": false,
+        "value": "overworld"
+      },
+      {
+        "type": "BIOME_CATEGORY",
+        "negate": false,
+        "value": "plains"
+      }
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/overworldtwo.json b/configuration/services/configs/minecraft/voor-kia/config/overworldtwo.json
new file mode 100644
index 0000000..623db10
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/overworldtwo.json
@@ -0,0 +1,5 @@
+{
+  "version": 0,
+  "generate_nether": true,
+  "fast_ores": true
+}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/supplementaries-common.toml b/configuration/services/configs/minecraft/voor-kia/config/supplementaries-common.toml
new file mode 100644
index 0000000..4de24d6
--- /dev/null
+++ b/configuration/services/configs/minecraft/voor-kia/config/supplementaries-common.toml
@@ -0,0 +1,274 @@
+
+#Server side blocks configs
+[blocks]
+
+	[blocks.globe]
+		#how many globe trades to give to the wandering trader. This will effectively increase the chance of him having a globe trader. Increase this if you have other mods that add stuff to that trader
+		#Range: 0 ~ 50
+		chance = 2
+		#chanche of finding a globe in a shipwreck treasure chest.
+		#Range: 0.0 ~ 1.0
+		shipwreck_treasure_chance = 0.25
+
+	[blocks.speaker_block]
+		#maximum range
+		#Range: 0 ~ 256
+		range = 64
+
+	[blocks.bellows]
+		#bellows pushes air following this equation: 
+		#air=(sin(2PI*ticks/period)<0), with period = base_period-(redstone_power-1)*power_scaling 
+		#represents base period at 1 power
+		#Range: 1 ~ 512
+		base_period = 78
+		#entities with velocity greated than this won't be pushed
+		#Range: 0.0 ~ 16.0
+		power_scaling = 2.0
+		#velocity increase uses this equation: 
+		#vel = base_vel*((range-entity_distance)/range) with base_vel = base_velocity_scaling/period 
+		#note that the block will push further the faster it's pulsing
+		#Range: 0.0 ~ 64.0
+		base_velocity_scaling = 5.0
+		#sets velocity changed flag when pushing entities +
+		#causes pushing animation to be smooth client side but also restricts player movement when being pushed
+		velocity_changed_flag = true
+		#note that it will still only keep alive the two fire blocks closer to it
+		#Range: 0 ~ 16
+		range = 5
+
+	[blocks.spring_launcher]
+		#spring launcher launch speed
+		#Range: 0.0 ~ 16.0
+		velocity = 1.5
+		#fall distance needed to trigger the automatic spring launch
+		#Range: 0 ~ 512
+		fall_height_required = 5
+
+	[blocks.turn_table]
+		#can rotate entities standing on it?
+		rotate_entities = true
+		#blocks that can't be rotated. Some special ones like chests, beds and pistons are already hardcoded
+		blacklist = ["minecraft:end_portal_frame"]
+
+	[blocks.jar]
+		#jar liquid capacity: leave at 12 for pixel accuracy
+		#Range: 0 ~ 1024
+		capacity = 12
+		#allow right click to instantly eat or drink food or potions inside a jar.
+		#Disable if you think this ability is op. Cookies are excluded
+		drink_from_jar = true
+
+	[blocks.cage]
+		#allow all entities to be captured by cages and jars. Not meant for survival
+		cage_allow_all_mobs = false
+		#allow all baby mobs to be captured by cages
+		cage_allow_all_babies = false
+
+	[blocks.notice_board]
+		#allow notice boards to accept and display any item, not just maps and books
+		allow_any_item = false
+
+	[blocks.sack]
+		#Penalize the player with slowness effect when carrying too many sacks
+		sack_penality = true
+		#maximum number of sacks after which the slowness effect will be applied. each multiple of this number will further slow the player down
+		#Range: 0 ~ 50
+		sack_increment = 2
+		#How many slots should a sack have
+		#Range: 1 ~ 27
+		slots = 9
+
+	[blocks.safe]
+		#Makes safes only breakable by their owner or by a player in creative
+		prevent_breaking = false
+		#Make safes simpler so they do not require keys:
+		#they will be bound to the first person that opens one and only that person will be able to interact with them
+		simple_safes = false
+
+	[blocks.blackboard]
+		#Enable to draw directly on a blackboard using any dye. Gui still only works in black and white
+		colored_blackboard = false
+
+	[blocks.candle_holder]
+		#Candle holder light level
+		#Range: 1 ~ 15
+		light_level = 12
+
+	[blocks.timber_frame]
+		#Replace a timber frame with wattle and daub block when daub is placed in it
+		replace_daub = true
+
+	[blocks.hourglass]
+		#Time in ticks for sugar
+		#Range: 0 ~ 10000
+		sugar_time = 40
+		#Time in ticks for sand blocks
+		#Range: 0 ~ 10000
+		sand_time = 70
+		#Time in ticks for concrete blocks
+		#Range: 0 ~ 10000
+		concrete_time = 105
+		#Time in ticks for generic dust
+		#Range: 0 ~ 10000
+		dust_time = 150
+		#Time in ticks for glowstone dust
+		#Range: 0 ~ 10000
+		glowstone_time = 190
+		#Time in ticks for blaze powder
+		#Range: 0 ~ 10000
+		blaze_powder_time = 277
+		#Time in ticks for redstone dust
+		#Range: 0 ~ 10000
+		redstone_time = 400
+		#Time in ticks for slime balls
+		#Range: 0 ~ 10000
+		slime_time = 1750
+		#Time in ticks for honey
+		#Range: 0 ~ 10000
+		honey_time = 2000
+
+	[blocks.item_shelf]
+		#Makes item shelves climbable
+		climbable_shelves = false
+
+	[blocks.iron_gate]
+		#Allows two iron gates to be opened simultaneously when on top of the other
+		double_opening = true
+
+#Configure spawning conditions
+[spawns]
+
+	[spawns.firefly]
+		#Spawnable biomes
+		biomes = ["minecraft:swamp", "minecraft:swamp_hills", "minecraft:plains", "minecraft:sunflower_plains", "minecraft:dark_forest", "minecraft:dark_forest_hills", "byg:bayou", "byg:cypress_swamplands", "byg:glowshroom_bayou", "byg:mangrove_marshes", "byg:vibrant_swamplands", "byg:fresh_water_lake", "byg:grassland_plateau", "byg:wooded_grassland_plateau", "byg:flowering_grove", "byg:guiana_shield", "byg:guiana_clearing", "byg:meadow", "byg:orchard", "byg:seasonal_birch_forest", "byg:seasonal_deciduous_forest", "byg:seasonal_forest", "biomesoplenty:flower_meadow", "biomesoplenty:fir_clearing", "biomesoplenty:grove_lakes", "biomesoplenty:grove", "biomesoplenty:highland_moor", "biomesoplenty:wetland_marsh", "biomesoplenty:deep_bayou", "biomesoplenty:wetland"]
+		#Whitelisted mods. All biomes from said mods will be able to spawn fireflies. Use the one above for more control
+		mod_whitelist = []
+		#Spawn weight 
+		#Set to 0 to disable spawning entirely
+		#Range: 0 ~ 100
+		weight = 3
+		#Minimum group size
+		#Range: 0 ~ 64
+		min = 5
+		#Maximum group size
+		#Range: 0 ~ 64
+		max = 9
+
+	[spawns.structures]
+
+		[spawns.structures.way_sign]
+			#Average distance apart in chunks between spawn attempts
+			#Range: 0 ~ 1001
+			average_distance = 19
+			#Minimum distance apart in chunks between spawn attempts. 1001 to disable them entirely
+			#Range: 0 ~ 1001
+			minimum_distance = 10
+			#With this option road signs will display the distance to the structure that they are pointing to
+			show_distance_text = true
+			#list of structure that a sign can point to. Note that they will only spawn in dimensions where vanilla villages can
+			villages = ["minecraft:village", "repurposed_structures:village_badlands", "repurposed_structures:village_dark_oak", "repurposed_structures:village_birch", "repurposed_structures:village_giant_taiga", "repurposed_structures:village_jungle", "repurposed_structures:village_mountains", "repurposed_structures:village_oak", "repurposed_structures:village_swamp", "pokecube:village", "pokecube_legends:village", "pokecube_legends:village/ocean", "valhelsia_structures:castle", "valhelsia_structures:castle_ruin", "valhelsia_structures:small_castle", "valhelsia_structures:tower_ruin", "stoneholm:underground_village"]
+
+#entities parameters
+[entities]
+
+	[entities.firefly]
+		#firefly animation period
+		#note that actual period will be this + a random number between 0 and 10
+		#this needs to be here to allow correct despawning of the entity when it's not glowing
+		#check client configs come more animation settings
+		#Range: 1 ~ 200
+		period = 65
+		#firefly flying speed
+		#Range: 0.0 ~ 10.0
+		speed = 0.3
+		#despawn during the day
+		despawn = true
+
+#Vanilla tweaks
+[tweaks]
+
+	[tweaks.cake_tweaks]
+		#allows you to place a cake ontop of another
+		double_cake = true
+		#replaces normal cake placement with a directional one
+		directional_cake = true
+
+	[tweaks.hanging_flower_pots]
+		#allows you to place hanging flower pots. Works with any modded pot too
+		enabled = true
+
+	[tweaks.throwable_bricks]
+		#throw bricks at your foes! Might break glass blocks
+		enabled = true
+
+	[tweaks.wall_lantern]
+		#allow wall lanterns placement
+		enabled = true
+		#mod ids of mods that have lantern block that extend the base lantern class but don't look like one
+		mod_blacklist = ["extlights", "betterendforge", "tconstruct"]
+
+	[tweaks.bells_tweaks]
+		#ring a bell by clicking on a chain that's connected to it
+		chain_ringing = true
+		#max chain length that allows a bell to ring
+		#Range: 0 ~ 1024
+		chain_length = 16
+
+	[tweaks.raked_gravel]
+		#allow gravel to be raked with a hoe
+		enabled = true
+
+	[tweaks.bottle_xp]
+		#Allow bottling up xp by using a bottle on an enchanting table
+		enabled = true
+		#bottling health cost
+		#Range: 0 ~ 20
+		cost = 2
+
+	[tweaks.map_tweaks]
+		#In this section you can add custom structure maps to cartographers
+		#The format required is as follows:
+		#[[<structure>,<level>,<min_price>,<max_price>,<map_name>,<map_color>,<map_marker>],[<structure>,...,<map_marker>],...]
+		#With the following parameters:
+		# - <structure> structure id to be located (ie: minecraft:igloo)
+		# - <level> villager trading level at which the map will be sold. Must be between 1 and 5
+		# - <min_price> minimum emerald price
+		# - <max_price> maximum emerald price
+		# - <map_name> map item name
+		# - <map_color> hex color of the map item overlay texture
+		# - <map_marker> id of the map marker to be used (ie: supplementaries:igloo). 
+		#See texture folder for all the names. Leave empty for default ones
+		#Note that ony the first parameter is required, each of the others others can me removed and will be defaulted to reasonable values
+		#example: ['minecraft:swamp_hut','2','5','7','witch hut map','0x00ff33']
+		custom_adventurer_maps = [[""]]
+		#Cartographers will sell 'adventurer maps' that will lead to a random vanilla structure (choosen from a thought out preset list).
+		#Best kept disabled if you are adding custom adventurer maps with its config
+		random_adventurer_maps = true
+		#enables beacons, lodestones, respawn anchors, beds, conduits, portals to be displayed on maps by clicking one of them with a map
+		block_map_markers = true
+
+	[tweaks.ceiling_banners]
+		#Allow banners to be placed on ceilings
+		enabled = true
+
+	[tweaks.zombie_horse]
+		#Feed a stack of rotten flesh to a skeleton horse to buff him up to a zombie horse
+		zombie_horse_conversion = true
+		#Amount of rotten flesh needed
+		#Range: 1 ~ 1000
+		rotten_flesh = 64
+
+[items]
+
+	[items.rope_arrow]
+		#If you really don't like my ropes you can specify here the block id ofa rope from another mod which will get deployed by rope arrows instead of mine
+		rope_arrow_override = "supplementaries:rope"
+
+	[items.flute]
+		#radius in which an unbound flute will search pets
+		#Range: 0 ~ 500
+		unbound_radius = 64
+		#max distance at which a bound flute will allow a pet to teleport
+		#Range: 0 ~ 500
+		bound_distance = 64
+

From 6b85b9523c859fdbedccb1211f52fc9d25132d4e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 21 Aug 2021 00:20:20 +0100
Subject: [PATCH 021/212] minecraft: Enable command blocks to fix ice and fire
 ores

---
 .../services/configs/minecraft/voor-kia/server.properties       | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configuration/services/configs/minecraft/voor-kia/server.properties b/configuration/services/configs/minecraft/voor-kia/server.properties
index 1c5787e..84a8cd5 100644
--- a/configuration/services/configs/minecraft/voor-kia/server.properties
+++ b/configuration/services/configs/minecraft/voor-kia/server.properties
@@ -5,7 +5,7 @@ allow-nether=true
 broadcast-console-to-ops=true
 broadcast-rcon-to-ops=true
 difficulty=normal
-enable-command-block=false
+enable-command-block=true
 enable-jmx-monitoring=false
 enable-query=false
 enable-rcon=false

From b7d0d7521c4cbabb11b72434bcc03105e40ee6b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 24 Aug 2021 00:02:47 +0100
Subject: [PATCH 022/212] flake.lock: Update

Flake input changes:

* Updated 'flake-utils': 'github:numtide/flake-utils/7d706970d94bc5559077eb1a6600afddcd25a7c8' -> 'github:numtide/flake-utils/997f7efcb746a9c140ce1f13c72263189225f482'
* Updated 'nixos-hardware': 'github:nixos/nixos-hardware/fccbee72df707c3fb074854668deee6e1ff02351' -> 'github:nixos/nixos-hardware/de40acde6c056a7c5f3c9ad4dca0c172fa35d207'
* Updated 'nixpkgs': 'github:nixos/nixpkgs/5de44c15758465f8ddf84d541ba300b48e56eda4' -> 'github:nixos/nixpkgs/a1007637cea374bd1bafd754cfd5388894c49129'
---
 flake.lock | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/flake.lock b/flake.lock
index b2d4187..ee275c8 100644
--- a/flake.lock
+++ b/flake.lock
@@ -2,11 +2,11 @@
   "nodes": {
     "flake-utils": {
       "locked": {
-        "lastModified": 1622445595,
-        "narHash": "sha256-m+JRe6Wc5OZ/mKw2bB3+Tl0ZbtyxxxfnAWln8Q5qs+Y=",
+        "lastModified": 1629481132,
+        "narHash": "sha256-JHgasjPR0/J1J3DRm4KxM4zTyAj4IOJY8vIl75v/kPI=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "7d706970d94bc5559077eb1a6600afddcd25a7c8",
+        "rev": "997f7efcb746a9c140ce1f13c72263189225f482",
         "type": "github"
       },
       "original": {
@@ -37,11 +37,11 @@
     },
     "nixos-hardware": {
       "locked": {
-        "lastModified": 1623143341,
-        "narHash": "sha256-a8NjpJVvJkb3ehu/KP1OaWwlRexom2D7lQEH5uCO9yA=",
+        "lastModified": 1629744693,
+        "narHash": "sha256-guZxgF5v8Avqpdu5M/F3ygZ4f67Y6ruS7y2kA5yUhZE=",
         "owner": "nixos",
         "repo": "nixos-hardware",
-        "rev": "fccbee72df707c3fb074854668deee6e1ff02351",
+        "rev": "de40acde6c056a7c5f3c9ad4dca0c172fa35d207",
         "type": "github"
       },
       "original": {
@@ -53,11 +53,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1622922048,
-        "narHash": "sha256-nTyKxe0n7l/4HSmYaIN+63WQrvHrTJY6drSwP7bMqhU=",
+        "lastModified": 1629379628,
+        "narHash": "sha256-dI8wpEo7wIVWoTUk2oyWFUnlVHNKLs+ren1TqITN1mI=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "5de44c15758465f8ddf84d541ba300b48e56eda4",
+        "rev": "a1007637cea374bd1bafd754cfd5388894c49129",
         "type": "github"
       },
       "original": {

From 64057828cb5ad6f35bd53be690f30c46d85280a5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 24 Aug 2021 00:31:35 +0100
Subject: [PATCH 023/212] minecraft: Fix forge server curl command

---
 pkgs/minecraft/forge-server.nix | 1 +
 1 file changed, 1 insertion(+)

diff --git a/pkgs/minecraft/forge-server.nix b/pkgs/minecraft/forge-server.nix
index 22df91f..2dea39a 100644
--- a/pkgs/minecraft/forge-server.nix
+++ b/pkgs/minecraft/forge-server.nix
@@ -7,6 +7,7 @@ let
   mirror = "https://files.minecraftforge.net/maven/net/minecraftforge/forge";
   src = fetchurl {
     url = "${mirror}/${version}/forge-${version}-installer.jar";
+    curlOpts = "--globoff";
     # Forge doesn't seem to like newer shas
     sha1 = "e97821e5431bdcaa46e12048769922e2cdb5e2e1";
   };

From 4fe3b8b22b43d4f2be8e60ac8561ec13707dfdb4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 25 Aug 2021 19:45:15 +0100
Subject: [PATCH 024/212] minecraft: Fix ridiculous CPU usage

Tapes over https://bugs.mojang.com/browse/MC-183518, which schedules
things completely stupidly on Linux starting with 1.14.
---
 configuration/default.nix            | 2 ++
 configuration/services/minecraft.nix | 1 +
 2 files changed, 3 insertions(+)

diff --git a/configuration/default.nix b/configuration/default.nix
index a12aceb..683b144 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -20,6 +20,8 @@
     trustedUsers = [ "@wheel" ];
   };
 
+  boot.kernelParams = [ "highres=off" "nohz=off" ];
+
   networking = {
     hostName = "tlaternet";
 
diff --git a/configuration/services/minecraft.nix b/configuration/services/minecraft.nix
index 9b77c09..826ecd9 100644
--- a/configuration/services/minecraft.nix
+++ b/configuration/services/minecraft.nix
@@ -90,6 +90,7 @@ in {
       };
     };
 
+    extraOptions = [ "--cpu-quota=90000" ];
     autoStart = false;
     ports = [ "25565:25565" ];
     volumes = [

From 6bc37ebdae3fe3e54455aefcad659f5759997033 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 27 Aug 2021 18:09:43 +0100
Subject: [PATCH 025/212] minecraft: Limit to a single core instead of limiting
 the quota

Minecraft is anyway supposed to be single-threaded, so if it goes
beyond one core something is very wrong.
---
 configuration/services/minecraft.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configuration/services/minecraft.nix b/configuration/services/minecraft.nix
index 826ecd9..af5c75f 100644
--- a/configuration/services/minecraft.nix
+++ b/configuration/services/minecraft.nix
@@ -90,7 +90,7 @@ in {
       };
     };
 
-    extraOptions = [ "--cpu-quota=90000" ];
+    extraOptions = [ "--cpus=1.0" ];
     autoStart = false;
     ports = [ "25565:25565" ];
     volumes = [

From a66eac3b17ee54faddb577c9d84c4eaae7478452 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 27 Aug 2021 18:10:19 +0100
Subject: [PATCH 026/212] minecraft: Add automatic restart scheduling

This starts/stops the server at 2 pm and 4 am respectively. This
should hopefully fix some of the issues caused by shoddy programming.
---
 configuration/services/minecraft.nix | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/configuration/services/minecraft.nix b/configuration/services/minecraft.nix
index af5c75f..bf8f58f 100644
--- a/configuration/services/minecraft.nix
+++ b/configuration/services/minecraft.nix
@@ -102,4 +102,31 @@ in {
       "${whitelist}:/var/lib/minecraft/whitelist.json:ro"
     ];
   };
+
+  systemd.timers.podman-minecraft-voor-kia-off = {
+    description = "Turns off the minecraft server every day at 4 am";
+    wantedBy = [ "podman-minecraft-voor-kia.service" ];
+    timerConfig = {
+      Unit = "podman-minecraft-voor-kia-starter@stop.service";
+      OnCalendar = "04:00:00";
+    };
+  };
+
+  systemd.timers.podman-minecraft-voor-kia-on = {
+    description = "Turns on the minecraft server every day at 2 pm";
+    wantedBy = [ "podman-minecraft-voor-kia.service" ];
+    timerConfig = {
+      Unit = "podman-minecraft-voor-kia-starter@start.service";
+      OnCalendar = "14:00:00";
+    };
+  };
+
+  systemd.services."podman-minecraft-voor-kia-starter@" = {
+    description = "Unit to stop/start the minecraft server";
+    serviceConfig = {
+      ExecStart =
+        "${pkgs.systemd}/bin/systemctl %i podman-minecraft-voor-kia.service";
+      Type = "oneshot";
+    };
+  };
 }

From b9af400942d555ce32fc15f97965d8282ca62ae9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 5 Oct 2021 12:50:05 +0100
Subject: [PATCH 027/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file changes:

• Updated input 'flake-utils':
    'github:numtide/flake-utils/997f7efcb746a9c140ce1f13c72263189225f482' (2021-08-20)
  → 'github:numtide/flake-utils/7e5bf3925f6fbdfaf50a2a7ca0be2879c4261d19' (2021-09-13)
• Updated input 'nixos-hardware':
    'github:nixos/nixos-hardware/de40acde6c056a7c5f3c9ad4dca0c172fa35d207' (2021-08-23)
  → 'github:nixos/nixos-hardware/0a8b8054c9920368a3c15e6d766188fdf04b736f' (2021-09-30)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/a1007637cea374bd1bafd754cfd5388894c49129' (2021-08-19)
  → 'github:nixos/nixpkgs/7daf35532d2d8bf5e6f7f962e6cd13a66d01a71d' (2021-10-03)
• Updated input 'tlaternet-templates':
    'git+https://gitea.tlater.net/tlaternet/tlaternet-templates.git?ref=master&rev=6da1d644ac02143172d20e0d3e9fcd7a0c8720ef' (2021-04-11)
  → 'git+https://gitea.tlater.net/tlaternet/tlaternet-templates.git?ref=master&rev=555a2949bdf643c74b535bd0c623d98f99d33628' (2021-10-05)
• Removed input 'tlaternet-templates/nixpkgs-unstable'
• Updated input 'tlaternet-webserver':
    'git+https://gitea.tlater.net/tlaternet/tlaternet.git?ref=master&rev=ff25f151d3c170c7290b83be5cbdb1fd84261997' (2021-04-09)
  → 'git+https://gitea.tlater.net/tlaternet/tlaternet.git?ref=master&rev=1232950c06ae16bf17fb16ac1f5f2231e971936b' (2021-10-05)
• Updated input 'tlaternet-webserver/naersk':
    'github:nmattia/naersk/e0fe990b478a66178a58c69cf53daec0478ca6f9' (2021-03-03)
  → 'github:nmattia/naersk/ee7edec50b49ab6d69b06d62f1de554efccb1ccd' (2021-09-21)
• Updated input 'tlaternet-webserver/naersk/nixpkgs':
    follows 'nixpkgs'
  → follows 'tlaternet-webserver/nixpkgs'
• Updated input 'tlaternet-webserver/rust-overlay':
    'github:oxalica/rust-overlay/38766381042021f547a168ebb3f10305dc6fde08' (2021-03-30)
  → 'github:oxalica/rust-overlay/9c2fc6a62ccbc6f420d71ecac6bf0b84dbbee64f' (2021-10-05)
• Updated input 'tlaternet-webserver/rust-overlay/flake-utils':
    follows 'flake-utils'
  → follows 'tlaternet-webserver/flake-utils'
• Updated input 'tlaternet-webserver/rust-overlay/nixpkgs':
    follows 'nixpkgs'
  → follows 'tlaternet-webserver/nixpkgs'
---
 flake.lock | 68 ++++++++++++++++++++++--------------------------------
 1 file changed, 27 insertions(+), 41 deletions(-)

diff --git a/flake.lock b/flake.lock
index ee275c8..3be1860 100644
--- a/flake.lock
+++ b/flake.lock
@@ -2,11 +2,11 @@
   "nodes": {
     "flake-utils": {
       "locked": {
-        "lastModified": 1629481132,
-        "narHash": "sha256-JHgasjPR0/J1J3DRm4KxM4zTyAj4IOJY8vIl75v/kPI=",
+        "lastModified": 1631561581,
+        "narHash": "sha256-3VQMV5zvxaVLvqqUrNz3iJelLw30mIVSfZmAaauM3dA=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "997f7efcb746a9c140ce1f13c72263189225f482",
+        "rev": "7e5bf3925f6fbdfaf50a2a7ca0be2879c4261d19",
         "type": "github"
       },
       "original": {
@@ -18,15 +18,16 @@
     "naersk": {
       "inputs": {
         "nixpkgs": [
+          "tlaternet-webserver",
           "nixpkgs"
         ]
       },
       "locked": {
-        "lastModified": 1614785451,
-        "narHash": "sha256-TPw8kQvr2UNCuvndtY+EjyXp6Q5GEW2l9UafXXh1XmI=",
+        "lastModified": 1632266297,
+        "narHash": "sha256-J1yeJk6Gud9ef2pEf6aKQemrfg1pVngYDSh+SAY94xk=",
         "owner": "nmattia",
         "repo": "naersk",
-        "rev": "e0fe990b478a66178a58c69cf53daec0478ca6f9",
+        "rev": "ee7edec50b49ab6d69b06d62f1de554efccb1ccd",
         "type": "github"
       },
       "original": {
@@ -37,11 +38,11 @@
     },
     "nixos-hardware": {
       "locked": {
-        "lastModified": 1629744693,
-        "narHash": "sha256-guZxgF5v8Avqpdu5M/F3ygZ4f67Y6ruS7y2kA5yUhZE=",
+        "lastModified": 1632990363,
+        "narHash": "sha256-SNqz+9Vt4yDHqw8u/CMFdzMQTulKoMlVGJdshfcb5O0=",
         "owner": "nixos",
         "repo": "nixos-hardware",
-        "rev": "de40acde6c056a7c5f3c9ad4dca0c172fa35d207",
+        "rev": "0a8b8054c9920368a3c15e6d766188fdf04b736f",
         "type": "github"
       },
       "original": {
@@ -53,11 +54,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1629379628,
-        "narHash": "sha256-dI8wpEo7wIVWoTUk2oyWFUnlVHNKLs+ren1TqITN1mI=",
+        "lastModified": 1633267966,
+        "narHash": "sha256-gFKvZ5AmV/dDTKXVxacPbXe4R0BsFpwtVaQxuIm2nnk=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "a1007637cea374bd1bafd754cfd5388894c49129",
+        "rev": "7daf35532d2d8bf5e6f7f962e6cd13a66d01a71d",
         "type": "github"
       },
       "original": {
@@ -67,22 +68,6 @@
         "type": "github"
       }
     },
-    "nixpkgs-unstable": {
-      "locked": {
-        "lastModified": 1617899217,
-        "narHash": "sha256-gd5JHH7IkeoIQ/oiGZSqDpGdGt7DMRJTQ8JiD8+hdOQ=",
-        "owner": "nixos",
-        "repo": "nixpkgs",
-        "rev": "9e377a6ce42dccd9b624ae4ce8f978dc892ba0e2",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nixos",
-        "ref": "nixos-unstable",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
     "root": {
       "inputs": {
         "flake-utils": "flake-utils",
@@ -95,18 +80,20 @@
     "rust-overlay": {
       "inputs": {
         "flake-utils": [
+          "tlaternet-webserver",
           "flake-utils"
         ],
         "nixpkgs": [
+          "tlaternet-webserver",
           "nixpkgs"
         ]
       },
       "locked": {
-        "lastModified": 1617071065,
-        "narHash": "sha256-9JXhxwlc/ZJaO4aZ3cUwQwlK7ZRamjV+BvOTvdXrggs=",
+        "lastModified": 1633400100,
+        "narHash": "sha256-kHQV7jZ2vVHVI9sfda1mUROVBbQbdfKcbIpKG9WdqGo=",
         "owner": "oxalica",
         "repo": "rust-overlay",
-        "rev": "38766381042021f547a168ebb3f10305dc6fde08",
+        "rev": "9c2fc6a62ccbc6f420d71ecac6bf0b84dbbee64f",
         "type": "github"
       },
       "original": {
@@ -122,15 +109,14 @@
         ],
         "nixpkgs": [
           "nixpkgs"
-        ],
-        "nixpkgs-unstable": "nixpkgs-unstable"
+        ]
       },
       "locked": {
-        "lastModified": 1618117315,
-        "narHash": "sha256-RSqbWv20zNDhCx1VARxEjrYH1pNv+H2pY8dQ29tdNjA=",
+        "lastModified": 1633432574,
+        "narHash": "sha256-IjGaJAQuFIJ1Is9gtHXsryPOnTDE6tlA61PUKuS8dzw=",
         "ref": "master",
-        "rev": "6da1d644ac02143172d20e0d3e9fcd7a0c8720ef",
-        "revCount": 60,
+        "rev": "555a2949bdf643c74b535bd0c623d98f99d33628",
+        "revCount": 61,
         "type": "git",
         "url": "https://gitea.tlater.net/tlaternet/tlaternet-templates.git"
       },
@@ -151,11 +137,11 @@
         "rust-overlay": "rust-overlay"
       },
       "locked": {
-        "lastModified": 1617992257,
-        "narHash": "sha256-TfcLtS/1Niv21NN5e9VGUbK0fpoOvgmx1caO4LBcTas=",
+        "lastModified": 1633433130,
+        "narHash": "sha256-jkW+HV8cJvE86gppOEXQl2ke+bDHJ7SAp8eJp8pJ0N8=",
         "ref": "master",
-        "rev": "ff25f151d3c170c7290b83be5cbdb1fd84261997",
-        "revCount": 14,
+        "rev": "1232950c06ae16bf17fb16ac1f5f2231e971936b",
+        "revCount": 16,
         "type": "git",
         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git"
       },

From d6e1cd3ffadfd1667ea18e978b539497ea869842 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 6 Oct 2021 01:13:31 +0100
Subject: [PATCH 028/212] update-mods.py: Fix issues revealed by 1.17 updates

---
 flake.nix                              |  1 +
 pkgs/minecraft/voor-kia/update-mods.py | 97 +++++++++++++-------------
 2 files changed, 51 insertions(+), 47 deletions(-)

diff --git a/flake.nix b/flake.nix
index fba329c..a7b1ef7 100644
--- a/flake.nix
+++ b/flake.nix
@@ -97,6 +97,7 @@
               # For the minecraft mod update script
               (python3.withPackages (pypkgs:
                 with pypkgs; [
+                  dateutil
                   requests
 
                   ipython
diff --git a/pkgs/minecraft/voor-kia/update-mods.py b/pkgs/minecraft/voor-kia/update-mods.py
index df32d86..36722be 100644
--- a/pkgs/minecraft/voor-kia/update-mods.py
+++ b/pkgs/minecraft/voor-kia/update-mods.py
@@ -3,13 +3,16 @@ import json
 import hashlib
 import pathlib
 from copy import deepcopy
+from datetime import datetime
 from enum import Enum
-from typing import Dict, Generator, NamedTuple, Optional, Union
+from typing import Any, Dict, Generator, List, NamedTuple, Optional, Union
 
 import requests
+from dateutil import parser
 
 
 API = "https://addons-ecs.forgesvc.net/api/v2"
+JSON = Union[List[Dict[str, Any]], Dict[str, Any]]
 
 
 class ModLoader(Enum):
@@ -19,25 +22,34 @@ class ModLoader(Enum):
 
 class File(NamedTuple):
     id: int
-    gameVersion: str
+    gameVersions: List[str]
     name: str
     modLoader: Optional[ModLoader]
+    date: datetime
 
     @classmethod
-    def from_json(cls, f: Dict[str, Union[str, int]]):
-        modLoader = f.get("modLoader", None)
+    def from_json(cls, f: JSON):
+        assert isinstance(f, dict)
 
-        assert isinstance(f["gameVersion"], str)
-        assert isinstance(f["projectFileId"], int)
-        assert isinstance(f["projectFileName"], str)
-        if modLoader is not None:
-            assert isinstance(modLoader, int)
+        assert isinstance(f.get("gameVersion"), list)
+        assert isinstance(f.get("id"), int)
+        assert isinstance(f.get("fileName"), str)
+        assert isinstance(f.get("fileDate"), str)
+
+        modLoader = (
+            ModLoader.FORGE
+            if "Forge" in f["gameVersion"]
+            else ModLoader.FABRIC
+            if "Fabric" in f["gameVersion"]
+            else None
+        )
 
         return cls(
-            f["projectFileId"],
+            f["id"],
             f["gameVersion"],
-            f["projectFileName"],
-            ModLoader(modLoader) if modLoader is not None else None,
+            f["fileName"],
+            modLoader,
+            parser.isoparse(f["fileDate"]),
         )
 
 
@@ -49,15 +61,12 @@ class CurseAPI:
         ] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0"
 
     def get_latest_files(self, mod_id: int) -> Generator[File, None, None]:
-        res = self._session.get(f"{API}/addon/{mod_id}")
+        res = self._session.get(f"{API}/addon/{mod_id}/files")
         res.raise_for_status()
 
-        latest_files = res.json().get("gameVersionLatestFiles", None)
+        latest_files = res.json()
 
-        if latest_files is None:
-            return (_ for _ in [])
-        else:
-            return (File.from_json(f) for f in latest_files)
+        return (File.from_json(f) for f in latest_files)
 
     def get_file_url(self, mod_id: int, file_id: int) -> str:
         res = self._session.get(f"{API}/addon/{mod_id}/file/{file_id}/download-url")
@@ -107,43 +116,37 @@ def update(infile: pathlib.Path, version: str, mod_loader: ModLoader):
             latest_files = [_ for _ in []]
 
         def compatible(file_: File) -> bool:
-            file_version = file_.gameVersion.split(".")
-            target_version = version.split(".")
-
-            # We assume that major + minor version are compatible;
-            # this seems to generally be true, but check the output
-            # for possible mistakes.
-            #
-            # The patch version is completely ignored since mod
-            # authors generally don't register versions properly
-            # enough to match this.
-            #
-            # Being more strict than this usually results in
-            # technically compatible mods with no available versions.
             return (
-                (file_.modLoader is None or file_.modLoader == mod_loader)
-                and file_version[0] == target_version[0]
-                and file_version[1] == target_version[1]
+                mod_loader is None
+                or file_.modLoader is None
+                or file_.modLoader == mod_loader
+            ) and any(
+                file_version.startswith(version) for file_version in file_.gameVersions
             )
 
-        latest = max(filter(compatible, latest_files), key=lambda f: f.gameVersion)
+        compatible_files = list(filter(compatible, latest_files))
+        if compatible_files:
+            latest = max(compatible_files, key=lambda f: f.date)
+            if latest.id != mod["id"]:
+                print(
+                    f"Updating {mod['project']} {mod['filename']} -> {latest.name}..."
+                )
+                contents = curse.download_file(mod["project_id"], latest.id)
+                sha256 = hashlib.sha256(contents).hexdigest()
 
-        if latest is None:
+                new_mod = deepcopy(mod)
+                new_mod.update(
+                    {"filename": latest.name, "id": latest.id, "sha256": sha256}
+                )
+                new_mods.append(new_mod)
+            else:
+                new_mods.append(mod)
+        else:
             print(f"WARNING: No compatible files found for {mod['project']}")
             print(
-                f"Versions available: {[(f.name, f.gameVersion) for f in latest_files]}"
+                f"Versions available: {[(f.name, f.gameVersions) for f in latest_files]}"
             )
             new_mods.append(mod)
-        elif latest.id != mod["id"]:
-            print(f"Updating {mod['project']}...")
-            contents = curse.download_file(mod["project_id"], latest.id)
-            sha256 = hashlib.sha256(contents).hexdigest()
-
-            new_mod = deepcopy(mod)
-            new_mod.update({"filename": latest.name, "id": latest.id, "sha256": sha256})
-            new_mods.append(new_mod)
-        else:
-            new_mods.append(mod)
 
     with open("temp.json", "w") as out:
         json.dump(new_mods, out, sort_keys=True, indent=2)

From 3bdbe66fe47e38692b2a0eabd052255dafadbc1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 12 Oct 2021 13:53:08 +0100
Subject: [PATCH 029/212] nginx: Enable HSTS

---
 configuration/default.nix | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index 683b144..8600070 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -63,7 +63,10 @@
         lib.recursiveUpdate {
           forceSSL = true;
           enableACME = true;
-          locations."/" = { proxyPass = "http://127.0.0.1:${toString port}"; };
+          locations."/".proxyPass = "http://127.0.0.1:${toString port}";
+          extraConfig = ''
+            add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
+          '';
         } extra;
       domain = config.services.nginx.domain;
     in {

From b16ea49c4499ee50309e46d1ecc9fc4b06fdb51b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 13 Oct 2021 13:27:27 +0100
Subject: [PATCH 030/212] nextcloud: Set TRUSTED_PROXIES

Part of #47
---
 configuration/services/nextcloud.nix | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 4b74ac7..f8a0f08 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -20,6 +20,7 @@
           POSTGRES_USER = "nextcloud";
           POSTGRES_HOST = "nextcloud-postgres";
           OVERWRITEPROTOCOL = "https";
+          TRUSTED_PROXIES = "127.0.0.1";
         };
       };
 

From 20cda4404094344331491dda8b7916681567bbaf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 13 Oct 2021 14:53:05 +0100
Subject: [PATCH 031/212] nextcloud: Update nginx config

---
 .../services/configs/nginx-nextcloud.conf     | 156 +++++++++---------
 1 file changed, 75 insertions(+), 81 deletions(-)

diff --git a/configuration/services/configs/nginx-nextcloud.conf b/configuration/services/configs/nginx-nextcloud.conf
index 3eb1193..eec7bdb 100644
--- a/configuration/services/configs/nginx-nextcloud.conf
+++ b/configuration/services/configs/nginx-nextcloud.conf
@@ -24,11 +24,6 @@ http {
 
     keepalive_timeout  65;
 
-    set_real_ip_from  10.0.0.0/8;
-    set_real_ip_from  172.16.0.0/12;
-    set_real_ip_from  192.168.0.0/16;
-    real_ip_header    X-Real-IP;
-
     #gzip  on;
 
     upstream php-handler {
@@ -38,23 +33,22 @@ http {
     server {
         listen 80;
 
-        # Add headers to serve security related headers
-        # Before enabling Strict-Transport-Security headers please read into this
-        # topic first.
-        #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
-        #
+        # HSTS settings
         # WARNING: Only add the preload option once you read about
         # the consequences in https://hstspreload.org/. This option
         # will add the domain to a hardcoded list that is shipped
         # in all major browsers and getting removed from this list
         # could take several months.
-        add_header Referrer-Policy "no-referrer" always;
-        add_header X-Content-Type-Options "nosniff" always;
-        add_header X-Download-Options "noopen" always;
-        add_header X-Frame-Options "SAMEORIGIN" always;
-        add_header X-Permitted-Cross-Domain-Policies "none" always;
-        add_header X-Robots-Tag "none" always;
-        add_header X-XSS-Protection "1; mode=block" always;
+        #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
+
+        # HTTP response headers borrowed from Nextcloud `.htaccess`
+        add_header Referrer-Policy                      "no-referrer"   always;
+        add_header X-Content-Type-Options               "nosniff"       always;
+        add_header X-Download-Options                   "noopen"        always;
+        add_header X-Frame-Options                      "SAMEORIGIN"    always;
+        add_header X-Permitted-Cross-Domain-Policies    "none"          always;
+        add_header X-Robots-Tag                         "none"          always;
+        add_header X-XSS-Protection                     "1; mode=block" always;
 
         # Remove X-Powered-By, which is an information leak
         fastcgi_hide_header X-Powered-By;
@@ -62,27 +56,48 @@ http {
         # Path to the root of your installation
         root /var/www/html;
 
+        # Specify how to handle directories -- specifying `/index.php$request_uri`
+        # here as the fallback means that Nginx always exhibits the desired behaviour
+        # when a client requests a path that corresponds to a directory that exists
+        # on the server. In particular, if that directory contains an index.php file,
+        # that file is correctly served; if it doesn't, then the request is passed to
+        # the front-end controller. This consistent behaviour means that we don't need
+        # to specify custom rules for certain paths (e.g. images and other assets,
+        # `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
+        # `try_files $uri $uri/ /index.php$request_uri`
+        # always provides the desired behaviour.
+        index index.php index.html /index.php$request_uri;
+
+        # Rule borrowed from `.htaccess` to handle Microsoft DAV clients
+        location = / {
+            if ( $http_user_agent ~ ^DavClnt ) {
+                return 302 /remote.php/webdav/$is_args$args;
+            }
+        }
+
         location = /robots.txt {
             allow all;
             log_not_found off;
             access_log off;
         }
 
-        # The following 2 rules are only needed for the user_webfinger app.
-        # Uncomment it if you're planning to use this app.
-        #rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
-        #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
+        # Make a regex exception for `/.well-known` so that clients can still
+        # access it despite the existence of the regex rule
+        # `location ~ /(\.|autotest|...)` which would otherwise handle requests
+        # for `/.well-known`.
+        location ^~ /.well-known {
+            # The rules in this block are an adaptation of the rules
+            # in `.htaccess` that concern `/.well-known`.
 
-        # The following rule is only needed for the Social app.
-        # Uncomment it if you're planning to use this app.
-        #rewrite ^/.well-known/webfinger /public.php?service=webfinger last;
+            location = /.well-known/carddav { return 301 /remote.php/dav/; }
+            location = /.well-known/caldav  { return 301 /remote.php/dav/; }
 
-        location = /.well-known/carddav {
-            return 301 $scheme://$host:$server_port/remote.php/dav;
-        }
+            location /.well-known/acme-challenge    { try_files $uri $uri/ =404; }
+            location /.well-known/pki-validation    { try_files $uri $uri/ =404; }
 
-        location = /.well-known/caldav {
-            return 301 $scheme://$host:$server_port/remote.php/dav;
+            # Let Nextcloud's API for `/.well-known` URIs handle all other
+            # requests by passing them to the front-end controller.
+            return 301 /index.php$request_uri;
         }
 
         # set max upload size
@@ -97,77 +112,56 @@ http {
         gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
         gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
 
-        # Uncomment if your server is build with the ngx_pagespeed module
-        # This module is currently not supported.
+        # Pagespeed is not supported by Nextcloud, so if your server is built
+        # with the `ngx_pagespeed` module, uncomment this line to disable it.
         #pagespeed off;
 
-        location / {
-            rewrite ^ /index.php;
-        }
+        # Rules borrowed from `.htaccess` to hide certain paths from clients
+        location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; }
+        location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)                { return 404; }
 
-        location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
-            deny all;
-        }
-        location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
-            deny all;
-        }
-
-        location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
-            fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
+        # Ensure this block, which passes PHP files to the PHP process, is above the blocks
+        # which handle static assets (as seen below). If this block is not declared first,
+        # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
+        # to the URI, resulting in a HTTP 500 error response.
+        location ~ \.php(?:$|/) {
+            fastcgi_split_path_info ^(.+?\.php)(/.*)$;
             set $path_info $fastcgi_path_info;
+
             try_files $fastcgi_script_name =404;
+
             include fastcgi_params;
             fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
             fastcgi_param PATH_INFO $path_info;
-            # fastcgi_param HTTPS on;
+            #fastcgi_param HTTPS on;
 
-            # Avoid sending the security headers twice
-            fastcgi_param modHeadersAvailable true;
-
-            # Enable pretty urls
-            fastcgi_param front_controller_active true;
+            fastcgi_param modHeadersAvailable true;         # Avoid sending the security headers twice
+            fastcgi_param front_controller_active true;     # Enable pretty urls
             fastcgi_pass php-handler;
+
             fastcgi_intercept_errors on;
             fastcgi_request_buffering off;
         }
 
-        location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
-            try_files $uri/ =404;
-            index index.php;
+        location ~ \.(?:css|js|svg|gif)$ {
+            try_files $uri /index.php$request_uri;
+            expires 6M;         # Cache-Control policy borrowed from `.htaccess`
+            access_log off;     # Optional: Don't log access to assets
         }
 
-        # Adding the cache control header for js, css and map files
-        # Make sure it is BELOW the PHP block
-        location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
+        location ~ \.woff2?$ {
             try_files $uri /index.php$request_uri;
-            add_header Cache-Control "public, max-age=15778463";
-            # Add headers to serve security related headers (It is intended to
-            # have those duplicated to the ones above)
-            # Before enabling Strict-Transport-Security headers please read into
-            # this topic first.
-            #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
-            #
-            # WARNING: Only add the preload option once you read about
-            # the consequences in https://hstspreload.org/. This option
-            # will add the domain to a hardcoded list that is shipped
-            # in all major browsers and getting removed from this list
-            # could take several months.
-            add_header Referrer-Policy "no-referrer" always;
-            add_header X-Content-Type-Options "nosniff" always;
-            add_header X-Download-Options "noopen" always;
-            add_header X-Frame-Options "SAMEORIGIN" always;
-            add_header X-Permitted-Cross-Domain-Policies "none" always;
-            add_header X-Robots-Tag "none" always;
-            add_header X-XSS-Protection "1; mode=block" always;
-
-            # Optional: Don't log access to assets
-            access_log off;
+            expires 7d;         # Cache-Control policy borrowed from `.htaccess`
+            access_log off;     # Optional: Don't log access to assets
         }
 
-        location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$ {
-            try_files $uri /index.php$request_uri;
-            # Optional: Don't log access to other assets
-            access_log off;
+        # Rule borrowed from `.htaccess`
+        location /remote {
+            return 301 /remote.php$request_uri;
+        }
+
+        location / {
+            try_files $uri $uri/ /index.php$request_uri;
         }
     }
 }

From 90926e2eeecbb1051c88ec03471b8cb3a97f778a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 13 Oct 2021 15:29:12 +0100
Subject: [PATCH 032/212] nextcloud: Give nginx access to the nextcloud root

---
 configuration/services/nextcloud.nix | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index f8a0f08..d4a7fe5 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -11,6 +11,7 @@
         image = "nextcloud:fpm-alpine";
         dependsOn = [ "postgres" ];
         volumes = [
+          "nextcloud-root:/var/www/html"
           "nextcloud-apps:/var/www/html/custom_apps"
           "nextcloud-config:/var/www/html/config"
           "nextcloud-data:/var/www/html/data"
@@ -34,8 +35,10 @@
       nginx = {
         image = "nginx:alpine";
         dependsOn = [ "nextcloud" ];
-        volumes =
-          [ "${./configs/nginx-nextcloud.conf}:/etc/nginx/nginx.conf:ro" ];
+        volumes = [
+          "nextcloud-root:/var/www/html:ro"
+          "${./configs/nginx-nextcloud.conf}:/etc/nginx/nginx.conf:ro"
+        ];
         extraOptions = [ "--volumes-from=nextcloud-nextcloud" ];
       };
 

From 9060cb6414c4bef04c95f7a9873836ca6e65b67a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 17 Dec 2021 18:40:40 +0000
Subject: [PATCH 033/212] Update to NixOS 21.11
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file changes:

• Updated input 'flake-utils':
    'github:numtide/flake-utils/7e5bf3925f6fbdfaf50a2a7ca0be2879c4261d19' (2021-09-13)
  → 'github:numtide/flake-utils/74f7e4319258e287b0f9cb95426c9853b282730b' (2021-11-28)
• Updated input 'nixos-hardware':
    'github:nixos/nixos-hardware/0a8b8054c9920368a3c15e6d766188fdf04b736f' (2021-09-30)
  → 'github:nixos/nixos-hardware/2a7063461c3751d83869a2a0a8ebc59e34bec5b2' (2021-12-11)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/7daf35532d2d8bf5e6f7f962e6cd13a66d01a71d' (2021-10-03)
  → 'github:nixos/nixpkgs/573095944e7c1d58d30fc679c81af63668b54056' (2021-12-10)
---
 flake.lock | 20 ++++++++++----------
 flake.nix  |  2 +-
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/flake.lock b/flake.lock
index 3be1860..11de3e3 100644
--- a/flake.lock
+++ b/flake.lock
@@ -2,11 +2,11 @@
   "nodes": {
     "flake-utils": {
       "locked": {
-        "lastModified": 1631561581,
-        "narHash": "sha256-3VQMV5zvxaVLvqqUrNz3iJelLw30mIVSfZmAaauM3dA=",
+        "lastModified": 1638122382,
+        "narHash": "sha256-sQzZzAbvKEqN9s0bzWuYmRaA03v40gaJ4+iL1LXjaeI=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "7e5bf3925f6fbdfaf50a2a7ca0be2879c4261d19",
+        "rev": "74f7e4319258e287b0f9cb95426c9853b282730b",
         "type": "github"
       },
       "original": {
@@ -38,11 +38,11 @@
     },
     "nixos-hardware": {
       "locked": {
-        "lastModified": 1632990363,
-        "narHash": "sha256-SNqz+9Vt4yDHqw8u/CMFdzMQTulKoMlVGJdshfcb5O0=",
+        "lastModified": 1639240632,
+        "narHash": "sha256-BAXhgnPOW1COIfZ9EOOFTdolalYS73MFHSRajgrSdZw=",
         "owner": "nixos",
         "repo": "nixos-hardware",
-        "rev": "0a8b8054c9920368a3c15e6d766188fdf04b736f",
+        "rev": "2a7063461c3751d83869a2a0a8ebc59e34bec5b2",
         "type": "github"
       },
       "original": {
@@ -54,16 +54,16 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1633267966,
-        "narHash": "sha256-gFKvZ5AmV/dDTKXVxacPbXe4R0BsFpwtVaQxuIm2nnk=",
+        "lastModified": 1639161226,
+        "narHash": "sha256-75Y08ynJDTq6HHGIF+8IADBJSVip0UyWQH7jqSFnRR8=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "7daf35532d2d8bf5e6f7f962e6cd13a66d01a71d",
+        "rev": "573095944e7c1d58d30fc679c81af63668b54056",
         "type": "github"
       },
       "original": {
         "owner": "nixos",
-        "ref": "nixos-21.05",
+        "ref": "nixos-21.11",
         "repo": "nixpkgs",
         "type": "github"
       }
diff --git a/flake.nix b/flake.nix
index a7b1ef7..8a0025f 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,7 +2,7 @@
   description = "tlater.net host configuration";
 
   inputs = {
-    nixpkgs.url = "github:nixos/nixpkgs/nixos-21.05";
+    nixpkgs.url = "github:nixos/nixpkgs/nixos-21.11";
     nixos-hardware.url = "github:nixos/nixos-hardware/master";
     flake-utils.url = "github:numtide/flake-utils";
     tlaternet-webserver = {

From bd7e4a319328da315222d9c37b3629d7a9566621 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 26 Dec 2021 19:00:59 +0000
Subject: [PATCH 034/212] Fix service uid/gids

---
 configuration/ids.nix                |  6 ++++++
 configuration/services/minecraft.nix | 15 ++++++++++++---
 configuration/services/webserver.nix | 18 ++++++++++--------
 3 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/configuration/ids.nix b/configuration/ids.nix
index 895b976..5488ff0 100644
--- a/configuration/ids.nix
+++ b/configuration/ids.nix
@@ -4,6 +4,12 @@
   ids.uids = {
     # System user ids start at 400 (see nixos/modules/programs/shadow.nix)
     webserver = 400;
+    minecraft = 401;
     # The limit is 999
   };
+
+  ids.gids = {
+    webserver = 400;
+    minecraft = 401;
+  };
 }
diff --git a/configuration/services/minecraft.nix b/configuration/services/minecraft.nix
index bf8f58f..23705ac 100644
--- a/configuration/services/minecraft.nix
+++ b/configuration/services/minecraft.nix
@@ -54,6 +54,16 @@ in {
   nixpkgs.config.allowUnfreePredicate = pkg:
     builtins.elem (lib.getName pkg) [ "forge-server" ];
 
+  users = {
+    extraUsers.minecraft = {
+      uid = config.ids.uids.minecraft;
+      group = config.users.extraGroups.minecraft.name;
+      isSystemUser = true;
+      description = "Minecraft server user";
+    };
+    extraGroups.minecraft = { gid = config.ids.gids.minecraft; };
+  };
+
   virtualisation.oci-containers.containers.minecraft-voor-kia = let
     properties = ./configs/minecraft/voor-kia/server.properties;
     icon = ./configs/minecraft/voor-kia/server-icon.png;
@@ -73,9 +83,8 @@ in {
       ];
 
       config = let
-        # Use the upstream minecraft uid
-        uid = toString config.ids.uids.minecraft;
-        gid = toString config.users.groups.nogroup.gid;
+        uid = toString config.users.extraUsers.minecraft.uid;
+        gid = toString config.users.extraGroups.minecraft.gid;
       in {
         Cmd = [ "forge-server" ] ++ minecraft-server-args;
         WorkingDir = "/var/lib/minecraft";
diff --git a/configuration/services/webserver.nix b/configuration/services/webserver.nix
index c1966a5..d72b417 100644
--- a/configuration/services/webserver.nix
+++ b/configuration/services/webserver.nix
@@ -1,10 +1,14 @@
 { config, pkgs, ... }:
 
 {
-  users.extraUsers.webserver = {
-    uid = config.ids.uids.webserver;
-    isSystemUser = true;
-    description = "tlater.net web server user";
+  users = {
+    extraUsers.webserver = {
+      uid = config.ids.uids.webserver;
+      group = config.users.extraGroups.webserver.name;
+      isSystemUser = true;
+      description = "tlater.net web server user";
+    };
+    extraGroups.webserver = { gid = config.ids.gids.webserver; };
   };
 
   virtualisation.oci-containers.containers.webserver = {
@@ -16,10 +20,8 @@
       contents = pkgs.tlaternet-webserver.webserver;
 
       config = let
-        user = config.users.extraUsers.webserver;
-        group = config.users.groups.${user.group};
-        uid = toString user.uid;
-        gid = toString group.gid;
+        uid = toString config.users.extraUsers.webserver.uid;
+        gid = toString config.users.extraGroups.webserver.gid;
       in {
         Cmd = [ "tlaternet-webserver" ];
         Volumes = { "/srv/mail" = { }; };

From b6f39969cc50293b6dce493ef3273bc0573939f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 8 Jan 2022 00:27:01 +0000
Subject: [PATCH 035/212] Fix podman hostnames

It seems that with the newest version of podman container names are no
longer added as hostnames, meaning that any attempt to resolve
hostnames with the current config will fail. `localhost` is probably
more robust anyway, so we switch to that.

The bug manifests as broken services because nextcloud/gitea cannot
resolve their databases and nextcloud fails to resolve the php
server. To fix this a running system, the gitea and nextcloud database
configurations will need to be hand-edited, since those values are
only set on initialization, and not updated when changed later.
---
 configuration/services/configs/nginx-nextcloud.conf | 2 +-
 configuration/services/gitea.nix                    | 2 +-
 configuration/services/nextcloud.nix                | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/configuration/services/configs/nginx-nextcloud.conf b/configuration/services/configs/nginx-nextcloud.conf
index eec7bdb..7c6ad78 100644
--- a/configuration/services/configs/nginx-nextcloud.conf
+++ b/configuration/services/configs/nginx-nextcloud.conf
@@ -27,7 +27,7 @@ http {
     #gzip  on;
 
     upstream php-handler {
-        server nextcloud-nextcloud:9000;
+        server localhost:9000;
     }
 
     server {
diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index 2258566..221b976 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -24,7 +24,7 @@
 
         environment = {
           DB_TYPE = "postgres";
-          DB_HOST = "gitea-postgres:5432";
+          DB_HOST = "localhost:5432";
           DB_NAME = "gitea";
           DB_USER = "gitea";
 
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index d4a7fe5..7d94bcf 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -19,7 +19,7 @@
         environment = {
           POSTGRES_DB = "nextcloud";
           POSTGRES_USER = "nextcloud";
-          POSTGRES_HOST = "nextcloud-postgres";
+          POSTGRES_HOST = "localhost";
           OVERWRITEPROTOCOL = "https";
           TRUSTED_PROXIES = "127.0.0.1";
         };

From c019187b37f12c7940c32b5b9cbbd82eac4be130 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 18 Jan 2022 18:46:37 +0000
Subject: [PATCH 036/212] postgres: Upgrade to version 14

---
 configuration/services/gitea.nix     | 2 +-
 configuration/services/nextcloud.nix | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index 221b976..7f49d32 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -43,7 +43,7 @@
           POSTGRES_DB = "gitea";
           POSTGRES_USER = "gitea";
         };
-        volumes = [ "gitea-db-data:/var/lib/postgresql/data" ];
+        volumes = [ "gitea-postgres-14:/var/lib/postgresql/data" ];
       };
     };
   };
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 7d94bcf..f63b294 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -48,7 +48,7 @@
           POSTGRES_DB = "nextcloud";
           POSTGRES_USER = "nextcloud";
         };
-        volumes = [ "nextcloud-db-data:/var/lib/postgresql/data" ];
+        volumes = [ "nextcloud-postgres-14:/var/lib/postgresql/data" ];
       };
     };
   };

From 4ef17ed1a21b4ff07db0d647855b3cbad45ae32a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Thu, 10 Feb 2022 22:17:37 +0000
Subject: [PATCH 037/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file changes:

• Updated input 'flake-utils':
    'github:numtide/flake-utils/74f7e4319258e287b0f9cb95426c9853b282730b' (2021-11-28)
  → 'github:numtide/flake-utils/3cecb5b042f7f209c56ffd8371b2711a290ec797' (2022-02-07)
• Updated input 'nixos-hardware':
    'github:nixos/nixos-hardware/2a7063461c3751d83869a2a0a8ebc59e34bec5b2' (2021-12-11)
  → 'github:nixos/nixos-hardware/9886a06e4745edb31587d0e9481ad82d35f0d593' (2022-02-04)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/573095944e7c1d58d30fc679c81af63668b54056' (2021-12-10)
  → 'github:nixos/nixpkgs/521e4d7d13b09bc0a21976b9d19abd197d4e3b1e' (2022-02-07)
---
 flake.lock | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/flake.lock b/flake.lock
index 11de3e3..91b61ea 100644
--- a/flake.lock
+++ b/flake.lock
@@ -2,11 +2,11 @@
   "nodes": {
     "flake-utils": {
       "locked": {
-        "lastModified": 1638122382,
-        "narHash": "sha256-sQzZzAbvKEqN9s0bzWuYmRaA03v40gaJ4+iL1LXjaeI=",
+        "lastModified": 1644229661,
+        "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "74f7e4319258e287b0f9cb95426c9853b282730b",
+        "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
         "type": "github"
       },
       "original": {
@@ -38,11 +38,11 @@
     },
     "nixos-hardware": {
       "locked": {
-        "lastModified": 1639240632,
-        "narHash": "sha256-BAXhgnPOW1COIfZ9EOOFTdolalYS73MFHSRajgrSdZw=",
+        "lastModified": 1643980037,
+        "narHash": "sha256-RdVHt2mD408WXMjQIOLvUzy8cSUHu8NAbilDmPVxf7E=",
         "owner": "nixos",
         "repo": "nixos-hardware",
-        "rev": "2a7063461c3751d83869a2a0a8ebc59e34bec5b2",
+        "rev": "9886a06e4745edb31587d0e9481ad82d35f0d593",
         "type": "github"
       },
       "original": {
@@ -54,11 +54,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1639161226,
-        "narHash": "sha256-75Y08ynJDTq6HHGIF+8IADBJSVip0UyWQH7jqSFnRR8=",
+        "lastModified": 1644193793,
+        "narHash": "sha256-ggCI5LCXwkUJQwjpkr9qDFbQMiK3JvAfeNR4Uy0ny5Q=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "573095944e7c1d58d30fc679c81af63668b54056",
+        "rev": "521e4d7d13b09bc0a21976b9d19abd197d4e3b1e",
         "type": "github"
       },
       "original": {

From 1721785d1ce63b461ac862706cae4bed19df096e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 26 Dec 2021 19:01:56 +0000
Subject: [PATCH 038/212] Update forge server sha

---
 pkgs/minecraft/forge-server.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkgs/minecraft/forge-server.nix b/pkgs/minecraft/forge-server.nix
index 2dea39a..e26a7a5 100644
--- a/pkgs/minecraft/forge-server.nix
+++ b/pkgs/minecraft/forge-server.nix
@@ -9,7 +9,7 @@ let
     url = "${mirror}/${version}/forge-${version}-installer.jar";
     curlOpts = "--globoff";
     # Forge doesn't seem to like newer shas
-    sha1 = "e97821e5431bdcaa46e12048769922e2cdb5e2e1";
+    sha1 = "sha1-oHNpyrgHluRrAXWZJg9j+OInAwA=";
   };
 
   unpackCmd = "mkdir -p src; cp $curSrc src/forge-${version}-installer.jar";

From 34235a20414e9f61fbb8c831ffe3d8bf6103c307 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Thu, 21 Apr 2022 18:00:09 +0100
Subject: [PATCH 039/212] flake: Fix python language server version

---
 flake.nix | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/flake.nix b/flake.nix
index 8a0025f..82ce5b7 100644
--- a/flake.nix
+++ b/flake.nix
@@ -101,10 +101,19 @@
                   requests
 
                   ipython
-                  python-language-server
-                  pyls-black
-                  pyls-isort
-                  pyls-mypy
+
+                  python3.withPackages (ppkgs:
+                    with pkgs; [
+                      python-lsp-server
+                      python-lsp-black
+                      pyls-isort
+                      pyls-mypy
+                      rope
+                      pyflakes
+                      mccabe
+                      pycodestyle
+                      pydocstyle
+                    ])
                 ]))
             ];
             shellHook = ''

From 73988df2a6ad360f57d2bd37003966a8f58475cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Thu, 21 Apr 2022 18:21:53 +0100
Subject: [PATCH 040/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file changes:

• Updated input 'flake-utils':
    'github:numtide/flake-utils/3cecb5b042f7f209c56ffd8371b2711a290ec797' (2022-02-07)
  → 'github:numtide/flake-utils/a4b154ebbdc88c8498a5c7b01589addc9e9cb678' (2022-04-11)
• Updated input 'nixos-hardware':
    'github:nixos/nixos-hardware/9886a06e4745edb31587d0e9481ad82d35f0d593' (2022-02-04)
  → 'github:nixos/nixos-hardware/6b4ebea9093c997c5f275c820e679108de4871ab' (2022-04-21)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/521e4d7d13b09bc0a21976b9d19abd197d4e3b1e' (2022-02-07)
  → 'github:nixos/nixpkgs/9887f024766aa27704d1f89f623efd1d063da92a' (2022-04-21)
---
 flake.lock | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/flake.lock b/flake.lock
index 91b61ea..7a563d8 100644
--- a/flake.lock
+++ b/flake.lock
@@ -2,11 +2,11 @@
   "nodes": {
     "flake-utils": {
       "locked": {
-        "lastModified": 1644229661,
-        "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
+        "lastModified": 1649676176,
+        "narHash": "sha256-OWKJratjt2RW151VUlJPRALb7OU2S5s+f0vLj4o1bHM=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
+        "rev": "a4b154ebbdc88c8498a5c7b01589addc9e9cb678",
         "type": "github"
       },
       "original": {
@@ -38,11 +38,11 @@
     },
     "nixos-hardware": {
       "locked": {
-        "lastModified": 1643980037,
-        "narHash": "sha256-RdVHt2mD408WXMjQIOLvUzy8cSUHu8NAbilDmPVxf7E=",
+        "lastModified": 1650522846,
+        "narHash": "sha256-SxWHXRI3qJwswyXAtzsi6PKVY3KLNNnb072KaJthII8=",
         "owner": "nixos",
         "repo": "nixos-hardware",
-        "rev": "9886a06e4745edb31587d0e9481ad82d35f0d593",
+        "rev": "6b4ebea9093c997c5f275c820e679108de4871ab",
         "type": "github"
       },
       "original": {
@@ -54,11 +54,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1644193793,
-        "narHash": "sha256-ggCI5LCXwkUJQwjpkr9qDFbQMiK3JvAfeNR4Uy0ny5Q=",
+        "lastModified": 1650501692,
+        "narHash": "sha256-ApKf0/dc0SyB7zZ6yiiOQgcXAhCXxbSDyihHfRDIzx0=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "521e4d7d13b09bc0a21976b9d19abd197d4e3b1e",
+        "rev": "9887f024766aa27704d1f89f623efd1d063da92a",
         "type": "github"
       },
       "original": {

From e7102adec11bd1f5dc6716651767ec6acc7c1428 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 23 Apr 2022 04:06:50 +0100
Subject: [PATCH 041/212] Add sops-nix

---
 .sops.yaml                |  9 +++++
 configuration/default.nix |  5 +++
 flake.lock                | 21 ++++++++++++
 flake.nix                 | 26 ++++++++++----
 keys/external.yaml        | 52 ++++++++++++++++++++++++++++
 keys/hosts/tlaternet.asc  | 28 +++++++++++++++
 keys/users/tlater.asc     | 72 +++++++++++++++++++++++++++++++++++++++
 7 files changed, 207 insertions(+), 6 deletions(-)
 create mode 100644 .sops.yaml
 create mode 100644 keys/external.yaml
 create mode 100644 keys/hosts/tlaternet.asc
 create mode 100644 keys/users/tlater.asc

diff --git a/.sops.yaml b/.sops.yaml
new file mode 100644
index 0000000..ad56f8b
--- /dev/null
+++ b/.sops.yaml
@@ -0,0 +1,9 @@
+keys:
+  - &tlater 535B61015823443941C744DD12264F6BBDFABA89
+  - &server_tlaternet 8a3737d48f1035fe6c3a0a8fd6a1976ca74c7f3b
+
+creation_rules:
+  - key_groups:
+      - pgp:
+          - *tlater
+          - *server_tlaternet
diff --git a/configuration/default.nix b/configuration/default.nix
index 8600070..d6cc5cf 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -20,6 +20,11 @@
     trustedUsers = [ "@wheel" ];
   };
 
+  sops = {
+    defaultSopsFile = ../keys/external.yaml;
+    secrets.steam = { };
+  };
+
   boot.kernelParams = [ "highres=off" "nohz=off" ];
 
   networking = {
diff --git a/flake.lock b/flake.lock
index 7a563d8..5c75d61 100644
--- a/flake.lock
+++ b/flake.lock
@@ -73,6 +73,7 @@
         "flake-utils": "flake-utils",
         "nixos-hardware": "nixos-hardware",
         "nixpkgs": "nixpkgs",
+        "sops-nix": "sops-nix",
         "tlaternet-templates": "tlaternet-templates",
         "tlaternet-webserver": "tlaternet-webserver"
       }
@@ -102,6 +103,26 @@
         "type": "github"
       }
     },
+    "sops-nix": {
+      "inputs": {
+        "nixpkgs": [
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1649756291,
+        "narHash": "sha256-KTll8bCINAzIUGaaMrbn9wb5nfhkXRLgmFrWGR/Dku0=",
+        "owner": "Mic92",
+        "repo": "sops-nix",
+        "rev": "c2614c4fe61943b3d280ac1892fcebe6e8eaf8c8",
+        "type": "github"
+      },
+      "original": {
+        "owner": "Mic92",
+        "repo": "sops-nix",
+        "type": "github"
+      }
+    },
     "tlaternet-templates": {
       "inputs": {
         "flake-utils": [
diff --git a/flake.nix b/flake.nix
index 82ce5b7..d8928df 100644
--- a/flake.nix
+++ b/flake.nix
@@ -5,6 +5,11 @@
     nixpkgs.url = "github:nixos/nixpkgs/nixos-21.11";
     nixos-hardware.url = "github:nixos/nixos-hardware/master";
     flake-utils.url = "github:numtide/flake-utils";
+    sops-nix = {
+      url = "github:Mic92/sops-nix";
+      inputs.nixpkgs.follows = "nixpkgs";
+    };
+
     tlaternet-webserver = {
       url = "git+https://gitea.tlater.net/tlaternet/tlaternet.git";
       inputs = {
@@ -21,8 +26,8 @@
     };
   };
 
-  outputs = { self, nixpkgs, nixos-hardware, flake-utils, tlaternet-webserver
-    , tlaternet-templates, ... }@inputs:
+  outputs = { self, nixpkgs, nixos-hardware, flake-utils, sops-nix
+    , tlaternet-webserver, tlaternet-templates, ... }@inputs:
     let
       overlays = [
         (final: prev: {
@@ -53,6 +58,7 @@
             (import ./configuration)
             (import ./configuration/linode.nix)
             (import ./configuration/hardware-configuration.nix)
+            sops-nix.nixosModules.sops
           ];
         };
 
@@ -68,6 +74,7 @@
             (import ./modules)
 
             (import ./configuration)
+            sops-nix.nixosModules.sops
             ({ lib, ... }: {
               users.users.tlater.password = "insecure";
 
@@ -86,13 +93,20 @@
         };
       };
     } // flake-utils.lib.eachDefaultSystem (system:
-      let pkgs = import nixpkgs { inherit system overlays; };
+      let
+        pkgs = import nixpkgs { inherit system overlays; };
+        sops-pkgs = sops-nix.packages.${system};
       in {
-        devShell = with pkgs;
-          mkShell {
-            buildInputs = [
+        devShell =
+          pkgs.mkShell {
+            sopsPGPKeyDirs = ["./keys/hosts/" "./keys/users/"];
+            nativeBuildInputs = with sops-pkgs; [
+              sops-import-keys-hook
+            ];
+            buildInputs = with pkgs; with sops-pkgs; [
               nixfmt
               git-lfs
+              sops-init-gpg-key
 
               # For the minecraft mod update script
               (python3.withPackages (pypkgs:
diff --git a/keys/external.yaml b/keys/external.yaml
new file mode 100644
index 0000000..c51d957
--- /dev/null
+++ b/keys/external.yaml
@@ -0,0 +1,52 @@
+steam: ENC[AES256_GCM,data:Jhk91uP3Ixo7H4I9kXEWeA==,iv:s8BcwGNF1vG8KI41FmQXOBbqZl8SnMZ9+YP6GKwHdtY=,tag:dW462jNJCtG4HWrkeQTUzw==,type:str]
+sops:
+    kms: []
+    gcp_kms: []
+    azure_kv: []
+    hc_vault: []
+    age: []
+    lastmodified: "2022-04-23T07:07:21Z"
+    mac: ENC[AES256_GCM,data:E9z+h2kejAobo3wIRBQFGyMfMHoeVREE+pEF9XoVZF8cQM4xC4tHub+eENsBIDeWoIcPtugLE9Xwzn9odyg92Vri/SzcaxrEXzsAcvFj6Ox2cN27h17OrkQBMKeA/tnMVg+uJxQesWZbrfcMsmd99X1W1RH5SMUwNrqjCsNxZ7s=,iv:pfi/EXgacNapdVlKP0UEMKdxi7s4YicfFcSopvwOrNA=,tag:RmMPwBYFZx2M5FJCVyhcLg==,type:str]
+    pgp:
+        - created_at: "2022-04-23T07:07:08Z"
+          enc: |
+            -----BEGIN PGP MESSAGE-----
+
+            hQIMAzWu0p84AOApAQ/8DeQLvWBjQn3mNfmiPyH0NNj0d70FKbm546jFjBuVHW9h
+            P3KWVJF8pWdg17W5Hlu8xDPCCYmX5Rew3JznbEpyxIMUAUPS+HpwEWXvpKUMNhIj
+            VDcQ5cVkfiOc81gRKXLiWNmBP2lRKrjjmFBEbwZgHxW2Y9yzmzqsR97VWrBhkz9r
+            Rsif8Mi29LAbpG0lgVZSji7pzs/4EbclSQsfv6JSJMoA0bD3OdtyAmJh4dfUV31i
+            kzkOJ8WIAwYpvKXI4Jf3DuUS7njzdw4SRCgf5nuC8Ml1Kb4IvCwTsPEOaYRhCZIX
+            jUTmQ4DwiIZ+618Wzi6SHgdH1QZaS5e71n0rxPxsYY6UbCyDhrGNcXgn/p0DHP04
+            p+Hscl75IqJiMzlAnQobx111vw1f3oGgTuWYS78Tccpy/QgMtVf99CeVwp4fVkeU
+            iPGr5oy5KO3WF3EWvuK/A/eoiK208YRMcL+0hrFDuhTB7qnyCRBjTv+4SJdY3FiC
+            KA/syZ/+DioUVyEXNn8cttk0U9Wf5zub7s/9Ei7MQVVUgCvyZZDHFE+50d5UeVRm
+            WW5T38D3G+v6py8gkC4/noKndr6SzRgPBAVW/Ba9CZZtEulhA39U9M4Q9cCSyLCM
+            nAiu0ikOiDif4w+1fxeEA+BXp7uBbW9vz09jetfDkp+i4hvt41a9dwJpTmxWm57S
+            XgFQDuO+HdFs44Yw1gyJQKLK3YejSyoKIo5pN36yMGuYPw9B75Cx+MWJJihL5IHl
+            gTqNPiD3cIyFw9U+FYfvqdQz9Vo/dD8gF0G5Y5MVH0E9xNsSFuSWoA9H2Zl+Ops=
+            =W5PZ
+            -----END PGP MESSAGE-----
+          fp: 535B61015823443941C744DD12264F6BBDFABA89
+        - created_at: "2022-04-23T07:07:08Z"
+          enc: |
+            -----BEGIN PGP MESSAGE-----
+
+            hQIMA9ahl2ynTH87ARAAwKoe5UHRlt86d47oCSvXVV0JvRdw6K5VKDIyZr5FEAZD
+            VHDvZb7a0qlKuJsKiq5+3hZPkw9W9DLtpacxQdEoTUDQVAfVAi1pIKaJIYP7pSC3
+            LbcqNXucqJoKLKXHE0zCPAJdbTYOo804Z6iLRJRYwuLHfE17lVPMoJD9OjwZn1LS
+            ksJnki68YqQcFocRuUF/pq+bcd0ceV7YQiBIdO/89YyVPgviORXzlRZ5+hTpFjqd
+            rYFzgNBkHVRHUso8S9YNiFsU8dKVXBDS6LiykcKe9C6kEYDCe24VVHyrlj2s3isH
+            68PefnfQY5ZIBSDm2uwGmym1pSwhR015Ely/gqRx+T4qfCcAwva9ZPusXHzHu2+z
+            vwO83yeBXFbs4YFdHhh9GNbOfbBKCdPU0FAqQCuU0P7iVrCfjtTXdg622hn7x2YW
+            YwH5nlcm14/U39jOzWNketmyAiaOJ32ko3Ec63ELkGCb8+LR0eCPDNUNCQcnKGaU
+            yrTYnqUG6ODxdkhvq1JCsPKlZ/0pqiSQKBE1dGZBrcshZZ6SvdhO6hSimg3m+Mqn
+            wh5pcx/P5k3VXPovTRkRAU/U6RdYKs+qH1tXCBSMwjz4EU9VCYZbqLb1Bp/NfsPa
+            0CL50HA617ID0ofxOL8eT49xQJZZFFAArOMZmRGgsKrPAEYijnQ/593nci4DdozS
+            UAFrki95hH3EFygU3KkVdpULaOwc/0SWIPLZgmpFq2H5bKOqi9TL0IV3G00qEf5G
+            bOFb1q7pCAWMe5b6JH7MQRmSWwaoE4qhtmOkjHMOuqhA
+            =hTbV
+            -----END PGP MESSAGE-----
+          fp: 8a3737d48f1035fe6c3a0a8fd6a1976ca74c7f3b
+    unencrypted_suffix: _unencrypted
+    version: 3.7.2
diff --git a/keys/hosts/tlaternet.asc b/keys/hosts/tlaternet.asc
new file mode 100644
index 0000000..5b03dea
--- /dev/null
+++ b/keys/hosts/tlaternet.asc
@@ -0,0 +1,28 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+xsFNBAAAAAABEADkGxU+/uxtkVsX9+Wycp6ikG9177NvCsXqROeuIIJ5nDWD+jrt
+jlO1ngL9vvOfE4mGNY839r86cbSocK2WCirVnPdh8K5o9X+YptA7yHoe8RHn0fZC
+wM1eGSDTMmtGvP00IXoMpktzU+GcrO/1XMFIshj/2KboUGYqRpqhfiNQXPcYlz4J
+QRXsPzPnAphSn9ausYb6f8qYn+ivSo9jKDHZL4FJJ2OkYsoo3sX8lMWCE3ON48QF
+9K4UU0Ru86/1sBW55AT5IzVTF7TKWAjnHi8v9Lzd7lVJy8ZLe1bioP75wCl3aE1N
+owE/H4hPKfYTjKHdNkU4c4HjsATU1Ak9hJXj7zMeI/J7JF+wD7ztYo4RZWZTPPNP
+k1ELmCXMNQp3Dujy54kXLi+d5ii4FK/q/G1n1ZdMjjEhem7LEpZXq8tNsHnzfnlK
+QDazAQvGb3Gnv4OuMe4CvvMNBNRiooikCejsBYswW9QkOguyivQHDx2UMqUVU8L0
+HCBzVi9JQKy2Dn1gKP9SDvotYZmS/VVe++wx+EkIIty3ecl1HpsxtqQgNaUewJiM
+NnBBgnwzKigqCqCUDjg+8KKh6AENtAeGa+LFZWw2pZ6ZiwcqjDIu0zoQVesCuF/Z
+zktNVPjIMTH2Cg4PTKccHIROHRjFJjn1fIAmQPoh3QjDHrUMSbtaTbfWIQARAQAB
+zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT
+AQgAFgUCAAAAAAkQ1qGXbKdMfzsCGw8CGQEAABDNEAAjEKhsm0ukNqHQZzmIlYRL
+6ybTmeGOYczKlTM0h5EDTMSvPn89WuWPZCL/oyIOE+TKqkjEsBc4ej2YmxdHSS/f
+4WLOLqWre6Krs1qZ/eTBLU0LOwEtYYt8x44WN5K1GyyVyZAkGdIYO5NaQPP86m/H
+QzyZ+YRQvcqlUgNUmRIsq2F+X7kRKl9X+6zZDsM72aAEvOlWss/sn3Dca2omxaAB
+/b32P0r1ppCPXLk0QRbZM+D38CUaZIKWhKKvaifKaRhY1eTPv1OG8uFGrkYcxB9m
+GkOZh4Kbz4+Es5uM5uYSxNWWmqU5FX/D8qEzsn7OB+WH1wFLwp75oR8shy8FQ3B0
++JVBwJEmg+kBoYZHPjVHxp/z2h4drTQ/h2uulplWUuCpH8dLjCy3dHukEH1tw803
+34fCUxN5RTyOG3uGC/8cXZ7Xj5RnX0dso6g4/0kmy42S2EAoxB+L1CmuI02SBxCK
+9go7oyP9sUBQ59BA8W5Ab8a5+CpB/kWthGErtMcq56bNqA7S9+UgyqOJze4mqBVs
+qBFjYK1/aYbKIarXuw6cOuCZfXQIRex7IDVdW1ikKs4h3g2h0wBgnY+xOaFNUQxa
+I7gG4e+sBnlvlCyoyzstE/JjAQr9QC9qj30UB3iankyDZD/F1MfEx4HRm7f+V/4P
+PoGnDfqmEEn9P7j7sOJ0iw==
+=z4j4
+-----END PGP PUBLIC KEY BLOCK-----
\ No newline at end of file
diff --git a/keys/users/tlater.asc b/keys/users/tlater.asc
new file mode 100644
index 0000000..d9c50dd
--- /dev/null
+++ b/keys/users/tlater.asc
@@ -0,0 +1,72 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBF4nGvQBEAC7BhX6nCHHt/lmxnnu+z/GPJ9QPcNkXZuGtf9+GCBjUfkNpeuf
+4vbyX88jlqhBHYkLKqFeWitNH1bwJtk+0gslPLnXUcYDgKNu+JrWiJd+ygJptrDf
+Kh8wLRVoyKeSVURVMclAkHA328qgEPPQuIrPX6ILa2+xey3gOAW1jKm1teldQ6IB
+dt1OgzaglVWhKENWQt5VamkN+ABnBymalg2Z5nbgE3LO/QW1bnAXM1wpRUcK+v99
+b2KpoPVn44ZjWGXD3jLJAPxZcvanpT2RDaYhPLTrr8nRf2+i8BzA7BUHmzVZFF4h
+8J9N3da/+LINGCFVqHgMT8N7/ZZgXg7PwW+k8s2juhjyv5ycgzJlE2E679LoXJeJ
+jDmZdP/kFqa2FCQjfM4wpflB7EfmdNIbEIJ82kXaZOKG/cGjbEsQ8oZtGBV+Y0aH
+FMU/1LD0M+n+if7Ydw7RsMzgOnr4DEXYLtNtaOgebc/rZRu7Wkix+gvAYSTwV+ph
+eDSnFQZui1QXJ1gnzO6Hi4Xe4ChPwUrcIIAoJ07INWruF6nXo8h9dtpPOtMsIZ02
+Ena7OwfaCuKRf0hwNYERyZN+Lzc105BzUv0d9rsA6qlv4qlaG01Lz+2kdb1zhk7E
+8FYksFrdnSRwd1qYm4KKGJO/dKJat1sJI4ldK2rn2/O5Hrm9O9RaATT1QQARAQAB
+tDpUcmlzdGFuIERhbmnDq2wgTWFhdCAod29yaykgPHRyaXN0YW4ubWFhdEBjb2Rl
+dGhpbmsuY28udWs+iQJMBBMBCgA2FiEEU1thAVgjRDlBx0TdEiZPa736uokFAl4n
+HXICGwEECwkIBwQVCgkIBRYCAwEAAh4BAheAAAoJEBImT2u9+rqJy0oP/1rl/R4n
+oqJbVa4BCkUZI3wyVomibyodWed/nAFRT9BzapVWqrhYsZuOtv7Xy5/qzFHrxMOW
+9aaJ3Rz7lI72uy4o86AqwRdMmSsmgFDj+HEk98eUoZed3ijtAltR83xYzlpQuJ3+
+o+O+Vs+sUUAI57FZ/7RyEPzcxk/+9yU1aSGWGwjDP4tWR+Fe69kqCoCUskydU4IM
+Ss3LbNzEypVGG/GOa/rUlJ3n/XvG0HjjGm1g4tnelkE06zFDIbglhPKJNuLbeH1j
+RDUdj1iX81B5nFDr+ARr4zqS5PJFgyiQDxU7fDx55mTRuqQ8M/X8eYeK7PXn8w5U
+2DQgh1AEgfQrLbPdZ2lwf/aINHf5wRSGvxBKIAxXpsMt98RUfd+L//aPrl5Hwi6H
+ZKe0Pbkn/GwmKZq3iqd5uaN6vLqybl9cHHaQ58MPCb0guYAJD0higgrw1tgNMhX1
+RGAutfQCbgJhkzqgYQ2Ystd9ky+mf4L+d5Ct+ks9J/WkkjQ61A8WbtqR34iytE+P
+clR9Z+p1kgeF0mzN29ZYYrIxVFhxD7abBBZfzNLJPEmRiU7EstH0sqVtuD8G1Uec
+/u/v7NTECtUu1zq5BK09mV8ZkeqTkQKCx1iRyfD8JSFYYb3sGyYtCIaOvLnnQf93
+mhbzdlXAyHLshjzrHoF2TixCIpskMWx1zM/5tC1UcmlzdGFuIERhbmnDq2wgTWFh
+dCAodGxhdGVyKSA8dG1AdGxhdGVyLm5ldD6JAkwEEwEKADYWIQRTW2EBWCNEOUHH
+RN0SJk9rvfq6iQUCXica9AIbAQQLCQgHBBUKCQgFFgIDAQACHgECF4AACgkQEiZP
+a736uon/aA/6A0tn+otsfGfei9QxDgM255R1U76PdSVb2bEl4/IdSq4uw8CtM69b
+CesCoajj/qgXzEFhpijQ9pXZDpMDXk64EZtcO5T96RNXA8Oh5CkpnVXv2MOrFXVL
+Zc05EOh6qxMCRACliii7CyGExAbRU/TdhL86dWc06CAiMt0/vzYgHpy69jpomHsP
+OeWk8TghHsMHPHOpfk4sS8gYlvsKV7QDpW5sNPmbm/nCFr+PoR7R+BKnklhdX9HN
+d/Ha6KSXpEjzqIoI/X3TtYtTyhNdwZ0rbKPtQYqMi08dnr4INjED5kZvrVFr16s1
+nFp8CghrnnUq9t1hzFAnYTWX736/CU/0ZrANRVsaKdJ3tCey2OT+IdprYZlriFvO
+ZO9AD5BV/V/e+QFi7LUZEEmsK3AVFERmRxP+597ZyK4ozjc0s8aLI2q9O8GROGxR
+GHloGMH9Mv5T/gfBfyFtoMU3poYOHCfwvtt9sr5IuiaexsGKTSTqRUWhq9moiGb8
+mQxQnZwIoRuQkmcV1JlfuS2inSpnd/Ar7M+eFUjV/qjW4Pg6LUH5WQoZbTT/3TUS
+9qS1v10wLJNMIniYGZslh71yb937i6BsAKLzVP6VTsZgO4+8eoEpL46l1C/h/sTW
+gdWwG/cB8c3qgcYRTtn9t93TRofnxxr8pSVihe2TAzk6I1EKcf2DzymJAjMEEAEK
+AB0WIQTfYF3xdR5NoZx+auO0Z9GZCjri0AUCXiccgwAKCRC0Z9GZCjri0Mc3D/9X
+/OLjPBrwR2rnv7qGB8jhg304RskvYx/kzcSadp4JQhF8zD6Lzb+F/NRzaN09E9RD
+jsnF595UiOqQ9NUY1Ku0+1HicJHKg7chK11tQWQyjYZKyCc/WxoOye+G7LGjLLl0
+MpJ2uO/fgD5asF6ufXU0XDVPUGUBilM2NiEFuVRK51ZOmP7hrQYjMD+TSz3PfvT5
+xAyggGmDOswQGMYCRj2S/hIbTADkSVwG61OiPHWAKxIPaIK+MBJm04KM7bnZmTly
+4j7ZA9oj2MikMe2z5M99EYIIDauVy5N9R0qzaOcUCFZXDaoZpPfq1fwk5Aj9tG4S
+/FdlMZeYeJNHkk7ZNaZ0vdQf4P7lib6gv9V1XePB4WANoG1KRVSq8eVYQvlxlFhR
+EJjiuahoT59KhX1aC4tEmBo4yC0LwQ+G2Vw2DZMZHDo8IqP/wrAPGblyOlo09vr+
+Hqd7oyDSxiYFekttvLmS3wtD+Fz3X7xZ3NOooqemH1pKd4XYTTX2RNryEx+pIcMh
+Emkmyo9D8P/FgwB7qTj5ANOhEVY4zYWmYKDck8AlDe1VY/yQ8mo2cJWYKo1qdpI3
+mrdHBkDhNANwBfKBUu4zxrapBSrZvIYJd8YJjqvBX/EsqrQHb8Sf71HrZt8UILrQ
+WBhTC0/BETEay2BDgV8tP+9l3/lJyJZzRB8u6x4UtrkBDQReJx0UAQgAk+y5c4DR
+oWSiJvZMQ+w+Hz7hv4s8Q/xxvjVPmp921oYRk+qrMS963Qc9Zstn9RSI8ALZFksD
+gKDPZ+DAgF1FLkv9HqoggcE8iUU+WiYCVkxj4M67nmuOeUf/vIja4fxs/t0vJXkP
+U9/Hn2d5dyRyseZEYbxPdJvQGk6GJ1OO+h6hLos9GNrFB64SQug9j57YY2R5u+fU
+RwE/xg2YDb4xGH8sAyZkKRNFnfQ67cL1TdfcbKs9jrI2U6KFYbdWVbRgeWEQSlLS
+fIzQuUG73iHuo8FD2CKsag5smI9l4iV3W1UHEscc5soeDzLA2lH66sb/yl858bEJ
+KDci3k+wE3RQEwARAQABiQI7BBgBCgAmAhsMFiEEU1thAVgjRDlBx0TdEiZPa736
+uokFAmASBaMFCQPMHA8ACgkQEiZPa736uonUAw/4xh//cHEJ2UBgiei//8vBYR7E
+PB62NUmFXDphoAHB1xRMlFh3ljsU25hzXfTR1SyEvuYN9f7zmmW3ZmH0rV8xn0zb
+BCAORGmFm6auYV5x89Ika/ecoFAew8eeZbKuzT/ZWH9OEmGXoRP0eFAxDpOlEg85
+n+ErkRxnvc3VxUYt1swPhZ9Om/bZ26XzznJ11FztmYht6VXcB9jrpVwMjk5rAAAF
+LuK7Uiw9yQMaW8z7lcKQvAdiQ6j1TmGogIT3XAhVJkBNcMyb5qz+mylupMe69hs3
+L8I3PPMZJhT7ymll09KURChaGR8H3dohS2b/wLNdWoqMAyXqXWHDrZ83Uor/wzGh
+TQ6FHz0z8GMoiUgoU9GEQVu4vy2mjpR4vnHZ0pXP469rYdxQDkrfyuQSvbpYi9br
+ayllJQG8qoHXI92wugslD2CIeI14h8C14ZkOymI4uZCv0kR3mIxV9WVAanJyHVto
+HrYiHVt5TzJMqY0Eu3NPvr9W/B4x0srFOmM9MBivbTo4S3KDZEfRpqC5QCdw79qP
+spm35kqWIEpM+O4gc+zE4EHUbddu/68yXNaqvWRODg8mo8flFTZ5PvpIb/qNkPOG
+GDgPiiIae4ga6KNOS1STroHf63ort4G0zuQPzQg1N9ll4lo62OqDmW+25nzHC7yB
+PhCB2Dz76iQ5nDY4MQ==
+=R7Pm
+-----END PGP PUBLIC KEY BLOCK-----

From cd92ec64c218bf4d3f0d077bd0078d6cb251968b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 23 Apr 2022 04:08:45 +0100
Subject: [PATCH 042/212] Add starbound server

---
 configuration/default.nix                     |   6 +-
 configuration/services/configs/starbound.json |  50 ++++++++
 configuration/services/minecraft.nix          |   3 -
 configuration/services/starbound.nix          | 110 ++++++++++++++++++
 flake.nix                                     |  21 +++-
 pkgs/default.nix                              |   3 +
 pkgs/starbound/default.nix                    |  34 ++++++
 pkgs/starbound/launch-starbound.sh            |  32 +++++
 8 files changed, 253 insertions(+), 6 deletions(-)
 create mode 100644 configuration/services/configs/starbound.json
 create mode 100644 configuration/services/starbound.nix
 create mode 100644 pkgs/starbound/default.nix
 create mode 100644 pkgs/starbound/launch-starbound.sh

diff --git a/configuration/default.nix b/configuration/default.nix
index d6cc5cf..76a1bf7 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -6,6 +6,7 @@
     ./services/minecraft.nix
     ./services/nextcloud.nix
     ./services/webserver.nix
+    ./services/starbound.nix
     ./ids.nix
   ];
 
@@ -20,6 +21,9 @@
     trustedUsers = [ "@wheel" ];
   };
 
+  nixpkgs.config.allowUnfreePredicate = pkg:
+    builtins.elem (lib.getName pkg) ["forge-server" "steam-runtime" "steamcmd"];
+
   sops = {
     defaultSopsFile = ../keys/external.yaml;
     secrets.steam = { };
@@ -34,7 +38,7 @@
     useDHCP = false;
     interfaces.eth0.useDHCP = true;
 
-    firewall.allowedTCPPorts = [ 80 443 2222 2221 25565 ];
+    firewall.allowedTCPPorts = [ 80 443 2222 2221 25565 21025 ];
   };
 
   time.timeZone = "Europe/London";
diff --git a/configuration/services/configs/starbound.json b/configuration/services/configs/starbound.json
new file mode 100644
index 0000000..d995fdf
--- /dev/null
+++ b/configuration/services/configs/starbound.json
@@ -0,0 +1,50 @@
+{
+  "allowAdminCommands" : true,
+  "allowAdminCommandsFromAnyone" : false,
+  "allowAnonymousConnections" : true,
+  "allowAssetsMismatch" : true,
+  "anonymousConnectionsAreAdmin" : false,
+  "bannedIPs" : [],
+  "bannedUuids" : [],
+  "checkAssetsDigest" : false,
+  "clearPlayerFiles" : false,
+  "clearUniverseFiles" : false,
+  "clientIPJoinable" : false,
+  "clientP2PJoinable" : true,
+  "configurationVersion" : {
+    "basic" : 2,
+    "server" : 4
+  },
+  "crafting" : {
+    "filterHaveMaterials" : false
+  },
+  "gameServerBind" : "::",
+  "gameServerPort" : 21025,
+  "interactiveHighlight" : true,
+  "inventory" : {
+    "pickupToActionBar" : true
+  },
+  "maxPlayers" : 8,
+  "maxTeamSize" : 4,
+  "monochromeLighting" : false,
+  "playerBackupFileCount" : 3,
+  "queryServerBind" : "::",
+  "queryServerPort" : 21025,
+  "rconServerBind" : "::",
+  "rconServerPassword" : "",
+  "rconServerPort" : 21026,
+  "rconServerTimeout" : 1000,
+  "runQueryServer" : false,
+  "runRconServer" : false,
+  "safeScripts" : true,
+  "scriptInstructionLimit" : 10000000,
+  "scriptInstructionMeasureInterval" : 10000,
+  "scriptProfilingEnabled" : false,
+  "scriptRecursionLimit" : 100,
+  "serverFidelity" : "automatic",
+  "serverName" : "tlater.net",
+  "serverOverrideAssetsDigest" : null,
+  "serverUsers" : {
+  },
+  "tutorialMessages" : true
+}
diff --git a/configuration/services/minecraft.nix b/configuration/services/minecraft.nix
index 23705ac..80b4ff5 100644
--- a/configuration/services/minecraft.nix
+++ b/configuration/services/minecraft.nix
@@ -51,9 +51,6 @@ let
   eula = pkgs.writeText "eula.txt" "eula=true";
 
 in {
-  nixpkgs.config.allowUnfreePredicate = pkg:
-    builtins.elem (lib.getName pkg) [ "forge-server" ];
-
   users = {
     extraUsers.minecraft = {
       uid = config.ids.uids.minecraft;
diff --git a/configuration/services/starbound.nix b/configuration/services/starbound.nix
new file mode 100644
index 0000000..e23028f
--- /dev/null
+++ b/configuration/services/starbound.nix
@@ -0,0 +1,110 @@
+{
+  pkgs,
+  lib,
+  ...
+}: let
+  inherit (lib) concatStringsSep;
+in {
+  systemd.services.starbound = {
+    description = "Starbound";
+    after = ["network.target"];
+
+    serviceConfig = {
+      ExecStart = "${pkgs.local.starbound}/bin/launch-starbound ${./configs/starbound.json}";
+
+      Type = "simple";
+
+      # Credential loading for steam auth (if necessary; prefer
+      # anonymous login wherever possible).
+      LoadCredential = "steam:/run/secrets/steam";
+
+      # Security settings
+      DynamicUser = true;
+
+      # This is where the StateDirectory ends up
+      WorkingDirectory = "/var/lib/starbound";
+      # Creates /var/lib/starbound (or rather, a symlink there to
+      # /var/lib/private/starbound), and sets it up to be writeable to
+      # by the dynamic user.
+      StateDirectory = "starbound";
+
+      # Note some settings below are basically tautologous with
+      # `NoNewPrivileges`, but they all work slightly differently so
+      # add additional layers in case of bugs.
+
+      ## THESE SETTINGS ARE A GOOD IDEA BUT THE STEAM CLIENT IS
+      ## REALLY, REALLY BAD, AND FOR SOME REASON I NEED TO USE IT TO
+      ## DOWNLOAD GAME SERVERS AS WELL:
+      ##
+      # To guarantee the above (only permits 64-bit syscalls, 32-bit
+      # syscalls can circumvent the above restrictions).
+      #
+      # Obviously, if running a 32 bit game server, change this.
+      # SystemCallArchitectures = "native";
+      # Game servers shouldn't need to create new namespaces ever.
+      #
+      # TODO: Since steam uses namespaces for things *entirely
+      # unrelated* to installing game servers, we need to allow
+      # namespace access. Ideally I'd instead do this in an
+      # ExecStartPre, but alas, this isn't possible because of
+      # https://github.com/systemd/systemd/issues/19604.
+      #
+      # RestrictNamespaces = true;
+
+      # Don't need to let the game server see other user accounts
+      PrivateUsers = true;
+      # *Probably* not harmful for game servers, which probably don't update dynamically
+      ProtectHostname = true;
+      # Yeah, if a game server tries to edit the hardware clock something's fishy
+      ProtectClock = true;
+      # Don't let game servers modify kernel settings, duh
+      ProtectKernelTunables = true;
+      ProtectKernelModules = true;
+      ProtectKernelLogs = true;
+      # Game servers shouldn't use cgroups themselves either
+      ProtectControlGroups = true;
+      # Most game servers will never need other socket types
+      RestrictAddressFamilies = ["AF_UNIX AF_INET AF_INET6"];
+      # Also a no-brainer, no game server should ever need this
+      LockPersonality = true;
+      # Some game servers will probably try to set this, but they
+      # don't need it. It's only required for audio processing and
+      # such, which the server end doesn't need to do.
+      RestrictRealtime = true;
+      # Don't allow a variety of syscalls that gameservers have no
+      # business using anyway
+      SystemCallFilter =
+        "~"
+        + (concatStringsSep " " [
+          "@clock"
+          "@cpu-emulation"
+          "@debug"
+          "@keyring"
+          "@memlock"
+          "@module"
+          # "@mount"  TODO: Consider adding when steamcmd is run in ExecStartPre
+          "@obsolete"
+          "@raw-io"
+          "@reboot"
+          "@resources"
+          "@setuid"
+          "@swap"
+        ]);
+      # Normally only "read-only", but steamcmd will puke if there is
+      # no home directory to write to (though the nix package will
+      # implicitly symlink to the path that we set in its override, so
+      # no actual files are created, besides a symlink).
+      ProtectHome = "tmpfs";
+
+      # Implied by DynamicUser anyway, but it doesn't hurt to add
+      # these explicitly, at least for reference.
+      RemoveIPC = true;
+      PrivateTmp = true;
+      PrivateDevices = true;
+      NoNewPrivileges = true;
+      RestrictSUIDSGID = true;
+      ProtectSystem = "strict";
+      # ProtectHome = "read-only"; # See further up
+    };
+  };
+}
diff --git a/flake.nix b/flake.nix
index d8928df..772580b 100644
--- a/flake.nix
+++ b/flake.nix
@@ -130,9 +130,26 @@
                     ])
                 ]))
             ];
-            shellHook = ''
+            shellHook = let
+              inherit (pkgs.lib.attrsets) mapAttrsToList;
+              inherit (pkgs.lib.strings) concatStringsSep;
+              ports = {
+                "3022" = "2222";
+                "3080" = "80";
+                "3443" = "443";
+                "3021" = "2221";
+                "25565" = "25565";
+                "21025" = "21025"; # Starbound
+              };
+              QEMU_NET_OPTS =
+                concatStringsSep ","
+                  (mapAttrsToList
+                    (host: vm: "hostfwd=::${host}-:${vm}")
+                    ports);
+            in
+              ''
               export QEMU_OPTS="-m 3941 -smp 2 -curses"
-              export QEMU_NET_OPTS="hostfwd=::3022-:2222,hostfwd=::3080-:80,hostfwd=::3443-:443,hostfwd=::3021-:2221,hostfwd=::25565-:25565"
+              export QEMU_NET_OPTS="${QEMU_NET_OPTS}"
 
               # Work around sudo requiring a full terminal
               export NIX_SSHOPTS="-t"
diff --git a/pkgs/default.nix b/pkgs/default.nix
index 88a0112..dd334bc 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -13,4 +13,7 @@ in {
   # Minecraft modpacks
   voor-kia = callPackage ./minecraft/voor-kia.nix { };
   voor-kia-client = callPackage ./minecraft/voor-kia-client.nix { };
+
+  # Starbound
+  starbound = callPackage ./starbound { };
 }
diff --git a/pkgs/starbound/default.nix b/pkgs/starbound/default.nix
new file mode 100644
index 0000000..304f0f3
--- /dev/null
+++ b/pkgs/starbound/default.nix
@@ -0,0 +1,34 @@
+{
+  stdenv,
+  lib,
+  makeWrapper,
+  patchelf,
+  steamPackages,
+  replace-secret,
+}: let
+  # Use the directory in which starbound is installed so steamcmd
+  # doesn't have to be reinstalled constantly (we're using DynamicUser
+  # with StateDirectory to persist this).
+  steamcmd = steamPackages.steamcmd.override {
+    steamRoot = "/var/lib/starbound/.steamcmd";
+  };
+  wrapperPath = lib.makeBinPath [patchelf steamcmd replace-secret];
+in
+  stdenv.mkDerivation {
+    name = "starbound-update-script";
+    nativeBuildInputs = [makeWrapper];
+    dontUnpack = true;
+    patchPhase = ''
+      interpreter="$(cat $NIX_CC/nix-support/dynamic-linker)"
+      substitute ${./launch-starbound.sh} launch-starbound --subst-var interpreter
+    '';
+    installPhase = ''
+      mkdir -p $out/bin
+      cp launch-starbound $out/bin/launch-starbound
+      chmod +x $out/bin/launch-starbound
+    '';
+    postFixup = ''
+      wrapProgram $out/bin/launch-starbound \
+          --prefix PATH : "${wrapperPath}"
+    '';
+  }
diff --git a/pkgs/starbound/launch-starbound.sh b/pkgs/starbound/launch-starbound.sh
new file mode 100644
index 0000000..24d4db1
--- /dev/null
+++ b/pkgs/starbound/launch-starbound.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+
+set -eu
+
+if ! [[ -v STATE_DIRECTORY  &&  -v CREDENTIALS_DIRECTORY ]]; then
+    echo "Error: Runtime dir or credential not set"
+    exit 1
+fi
+
+# Update the server to the latest version
+echo "Updating/installing starbound"
+
+mkdir -p "${STATE_DIRECTORY}/.steamcmd"
+steamcmd <<EOF
+force_install_dir $STATE_DIRECTORY
+login tlater $(cat "$CREDENTIALS_DIRECTORY/steam")
+app_update 211820
+quit
+EOF
+
+echo "Updating config"
+if [ -f "$1" ]; then
+    mkdir -p ./storage
+    cp "$1" ./storage/starbound_server.config
+fi
+
+echo "Running starbound server"
+patchelf --set-interpreter '@interpreter@' ./linux/starbound_server
+# Must be run from the directory that the binary is in (why do game
+# devs do this?)
+cd linux
+./starbound_server

From ed74cfa576bdde964c23da5c999148cb2e0e95b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 23 Apr 2022 09:31:21 +0100
Subject: [PATCH 043/212] starbound: Fix permissions for a syscall steamcmd
 needs

---
 configuration/services/starbound.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configuration/services/starbound.nix b/configuration/services/starbound.nix
index e23028f..e8a0772 100644
--- a/configuration/services/starbound.nix
+++ b/configuration/services/starbound.nix
@@ -86,7 +86,7 @@ in {
           "@obsolete"
           "@raw-io"
           "@reboot"
-          "@resources"
+          # "@resources" TODO: Ditto
           "@setuid"
           "@swap"
         ]);

From 58e52dd119087ebad1964ff96b118a4fff07202e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 10 Oct 2022 13:01:26 +0100
Subject: [PATCH 044/212] ssh: Allow proxy connections with gatewayPorts

---
 configuration/default.nix | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configuration/default.nix b/configuration/default.nix
index 76a1bf7..6a2a79d 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -56,6 +56,7 @@
     permitRootLogin = "no";
     ports = [ 2222 ];
     startWhenNeeded = true;
+    gatewayPorts = "yes";
   };
 
   services.nginx = {

From 046a88905ddfa7f9edc3291c310dbb985dee34f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 10 Oct 2022 13:03:08 +0100
Subject: [PATCH 045/212] treewide: Reformat project with alejandra

---
 configuration/default.nix                  |  30 ++-
 configuration/ids.nix                      |   4 +-
 configuration/linode.nix                   |   9 +-
 configuration/services/gitea.nix           |  14 +-
 configuration/services/minecraft.nix       |  45 ++--
 configuration/services/nextcloud.nix       |  18 +-
 configuration/services/webserver.nix       |  18 +-
 flake.nix                                  | 277 +++++++++++----------
 lib/default.nix                            |  18 +-
 lib/minecraft.nix                          |  20 +-
 modules/default.nix                        |   9 +-
 modules/virtualisation/pods.nix            |  80 +++---
 pkgs/build-support/fetchFromCurseForge.nix |  53 ++--
 pkgs/default.nix                           |  20 +-
 pkgs/minecraft/forge-server.nix            | 126 +++++-----
 pkgs/minecraft/voor-kia-client.nix         |  10 +-
 pkgs/minecraft/voor-kia.nix                |   7 +-
 17 files changed, 405 insertions(+), 353 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index 6a2a79d..8e9744d 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -1,6 +1,9 @@
-{ config, pkgs, lib, ... }:
-
 {
+  config,
+  pkgs,
+  lib,
+  ...
+}: {
   imports = [
     ./services/gitea.nix
     ./services/minecraft.nix
@@ -18,7 +21,7 @@
     '';
 
     # Enable remote builds from tlater
-    trustedUsers = [ "@wheel" ];
+    trustedUsers = ["@wheel"];
   };
 
   nixpkgs.config.allowUnfreePredicate = pkg:
@@ -26,10 +29,10 @@
 
   sops = {
     defaultSopsFile = ../keys/external.yaml;
-    secrets.steam = { };
+    secrets.steam = {};
   };
 
-  boot.kernelParams = [ "highres=off" "nohz=off" ];
+  boot.kernelParams = ["highres=off" "nohz=off"];
 
   networking = {
     hostName = "tlaternet";
@@ -38,15 +41,15 @@
     useDHCP = false;
     interfaces.eth0.useDHCP = true;
 
-    firewall.allowedTCPPorts = [ 80 443 2222 2221 25565 21025 ];
+    firewall.allowedTCPPorts = [80 443 2222 2221 25565 21025];
   };
 
   time.timeZone = "Europe/London";
 
   users.users.tlater = {
     isNormalUser = true;
-    extraGroups = [ "wheel" ];
-    openssh.authorizedKeys.keyFiles = [ ../keys/tlater.pub ];
+    extraGroups = ["wheel"];
+    openssh.authorizedKeys.keyFiles = [../keys/tlater.pub];
   };
 
   services.openssh = {
@@ -54,7 +57,7 @@
     allowSFTP = false;
     passwordAuthentication = false;
     permitRootLogin = "no";
-    ports = [ 2222 ];
+    ports = [2222];
     startWhenNeeded = true;
     gatewayPorts = "yes";
   };
@@ -77,12 +80,13 @@
           extraConfig = ''
             add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
           '';
-        } extra;
+        }
+        extra;
       domain = config.services.nginx.domain;
     in {
-      "${domain}" = host 3002 { serverAliases = [ "www.${domain}" ]; };
-      "gitea.${domain}" = host 3000 { };
-      "nextcloud.${domain}" = host 3001 { };
+      "${domain}" = host 3002 {serverAliases = ["www.${domain}"];};
+      "gitea.${domain}" = host 3000 {};
+      "nextcloud.${domain}" = host 3001 {};
     };
   };
 
diff --git a/configuration/ids.nix b/configuration/ids.nix
index 5488ff0..9b99011 100644
--- a/configuration/ids.nix
+++ b/configuration/ids.nix
@@ -1,6 +1,4 @@
-{ ... }:
-
-{
+{...}: {
   ids.uids = {
     # System user ids start at 400 (see nixos/modules/programs/shadow.nix)
     webserver = 400;
diff --git a/configuration/linode.nix b/configuration/linode.nix
index da82d20..4224cfe 100644
--- a/configuration/linode.nix
+++ b/configuration/linode.nix
@@ -1,8 +1,11 @@
-{ config, lib, pkgs, ... }:
-
 {
+  config,
+  lib,
+  pkgs,
+  ...
+}: {
   # Required for the lish console
-  boot.kernelParams = [ "console=ttyS0,19200n8" ];
+  boot.kernelParams = ["console=ttyS0,19200n8"];
 
   boot.loader = {
     # Timeout to allow lish to connect
diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index 7f49d32..5f9ebd0 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -1,6 +1,4 @@
-{ config, ... }:
-
-{
+{config, ...}: {
   users = {
     extraUsers.gitea = {
       uid = config.ids.uids.git;
@@ -8,19 +6,19 @@
       description = "Gitea Service";
       group = config.users.extraGroups.gitea.name;
     };
-    extraGroups.gitea = { gid = config.ids.gids.git; };
+    extraGroups.gitea = {gid = config.ids.gids.git;};
   };
 
   virtualisation.pods.gitea = {
     hostname = "gitea.tlater.net";
-    publish = [ "3000:3000" "2221:2221" ];
+    publish = ["3000:3000" "2221:2221"];
     network = "slirp4netns";
 
     containers = {
       gitea = {
         image = "gitea/gitea:latest";
-        volumes = [ "gitea:/data:Z" "/etc/localtime:/etc/localtime:ro" ];
-        dependsOn = [ "postgres" ];
+        volumes = ["gitea:/data:Z" "/etc/localtime:/etc/localtime:ro"];
+        dependsOn = ["postgres"];
 
         environment = {
           DB_TYPE = "postgres";
@@ -43,7 +41,7 @@
           POSTGRES_DB = "gitea";
           POSTGRES_USER = "gitea";
         };
-        volumes = [ "gitea-postgres-14:/var/lib/postgresql/data" ];
+        volumes = ["gitea-postgres-14:/var/lib/postgresql/data"];
       };
     };
   };
diff --git a/configuration/services/minecraft.nix b/configuration/services/minecraft.nix
index 80b4ff5..c19335c 100644
--- a/configuration/services/minecraft.nix
+++ b/configuration/services/minecraft.nix
@@ -1,6 +1,9 @@
-{ config, pkgs, lib, ... }:
-
-let
+{
+  config,
+  pkgs,
+  lib,
+  ...
+}: let
   minecraft-server-args = [
     "-Xms2G"
     "-Xmx2G"
@@ -24,12 +27,14 @@ let
     "-XX:+PerfDisableSharedMem"
     "-XX:MaxTenuringThreshold=1"
   ];
-  ops = pkgs.writeText "ops.json" (builtins.toJSON [{
-    uuid = "140d177a-966f-41b8-a4c0-e305babd291b";
-    name = "TLATER";
-    level = 4;
-    bypassesPlayerLimit = true;
-  }]);
+  ops = pkgs.writeText "ops.json" (builtins.toJSON [
+    {
+      uuid = "140d177a-966f-41b8-a4c0-e305babd291b";
+      name = "TLATER";
+      level = 4;
+      bypassesPlayerLimit = true;
+    }
+  ]);
   whitelist = pkgs.writeText "whitelist.json" (builtins.toJSON [
     {
       uuid = "59cd1648-14a4-4bcf-8f5a-2e1bde678f2c";
@@ -49,7 +54,6 @@ let
     }
   ]);
   eula = pkgs.writeText "eula.txt" "eula=true";
-
 in {
   users = {
     extraUsers.minecraft = {
@@ -58,7 +62,7 @@ in {
       isSystemUser = true;
       description = "Minecraft server user";
     };
-    extraGroups.minecraft = { gid = config.ids.gids.minecraft; };
+    extraGroups.minecraft = {gid = config.ids.gids.minecraft;};
   };
 
   virtualisation.oci-containers.containers.minecraft-voor-kia = let
@@ -83,22 +87,22 @@ in {
         uid = toString config.users.extraUsers.minecraft.uid;
         gid = toString config.users.extraGroups.minecraft.gid;
       in {
-        Cmd = [ "forge-server" ] ++ minecraft-server-args;
+        Cmd = ["forge-server"] ++ minecraft-server-args;
         WorkingDir = "/var/lib/minecraft";
         Volumes = {
-          "/var/lib/minecraft" = { };
+          "/var/lib/minecraft" = {};
           # Required because some things will try to write to /tmp,
           # which doesn't exist if it's not defined as a volume.
-          "/tmp" = { };
+          "/tmp" = {};
         };
-        ExposedPorts = { "25565" = { }; };
+        ExposedPorts = {"25565" = {};};
         User = "${uid}:${gid}";
       };
     };
 
-    extraOptions = [ "--cpus=1.0" ];
+    extraOptions = ["--cpus=1.0"];
     autoStart = false;
-    ports = [ "25565:25565" ];
+    ports = ["25565:25565"];
     volumes = [
       "minecraft:/var/lib/minecraft"
       "${eula}:/var/lib/minecraft/eula.txt:ro"
@@ -111,7 +115,7 @@ in {
 
   systemd.timers.podman-minecraft-voor-kia-off = {
     description = "Turns off the minecraft server every day at 4 am";
-    wantedBy = [ "podman-minecraft-voor-kia.service" ];
+    wantedBy = ["podman-minecraft-voor-kia.service"];
     timerConfig = {
       Unit = "podman-minecraft-voor-kia-starter@stop.service";
       OnCalendar = "04:00:00";
@@ -120,7 +124,7 @@ in {
 
   systemd.timers.podman-minecraft-voor-kia-on = {
     description = "Turns on the minecraft server every day at 2 pm";
-    wantedBy = [ "podman-minecraft-voor-kia.service" ];
+    wantedBy = ["podman-minecraft-voor-kia.service"];
     timerConfig = {
       Unit = "podman-minecraft-voor-kia-starter@start.service";
       OnCalendar = "14:00:00";
@@ -130,8 +134,7 @@ in {
   systemd.services."podman-minecraft-voor-kia-starter@" = {
     description = "Unit to stop/start the minecraft server";
     serviceConfig = {
-      ExecStart =
-        "${pkgs.systemd}/bin/systemctl %i podman-minecraft-voor-kia.service";
+      ExecStart = "${pkgs.systemd}/bin/systemctl %i podman-minecraft-voor-kia.service";
       Type = "oneshot";
     };
   };
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index f63b294..5b32cf2 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -1,15 +1,13 @@
-{ config, ... }:
-
-{
+{config, ...}: {
   virtualisation.pods.nextcloud = {
     hostname = "nextcloud.tlater.net";
-    publish = [ "3001:80" ];
+    publish = ["3001:80"];
     network = "slirp4netns";
 
     containers = {
       nextcloud = {
         image = "nextcloud:fpm-alpine";
-        dependsOn = [ "postgres" ];
+        dependsOn = ["postgres"];
         volumes = [
           "nextcloud-root:/var/www/html"
           "nextcloud-apps:/var/www/html/custom_apps"
@@ -28,18 +26,18 @@
       cron = {
         image = "nextcloud:fpm-alpine";
         entrypoint = "/cron.sh";
-        dependsOn = [ "postgres" "nextcloud" ];
-        extraOptions = [ "--volumes-from=nextcloud-nextcloud" ];
+        dependsOn = ["postgres" "nextcloud"];
+        extraOptions = ["--volumes-from=nextcloud-nextcloud"];
       };
 
       nginx = {
         image = "nginx:alpine";
-        dependsOn = [ "nextcloud" ];
+        dependsOn = ["nextcloud"];
         volumes = [
           "nextcloud-root:/var/www/html:ro"
           "${./configs/nginx-nextcloud.conf}:/etc/nginx/nginx.conf:ro"
         ];
-        extraOptions = [ "--volumes-from=nextcloud-nextcloud" ];
+        extraOptions = ["--volumes-from=nextcloud-nextcloud"];
       };
 
       postgres = {
@@ -48,7 +46,7 @@
           POSTGRES_DB = "nextcloud";
           POSTGRES_USER = "nextcloud";
         };
-        volumes = [ "nextcloud-postgres-14:/var/lib/postgresql/data" ];
+        volumes = ["nextcloud-postgres-14:/var/lib/postgresql/data"];
       };
     };
   };
diff --git a/configuration/services/webserver.nix b/configuration/services/webserver.nix
index d72b417..093da3d 100644
--- a/configuration/services/webserver.nix
+++ b/configuration/services/webserver.nix
@@ -1,6 +1,8 @@
-{ config, pkgs, ... }:
-
 {
+  config,
+  pkgs,
+  ...
+}: {
   users = {
     extraUsers.webserver = {
       uid = config.ids.uids.webserver;
@@ -8,7 +10,7 @@
       isSystemUser = true;
       description = "tlater.net web server user";
     };
-    extraGroups.webserver = { gid = config.ids.gids.webserver; };
+    extraGroups.webserver = {gid = config.ids.gids.webserver;};
   };
 
   virtualisation.oci-containers.containers.webserver = {
@@ -23,19 +25,19 @@
         uid = toString config.users.extraUsers.webserver.uid;
         gid = toString config.users.extraGroups.webserver.gid;
       in {
-        Cmd = [ "tlaternet-webserver" ];
-        Volumes = { "/srv/mail" = { }; };
+        Cmd = ["tlaternet-webserver"];
+        Volumes = {"/srv/mail" = {};};
         Env = [
           "ROCKET_PORT=3002"
           "ROCKET_TEMPLATE_DIR=${pkgs.tlaternet-templates.templates}/browser/"
         ];
-        ExposedPorts = { "3002" = { }; };
+        ExposedPorts = {"3002" = {};};
         User = "${uid}:${gid}";
       };
     };
 
-    ports = [ "3002:3002" ];
-    volumes = [ "tlaternet-mail:/srv/mail" ];
+    ports = ["3002:3002"];
+    volumes = ["tlaternet-mail:/srv/mail"];
     extraOptions = [
       "--hostname=tlater.net"
       # Rocket 0.4 doesn't support SIGTERM anyway, so SIGKILL is the cleanest exit possible.
diff --git a/flake.nix b/flake.nix
index 772580b..3f0ad1b 100644
--- a/flake.nix
+++ b/flake.nix
@@ -26,144 +26,155 @@
     };
   };
 
-  outputs = { self, nixpkgs, nixos-hardware, flake-utils, sops-nix
-    , tlaternet-webserver, tlaternet-templates, ... }@inputs:
-    let
-      overlays = [
-        (final: prev: {
-          tlaternet-webserver =
-            tlaternet-webserver.legacyPackages.${prev.system}.packages;
-          tlaternet-templates =
-            tlaternet-templates.legacyPackages.${prev.system}.packages;
-          local = import ./pkgs {
-            pkgs = prev;
-            local-lib = self.lib.${prev.system};
-          };
-        })
-      ];
-
-    in {
+  outputs = {
+    self,
+    nixpkgs,
+    nixos-hardware,
+    flake-utils,
+    sops-nix,
+    tlaternet-webserver,
+    tlaternet-templates,
+    ...
+  } @ inputs: let
+    overlays = [
+      (final: prev: {
+        tlaternet-webserver =
+          tlaternet-webserver.legacyPackages.${prev.system}.packages;
+        tlaternet-templates =
+          tlaternet-templates.legacyPackages.${prev.system}.packages;
+        local = import ./pkgs {
+          pkgs = prev;
+          local-lib = self.lib.${prev.system};
+        };
+      })
+    ];
+  in
+    {
       nixosConfigurations = {
-        tlaternet = let system = "x86_64-linux";
-        in nixpkgs.lib.nixosSystem {
-          inherit system;
+        tlaternet = let
+          system = "x86_64-linux";
+        in
+          nixpkgs.lib.nixosSystem {
+            inherit system;
 
-          modules = [
-            ({ modulesPath, ... }: {
-              imports = [ (modulesPath + "/profiles/headless.nix") ];
-              nixpkgs.overlays = overlays;
-            })
-            (import ./modules)
+            modules = [
+              ({modulesPath, ...}: {
+                imports = [(modulesPath + "/profiles/headless.nix")];
+                nixpkgs.overlays = overlays;
+              })
+              (import ./modules)
 
-            (import ./configuration)
-            (import ./configuration/linode.nix)
-            (import ./configuration/hardware-configuration.nix)
-            sops-nix.nixosModules.sops
-          ];
-        };
-
-        vm = let system = "x86_64-linux";
-        in nixpkgs.lib.nixosSystem {
-          inherit system;
-
-          modules = [
-            ({ modulesPath, ... }: {
-              imports = [ (modulesPath + "/profiles/headless.nix") ];
-              nixpkgs.overlays = overlays;
-            })
-            (import ./modules)
-
-            (import ./configuration)
-            sops-nix.nixosModules.sops
-            ({ lib, ... }: {
-              users.users.tlater.password = "insecure";
-
-              # Disable graphical tty so -curses works
-              boot.kernelParams = [ "nomodeset" ];
-
-              # Sets the base domain for nginx to localhost so that we
-              # can easily test locally with the VM.
-              services.nginx.domain = lib.mkOverride 99 "localhost";
-
-              # # Set up VM settings to match real VPS
-              # virtualisation.memorySize = 3941;
-              # virtualisation.cores = 2;
-            })
-          ];
-        };
-      };
-    } // flake-utils.lib.eachDefaultSystem (system:
-      let
-        pkgs = import nixpkgs { inherit system overlays; };
-        sops-pkgs = sops-nix.packages.${system};
-      in {
-        devShell =
-          pkgs.mkShell {
-            sopsPGPKeyDirs = ["./keys/hosts/" "./keys/users/"];
-            nativeBuildInputs = with sops-pkgs; [
-              sops-import-keys-hook
+              (import ./configuration)
+              (import ./configuration/linode.nix)
+              (import ./configuration/hardware-configuration.nix)
+              sops-nix.nixosModules.sops
             ];
-            buildInputs = with pkgs; with sops-pkgs; [
-              nixfmt
-              git-lfs
-              sops-init-gpg-key
-
-              # For the minecraft mod update script
-              (python3.withPackages (pypkgs:
-                with pypkgs; [
-                  dateutil
-                  requests
-
-                  ipython
-
-                  python3.withPackages (ppkgs:
-                    with pkgs; [
-                      python-lsp-server
-                      python-lsp-black
-                      pyls-isort
-                      pyls-mypy
-                      rope
-                      pyflakes
-                      mccabe
-                      pycodestyle
-                      pydocstyle
-                    ])
-                ]))
-            ];
-            shellHook = let
-              inherit (pkgs.lib.attrsets) mapAttrsToList;
-              inherit (pkgs.lib.strings) concatStringsSep;
-              ports = {
-                "3022" = "2222";
-                "3080" = "80";
-                "3443" = "443";
-                "3021" = "2221";
-                "25565" = "25565";
-                "21025" = "21025"; # Starbound
-              };
-              QEMU_NET_OPTS =
-                concatStringsSep ","
-                  (mapAttrsToList
-                    (host: vm: "hostfwd=::${host}-:${vm}")
-                    ports);
-            in
-              ''
-              export QEMU_OPTS="-m 3941 -smp 2 -curses"
-              export QEMU_NET_OPTS="${QEMU_NET_OPTS}"
-
-              # Work around sudo requiring a full terminal
-              export NIX_SSHOPTS="-t"
-            '';
           };
 
-        packages = import ./pkgs {
-          inherit pkgs;
-          local-lib = self.lib.${system};
-        };
+        vm = let
+          system = "x86_64-linux";
+        in
+          nixpkgs.lib.nixosSystem {
+            inherit system;
 
-        lib = import ./lib {
-          inherit pkgs inputs;
-          lib = nixpkgs.lib;
-        };
-      });
+            modules = [
+              ({modulesPath, ...}: {
+                imports = [(modulesPath + "/profiles/headless.nix")];
+                nixpkgs.overlays = overlays;
+              })
+              (import ./modules)
+
+              (import ./configuration)
+              sops-nix.nixosModules.sops
+              ({lib, ...}: {
+                users.users.tlater.password = "insecure";
+
+                # Disable graphical tty so -curses works
+                boot.kernelParams = ["nomodeset"];
+
+                # Sets the base domain for nginx to localhost so that we
+                # can easily test locally with the VM.
+                services.nginx.domain = lib.mkOverride 99 "localhost";
+
+                # # Set up VM settings to match real VPS
+                # virtualisation.memorySize = 3941;
+                # virtualisation.cores = 2;
+              })
+            ];
+          };
+      };
+    }
+    // flake-utils.lib.eachDefaultSystem (system: let
+      pkgs = import nixpkgs {inherit system overlays;};
+      sops-pkgs = sops-nix.packages.${system};
+    in {
+      devShell = pkgs.mkShell {
+        sopsPGPKeyDirs = ["./keys/hosts/" "./keys/users/"];
+        nativeBuildInputs = with sops-pkgs; [
+          sops-import-keys-hook
+        ];
+        buildInputs = with pkgs;
+        with sops-pkgs; [
+          nixfmt
+          git-lfs
+          sops-init-gpg-key
+
+          # For the minecraft mod update script
+          (python3.withPackages (pypkgs:
+            with pypkgs; [
+              dateutil
+              requests
+
+              ipython
+
+              python3.withPackages
+              (ppkgs:
+                with pkgs; [
+                  python-lsp-server
+                  python-lsp-black
+                  pyls-isort
+                  pyls-mypy
+                  rope
+                  pyflakes
+                  mccabe
+                  pycodestyle
+                  pydocstyle
+                ])
+            ]))
+        ];
+        shellHook = let
+          inherit (pkgs.lib.attrsets) mapAttrsToList;
+          inherit (pkgs.lib.strings) concatStringsSep;
+          ports = {
+            "3022" = "2222";
+            "3080" = "80";
+            "3443" = "443";
+            "3021" = "2221";
+            "25565" = "25565";
+            "21025" = "21025"; # Starbound
+          };
+          QEMU_NET_OPTS =
+            concatStringsSep ","
+            (mapAttrsToList
+              (host: vm: "hostfwd=::${host}-:${vm}")
+              ports);
+        in ''
+          export QEMU_OPTS="-m 3941 -smp 2 -curses"
+          export QEMU_NET_OPTS="${QEMU_NET_OPTS}"
+
+          # Work around sudo requiring a full terminal
+          export NIX_SSHOPTS="-t"
+        '';
+      };
+
+      packages = import ./pkgs {
+        inherit pkgs;
+        local-lib = self.lib.${system};
+      };
+
+      lib = import ./lib {
+        inherit pkgs inputs;
+        lib = nixpkgs.lib;
+      };
+    });
 }
diff --git a/lib/default.nix b/lib/default.nix
index 3d657e4..2a5d54f 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -1,8 +1,12 @@
-{ inputs, lib, pkgs, ... }:
-
-let
+{
+  inputs,
+  lib,
+  pkgs,
+  ...
+}: let
   inherit (lib) makeExtensible foldr attrValues;
-  tlater-lib = makeExtensible (self:
-    let callLibs = file: import file { inherit self lib pkgs inputs; };
-    in { minecraft = callLibs ./minecraft.nix; });
-in tlater-lib.extend (self: super: foldr (a: b: a // b) { } (attrValues super))
+  tlater-lib = makeExtensible (self: let
+    callLibs = file: import file {inherit self lib pkgs inputs;};
+  in {minecraft = callLibs ./minecraft.nix;});
+in
+  tlater-lib.extend (self: super: foldr (a: b: a // b) {} (attrValues super))
diff --git a/lib/minecraft.nix b/lib/minecraft.nix
index ef50b3d..e3f8c4e 100644
--- a/lib/minecraft.nix
+++ b/lib/minecraft.nix
@@ -1,6 +1,8 @@
-{ lib, pkgs, ... }:
-
 {
+  lib,
+  pkgs,
+  ...
+}: {
   # Make a modpack given its mod inputs.
   #
   # Mods should be attrsets in this format:
@@ -13,7 +15,11 @@
   #
   # This may be nice to read from a json ;)
   #
-  mkModpack = { name, version, mods }:
+  mkModpack = {
+    name,
+    version,
+    mods,
+  }:
     pkgs.stdenv.mkDerivation {
       inherit name version;
       srcs = map pkgs.local.fetchFromCurseForge mods;
@@ -28,7 +34,11 @@
       '';
     };
 
-  mkModpackZip = { name, version, mods }:
+  mkModpackZip = {
+    name,
+    version,
+    mods,
+  }:
     pkgs.stdenv.mkDerivation {
       inherit name version;
       srcs = map pkgs.local.fetchFromCurseForge mods;
@@ -37,7 +47,7 @@
       preUnpack = "mkdir -p src/";
       unpackCmd = "cp $curSrc src/";
 
-      buildInputs = [ pkgs.zip];
+      buildInputs = [pkgs.zip];
 
       buildPhase = ''
         zip voor-kia-mods.zip *.jar
diff --git a/modules/default.nix b/modules/default.nix
index 1fd86fc..46f5e10 100644
--- a/modules/default.nix
+++ b/modules/default.nix
@@ -1,9 +1,6 @@
-{ lib, ... }:
-
-with lib;
-
-{
-  imports = [ ./virtualisation/pods.nix ];
+{lib, ...}:
+with lib; {
+  imports = [./virtualisation/pods.nix];
 
   options.services.nginx.domain = mkOption {
     type = types.str;
diff --git a/modules/virtualisation/pods.nix b/modules/virtualisation/pods.nix
index a5c9daa..5a96cc8 100644
--- a/modules/virtualisation/pods.nix
+++ b/modules/virtualisation/pods.nix
@@ -1,20 +1,21 @@
-{ lib, config, options, ... }:
-
-with lib;
-
-let
+{
+  lib,
+  config,
+  options,
+  ...
+}:
+with lib; let
   cfg = config.virtualisation.pods;
   list-to-args = arg: list:
     concatStringsSep " " (map (e: "--${arg}=${escapeShellArg e}") list);
-  possibly-unset-arg = arg: val:
-    (optionalString (val != null) "--${arg}=${escapeShellArg val}");
+  possibly-unset-arg = arg: val: (optionalString (val != null) "--${arg}=${escapeShellArg val}");
 
   mkPod = name: pod: rec {
-    path = [ config.virtualisation.podman.package ];
+    path = [config.virtualisation.podman.package];
 
-    wants = [ "network.target" ];
-    after = [ "network-online.target" ];
-    wantedBy = [ "multi-user.target" "default.target" ];
+    wants = ["network.target"];
+    after = ["network-online.target"];
+    wantedBy = ["multi-user.target" "default.target"];
 
     environment.PODMAN_SYSTEMD_UNIT = "%n";
 
@@ -55,7 +56,6 @@ let
       PIDFile = "/run/podman/pods/${name}.pid";
     };
   };
-
 in {
   options.virtualisation.pods = mkOption {
     type = with types;
@@ -63,9 +63,8 @@ in {
         options = {
           added-hosts = mkOption {
             type = listOf str;
-            default = [ ];
-            description =
-              "Additional hosts to add to /etc/hosts for each container.";
+            default = [];
+            description = "Additional hosts to add to /etc/hosts for each container.";
             example = literalExample ''
               [ "database:10.0.0.1" ]
             '';
@@ -74,25 +73,24 @@ in {
           cgroup-parent = mkOption {
             type = nullOr str;
             default = null;
-            description =
-              "The cgroups path under which the pod cgroup will be created.";
+            description = "The cgroups path under which the pod cgroup will be created.";
           };
 
           dns = mkOption {
             type = listOf str;
-            default = [ ];
+            default = [];
             description = "The dns servers to set in /etc/resolv.conf.";
           };
 
           dns-opt = mkOption {
             type = listOf str;
-            default = [ ];
+            default = [];
             description = "dns options to set in /etc/resolv.conf.";
           };
 
           dns-search = mkOption {
             type = listOf str;
-            default = [ ];
+            default = [];
             description = "Search domains to set in /etc/resolv.conf.";
           };
 
@@ -156,20 +154,20 @@ in {
 
           publish = mkOption {
             type = listOf str;
-            default = [ ];
+            default = [];
             description = "List of ports to publish from the pod.";
           };
 
           share = mkOption {
             type = listOf str;
-            default = [ ];
+            default = [];
             description = "List of kernel namespaces to share.";
           };
 
           containers = options.virtualisation.oci-containers.containers;
         };
       });
-    default = { };
+    default = {};
     description = "Podman pods to run as systemd services.";
   };
 
@@ -178,7 +176,7 @@ in {
     #
     # TODO: See if there's a generic version for this somewhere in the
     # pkgs lib?
-    mergeAttrs = attrList: foldr (a: b: a // b) { } attrList;
+    mergeAttrs = attrList: foldr (a: b: a // b) {} attrList;
 
     # Create services for all defined pods
     pod-services = mapAttrs' (n: v: nameValuePair "pod-${n}" (mkPod n v)) cfg;
@@ -190,31 +188,35 @@ in {
     pod-container-services = mergeAttrs (mapAttrsToList (pname: pod:
       mapAttrs' (cname: container:
         nameValuePair "podman-${pname}-${cname}" rec {
-          after = [ "pod-${pname}.service" ];
+          after = ["pod-${pname}.service"];
           requires = after;
-        }) pod.containers) cfg);
+        })
+      pod.containers)
+    cfg);
 
     # Override the oci-container settings for containers defined in pods.
     #
     # I.e., set the --pod=podname setting, and update the dependsOn so
     # it points to containers in the same pod.
     podifyContainer = container: podname:
-      container // {
+      container
+      // {
         dependsOn =
           map (dependency: "${podname}-${dependency}") container.dependsOn;
-        extraOptions = container.extraOptions ++ [ "--pod=${podname}" ];
+        extraOptions = container.extraOptions ++ ["--pod=${podname}"];
       };
+  in
+    lib.mkIf (cfg != {}) {
+      virtualisation.podman.enable = true;
+      virtualisation.oci-containers.backend = "podman";
 
-  in lib.mkIf (cfg != { }) {
-    virtualisation.podman.enable = true;
-    virtualisation.oci-containers.backend = "podman";
+      systemd.services = pod-services // pod-container-services;
 
-    systemd.services = pod-services // pod-container-services;
-
-    virtualisation.oci-containers.containers = mergeAttrs (mapAttrsToList
-      (pname: pod:
-        mapAttrs' (cname: container:
-          nameValuePair "${pname}-${cname}" (podifyContainer container pname))
-        pod.containers) cfg);
-  };
+      virtualisation.oci-containers.containers = mergeAttrs (mapAttrsToList
+        (pname: pod:
+          mapAttrs' (cname: container:
+            nameValuePair "${pname}-${cname}" (podifyContainer container pname))
+          pod.containers)
+        cfg);
+    };
 }
diff --git a/pkgs/build-support/fetchFromCurseForge.nix b/pkgs/build-support/fetchFromCurseForge.nix
index e3e5b51..674803f 100644
--- a/pkgs/build-support/fetchFromCurseForge.nix
+++ b/pkgs/build-support/fetchFromCurseForge.nix
@@ -1,26 +1,31 @@
-{ lib, fetchurl }:
-
+{
+  lib,
+  fetchurl,
+}:
 with builtins;
+  {
+    project,
+    id,
+    filename,
+    ...
+  } @ args: let
+    # I think this is supposed to be some weak automation
+    # protection. This split "id" is simply part of the download URL.
+    #
+    # Note that if it's zero-prefixed we need to remove the zeroes. It's
+    # really an odd one...
+    a = head (match "0*([[:digit:]]+)" (substring 0 4 (toString id)));
+    b = head (match "0*([[:digit:]]+)" (substring 4 7 (toString id)));
+    encoded-filename = replaceStrings [" "] ["%20"] filename;
 
-{ project, id, filename, ... }@args:
-
-let
-  # I think this is supposed to be some weak automation
-  # protection. This split "id" is simply part of the download URL.
-  #
-  # Note that if it's zero-prefixed we need to remove the zeroes. It's
-  # really an odd one...
-  a = head (match "0*([[:digit:]]+)" (substring 0 4 (toString id)));
-  b = head (match "0*([[:digit:]]+)" (substring 4 7 (toString id)));
-  encoded-filename = replaceStrings [ " " ] [ "%20" ] filename;
-
-  url = "https://media.forgecdn.net/files/${a}/${b}/${encoded-filename}";
-  otherArgs = removeAttrs args [ "project" "project_id" "id" "filename" ];
-
-in fetchurl (otherArgs // {
-  inherit url;
-  # Rename files to avoid names incompatible with the nix store
-  name = "${project}.jar";
-  # Avoid accidental URL globbing
-  curlOpts = "--globoff";
-})
+    url = "https://media.forgecdn.net/files/${a}/${b}/${encoded-filename}";
+    otherArgs = removeAttrs args ["project" "project_id" "id" "filename"];
+  in
+    fetchurl (otherArgs
+      // {
+        inherit url;
+        # Rename files to avoid names incompatible with the nix store
+        name = "${project}.jar";
+        # Avoid accidental URL globbing
+        curlOpts = "--globoff";
+      })
diff --git a/pkgs/default.nix b/pkgs/default.nix
index dd334bc..ef226db 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -1,19 +1,21 @@
-{ pkgs, local-lib, ... }:
-
-let
+{
+  pkgs,
+  local-lib,
+  ...
+}: let
   inherit (pkgs.lib) callPackageWith;
-  callPackage = callPackageWith (pkgs // { inherit local-lib; });
+  callPackage = callPackageWith (pkgs // {inherit local-lib;});
 in {
   # Forge
-  forge-server = callPackage ./minecraft/forge-server.nix { };
+  forge-server = callPackage ./minecraft/forge-server.nix {};
 
   # Build support
-  fetchFromCurseForge = callPackage ./build-support/fetchFromCurseForge.nix { };
+  fetchFromCurseForge = callPackage ./build-support/fetchFromCurseForge.nix {};
 
   # Minecraft modpacks
-  voor-kia = callPackage ./minecraft/voor-kia.nix { };
-  voor-kia-client = callPackage ./minecraft/voor-kia-client.nix { };
+  voor-kia = callPackage ./minecraft/voor-kia.nix {};
+  voor-kia-client = callPackage ./minecraft/voor-kia-client.nix {};
 
   # Starbound
-  starbound = callPackage ./starbound { };
+  starbound = callPackage ./starbound {};
 }
diff --git a/pkgs/minecraft/forge-server.nix b/pkgs/minecraft/forge-server.nix
index e26a7a5..5d7a8c2 100644
--- a/pkgs/minecraft/forge-server.nix
+++ b/pkgs/minecraft/forge-server.nix
@@ -1,7 +1,15 @@
-{ lib, stdenv, fetchurl, busybox, coreutils, jre_headless, runtimeShell
-, mods ? null, modConfig ? null, defaultconfigs ? null }:
-
-let
+{
+  lib,
+  stdenv,
+  fetchurl,
+  busybox,
+  coreutils,
+  jre_headless,
+  runtimeShell,
+  mods ? null,
+  modConfig ? null,
+  defaultconfigs ? null,
+}: let
   name = "forge-server";
   version = "1.16.5-36.2.2";
   mirror = "https://files.minecraftforge.net/maven/net/minecraftforge/forge";
@@ -14,7 +22,7 @@ let
 
   unpackCmd = "mkdir -p src; cp $curSrc src/forge-${version}-installer.jar";
 
-  nativeBuildInputs = [ jre_headless ];
+  nativeBuildInputs = [jre_headless];
 
   # Somewhat evil pre-install step to run through the network
   # dependency resolution forge needs. This is also common for gradle
@@ -43,70 +51,70 @@ let
     outputHashMode = "recursive";
     outputHash = "VuUGc5JnzcRhDt9aaGrU+yUrJILVdU2vzv1PxLwdAig=";
   };
+in
+  stdenv.mkDerivation rec {
+    inherit name version src unpackCmd nativeBuildInputs;
 
-in stdenv.mkDerivation rec {
-  inherit name version src unpackCmd nativeBuildInputs;
+    buildPhase = ''
+      mkdir -p installation
 
-  buildPhase = ''
-    mkdir -p installation
+      # Take the input deps and patch the Minecraft server jar into our
+      # libraries to create the package.
+      cp -rv ${deps}/* installation/
+      chmod -R +w installation/
+      java -jar forge-${version}-installer.jar --offline --installServer installation/
+    '';
 
-    # Take the input deps and patch the Minecraft server jar into our
-    # libraries to create the package.
-    cp -rv ${deps}/* installation/
-    chmod -R +w installation/
-    java -jar forge-${version}-installer.jar --offline --installServer installation/
-  '';
+    installPhase = ''
+      mkdir -p $out/{bin,lib/forge}
 
-  installPhase = ''
-    mkdir -p $out/{bin,lib/forge}
+      cp -r installation/{forge-${version}.jar,libraries} $out/lib/forge/
 
-    cp -r installation/{forge-${version}.jar,libraries} $out/lib/forge/
+      cat > $out/bin/forge-server << EOF
+      #!${runtimeShell}
+      set -eu
 
-    cat > $out/bin/forge-server << EOF
-    #!${runtimeShell}
-    set -eu
+      # Delete any previous mods directory so that it can be updated
+      ${busybox}/bin/rm -fr mods
 
-    # Delete any previous mods directory so that it can be updated
-    ${busybox}/bin/rm -fr mods
+      ${lib.optionalString (mods != null) ''
+        # Copy the specified mods into the directory. Note that, sadly,
+        # forge doesn't support symlinks here.
+        ${busybox}/bin/mkdir -p mods
+        ${busybox}/bin/cp -r '${mods}/mods/'*.jar mods
+      ''}
 
-    ${lib.optionalString (mods != null) ''
-      # Copy the specified mods into the directory. Note that, sadly,
-      # forge doesn't support symlinks here.
-      ${busybox}/bin/mkdir -p mods
-      ${busybox}/bin/cp -r '${mods}/mods/'*.jar mods
-    ''}
+      # Delete any previous config directories so that they can be updated
+      ${busybox}/bin/rm -fr config defaultconfigs
 
-    # Delete any previous config directories so that they can be updated
-    ${busybox}/bin/rm -fr config defaultconfigs
+      ${lib.optionalString (modConfig != null) ''
+        # Copy the specified configs into the directory. Forge (and
+        # mods) will try to write here, so we cannot symlink.
+        ${busybox}/bin/mkdir -p config
+        ${busybox}/bin/cp -r '${modConfig}'/* config
+        ${busybox}/bin/chmod -R u+w config
+      ''}
 
-    ${lib.optionalString (modConfig != null) ''
-      # Copy the specified configs into the directory. Forge (and
-      # mods) will try to write here, so we cannot symlink.
-      ${busybox}/bin/mkdir -p config
-      ${busybox}/bin/cp -r '${modConfig}'/* config
-      ${busybox}/bin/chmod -R u+w config
-    ''}
+      ${lib.optionalString (defaultconfigs != null) ''
+        # Copy the specified configs into the directory. Forge (and
+        # mods) will try to write here, so we cannot symlink.
+        ${busybox}/bin/mkdir -p defaultconfigs
+        ${busybox}/bin/cp -r '${defaultconfigs}'/* defaultconfigs
+        ${busybox}/bin/chmod -R u+w defaultconfigs
+      ''}
 
-    ${lib.optionalString (defaultconfigs != null) ''
-      # Copy the specified configs into the directory. Forge (and
-      # mods) will try to write here, so we cannot symlink.
-      ${busybox}/bin/mkdir -p defaultconfigs
-      ${busybox}/bin/cp -r '${defaultconfigs}'/* defaultconfigs
-      ${busybox}/bin/chmod -R u+w defaultconfigs
-    ''}
+      exec ${jre_headless}/bin/java \$@ -jar $out'/lib/forge/forge-${version}.jar' nogui
+      EOF
 
-    exec ${jre_headless}/bin/java \$@ -jar $out'/lib/forge/forge-${version}.jar' nogui
-    EOF
+      chmod +x $out/bin/forge-server
+    '';
 
-    chmod +x $out/bin/forge-server
-  '';
-
-  meta = with lib; {
-    description = "Forge Minecraft Server";
-    homepage = "https://files.minecraftforge.net/";
-    # Forge itself is open source, but this package pulls in
-    # minecraft.
-    license = licenses.unfreeRedistributable;
-    platforms = platforms.unix;
-  };
-}
+    meta = with lib; {
+      description = "Forge Minecraft Server";
+      homepage = "https://files.minecraftforge.net/";
+      # Forge itself is open source, but this package pulls in
+      # minecraft.
+      license = licenses.unfreeRedistributable;
+      platforms = platforms.unix;
+    };
+  }
diff --git a/pkgs/minecraft/voor-kia-client.nix b/pkgs/minecraft/voor-kia-client.nix
index 8d0c687..fea9879 100644
--- a/pkgs/minecraft/voor-kia-client.nix
+++ b/pkgs/minecraft/voor-kia-client.nix
@@ -1,8 +1,12 @@
-{ lib, local-lib, stdenv }:
-
+{
+  lib,
+  local-lib,
+  stdenv,
+}:
 local-lib.minecraft.mkModpackZip {
   name = "voor-kia-client";
   version = "1.1";
-  mods = (builtins.fromJSON (builtins.readFile ./voor-kia/mods.json))
+  mods =
+    (builtins.fromJSON (builtins.readFile ./voor-kia/mods.json))
     ++ (builtins.fromJSON (builtins.readFile ./voor-kia/client-mods.json));
 }
diff --git a/pkgs/minecraft/voor-kia.nix b/pkgs/minecraft/voor-kia.nix
index 86c5cde..4bbd433 100644
--- a/pkgs/minecraft/voor-kia.nix
+++ b/pkgs/minecraft/voor-kia.nix
@@ -1,5 +1,8 @@
-{ lib, local-lib, stdenv }:
-
+{
+  lib,
+  local-lib,
+  stdenv,
+}:
 local-lib.minecraft.mkModpack {
   name = "voor-kia";
   version = "1.0";

From 7095ab26310ff71eaa094ca38e54b5ebeb821e67 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 12 Oct 2022 01:05:24 +0100
Subject: [PATCH 046/212] treewide: Remove minecraft server

This has fallen into disuse since the big Java vulnerability, and I
have ideas for better ways of doing this. Meanwhile it's making
maintenance and refactoring more difficult.

Hence I'll remove the server completely for the time being.
---
 configuration/default.nix                     |    5 +-
 configuration/ids.nix                         |    2 -
 .../voor-kia/config/EnderStorage.cfg          |   14 -
 .../voor-kia/config/WeirdingGadget.toml       |   12 -
 .../voor-kia/config/WeirdingGadgetLimits.toml |   13 -
 .../config/aiimprovements-common.toml         |   40 -
 .../minecraft/voor-kia/config/alexsmobs.toml  |  415 ----
 .../alligator_snapping_turtle_spawns.json     |   16 -
 .../config/alexsmobs/bald_eagle_spawns.json   |   21 -
 .../config/alexsmobs/blobfish_spawns.json     |   32 -
 .../config/alexsmobs/bone_serpent_spawns.json |   11 -
 .../cachalot_whale_beached_spawns.json        |   16 -
 .../alexsmobs/cachalot_whale_spawns.json      |   42 -
 .../alexsmobs/capuchin_monkey_spawns.json     |   26 -
 .../alexsmobs/cave_centipede_spawns.json      |   21 -
 .../config/alexsmobs/cockroach_spawns.json    |   21 -
 .../alexsmobs/crimson_mosquito_spawns.json    |   25 -
 .../config/alexsmobs/crocodile_spawns.json    |   33 -
 .../config/alexsmobs/crow_spawns.json         |   38 -
 .../config/alexsmobs/dropbear_spawns.json     |   18 -
 .../config/alexsmobs/elephant_spawns.json     |   28 -
 .../voor-kia/config/alexsmobs/emu_spawns.json |   28 -
 .../config/alexsmobs/endergrade_spawns.json   |   16 -
 .../config/alexsmobs/enderiophage_spawns.json |   31 -
 .../voor-kia/config/alexsmobs/fly_spawns.json |   21 -
 .../alexsmobs/frilled_shark_spawns.json       |   32 -
 .../config/alexsmobs/gazelle_spawns.json      |   28 -
 .../config/alexsmobs/gorilla_spawns.json      |   26 -
 .../config/alexsmobs/grizzly_bear_spawns.json |   28 -
 .../config/alexsmobs/guster_spawns.json       |   16 -
 .../alexsmobs/hammerhead_shark_spawns.json    |   21 -
 .../config/alexsmobs/hummingbird_spawns.json  |   30 -
 .../config/alexsmobs/kangaroo_spawns.json     |   28 -
 .../alexsmobs/komodo_dragon_spawns.json       |   16 -
 .../alexsmobs/leafcutter_anthill_spawns.json  |   26 -
 .../config/alexsmobs/lobster_spawns.json      |   16 -
 .../alexsmobs/mantis_shrimp_spawns.json       |   21 -
 .../alexsmobs/mimic_octopus_spawns.json       |   26 -
 .../config/alexsmobs/mimicube_spawns.json     |   16 -
 .../config/alexsmobs/moose_spawns.json        |   38 -
 .../config/alexsmobs/mungus_spawns.json       |   21 -
 .../config/alexsmobs/orca_spawns.json         |   21 -
 .../config/alexsmobs/platypus_spawns.json     |   28 -
 .../config/alexsmobs/raccoon_spawns.json      |   38 -
 .../config/alexsmobs/rattlesnake_spawns.json  |   28 -
 .../config/alexsmobs/roadrunner_spawns.json   |   28 -
 .../config/alexsmobs/seal_spawns.json         |   33 -
 .../config/alexsmobs/shoebill_spawns.json     |   16 -
 .../config/alexsmobs/snow_leopard_spawns.json |   21 -
 .../config/alexsmobs/soul_vulture_spawns.json |   18 -
 .../config/alexsmobs/spectre_spawns.json      |   11 -
 .../config/alexsmobs/straddler_spawns.json    |   11 -
 .../config/alexsmobs/stradpole_spawns.json    |   11 -
 .../config/alexsmobs/sunbird_spawns.json      |   16 -
 .../alexsmobs/tarantula_hawk_spawns.json      |   16 -
 .../alexsmobs/tasmanian_devil_spawns.json     |   36 -
 .../config/alexsmobs/tiger_spawns.json        |   42 -
 .../config/alexsmobs/void_worm_spawns.json    |    3 -
 .../config/alexsmobs/warped_mosco_spawns.json |    3 -
 .../config/alexsmobs/warped_toad_spawns.json  |   18 -
 .../voor-kia/config/apotheosis/affixes.cfg    |  212 --
 .../voor-kia/config/apotheosis/apotheosis.cfg |   23 -
 .../voor-kia/config/apotheosis/deadly.cfg     |  222 --
 .../config/apotheosis/enchantments.cfg        | 1007 --------
 .../voor-kia/config/apotheosis/garden.cfg     |   14 -
 .../voor-kia/config/apotheosis/names.cfg      | 1198 ----------
 .../voor-kia/config/apotheosis/potion.cfg     |    8 -
 .../voor-kia/config/apotheosis/spawner.cfg    |  135 --
 .../voor-kia/config/apotheosis/village.cfg    |   12 -
 .../voor-kia/config/appleskin-client.toml     |   24 -
 .../voor-kia/config/artifacts-common.toml     |   36 -
 .../config/attributefix-common-1.toml.bak     |    0
 .../voor-kia/config/attributefix-common.toml  |  144 --
 .../voor-kia/config/betterburning-common.toml |   35 -
 .../voor-kia/config/bettercaves-1_16.toml     |  310 ---
 .../voor-kia/config/bettercaves/README.txt    |   12 -
 .../config/bettermineshafts-forge-1_16.toml   |  104 -
 .../config/bettermineshafts/1_16/README.txt   |   85 -
 .../bettermineshafts/1_16/biomeTags.txt       |   38 -
 .../bettermineshafts/1_16/variants.json       |  577 -----
 .../config/bettermineshafts/README.txt        |    5 -
 .../voor-kia/config/betterportals-1_16.toml   |   11 -
 .../config/betterportals/1_16/README.txt      |   69 -
 .../config/betterportals/1_16/monoliths.json  |   55 -
 .../config/betterportals/1_16/rifts.json      |   30 -
 .../config/betterportals/1_16_3/README.txt    |   69 -
 .../betterportals/1_16_3/monoliths.json       |   55 -
 .../config/betterportals/1_16_3/rifts.json    |   30 -
 .../voor-kia/config/bwncr-common.toml         |   16 -
 .../minecraft/voor-kia/config/byg/README.txt  |    3 -
 .../voor-kia/config/byg/byg-biomes.json       | 1125 ---------
 .../voor-kia/config/byg/byg-end-biomes.json   |   86 -
 .../config/byg/byg-end-sub-biomes.json        |   22 -
 .../voor-kia/config/byg/byg-nether.toml       |   15 -
 .../voor-kia/config/byg/byg-sub-biomes.json   |  520 ----
 .../voor-kia/config/byg/byg-world.toml        |  218 --
 .../voor-kia/config/citadel-common.toml       |    8 -
 .../config/cookingforblockheads-common.toml   |   23 -
 .../config/cosmeticarmorreworked-common.toml  |   10 -
 .../voor-kia/config/create-common.toml        |  136 --
 .../config/decorative_blocks-common.toml      |    8 -
 .../config/farmingforblockheads-common.toml   |   24 -
 .../farmingforblockheads/MarketRegistry.json  |    1 -
 .../minecraft/voor-kia/config/fastbench.cfg   |    8 -
 .../minecraft/voor-kia/config/fml.toml        |    8 -
 .../voor-kia/config/forge-common.toml         |    7 -
 .../config/hardcorerevival-common.toml        |   34 -
 .../voor-kia/config/iceandfire-biomes.toml    |   89 -
 .../voor-kia/config/iceandfire-common.toml    |  452 ----
 .../iceandfire/amethyst_gen_biomes.json       |   28 -
 .../config/iceandfire/amphithere_biomes.json  |   16 -
 .../config/iceandfire/cockatrice_biomes.json  |   28 -
 .../iceandfire/cyclops_cave_biomes.json       |   28 -
 .../config/iceandfire/deathworm_biomes.json   |   16 -
 .../iceandfire/desert_myrmex_biomes.json      |   16 -
 .../config/iceandfire/fire_dragon_biomes.json |   73 -
 .../fire_dragon_skeleton_biomes.json          |   16 -
 .../config/iceandfire/fire_lily_biomes.json   |   16 -
 .../iceandfire/forest_troll_biomes.json       |   28 -
 .../iceandfire/gorgon_temple_biomes.json      |   28 -
 .../config/iceandfire/graveyard_biomes.json   |   31 -
 .../config/iceandfire/hippocampus_biomes.json |   28 -
 .../config/iceandfire/hippogryph_biomes.json  |   52 -
 .../iceandfire/hippogryph_black_biomes.json   |   16 -
 .../iceandfire/hippogryph_brown_biomes.json   |   28 -
 .../hippogryph_chestnut_biomes.json           |   16 -
 .../iceandfire/hippogryph_creamy_biomes.json  |   16 -
 .../hippogryph_dark_brown_biomes.json         |   28 -
 .../iceandfire/hippogryph_gray_biomes.json    |   16 -
 .../iceandfire/hippogryph_white_biomes.json   |   40 -
 .../config/iceandfire/hydra_cave_biomes.json  |   28 -
 .../config/iceandfire/ice_dragon_biomes.json  |   40 -
 .../ice_dragon_skeleton_biomes.json           |   28 -
 .../config/iceandfire/ice_lily_biomes.json    |   28 -
 .../iceandfire/jungle_myrmex_biomes.json      |   16 -
 .../iceandfire/lightning_dragon_biomes.json   |   40 -
 .../lightning_dragon_skeleton_biomes.json     |   28 -
 .../iceandfire/lightning_lily_biomes.json     |   28 -
 .../config/iceandfire/mausoleum_biomes.json   |   28 -
 .../iceandfire/mountain_troll_biomes.json     |   28 -
 .../config/iceandfire/ore_gen_biomes.json     |   11 -
 .../iceandfire/pixie_village_biomes.json      |   73 -
 .../iceandfire/sapphire_gen_biomes.json       |   28 -
 .../config/iceandfire/sea_serpent_biomes.json |   28 -
 .../config/iceandfire/siren_biomes.json       |   28 -
 .../config/iceandfire/snowy_troll_biomes.json |   16 -
 .../iceandfire/stymphalian_bird_biomes.json   |   28 -
 .../iceandfire/wandering_cyclops_biomes.json  |   28 -
 .../voor-kia/config/ironfurnaces-client.toml  |    9 -
 .../voor-kia/config/ironfurnaces.toml         |  142 --
 .../voor-kia/config/jeresources-common.toml   |   11 -
 .../voor-kia/config/jeresources.toml          |   11 -
 .../config/lottaterracotta-common.toml        |   25 -
 .../voor-kia/config/overworldtwo.json         |    5 -
 .../voor-kia/config/pamhc2crops.toml          |   50 -
 .../voor-kia/config/pamhc2trees.toml          |  126 -
 .../config/passablefoliage-common.toml        |   24 -
 .../voor-kia/config/performant-common.toml    |  138 --
 .../voor-kia/config/platter-common.toml       |   13 -
 .../config/powah/energy/ender_cell.toml       |   49 -
 .../config/powah/energy/ender_gate.toml       |   49 -
 .../config/powah/energy/energizing.toml       |   36 -
 .../config/powah/energy/energy_cable.toml     |   33 -
 .../config/powah/energy/energy_cell.toml      |   33 -
 .../powah/energy/energy_discharger.toml       |   33 -
 .../config/powah/energy/energy_hopper.toml    |   49 -
 .../powah/energy/generators/furnator.toml     |   49 -
 .../powah/energy/generators/magmator.toml     |   56 -
 .../powah/energy/generators/reactor.toml      |   49 -
 .../powah/energy/generators/solar_panel.toml  |   49 -
 .../powah/energy/generators/thermo_gen.toml   |   49 -
 .../config/powah/energy/items/battery.toml    |   33 -
 .../powah/energy/player_transmitter.toml      |   49 -
 .../voor-kia/config/powah/general_common.toml |   46 -
 .../voor-kia/config/quark-common-1.toml.bak   | 2128 -----------------
 .../voor-kia/config/quark-common-2.toml.bak   |    0
 .../voor-kia/config/quark-common-3.toml.bak   |    0
 .../voor-kia/config/quark-common-4.toml.bak   |    0
 .../voor-kia/config/quark-common-5.toml.bak   |    0
 .../voor-kia/config/quark-common.toml         | 2078 ----------------
 .../voor-kia/config/repairchests-common.toml  |    9 -
 .../voor-kia/config/rsgauges-common.toml      |   40 -
 .../voor-kia/config/snowrealmagic-common.toml |   25 -
 .../config/snowundertrees-common.toml         |    8 -
 .../config/storagedrawers-common.toml         |   30 -
 .../config/supplementaries-common.toml        |  274 ---
 .../config/supplementaries-registry.toml      |   73 -
 .../voor-kia/config/sweetconcrete-common.toml |   27 -
 .../the_bumblezone-mod_compatibility.toml     |  262 --
 .../config/towers_of_the_wild-common.toml     |   20 -
 .../config/travelersbackpack-common.toml      |   13 -
 .../voor-kia/config/wstweaks-common.toml      |   19 -
 .../defaultconfigs/solcarrot-server.toml      |   26 -
 .../minecraft/voor-kia/server-icon.png        |  Bin 23263 -> 0 bytes
 .../minecraft/voor-kia/server.properties      |   52 -
 configuration/services/minecraft.nix          |  141 --
 flake.nix                                     |   34 +-
 lib/default.nix                               |   12 -
 lib/minecraft.nix                             |   61 -
 pkgs/build-support/fetchFromCurseForge.nix    |   31 -
 pkgs/default.nix                              |   20 +-
 pkgs/minecraft/forge-server.nix               |  120 -
 pkgs/minecraft/voor-kia-client.nix            |   12 -
 pkgs/minecraft/voor-kia.nix                   |   10 -
 pkgs/minecraft/voor-kia/client-mods.json      |   86 -
 pkgs/minecraft/voor-kia/mods.json             |  625 -----
 pkgs/minecraft/voor-kia/update-mods.py        |  156 --
 207 files changed, 5 insertions(+), 17764 deletions(-)
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/EnderStorage.cfg
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/WeirdingGadget.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/WeirdingGadgetLimits.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/aiimprovements-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/alligator_snapping_turtle_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/bald_eagle_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/blobfish_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/bone_serpent_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cachalot_whale_beached_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cachalot_whale_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/capuchin_monkey_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cave_centipede_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cockroach_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/crimson_mosquito_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/crocodile_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/crow_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/dropbear_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/elephant_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/emu_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/endergrade_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/enderiophage_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/fly_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/frilled_shark_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/gazelle_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/gorilla_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/grizzly_bear_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/guster_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/hammerhead_shark_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/hummingbird_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/kangaroo_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/komodo_dragon_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/leafcutter_anthill_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/lobster_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mantis_shrimp_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mimic_octopus_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mimicube_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/moose_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mungus_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/orca_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/platypus_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/raccoon_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/rattlesnake_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/roadrunner_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/seal_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/shoebill_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/snow_leopard_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/soul_vulture_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/spectre_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/straddler_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/stradpole_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/sunbird_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tarantula_hawk_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tasmanian_devil_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tiger_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/void_worm_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/warped_mosco_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/alexsmobs/warped_toad_spawns.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/apotheosis/affixes.cfg
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/apotheosis/apotheosis.cfg
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/apotheosis/deadly.cfg
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/apotheosis/enchantments.cfg
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/apotheosis/garden.cfg
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/apotheosis/names.cfg
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/apotheosis/potion.cfg
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/apotheosis/spawner.cfg
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/apotheosis/village.cfg
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/appleskin-client.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/artifacts-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/attributefix-common-1.toml.bak
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/attributefix-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/betterburning-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/bettercaves-1_16.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/bettercaves/README.txt
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/bettermineshafts-forge-1_16.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/bettermineshafts/1_16/README.txt
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/bettermineshafts/1_16/biomeTags.txt
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/bettermineshafts/1_16/variants.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/bettermineshafts/README.txt
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/betterportals-1_16.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/README.txt
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/monoliths.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/rifts.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16_3/README.txt
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16_3/monoliths.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16_3/rifts.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/bwncr-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/byg/README.txt
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/byg/byg-biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/byg/byg-end-biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/byg/byg-end-sub-biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/byg/byg-nether.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/byg/byg-sub-biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/byg/byg-world.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/citadel-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/cookingforblockheads-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/cosmeticarmorreworked-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/create-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/decorative_blocks-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/farmingforblockheads-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/farmingforblockheads/MarketRegistry.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/fastbench.cfg
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/fml.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/forge-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/hardcorerevival-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire-biomes.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/amethyst_gen_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/amphithere_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/cockatrice_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/cyclops_cave_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/deathworm_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/desert_myrmex_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_dragon_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_dragon_skeleton_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_lily_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/forest_troll_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/gorgon_temple_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/graveyard_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippocampus_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_black_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_brown_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_chestnut_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_creamy_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_dark_brown_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_gray_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_white_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/hydra_cave_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_dragon_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_dragon_skeleton_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_lily_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/jungle_myrmex_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_dragon_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_dragon_skeleton_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_lily_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/mausoleum_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/mountain_troll_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/ore_gen_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/pixie_village_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/sapphire_gen_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/sea_serpent_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/siren_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/snowy_troll_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/stymphalian_bird_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/iceandfire/wandering_cyclops_biomes.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/ironfurnaces-client.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/ironfurnaces.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/jeresources-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/jeresources.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/lottaterracotta-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/overworldtwo.json
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/pamhc2crops.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/pamhc2trees.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/passablefoliage-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/performant-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/platter-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/powah/energy/ender_cell.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/powah/energy/ender_gate.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/powah/energy/energizing.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/powah/energy/energy_cable.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/powah/energy/energy_cell.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/powah/energy/energy_discharger.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/powah/energy/energy_hopper.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/furnator.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/magmator.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/reactor.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/solar_panel.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/thermo_gen.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/powah/energy/items/battery.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/powah/energy/player_transmitter.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/powah/general_common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/quark-common-1.toml.bak
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/quark-common-2.toml.bak
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/quark-common-3.toml.bak
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/quark-common-4.toml.bak
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/quark-common-5.toml.bak
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/quark-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/repairchests-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/rsgauges-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/snowrealmagic-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/snowundertrees-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/storagedrawers-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/supplementaries-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/supplementaries-registry.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/sweetconcrete-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/the_bumblezone-mod_compatibility.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/towers_of_the_wild-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/travelersbackpack-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/config/wstweaks-common.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/defaultconfigs/solcarrot-server.toml
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/server-icon.png
 delete mode 100644 configuration/services/configs/minecraft/voor-kia/server.properties
 delete mode 100644 configuration/services/minecraft.nix
 delete mode 100644 lib/default.nix
 delete mode 100644 lib/minecraft.nix
 delete mode 100644 pkgs/build-support/fetchFromCurseForge.nix
 delete mode 100644 pkgs/minecraft/forge-server.nix
 delete mode 100644 pkgs/minecraft/voor-kia-client.nix
 delete mode 100644 pkgs/minecraft/voor-kia.nix
 delete mode 100644 pkgs/minecraft/voor-kia/client-mods.json
 delete mode 100644 pkgs/minecraft/voor-kia/mods.json
 delete mode 100644 pkgs/minecraft/voor-kia/update-mods.py

diff --git a/configuration/default.nix b/configuration/default.nix
index 8e9744d..b008454 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -6,7 +6,6 @@
 }: {
   imports = [
     ./services/gitea.nix
-    ./services/minecraft.nix
     ./services/nextcloud.nix
     ./services/webserver.nix
     ./services/starbound.nix
@@ -25,7 +24,7 @@
   };
 
   nixpkgs.config.allowUnfreePredicate = pkg:
-    builtins.elem (lib.getName pkg) ["forge-server" "steam-runtime" "steamcmd"];
+    builtins.elem (lib.getName pkg) ["steam-runtime" "steamcmd"];
 
   sops = {
     defaultSopsFile = ../keys/external.yaml;
@@ -41,7 +40,7 @@
     useDHCP = false;
     interfaces.eth0.useDHCP = true;
 
-    firewall.allowedTCPPorts = [80 443 2222 2221 25565 21025];
+    firewall.allowedTCPPorts = [80 443 2222 2221 21025];
   };
 
   time.timeZone = "Europe/London";
diff --git a/configuration/ids.nix b/configuration/ids.nix
index 9b99011..352b4d3 100644
--- a/configuration/ids.nix
+++ b/configuration/ids.nix
@@ -2,12 +2,10 @@
   ids.uids = {
     # System user ids start at 400 (see nixos/modules/programs/shadow.nix)
     webserver = 400;
-    minecraft = 401;
     # The limit is 999
   };
 
   ids.gids = {
     webserver = 400;
-    minecraft = 401;
   };
 }
diff --git a/configuration/services/configs/minecraft/voor-kia/config/EnderStorage.cfg b/configuration/services/configs/minecraft/voor-kia/config/EnderStorage.cfg
deleted file mode 100644
index df6c551..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/EnderStorage.cfg
+++ /dev/null
@@ -1,14 +0,0 @@
-# The RegistryName for the Item to lock EnderChests and Tanks.
-S:"personalItem"="minecraft:diamond"
-
-# Causes chests to lose personal settings and drop the diamond on break.
-B:"anarchyMode"=false
-
-# The size of each inventory of EnderStorage, 0 = 3x3, 1 = 3x9, 2 = 6x9, default = 1
-I:"item_storage_size"=1
-
-# Disables the tank on top of creators heads.
-B:"disableCreatorVisuals"=false
-
-# Enable this to make EnderStorage use vanilla's EnderChest sounds instead of the standard chest.
-B:"useVanillaEnderChestsSounds"=false
diff --git a/configuration/services/configs/minecraft/voor-kia/config/WeirdingGadget.toml b/configuration/services/configs/minecraft/voor-kia/config/WeirdingGadget.toml
deleted file mode 100644
index deb1f5b..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/WeirdingGadget.toml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-#Server configuration settings
-[server]
-	#The number of hours the player will be offline before deactivating (default 2 days)
-	#Range: 1 ~ 8760
-	hoursBeforeDeactivation = 48
-	#Disables Chunk loading, use if there is a crash happening in a chunk loaded area
-	emergencymode = false
-	#Width/length of chunks to be loaded, it is recommend this is an odd number (max 25)
-	#Range: 1 ~ 25
-	chunkLoaderWidth = 3
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/WeirdingGadgetLimits.toml b/configuration/services/configs/minecraft/voor-kia/config/WeirdingGadgetLimits.toml
deleted file mode 100644
index 31eeb1f..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/WeirdingGadgetLimits.toml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-#Limits for chunk loading
-[chunkLoadingLimits]
-	#The number of tickets a player can be assigned instead of a mod. This is shared across all mods.
-	#Range: > 0
-	maximumPlayerTickets = 500
-	#No comment
-	#Range: 0 ~ 225
-	maximumChunksPerTicket = 25
-	#Maximum ticket count for the mod. Zero disables chunkloading capabilities.
-	#Range: > 0
-	maximumModTickets = 200
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/aiimprovements-common.toml b/configuration/services/configs/minecraft/voor-kia/config/aiimprovements-common.toml
deleted file mode 100644
index aca1132..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/aiimprovements-common.toml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-#Entity Settings
-[entity]
-
-	#General
-	[entity.general]
-		#Allows repeat remove calls to bubble to the top of the list to improve performance of repeat mob spawning.
-		enable_call_bubbling = true
-		#Allow AI tasks to be removed from entities at runtime. If this is disable no per mob or per mob type removes will run.
-		allow_remove_calls = true
-
-	#Entity Mob
-	[entity.mob]
-		#Remove the look at goal (player or attack target) AI task. This will cause AIs to not face targets or walking directions.
-		remove_look_goal = false
-		#Replaces the default look controller with a version featuring cached tan math improving performance. Only works on vanilla style mobs, if a mod overrides the look controller it will skip.
-		replace_look_controller = true
-		#Remove the look at random position AI task. This will cause AIs to feel a little lifeless as they do not animate head movement while idle.
-		remove_look_random = false
-
-	#Entity Fish
-	[entity.fish]
-		#Remove the fish's AI task to follow a leader fish to act as a group of fish.
-		remove_follow_leader = false
-		#Remove the fish's random swimming pathfinder. This will cause fish to stay in position more often.
-		remove_swim = false
-		#Remove the fish's panic pathfinder. This will cause fish to not run away.
-		remove_panic = false
-		#Remove the fish's AI task to avoid players.
-		remove_avoid_player = false
-		#Remove the fish's AI task to puff up when entities are nearby
-		remove_puff = false
-
-	#Squid Fish
-	[entity.squid]
-		#Remove the squid's flee pathfinder. This will cause squid to not run away.
-		remove_flee = false
-		#Remove the squid's random movement pathfinder. This will cause squid to swim around randomly.
-		remove_random_move = false
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs.toml b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs.toml
deleted file mode 100644
index 0226397..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs.toml
+++ /dev/null
@@ -1,415 +0,0 @@
-
-[general]
-	#Whether polar bears should target seal mobs.
-	polarBearsAttackSeals = true
-	#Whether bone serpents are neutral or hostile.
-	neutralBoneSerpents = false
-	#Makes eagles teleport back to their owner if they get stuck during controlled flight. Useful for when playing with the Optifine mod, since this mod is the fault of many issues with the falconry system.
-	falconryTeleportsBack = false
-	#List of dimensions in which spawning void worms via mysterious worm items is allowed.
-	voidWormSpawnDimensions = ["minecraft:the_end"]
-	#True if straddleboard enchants are enabled.
-	straddleboardEnchants = true
-	#Whether Crimson Mosquitoes can transform into Warped Moscos if attacking a Mungus or any listed creature.
-	warpedMoscoTransformation = true
-	#Whether wild raccoons steal food from chests.
-	raccoonStealFromChests = true
-	#Whether mimicream can be used to duplicate items.
-	mimicreamRepair = true
-	#Whether acacia blossoms should drop from blocks tagged with #alexsmobs:drops_acacia_blossoms
-	acaciaBlossomsDropFromLeaves = true
-	#Whether lava can be bottled with a right click of a glass bottle.
-	lavaBottleEnabled = true
-	#Maximum world y-level that blobfish can spawn at
-	#Range: 0 ~ 256
-	blobfishSpawnHeight = 38
-	#Whether guster spawns are limited to when it is raining/thundering.
-	limitGusterSpawnsToWeather = true
-	#Whether all players should get an Animal Dictionary when joining the world for the first time.
-	giveBookOnStartup = true
-	#Maximum world y-level that cave centipedes can spawn at
-	#Range: 0 ~ 256
-	caveCentipedeSpawnHeight = 30
-	#Blacklist for items that mimicream cannot make a copy of. Ex: "minecraft:stone_sword", "alexsmobs:blood_sprayer"
-	mimicreamBlacklist = ["alexsmobs:blood_sprayer", "alexsmobs:hemolymph_blaster"]
-	#0 = no mungus biome transformation. 1 = mungus changes blocks, but not chunk's biome. 2 = mungus transforms blocks and biome of chunk.
-	#Range: 0 ~ 2
-	mungusBiomeTransformationType = 2
-	#Max Health of the void worm boss.
-	#Range: 0.0 ~ 1000000.0
-	voidWormMaxHealth = 160.0
-	#All void worm damage is scaled to this.
-	#Range: 0.0 ~ 100.0
-	voidWormDamageModifier = 1.0
-	#Whether the void worm boss is summonable or not, via the mysterious worm item.
-	voidWormSummonable = true
-	#List of all mungus mushrooms, biome transformations and surface blocks. Each is seperated by a |. Add an entry with a block registry name, biome registry name, and block registry name(for the ground).
-	mungusBiomeMatches = ["minecraft:red_mushroom|minecraft:mushroom_fields|minecraft:mycelium", "minecraft:brown_mushroom|minecraft:mushroom_fields|minecraft:mycelium", "minecraft:crimson_fungus|minecraft:crimson_forest|minecraft:crimson_nylium", "minecraft:warped_fungus|minecraft:warped_forest|minecraft:warped_nylium"]
-	#Percent chance for leafcutter ants to break leaves blocks when harvesting. Set to zero so that they can not break any blocks.
-	#Range: 0.0 ~ 1.0
-	leafcutterAntBreakLeavesChance = 0.2
-	#Whether to disable certain aspects of the Lava Vision Potion. Enable if issues with shaders persist.
-	shadersCompat = false
-	#List of extra(non mungus) mobs that will trigger a crimson mosquito to become a warped mosquito. Ex: "minecraft:mooshroom", "alexsmobs:warped_toad"
-	warpedMoscoMobTriggers = [""]
-	#1 out of this number chance for leaves to drop a banana when broken. Fortune is automatically factored in
-	#Range: > 0
-	bananaChance = 200
-	#Max number of ant entities allowed inside a leafcutter anthill.
-	#Range: 2 ~ 100000
-	leafcutterAntColonySize = 20
-	#Whether soul vulture spawns should be restricted solely to the nether fossil structure or to whatever biome is specified in their respective biome config.
-	soulVultureSpawnOnFossil = true
-	#Makes Tarantula Hawks fireproof, perfect if you also want these guys to spawn in the nether.
-	fireproofTarantulaHawk = false
-	#Percent chance for fungus to grow per each leaf a leafcutter ant returns to the colony.
-	#Range: 0.0 ~ 1.0
-	leafcutterAntFungusGrowChance = 0.3
-	#Whether fish oil gives players a special levitation effect.
-	fishOilMeme = true
-	#Whether mimicubes spawns should be restricted solely to the end city structure or to whatever biome is specified in their respective biome config.
-	mimicubeSpawnInEndCity = true
-	#Whether bananas should drop from blocks tagged with #alexsmobs:drops_bananas
-	bananasDropFromLeaves = true
-	#Relative volume of cachalot whales compared to other animals. Note that irl they are the loudest animal. Turn this down if you find their clicks annoying.
-	#Range: 0.0 ~ 10.0
-	cachalotVolume = 3.0
-	#Whether emu should target skeletons.
-	emuTargetSkeletons = true
-	#Lava Opacity for the Lava Vision Potion.
-	#Range: 0.01 ~ 1.0
-	lavaVisionOpacity = 0.65
-	#Whether spiders should target fly mobs.
-	spidersAttackFlies = true
-	#Whether wolves should target moose mobs.
-	wolvesAttackMoose = true
-	#Percent chance for emu leggings to dodge projectile attacks.
-	#Range: 0.0 ~ 1.0
-	emuPantsDodgeChance = 0.45
-	#How many feedings of leaves does a leafcutter colony need in order to regain a worker ant, if below half the max members.
-	#Range: 2 ~ 100000
-	leafcutterAntRepopulateFeedings = 25
-	#Whether wandering traders offer items like acacia blossoms, mosquito larva, crocodile egg, etc.
-	wanderingTraderOffers = true
-
-	[general.spawning]
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		boneSerpentSpawnWeight = 8
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		alligatorSnappingTurtleSpawnRolls = 1
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		frilledSharkSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		stradpoleSpawnRolls = 3
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		mantisShrimpSpawnWeight = 15
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		lobsterSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		spectreSpawnWeight = 10
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		endergradeSpawnWeight = 10
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		sealSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		sunbirdSpawnRolls = 15
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		shoebillSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		sunbirdSpawnWeight = 2
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		raccoonSpawnWeight = 10
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		mungusSpawnRolls = 1
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		mimicubeSpawnWeight = 40
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		blobfishSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		crowSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		tasmanianDevilSpawnWeight = 10
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		grizzlyBearSpawnWeight = 8
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		elephantSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		caveCentipedeSpawnWeight = 8
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		shoebillSpawnWeight = 10
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		sealSpawnWeight = 30
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		baldEagleSpawnWeight = 15
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		kangarooSpawnWeight = 25
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		rattlesnakeSpawnWeight = 12
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		soulVultureSpawnWeight = 30
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		enderiophageSpawnRolls = 2
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		mooseSpawnWeight = 15
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		warpedMoscoSpawnRolls = 1000
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		platypusSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		tarantulaHawkSpawnRolls = 1
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		soulVultureSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		orcaSpawnRolls = 6
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		capuchinMonkeySpawnWeight = 55
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		alligatorSnappingTurtleSpawnWeight = 20
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		boneSeprentSpawnRolls = 40
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		mimicubeSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn. NOTE: By default the warped mosco doesn't spawn in any biomes.
-		#Range: 0 ~ 1000
-		warpedMoscoSpawnWeight = 1
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		cockroachSpawnWeight = 4
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		gazelleSpawnWeight = 40
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		gorillaSpawnWeight = 50
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		flySpawnRolls = 1
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		platypusSpawnWeight = 30
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		warpedToadSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		gorillaSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		snowLeopardSpawnWeight = 20
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		orcaSpawnWeight = 2
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		mimicOctopusSpawnWeight = 9
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		tigerSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		dropbearSpawnRolls = 1
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		crimsonMosquitoSpawnWeight = 15
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		straddlerSpawnWeight = 85
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		hummingbirdSpawnWeight = 39
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		roadrunnerSpawnRolls = 1
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		gusterSpawnWeight = 35
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		endergradeSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		elephantSpawnWeight = 30
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		tasmanianDevilSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		hammerheadSharkSpawnWeight = 8
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		straddlerSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		voidWormSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		gazelleSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		mantisShrimpSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		mungusSpawnWeight = 4
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		voidWormSpawnWeight = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		crocSpawnRolls = 1
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		stradpoleSpawnWeight = 10
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		mooseSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		spectreSpawnRolls = 5
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		caveCentipedeSpawnRolls = 1
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		blobfishSpawnWeight = 30
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		baldEagleSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		tigerSpawnWeight = 100
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		raccoonSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		warpedToadSpawnWeight = 80
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		frilledSharkSpawnWeight = 11
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		emuSpawnWeight = 20
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		kangarooSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		crowSpawnWeight = 10
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		mimicOctopusSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		komodoDragonSpawnWeight = 4
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		flySpawnWeight = 3
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		snowLeopardSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		cachalotWhaleSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		cachalotWhaleSpawnWeight = 2
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		komodoDragonSpawnRolls = 1
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		emuSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		tarantulaHawkSpawnWeight = 6
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		crocodileSpawnWeight = 40
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		gusterSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		cockroachSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		rattlesnakeSpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		roadrunnerSpawnWeight = 15
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		lobsterSpawnWeight = 7
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		capuchinMonkeySpawnRolls = 0
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		dropbearSpawnWeight = 19
-		#Spawn Weight, added to a pool of other mobs for each biome. Higher number = higher chance of spawning. 0 = disable spawn
-		#Range: 0 ~ 1000
-		enderiophageSpawnWeight = 4
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		hummingbirdSpawnRolls = 1
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		grizzlyBearSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		crimsonMosquitoSpawnRolls = 0
-		#Random roll chance to enable mob spawning. Higher number = lower chance of spawning
-		#Range: > 0
-		hammerheadSharkSpawnRolls = 1
-
-		[general.spawning.uniqueSpawning]
-			#Delay (in ticks) between attempts to spawn beached cachalot whales. Default is a single day. Works like wandering traders.
-			#Range: > 0
-			beachedCachalotWhaleSpawnDelay = 24000
-			#Percent chance for leafcutter anthills to spawn as world gen in each chunk. Set to zero to disable spawning.
-			#Range: 0.0 ~ 1.0
-			leafcutterAnthillSpawnChance = 0.004999999888241291
-			#Whether to enable beached cachalot whales to spawn on beaches during thunder storms.
-			beachedCachalotWhales = true
-			#Percent chance increase for each failed attempt to spawn a beached cachalot whale. Higher value = more spawns.
-			#Range: 0 ~ 100
-			beachedCachalotWhaleSpawnChance = 5
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/alligator_snapping_turtle_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/alligator_snapping_turtle_spawns.json
deleted file mode 100644
index 2f80bc7..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/alligator_snapping_turtle_spawns.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "swamp"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/bald_eagle_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/bald_eagle_spawns.json
deleted file mode 100644
index e2ade4f..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/bald_eagle_spawns.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "mountain"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "forest"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/blobfish_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/blobfish_spawns.json
deleted file mode 100644
index 696a296..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/blobfish_spawns.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:deep_ocean"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:deep_lukewarm_ocean"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:deep_cold_ocean"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:deep_frozen_ocean"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/bone_serpent_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/bone_serpent_spawns.json
deleted file mode 100644
index b693e3d..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/bone_serpent_spawns.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "nether"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cachalot_whale_beached_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cachalot_whale_beached_spawns.json
deleted file mode 100644
index cfb150a..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cachalot_whale_beached_spawns.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "beach"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cachalot_whale_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cachalot_whale_spawns.json
deleted file mode 100644
index 15f385f..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cachalot_whale_spawns.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "ocean"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "cold"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:lukewarm_ocean"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:deep_ocean"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:deep_lukewarm_ocean"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/capuchin_monkey_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/capuchin_monkey_spawns.json
deleted file mode 100644
index feabd66..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/capuchin_monkey_spawns.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "jungle"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": true,
-        "value": "minecraft:bamboo_jungle"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": true,
-        "value": "minecraft:bamboo_jungle_hills"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cave_centipede_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cave_centipede_spawns.json
deleted file mode 100644
index 32ef084..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cave_centipede_spawns.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "ocean"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "mushroom"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cockroach_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cockroach_spawns.json
deleted file mode 100644
index 32ef084..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/cockroach_spawns.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "ocean"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "mushroom"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/crimson_mosquito_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/crimson_mosquito_spawns.json
deleted file mode 100644
index ceeb04c..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/crimson_mosquito_spawns.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:crimson_forest"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "byg:crimson_garden"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "biomesoplenty:visceral_heap"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/crocodile_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/crocodile_spawns.json
deleted file mode 100644
index 5c2a548..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/crocodile_spawns.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "swamp"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "river"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "cold"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/crow_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/crow_spawns.json
deleted file mode 100644
index ed8b56d..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/crow_spawns.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "savanna"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "forest"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "savanna"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "plains"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/dropbear_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/dropbear_spawns.json
deleted file mode 100644
index 6abab58..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/dropbear_spawns.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:nether_wastes"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "biomesoplenty:crystalline_chasm"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/elephant_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/elephant_spawns.json
deleted file mode 100644
index 9e69d3b..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/elephant_spawns.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "savanna"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "savanna"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/emu_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/emu_spawns.json
deleted file mode 100644
index 7de7826..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/emu_spawns.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "mesa"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "savanna"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/endergrade_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/endergrade_spawns.json
deleted file mode 100644
index 5d3ca68..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/endergrade_spawns.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "end"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": true,
-        "value": "minecraft:the_end"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/enderiophage_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/enderiophage_spawns.json
deleted file mode 100644
index 427b044..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/enderiophage_spawns.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "end"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": true,
-        "value": "minecraft:the_end"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": true,
-        "value": "minecraft:end_barrens"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": true,
-        "value": "minecraft:end_highlands"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": true,
-        "value": "minecraft:small_end_islands"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/fly_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/fly_spawns.json
deleted file mode 100644
index a8ddaed..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/fly_spawns.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": true,
-        "value": "ocean"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "ocean"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/frilled_shark_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/frilled_shark_spawns.json
deleted file mode 100644
index 696a296..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/frilled_shark_spawns.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:deep_ocean"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:deep_lukewarm_ocean"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:deep_cold_ocean"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:deep_frozen_ocean"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/gazelle_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/gazelle_spawns.json
deleted file mode 100644
index 9e69d3b..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/gazelle_spawns.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "savanna"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "savanna"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/gorilla_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/gorilla_spawns.json
deleted file mode 100644
index feabd66..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/gorilla_spawns.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "jungle"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": true,
-        "value": "minecraft:bamboo_jungle"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": true,
-        "value": "minecraft:bamboo_jungle_hills"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/grizzly_bear_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/grizzly_bear_spawns.json
deleted file mode 100644
index 18bc5d3..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/grizzly_bear_spawns.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "forest"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "forest"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/guster_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/guster_spawns.json
deleted file mode 100644
index 7f73edd..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/guster_spawns.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "desert"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/hammerhead_shark_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/hammerhead_shark_spawns.json
deleted file mode 100644
index 8f5ff21..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/hammerhead_shark_spawns.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "ocean"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "hot"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/hummingbird_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/hummingbird_spawns.json
deleted file mode 100644
index bb35060..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/hummingbird_spawns.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:flower_forest"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:sunflower_plains"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "jungle"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/kangaroo_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/kangaroo_spawns.json
deleted file mode 100644
index 7de7826..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/kangaroo_spawns.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "mesa"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "savanna"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/komodo_dragon_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/komodo_dragon_spawns.json
deleted file mode 100644
index c1bcd89..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/komodo_dragon_spawns.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "mesa"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/leafcutter_anthill_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/leafcutter_anthill_spawns.json
deleted file mode 100644
index feabd66..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/leafcutter_anthill_spawns.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "jungle"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": true,
-        "value": "minecraft:bamboo_jungle"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": true,
-        "value": "minecraft:bamboo_jungle_hills"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/lobster_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/lobster_spawns.json
deleted file mode 100644
index cfb150a..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/lobster_spawns.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "beach"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mantis_shrimp_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mantis_shrimp_spawns.json
deleted file mode 100644
index 8f5ff21..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mantis_shrimp_spawns.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "ocean"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "hot"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mimic_octopus_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mimic_octopus_spawns.json
deleted file mode 100644
index 5c1d0ef..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mimic_octopus_spawns.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "ocean"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "hot"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": true,
-        "value": "minecraft:deep_warm_ocean"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mimicube_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mimicube_spawns.json
deleted file mode 100644
index 5d3ca68..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mimicube_spawns.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "end"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": true,
-        "value": "minecraft:the_end"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/moose_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/moose_spawns.json
deleted file mode 100644
index dc1dd28..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/moose_spawns.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "snowy"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "wasteland"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "snowy"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "forest"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mungus_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mungus_spawns.json
deleted file mode 100644
index 927929a..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/mungus_spawns.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "mushroom"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "rare"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/orca_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/orca_spawns.json
deleted file mode 100644
index 0bcd599..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/orca_spawns.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "ocean"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "cold"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/platypus_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/platypus_spawns.json
deleted file mode 100644
index 8b1a91c..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/platypus_spawns.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "river"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "cold"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "biomesoplenty:tundra_bog"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/raccoon_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/raccoon_spawns.json
deleted file mode 100644
index ed8b56d..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/raccoon_spawns.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "savanna"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "forest"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "savanna"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "plains"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/rattlesnake_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/rattlesnake_spawns.json
deleted file mode 100644
index 3796884..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/rattlesnake_spawns.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "mesa"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "desert"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/roadrunner_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/roadrunner_spawns.json
deleted file mode 100644
index 3796884..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/roadrunner_spawns.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "mesa"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "desert"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/seal_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/seal_spawns.json
deleted file mode 100644
index cd1e2c6..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/seal_spawns.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "beach"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "ocean"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "snowy"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/shoebill_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/shoebill_spawns.json
deleted file mode 100644
index 2f80bc7..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/shoebill_spawns.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "swamp"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/snow_leopard_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/snow_leopard_spawns.json
deleted file mode 100644
index 5234f77..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/snow_leopard_spawns.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "mountain"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "snowy"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/soul_vulture_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/soul_vulture_spawns.json
deleted file mode 100644
index dcee03e..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/soul_vulture_spawns.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:soul_sand_valley"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "byg:warped_desert"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/spectre_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/spectre_spawns.json
deleted file mode 100644
index 7593141..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/spectre_spawns.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:small_end_islands"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/straddler_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/straddler_spawns.json
deleted file mode 100644
index 5708081..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/straddler_spawns.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:basalt_deltas"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/stradpole_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/stradpole_spawns.json
deleted file mode 100644
index 5708081..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/stradpole_spawns.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:basalt_deltas"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/sunbird_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/sunbird_spawns.json
deleted file mode 100644
index c0efaa4..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/sunbird_spawns.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "mountain"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tarantula_hawk_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tarantula_hawk_spawns.json
deleted file mode 100644
index 7f73edd..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tarantula_hawk_spawns.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "desert"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tasmanian_devil_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tasmanian_devil_spawns.json
deleted file mode 100644
index c0342a8..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tasmanian_devil_spawns.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "savanna"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "forest"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "cold"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": true,
-        "value": "minecraft:jungle_egde"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": true,
-        "value": "minecraft:modified_jungle_edge"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tiger_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tiger_spawns.json
deleted file mode 100644
index f62ca32..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/tiger_spawns.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:bamboo_jungle"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:bamboo_jungle_hills"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "biomesoplenty:bamboo_blossom_grove"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "biomesoplenty:cherry_blossom_grove"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/void_worm_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/void_worm_spawns.json
deleted file mode 100644
index 333b7b9..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/void_worm_spawns.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  "biomes": []
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/warped_mosco_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/warped_mosco_spawns.json
deleted file mode 100644
index 333b7b9..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/warped_mosco_spawns.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  "biomes": []
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/warped_toad_spawns.json b/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/warped_toad_spawns.json
deleted file mode 100644
index 445320d..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/alexsmobs/warped_toad_spawns.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:warped_forest"
-      }
-    ],
-    [
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "byg:crimson_garden"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/affixes.cfg b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/affixes.cfg
deleted file mode 100644
index 031011a..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/affixes.cfg
+++ /dev/null
@@ -1,212 +0,0 @@
-# Configuration file
-
-armor {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
-    I:Weight=5
-}
-
-
-armor_toughness {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
-    I:Weight=5
-}
-
-
-arrow_catcher {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 1]
-    I:Weight=1
-}
-
-
-attack_speed {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
-    I:Weight=5
-}
-
-
-cleave {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 3]
-    I:Weight=3
-}
-
-
-cold_damage {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
-    I:Weight=5
-}
-
-
-crit_chance {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 2]
-    I:Weight=2
-}
-
-
-crit_damage {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 3]
-    I:Weight=3
-}
-
-
-current_hp_damage {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 2]
-    I:Weight=2
-}
-
-
-damage_chain {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 1]
-    I:Weight=1
-}
-
-
-disengage {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 3]
-    I:Weight=3
-}
-
-
-draw_speed {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
-    I:Weight=5
-}
-
-
-eldritch_block {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 1]
-    I:Weight=1
-}
-
-
-enchantability {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 3]
-    I:Weight=3
-}
-
-
-execute {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
-    I:Weight=5
-}
-
-
-fire_damage {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
-    I:Weight=5
-}
-
-
-life_steal {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 3]
-    I:Weight=3
-}
-
-
-loot_pinata {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 2]
-    I:Weight=2
-}
-
-
-magic_arrow {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 1]
-    I:Weight=1
-}
-
-
-max_crit {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 1]
-    I:Weight=1
-}
-
-
-max_health {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
-    I:Weight=5
-}
-
-
-movement_speed {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
-    I:Weight=5
-}
-
-
-omnitool {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 2]
-    I:Weight=2
-}
-
-
-overheal {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 4]
-    I:Weight=4
-}
-
-
-piercing {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 0]
-    I:Weight=0
-}
-
-
-radius_mining {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 2]
-    I:Weight=2
-}
-
-
-reach_distance {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 3]
-    I:Weight=3
-}
-
-
-shield_damage {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 3]
-    I:Weight=3
-}
-
-
-shield_speed {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 5]
-    I:Weight=5
-}
-
-
-snare_hit {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 1]
-    I:Weight=1
-}
-
-
-snipe_damage {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 3]
-    I:Weight=3
-}
-
-
-spectral_shot {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 2]
-    I:Weight=2
-}
-
-
-spiked_shield {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 2]
-    I:Weight=2
-}
-
-
-teleport_drops {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 2]
-    I:Weight=2
-}
-
-
-torch_placement {
-    # The weight of this affix, relative to others that may apply to the same item. [range: 0 ~ 2147483647, default: 4]
-    I:Weight=4
-}
-
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/apotheosis.cfg b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/apotheosis.cfg
deleted file mode 100644
index 40dd127..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/apotheosis.cfg
+++ /dev/null
@@ -1,23 +0,0 @@
-# Configuration file
-
-general {
-    # If the deadly module is loaded. [default: true]
-    B:"Enable Deadly Module"=true
-
-    # If the enchantment module is enabled. [default: true]
-    B:"Enable Enchantment Module"=true
-
-    # If the garden module is loaded. [default: true]
-    B:"Enable Garden Module"=true
-
-    # If the potion module is loaded. [default: true]
-    B:"Enable Potion Module"=true
-
-    # If the spawner module is enabled. [default: true]
-    B:"Enable Spawner Module"=true
-
-    # If the village module is loaded. [default: true]
-    B:"Enable Village Module"=true
-}
-
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/deadly.cfg b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/deadly.cfg
deleted file mode 100644
index 8b1b5e8..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/deadly.cfg
+++ /dev/null
@@ -1,222 +0,0 @@
-# Configuration file
-
-affixes {
-    # A list of type overrides for the affix loot system.  Format is <itemname>|<type>.  Types are SWORD, RANGED, PICKAXE, SHOVEL, AXE, SHIELD [default: [minecraft:stick|SWORD]]
-    S:"Equipment Type Overrides" <
-        minecraft:stick|SWORD
-     >
-
-    # The 1/n chance that a naturally spawned mob will be granted an affix item. 0 to disable. [range: 0 ~ 500000, default: 125]
-    I:"Random Affix Chance"=250
-}
-
-
-bosses {
-    S:"Blacklisted Potions" <
-        forbidden_arcanus:spectral_vision
-     >
-    S:"Boss Filler Block"=minecraft:red_sandstone
-    I:"Boss Rarity Offset"=475
-    S:"Boss Spawner Mobs" <
-        3@minecraft:zombie
-        3@minecraft:skeleton
-        2@minecraft:husk
-        2@minecraft:stray
-        1@minecraft:wither_skeleton
-        1@minecraft:pillager
-     >
-    S:"Fire Resistance"=1.0
-    S:"Max Damage Bonus"=4.5
-    S:"Max Health Multiplier"=8.0
-    S:"Max Knockback Resist"=1.0
-    I:"Max Regen Level"=2
-    I:"Max Resistance Level"=3
-    S:"Max Speed Multiplier"=1.4
-    S:"Min Damage Bonus"=2.0
-    S:"Min Health Multiplier"=4.0
-    S:"Min Knockback Resist"=0.65
-    I:"Min Regen Level"=0
-    I:"Min Resistance Level"=0
-    S:"Min Speed Multiplier"=1.1
-    S:"Random Enchantment Chance"=0.45
-    S:"Random Potion Chance"=0.65
-
-    # The 1/n chance that a naturally spawned mob that can see the sky is transformed into a boss.  0 to disable. [range: 0 ~ 500000, default: 85]
-    I:"Surface Boss Chance"=600
-
-    # If a lightning bolt strikes when a surface boss spawn occurs. [default: true]
-    B:"Surface Boss Lightning"=true
-    S:"Water Breathing"=1.0
-}
-
-
-"brutal spawners" {
-    S:"Brutal Potion Effects" <
-        minecraft:resistance@2
-        minecraft:fire_resistance@1
-        minecraft:regeneration@1
-        minecraft:speed@2
-        minecraft:water_breathing@1
-        minecraft:strength@1
-     >
-    S:"Brutal Spawner Mobs" <
-        3@minecraft:zombie
-        3@minecraft:skeleton
-        2@minecraft:husk
-        2@minecraft:stray
-        1@minecraft:spider
-     >
-}
-
-
-frequencies {
-    S:"Boss Chance"=0.07
-    S:"Brutal Spawner Chance"=0.18
-    S:"Swarm Spawner Chance"=0.2
-}
-
-
-frequency {
-    # The number of generation attempts (per chunk) for boss dungeons. [range: 0 ~ 50000, default: 8]
-    I:"Boss Dungeon"=8
-
-    # The number of generation attempts (per chunk) for boss dungeon variant 2. [range: 0 ~ 50000, default: 8]
-    I:"Boss Dungeon Variant 2"=8
-
-    # The number of generation attempts (per chunk) for ore troves. [range: 0 ~ 50000, default: 8]
-    I:"Ore Troves"=8
-
-    # The number of generation attempts (per chunk) for rogue spawners. [range: 0 ~ 50000, default: 4]
-    I:"Rogue Spawners"=4
-
-    # The 1/n chance (per chunk) that a tome tower may attempt generation. 0 = disabled, lower = more chances. [range: 0 ~ 50000, default: 125]
-    I:"Tome Tower"=125
-}
-
-
-general {
-    # The biomes that the deadly module will not generate in. [default: [minecraft:warm_ocean], [minecraft:lukewarm_ocean], [minecraft:cold_ocean], [minecraft:frozen_ocean], [minecraft:deep_warm_ocean], [minecraft:deep_frozen_ocean], [minecraft:deep_lukewarm_ocean], [minecraft:deep_cold_ocean], [minecraft:ocean], [minecraft:deep_ocean]]
-    S:"Generation Biome Blacklist" <
-        minecraft:warm_ocean
-        minecraft:lukewarm_ocean
-        minecraft:cold_ocean
-        minecraft:frozen_ocean
-        minecraft:deep_warm_ocean
-        minecraft:deep_frozen_ocean
-        minecraft:deep_lukewarm_ocean
-        minecraft:deep_cold_ocean
-        minecraft:ocean
-        minecraft:deep_ocean
-     >
-
-    # The dimensions that the deadly module will generate in. [default: [overworld]]
-    S:"Generation Dimension Whitelist" <
-        overworld
-     >
-
-    # The 1/n chance that a rogue spawner will generate with a CHEST_VALUABLE instead of it's default chest.  0 to disable. [range: 0 ~ 80000, default: 9]
-    I:"Spawner Rare Loot Chance"=9
-}
-
-
-"random spawners" {
-    I:"alexsmobs:bone_serpent"=1
-    I:"alexsmobs:bone_serpent_part"=1
-    I:"alexsmobs:guster"=1
-    I:"alexsmobs:mimicube"=1
-    I:"alexsmobs:soul_vulture"=1
-    I:"alexsmobs:straddler"=1
-    I:"alexsmobs:warped_mosco"=1
-    I:"artifacts:mimic"=1
-    I:"minecraft:blaze"=8
-    I:"minecraft:cave_spider"=8
-    I:"minecraft:creeper"=8
-    I:"minecraft:drowned"=8
-    I:"minecraft:elder_guardian"=8
-    I:"minecraft:ender_dragon"=8
-    I:"minecraft:enderman"=8
-    I:"minecraft:endermite"=8
-    I:"minecraft:evoker"=8
-    I:"minecraft:ghast"=8
-    I:"minecraft:giant"=8
-    I:"minecraft:guardian"=8
-    I:"minecraft:hoglin"=8
-    I:"minecraft:husk"=8
-    I:"minecraft:illusioner"=8
-    I:"minecraft:magma_cube"=8
-    I:"minecraft:phantom"=8
-    I:"minecraft:piglin"=8
-    I:"minecraft:piglin_brute"=8
-    I:"minecraft:pillager"=8
-    I:"minecraft:ravager"=8
-    I:"minecraft:shulker"=8
-    I:"minecraft:silverfish"=8
-    I:"minecraft:skeleton"=8
-    I:"minecraft:slime"=8
-    I:"minecraft:spider"=8
-    I:"minecraft:stray"=8
-    I:"minecraft:vex"=8
-    I:"minecraft:vindicator"=8
-    I:"minecraft:witch"=8
-    I:"minecraft:wither"=8
-    I:"minecraft:wither_skeleton"=8
-    I:"minecraft:zoglin"=8
-    I:"minecraft:zombie"=8
-    I:"minecraft:zombie_villager"=8
-    I:"minecraft:zombified_piglin"=8
-    I:"quark:forgotten"=1
-    I:"quark:wraith"=1
-    I:"quark:wrapped"=1
-    I:"undergarden:brute"=1
-    I:"undergarden:forgotten_guardian"=1
-    I:"undergarden:masticator"=1
-    I:"undergarden:muncher"=1
-    I:"undergarden:nargoyle"=1
-    I:"undergarden:rotbeast"=1
-    I:"undergarden:rotdweller"=1
-    I:"undergarden:rotling"=1
-    I:"undergarden:rotwalker"=1
-    I:"undergarden:sploogie"=1
-    I:"undergarden:stoneborn"=1
-}
-
-
-"spawner stats: brutal spawners" {
-    I:"Max Delay"=400
-    I:"Max Nearby Entities"=6
-    I:"Min Delay"=200
-    I:"Player Range"=16
-    I:"Spawn Count"=6
-    I:"Spawn Delay"=20
-    I:"Spawn Range"=4
-}
-
-
-"spawner stats: swarm spawners" {
-    I:"Max Delay"=300
-    I:"Max Nearby Entities"=32
-    I:"Min Delay"=75
-    I:"Player Range"=8
-    I:"Spawn Count"=8
-    I:"Spawn Delay"=20
-    I:"Spawn Range"=6
-}
-
-
-"swarm spawners" {
-    S:"Swarm Spawner Mobs" <
-        4@minecraft:zombie
-        2@minecraft:skeleton
-        5@minecraft:spider
-        8@minecraft:cave_spider
-        1@minecraft:creeper
-     >
-}
-
-
-wanderer {
-    # If the wandering trader may sell affix loot items as a rare trade. [default: true]
-    B:"Affix Trades"=true
-}
-
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/enchantments.cfg b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/enchantments.cfg
deleted file mode 100644
index 0144ba8..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/enchantments.cfg
+++ /dev/null
@@ -1,1007 +0,0 @@
-# Configuration file
-
-"alexsmobs:board_return" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"alexsmobs:lavawax" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"alexsmobs:serpentfriend" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"alexsmobs:straddle_jump" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 7]
-    I:"Max Level"=7
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:bane_of_illagers" {
-    # The max level of this enchantment - normally 5. [range: 1 ~ 127, default: 10]
-    I:"Max Level"=10
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:berserk" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 4]
-    I:"Max Level"=4
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:capturing" {
-    # The max level of this enchantment - normally 5. [range: 1 ~ 127, default: 7]
-    I:"Max Level"=7
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:crescendo" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 5]
-    I:"Max Level"=5
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:depth_miner" {
-    # The max level of this enchantment - normally 5. [range: 1 ~ 127, default: 5]
-    I:"Max Level"=5
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:hell_infusion" {
-    # The max level of this enchantment - normally 5. [range: 1 ~ 127, default: 7]
-    I:"Max Level"=7
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:icy_thorns" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 4]
-    I:"Max Level"=4
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:knowledge" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 4]
-    I:"Max Level"=4
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:life_mending" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 4]
-    I:"Max Level"=4
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:magic_protection" {
-    # The max level of this enchantment - normally 4. [range: 1 ~ 127, default: 5]
-    I:"Max Level"=5
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:natures_blessing" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 7]
-    I:"Max Level"=7
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:obliteration" {
-    # The max level of this enchantment - normally 5. [range: 1 ~ 127, default: 9]
-    I:"Max Level"=9
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:rebounding" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 6]
-    I:"Max Level"=6
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:reflective" {
-    # The max level of this enchantment - normally 5. [range: 1 ~ 127, default: 7]
-    I:"Max Level"=7
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:scavenger" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 3]
-    I:"Max Level"=3
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:sea_infusion" {
-    # The max level of this enchantment - normally 5. [range: 1 ~ 127, default: 7]
-    I:"Max Level"=7
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:shield_bash" {
-    # The max level of this enchantment - normally 4. [range: 1 ~ 127, default: 7]
-    I:"Max Level"=7
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:splitting" {
-    # The max level of this enchantment - normally 5. [range: 1 ~ 127, default: 9]
-    I:"Max Level"=9
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:stable_footing" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:tempting" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"apotheosis:true_infinity" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"create:capacity" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 7]
-    I:"Max Level"=7
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"create:potato_recovery" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 7]
-    I:"Max Level"=7
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:aqua_affinity" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:bane_of_arthropods" {
-    # The max level of this enchantment - normally 5. [range: 1 ~ 127, default: 10]
-    I:"Max Level"=10
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:binding_curse" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:blast_protection" {
-    # The max level of this enchantment - normally 4. [range: 1 ~ 127, default: 8]
-    I:"Max Level"=8
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:channeling" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:depth_strider" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 7]
-    I:"Max Level"=7
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:efficiency" {
-    # The max level of this enchantment - normally 5. [range: 1 ~ 127, default: 9]
-    I:"Max Level"=9
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:feather_falling" {
-    # The max level of this enchantment - normally 4. [range: 1 ~ 127, default: 8]
-    I:"Max Level"=8
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:fire_aspect" {
-    # The max level of this enchantment - normally 2. [range: 1 ~ 127, default: 5]
-    I:"Max Level"=5
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:fire_protection" {
-    # The max level of this enchantment - normally 4. [range: 1 ~ 127, default: 8]
-    I:"Max Level"=8
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:flame" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:fortune" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 7]
-    I:"Max Level"=7
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:frost_walker" {
-    # The max level of this enchantment - normally 2. [range: 1 ~ 127, default: 6]
-    I:"Max Level"=6
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:impaling" {
-    # The max level of this enchantment - normally 5. [range: 1 ~ 127, default: 10]
-    I:"Max Level"=10
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:infinity" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:knockback" {
-    # The max level of this enchantment - normally 2. [range: 1 ~ 127, default: 5]
-    I:"Max Level"=5
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:looting" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 7]
-    I:"Max Level"=7
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:loyalty" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 8]
-    I:"Max Level"=8
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:luck_of_the_sea" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 7]
-    I:"Max Level"=7
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:lure" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 7]
-    I:"Max Level"=7
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:mending" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:multishot" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:piercing" {
-    # The max level of this enchantment - normally 4. [range: 1 ~ 127, default: 8]
-    I:"Max Level"=8
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:power" {
-    # The max level of this enchantment - normally 5. [range: 1 ~ 127, default: 9]
-    I:"Max Level"=9
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:projectile_protection" {
-    # The max level of this enchantment - normally 4. [range: 1 ~ 127, default: 8]
-    I:"Max Level"=8
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:protection" {
-    # The max level of this enchantment - normally 4. [range: 1 ~ 127, default: 8]
-    I:"Max Level"=8
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:punch" {
-    # The max level of this enchantment - normally 2. [range: 1 ~ 127, default: 5]
-    I:"Max Level"=5
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:quick_charge" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 5]
-    I:"Max Level"=5
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:respiration" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 7]
-    I:"Max Level"=7
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:riptide" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 8]
-    I:"Max Level"=8
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:sharpness" {
-    # The max level of this enchantment - normally 5. [range: 1 ~ 127, default: 9]
-    I:"Max Level"=9
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:silk_touch" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:smite" {
-    # The max level of this enchantment - normally 5. [range: 1 ~ 127, default: 10]
-    I:"Max Level"=10
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:soul_speed" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 7]
-    I:"Max Level"=7
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:sweeping" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 8]
-    I:"Max Level"=8
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:thorns" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 5]
-    I:"Max Level"=5
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:unbreaking" {
-    # The max level of this enchantment - normally 3. [range: 1 ~ 127, default: 8]
-    I:"Max Level"=8
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"minecraft:vanishing_curse" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"passablefoliage:leaf_walker" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
-"the_bumblezone:comb_cutter" {
-    # The max level of this enchantment - normally 1. [range: 1 ~ 127, default: 1]
-    I:"Max Level"=1
-
-    # A function to determine the max enchanting power.  The variable "x" is level.  See: https://github.com/uklimaschewski/EvalEx#usage-examples [default: ]
-    S:"Max Power Function"=
-
-    # The min level of this enchantment. [range: 1 ~ 127, default: 1]
-    I:"Min Level"=1
-
-    # A function to determine the min enchanting power. [default: ]
-    S:"Min Power Function"=
-}
-
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/garden.cfg b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/garden.cfg
deleted file mode 100644
index 14160db..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/garden.cfg
+++ /dev/null
@@ -1,14 +0,0 @@
-# Configuration file
-
-general {
-    # The max height a stack of bamboo may grow to.  Vanilla is 16. [range: 1 ~ 255, default: 32]
-    I:"Bamboo Height"=16
-
-    # The max height a stack of cacti may grow to.  Vanilla is 3. [range: 1 ~ 255, default: 5]
-    I:"Cactus Height"=5
-
-    # The max height a stack of reeds may grow to.  Vanilla is 3. [range: 1 ~ 255, default: 255]
-    I:"Reed Height"=5
-}
-
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/names.cfg b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/names.cfg
deleted file mode 100644
index 127f4c8..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/names.cfg
+++ /dev/null
@@ -1,1198 +0,0 @@
-# Configuration file
-
-armors {
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: byg:ametrine_helmet, byg:ametrine_chestplate, byg:ametrine_leggings, byg:ametrine_boots
-    #  [default: ]
-    S:AMETRINE <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: minecraft:chainmail_helmet, minecraft:chainmail_chestplate, minecraft:chainmail_leggings, minecraft:chainmail_boots
-    #  [default: [Chainmail], [Chain], [Chain Link], [Scale]]
-    S:CHAIN <
-        Chainmail
-        Chain
-        Chain Link
-        Scale
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: undergarden:cloggrum_helmet, undergarden:cloggrum_chestplate, undergarden:cloggrum_leggings, undergarden:cloggrum_boots
-    #  [default: ]
-    S:CLOGGRUM <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: create:copper_backtank, create:diving_helmet, create:diving_boots
-    #  [default: ]
-    S:COPPER <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: minecraft:diamond_helmet, minecraft:diamond_chestplate, minecraft:diamond_leggings, minecraft:diamond_boots
-    #  [default: [Diamond], [Zircon], [Gemstone], [Jewel], [Crystal]]
-    S:DIAMOND <
-        Diamond
-        Zircon
-        Gemstone
-        Jewel
-        Crystal
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: undergarden:froststeel_helmet, undergarden:froststeel_chestplate, undergarden:froststeel_leggings, undergarden:froststeel_boots
-    #  [default: ]
-    S:FROSTSTEEL <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: minecraft:golden_helmet, minecraft:golden_chestplate, minecraft:golden_leggings, minecraft:golden_boots
-    #  [default: [Golden], [Gold], [Gilt], [Auric], [Ornate]]
-    S:GOLD <
-        Golden
-        Gold
-        Gilt
-        Auric
-        Ornate
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: minecraft:iron_helmet, minecraft:iron_chestplate, minecraft:iron_leggings, minecraft:iron_boots
-    #  [default: [Iron], [Steel], [Ferrous], [Rusty], [Wrought Iron]]
-    S:IRON <
-        Iron
-        Steel
-        Ferrous
-        Rusty
-        Wrought Iron
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: minecraft:leather_helmet, minecraft:leather_chestplate, minecraft:leather_leggings, minecraft:leather_boots, quark:forgotten_hat, quark:backpack
-    #  [default: [Leather], [Rawhide], [Lamellar], [Cow Skin]]
-    S:LEATHER <
-        Leather
-        Rawhide
-        Lamellar
-        Cow Skin
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: undergarden:masticated_chestplate
-    #  [default: ]
-    S:MASTICATED <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: minecraft:netherite_helmet, minecraft:netherite_chestplate, minecraft:netherite_leggings, minecraft:netherite_boots
-    #  [default: [Burnt], [Embered], [Fiery], [Hellborn], [Flameforged]]
-    S:NETHERITE <
-        Burnt
-        Embered
-        Fiery
-        Hellborn
-        Flameforged
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: minecraft:turtle_helmet
-    #  [default: [Tortollan], [Very Tragic], [Environmental], [Organic]]
-    S:TURTLE <
-        Tortollan
-        Very Tragic
-        Environmental
-        Organic
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: undergarden:utheric_helmet, undergarden:utheric_chestplate, undergarden:utheric_leggings, undergarden:utheric_boots
-    #  [default: ]
-    S:UTHERIC <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: alexsmobs:centipede_leggings
-    #  [default: ]
-    S:alexsmobs_centipede_leggings <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: alexsmobs:crocodile_chestplate
-    #  [default: ]
-    S:alexsmobs_crocodile_chestplate <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: alexsmobs:emu_leggings
-    #  [default: ]
-    S:alexsmobs_emu_leggings <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: alexsmobs:fedora
-    #  [default: ]
-    S:alexsmobs_fedora <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: alexsmobs:frontier_cap
-    #  [default: ]
-    S:alexsmobs_frontier_cap <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: alexsmobs:moose_headgear
-    #  [default: ]
-    S:alexsmobs_moose_headgear <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: alexsmobs:roadrunner_boots
-    #  [default: ]
-    S:alexsmobs_roadrunner_boots <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: alexsmobs:sombrero
-    #  [default: ]
-    S:alexsmobs_sombrero <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: alexsmobs:spiked_turtle_shell
-    #  [default: ]
-    S:alexsmobs_spiked_turtle_shell <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: alexsmobs:tarantula_hawk_elytra
-    #  [default: ]
-    S:alexsmobs_tarantula_hawk_elytra <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:armor_amythest_helmet, iceandfire:armor_amythest_chestplate, iceandfire:armor_amythest_leggings, iceandfire:armor_amythest_boots
-    #  [default: ]
-    S:iceandfire_armor_amythest_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:armor_black_helmet, iceandfire:armor_black_chestplate, iceandfire:armor_black_leggings, iceandfire:armor_black_boots
-    #  [default: ]
-    S:iceandfire_armor_black_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:armor_blue_helmet, iceandfire:armor_blue_chestplate, iceandfire:armor_blue_leggings, iceandfire:armor_blue_boots
-    #  [default: ]
-    S:iceandfire_armor_blue_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:armor_bronze_helmet, iceandfire:armor_bronze_chestplate, iceandfire:armor_bronze_leggings, iceandfire:armor_bronze_boots
-    #  [default: ]
-    S:iceandfire_armor_bronze_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:armor_copper_helmet, iceandfire:armor_copper_chestplate, iceandfire:armor_copper_leggings, iceandfire:armor_copper_boots
-    #  [default: ]
-    S:iceandfire_armor_copper_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:armor_copper_metal_helmet, iceandfire:armor_copper_metal_chestplate, iceandfire:armor_copper_metal_leggings, iceandfire:armor_copper_metal_boots
-    #  [default: ]
-    S:iceandfire_armor_copper_metal_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:armor_electric_helmet, iceandfire:armor_electric_chestplate, iceandfire:armor_electric_leggings, iceandfire:armor_electric_boots
-    #  [default: ]
-    S:iceandfire_armor_electric_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:armor_gray_helmet, iceandfire:armor_gray_chestplate, iceandfire:armor_gray_leggings, iceandfire:armor_gray_boots
-    #  [default: ]
-    S:iceandfire_armor_gray_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:armor_green_helmet, iceandfire:armor_green_chestplate, iceandfire:armor_green_leggings, iceandfire:armor_green_boots
-    #  [default: ]
-    S:iceandfire_armor_green_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:armor_red_helmet, iceandfire:armor_red_chestplate, iceandfire:armor_red_leggings, iceandfire:armor_red_boots
-    #  [default: ]
-    S:iceandfire_armor_red_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:armor_sapphire_helmet, iceandfire:armor_sapphire_chestplate, iceandfire:armor_sapphire_leggings, iceandfire:armor_sapphire_boots
-    #  [default: ]
-    S:iceandfire_armor_sapphire_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:armor_silver_helmet, iceandfire:armor_silver_chestplate, iceandfire:armor_silver_leggings, iceandfire:armor_silver_boots
-    #  [default: ]
-    S:iceandfire_armor_silver_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:armor_silver_metal_helmet, iceandfire:armor_silver_metal_chestplate, iceandfire:armor_silver_metal_leggings, iceandfire:armor_silver_metal_boots
-    #  [default: ]
-    S:iceandfire_armor_silver_metal_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:armor_white_helmet, iceandfire:armor_white_chestplate, iceandfire:armor_white_leggings, iceandfire:armor_white_boots
-    #  [default: ]
-    S:iceandfire_armor_white_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:blindfold
-    #  [default: ]
-    S:iceandfire_blindfold <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:deathworm_red_helmet, iceandfire:deathworm_red_chestplate, iceandfire:deathworm_red_leggings, iceandfire:deathworm_red_boots
-    #  [default: ]
-    S:iceandfire_deathworm_red_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:deathworm_white_helmet, iceandfire:deathworm_white_chestplate, iceandfire:deathworm_white_leggings, iceandfire:deathworm_white_boots
-    #  [default: ]
-    S:iceandfire_deathworm_white_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:deathworm_yellow_helmet, iceandfire:deathworm_yellow_chestplate, iceandfire:deathworm_yellow_leggings, iceandfire:deathworm_yellow_boots
-    #  [default: ]
-    S:iceandfire_deathworm_yellow_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:dragonsteel_fire_helmet, iceandfire:dragonsteel_fire_chestplate, iceandfire:dragonsteel_fire_leggings, iceandfire:dragonsteel_fire_boots
-    #  [default: ]
-    S:iceandfire_dragonsteel_fire_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:dragonsteel_ice_helmet, iceandfire:dragonsteel_ice_chestplate, iceandfire:dragonsteel_ice_leggings, iceandfire:dragonsteel_ice_boots
-    #  [default: ]
-    S:iceandfire_dragonsteel_ice_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:dragonsteel_lightning_helmet, iceandfire:dragonsteel_lightning_chestplate, iceandfire:dragonsteel_lightning_leggings, iceandfire:dragonsteel_lightning_boots
-    #  [default: ]
-    S:iceandfire_dragonsteel_lightning_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:earplugs
-    #  [default: ]
-    S:iceandfire_earplugs <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:forest_troll_leather_helmet, iceandfire:forest_troll_leather_chestplate, iceandfire:forest_troll_leather_leggings, iceandfire:forest_troll_leather_boots
-    #  [default: ]
-    S:iceandfire_forest_troll_leather_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:frost_troll_leather_helmet, iceandfire:frost_troll_leather_chestplate, iceandfire:frost_troll_leather_leggings, iceandfire:frost_troll_leather_boots
-    #  [default: ]
-    S:iceandfire_frost_troll_leather_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:mountain_troll_leather_helmet, iceandfire:mountain_troll_leather_chestplate, iceandfire:mountain_troll_leather_leggings, iceandfire:mountain_troll_leather_boots
-    #  [default: ]
-    S:iceandfire_mountain_troll_leather_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:myrmex_desert_helmet, iceandfire:myrmex_desert_chestplate, iceandfire:myrmex_desert_leggings, iceandfire:myrmex_desert_boots
-    #  [default: ]
-    S:iceandfire_myrmex_desert_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:myrmex_jungle_helmet, iceandfire:myrmex_jungle_chestplate, iceandfire:myrmex_jungle_leggings, iceandfire:myrmex_jungle_boots
-    #  [default: ]
-    S:iceandfire_myrmex_jungle_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:sheep_helmet, iceandfire:sheep_chestplate, iceandfire:sheep_leggings, iceandfire:sheep_boots
-    #  [default: ]
-    S:iceandfire_sheep_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:tide_blue_helmet, iceandfire:tide_blue_chestplate, iceandfire:tide_blue_leggings, iceandfire:tide_blue_boots
-    #  [default: ]
-    S:iceandfire_tide_blue_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:tide_bronze_helmet, iceandfire:tide_bronze_chestplate, iceandfire:tide_bronze_leggings, iceandfire:tide_bronze_boots
-    #  [default: ]
-    S:iceandfire_tide_bronze_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:tide_deepblue_helmet, iceandfire:tide_deepblue_chestplate, iceandfire:tide_deepblue_leggings, iceandfire:tide_deepblue_boots
-    #  [default: ]
-    S:iceandfire_tide_deepblue_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:tide_green_helmet, iceandfire:tide_green_chestplate, iceandfire:tide_green_leggings, iceandfire:tide_green_boots
-    #  [default: ]
-    S:iceandfire_tide_green_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:tide_purple_helmet, iceandfire:tide_purple_chestplate, iceandfire:tide_purple_leggings, iceandfire:tide_purple_boots
-    #  [default: ]
-    S:iceandfire_tide_purple_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:tide_red_helmet, iceandfire:tide_red_chestplate, iceandfire:tide_red_leggings, iceandfire:tide_red_boots
-    #  [default: ]
-    S:iceandfire_tide_red_helmet <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:tide_teal_helmet, iceandfire:tide_teal_chestplate, iceandfire:tide_teal_leggings, iceandfire:tide_teal_boots
-    #  [default: ]
-    S:iceandfire_tide_teal_helmet <
-     >
-}
-
-
-entity {
-    # A list of name pieces, which can be spliced together to create full names.  May be empty only if names is not empty. [default: [Dark], [Osto], [Grab], [Thar], [Ger], [Ald], [Mas], [On], [O], [Din], [Thor], [Jon], [Ath], [Burb], [En], [A], [E], [I], [U], [Hab], [Bloo], [Ena], [Dit], [Aph], [Ern], [Bor], [Dav], [Id], [Toast], [Son], [Dottir], [For], [Wen], [Lob], [Ed], [Die], [Van], [Y], [Zap], [Ear], [Ben], [Don], [Bran], [Gro], [Jen], [Bob], [Ette], [Ere], [Man], [Qua], [Bro], [Cree], [Per], [Skel], [Ton], [Zom], [Bie], [Wolf], [End], [Er], [Pig], [Sil], [Ver], [Fish], [Cow], [Chic], [Ken], [Sheep], [Squid], [Hell]]
-    S:"Name Parts" <
-        Grab
-        Thar
-        Ger
-        Ald
-        Mas
-        On
-        O
-        Din
-        Thor
-        Jon
-        Ath
-        Burb
-        En
-        A
-        E
-        I
-        U
-        Hab
-        Bloo
-        Ena
-        Dit
-        Aph
-        Ern
-        Bor
-        Dav
-        Id
-        Toast
-        Son
-        Dottir
-        For
-        Wen
-        Lob
-        Ed
-        Die
-        Van
-        Y
-        Zap
-        Ear
-        Ben
-        Don
-        Bran
-        Gro
-        Jen
-        Bob
-        Ette
-        Ere
-        Man
-        Qua
-        Bro
-        Cree
-        Per
-        Skel
-        Ton
-        Zom
-        Bie
-        Wolf
-        End
-        Er
-        Pig
-        Sil
-        Ver
-        Fish
-        Cow
-        Chic
-        Ken
-        Sheep
-        Squid
-        Hell
-     >
-
-    # A list of full names, which are used in the generation of boss names. May be empty only if name parts is not empty. [default: [Darko], [Shadows], [Kat], [Jank], [Albert], [Andrew], [Anderson], [Andy], [Allan], [Arthur], [Aaron], [Allison], [Arielle], [Amanda], [Anne], [Annie], [Amy], [Alana], [Brandon], [Brady], [Bernard], [Ben], [Benjamin], [Bob], [Bobette], [Brooke], [Brandy], [Beatrice], [Bea], [Bella], [Becky], [Carlton], [Carl], [Calvin], [Cameron], [Carson], [Chase], [Cassandra], [Cassie], [Cas], [Carol], [Carly], [Cherise], [Charlotte], [Cheryl], [Chasity], [Danny], [Drake], [Daniel], [Derrel], [David], [Dave], [Donovan], [Don], [Donald], [Drew], [Derrick], [Darla], [Donna], [Dora], [Danielle], [Edward], [Elliot], [Ed], [Edson], [Elton], [Eddison], [Earl], [Eric], [Ericson], [Eddie], [Ediovany], [Emma], [Elizabeth], [Eliza], [Esperanza], [Esper], [Esmeralda], [Emi], [Emily], [Elaine], [Fernando], [Ferdinand], [Fred], [Feddie], [Fredward], [Frank], [Franklin], [Felix], [Felicia], [Fran], [Greg], [Gregory], [George], [Gerald], [Gina], [Geraldine], [Gabby], [Hendrix], [Henry], [Hobbes], [Herbert], [Heath], [Henderson], [Helga], [Hera], [Helen], [Helena], [Hannah], [Ike], [Issac], [Israel], [Ismael], [Irlanda], [Isabelle], [Irene], [Irenia], [Jimmy], [Jim], [Justin], [Jacob], [Jake], [Jon], [Johnson], [Jonny], [Jonathan], [Josh], [Joshua], [Julian], [Jesus], [Jericho], [Jeb], [Jess], [Joan], [Jill], [Jillian], [Jessica], [Jennifer], [Jenny], [Jen], [Judy], [Kenneth], [Kenny], [Ken], [Keith], [Kevin], [Karen], [Kassandra], [Kassie], [Leonard], [Leo], [Leroy], [Lee], [Lenny], [Luke], [Lucas], [Liam], [Lorraine], [Latasha], [Lauren], [Laquisha], [Livia], [Lydia], [Lila], [Lilly], [Lillian], [Lilith], [Lana], [Mason], [Mike], [Mickey], [Mario], [Manny], [Mark], [Marcus], [Martin], [Marty], [Matthew], [Matt], [Max], [Maximillian], [Marth], [Mia], [Marriah], [Maddison], [Maddie], [Marissa], [Miranda], [Mary], [Martha], [Melonie], [Melody], [Mel], [Minnie], [Nathan], [Nathaniel], [Nate], [Ned], [Nick], [Norman], [Nicholas], [Natasha], [Nicki], [Nora], [Nelly], [Nina], [Orville], [Oliver], [Orlando], [Owen], [Olsen], [Odin], [Olaf], [Ortega], [Olivia], [Patrick], [Pat], [Paul], [Perry], [Pinnochio], [Patrice], [Patricia], [Pennie], [Petunia], [Patti], [Pernelle], [Quade], [Quincy], [Quentin], [Quinn], [Roberto], [Robbie], [Rob], [Robert], [Roy], [Roland], [Ronald], [Richard], [Rick], [Ricky], [Rose], [Rosa], [Rhonda], [Rebecca], [Roberta], [Sparky], [Shiloh], [Stephen], [Steve], [Saul], [Sheen], [Shane], [Sean], [Sampson], [Samuel], [Sammy], [Stefan], [Sasha], [Sam], [Susan], [Suzy], [Shelby], [Samantha], [Sheila], [Sharon], [Sally], [Stephanie], [Sandra], [Sandy], [Sage], [Tim], [Thomas], [Thompson], [Tyson], [Tyler], [Tom], [Tyrone], [Timmothy], [Tamara], [Tabby], [Tabitha], [Tessa], [Tiara], [Tyra], [Uriel], [Ursala], [Uma], [Victor], [Vincent], [Vince], [Vance], [Vinny], [Velma], [Victoria], [Veronica], [Wilson], [Wally], [Wallace], [Will], [Wilard], [William], [Wilhelm], [Xavier], [Xandra], [Young], [Yvonne], [Yolanda], [Zach], [Zachary]]
-    S:Names <
-        Albert
-        Andrew
-        Anderson
-        Andy
-        Allan
-        Arthur
-        Aaron
-        Allison
-        Arielle
-        Amanda
-        Anne
-        Annie
-        Amy
-        Alana
-        Brandon
-        Brady
-        Bernard
-        Ben
-        Benjamin
-        Bob
-        Bobette
-        Brooke
-        Brandy
-        Beatrice
-        Bea
-        Bella
-        Becky
-        Carlton
-        Carl
-        Calvin
-        Cameron
-        Carson
-        Chase
-        Cassandra
-        Cassie
-        Cas
-        Carol
-        Carly
-        Cherise
-        Charlotte
-        Cheryl
-        Chasity
-        Danny
-        Drake
-        Daniel
-        Derrel
-        David
-        Dave
-        Donovan
-        Don
-        Donald
-        Drew
-        Derrick
-        Darla
-        Donna
-        Dora
-        Danielle
-        Edward
-        Elliot
-        Ed
-        Edson
-        Elton
-        Eddison
-        Earl
-        Eric
-        Ericson
-        Eddie
-        Ediovany
-        Emma
-        Elizabeth
-        Eliza
-        Esperanza
-        Esper
-        Esmeralda
-        Emi
-        Emily
-        Elaine
-        Fernando
-        Ferdinand
-        Fred
-        Feddie
-        Fredward
-        Frank
-        Franklin
-        Felix
-        Felicia
-        Fran
-        Greg
-        Gregory
-        George
-        Gerald
-        Gina
-        Geraldine
-        Gabby
-        Hendrix
-        Henry
-        Hobbes
-        Herbert
-        Heath
-        Henderson
-        Helga
-        Hera
-        Helen
-        Helena
-        Hannah
-        Ike
-        Issac
-        Israel
-        Ismael
-        Irlanda
-        Isabelle
-        Irene
-        Irenia
-        Jimmy
-        Jim
-        Justin
-        Jacob
-        Jake
-        Jon
-        Johnson
-        Jonny
-        Jonathan
-        Josh
-        Joshua
-        Julian
-        Jesus
-        Jericho
-        Jeb
-        Jess
-        Joan
-        Jill
-        Jillian
-        Jessica
-        Jennifer
-        Jenny
-        Jen
-        Judy
-        Kenneth
-        Kenny
-        Ken
-        Keith
-        Kevin
-        Karen
-        Kassandra
-        Kassie
-        Leonard
-        Leo
-        Leroy
-        Lee
-        Lenny
-        Luke
-        Lucas
-        Liam
-        Lorraine
-        Latasha
-        Lauren
-        Laquisha
-        Livia
-        Lydia
-        Lila
-        Lilly
-        Lillian
-        Lilith
-        Lana
-        Mason
-        Mike
-        Mickey
-        Mario
-        Manny
-        Mark
-        Marcus
-        Martin
-        Marty
-        Matthew
-        Matt
-        Max
-        Maximillian
-        Marth
-        Mia
-        Marriah
-        Maddison
-        Maddie
-        Marissa
-        Miranda
-        Mary
-        Martha
-        Melonie
-        Melody
-        Mel
-        Minnie
-        Nathan
-        Nathaniel
-        Nate
-        Ned
-        Nick
-        Norman
-        Nicholas
-        Natasha
-        Nicki
-        Nora
-        Nelly
-        Nina
-        Orville
-        Oliver
-        Orlando
-        Owen
-        Olsen
-        Odin
-        Olaf
-        Ortega
-        Olivia
-        Patrick
-        Pat
-        Paul
-        Perry
-        Pinnochio
-        Patrice
-        Patricia
-        Pennie
-        Petunia
-        Patti
-        Pernelle
-        Quade
-        Quincy
-        Quentin
-        Quinn
-        Roberto
-        Robbie
-        Rob
-        Robert
-        Roy
-        Roland
-        Ronald
-        Richard
-        Rick
-        Ricky
-        Rose
-        Rosa
-        Rhonda
-        Rebecca
-        Roberta
-        Sparky
-        Shiloh
-        Stephen
-        Steve
-        Saul
-        Sheen
-        Shane
-        Sean
-        Sampson
-        Samuel
-        Sammy
-        Stefan
-        Sasha
-        Sam
-        Susan
-        Suzy
-        Shelby
-        Samantha
-        Sheila
-        Sharon
-        Sally
-        Stephanie
-        Sandra
-        Sandy
-        Sage
-        Tim
-        Thomas
-        Thompson
-        Tyson
-        Tyler
-        Tom
-        Tyrone
-        Timmothy
-        Tamara
-        Tabby
-        Tabitha
-        Tessa
-        Tiara
-        Tyra
-        Uriel
-        Ursala
-        Uma
-        Victor
-        Vincent
-        Vince
-        Vance
-        Vinny
-        Velma
-        Victoria
-        Veronica
-        Wilson
-        Wally
-        Wallace
-        Will
-        Wilard
-        William
-        Wilhelm
-        Xavier
-        Xandra
-        Young
-        Yvonne
-        Yolanda
-        Zach
-        Zachary
-     >
-
-    # A list of prefixes, which are used in the generation of boss names. May be empty. [default: [Sir], [Mister], [Madam], [Doctor], [Father], [Mother], [Poppa]]
-    S:Prefixes <
-        Sir
-        Mister
-        Madam
-        Doctor
-        Father
-        Mother
-     >
-
-    # A list of suffixes, which are used in the generation of boss names. A suffix is always preceeded by "The". May be empty. [default: [Mighty], [Supreme], [Superior], [Ultimate], [Lame], [Wimpy], [Curious], [Sneaky], [Pathetic], [Crying], [Eagle], [Errant], [Unholy], [Questionable], [Mean], [Hungry], [Thirsty], [Feeble], [Wise], [Sage], [Magical], [Mythical], [Legendary], [Not Very Nice], [Jerk], [Doctor], [Misunderstood], [Angry], [Knight], [Bishop], [Godly], [Special], [Toasty], [Shiny], [Shimmering], [Light], [Dark], [Odd-Smelling], [Funky], [Rock Smasher], [Son of Herobrine], [Cracked], [Sticky], [§kAlien§r], [Baby], [Manly], [Rough], [Scary], [Undoubtable], [Honest], [Non-Suspicious], [Boring], [Odd], [Lazy], [Super], [Nifty], [Ogre Slayer], [Pig Thief], [Dirt Digger], [Really Cool], [Doominator], [... Something], [Extra-Fishy], [Gorilla Slaughterer], [Marbles Winner]]
-    S:Suffixes <
-        Mighty
-        Supreme
-        Superior
-        Ultimate
-        Lame
-        Wimpy
-        Curious
-        Sneaky
-        Pathetic
-        Crying
-        Eagle
-        Errant
-        Unholy
-        Questionable
-        Mean
-        Hungry
-        Thirsty
-        Feeble
-        Wise
-        Sage
-        Magical
-        Mythical
-        Legendary
-        Not Very Nice
-        Jerk
-        Doctor
-        Misunderstood
-        Angry
-        Knight
-        Bishop
-        Godly
-        Special
-        Toasty
-        Shiny
-        Shimmering
-        Light
-        Dark
-        Odd-Smelling
-        Funky
-        Rock Smasher
-        Son of Herobrine
-        Cracked
-        Sticky
-        §kAlien§r
-        Baby
-        Manly
-        Rough
-        Scary
-        Undoubtable
-        Honest
-        Non-Suspicious
-        Boring
-        Odd
-        Lazy
-        Super
-        Nifty
-        Ogre Slayer
-        Pig Thief
-        Dirt Digger
-        Really Cool
-        Doominator
-        ... Something
-     >
-}
-
-
-formatting {
-    # The format string that will be used to indicate ownership. [default: %s's]
-    S:"Ownership Format"=%s's
-
-    # The format string that will be used when a suffix is applied. [default: %s the %s]
-    S:"Suffix Format"=%s the %s
-}
-
-
-items {
-    # A list of root names for helms, used in the generation of item names. May not be empty. [default: [Helmet], [Cap], [Crown], [Great Helm], [Bassinet], [Sallet], [Close Helm], [Barbute]]
-    S:Helms <
-        Helmet
-        Cap
-        Crown
-        Great Helm
-        Bassinet
-        Sallet
-        Close Helm
-        Barbute
-     >
-
-    # A list of root names for axes, used in the generation of item names. May not be empty. [default: [Axe], [Chopper], [Hatchet], [Tomahawk], [Cleaver], [Hacker], [Tree-Cutter], [Truncator]]
-    S:axes <
-        Axe
-        Chopper
-        Hatchet
-        Tomahawk
-        Cleaver
-        Hacker
-        Tree-Cutter
-        Truncator
-     >
-
-    # A list of root names for boots, used in the generation of item names. May not be empty. [default: [Boots], [Shoes], [Greaves], [Sabatons], [Sollerets]]
-    S:boots <
-        Boots
-        Shoes
-        Greaves
-        Sabatons
-        Sollerets
-     >
-
-    # A list of root names for bows, used in the generation of item names. May not be empty. [default: [Bow], [Shortbow], [Longbow], [Flatbow], [Recurve Bow], [Reflex Bow], [Self Bow], [Composite Bow], [Arrow-Flinger]]
-    S:bows <
-        Bow
-        Shortbow
-        Longbow
-        Flatbow
-        Recurve Bow
-        Reflex Bow
-        Self Bow
-        Composite Bow
-        Arrow-Flinger
-     >
-
-    # A list of root names for chestplates, used in the generation of item names. May not be empty. [default: [Chestplate], [Tunic], [Brigandine], [Hauberk], [Cuirass]]
-    S:chestplates <
-        Chestplate
-        Tunic
-        Brigandine
-        Hauberk
-        Cuirass
-     >
-
-    # A list of root names for leggings, used in the generation of item names. May not be empty. [default: [Leggings], [Pants], [Tassets], [Cuisses], [Schynbalds]]
-    S:leggings <
-        Leggings
-        Pants
-        Tassets
-        Cuisses
-        Schynbalds
-     >
-
-    # A list of root names for pickaxes, used in the generation of item names. May not be empty. [default: [Pickaxe], [Pick], [Mattock], [Rock-Smasher], [Miner]]
-    S:pickaxes <
-        Pickaxe
-        Pick
-        Mattock
-        Rock-Smasher
-        Miner
-     >
-
-    # A list of root names for shields, used in the generation of item names. May not be empty. [default: [Shield], [Defender], [Ardent Defender], [Greatshield], [Blockade], [Bulwark], [Tower Shield], [Protector], [Aegis]]
-    S:shields <
-        Shield
-        Defender
-        Ardent Defender
-        Greatshield
-        Blockade
-        Bulwark
-        Tower Shield
-        Protector
-        Aegis
-     >
-
-    # A list of root names for shovels, used in the generation of item names. May not be empty. [default: [Shovel], [Spade], [Digger], [Excavator], [Trowel], [Scoop]]
-    S:shovels <
-        Shovel
-        Spade
-        Digger
-        Excavator
-        Trowel
-        Scoop
-     >
-
-    # A list of root names for swords, used in the generation of item names. May not be empty. [default: [Sword], [Cutter], [Slicer], [Dicer], [Knife], [Blade], [Machete], [Brand], [Claymore], [Cutlass], [Foil], [Dagger], [Glaive], [Rapier], [Saber], [Scimitar], [Shortsword], [Longsword], [Broadsword], [Calibur]]
-    S:swords <
-        Sword
-        Cutter
-        Slicer
-        Dicer
-        Knife
-        Blade
-        Machete
-        Brand
-        Claymore
-        Cutlass
-        Foil
-        Dagger
-        Glaive
-        Rapier
-        Saber
-        Scimitar
-        Shortsword
-        Longsword
-        Broadsword
-        Calibur
-     >
-}
-
-
-tools {
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: undergarden:cloggrum_battleaxe, undergarden:cloggrum_sword, undergarden:cloggrum_pickaxe, undergarden:cloggrum_axe, undergarden:cloggrum_shovel, undergarden:cloggrum_hoe
-    #  [default: ]
-    S:CLOGGRUM <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: minecraft:diamond_sword, minecraft:diamond_shovel, minecraft:diamond_pickaxe, minecraft:diamond_axe, minecraft:diamond_hoe
-    #  [default: [Diamond], [Zircon], [Gemstone], [Jewel], [Crystal]]
-    S:DIAMOND <
-        Diamond
-        Zircon
-        Gemstone
-        Jewel
-        Crystal
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: undergarden:forgotten_sword, undergarden:forgotten_pickaxe, undergarden:forgotten_axe, undergarden:forgotten_shovel, undergarden:forgotten_hoe
-    #  [default: ]
-    S:FORGOTTEN <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: undergarden:froststeel_sword, undergarden:froststeel_pickaxe, undergarden:froststeel_axe, undergarden:froststeel_shovel, undergarden:froststeel_hoe
-    #  [default: ]
-    S:FROSTSTEEL <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: minecraft:golden_sword, minecraft:golden_shovel, minecraft:golden_pickaxe, minecraft:golden_axe, minecraft:golden_hoe
-    #  [default: [Golden], [Gold], [Gilt], [Auric], [Ornate]]
-    S:GOLD <
-        Golden
-        Gold
-        Gilt
-        Auric
-        Ornate
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: minecraft:iron_sword, minecraft:iron_shovel, minecraft:iron_pickaxe, minecraft:iron_axe, minecraft:iron_hoe
-    #  [default: [Iron], [Steel], [Ferrous], [Rusty], [Wrought Iron]]
-    S:IRON <
-        Iron
-        Steel
-        Ferrous
-        Rusty
-        Wrought Iron
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: minecraft:netherite_sword, minecraft:netherite_shovel, minecraft:netherite_pickaxe, minecraft:netherite_axe, minecraft:netherite_hoe
-    #  [default: [Burnt], [Embered], [Fiery], [Hellborn], [Flameforged]]
-    S:NETHERITE <
-        Burnt
-        Embered
-        Fiery
-        Hellborn
-        Flameforged
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: byg:pendorite_axe, byg:pendorite_pickaxe, byg:pendorite_sword, byg:pendorite_battleaxe, byg:pendorite_shovel, byg:pendorite_hoe
-    #  [default: ]
-    S:PENDORITE <
-     >
-    S:RADIANT <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: minecraft:stone_sword, minecraft:stone_shovel, minecraft:stone_pickaxe, minecraft:stone_axe, minecraft:stone_hoe
-    #  [default: [Stone], [Rock], [Marble], [Cobblestone]]
-    S:STONE <
-        Stone
-        Rock
-        Marble
-        Cobblestone
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: undergarden:utheric_sword, undergarden:utheric_pickaxe, undergarden:utheric_axe, undergarden:utheric_shovel, undergarden:utheric_hoe
-    #  [default: ]
-    S:UTHERIC <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: minecraft:wooden_sword, minecraft:wooden_shovel, minecraft:wooden_pickaxe, minecraft:wooden_axe, minecraft:wooden_hoe
-    #  [default: [Wooden], [Wood], [Hardwood], [Balsa Wood], [Mahogany], [Plywood]]
-    S:WOOD <
-        Wooden
-        Wood
-        Hardwood
-        Balsa Wood
-        Mahogany
-        Plywood
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:amphithere_macuahuitl
-    #  [default: ]
-    S:iceandfire_amphithere_macuahuitl <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:copper_sword, iceandfire:copper_shovel, iceandfire:copper_pickaxe, iceandfire:copper_axe, iceandfire:copper_hoe
-    #  [default: ]
-    S:iceandfire_copper_sword <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:dragonbone_sword, iceandfire:dragonbone_shovel, iceandfire:dragonbone_pickaxe, iceandfire:dragonbone_axe, iceandfire:dragonbone_hoe
-    #  [default: ]
-    S:iceandfire_dragonbone_sword <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:dragonbone_sword_fire
-    #  [default: ]
-    S:iceandfire_dragonbone_sword_fire <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:dragonbone_sword_ice
-    #  [default: ]
-    S:iceandfire_dragonbone_sword_ice <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:dragonbone_sword_lightning
-    #  [default: ]
-    S:iceandfire_dragonbone_sword_lightning <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:dragonsteel_fire_sword, iceandfire:dragonsteel_fire_pickaxe, iceandfire:dragonsteel_fire_axe, iceandfire:dragonsteel_fire_shovel, iceandfire:dragonsteel_fire_hoe
-    #  [default: ]
-    S:iceandfire_dragonsteel_fire_sword <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:dragonsteel_ice_sword, iceandfire:dragonsteel_ice_pickaxe, iceandfire:dragonsteel_ice_axe, iceandfire:dragonsteel_ice_shovel, iceandfire:dragonsteel_ice_hoe
-    #  [default: ]
-    S:iceandfire_dragonsteel_ice_sword <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:dragonsteel_lightning_sword, iceandfire:dragonsteel_lightning_pickaxe, iceandfire:dragonsteel_lightning_axe, iceandfire:dragonsteel_lightning_shovel, iceandfire:dragonsteel_lightning_hoe
-    #  [default: ]
-    S:iceandfire_dragonsteel_lightning_sword <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:dread_knight_sword
-    #  [default: ]
-    S:iceandfire_dread_knight_sword <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:dread_queen_sword
-    #  [default: ]
-    S:iceandfire_dread_queen_sword <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:dread_sword
-    #  [default: ]
-    S:iceandfire_dread_sword <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:ghost_sword
-    #  [default: ]
-    S:iceandfire_ghost_sword <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:hippocampus_slapper
-    #  [default: ]
-    S:iceandfire_hippocampus_slapper <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:hippogryph_sword
-    #  [default: ]
-    S:iceandfire_hippogryph_sword <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:myrmex_desert_sword, iceandfire:myrmex_desert_sword_venom, iceandfire:myrmex_desert_shovel, iceandfire:myrmex_desert_pickaxe, iceandfire:myrmex_desert_axe, iceandfire:myrmex_desert_hoe, iceandfire:myrmex_jungle_sword, iceandfire:myrmex_jungle_sword_venom, iceandfire:myrmex_jungle_shovel, iceandfire:myrmex_jungle_pickaxe, iceandfire:myrmex_jungle_axe, iceandfire:myrmex_jungle_hoe
-    #  [default: ]
-    S:iceandfire_myrmex_desert_sword <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:silver_sword, iceandfire:silver_shovel, iceandfire:silver_pickaxe, iceandfire:silver_axe, iceandfire:silver_hoe
-    #  [default: ]
-    S:iceandfire_silver_sword <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:stymphalian_bird_dagger
-    #  [default: ]
-    S:iceandfire_stymphalian_bird_dagger <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: iceandfire:troll_weapon_axe, iceandfire:troll_weapon_column, iceandfire:troll_weapon_column_forest, iceandfire:troll_weapon_column_frost, iceandfire:troll_weapon_hammer, iceandfire:troll_weapon_trunk, iceandfire:troll_weapon_trunk_frost
-    #  [default: ]
-    S:iceandfire_troll_weapon_axe <
-     >
-
-    # A list of material-based prefix names for this material group. May be empty.
-    # Items in this group: wstweaks:lava_blade, wstweaks:blaze_blade
-    #  [default: ]
-    S:wstweaks_lava_blade <
-     >
-}
-
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/potion.cfg b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/potion.cfg
deleted file mode 100644
index ce03804..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/potion.cfg
+++ /dev/null
@@ -1,8 +0,0 @@
-# Configuration file
-
-general {
-    # The strength of Ancient Knowledge.  This multiplier determines how much additional xp is granted. [range: 1 ~ 2147483647, default: 4]
-    I:"Knowledge XP Multiplier"=4
-}
-
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/spawner.cfg b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/spawner.cfg
deleted file mode 100644
index 860e05e..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/spawner.cfg
+++ /dev/null
@@ -1,135 +0,0 @@
-# Configuration file
-
-general {
-    # When held in the off-hand, this item makes modifiers change stats in the opposite direction. [default: minecraft:quartz]
-    S:"Inverse Item"=minecraft:quartz
-
-    # The durability damage dealt to an item that silk touches a spawner. [range: 0 ~ 100000, default: 100]
-    I:"Spawner Silk Damage"=100
-
-    # The level of silk touch needed to harvest a spawner.  Set to -1 to disable, 0 to always drop.  The enchantment module can increase the max level of silk touch. [range: -1 ~ 127, default: 1]
-    I:"Spawner Silk Level"=-1
-}
-
-
-ignore_spawn_cap {
-    # The item that applies this modifier. [default: minecraft:chorus_fruit]
-    S:item=minecraft:chorus_fruit
-}
-
-
-ignore_spawn_conditions {
-    # The item that applies this modifier. [default: minecraft:dragon_egg]
-    S:item=minecraft:dragon_egg
-}
-
-
-max_delay {
-    # The item that applies this modifier. [default: minecraft:clock]
-    S:item=minecraft:clock
-
-    # The max value of this stat. [range: -2147483648 ~ 2147483647, default: 99999]
-    I:max_value=99999
-
-    # The min value of this stat. [range: -2147483648 ~ 2147483647, default: 10]
-    I:min_value=10
-
-    # The amount each item changes this stat. [range: -2147483648 ~ 2147483647, default: -10]
-    I:value=-10
-}
-
-
-max_nearby_entities {
-    # The item that applies this modifier. [default: minecraft:ghast_tear]
-    S:item=minecraft:ghast_tear
-
-    # The max value of this stat. [range: -2147483648 ~ 2147483647, default: 40]
-    I:max_value=40
-
-    # The min value of this stat. [range: -2147483648 ~ 2147483647, default: 0]
-    I:min_value=0
-
-    # The amount each item changes this stat. [range: -2147483648 ~ 2147483647, default: 2]
-    I:value=2
-}
-
-
-min_delay {
-    # The item that applies this modifier. [default: minecraft:sugar]
-    S:item=minecraft:sugar
-
-    # The max value of this stat. [range: -2147483648 ~ 2147483647, default: 99999]
-    I:max_value=99999
-
-    # The min value of this stat. [range: -2147483648 ~ 2147483647, default: 5]
-    I:min_value=5
-
-    # The amount each item changes this stat. [range: -2147483648 ~ 2147483647, default: -5]
-    I:value=-5
-}
-
-
-player_activation_range {
-    # The item that applies this modifier. [default: minecraft:prismarine_crystals]
-    S:item=minecraft:prismarine_crystals
-
-    # The max value of this stat. [range: -2147483648 ~ 2147483647, default: 50]
-    I:max_value=50
-
-    # The min value of this stat. [range: -2147483648 ~ 2147483647, default: 0]
-    I:min_value=0
-
-    # The amount each item changes this stat. [range: -2147483648 ~ 2147483647, default: 2]
-    I:value=2
-}
-
-
-redstone_control {
-    # The item that applies this modifier. [default: minecraft:comparator]
-    S:item=minecraft:comparator
-}
-
-
-require_players {
-    # The item that applies this modifier. [default: minecraft:nether_star]
-    S:item=minecraft:nether_star
-}
-
-
-spawn_count {
-    # The item that applies this modifier. [default: minecraft:fermented_spider_eye]
-    S:item=minecraft:fermented_spider_eye
-
-    # The max value of this stat. [range: -2147483648 ~ 2147483647, default: 20]
-    I:max_value=20
-
-    # The min value of this stat. [range: -2147483648 ~ 2147483647, default: 1]
-    I:min_value=1
-
-    # The amount each item changes this stat. [range: -2147483648 ~ 2147483647, default: 1]
-    I:value=1
-}
-
-
-spawn_eggs {
-    # A list of entity registry names that cannot be applied to spawners via egg. [default: ]
-    S:"Banned Mobs" <
-     >
-}
-
-
-spawn_range {
-    # The item that applies this modifier. [default: minecraft:blaze_rod]
-    S:item=minecraft:blaze_rod
-
-    # The max value of this stat. [range: -2147483648 ~ 2147483647, default: 32]
-    I:max_value=32
-
-    # The min value of this stat. [range: -2147483648 ~ 2147483647, default: 0]
-    I:min_value=0
-
-    # The amount each item changes this stat. [range: -2147483648 ~ 2147483647, default: 1]
-    I:value=1
-}
-
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/village.cfg b/configuration/services/configs/minecraft/voor-kia/config/apotheosis/village.cfg
deleted file mode 100644
index 109b3e5..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/apotheosis/village.cfg
+++ /dev/null
@@ -1,12 +0,0 @@
-# Configuration file
-
-wanderer {
-    # If the generic trade list will be cleared before datapack loaded trades are added. [default: false]
-    B:"Clear Generic Trades"=false
-
-    # If the rare trade list will be cleared before datapack loaded trades are added. [default: false]
-    B:"Clear Rare Trades"=false
-    B:"Enable New Trades"=true
-}
-
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/appleskin-client.toml b/configuration/services/configs/minecraft/voor-kia/config/appleskin-client.toml
deleted file mode 100644
index b171cd8..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/appleskin-client.toml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-[client]
-	#If true, shows the hunger (and saturation if showSaturationHudOverlay is true) that would be restored by food you are currently holding
-	showFoodValuesHudOverlay = true
-	#If true, shows your food exhaustion as a progress bar behind the hunger bars
-	showFoodExhaustionHudUnderlay = true
-	#Alpha value of the flashing icons at their most visible point (1.0 = fully opaque, 0.0 = fully transparent)
-	#Range: 0.0 ~ 1.0
-	maxHudOverlayFlashAlpha = 0.65
-	#If true, health/hunger overlay will shake to match Minecraft's icon animations
-	showVanillaAnimationsOverlay = true
-	#If true, adds a line that shows your hunger, saturation, and exhaustion level in the F3 debug overlay
-	showFoodStatsInDebugOverlay = true
-	#If true, shows the hunger and saturation values of food in its tooltip while holding SHIFT
-	showFoodValuesInTooltip = true
-	#If true, shows the hunger and saturation values of food in its tooltip automatically (without needing to hold SHIFT)
-	showFoodValuesInTooltipAlways = true
-	#If true, shows estimated health restored by food on the health bar
-	showFoodHealthHudOverlay = true
-	#If true, shows your current saturation level overlayed on the hunger bar
-	showSaturationHudOverlay = true
-	#If true, enables the hunger/saturation/health overlays for food in your off-hand
-	showFoodValuesHudOverlayWhenOffhand = true
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/artifacts-common.toml b/configuration/services/configs/minecraft/voor-kia/config/artifacts-common.toml
deleted file mode 100644
index 5977567..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/artifacts-common.toml
+++ /dev/null
@@ -1,36 +0,0 @@
-#Affects how common artifacts are (does not affect mimics)
-#When this is 1, the default artifact spawn rates will be used
-#Values higher that 1 will decrease spawn rates while values lower than 1 will increase spawn rates
-#Doubling this value will (roughly) halve the chance a container contains an artifact
-#Setting this to 10000 will completely prevent artifacts from spawning
-#When set to 0, every container that can contain artifacts will contain an artifact
-#Range: 0.0 ~ 10000.0
-artifact_rarity = 1.0
-
-[campsite]
-	#The maximum y-level at which a campsite can generate
-	#Range: 1 ~ 255
-	max_y = 45
-	#Whether to use wooden chests from other mods when generating campsites
-	#(keeping this enabled may make it easier to distinguish them from mimics)
-	use_modded_chests = true
-	#List of biome IDs in which campsites are not allowed to generate
-	#End and nether biomes are excluded by default
-	#To blacklist all biomes from a single mod, use "modid:*"
-	biome_blacklist = ["minecraft:void", "undergarden:*", "the_bumblezone:*"]
-	#Probability for a container of a campsite to be replaced by a mimic
-	#Range: 0.0 ~ 1.0
-	mimic_chance = 0.3
-	#The minimum y-level at which a campsite can generate
-	#Range: 1 ~ 255
-	min_y = 1
-	#Probability for an ore vein to generate underneath a campsite
-	#Range: 0.0 ~ 1.0
-	ore_chance = 0.25
-	#Rarity of campsites generating in the world
-	#The chance a campsite generates in a specific chunk is 1/rarity
-	#A rarity of 1 will generate a campsite in every chunk, while 10000 will generate no campsites
-	#Not every attempt at generating a campsite succeeds, this also depends on the density and shape of caves
-	#Range: 1 ~ 10000
-	rarity = 12
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/attributefix-common-1.toml.bak b/configuration/services/configs/minecraft/voor-kia/config/attributefix-common-1.toml.bak
deleted file mode 100644
index e69de29..0000000
diff --git a/configuration/services/configs/minecraft/voor-kia/config/attributefix-common.toml b/configuration/services/configs/minecraft/voor-kia/config/attributefix-common.toml
deleted file mode 100644
index b13b887..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/attributefix-common.toml
+++ /dev/null
@@ -1,144 +0,0 @@
-
-#Values for the minecraft:generic.max_health attribute.
-[minecraft_generic_max_health]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	min = 1.0
-	#The maximum value for the attribute.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the minecraft:generic.follow_range attribute.
-[minecraft_generic_follow_range]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the minecraft:generic.knockback_resistance attribute.
-[minecraft_generic_knockback_resistance]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the minecraft:generic.movement_speed attribute.
-[minecraft_generic_movement_speed]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the minecraft:generic.flying_speed attribute.
-[minecraft_generic_flying_speed]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the minecraft:generic.attack_damage attribute.
-[minecraft_generic_attack_damage]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the minecraft:generic.attack_knockback attribute.
-[minecraft_generic_attack_knockback]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the minecraft:generic.attack_speed attribute.
-[minecraft_generic_attack_speed]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the minecraft:generic.armor attribute.
-[minecraft_generic_armor]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the minecraft:generic.armor_toughness attribute.
-[minecraft_generic_armor_toughness]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the minecraft:generic.luck attribute.
-[minecraft_generic_luck]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the minecraft:zombie.spawn_reinforcements attribute.
-[minecraft_zombie_spawn_reinforcements]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
-#Values for the minecraft:horse.jump_strength attribute.
-[minecraft_horse_jump_strength]
-	#The minimum vallue for the attribute. Changing this may have unforseen consequences.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	min = 4.9E-324
-	#The maximum value for the attribute.
-	#Range: -1.7976931348623157E308 ~ 1.7976931348623157E308
-	max = 65536.0
-	#Whether or not this attribute should be modified.
-	enabled = true
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/betterburning-common.toml b/configuration/services/configs/minecraft/voor-kia/config/betterburning-common.toml
deleted file mode 100644
index d159303..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/betterburning-common.toml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-#General settings for the mod.
-[general]
-	#Should flint and steel deal fire damage when used as a weapon?
-	ShouldFlintAndSteelDoFireDamage = true
-	#Fixes some fire related damage sources not causing mobs to drop cooked items?
-	fireFromDamagesource = true
-	#How much fire damage should flint and steel do?
-	#Range: > 0
-	flintAndSteelFireDamage = 3
-	#What is the % chance skeletons will shoot flaming arrows while on fire?
-	#Range: 0.0 ~ 1.0
-	flameArrowSkeletonChance = 0.7
-	#How long should Soulfire burn players if they try to punch it out?
-	#Range: > 0
-	soulfireHitBurnTime = 2
-	#Can players put out fire with bottled water?
-	extinguishWithBottledWater = true
-	#Should the fire/burning HUD overlay be hidden if the player has fire immunity?
-	hideFireOverlayWhenImmune = true
-	#Should skeletons shoot flaming arrows while on fire?
-	flameArrowSkeletons = true
-	#Should players be able to put out fire blocks by punching them?
-	punchOutFlames = true
-	#How long should Fire burn players if they try to punch it out?
-	#Range: > 0
-	fireHitBurnTime = 1
-	#Should fire damage spread between mobs when they hurt eachother? Zombies already do this and won't be changed.
-	fireDamageSpreads = true
-	#What is the % chance that fire damage will spread between mobs?
-	#Range: 0.0 ~ 1.0
-	fireDamageSpreadChance = 0.3
-	#Should having fire resistance stop things from being on fire visually?
-	fireResistanceExtinguish = true
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/bettercaves-1_16.toml b/configuration/services/configs/minecraft/voor-kia/config/bettercaves-1_16.toml
deleted file mode 100644
index 24a05a4..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/bettercaves-1_16.toml
+++ /dev/null
@@ -1,310 +0,0 @@
-
-["Better Caves"]
-	# List of dimensions that will have Better Caves. Ignored if Global Whitelisting is enabled.
-	# List must be comma-separated values enclosed in square brackets.
-	# Entries must have the mod namespace included.
-	# For example: "[minecraft:overworld, minecraft:the_nether, rats:ratlantis]"
-	# Default: "[minecraft:overworld]"
-	"Whitelisted Dimensions" = "[minecraft:overworld]"
-	# Automatically enables Better Caves in every possible dimension.
-	#     If this is enabled, the Whitelisted Dimension IDs option is ignored.
-	# Default: false
-	"Enable Global Whitelist" = false
-
-	###########################################################################################################
-	## Configure how bedrock generates.
-	###########################################################################################################
-	["Better Caves"."Bedrock Generation"]
-		# Replaces the usual bedrock generation pattern with flat layers.
-		#     Activates in all whitelisted dimensions.
-		# Default: true
-		"Flatten Bedrock" = true
-		# The width of the bedrock layer. Only works if Flatten Bedrock is true.
-		#Range: 0 ~ 256
-		"Bedrock Layer Width" = 1
-
-	###########################################################################################################
-	## Configure settings related to caves, caverns, ravines and more.
-	###########################################################################################################
-	["Better Caves"."Underground Generation"]
-
-		###########################################################################################################
-		## Miscellaneous settings used in cave and cavern generation.
-		###########################################################################################################
-		["Better Caves"."Underground Generation".Miscellaneous]
-			# Set to true to enable flooded underground in ocean biomes.
-			# Default: true
-			"Enable Flooded Underground" = true
-			# Ignores surface detection for closing off caves and caverns, forcing them to spawn
-			#     up until their max height. Useful for Nether-like dimensions with no real "surface".
-			# Default: false
-			"Override Surface Detection" = false
-			# Lava (or water in water regions) spawns at and below this y-coordinate.
-			# Default: 10
-			#Range: 0 ~ 255
-			"Liquid Altitude" = 10
-			# Replace naturally generated floating gravel on the ocean floor with andesite.
-			#     Can prevent lag due to cascading gravel falling into caverns under the ocean.
-			# Default: true
-			"Prevent Cascading Gravel" = true
-			# The block used for lava generation at and below the Liquid Altitude.
-			#     Defaults to regular lava if an invalid block is given.
-			# Default: minecraft:lava
-			"Lava Block" = "minecraft:lava"
-			# The block used for water generation in water caves/caverns at and below the Liquid Altitude.
-			#     Defaults to regular water if an invalid block is given.
-			# Default: minecraft:water
-			"Water Block" = "minecraft:water"
-
-		###########################################################################################################
-		## Settings used in the generation of water regions.
-		###########################################################################################################
-		["Better Caves"."Underground Generation"."Water Regions"]
-			# Custom value for water region size. Smaller value = larger regions. This value is very sensitive to change.
-			#     ONLY WORKS IF Water Region Size IS Custom.
-			#     Provided values:
-			#         Small: 0.008
-			#         Medium: 0.004
-			#         Large: 0.0028
-			#         ExtraLarge: 0.001
-			# Default: 0.004
-			#Range: 0.0 ~ 0.05
-			"Water Region Size Custom Value" = 0.004
-			# Percent chance of a region having water instead of lava at low altitudes.
-			# Default: 40%
-			#Range: 0.0 ~ 100.0
-			"Water Region Spawn Chance" = 40.0
-			# Determines how large water regions are.
-			# Default: Medium (recommended).
-			"Water Region Size" = "Medium"
-
-		###########################################################################################################
-		## Settings used in the generation of caves.
-		###########################################################################################################
-		["Better Caves"."Underground Generation".Caves]
-			# Percent chance of caves spawning in a given region.
-			# Default: caves spawn in 100% of regions.
-			#Range: 0.0 ~ 100.0
-			"Cave Spawn Chance" = 100.0
-			# Determines how large cave regions are.
-			#     Controls the average size of a cave system.
-			# Accepted values: Small, Medium, Large, ExtraLarge, Custom
-			# Default: Small (recommended).
-			"Cave Region Size" = "Small"
-			# Custom value for cave region size. Smaller value = larger regions. This value is very sensitive to change.
-			#     ONLY WORKS IF Cave Region Size IS Custom.
-			#     Provided values:
-			#         Small: 0.008
-			#         Medium: 0.005
-			#         Large: 0.0032
-			#         ExtraLarge: 0.001
-			# Default: 0.008
-			#Range: 0.0 ~ 0.05000000074505806
-			"Cave Region Size Custom Value" = 0.00800000037997961
-
-			###########################################################################################################
-			## Settings used in the generation of vanilla-like caves near the surface.
-			###########################################################################################################
-			["Better Caves"."Underground Generation".Caves."Surface Caves"]
-				# The minimum y-coordinate at which surface caves can generate.
-				# Default: 40
-				#Range: 0 ~ 255
-				"Surface Cave Minimum Altitude" = 40
-				# Set to true to enable vanilla-like caves which provide nice, natural-looking openings at the surface.
-				# Default: true
-				"Enable Surface Caves" = true
-				# The maximum y-coordinate at which surface caves can generate.
-				# Default: 128
-				#Range: 0 ~ 255
-				"Surface Cave Maximum Altitude" = 128
-				# The density of surface caves. Higher = more caves, closer together. 
-				# Default: 17
-				#Range: 0 ~ 100
-				"Surface Cave Density" = 17
-
-			###########################################################################################################
-			## Settings used in the generation of type 1 caves, which are more worm-like.
-			###########################################################################################################
-			["Better Caves"."Underground Generation".Caves."Type 1 Caves"]
-				# The maximum y-coordinate at which type 1 caves can generate.
-				# Default: 80
-				#Range: 0 ~ 255
-				"Type 1 Cave Maximum Altitude" = 80
-				# Stretches caves horizontally. Lower value = wider caves.
-				# Default: 1.6 (recommended)
-				#Range: 0.0 ~ 100.0
-				"Compression - Horizontal" = 1.6
-				# The minimum y-coordinate at which type 1 caves can generate.
-				# Default: 1
-				#Range: 0 ~ 255
-				"Type 1 Cave Minimum Altitude" = 1
-				# The depth from a given point on the surface at which type 1 caves start to close off.
-				#     Will use the Max Cave Altitude instead of surface height if it is lower.
-				#     Will use the Max Cave Altitude no matter what if Override Surface Detection is enabled.
-				# Default: 15 (recommended)
-				#Range: 0 ~ 255
-				"Type 1 Cave Surface Cutoff Depth" = 15
-				# Stretches caves vertically. Lower value = taller caves with steeper drops.
-				# Default: 5.0 (recommended)
-				#Range: 0.0 ~ 100.0
-				"Compression - Vertical" = 5.0
-				# Determines how frequently Type 1 Caves spawn. 0 = will not spawn at all.
-				# Default: 10
-				#Range: 0 ~ 10
-				"Type 1 Cave Priority" = 10
-
-			###########################################################################################################
-			## Settings used in the generation of type 2 caves, which tend to be more open and spacious.
-			###########################################################################################################
-			["Better Caves"."Underground Generation".Caves."Type 2 Caves"]
-				# The minimum y-coordinate at which type 2 caves can generate.
-				# Default: 1
-				#Range: 0 ~ 255
-				"Type 2 Cave Minimum Altitude" = 1
-				# The maximum y-coordinate at which type 2 caves can generate.
-				# Default: 80
-				#Range: 0 ~ 255
-				"Type 2 Cave Maximum Altitude" = 80
-				# Stretches caves horizontally. Lower value = wider caves.
-				# Default: 0.9 (recommended)
-				#Range: 0.0 ~ 100.0
-				"Compression - Horizontal" = 0.9
-				# The depth from a given point on the surface at which type 2 caves start to close off.
-				#     Will use the Max Cave Altitude instead of surface height if it is lower.
-				#     Will use the Max Cave Altitude no matter what if Override Surface Detection is enabled.
-				# Default: 15 (recommended)
-				#Range: 0 ~ 255
-				"Type 2 Cave Surface Cutoff Depth" = 15
-				# Stretches caves vertically. Lower value = taller caves with steeper drops.
-				# Default: 2.2 (recommended)
-				#Range: 0.0 ~ 100.0
-				"Compression - Vertical" = 2.2
-				# Determines how frequently Type 2 Caves spawn. 0 = will not spawn at all.
-				# Default: 5
-				#Range: 0 ~ 10
-				"Type 2 Cave Priority" = 5
-
-			###########################################################################################################
-			## Settings controlling vanilla Minecraft cave generation.
-			###########################################################################################################
-			["Better Caves"."Underground Generation".Caves."Vanilla Caves"]
-				# The maximum y-coordinate at which vanilla caves can generate.
-				# Default: 128
-				#Range: 0 ~ 255
-				"Vanilla Cave Maximum Altitude" = 128
-				# The density of vanilla caves. Higher = more caves, closer together. 
-				# Default: 14 (value used in vanilla)
-				#Range: 0 ~ 100
-				"Vanilla Cave Density" = 14
-				# Determines how frequently vanilla caves spawn. 0 = will not spawn at all.
-				# Default: 0
-				#Range: 0 ~ 10
-				"Vanilla Cave Priority" = 0
-				# The minimum y-coordinate at which vanilla caves can generate.
-				# Default: 8
-				#Range: 0 ~ 255
-				"Vanilla Cave Minimum Altitude" = 8
-
-		###########################################################################################################
-		## Settings used in the generation of caverns. Caverns are spacious caves at low altitudes.
-		###########################################################################################################
-		["Better Caves"."Underground Generation".Caverns]
-			# Custom value for cavern region size. Only works if Cavern Region Size is set to Custom.      Smaller value = larger regions. This value is very sensitive to change.
-			#     Provided values:
-			#         Small: 0.01
-			#         Medium: 0.007
-			#         Large: 0.005
-			#         ExtraLarge: 0.001
-			# Default: 0.01
-			#Range: 0.0 ~ 0.05
-			"Cavern Region Size Custom Value" = 0.01
-			# Percent chance of caverns spawning in a given region.
-			# Default: caverns spawn in 25% of regions.
-			#Range: 0.0 ~ 100.0
-			"Cavern Spawn Chance" = 25.0
-			# Determines how large cavern regions are. This controls the average size of caverns.
-			# Accepted values: Small, Medium, Large, ExtraLarge, Custom
-			# Default: Small (recommended).
-			"Cavern Region Size" = "Small"
-
-			###########################################################################################################
-			## Settings used in the generation of Floored Caverns found at low altitudes.
-			## These have much more ground to walk on than Liquid Caverns.
-			###########################################################################################################
-			["Better Caves"."Underground Generation".Caverns."Floored Caverns"]
-				# Stretches caverns horizontally. Lower value = more open caverns with larger features.
-				# Default: 0.7
-				#Range: 0.0 ~ 100.0
-				"Compression - Horizontal" = 0.7
-				# Determines how frequently Floored Caverns spawn. 0 = will not spawn at all.
-				# Default: 10
-				#Range: 0 ~ 10
-				"Floored Cavern Priority" = 10
-				# Stretches caverns vertically. Lower value = more open caverns with larger features.
-				# Default: 1.3
-				#Range: 0.0 ~ 100.0
-				"Compression - Vertical" = 1.3
-				# The minimum y-coordinate at which Floored Caverns can generate.
-				# Default: 1
-				#Range: 0 ~ 255
-				"Floored Cavern Minimum Altitude" = 1
-				# The maximum y-coordinate at which Floored Caverns can generate.
-				#     Caverns will attempt to close off anyway if this value is greater than the surface's altitude.
-				# Default: 35
-				#Range: 0 ~ 255
-				"Floored Cavern Maximum Altitude" = 35
-
-			###########################################################################################################
-			## Settings used in the generation of Liquid Caverns found at low altitudes.
-			## These are caverns where the floor is predominantly water or lava.
-			###########################################################################################################
-			["Better Caves"."Underground Generation".Caverns."Liquid Caverns"]
-				# Stretches caverns horizontally. Lower value = more open caverns with larger features.
-				# Default: 0.7
-				#Range: 0.0 ~ 100.0
-				"Compression - Horizontal" = 0.7
-				# Determines how frequently Liquid Caverns spawn. 0 = will not spawn at all.
-				# Default: 10
-				#Range: 0 ~ 10
-				"Liquid Cavern Priority" = 10
-				# Stretches caverns vertically. Lower value = more open caverns with larger features.
-				# Default: 1.3
-				#Range: 0.0 ~ 100.0
-				"Compression - Vertical" = 1.3
-				# The minimum y-coordinate at which Liquid Caverns can generate.
-				# Default: 1
-				#Range: 0 ~ 255
-				"Liquid Cavern Minimum Altitude" = 1
-				# The maximum y-coordinate at which Liquid Caverns can generate.
-				#     Caverns will attempt to close off anyway if this value is greater than the surface's altitude.
-				# Default: 35
-				#Range: 0 ~ 255
-				"Liquid Cavern Maximum Altitude" = 35
-
-		###########################################################################################################
-		## Settings used for ravine generation.
-		###########################################################################################################
-		["Better Caves"."Underground Generation".Ravines]
-			# Set to true to enable flooded ravines in ocean biomes.
-			# Default: true
-			"Enable Flooded Ravines" = true
-			# Set to true to enable ravine generation.
-			# Default: true
-			"Enable Ravines" = true
-
-	###########################################################################################################
-	## Don't mess with these settings for normal gameplay.
-	###########################################################################################################
-	["Better Caves"."DEBUG Settings"]
-		# The visualizer creates worlds where there are no blocks except those indicating where caves
-		#     and caverns would be carved out in a regular world. This is useful for visualizing the kinds of
-		#     caves and caverns your current config options will create.
-		#     Type 1 Cave: Wooden Planks
-		#     Type 2 Cave: Cobblestone
-		#     Lava Cavern: Redstone Block
-		#     Floored Cavern: Gold Block
-		#     Surface Cave: Emerald Block
-		#     Vanilla Cave: Bricks
-		# Default: false
-		"Enable DEBUG Visualizer" = false
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/bettercaves/README.txt b/configuration/services/configs/minecraft/voor-kia/config/bettercaves/README.txt
deleted file mode 100644
index 6f6a401..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/bettercaves/README.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-This directory is for adding YUNG's Better Caves configurations specific to certain dimensions.
-Starting with Minecraft 1.16, this directory serves as the base directory for all future versions.
-
-For example, to add a dimension-specific config to the Nether in 1.16, you need to first create a
-directory named 1_16 in this folder.
-(This will be created for you the first time you run YUNG's Better Caves for 1.16).
-Then, in the 1_16 folder, create a config file named DIM_minecraft-the_nether.toml.
-
-NOTE -- YOU MUST HAVE THE DIMENSIONS YOU WANT TO USE WHITELISTED (OR HAVE GLOBAL WHITELISTING ENABLED)
-IN THE BASE CONFIG FILE FOR THIS TO WORK.
-
-FOR MORE INFORMATION, CHECK OUT THE WIKI -- https://github.com/yungnickyoung/YUNGs-Better-Caves/wiki
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/bettermineshafts-forge-1_16.toml b/configuration/services/configs/minecraft/voor-kia/config/bettermineshafts-forge-1_16.toml
deleted file mode 100644
index 0ad3c6b..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/bettermineshafts-forge-1_16.toml
+++ /dev/null
@@ -1,104 +0,0 @@
-
-["YUNG's Better Mineshafts"]
-	# Default: .003
-	"Mineshaft Spawn Rate" = 0.003
-	# The lowest a mineshaft can spawn.
-	# Default: 17
-	"Minimum y-coordinate" = 17
-	# The highest the a mineshaft can spawn.
-	#     Be careful, setting this too high may make mineshafts poke through ocean floors.
-	# Default: 37
-	"Maximum y-coordinate" = 37
-
-	###########################################################################################################
-	## Spawn rates for various mineshaft parts and decorations.
-	###########################################################################################################
-	["YUNG's Better Mineshafts"."Spawn Rates & More"]
-		# The spawn rate for minecarts holding TNT in the main shaft.
-		# Default: .0025
-		#Range: 0.0 ~ 1.0
-		"Main Shaft TNT Minecart Spawn Rate" = 0.0025
-		# The spawn rate for minecarts holding TNT in small shafts.
-		# Default: .0025
-		#Range: 0.0 ~ 1.0
-		"Small Shaft TNT Minecart Spawn Rate" = 0.0025
-		# Percent chance of an Abandoned Miners' Outpost to spawn at the end of a small mineshaft tunnel.
-		# Default: 2
-		#Range: 0 ~ 100
-		"Abandoned Miners' Outpost Spawn Chance" = 2
-		# The spawn rate for minecarts holding chests in small shafts.
-		# Default: .00125
-		#Range: 0.0 ~ 1.0
-		"Small Shaft Chest Minecart Spawn Rate" = 0.00125
-		# The spawn rate for minecarts holding chests in the main shaft.
-		# Default: .01
-		#Range: 0.0 ~ 1.0
-		"Main Shaft Chest Minecart Spawn Rate" = 0.01
-		# The spawn rate for workstation cellars below workstations along the main shaft.
-		# Default: .25
-		#Range: 0.0 ~ 1.0
-		"Workstation Cellar Spawn Rate" = 0.25
-		# The spawn rate for smaller tunnels that generate along the main shaft.
-		# Default: .07
-		#Range: 0.0 ~ 1.0
-		"Small Shaft Spawn Rate" = 0.07
-		# The spawn rate for workstation side rooms along the main shaft.
-		# Default: .025
-		#Range: 0.0 ~ 1.0
-		"Workstation Spawn Rate" = 0.025
-		# The spawn rate for cobwebs.
-		# Default: .15
-		#Range: 0.0 ~ 1.0
-		"Cobweb Spawn Rate" = 0.15
-		# The spawn rate for lanterns in the main shaft.
-		# Default: .0067
-		#Range: 0.0 ~ 1.0
-		"Lantern Spawn Rate" = 0.0067
-		# The spawn rate for torches in small shafts.
-		# Default: .02
-		#Range: 0.0 ~ 1.0
-		"Torch Spawn Rate" = 0.02
-		# The number of "pieces" (e.g. straight, turn, ladder, intersection, etc.) in a single small shaft.
-		# This determines the overall length of small shafts.
-		# Default: 9
-		#Range: 0 ~ 1000
-		"Small Shaft Piece Chain Length" = 9
-
-	###########################################################################################################
-	## Ore deposit settings.
-	###########################################################################################################
-	["YUNG's Better Mineshafts"."Ore Deposits"]
-		# Chance of an ore deposit containing emerald.
-		# Default: 3
-		#Range: 0 ~ 100
-		"Emerald Spawn Chance" = 3
-		# Chance of an ore deposit being cobblestone only.
-		# Default: 50
-		#Range: 0 ~ 100
-		"Cobble Spawn Chance (Empty Deposit)" = 50
-		# Chance of an ore deposit containing iron.
-		# Default: 9
-		#Range: 0 ~ 100
-		"Iron Spawn Chance" = 9
-		# Chance of an ore deposit containing gold.
-		# Default: 7
-		#Range: 0 ~ 100
-		"Gold Spawn Chance" = 7
-		# Chance of an ore deposit containing diamond.
-		# Default: 1
-		#Range: 0 ~ 100
-		"Diamond Spawn Chance" = 1
-		"Enable Ore Deposits" = true
-		# Chance of an ore deposit containing lapis lazuli.
-		# Default: 3
-		#Range: 0 ~ 100
-		"Lapis Spawn Chance" = 3
-		# Chance of an ore deposit containing coal.
-		# Default: 20
-		#Range: 0 ~ 100
-		"Coal Spawn Chance" = 20
-		# Chance of an ore deposit containing redstone.
-		# Default: 7
-		#Range: 0 ~ 100
-		"Redstone Spawn Chance" = 7
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/bettermineshafts/1_16/README.txt b/configuration/services/configs/minecraft/voor-kia/config/bettermineshafts/1_16/README.txt
deleted file mode 100644
index 498b745..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/bettermineshafts/1_16/README.txt
+++ /dev/null
@@ -1,85 +0,0 @@
-variants.json README
-
-The variants.json file contains two properties:
- - variants: a list of all the biome-dependent Variant Settings objects (see below)
-      * NOTE - order is important! The list will be searched in order, and searching will be stopped at the first match.
-      For example, if you have a rare mesa variant that uses the RARE and MESA biomeTags, as well as a normal mesa variant that only uses the MESA biomeTag,
-      you will have to put the rare mesa variant BEFORE the normal mesa variant, or else all mesa biomes will match the normal mesa variant before they can check for the rare mesa variant.
- - defaultVariant: a Variant Settings object to use for biomes that don't match the biomeTags for any of the Variant Settings in the "variants" list.
-      This serves as the go-to/default mineshaft - think plain ol' oak planks mineshafts
-
-Variant Settings: a single Variant Settings object is composed of the following properties.
-ALL of these properties are required for ALL Variants Settings objects, with the exception of the biomeTags for the defaultVariant.
- - biomeTags: a list of lists of BiomeDictionary tags required for this variant to spawn. Only one of the lists of tags must be matched.
-      For example, by default we want the Red Desert mineshaft variant to spawn in rare desert AND rare mesa biomes.
-      All desert biomes have the HOT, DRY, and SANDY tags; all mesa biomes have the MESA tag.
-      Therefore, the biomeTags list for our Red Desert mineshaft in this example will look like the following:
-      "biomeTags": [
-        [
-          "HOT",
-          "DRY",
-          "SANDY",
-          "RARE"
-        ],
-        [
-          "MESA",
-          "RARE"
-        ]
-      ]
-      NOTE that the biomeTags property is IGNORED for the defaultVariant, since the defaultVariant simply acts as the variant for all
-         the biomes in the world that don't meet the criteria for any of the variants in the "variants" list.
-      * SEE THE biomeTags.txt FILE FOR A LIST OF ALL BIOME TAGS *
- - mainSelector: the BlockSelector (see below) used for generating the mineshaft's walls and ceiling
- - floorSelector: the BlockSelector (see below) used for generating the mineshaft's floor
- - brickSelector: the BlockSelector (see below) used for generating areas of the mineshaft where brick-like blocks would be more appropriate.
-      This includes abandoned workstations, workstation cellars, and the doorway at the end of the main shaft for mineshafts containing surface openings.
- - legSelector: the BlockSetSelector (see below) used for generating the 'legs' of the main mineshaft.
-      These are the supports that form underneath the main mineshaft tunnel when the mineshaft spawns over a big opening.
- - mainBlock: The main thematic block for the mineshaft. You will almost certainly want this to be the same as the defaultBlock in the mainSelector and floorSelector properties (see above).
-      Used as the base and top of the small supports generated throughout the mineshaft.
-      Also used as the floor for bridging gaps the mineshaft might spawn over.
- - supportBlock: Used as the middle section of the small supports generated throughout the mineshaft.
-      Also used as the supports in rooms with ladders found in the small shafts.
-      Also used in Type 1 Leg Variants (see below).
-      Usually this is a fence or wall block, but it's not required to be.
- - slabBlock: The main slab block to use. Should be a block that matches your mainBlock well.
- - gravelBlock: The block used for gravel deposits placed randomly throughout mineshafts.
-      Usually gravel, sand, or snow.
- - stoneWallBlock: The block used to frame the left and right sides of the doorway in the main shaft leading to the surface entrance, if present.
-      This is a very minor piece and doesn't matter much. If you aren't sure, use your mainBlock or one of the blocks in your brickSelector.
- - stoneSlabBlock: The block used to frame the top side of the doorway in the main shaft leading to the surface entrance, if present.
-      This is a very minor piece and doesn't matter much. If you aren't sure, use your mainBlock or one of the blocks in your brickSelector.
- - trapdoorBlock: The block used for trapdoors leading to workstation cellars.
- - vineChance: chance of vines spawning in the mineshaft
- - snowChance: chance of snow spawning on the floor of the mineshaft
- - cactusChance: chance of cactus spawning in the mineshaft. Can only spawn on top of valid floor blocks (e.g. sand)
- - deadBushChance: chance of dead bushes spawning the mineshaft. Can only spawn on top of valid floor blocks (sand, terracotta, dirt)
- - mushroomChance: chance of mushrooms spawning in the mineshaft. Can only spawn on top of valid floor blocks (mycelium, dirt)
- - legVariant: The ID of the leg variant to use. ACCEPTABLE VALUES: 1, 2
-      1: The legs used for most mineshafts. Uses the legSelector and the supportBlock.
-      2: The legs used for ice and mushroom variants by default. Uses only the legSelector.
- - flammableLegs: Boolean value for whether the legs of this mineshaft are made of flammable material.
-      If a mineshaft variant has this value set to true, it will use the brickSelector instead of the legSelector
-      to generate legs that will spawn in lava. This helps to prevent mineshafts from catching on fire right after generation.
- - replacementRate: The percent of existing blocks the mainSelector and floorSelector should replace.
-      For example, if the replacementRate is .6, then 60% of the already existing stone, andesite, etc in the floors/walls/ceiling
-      will be replaced with blocks determined by the selectors.
-      Lowering this value preserves more of the regular worldgen blocks in the mineshaft's floors/walls/ceiling.
-
-BlockSelector: Describes a set of blocks and the probability of each block being chosen.
- - entries: An object where each entry's key is a block, and each value is that block's probability of being chosen.
-      The total sum of all probabilities SHOULD NOT exceed 1.0!
- - defaultBlock: The block used for any leftover probability ranges.
-      For example, if the total sum of all the probabilities of the entries is 0.6, then
-      there is a 0.4 chance of the defaultBlock being selected.
-
-Here's an example block selector:
-"entries": {
-  "minecraft:cobblestone": 0.25,
-  "minecraft:air": 0.2,
-  "minecraft:stonebrick[variant=stonebrick]": 0.1
-},
-"defaultBlock": "minecraft:planks[variant=oak]"
-
-For each block, this selector has a 25% chance of returning cobblestone, 20% chance of choosing air,
-10% chance of choosing stone bricks, and a 100 - (25 + 20 + 10) = 45% chance of choosing oak planks (since it's the default block).
diff --git a/configuration/services/configs/minecraft/voor-kia/config/bettermineshafts/1_16/biomeTags.txt b/configuration/services/configs/minecraft/voor-kia/config/bettermineshafts/1_16/biomeTags.txt
deleted file mode 100644
index 80cb705..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/bettermineshafts/1_16/biomeTags.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-Helper file showing all available BiomeDictionary biome tags.
-
-[
-  "BEACH",
-  "COLD",
-  "CONIFEROUS",
-  "DEAD",
-  "DENSE",
-  "DRY",
-  "END",
-  "FOREST",
-  "HILLS",
-  "HOT",
-  "JUNGLE",
-  "LUSH",
-  "MAGICAL",
-  "MESA",
-  "MODIFIED",
-  "MOUNTAIN",
-  "MUSHROOM",
-  "NETHER",
-  "OCEAN",
-  "OVERWORLD",
-  "PLAINS",
-  "PLATEAU",
-  "RARE",
-  "RIVER",
-  "SANDY",
-  "SAVANNA",
-  "SNOWY",
-  "SPARSE",
-  "SPOOKY",
-  "SWAMP",
-  "VOID",
-  "WASTELAND",
-  "WATER",
-  "WET"
-]
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/bettermineshafts/1_16/variants.json b/configuration/services/configs/minecraft/voor-kia/config/bettermineshafts/1_16/variants.json
deleted file mode 100644
index 6a31f4c..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/bettermineshafts/1_16/variants.json
+++ /dev/null
@@ -1,577 +0,0 @@
-{
-  "variants": [
-    {
-      "biomeTags": [
-        [
-          "HOT",
-          "DRY",
-          "SANDY",
-          "RARE"
-        ],
-        [
-          "MESA",
-          "RARE"
-        ]
-      ],
-      "mainSelector": {
-        "entries": {
-          "minecraft:cracked_stone_bricks": 0.05,
-          "minecraft:cut_red_sandstone": 0.1,
-          "minecraft:smooth_red_sandstone": 0.1,
-          "minecraft:stone_bricks": 0.05,
-          "minecraft:chiseled_red_sandstone": 0.1,
-          "minecraft:cave_air": 0.2
-        },
-        "defaultBlock": "minecraft:red_sandstone"
-      },
-      "floorSelector": {
-        "entries": {
-          "minecraft:cracked_stone_bricks": 0.05,
-          "minecraft:cut_red_sandstone": 0.1,
-          "minecraft:smooth_red_sandstone": 0.1,
-          "minecraft:stone_bricks": 0.05,
-          "minecraft:chiseled_red_sandstone": 0.1,
-          "minecraft:red_sand": 0.3
-        },
-        "defaultBlock": "minecraft:red_sandstone"
-      },
-      "brickSelector": {
-        "entries": {
-          "minecraft:cut_red_sandstone": 0.2,
-          "minecraft:smooth_red_sandstone": 0.2,
-          "minecraft:chiseled_red_sandstone": 0.1,
-          "minecraft:red_sandstone": 0.5
-        },
-        "defaultBlock": "minecraft:red_sandstone"
-      },
-      "legSelector": {
-        "entries": {
-          "minecraft:cut_red_sandstone": 0.2,
-          "minecraft:smooth_red_sandstone": 0.2,
-          "minecraft:chiseled_red_sandstone": 0.1,
-          "minecraft:red_sandstone": 0.5
-        },
-        "defaultBlock": "minecraft:red_sandstone"
-      },
-      "mainBlock": "minecraft:red_sandstone",
-      "supportBlock": "minecraft:red_sandstone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]",
-      "slabBlock": "minecraft:red_sandstone_slab[type=bottom,waterlogged=false]",
-      "gravelBlock": "minecraft:red_sand",
-      "stoneWallBlock": "minecraft:red_sandstone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]",
-      "stoneSlabBlock": "minecraft:red_sandstone_slab[type=top,waterlogged=false]",
-      "trapdoorBlock": "minecraft:dark_oak_trapdoor[facing=north,half=bottom,open=false,powered=false,waterlogged=false]",
-      "vineChance": 0.1,
-      "snowChance": 0.0,
-      "cactusChance": 0.1,
-      "deadBushChance": 0.1,
-      "mushroomChance": 0.0,
-      "legVariant": 1,
-      "flammableLegs": false,
-      "replacementRate": 0.6
-    },
-    {
-      "biomeTags": [
-        [
-          "SNOWY",
-          "RARE"
-        ]
-      ],
-      "mainSelector": {
-        "entries": {
-          "minecraft:blue_ice": 0.4,
-          "minecraft:snow_block": 0.1,
-          "minecraft:cave_air": 0.1
-        },
-        "defaultBlock": "minecraft:blue_ice"
-      },
-      "floorSelector": {
-        "entries": {
-          "minecraft:blue_ice": 0.2,
-          "minecraft:snow_block": 0.1
-        },
-        "defaultBlock": "minecraft:blue_ice"
-      },
-      "brickSelector": {
-        "entries": {
-          "minecraft:blue_ice": 0.5
-        },
-        "defaultBlock": "minecraft:blue_ice"
-      },
-      "legSelector": {
-        "entries": {
-          "minecraft:blue_ice": 0.5
-        },
-        "defaultBlock": "minecraft:blue_ice"
-      },
-      "mainBlock": "minecraft:blue_ice",
-      "supportBlock": "minecraft:blue_ice",
-      "slabBlock": "minecraft:blue_ice",
-      "gravelBlock": "minecraft:snow_block",
-      "stoneWallBlock": "minecraft:blue_ice",
-      "stoneSlabBlock": "minecraft:blue_ice",
-      "trapdoorBlock": "minecraft:spruce_trapdoor[facing=north,half=bottom,open=false,powered=false,waterlogged=false]",
-      "vineChance": 0.05,
-      "snowChance": 0.0,
-      "cactusChance": 0.0,
-      "deadBushChance": 0.0,
-      "mushroomChance": 0.0,
-      "legVariant": 2,
-      "flammableLegs": false,
-      "replacementRate": 0.95
-    },
-    {
-      "biomeTags": [
-        [
-          "MESA"
-        ]
-      ],
-      "mainSelector": {
-        "entries": {
-          "minecraft:brown_terracotta": 0.05,
-          "minecraft:white_terracotta": 0.05,
-          "minecraft:orange_terracotta": 0.05,
-          "minecraft:yellow_terracotta": 0.05,
-          "minecraft:cave_air": 0.2
-        },
-        "defaultBlock": "minecraft:dark_oak_planks"
-      },
-      "floorSelector": {
-        "entries": {
-          "minecraft:brown_terracotta": 0.1,
-          "minecraft:white_terracotta": 0.1,
-          "minecraft:orange_terracotta": 0.1,
-          "minecraft:mossy_stone_bricks": 0.05,
-          "minecraft:stone_bricks": 0.1,
-          "minecraft:chiseled_stone_bricks": 0.05,
-          "minecraft:yellow_terracotta": 0.1
-        },
-        "defaultBlock": "minecraft:dark_oak_planks"
-      },
-      "brickSelector": {
-        "entries": {
-          "minecraft:cracked_stone_bricks": 0.33333,
-          "minecraft:mossy_stone_bricks": 0.33333,
-          "minecraft:stone_bricks": 0.33333
-        },
-        "defaultBlock": "minecraft:dark_oak_planks"
-      },
-      "legSelector": {
-        "entries": {
-          "minecraft:stripped_dark_oak_log[axis=y]": 1.0
-        },
-        "defaultBlock": "minecraft:dark_oak_planks"
-      },
-      "mainBlock": "minecraft:dark_oak_planks",
-      "supportBlock": "minecraft:dark_oak_fence[east=false,north=false,south=false,waterlogged=false,west=false]",
-      "slabBlock": "minecraft:dark_oak_slab[type=bottom,waterlogged=false]",
-      "gravelBlock": "minecraft:gravel",
-      "stoneWallBlock": "minecraft:stone_brick_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]",
-      "stoneSlabBlock": "minecraft:stone_brick_slab[type=top,waterlogged=false]",
-      "trapdoorBlock": "minecraft:dark_oak_trapdoor[facing=north,half=bottom,open=false,powered=false,waterlogged=false]",
-      "vineChance": 0.15,
-      "snowChance": 0.0,
-      "cactusChance": 0.0,
-      "deadBushChance": 0.1,
-      "mushroomChance": 0.0,
-      "legVariant": 1,
-      "flammableLegs": true,
-      "replacementRate": 0.9
-    },
-    {
-      "biomeTags": [
-        [
-          "JUNGLE"
-        ]
-      ],
-      "mainSelector": {
-        "entries": {
-          "minecraft:cracked_stone_bricks": 0.05,
-          "minecraft:mossy_stone_bricks": 0.2,
-          "minecraft:stone_bricks": 0.05,
-          "minecraft:chiseled_stone_bricks": 0.05,
-          "minecraft:cave_air": 0.2,
-          "minecraft:mossy_cobblestone": 0.1
-        },
-        "defaultBlock": "minecraft:jungle_planks"
-      },
-      "floorSelector": {
-        "entries": {
-          "minecraft:cracked_stone_bricks": 0.05,
-          "minecraft:mossy_stone_bricks": 0.2,
-          "minecraft:stone_bricks": 0.05,
-          "minecraft:chiseled_stone_bricks": 0.05,
-          "minecraft:mossy_cobblestone": 0.1
-        },
-        "defaultBlock": "minecraft:jungle_planks"
-      },
-      "brickSelector": {
-        "entries": {
-          "minecraft:cracked_stone_bricks": 0.25,
-          "minecraft:mossy_stone_bricks": 0.25,
-          "minecraft:stone_bricks": 0.25,
-          "minecraft:chiseled_stone_bricks": 0.25
-        },
-        "defaultBlock": "minecraft:jungle_planks"
-      },
-      "legSelector": {
-        "entries": {
-          "minecraft:stripped_jungle_log[axis=y]": 1.0
-        },
-        "defaultBlock": "minecraft:jungle_planks"
-      },
-      "mainBlock": "minecraft:jungle_planks",
-      "supportBlock": "minecraft:jungle_fence[east=false,north=false,south=false,waterlogged=false,west=false]",
-      "slabBlock": "minecraft:jungle_slab[type=bottom,waterlogged=false]",
-      "gravelBlock": "minecraft:gravel",
-      "stoneWallBlock": "minecraft:stone_brick_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]",
-      "stoneSlabBlock": "minecraft:stone_brick_slab[type=top,waterlogged=false]",
-      "trapdoorBlock": "minecraft:jungle_trapdoor[facing=north,half=bottom,open=false,powered=false,waterlogged=false]",
-      "vineChance": 0.6,
-      "snowChance": 0.0,
-      "cactusChance": 0.0,
-      "deadBushChance": 0.0,
-      "mushroomChance": 0.0,
-      "legVariant": 1,
-      "flammableLegs": true,
-      "replacementRate": 0.6
-    },
-    {
-      "biomeTags": [
-        [
-          "SNOWY"
-        ]
-      ],
-      "mainSelector": {
-        "entries": {
-          "minecraft:blue_ice": 0.1,
-          "minecraft:cracked_stone_bricks": 0.1,
-          "minecraft:cobblestone": 0.05,
-          "minecraft:packed_ice": 0.2,
-          "minecraft:snow_block": 0.25,
-          "minecraft:cave_air": 0.2
-        },
-        "defaultBlock": "minecraft:spruce_planks"
-      },
-      "floorSelector": {
-        "entries": {
-          "minecraft:blue_ice": 0.1,
-          "minecraft:cracked_stone_bricks": 0.1,
-          "minecraft:cobblestone": 0.05,
-          "minecraft:packed_ice": 0.2,
-          "minecraft:snow_block": 0.25
-        },
-        "defaultBlock": "minecraft:spruce_planks"
-      },
-      "brickSelector": {
-        "entries": {
-          "minecraft:blue_ice": 0.25,
-          "minecraft:packed_ice": 0.25,
-          "minecraft:snow_block": 0.5
-        },
-        "defaultBlock": "minecraft:spruce_planks"
-      },
-      "legSelector": {
-        "entries": {
-          "minecraft:stripped_spruce_log[axis=y]": 1.0
-        },
-        "defaultBlock": "minecraft:spruce_planks"
-      },
-      "mainBlock": "minecraft:spruce_planks",
-      "supportBlock": "minecraft:spruce_fence[east=false,north=false,south=false,waterlogged=false,west=false]",
-      "slabBlock": "minecraft:spruce_slab[type=bottom,waterlogged=false]",
-      "gravelBlock": "minecraft:snow_block",
-      "stoneWallBlock": "minecraft:snow_block",
-      "stoneSlabBlock": "minecraft:snow_block",
-      "trapdoorBlock": "minecraft:spruce_trapdoor[facing=north,half=bottom,open=false,powered=false,waterlogged=false]",
-      "vineChance": 0.2,
-      "snowChance": 1.0,
-      "cactusChance": 0.0,
-      "deadBushChance": 0.0,
-      "mushroomChance": 0.0,
-      "legVariant": 1,
-      "flammableLegs": true,
-      "replacementRate": 0.9
-    },
-    {
-      "biomeTags": [
-        [
-          "COLD",
-          "CONIFEROUS",
-          "FOREST"
-        ]
-      ],
-      "mainSelector": {
-        "entries": {
-          "minecraft:cracked_stone_bricks": 0.1,
-          "minecraft:mossy_stone_bricks": 0.1,
-          "minecraft:cobblestone": 0.1,
-          "minecraft:stone_bricks": 0.1,
-          "minecraft:cave_air": 0.2
-        },
-        "defaultBlock": "minecraft:spruce_planks"
-      },
-      "floorSelector": {
-        "entries": {
-          "minecraft:cracked_stone_bricks": 0.1,
-          "minecraft:mossy_stone_bricks": 0.1,
-          "minecraft:cobblestone": 0.1,
-          "minecraft:stone_bricks": 0.1
-        },
-        "defaultBlock": "minecraft:spruce_planks"
-      },
-      "brickSelector": {
-        "entries": {
-          "minecraft:cracked_stone_bricks": 0.33333,
-          "minecraft:mossy_stone_bricks": 0.33333,
-          "minecraft:stone_bricks": 0.33333
-        },
-        "defaultBlock": "minecraft:spruce_planks"
-      },
-      "legSelector": {
-        "entries": {
-          "minecraft:stripped_spruce_log[axis=y]": 1.0
-        },
-        "defaultBlock": "minecraft:spruce_planks"
-      },
-      "mainBlock": "minecraft:spruce_planks",
-      "supportBlock": "minecraft:spruce_fence[east=false,north=false,south=false,waterlogged=false,west=false]",
-      "slabBlock": "minecraft:spruce_slab[type=bottom,waterlogged=false]",
-      "gravelBlock": "minecraft:gravel",
-      "stoneWallBlock": "minecraft:stone_brick_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]",
-      "stoneSlabBlock": "minecraft:stone_brick_slab[type=top,waterlogged=false]",
-      "trapdoorBlock": "minecraft:spruce_trapdoor[facing=north,half=bottom,open=false,powered=false,waterlogged=false]",
-      "vineChance": 0.25,
-      "snowChance": 0.0,
-      "cactusChance": 0.0,
-      "deadBushChance": 0.0,
-      "mushroomChance": 0.0,
-      "legVariant": 1,
-      "flammableLegs": true,
-      "replacementRate": 0.6
-    },
-    {
-      "biomeTags": [
-        [
-          "HOT",
-          "DRY",
-          "SANDY"
-        ]
-      ],
-      "mainSelector": {
-        "entries": {
-          "minecraft:smooth_sandstone": 0.1,
-          "minecraft:cracked_stone_bricks": 0.05,
-          "minecraft:chiseled_sandstone": 0.1,
-          "minecraft:cut_sandstone": 0.1,
-          "minecraft:stone_bricks": 0.05,
-          "minecraft:cave_air": 0.2
-        },
-        "defaultBlock": "minecraft:sandstone"
-      },
-      "floorSelector": {
-        "entries": {
-          "minecraft:smooth_sandstone": 0.1,
-          "minecraft:cracked_stone_bricks": 0.05,
-          "minecraft:chiseled_sandstone": 0.1,
-          "minecraft:cut_sandstone": 0.1,
-          "minecraft:stone_bricks": 0.05,
-          "minecraft:cave_air": 0.2,
-          "minecraft:sand": 0.3
-        },
-        "defaultBlock": "minecraft:sandstone"
-      },
-      "brickSelector": {
-        "entries": {
-          "minecraft:smooth_sandstone": 0.2,
-          "minecraft:sandstone": 0.5,
-          "minecraft:cut_sandstone": 0.2,
-          "minecraft:chiseled_sandstone": 0.1
-        },
-        "defaultBlock": "minecraft:sandstone"
-      },
-      "legSelector": {
-        "entries": {
-          "minecraft:smooth_sandstone": 0.2,
-          "minecraft:sandstone": 0.5,
-          "minecraft:cut_sandstone": 0.2,
-          "minecraft:chiseled_sandstone": 0.1
-        },
-        "defaultBlock": "minecraft:sandstone"
-      },
-      "mainBlock": "minecraft:sandstone",
-      "supportBlock": "minecraft:sandstone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]",
-      "slabBlock": "minecraft:sandstone_slab[type=bottom,waterlogged=false]",
-      "gravelBlock": "minecraft:sand",
-      "stoneWallBlock": "minecraft:sandstone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]",
-      "stoneSlabBlock": "minecraft:sandstone_slab[type=top,waterlogged=false]",
-      "trapdoorBlock": "minecraft:oak_trapdoor[facing=north,half=bottom,open=false,powered=false,waterlogged=false]",
-      "vineChance": 0.1,
-      "snowChance": 0.0,
-      "cactusChance": 0.1,
-      "deadBushChance": 0.1,
-      "mushroomChance": 0.0,
-      "legVariant": 1,
-      "flammableLegs": false,
-      "replacementRate": 0.6
-    },
-    {
-      "biomeTags": [
-        [
-          "SAVANNA"
-        ]
-      ],
-      "mainSelector": {
-        "entries": {
-          "minecraft:cracked_stone_bricks": 0.1,
-          "minecraft:mossy_stone_bricks": 0.1,
-          "minecraft:cobblestone": 0.1,
-          "minecraft:stone_bricks": 0.1,
-          "minecraft:cave_air": 0.2
-        },
-        "defaultBlock": "minecraft:acacia_planks"
-      },
-      "floorSelector": {
-        "entries": {
-          "minecraft:cracked_stone_bricks": 0.1,
-          "minecraft:mossy_stone_bricks": 0.1,
-          "minecraft:cobblestone": 0.1,
-          "minecraft:stone_bricks": 0.1,
-          "minecraft:cave_air": 0.2
-        },
-        "defaultBlock": "minecraft:acacia_planks"
-      },
-      "brickSelector": {
-        "entries": {
-          "minecraft:cracked_stone_bricks": 0.33333,
-          "minecraft:mossy_stone_bricks": 0.33333,
-          "minecraft:stone_bricks": 0.33333
-        },
-        "defaultBlock": "minecraft:acacia_planks"
-      },
-      "legSelector": {
-        "entries": {
-          "minecraft:stripped_acacia_log[axis=y]": 1.0
-        },
-        "defaultBlock": "minecraft:acacia_planks"
-      },
-      "mainBlock": "minecraft:acacia_planks",
-      "supportBlock": "minecraft:acacia_fence[east=false,north=false,south=false,waterlogged=false,west=false]",
-      "slabBlock": "minecraft:acacia_slab[type=bottom,waterlogged=false]",
-      "gravelBlock": "minecraft:gravel",
-      "stoneWallBlock": "minecraft:stone_brick_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]",
-      "stoneSlabBlock": "minecraft:stone_brick_slab[type=top,waterlogged=false]",
-      "trapdoorBlock": "minecraft:acacia_trapdoor[facing=north,half=bottom,open=false,powered=false,waterlogged=false]",
-      "vineChance": 0.25,
-      "snowChance": 0.0,
-      "cactusChance": 0.0,
-      "deadBushChance": 0.0,
-      "mushroomChance": 0.0,
-      "legVariant": 1,
-      "flammableLegs": true,
-      "replacementRate": 0.6
-    },
-    {
-      "biomeTags": [
-        [
-          "MUSHROOM"
-        ]
-      ],
-      "mainSelector": {
-        "entries": {
-          "minecraft:mushroom_stem[down=true,east=true,north=true,south=true,up=true,west=true]": 0.33333,
-          "minecraft:red_mushroom_block[down=true,east=true,north=true,south=true,up=true,west=true]": 0.33333,
-          "minecraft:brown_mushroom_block[down=true,east=true,north=true,south=true,up=true,west=true]": 0.33333
-        },
-        "defaultBlock": "minecraft:red_mushroom_block[down=true,east=true,north=true,south=true,up=true,west=true]"
-      },
-      "floorSelector": {
-        "entries": {
-          "minecraft:mycelium[snowy=false]": 1.0
-        },
-        "defaultBlock": "minecraft:red_mushroom_block[down=true,east=true,north=true,south=true,up=true,west=true]"
-      },
-      "brickSelector": {
-        "entries": {
-          "minecraft:mushroom_stem[down=true,east=true,north=true,south=true,up=true,west=true]": 0.33333,
-          "minecraft:red_mushroom_block[down=true,east=true,north=true,south=true,up=true,west=true]": 0.33333,
-          "minecraft:brown_mushroom_block[down=true,east=true,north=true,south=true,up=true,west=true]": 0.33333
-        },
-        "defaultBlock": "minecraft:red_mushroom_block[down=true,east=true,north=true,south=true,up=true,west=true]"
-      },
-      "legSelector": {
-        "entries": {
-          "minecraft:mushroom_stem[down=true,east=true,north=true,south=true,up=true,west=true]": 0.33333,
-          "minecraft:red_mushroom_block[down=true,east=true,north=true,south=true,up=true,west=true]": 0.33333,
-          "minecraft:brown_mushroom_block[down=true,east=true,north=true,south=true,up=true,west=true]": 0.33333
-        },
-        "defaultBlock": "minecraft:red_mushroom_block[down=true,east=true,north=true,south=true,up=true,west=true]"
-      },
-      "mainBlock": "minecraft:red_mushroom_block[down=true,east=true,north=true,south=true,up=true,west=true]",
-      "supportBlock": "minecraft:mushroom_stem[down=true,east=true,north=true,south=true,up=true,west=true]",
-      "slabBlock": "minecraft:brown_mushroom_block[down=true,east=true,north=true,south=true,up=true,west=true]",
-      "gravelBlock": "minecraft:gravel",
-      "stoneWallBlock": "minecraft:red_mushroom_block[down=true,east=true,north=true,south=true,up=true,west=true]",
-      "stoneSlabBlock": "minecraft:red_mushroom_block[down=true,east=true,north=true,south=true,up=true,west=true]",
-      "trapdoorBlock": "minecraft:oak_trapdoor[facing=north,half=bottom,open=false,powered=false,waterlogged=false]",
-      "vineChance": 0.25,
-      "snowChance": 0.0,
-      "cactusChance": 0.0,
-      "deadBushChance": 0.0,
-      "mushroomChance": 0.4,
-      "legVariant": 2,
-      "flammableLegs": true,
-      "replacementRate": 0.95
-    }
-  ],
-  "defaultVariant": {
-    "biomeTags": [],
-    "mainSelector": {
-      "entries": {
-        "minecraft:cracked_stone_bricks": 0.1,
-        "minecraft:mossy_stone_bricks": 0.1,
-        "minecraft:cobblestone": 0.1,
-        "minecraft:stone_bricks": 0.1,
-        "minecraft:cave_air": 0.2
-      },
-      "defaultBlock": "minecraft:oak_planks"
-    },
-    "floorSelector": {
-      "entries": {
-        "minecraft:cracked_stone_bricks": 0.1,
-        "minecraft:mossy_stone_bricks": 0.1,
-        "minecraft:cobblestone": 0.1,
-        "minecraft:stone_bricks": 0.1
-      },
-      "defaultBlock": "minecraft:oak_planks"
-    },
-    "brickSelector": {
-      "entries": {
-        "minecraft:cracked_stone_bricks": 0.33333,
-        "minecraft:mossy_stone_bricks": 0.33333,
-        "minecraft:stone_bricks": 0.33333
-      },
-      "defaultBlock": "minecraft:oak_planks"
-    },
-    "legSelector": {
-      "entries": {
-        "minecraft:stripped_oak_log[axis=y]": 1.0
-      },
-      "defaultBlock": "minecraft:oak_planks"
-    },
-    "mainBlock": "minecraft:oak_planks",
-    "supportBlock": "minecraft:oak_fence[east=false,north=false,south=false,waterlogged=false,west=false]",
-    "slabBlock": "minecraft:oak_slab[type=bottom,waterlogged=false]",
-    "gravelBlock": "minecraft:gravel",
-    "stoneWallBlock": "minecraft:stone_brick_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]",
-    "stoneSlabBlock": "minecraft:stone_brick_slab[type=top,waterlogged=false]",
-    "trapdoorBlock": "minecraft:oak_trapdoor[facing=north,half=bottom,open=false,powered=false,waterlogged=false]",
-    "vineChance": 0.25,
-    "snowChance": 0.0,
-    "cactusChance": 0.0,
-    "deadBushChance": 0.0,
-    "mushroomChance": 0.0,
-    "legVariant": 1,
-    "flammableLegs": true,
-    "replacementRate": 0.6
-  }
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/bettermineshafts/README.txt b/configuration/services/configs/minecraft/voor-kia/config/bettermineshafts/README.txt
deleted file mode 100644
index 6fe4457..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/bettermineshafts/README.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This directory is for adding YUNG's Better Mineshafts advanced options.
-Options provided may vary by version.
-This directory contains subdirectories for supported versions. The first time you run Better Mineshafts, a version subdirectory will be created if that version supports advanced options.
-For example, the first time you use Better Mineshafts v2.0+ for Minecraft 1.12.2, the '1_12_2' subdirectory will be created in this folder.
-If no subdirectory for your version is created, then that version probably does not support advanced options.
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/betterportals-1_16.toml b/configuration/services/configs/minecraft/voor-kia/config/betterportals-1_16.toml
deleted file mode 100644
index c6fe574..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/betterportals-1_16.toml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-["Better Portals"]
-	# The maximum height at which a Dimensional Plasma Bucket may be used to place Dimensional Plasma.
-	#     This option exists to force users to go underground in order to get to the Nether (or other dimension, if configured).
-	# Default: 15
-	#Range: 1 ~ 255
-	"Max Dimensional Plasma Placement Altitude" = 15
-	# Whether or not vanilla Nether portals can be created.
-	# Default: false
-	"Enable Vanilla Nether Portals" = false
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/README.txt b/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/README.txt
deleted file mode 100644
index e0446b4..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/README.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-######################################################
-# README for the rifts.json and monoliths.json files #
-######################################################
-NOTE -- EDITING THE rifts.json and monoliths.json FILES REQUIRES A MINECRAFT RESTART TO UPDATE!
-Each of these JSON files contains the 'variants' property, which is a list of all the rifts and monoliths to spawn, respectively.
-
-Each dimensional rift in rifts.json is an object with the following properties:
- - blockSelector: A BlockSetSelector describing the blocks this rift is made of.
-       See the bottom of this README for documentation on BlockSetSelectors.
- - fluidColor: The color of ANY DIMENSIONAL PLASMA IN THIS DIMENSION. Keep in mind this hue is added to the base purple hue
-   - red: Any hex string from 00 to FF.
-   - green: Any hex string from 00 to FF.
-   - blue: Any hex string from 00 to FF.
-   - alpha: Any hex string from 00 to FF.
- - minY: The minimum y-coordinate a rift can spawn at.
- - maxY: The maximum y-coordinate a rift can spawn at.
- - playerTeleportedMinY: The minimum y-coordinate a player can be teleported to in the target dimension.
- - playerTeleportedMaxY: The maximum y-coordinate a player can be teleported to in the target dimension.
- - spawnDimension: The dimension this rift will spawn in. This MUST be distinct for each variant! In other words - only ONE variant per dimension!
- - targetDimension: The dimension this rift will teleport you to. This does not have to be distinct for each variant.
- - spawnChance: The chance of a Rift spawning.
- - spawnPlatformBlock: Sometimes, when teleporting the player, a small 3x3 platform is generated for the player to stand on.
-       This is the block the platform will be made of. Should be a block that matches the target dimension well.
-
-Each monolith in monoliths.json is an object with the following properties:
- - stairSelector: A BlockSetSelector describing the stairs on the perimeter of this monolith.
- - cornerSelector: A BlockSetSelector describing the blocks on the corners of this monolith.
- - insideSelector: A BlockSetSelector describing the blocks making up the inside of this monolith.
- - fenceSelector: A BlockSetSelector describing the fences used in this monolith.
- - powerBlock: The block required to power this monolith.
- - decorationBlock: The block in the four corners of the power grid at the center of this monolith.
- - beamStopBlocks: A list of blocks through which the beams of ANY RECLAIMERS PLACED IN THIS DIMENSION cannot pass.
- - unpoweredBeamColor: The color of the beam of ANY RECLAIMER IN THIS DIMENSION, when UNPOWERED.
-   - red: Any hex string from 00 to FF.
-   - green: Any hex string from 00 to FF.
-   - blue: Any hex string from 00 to FF.
-   - alpha: Any hex string from 00 to FF.
- - poweredBeamColor: The color of the beam of ANY RECLAIMER IN THIS DIMENSION, when POWERED.
-   - red: Any hex string from 00 to FF.
-   - green: Any hex string from 00 to FF.
-   - blue: Any hex string from 00 to FF.
-   - alpha: Any hex string from 00 to FF.
- - minY: The minimum y-coordinate this monolith can spawn at.
- - maxY: The maximum y-coordinate this monolith can spawn at.
- - playerTeleportedMinY: The minimum y-coordinate a player can be teleported to in the target dimension.
- - playerTeleportedMaxY: The maximum y-coordinate a player can be teleported to in the target dimension.
- - spawnDimension: The dimension this monolith will spawn in. This MUST be distinct for each variant! In other words - only ONE variant per dimension!
- - targetDimension: The dimension this monolith will teleport you to. This does not have to be distinct for each variant.
- - spawnChance: The chance of a Monolith spawning.
-
-BlockSetSelector information:
-A BlockSetSelector describes a set of blocks and the probability of each block being chosen.
-Each BlockSetSelector has the following two fields:
-   - entries: An object where each entry's key is a block, and each value is that block's probability of being chosen.
-        The total sum of all probabilities SHOULD NOT exceed 1.0!
-   - defaultBlock: The block used for any leftover probability ranges.
-        For example, if the total sum of all the probabilities of the entries is 0.6, then
-        there is a 0.4 chance of the defaultBlock being selected.
-
-Here's an example BlockSetSelector:
-"entries": {
-  "minecraft:cobblestone": 0.25,
-  "minecraft:air": 0.2,
-  "minecraft:stonebrick[variant=stonebrick]": 0.1
-},
-"defaultBlock": "minecraft:planks[variant=oak]"
-
-For each block, this selector has a 25% chance of returning cobblestone, 20% chance of choosing air,
-10% chance of choosing stone bricks, and a 100 - (25 + 20 + 10) = 45% chance of choosing oak planks (since it's the default block).
diff --git a/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/monoliths.json b/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/monoliths.json
deleted file mode 100644
index 71b85ba..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/monoliths.json
+++ /dev/null
@@ -1,55 +0,0 @@
-{
-  "variants": [
-    {
-      "stairSelector": {
-        "entries": {
-          "minecraft:blackstone_stairs[facing=north,half=bottom,shape=straight,waterlogged=false]": 0.5,
-          "minecraft:polished_blackstone_brick_stairs[facing=north,half=bottom,shape=straight,waterlogged=false]": 0.5
-        },
-        "defaultBlock": "minecraft:blackstone_stairs[facing=north,half=bottom,shape=straight,waterlogged=false]"
-      },
-      "cornerSelector": {
-        "entries": {},
-        "defaultBlock": "minecraft:chiseled_polished_blackstone"
-      },
-      "insideSelector": {
-        "entries": {
-          "minecraft:cracked_polished_blackstone_bricks": 0.2
-        },
-        "defaultBlock": "minecraft:polished_blackstone_bricks"
-      },
-      "fenceSelector": {
-        "entries": {
-          "minecraft:polished_blackstone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]": 0.33,
-          "minecraft:blackstone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]": 0.33,
-          "minecraft:polished_blackstone_brick_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]": 0.33
-        },
-        "defaultBlock": "minecraft:blackstone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]"
-      },
-      "powerBlock": "minecraft:gold_block",
-      "decorationBlock": "minecraft:yellow_glazed_terracotta[facing=north]",
-      "beamStopBlocks": [
-        "minecraft:obsidian"
-      ],
-      "unpoweredBeamColor": {
-        "red": "14",
-        "green": "0c",
-        "blue": "24",
-        "alpha": "FF"
-      },
-      "poweredBeamColor": {
-        "red": "FF",
-        "green": "DC",
-        "blue": "73",
-        "alpha": "FF"
-      },
-      "minY": 35,
-      "maxY": 70,
-      "playerTeleportedMinY": 11,
-      "playerTeleportedMaxY": 30,
-      "spawnChance": 0.1,
-      "spawnDimension": "minecraft:the_nether",
-      "targetDimension": "minecraft:overworld"
-    }
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/rifts.json b/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/rifts.json
deleted file mode 100644
index 644a9b4..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16/rifts.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
-  "variants": [
-    {
-      "blockSelector": {
-        "entries": {
-          "minecraft:obsidian": 0.1,
-          "minecraft:crying_obsidian": 0.05,
-          "minecraft:gilded_blackstone": 0.05,
-          "minecraft:blackstone": 0.1,
-          "minecraft:netherrack": 0.7
-        },
-        "defaultBlock": "minecraft:cave_air"
-      },
-      "fluidColor": {
-        "red": "19",
-        "green": "00",
-        "blue": "20",
-        "alpha": "FC"
-      },
-      "minY": 10,
-      "maxY": 15,
-      "playerTeleportedMinY": 100,
-      "playerTeleportedMaxY": 120,
-      "spawnChance": 0.05,
-      "spawnDimension": "minecraft:overworld",
-      "targetDimension": "minecraft:the_nether",
-      "spawnPlatformBlock": "minecraft:netherrack"
-    }
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16_3/README.txt b/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16_3/README.txt
deleted file mode 100644
index e0446b4..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16_3/README.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-######################################################
-# README for the rifts.json and monoliths.json files #
-######################################################
-NOTE -- EDITING THE rifts.json and monoliths.json FILES REQUIRES A MINECRAFT RESTART TO UPDATE!
-Each of these JSON files contains the 'variants' property, which is a list of all the rifts and monoliths to spawn, respectively.
-
-Each dimensional rift in rifts.json is an object with the following properties:
- - blockSelector: A BlockSetSelector describing the blocks this rift is made of.
-       See the bottom of this README for documentation on BlockSetSelectors.
- - fluidColor: The color of ANY DIMENSIONAL PLASMA IN THIS DIMENSION. Keep in mind this hue is added to the base purple hue
-   - red: Any hex string from 00 to FF.
-   - green: Any hex string from 00 to FF.
-   - blue: Any hex string from 00 to FF.
-   - alpha: Any hex string from 00 to FF.
- - minY: The minimum y-coordinate a rift can spawn at.
- - maxY: The maximum y-coordinate a rift can spawn at.
- - playerTeleportedMinY: The minimum y-coordinate a player can be teleported to in the target dimension.
- - playerTeleportedMaxY: The maximum y-coordinate a player can be teleported to in the target dimension.
- - spawnDimension: The dimension this rift will spawn in. This MUST be distinct for each variant! In other words - only ONE variant per dimension!
- - targetDimension: The dimension this rift will teleport you to. This does not have to be distinct for each variant.
- - spawnChance: The chance of a Rift spawning.
- - spawnPlatformBlock: Sometimes, when teleporting the player, a small 3x3 platform is generated for the player to stand on.
-       This is the block the platform will be made of. Should be a block that matches the target dimension well.
-
-Each monolith in monoliths.json is an object with the following properties:
- - stairSelector: A BlockSetSelector describing the stairs on the perimeter of this monolith.
- - cornerSelector: A BlockSetSelector describing the blocks on the corners of this monolith.
- - insideSelector: A BlockSetSelector describing the blocks making up the inside of this monolith.
- - fenceSelector: A BlockSetSelector describing the fences used in this monolith.
- - powerBlock: The block required to power this monolith.
- - decorationBlock: The block in the four corners of the power grid at the center of this monolith.
- - beamStopBlocks: A list of blocks through which the beams of ANY RECLAIMERS PLACED IN THIS DIMENSION cannot pass.
- - unpoweredBeamColor: The color of the beam of ANY RECLAIMER IN THIS DIMENSION, when UNPOWERED.
-   - red: Any hex string from 00 to FF.
-   - green: Any hex string from 00 to FF.
-   - blue: Any hex string from 00 to FF.
-   - alpha: Any hex string from 00 to FF.
- - poweredBeamColor: The color of the beam of ANY RECLAIMER IN THIS DIMENSION, when POWERED.
-   - red: Any hex string from 00 to FF.
-   - green: Any hex string from 00 to FF.
-   - blue: Any hex string from 00 to FF.
-   - alpha: Any hex string from 00 to FF.
- - minY: The minimum y-coordinate this monolith can spawn at.
- - maxY: The maximum y-coordinate this monolith can spawn at.
- - playerTeleportedMinY: The minimum y-coordinate a player can be teleported to in the target dimension.
- - playerTeleportedMaxY: The maximum y-coordinate a player can be teleported to in the target dimension.
- - spawnDimension: The dimension this monolith will spawn in. This MUST be distinct for each variant! In other words - only ONE variant per dimension!
- - targetDimension: The dimension this monolith will teleport you to. This does not have to be distinct for each variant.
- - spawnChance: The chance of a Monolith spawning.
-
-BlockSetSelector information:
-A BlockSetSelector describes a set of blocks and the probability of each block being chosen.
-Each BlockSetSelector has the following two fields:
-   - entries: An object where each entry's key is a block, and each value is that block's probability of being chosen.
-        The total sum of all probabilities SHOULD NOT exceed 1.0!
-   - defaultBlock: The block used for any leftover probability ranges.
-        For example, if the total sum of all the probabilities of the entries is 0.6, then
-        there is a 0.4 chance of the defaultBlock being selected.
-
-Here's an example BlockSetSelector:
-"entries": {
-  "minecraft:cobblestone": 0.25,
-  "minecraft:air": 0.2,
-  "minecraft:stonebrick[variant=stonebrick]": 0.1
-},
-"defaultBlock": "minecraft:planks[variant=oak]"
-
-For each block, this selector has a 25% chance of returning cobblestone, 20% chance of choosing air,
-10% chance of choosing stone bricks, and a 100 - (25 + 20 + 10) = 45% chance of choosing oak planks (since it's the default block).
diff --git a/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16_3/monoliths.json b/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16_3/monoliths.json
deleted file mode 100644
index 8337200..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16_3/monoliths.json
+++ /dev/null
@@ -1,55 +0,0 @@
-{
-  "variants": [
-    {
-      "stairSelector": {
-        "entries": {
-          "minecraft:polished_blackstone_brick_stairs[facing=north,half=bottom,shape=straight,waterlogged=false]": 0.5,
-          "minecraft:blackstone_stairs[facing=north,half=bottom,shape=straight,waterlogged=false]": 0.5
-        },
-        "defaultBlock": "minecraft:blackstone_stairs[facing=north,half=bottom,shape=straight,waterlogged=false]"
-      },
-      "cornerSelector": {
-        "entries": {},
-        "defaultBlock": "minecraft:chiseled_polished_blackstone"
-      },
-      "insideSelector": {
-        "entries": {
-          "minecraft:cracked_polished_blackstone_bricks": 0.2
-        },
-        "defaultBlock": "minecraft:polished_blackstone_bricks"
-      },
-      "fenceSelector": {
-        "entries": {
-          "minecraft:blackstone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]": 0.33,
-          "minecraft:polished_blackstone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]": 0.33,
-          "minecraft:polished_blackstone_brick_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]": 0.33
-        },
-        "defaultBlock": "minecraft:blackstone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]"
-      },
-      "powerBlock": "minecraft:gold_block",
-      "decorationBlock": "minecraft:yellow_glazed_terracotta[facing=north]",
-      "beamStopBlocks": [
-        "minecraft:obsidian"
-      ],
-      "unpoweredBeamColor": {
-        "red": "14",
-        "green": "0c",
-        "blue": "24",
-        "alpha": "FF"
-      },
-      "poweredBeamColor": {
-        "red": "FF",
-        "green": "DC",
-        "blue": "73",
-        "alpha": "FF"
-      },
-      "minY": 35,
-      "maxY": 70,
-      "playerTeleportedMinY": 11,
-      "playerTeleportedMaxY": 30,
-      "spawnChance": 0.1,
-      "spawnDimension": "minecraft:the_nether",
-      "targetDimension": "minecraft:overworld"
-    }
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16_3/rifts.json b/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16_3/rifts.json
deleted file mode 100644
index e288f36..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/betterportals/1_16_3/rifts.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
-  "variants": [
-    {
-      "blockSelector": {
-        "entries": {
-          "minecraft:crying_obsidian": 0.05,
-          "minecraft:netherrack": 0.7,
-          "minecraft:gilded_blackstone": 0.05,
-          "minecraft:obsidian": 0.1,
-          "minecraft:blackstone": 0.1
-        },
-        "defaultBlock": "minecraft:cave_air"
-      },
-      "fluidColor": {
-        "red": "19",
-        "green": "00",
-        "blue": "20",
-        "alpha": "FC"
-      },
-      "minY": 10,
-      "maxY": 15,
-      "playerTeleportedMinY": 100,
-      "playerTeleportedMaxY": 120,
-      "spawnChance": 0.05,
-      "spawnDimension": "minecraft:overworld",
-      "targetDimension": "minecraft:the_nether",
-      "spawnPlatformBlock": "minecraft:netherrack"
-    }
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/bwncr-common.toml b/configuration/services/configs/minecraft/voor-kia/config/bwncr-common.toml
deleted file mode 100644
index aae71da..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/bwncr-common.toml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-[General]
-	#Silence the wandering trader's ambient sound.
-	silenceTrader = true
-	#Silence the server-wide Wither spawn and death broadcast sounds.
-	silenceWither = true
-	#Silence the server-wide Ender Dragon Death broadcast sound.
-	silenceDragon = true
-	#Silence the server-wide Thunder broadcast sound caused by the Lightning event
-	silenceLightning = true
-	#If enabled the console will load up spam showing what sounds are being received and whether or not they are being canceled
-	debugMode = false
-	#A list of sounds to silence, discoverable with the toggle command /listen 
-	#enter one sound event per line with no commas.
-	silenceUs = []
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/byg/README.txt b/configuration/services/configs/minecraft/voor-kia/config/byg/README.txt
deleted file mode 100644
index 44954f1..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/byg/README.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-If you need help understanding what the byg-biomes or byg-sub-biomes configs allow you to do, please watch this video: https://youtu.be/iq0q09O7ZYo
-
-If you need help with datapacking, please watch this: https://youtu.be/TF_p8OeB-hc
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/byg/byg-biomes.json b/configuration/services/configs/minecraft/voor-kia/config/byg/byg-biomes.json
deleted file mode 100644
index 36bd968..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/byg/byg-biomes.json
+++ /dev/null
@@ -1,1125 +0,0 @@
-{
-  "biomes": {
-    "byg:allium_fields": {
-      "climate": "WARM",
-      "dictionary": "LUSH,OVERWORLD,PLAINS,RARE",
-      "weight": 2,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 5
-        },
-        {
-          "name": "byg:red_oak_forest",
-          "weight": 5
-        }
-      ]
-    },
-    "byg:alps": {
-      "climate": "ICY",
-      "dictionary": "COLD,MOUNTAIN,OVERWORLD,SNOWY",
-      "weight": 5,
-      "river": "byg:alpine_foothills",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:alpine_foothills",
-          "weight": 10
-        }
-      ]
-    },
-    "byg:amaranth_fields": {
-      "climate": "WARM",
-      "dictionary": "LUSH,OVERWORLD,PLAINS,RARE",
-      "weight": 2,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 5
-        },
-        {
-          "name": "byg:jacaranda_forest",
-          "weight": 5
-        }
-      ]
-    },
-    "byg:ancient_forest": {
-      "climate": "WARM",
-      "dictionary": "FOREST,MAGICAL,OVERWORLD,RARE",
-      "weight": 1,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:flowering_ancient_forest",
-          "weight": 5
-        },
-        {
-          "name": "byg:glowing_ancient_forest",
-          "weight": 5
-        }
-      ]
-    },
-    "byg:araucaria_savanna": {
-      "climate": "DESERT",
-      "dictionary": "FOREST,OVERWORLD",
-      "weight": 2,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 5
-        },
-        {
-          "name": "byg:araucaria_forest",
-          "weight": 5
-        }
-      ]
-    },
-    "byg:aspen_forest": {
-      "climate": "WARM",
-      "dictionary": "FOREST,OVERWORLD",
-      "weight": 6,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:aspen_forest_hills",
-          "weight": 4
-        },
-        {
-          "name": "byg:aspen_clearing",
-          "weight": 3
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:autumnal_valley": {
-      "climate": "COOL",
-      "dictionary": "DRY,OVERWORLD,PLAINS",
-      "weight": 5,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 10
-        }
-      ]
-    },
-    "byg:baobab_savanna": {
-      "climate": "DESERT",
-      "dictionary": "DRY,OVERWORLD,SAVANNA,SPARSE",
-      "weight": 6,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "minecraft:savanna",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:bayou": {
-      "climate": "WARM",
-      "dictionary": "FOREST,OVERWORLD,SWAMP,WET",
-      "weight": 5,
-      "river": "byg:bayou",
-      "beach": "byg:bayou",
-      "edge": "",
-      "hills": []
-    },
-    "byg:blue_taiga": {
-      "climate": "COOL",
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD",
-      "weight": 6,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:blue_giant_taiga",
-          "weight": 2
-        },
-        {
-          "name": "byg:blue_taiga_hills",
-          "weight": 4
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 4
-        }
-      ]
-    },
-    "byg:bluff_steeps": {
-      "climate": "COOL",
-      "dictionary": "COLD,CONIFEROUS,MOUNTAIN,OVERWORLD",
-      "weight": 6,
-      "river": "byg:bluff_steeps",
-      "beach": "byg:rocky_beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:bluff_peaks",
-          "weight": 10
-        }
-      ]
-    },
-    "byg:boreal_forest": {
-      "climate": "COOL",
-      "dictionary": "FOREST,OVERWORLD",
-      "weight": 6,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:boreal_forest_hills",
-          "weight": 4
-        },
-        {
-          "name": "byg:boreal_clearing",
-          "weight": 3
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:canyons": {
-      "climate": "WARM",
-      "dictionary": "MOUNTAIN,OVERWORLD,PLATEAU",
-      "weight": 0,
-      "river": "byg:canyons",
-      "beach": "byg:canyon_edge",
-      "edge": "byg:canyon_edge",
-      "hills": []
-    },
-    "byg:cherry_blossom_forest": {
-      "climate": "WARM",
-      "dictionary": "FOREST,OVERWORLD",
-      "weight": 6,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:cherry_blossom_clearing",
-          "weight": 4
-        },
-        {
-          "name": "byg:bamboo_forest",
-          "weight": 3
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:cika_woods": {
-      "climate": "COOL",
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD",
-      "weight": 6,
-      "river": "minecraft:river",
-      "beach": "byg:rocky_beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:cika_mountains",
-          "weight": 5
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 5
-        }
-      ]
-    },
-    "byg:cold_swamplands": {
-      "climate": "COOL",
-      "dictionary": "OVERWORLD,SWAMP",
-      "weight": 6,
-      "river": "byg:cold_swamplands",
-      "beach": "byg:cold_swamplands",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:cold_swamplands",
-          "weight": 10
-        }
-      ]
-    },
-    "byg:coniferous_forest": {
-      "climate": "COOL",
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD",
-      "weight": 5,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:coniferous_clearing",
-          "weight": 4
-        },
-        {
-          "name": "byg:coniferous_forest_hills",
-          "weight": 3
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:crag_gardens": {
-      "climate": "WARM",
-      "dictionary": "JUNGLE,MAGICAL,OVERWORLD,PLATEAU,RARE,WET",
-      "weight": 1,
-      "river": "byg:crag_gardens",
-      "beach": "minecraft:beach",
-      "edge": "minecraft:river",
-      "hills": []
-    },
-    "byg:cypress_swamplands": {
-      "climate": "WARM",
-      "dictionary": "OVERWORLD,SWAMP",
-      "weight": 5,
-      "river": "byg:cypress_swamplands",
-      "beach": "byg:cypress_swamplands",
-      "edge": "",
-      "hills": []
-    },
-    "byg:dead_sea": {
-      "climate": "DESERT",
-      "dictionary": "OCEAN,OVERWORLD,SPOOKY,WASTELAND",
-      "weight": 2,
-      "river": "byg:dead_sea",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": []
-    },
-    "byg:deciduous_forest": {
-      "climate": "WARM",
-      "dictionary": "FOREST,OVERWORLD",
-      "weight": 6,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:deciduous_forest_hills",
-          "weight": 4
-        },
-        {
-          "name": "byg:deciduous_clearing",
-          "weight": 3
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:dover_mountains": {
-      "climate": "COOL",
-      "dictionary": "COLD,CONIFEROUS,MOUNTAIN,OVERWORLD",
-      "weight": 3,
-      "river": "byg:dover_mountains",
-      "beach": "byg:white_beach",
-      "edge": "",
-      "hills": []
-    },
-    "byg:dunes": {
-      "climate": "DESERT",
-      "dictionary": "DRY,HOT,OVERWORLD,SANDY",
-      "weight": 6,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:oasis",
-          "weight": 10
-        }
-      ]
-    },
-    "byg:ebony_woods": {
-      "climate": "WARM",
-      "dictionary": "DENSE,FOREST,OVERWORLD",
-      "weight": 4,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 5
-        },
-        {
-          "name": "byg:ebony_hills",
-          "weight": 5
-        }
-      ]
-    },
-    "byg:enchanted_forest": {
-      "climate": "WARM",
-      "dictionary": "FOREST,MAGICAL,OVERWORLD,RARE",
-      "weight": 1,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 2
-        },
-        {
-          "name": "byg:enchanted_forest_hills",
-          "weight": 8
-        }
-      ]
-    },
-    "byg:enchanted_grove": {
-      "climate": "WARM",
-      "dictionary": "LUSH,MAGICAL,OVERWORLD,PLAINS,RARE",
-      "weight": 1,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 2
-        },
-        {
-          "name": "byg:flowering_enchanted_grove",
-          "weight": 8
-        }
-      ]
-    },
-    "byg:evergreen_taiga": {
-      "climate": "ICY",
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD",
-      "weight": 6,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:evergreen_hills",
-          "weight": 4
-        },
-        {
-          "name": "byg:evergreen_clearing",
-          "weight": 3
-        },
-        {
-          "name": "byg:evergreen_clearing",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:glowshroom_bayou": {
-      "climate": "WARM",
-      "dictionary": "FOREST,MAGICAL,OVERWORLD,RARE,SWAMP,WET",
-      "weight": 1,
-      "river": "byg:glowshroom_bayou",
-      "beach": "byg:glowshroom_bayou",
-      "edge": "",
-      "hills": []
-    },
-    "byg:grassland_plateau": {
-      "climate": "WARM",
-      "dictionary": "OVERWORLD,PLAINS",
-      "weight": 5,
-      "river": "byg:grassland_plateau",
-      "beach": "byg:rocky_beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:wooded_grassland_plateau",
-          "weight": 10
-        }
-      ]
-    },
-    "byg:great_lakes": {
-      "climate": "COOL",
-      "dictionary": "CONIFEROUS,FOREST,OVERWORLD,WATER",
-      "weight": 3,
-      "river": "byg:great_lake_isles",
-      "beach": "byg:great_lake_isles",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:great_lake_isles",
-          "weight": 3
-        },
-        {
-          "name": "byg:great_lakes",
-          "weight": 7
-        }
-      ]
-    },
-    "byg:grove": {
-      "climate": "WARM",
-      "dictionary": "LUSH,OVERWORLD,PLAINS",
-      "weight": 5,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 2
-        },
-        {
-          "name": "byg:flowering_grove",
-          "weight": 8
-        }
-      ]
-    },
-    "byg:guiana_shield": {
-      "climate": "WARM",
-      "dictionary": "DENSE,FOREST,HOT,JUNGLE,MOUNTAIN,OVERWORLD",
-      "weight": 3,
-      "river": "byg:guiana_shield",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:guiana_clearing",
-          "weight": 10
-        }
-      ]
-    },
-    "byg:jacaranda_forest": {
-      "climate": "WARM",
-      "dictionary": "FOREST,OVERWORLD",
-      "weight": 4,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:jacaranda_forest_hills",
-          "weight": 4
-        },
-        {
-          "name": "byg:jacaranda_clearing",
-          "weight": 3
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:lush_tundra": {
-      "climate": "ICY",
-      "dictionary": "COLD,LUSH,OVERWORLD,PLAINS,SNOWY",
-      "weight": 6,
-      "river": "minecraft:river",
-      "beach": "byg:basalt_barrera",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:frozen_lake",
-          "weight": 4
-        },
-        {
-          "name": "byg:northern_forest",
-          "weight": 6
-        }
-      ]
-    },
-    "byg:mangrove_marshes": {
-      "climate": "WARM",
-      "dictionary": "DENSE,FOREST,OVERWORLD,SWAMP,WET",
-      "weight": 4,
-      "river": "byg:mangrove_marshes",
-      "beach": "byg:mangrove_marshes",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:coral_mangroves",
-          "weight": 10
-        }
-      ]
-    },
-    "byg:maple_taiga": {
-      "climate": "COOL",
-      "dictionary": "COLD,FOREST,OVERWORLD",
-      "weight": 5,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": []
-    },
-    "byg:meadow": {
-      "climate": "WARM",
-      "dictionary": "LUSH,OVERWORLD,PLAINS",
-      "weight": 7,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:flowering_meadow",
-          "weight": 3
-        },
-        {
-          "name": "byg:wooded_meadow",
-          "weight": 3
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 4
-        }
-      ]
-    },
-    "byg:mojave_desert": {
-      "climate": "DESERT",
-      "dictionary": "DRY,HOT,OVERWORLD,SANDY",
-      "weight": 3,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "minecraft:desert",
-          "weight": 10
-        }
-      ]
-    },
-    "byg:orchard": {
-      "climate": "WARM",
-      "dictionary": "FOREST,LUSH,OVERWORLD,PLAINS",
-      "weight": 3,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "minecraft:flower_forest",
-          "weight": 5
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 5
-        }
-      ]
-    },
-    "byg:prairie": {
-      "climate": "WARM",
-      "dictionary": "DRY,OVERWORLD,PLAINS",
-      "weight": 5,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 2
-        },
-        {
-          "name": "byg:prairie_clearing",
-          "weight": 8
-        }
-      ]
-    },
-    "byg:red_desert": {
-      "climate": "DESERT",
-      "dictionary": "DRY,HOT,OVERWORLD,SANDY",
-      "weight": 2,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:lush_red_desert",
-          "weight": 5
-        },
-        {
-          "name": "byg:red_desert_dunes",
-          "weight": 5
-        }
-      ]
-    },
-    "byg:red_oak_forest": {
-      "climate": "WARM",
-      "dictionary": "FOREST,OVERWORLD",
-      "weight": 7,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:red_oak_forest_hills",
-          "weight": 6
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 4
-        }
-      ]
-    },
-    "byg:red_rock_mountains": {
-      "climate": "DESERT",
-      "dictionary": "DRY,HOT,MOUNTAIN,OVERWORLD",
-      "weight": 4,
-      "river": "byg:red_rock_mountains",
-      "beach": "minecraft:beach",
-      "edge": "byg:red_rock_lowlands",
-      "hills": [
-        {
-          "name": "byg:red_rock_highlands",
-          "weight": 4
-        },
-        {
-          "name": "byg:red_rock_lowlands",
-          "weight": 2
-        },
-        {
-          "name": "byg:wooded_red_rock_mountains",
-          "weight": 4
-        }
-      ]
-    },
-    "byg:redwood_tropics": {
-      "climate": "WARM",
-      "dictionary": "DENSE,FOREST,OVERWORLD,RARE",
-      "weight": 1,
-      "river": "minecraft:river",
-      "beach": "byg:rocky_beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:redwood_clearing",
-          "weight": 5
-        },
-        {
-          "name": "byg:redwood_mountains",
-          "weight": 3
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 2
-        }
-      ]
-    },
-    "byg:rose_fields": {
-      "climate": "WARM",
-      "dictionary": "LUSH,OVERWORLD,PLAINS,RARE",
-      "weight": 2,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:red_spruce_taiga",
-          "weight": 7
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:seasonal_birch_forest": {
-      "climate": "COOL",
-      "dictionary": "COLD,FOREST,OVERWORLD",
-      "weight": 7,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:seasonal_birch_forest_hills",
-          "weight": 7
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:seasonal_deciduous_forest": {
-      "climate": "COOL",
-      "dictionary": "FOREST,OVERWORLD",
-      "weight": 6,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:seasonal_deciduous_forest_hills",
-          "weight": 4
-        },
-        {
-          "name": "byg:seasonal_deciduous_clearing",
-          "weight": 4
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 2
-        }
-      ]
-    },
-    "byg:seasonal_forest": {
-      "climate": "COOL",
-      "dictionary": "COLD,FOREST,OVERWORLD",
-      "weight": 7,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:seasonal_forest",
-          "weight": 7
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:seasonal_taiga": {
-      "climate": "COOL",
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD",
-      "weight": 5,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:seasonal_taiga_hills",
-          "weight": 8
-        },
-        {
-          "name": "byg:seasonal_giant_taiga",
-          "weight": 2
-        }
-      ]
-    },
-    "byg:shattered_glacier": {
-      "climate": "ICY",
-      "dictionary": "OVERWORLD,RARE,SNOWY",
-      "weight": 2,
-      "river": "byg:shattered_glacier",
-      "beach": "byg:basalt_barrera",
-      "edge": "",
-      "hills": []
-    },
-    "byg:shrublands": {
-      "climate": "DESERT",
-      "dictionary": "DRY,OVERWORLD,PLAINS,SPARSE",
-      "weight": 6,
-      "river": "byg:shrublands",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:polluted_lake",
-          "weight": 3
-        },
-        {
-          "name": "byg:shrublands",
-          "weight": 7
-        }
-      ]
-    },
-    "byg:sierra_valley": {
-      "climate": "DESERT",
-      "dictionary": "DRY,HOT,OVERWORLD,PLAINS",
-      "weight": 5,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "byg:sierra_range",
-      "hills": [
-        {
-          "name": "byg:sierra_range",
-          "weight": 8
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 2
-        }
-      ]
-    },
-    "byg:skyris_highlands": {
-      "climate": "COOL",
-      "dictionary": "COLD,CONIFEROUS,MOUNTAIN,OVERWORLD",
-      "weight": 2,
-      "river": "byg:skyris_highlands",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": []
-    },
-    "byg:snowy_blue_taiga": {
-      "climate": "ICY",
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD",
-      "weight": 5,
-      "river": "minecraft:frozen_river",
-      "beach": "byg:snowy_rocky_black_beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:snowy_blue_taiga_hills",
-          "weight": 8
-        },
-        {
-          "name": "byg:snowy_blue_giant_taiga",
-          "weight": 2
-        }
-      ]
-    },
-    "byg:snowy_coniferous_forest": {
-      "climate": "ICY",
-      "dictionary": "CONIFEROUS,FOREST,OVERWORLD,SNOWY",
-      "weight": 4,
-      "river": "minecraft:frozen_river",
-      "beach": "byg:snowy_rocky_black_beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:snowy_coniferous_clearing",
-          "weight": 4
-        },
-        {
-          "name": "byg:snowy_coniferous_forest_hills",
-          "weight": 3
-        },
-        {
-          "name": "byg:frozen_lake",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:snowy_deciduous_forest": {
-      "climate": "ICY",
-      "dictionary": "FOREST,OVERWORLD,SNOWY",
-      "weight": 6,
-      "river": "minecraft:frozen_river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:snowy_deciduous_forest_hills",
-          "weight": 4
-        },
-        {
-          "name": "byg:snowy_deciduous_clearing",
-          "weight": 3
-        },
-        {
-          "name": "byg:frozen_lake",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:snowy_evergreen_taiga": {
-      "climate": "ICY",
-      "dictionary": "CONIFEROUS,FOREST,OVERWORLD,SNOWY",
-      "weight": 6,
-      "river": "minecraft:frozen_river",
-      "beach": "byg:snowy_rocky_black_beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:snowy_evergreen_clearing",
-          "weight": 4
-        },
-        {
-          "name": "byg:snowy_evergreen_hills",
-          "weight": 3
-        },
-        {
-          "name": "byg:frozen_lake",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:stone_forest": {
-      "climate": "WARM",
-      "dictionary": "DENSE,OVERWORLD,PLATEAU",
-      "weight": 1,
-      "river": "minecraft:river",
-      "beach": "byg:rocky_beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:pointed_stone_forest",
-          "weight": 7
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:the_black_forest": {
-      "climate": "COOL",
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD",
-      "weight": 4,
-      "river": "minecraft:river",
-      "beach": "byg:rocky_beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:black_forest_clearing",
-          "weight": 3
-        },
-        {
-          "name": "byg:black_forest_hills",
-          "weight": 3
-        },
-        {
-          "name": "byg:forest_fault",
-          "weight": 2
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 2
-        }
-      ]
-    },
-    "byg:tropical_fungal_forest": {
-      "climate": "WARM",
-      "dictionary": "DENSE,HOT,JUNGLE,MAGICAL,OVERWORLD",
-      "weight": 3,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:fungal_patch",
-          "weight": 4
-        },
-        {
-          "name": "byg:tropical_fungal_rainforest_hills",
-          "weight": 3
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:tropical_rainforest": {
-      "climate": "WARM",
-      "dictionary": "DENSE,HOT,JUNGLE,OVERWORLD",
-      "weight": 6,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:tropical_rainforest_hills",
-          "weight": 7
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:twilight_valley": {
-      "climate": "COOL",
-      "dictionary": "COLD,MAGICAL,OVERWORLD,WASTELAND",
-      "weight": 2,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:twilight_valley_hills",
-          "weight": 7
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 3
-        }
-      ]
-    },
-    "byg:vibrant_swamplands": {
-      "climate": "COOL",
-      "dictionary": "LUSH,OVERWORLD,SWAMP,WATER,WET",
-      "weight": 6,
-      "river": "byg:vibrant_swamplands",
-      "beach": "byg:vibrant_swamplands",
-      "edge": "",
-      "hills": []
-    },
-    "byg:weeping_witch_forest": {
-      "climate": "COOL",
-      "dictionary": "COLD,FOREST,MAGICAL,OVERWORLD,RARE",
-      "weight": 1,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:pumpkin_forest",
-          "weight": 3
-        },
-        {
-          "name": "byg:weeping_witch_clearing",
-          "weight": 7
-        }
-      ]
-    },
-    "byg:woodlands": {
-      "climate": "WARM",
-      "dictionary": "DENSE,FOREST,MAGICAL,OVERWORLD",
-      "weight": 4,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 10
-        }
-      ]
-    },
-    "byg:zelkova_forest": {
-      "climate": "COOL",
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD",
-      "weight": 5,
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:zelkova_clearing",
-          "weight": 4
-        },
-        {
-          "name": "byg:zelkova_forest_hills",
-          "weight": 3
-        },
-        {
-          "name": "byg:fresh_water_lake",
-          "weight": 3
-        }
-      ]
-    }
-  }
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/byg/byg-end-biomes.json b/configuration/services/configs/minecraft/voor-kia/config/byg/byg-end-biomes.json
deleted file mode 100644
index 717dec0..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/byg/byg-end-biomes.json
+++ /dev/null
@@ -1,86 +0,0 @@
-{
-  "biomes": {
-    "byg:bulbis_gardens": {
-      "dictionary": "END",
-      "weight": 5,
-      "edge": "byg:bulbis_gardens_edge",
-      "hills": []
-    },
-    "byg:cryptic_wastes": {
-      "dictionary": "END",
-      "weight": 5,
-      "edge": "",
-      "hills": []
-    },
-    "byg:ethereal_islands": {
-      "dictionary": "END",
-      "weight": 5,
-      "edge": "byg:ethereal_clearing",
-      "hills": [
-        {
-          "name": "byg:ethereal_forest",
-          "weight": 10
-        },
-        {
-          "name": "byg:ethereal_clearing",
-          "weight": 5
-        }
-      ]
-    },
-    "byg:ivis_fields": {
-      "dictionary": "END",
-      "weight": 5,
-      "edge": "",
-      "hills": []
-    },
-    "byg:nightshade_forest": {
-      "dictionary": "END",
-      "weight": 5,
-      "edge": "",
-      "hills": []
-    },
-    "byg:purpur_peaks": {
-      "dictionary": "END",
-      "weight": 5,
-      "edge": "",
-      "hills": []
-    },
-    "byg:shattered_desert": {
-      "dictionary": "END",
-      "weight": 5,
-      "edge": "",
-      "hills": []
-    },
-    "byg:shulkren_forest": {
-      "dictionary": "END",
-      "weight": 5,
-      "edge": "",
-      "hills": []
-    },
-    "minecraft:end_highlands": {
-      "dictionary": "END",
-      "weight": 5,
-      "edge": "",
-      "hills": []
-    },
-    "minecraft:end_midlands": {
-      "dictionary": "END",
-      "weight": 5,
-      "edge": "",
-      "hills": []
-    }
-  },
-  "void-biomes": {
-    "byg:viscal_isles": {
-      "dictionary": "END,VOID",
-      "weight": 5,
-      "edge": "",
-      "hills": [
-        {
-          "name": "byg:shattered_viscal_isles",
-          "weight": 10
-        }
-      ]
-    }
-  }
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/byg/byg-end-sub-biomes.json b/configuration/services/configs/minecraft/voor-kia/config/byg/byg-end-sub-biomes.json
deleted file mode 100644
index ba52746..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/byg/byg-end-sub-biomes.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "biomes": {
-    "byg:bulbis_gardens_edge": {
-      "dictionary": "END",
-      "edge": ""
-    },
-    "byg:ethereal_forest": {
-      "dictionary": "END",
-      "edge": ""
-    },
-    "byg:ethereal_clearing": {
-      "dictionary": "END",
-      "edge": ""
-    }
-  },
-  "void-biomes": {
-    "byg:shattered_viscal_isles": {
-      "dictionary": "END,VOID",
-      "edge": ""
-    }
-  }
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/byg/byg-nether.toml b/configuration/services/configs/minecraft/voor-kia/config/byg/byg-nether.toml
deleted file mode 100644
index 763a12d..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/byg/byg-nether.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-[The_Nether]
-	#
-	#Is the list of biomes a blacklist or whitelist?
-	#When this list is a blacklist, the values in the list will not be in world generation.
-	#When this list is a whitelist, Adding a biome several times gives it more weight in generation and it must contain at least 1 value.
-	#When set to true, datapack biomes will work automatically! When set to false, you will need to manually add datapack entries.
-	#Default: true
-	isBlacklistNether = true
-	#
-	#This works as a whitelist or blacklist depending on the "isBlacklistNether" value.
-	#NO SPACES AFTER COMMAS!
-	#Default: ""
-	BlacklistNether = ""
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/byg/byg-sub-biomes.json b/configuration/services/configs/minecraft/voor-kia/config/byg/byg-sub-biomes.json
deleted file mode 100644
index d7c9775..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/byg/byg-sub-biomes.json
+++ /dev/null
@@ -1,520 +0,0 @@
-{
-  "sub-biomes": {
-    "byg:alpine_foothills": {
-      "dictionary": "COLD,HILLS,OVERWORLD,SNOWY",
-      "river": "byg:alpine_foothills",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:araucaria_forest": {
-      "dictionary": "DENSE,FOREST,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:aspen_clearing": {
-      "dictionary": "FOREST,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:aspen_forest_hills": {
-      "dictionary": "FOREST,HILLS,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:bamboo_forest": {
-      "dictionary": "DENSE,FOREST,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:basalt_barrera": {
-      "dictionary": "BEACH,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "",
-      "edge": ""
-    },
-    "byg:black_forest_clearing": {
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "byg:rocky_beach",
-      "edge": ""
-    },
-    "byg:black_forest_hills": {
-      "dictionary": "COLD,CONIFEROUS,FOREST,HILLS,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "byg:rocky_beach",
-      "edge": ""
-    },
-    "byg:blue_giant_taiga": {
-      "dictionary": "OVERWORLD,RARE",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:blue_taiga_hills": {
-      "dictionary": "COLD,CONIFEROUS,FOREST,HILLS,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:bluff_peaks": {
-      "dictionary": "COLD,MOUNTAIN,OVERWORLD,SNOWY",
-      "river": "minecraft:river",
-      "beach": "byg:rocky_beach",
-      "edge": ""
-    },
-    "byg:bog": {
-      "dictionary": "OVERWORLD,SWAMP,WATER,WET",
-      "river": "byg:bog",
-      "beach": "byg:bog",
-      "edge": ""
-    },
-    "byg:boreal_clearing": {
-      "dictionary": "CONIFEROUS,FOREST,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:boreal_forest_hills": {
-      "dictionary": "COLD,CONIFEROUS,FOREST,HILLS,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:canyon_edge": {
-      "dictionary": "OVERWORLD,WATER,WET",
-      "river": "byg:canyon_edge",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:cherry_blossom_clearing": {
-      "dictionary": "FOREST,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:cika_mountains": {
-      "dictionary": "COLD,CONIFEROUS,FOREST,MOUNTAIN,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "byg:rocky_beach",
-      "edge": ""
-    },
-    "byg:coniferous_clearing": {
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:coniferous_forest_hills": {
-      "dictionary": "COLD,CONIFEROUS,FOREST,HILLS,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:coral_mangroves": {
-      "dictionary": "OVERWORLD,SWAMP,WATER,WET",
-      "river": "byg:coral_mangroves",
-      "beach": "byg:coral_mangroves",
-      "edge": ""
-    },
-    "byg:deciduous_clearing": {
-      "dictionary": "FOREST,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:deciduous_forest_hills": {
-      "dictionary": "FOREST,HILLS,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:dummy": {
-      "dictionary": "OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:ebony_hills": {
-      "dictionary": "DENSE,FOREST,HILLS,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:enchanted_forest_hills": {
-      "dictionary": "FOREST,HILLS,MAGICAL,OVERWORLD,RARE",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:evergreen_clearing": {
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:evergreen_hills": {
-      "dictionary": "COLD,CONIFEROUS,FOREST,HILLS,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:flowering_ancient_forest": {
-      "dictionary": "DENSE,FOREST,MAGICAL,OVERWORLD,RARE",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:flowering_enchanted_grove": {
-      "dictionary": "LUSH,MAGICAL,OVERWORLD,PLAINS",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:flowering_grove": {
-      "dictionary": "LUSH,OVERWORLD,PLAINS",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:flowering_meadow": {
-      "dictionary": "LUSH,OVERWORLD,PLAINS",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:forest_fault": {
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD,RARE",
-      "river": "minecraft:river",
-      "beach": "byg:rocky_beach",
-      "edge": ""
-    },
-    "byg:fresh_water_lake": {
-      "dictionary": "OVERWORLD,WATER,WET",
-      "river": "byg:fresh_water_lake",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:frozen_lake": {
-      "dictionary": "OVERWORLD,SNOWY,WATER,WET",
-      "river": "byg:frozen_lake",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:fungal_patch": {
-      "dictionary": "DENSE,HOT,JUNGLE,MAGICAL,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:glowing_ancient_forest": {
-      "dictionary": "DENSE,FOREST,MAGICAL,OVERWORLD,RARE",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:great_lake_isles": {
-      "dictionary": "CONIFEROUS,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:guiana_clearing": {
-      "dictionary": "FOREST,JUNGLE,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:jacaranda_clearing": {
-      "dictionary": "FOREST,JUNGLE,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:jacaranda_forest_hills": {
-      "dictionary": "DENSE,FOREST,HILLS,HOT,JUNGLE,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:lush_red_desert": {
-      "dictionary": "DRY,HOT,OVERWORLD,SANDY",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:maple_hills": {
-      "dictionary": "COLD,FOREST,HILLS,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:marshlands": {
-      "dictionary": "OVERWORLD,SWAMP,WATER,WET",
-      "river": "byg:marshlands",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:northern_forest": {
-      "dictionary": "COLD,FOREST,LUSH,OVERWORLD,SNOWY",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:oasis": {
-      "dictionary": "HOT,LUSH,OVERWORLD,SANDY,WATER,WET",
-      "river": "byg:oasis",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:pointed_stone_forest": {
-      "dictionary": "FOREST,MOUNTAIN,OVERWORLD,PLATEAU",
-      "river": "minecraft:river",
-      "beach": "byg:rocky_beach",
-      "edge": ""
-    },
-    "byg:polluted_lake": {
-      "dictionary": "OVERWORLD,WASTELAND,WATER,WET",
-      "river": "byg:polluted_lake",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:prairie_clearing": {
-      "dictionary": "DRY,OVERWORLD,PLAINS,SPARSE",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:pumpkin_forest": {
-      "dictionary": "COLD,FOREST,MAGICAL,OVERWORLD,RARE",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:rainbow_beach": {
-      "dictionary": "BEACH,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "",
-      "edge": ""
-    },
-    "byg:red_desert_dunes": {
-      "dictionary": "HILLS,HOT,OVERWORLD,SANDY,WASTELAND",
-      "river": "byg:red_desert_dunes",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:red_oak_forest_hills": {
-      "dictionary": "FOREST,HILLS,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:red_rock_highlands": {
-      "dictionary": "HOT,MOUNTAIN,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:red_rock_lowlands": {
-      "dictionary": "HOT,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:red_spruce_taiga": {
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:redwood_clearing": {
-      "dictionary": "FOREST,OVERWORLD,SPARSE",
-      "river": "minecraft:river",
-      "beach": "byg:rocky_beach",
-      "edge": ""
-    },
-    "byg:redwood_mountains": {
-      "dictionary": "DRY,HOT,MOUNTAIN,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "byg:rocky_beach",
-      "edge": ""
-    },
-    "byg:rocky_beach": {
-      "dictionary": "OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:seasonal_birch_forest_hills": {
-      "dictionary": "COLD,FOREST,HILLS,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:seasonal_deciduous_clearing": {
-      "dictionary": "FOREST,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:seasonal_deciduous_forest_hills": {
-      "dictionary": "FOREST,HILLS,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:seasonal_forest_hills": {
-      "dictionary": "COLD,FOREST,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:seasonal_giant_taiga": {
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:seasonal_taiga_hills": {
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:sierra_range": {
-      "dictionary": "DRY,HOT,MOUNTAIN,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:snowy_black_beach": {
-      "dictionary": "BEACH,OVERWORLD,SNOWY",
-      "river": "minecraft:frozen_river",
-      "beach": "",
-      "edge": ""
-    },
-    "byg:snowy_blue_giant_taiga": {
-      "dictionary": "CONIFEROUS,FOREST,OVERWORLD,RARE,SNOWY",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:snowy_blue_taiga_hills": {
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD,SNOWY",
-      "river": "minecraft:frozen_river",
-      "beach": "minecraft:snowy_beach",
-      "edge": ""
-    },
-    "byg:snowy_coniferous_clearing": {
-      "dictionary": "CONIFEROUS,FOREST,OVERWORLD,SNOWY",
-      "river": "minecraft:frozen_river",
-      "beach": "byg:snowy_black_beach",
-      "edge": ""
-    },
-    "byg:snowy_coniferous_forest_hills": {
-      "dictionary": "CONIFEROUS,FOREST,HILLS,OVERWORLD,SNOWY",
-      "river": "minecraft:frozen_river",
-      "beach": "byg:snowy_black_beach",
-      "edge": ""
-    },
-    "byg:snowy_deciduous_clearing": {
-      "dictionary": "FOREST,OVERWORLD,SNOWY",
-      "river": "minecraft:frozen_river",
-      "beach": "minecraft:snowy_beach",
-      "edge": ""
-    },
-    "byg:snowy_deciduous_forest_hills": {
-      "dictionary": "FOREST,HILLS,OVERWORLD,SNOWY",
-      "river": "minecraft:frozen_river",
-      "beach": "minecraft:snowy_beach",
-      "edge": ""
-    },
-    "byg:snowy_evergreen_clearing": {
-      "dictionary": "CONIFEROUS,FOREST,OVERWORLD,SNOWY",
-      "river": "minecraft:frozen_river",
-      "beach": "byg:snowy_black_beach",
-      "edge": ""
-    },
-    "byg:snowy_evergreen_hills": {
-      "dictionary": "CONIFEROUS,FOREST,OVERWORLD,SNOWY",
-      "river": "minecraft:frozen_river",
-      "beach": "byg:snowy_black_beach",
-      "edge": ""
-    },
-    "byg:snowy_rocky_black_beach": {
-      "dictionary": "BEACH,OVERWORLD,SNOWY",
-      "river": "minecraft:frozen_river",
-      "beach": "",
-      "edge": ""
-    },
-    "byg:tropical_fungal_rainforest_hills": {
-      "dictionary": "DENSE,HILLS,HOT,JUNGLE,MAGICAL,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:tropical_islands": {
-      "dictionary": "OVERWORLD",
-      "river": "byg:tropical_islands",
-      "beach": "byg:rainbow_beach",
-      "edge": ""
-    },
-    "byg:tropical_rainforest_hills": {
-      "dictionary": "DENSE,HILLS,HOT,JUNGLE,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:twilight_valley_hills": {
-      "dictionary": "COLD,HILLS,MAGICAL,OVERWORLD,WASTELAND",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:weeping_witch_clearing": {
-      "dictionary": "COLD,FOREST,MAGICAL,OVERWORLD,RARE",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:white_beach": {
-      "dictionary": "BEACH,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "",
-      "edge": ""
-    },
-    "byg:wooded_grassland_plateau": {
-      "dictionary": "FOREST,OVERWORLD,PLAINS",
-      "river": "minecraft:river",
-      "beach": "byg:rocky_beach",
-      "edge": ""
-    },
-    "byg:wooded_meadow": {
-      "dictionary": "FOREST,LUSH,OVERWORLD,PLAINS",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:wooded_red_rock_mountains": {
-      "dictionary": "DRY,HOT,MOUNTAIN,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:zelkova_clearing": {
-      "dictionary": "COLD,CONIFEROUS,FOREST,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    },
-    "byg:zelkova_forest_hills": {
-      "dictionary": "COLD,CONIFEROUS,FOREST,HILLS,OVERWORLD",
-      "river": "minecraft:river",
-      "beach": "minecraft:beach",
-      "edge": ""
-    }
-  }
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/byg/byg-world.toml b/configuration/services/configs/minecraft/voor-kia/config/byg/byg-world.toml
deleted file mode 100644
index 235c77b..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/byg/byg-world.toml
+++ /dev/null
@@ -1,218 +0,0 @@
-
-[Overworld]
-
-	[Overworld.Ores]
-
-		[Overworld.Ores.Pendorite]
-			#
-			#Number of times to spawn per chunk.
-			#Default: 10
-			#Range: 1 ~ 100
-			PendoritePerChunk = 10
-			#
-			#Generate Pendorite Ore? Only spawns in Forest Fault.
-			GeneratePendorite = true
-			#
-			#Y level to start generating at.
-			#Default: 56
-			#Range: 1 ~ 256
-			PendoriteY = 56
-			#
-			#Size of the clusters.
-			#Default: 4
-			#Range: 1 ~ 100
-			PendoriteSize = 4
-
-		#Datapacks can and will override all values in the "Ore" category so keep that in mind!
-		[Overworld.Ores.Ametrine]
-			#
-			#Number of times to spawn per chunk.
-			#Default: 10
-			#Range: 1 ~ 100
-			AmetrinePerChunk = 10
-			#
-			#Size of the clusters.
-			#Default: 4
-			#Range: 1 ~ 100
-			AmetrineSize = 4
-			#
-			#Generate Ametrine Ore? Only spawns in Guiana Shield, Stone Forest, and Pointed Stone Forest!
-			GenerateAmetrine = true
-			#
-			#Y level to start generating at.
-			#Default: 56
-			#Range: 1 ~ 256
-			AmetrineY = 56
-
-	[Overworld.Stones]
-
-		[Overworld.Stones.Scoria_Stone]
-			#
-			#Number of times to spawn per chunk.
-			#Default: 10
-			#Range: 1 ~ 100
-			ScoriaStonePerChunk = 10
-			#
-			#Y level to start generating at.
-			#Default: 63
-			#Range: 1 ~ 256
-			ScoriaStoneY = 63
-			#
-			#Size of the clusters.
-			#Default: 20
-			#Range: 1 ~ 100
-			ScoriaStoneSize = 20
-			#
-			#Generate Scoria Stone?
-			GenerateScoriaStone = true
-
-		[Overworld.Stones.Soap_Stone]
-			#
-			#Number of times to spawn per chunk.
-			#Default: 10
-			#Range: 1 ~ 100
-			SoapStonePerChunk = 10
-			#
-			#Size of the clusters.
-			#Default: 20
-			#Range: 1 ~ 100
-			SoapStoneSize = 20
-			#
-			#Generate Soap Stone?
-			GenerateSoapStone = true
-			#
-			#Y level to start generating at.
-			#Default: 63
-			#Range: 1 ~ 256
-			SoapStoneY = 63
-
-		#Datapacks can and will override all values in the "Stone" category so keep that in mind!
-		[Overworld.Stones.Rocky_Stone]
-			#
-			#Y level to start generating at.
-			#Default: 63
-			#Range: 1 ~ 256
-			RockyStoneY = 63
-			#
-			#Size of the clusters.
-			#Default: 20
-			#Range: 1 ~ 100
-			RockyStoneSize = 20
-			#
-			#Number of times to spawn per chunk.
-			#Default: 10
-			#Range: 1 ~ 100
-			RockyStonePerChunk = 10
-			#
-			#Generate Rocky Stone?
-			GenerateRockyStone = true
-
-[The_End]
-	#
-	#Does BYG control The End?
-	ControlEnd = true
-	#
-	#End Biome Size.
-	#Default: 3
-	#Range: 0 ~ 10
-	IslandBiomeSize = 3
-	#
-	#End Biome Size
-	#Default: 3
-	#Range: 0 ~ 10
-	EndBiomeSize = 3
-
-	[The_End.Void]
-		#
-		#Void Biome(where small end islands generate in vanilla) size.
-		#Default: 3
-		#Range: 0 ~ 10
-		VoidBiomeSize = 2
-
-[The_Nether]
-	#
-	#Is the list of biomes a blacklist or whitelist?
-	#When this list is a blacklist, the values in the list will not be in world generation.
-	#When this list is a whitelist, Adding a biome several times gives it more weight in generation and it must contain at least 1 value.
-	#When set to true, datapack biomes will work automatically! When set to false, you will need to manually add datapack entries.
-	#Default: true
-	isBlacklistNether = true
-	#
-	#Nether Biome Size
-	#Default: 3
-	#Range: 0 ~ 10
-	NetherBiomeSize = 3
-	#
-	#Does BYG control The Nether?
-	ControlNether = true
-	#
-	#This works as a whitelist or blacklist depending on the "isBlacklistNether" value.
-	#NO SPACES AFTER COMMAS!
-	#Default: ""
-	BlacklistNether = ""
-
-#End related settings
-[end]
-	#Does BYG control The End?
-	#This only applies when making NEW worlds!
-	#Is not guaranteed to work in specific world types.
-	#You can find more info here in regards to specific world types: https://github.com/CorgiTaco/BYG/wiki/Enabling-BYG-Nether-&-End-Biomes
-	#For existing worlds, follow the steps listed here: https://wiki.griefed.de/SCP/edit-world.
-	controlEnd = true
-	#End Biome Size
-	#Default: 3
-	#Range: 1-10
-	endBiomeSize = 3
-	#Void Biome Size
-	#Default: 2
-	#Range: 1-10
-	voidBiomeSize = 2
-
-#Nether related settings
-[nether]
-	#Does BYG control The Nether?
-	#This only applies when making NEW worlds!
-	#Is not guaranteed to work in specific world types.
-	#You can find more info here in regards to specific world types: https://github.com/CorgiTaco/BYG/wiki/Enabling-BYG-Nether-&-End-Biomes
-	#For existing worlds, follow the steps listed here: https://wiki.griefed.de/SCP/edit-world.
-	controlNether = true
-	#Nether Biome Size
-	#Default: 3
-	#Range: 1-10
-	netherBiomeSize = 3
-
-#BYG uses a prefix system for its ore spawns.
-# Prefix Guide:
-# "#" - Biome category representable.
-# "$" - Biome dictionary representable.
-# "," - Creates a new condition, separate from the previous.
-# "ALL" - Spawn in all biomes(no condition).
-# "!" - Negates/flips/does the reverse of the condition.
-# "" - No prefix serves as a biome ID OR Mod ID representable.
-#
-# Here are a few examples:
-#1. "byg#THE_END, $OCEAN" would mean that the ore may spawn in biomes with the name space "byg" AND in the "END" biome category, OR all biomes in the "OCEAN" dictionary.
-#2. "byg:guiana_shield, #MESA" would mean that the ore may spawn in the "byg:guiana_shield" OR all biomes in the "MESA" category.
-#3. "byg#ICY$MOUNTAIN" would mean that the ore may only spawn in biomes from byg in the "ICY" category and "MOUNTAIN" dictionary type.
-#4. "!byg#DESERT" would mean that the ore may only spawn in biomes that are NOT from byg and NOT in the "DESERT" category.
-#5. "ALL", spawn everywhere. 
-#6. "" Don't spawn anywhere.
-[ores]
-	#What biome(s) does Ametrine spawn in? Default: "byg:shattered_viscal_isles".
-	ametrineSpawns = "byg:shattered_viscal_isles"
-	#What biome(s) does Budding Ametrine spawn in? Default: "byg:shattered_viscal_isles".
-	buddingAmetrineSpawns = "byg:shattered_viscal_isles"
-	#What biome(s) does Pendorite spawn in? Default: "byg:forest_fault".
-	pendoriteSpawns = "byg:forest_fault"
-	#What biome(s) does Therium spawn in? Default: "byg#THE_END".
-	theriumSpawns = "byg#THEEND"
-
-#See the explanation for ores for configuring stones.
-[stones]
-	#What biome(s) does Rocky Stone spawn in? Default: "!#THEEND#NETHER".
-	rockyStoneSpawns = "!#THEEND#NETHER"
-	#What biome(s) does Scoria Stone spawn in? Default: "!#THEEND#NETHER".
-	scoriaStoneSpawns = "!#THEEND#NETHER"
-	#What biome(s) does Soap Stone spawn in? Default: "!#THEEND#NETHER".
-	soapStoneSpawns = "!#THEEND#NETHER"
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/citadel-common.toml b/configuration/services/configs/minecraft/voor-kia/config/citadel-common.toml
deleted file mode 100644
index af71d32..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/citadel-common.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-[general]
-	#True if citadel tracks entity properties(freezing, stone mobs, etc) on server. Turn this to false to solve some server lag, may break some stuff.
-	"Track Entities" = true
-	#Multiplies the count of entities spawned by this number. 0 = no entites added on chunk gen, 2 = twice as many entities added on chunk gen. Useful for many mods that add a lot of creatures, namely animals, to the spawn lists.
-	#Range: 0.0 ~ 100000.0
-	chunkGenSpawnModifier = 1.0
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/cookingforblockheads-common.toml b/configuration/services/configs/minecraft/voor-kia/config/cookingforblockheads-common.toml
deleted file mode 100644
index a6c1d69..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/cookingforblockheads-common.toml
+++ /dev/null
@@ -1,23 +0,0 @@
-#If true, a cow can be squished into a Milk Jar by dropping an anvil on top.
-cowJarEnabled = true
-#The amount of milk the cow in a jar generates per tick.
-#Range: 0.0 ~ 3.4028234663852886E38
-cowJarMilkPerTick = 0.5
-#Set this to true if you'd like the sink to require water to be piped in, instead of providing infinite of it.
-sinkRequiresWater = false
-#Enabling this will make the kitchen counters have twice as much inventory space.
-largeCounters = false
-#Set this to true if you'd like to disallow automation of the oven (pipes and such won't be able to insert/extract)
-disallowOvenAutomation = false
-#The fuel multiplier for the cooking oven. Higher values means fuel lasts longer, 1.0 is furnace default.
-#Range: 0.10000000149011612 ~ 2.0
-ovenFuelTimeMultiplier = 0.33000001311302185
-#The cooking time multiplier for the cooking oven. Higher values means it will take longer.
-#Range: 0.25 ~ 9.0
-ovenCookTimeMultiplier = 1.0
-#Set this to true if you'd like the oven to only accept cooking oil as fuel (requires Pam's Harvestcraft)
-ovenRequiresCookingOil = false
-#Ex Compressum compatibility. Multiplier applied to the milk per tick for Compressed Cow in a Jar.
-#Range: 0.0 ~ 3.4028234663852886E38
-compressedCowJarMilkMultiplier = 9.0
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/cosmeticarmorreworked-common.toml b/configuration/services/configs/minecraft/voor-kia/config/cosmeticarmorreworked-common.toml
deleted file mode 100644
index bb30134..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/cosmeticarmorreworked-common.toml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-#These settings affects both server and client
-[Common]
-	#Whether or not to disable the RecipeBook in the CosmeticArmorInventory
-	CosArmorDisableRecipeBook = false
-	#Whether or not to keep items in cosmetic armor slots in the event of player death
-	CosArmorKeepThroughDeath = false
-	#Whether or not to disable the coshat command
-	CosArmorDisableCosHatCommand = false
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/create-common.toml b/configuration/services/configs/minecraft/voor-kia/config/create-common.toml
deleted file mode 100644
index c01195c..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/create-common.toml
+++ /dev/null
@@ -1,136 +0,0 @@
-
-[worldgen]
-
-	# 
-	#Modify Create's impact on your terrain
-	[worldgen.v2]
-		# 
-		#Prevents all worldgen added by Create from taking effect
-		disableWorldGen = false
-
-		[worldgen.v2.copper_ore]
-			# 
-			#Range: > 0
-			minHeight = 40
-			# 
-			#Range: > 0
-			maxHeight = 85
-			# 
-			#Range: > 0
-			clusterSize = 18
-			# 
-			#Amount of clusters generated per Chunk.
-			#  >1 to spawn multiple.
-			#  <1 to make it a chance.
-			#  0 to disable.
-			#Range: 0.0 ~ 512.0
-			frequency = 2.0
-
-		[worldgen.v2.weathered_limestone]
-			# 
-			#Range: > 0
-			minHeight = 10
-			# 
-			#Range: > 0
-			maxHeight = 30
-			# 
-			#Range: > 0
-			clusterSize = 128
-			# 
-			#Amount of clusters generated per Chunk.
-			#  >1 to spawn multiple.
-			#  <1 to make it a chance.
-			#  0 to disable.
-			#Range: 0.0 ~ 512.0
-			frequency = 0.015625
-
-		[worldgen.v2.zinc_ore]
-			# 
-			#Range: > 0
-			minHeight = 15
-			# 
-			#Range: > 0
-			maxHeight = 70
-			# 
-			#Range: > 0
-			clusterSize = 14
-			# 
-			#Amount of clusters generated per Chunk.
-			#  >1 to spawn multiple.
-			#  <1 to make it a chance.
-			#  0 to disable.
-			#Range: 0.0 ~ 512.0
-			frequency = 4.0
-
-		[worldgen.v2.limestone]
-			# 
-			#Range: > 0
-			minHeight = 30
-			# 
-			#Range: > 0
-			maxHeight = 70
-			# 
-			#Range: > 0
-			clusterSize = 128
-			# 
-			#Amount of clusters generated per Chunk.
-			#  >1 to spawn multiple.
-			#  <1 to make it a chance.
-			#  0 to disable.
-			#Range: 0.0 ~ 512.0
-			frequency = 0.015625
-
-		[worldgen.v2.dolomite]
-			# 
-			#Range: > 0
-			minHeight = 20
-			# 
-			#Range: > 0
-			maxHeight = 70
-			# 
-			#Range: > 0
-			clusterSize = 128
-			# 
-			#Amount of clusters generated per Chunk.
-			#  >1 to spawn multiple.
-			#  <1 to make it a chance.
-			#  0 to disable.
-			#Range: 0.0 ~ 512.0
-			frequency = 0.015625
-
-		[worldgen.v2.gabbro]
-			# 
-			#Range: > 0
-			minHeight = 20
-			# 
-			#Range: > 0
-			maxHeight = 70
-			# 
-			#Range: > 0
-			clusterSize = 128
-			# 
-			#Amount of clusters generated per Chunk.
-			#  >1 to spawn multiple.
-			#  <1 to make it a chance.
-			#  0 to disable.
-			#Range: 0.0 ~ 512.0
-			frequency = 0.015625
-
-		[worldgen.v2.scoria]
-			# 
-			#Range: > 0
-			minHeight = 0
-			# 
-			#Range: > 0
-			maxHeight = 10
-			# 
-			#Range: > 0
-			clusterSize = 128
-			# 
-			#Amount of clusters generated per Chunk.
-			#  >1 to spawn multiple.
-			#  <1 to make it a chance.
-			#  0 to disable.
-			#Range: 0.0 ~ 512.0
-			frequency = 0.03125
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/decorative_blocks-common.toml b/configuration/services/configs/minecraft/voor-kia/config/decorative_blocks-common.toml
deleted file mode 100644
index 2ae0b55..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/decorative_blocks-common.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-#Decorative Blocks Configs
-[general]
-	#Bonfire Activator (define a resource location
-	"bonfire activator" = "minecraft:blaze_powder"
-	#Disable thatch creation on shearing hay bale
-	"thatch enabled" = true
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/farmingforblockheads-common.toml b/configuration/services/configs/minecraft/voor-kia/config/farmingforblockheads-common.toml
deleted file mode 100644
index e4b9a38..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/farmingforblockheads-common.toml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-#Common config for Farming for Blockheads
-[common]
-	#The range within animals can be fed by the feeding trough.
-	#Range: 1 ~ 16
-	feedingTroughRange = 8
-	#The chance for Fertilized Farmland to turn back into regular Farmland (per provided bonus).
-	#Range: 0.0 ~ 1.0
-	fertilizerRegressionChance = 0.0
-	#The chance to get a bonus growth when using Red Fertilizer.
-	#Range: 0.0 ~ 1.0
-	fertilizerBonusGrowthChance = 1.0
-	#List of names the merchant can have.
-	merchantNames = ["Swap-O-Matic", "Emerald Muncher", "Weathered Salesperson"]
-	#The range at which the chicken nest picks up laid eggs.
-	#Range: 1 ~ 16
-	chickenNestRange = 8
-	#The maximum amount of animals (per type) until the feeding trough stops feeding.
-	#Range: > 1
-	feedingTroughMaxAnimals = 8
-	#The chance to get a bonus crop when using Green Fertilizer.
-	#Range: 0.0 ~ 1.0
-	fertilizerBonusCropChance = 1.0
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/farmingforblockheads/MarketRegistry.json b/configuration/services/configs/minecraft/voor-kia/config/farmingforblockheads/MarketRegistry.json
deleted file mode 100644
index 9e26dfe..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/farmingforblockheads/MarketRegistry.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/fastbench.cfg b/configuration/services/configs/minecraft/voor-kia/config/fastbench.cfg
deleted file mode 100644
index 707f5ac..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/fastbench.cfg
+++ /dev/null
@@ -1,8 +0,0 @@
-# Configuration file
-
-general {
-    # If the recipe book is removed from the game.  Server-enforced. [default: true]
-    B:"Remove Recipe Book"=true
-}
-
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/fml.toml b/configuration/services/configs/minecraft/voor-kia/config/fml.toml
deleted file mode 100644
index e1ca72d..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/fml.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-# Enable forge global version checking
-versionCheck = true
-# does the splashscreen run
-splashscreen = true
-defaultConfigPath = "defaultconfigs"
-# max threads for parallel loading : -1 uses Runtime#availableProcessors
-maxThreads = -1
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/forge-common.toml b/configuration/services/configs/minecraft/voor-kia/config/forge-common.toml
deleted file mode 100644
index bef1dd9..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/forge-common.toml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-#General configuration settings
-[general]
-	#Defines a default world type to use. The vanilla default world type is represented by 'default'.
-	#The modded world types are registry names which should include the registry namespace, such as 'examplemod:example_world_type'.
-	defaultWorldType = "default"
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/hardcorerevival-common.toml b/configuration/services/configs/minecraft/voor-kia/config/hardcorerevival-common.toml
deleted file mode 100644
index e0f6a28..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/hardcorerevival-common.toml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-[general]
-	#If true, knocked out players will glow, making them visible through blocks.
-	glowOnKnockout = true
-	#The time in ticks in which a player can still be rescued from death. Set to 0 to disable the timer.
-	#Range: > 0
-	ticksUntilDeath = 2400
-	#If true, the timer until death continues even if the player logs out.
-	continueTimerWhileOffline = false
-
-[rescue]
-	#The distance at which a player can rescue another.
-	#Range: 0.0 ~ 3.4028234663852886E38
-	rescueDistance = 5.0
-	#The time in ticks it takes to rescue a player.
-	#Range: > 0
-	rescueActionTicks = 40
-	#The amount of health to respawn with when a player was rescued, out of 20.
-	#Range: > 1
-	rescueRespawnHealth = 1
-	#The food level to respawn with when a player was rescued, out of 20.
-	#Range: > 0
-	rescueRespawnFoodLevel = 5
-	#Effects applied to a player when rescued, in the format "effect|duration|amplifier"
-	rescueRespawnEffects = ["minecraft:hunger|600|0", "minecraft:weakness|1200|0"]
-
-[restrictions]
-	#If true, knocked out players are still able to punch nearby enemies.
-	allowUnarmedMelee = false
-	#If true, knocked out players are still able to fire bows.
-	allowBows = false
-	#If true, knocked out players are still able to fire pistols from Mr Crayfish's Gun Mod.
-	allowPistols = false
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire-biomes.toml b/configuration/services/configs/minecraft/voor-kia/config/iceandfire-biomes.toml
deleted file mode 100644
index 348d773..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire-biomes.toml
+++ /dev/null
@@ -1,89 +0,0 @@
-
-#Biome config
-#To filter biomes by registry name "mod_id:biome_id"
-#To filter biomes by category "@category"
-#To filter biomes by tags "#tag"
-#	Examples:
-#		"minecraft:plains"
-#		"@desert"
-#		"#overworld"
-#
-#If you want to exclude biomes put a ! before the biome identifier
-#	Examples:
-#		"!minecraft:plains"
-#		"!@desert"
-#		"!#nether"
-#
-#If you want to include biomes that would be satisfied by any in a set use |
-#	Examples:
-#		"|minecraft:plains"
-#		"|@desert"
-#		"|#nether"
-#
-#If you want a condition that MUST be satisfied use an & before the biome identifier
-#Please note using this on a registry name wouldn't be that useful
-#	Examples:
-#		"&minecraft:plains"
-#		"&@forest"
-#		"&#overworld"
-#
-#NOTE: Any entry without a !, |, or & symbol has a higher precedence
-#A list like ["!minecraft:plains", "#overworld"] would still see the plains as a viable biome
-#
-#Finally, you can create a expression that can be evaluated by itself using a + to combine identifiers
-#	Examples:
-#		"!#hot+!#dry+!#mountain"
-#
-#These expressions can be used to filter biomes in a lot of ways
-#Lets say we don't want anything to spawn in any place dry and sandy
-#	"!#dry+!#sandy"
-#
-#But there is a hot place we want them to spawn that's also wet
-#	"#hot+#wet"
-#
-#We just put them as separate values in the list and that'll work out
-#	["!#dry+!#sandy","#hot+#wet"]
-#
-#NOTE: Any entry that's an expression will not be affected by anything else in the list
-[biome_configs]
-	deathwormBiomes = ["&#overworld+|@desert"]
-	lightningDragonBiomes = ["&#overworld+|#jungle+|#mesa+|#savanna+"]
-	cockatriceBiomes = ["&#overworld+|@savanna+|#savanna"]
-	blackHippogryphBiomes = ["minecraft:desert_hills"]
-	lightningLilyBiomes = ["&#overworld+|@savanna+|#savanna"]
-	sirenBiomes = ["&#overworld+|@ocean+|#ocean"]
-	amphithereBiomes = ["&#overworld+|#jungle"]
-	fireDragonSkeletonBiomes = ["&#overworld+|@desert"]
-	brownHippogryphBiomes = ["&#overworld+|#mountains+|@extreme_hills"]
-	amethystBiomes = ["&#overworld+|@savanna+|#savanna"]
-	hippocampusBiomes = ["&#overworld+|@ocean+|#ocean"]
-	snowyTrollBiomes = ["&#overworld+|#snowy+|#cold"]
-	hippogryphBiomes = ["&#overworld+|#mesa+|#mountains+|#hills+|@extreme_hills"]
-	iceDragonSkeletonBiomes = ["&#overworld+&#snowy+|@icy+|#cold+"]
-	jungleMyrmexBiomes = ["&#overworld+|#jungle"]
-	mausoleumBiomes = ["&#overworld+&#snowy+|@icy+|#cold+"]
-	sapphireBiomes = ["&#overworld+&#snowy+|@icy+|#cold+"]
-	mountainTrollBiomes = ["&#overworld+|#mountains+|@extreme_hills"]
-	iceLilyBiomes = ["&#overworld+&#snowy+|@icy+|#cold+"]
-	chestnutHippogryphBiomes = ["minecraft:wooded_mountains"]
-	pixieBiomes = ["&#overworld+|#rare+|#magical+|#dense+&#forest+!@taiga+!#hills+!#mountain+!#wet+!#hot+!#cold+!#dry"]
-	creamyHippogryphBiomes = ["minecraft:savanna_plateau"]
-	overworldSpawnBiomes = ["|#overworld"]
-	forestTrollBiomes = ["&#overworld+|@forest+|#forest"]
-	grayHippogryphBiomes = ["minecraft:dark_forest_hills"]
-	seaSerpentBiomes = ["&#overworld+|@ocean+|#ocean"]
-	cyclopsCaveBiomes = ["&#overworld+|@beach+|#beach"]
-	stymphalianBiomes = ["&#overworld+|@swamp+|#swamp+"]
-	gorgonTempleBiomes = ["&#overworld+|@beach+|#beach"]
-	hydraBiomes = ["&#overworld+|@swamp+|#swamp+"]
-	whiteHippogryphBiomes = ["minecraft:snowy_mountains", "minecraft:snowy_taiga_mountains", "minecraft:snowy_taiga_hills"]
-	fireLilyBiomes = ["&#overworld+|#hot+"]
-	graveyardBiomes = ["&#overworld+!@ocean+!#ocean+!@beach+!#beach"]
-	oreGenBiomes = ["|#overworld"]
-	iceDragonBiomes = ["&#overworld+|@icy+|#snowy+|#cold+"]
-	darkBrownHippogryphBiomes = ["minecraft:taiga_mountains", "minecraft:taiga_hills"]
-	wanderingCyclopsBiomes = ["&#overworld+|@plains+|#plains"]
-	desertMyrmexBiomes = ["&#overworld+|@desert"]
-	lightningDragonSkeletonBiomes = ["&#overworld+|@savanna+|#savanna"]
-	fireDragonBiomes = ["&#overworld+|#hot+|#plains+!#wet+!#cold+!#forest+!#jungle+!#mesa+!#savanna"]
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire-common.toml b/configuration/services/configs/minecraft/voor-kia/config/iceandfire-common.toml
deleted file mode 100644
index 3ebb545..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire-common.toml
+++ /dev/null
@@ -1,452 +0,0 @@
-[Generation]
-
-    [Generation.Dimensions]
-        #True if using blacklists, false if using whitelists for dragons and structure gen.
-        "Use Dimension Blacklist" = false
-        #Whitelist dragon gen dimensions. Use the format like "minecraft:the_nether" or "rats:ratlantis" 
-        whitelistDimensionsDragons = ["minecraft:overworld"]
-        #Whitelisted feature(cyclops caves, hydra dens, etc) gen dimensions. Use the format like "minecraft:the_nether" or "rats:ratlantis" 
-        whitelistDimensionsFeature = ["minecraft:overworld"]
-        #Whitelist mob spawn (troll, hippogryph, etc) dimensions. Use the format like "minecraft:the_nether" or "rats:ratlantis" 
-        whitelistDimensionsMobs = ["minecraft:overworld"]
-        #Blacklisted dragon gen dimensions. Use the format like "minecraft:the_nether" or "rats:ratlantis" 
-        blacklistDimensionsDragons = ["minecraft:the_nether", "minecraft:the_end"]
-        #Blacklisted feature(cyclops caves, hydra dens, etc) gen dimensions. Use the format like "minecraft:the_nether" or "rats:ratlantis" 
-        blacklistDimensionsFeature = ["minecraft:the_nether", "minecraft:the_end"]
-        #Blacklisted mob spawn (troll, hippogryph, etc) dimensions. Use the format like "minecraft:the_nether" or "rats:ratlantis" 
-        blacklistDimensionsMobs = ["minecraft:the_nether", "minecraft:the_end"]
-
-    [Generation.Ores]
-        #Whether to generate copper ore or not
-        "Generate Copper Ore" = false
-        #Whether to generate silver ore or not
-        "Generate Silver Ore" = true
-        #Whether to generate sapphire ore or not
-        "Generate Sapphire Ore" = true
-        #Whether to generate amethyst ore or not
-        "Generate Amethyst Ore" = true
-
-    [Generation.Dragon]
-        #Whether to generate dragon skeletons or not
-        "Generate Dragon Skeletons" = true
-        #1 out of this number chance per chunk for generation
-        #Range: 1 ~ 10000
-        "Generate Dragon Skeleton Chance" = 300
-        #Whether to generate dragon caves or not
-        "Generate Dragon Caves" = true
-        #1 out of this number chance per chunk for generation
-        #Range: 1 ~ 10000
-        "Generate Dragon Cave Chance" = 200
-        #Whether to generate dragon roosts or not
-        "Generate Dragon Roosts" = true
-        #1 out of this number chance per chunk for generation
-        #Range: 1 ~ 10000
-        "Generate Dragon Roost Chance" = 1000
-        #1 out of this number chance per block that gold will generate in dragon lairs.
-        #Range: 1 ~ 10000
-        "Dragon Den Gold Amount" = 4
-        #Ratio of Stone(this number) to Ores in Dragon Caves
-        #Range: 1 ~ 10000
-        "Dragon Cave Ore Ratio" = 45
-
-    [Generation.Structures-Features]
-        #How far away dangerous structures(dragon roosts, cyclops caves, etc.) must be from spawn(0, 0).
-        #Range: 1 ~ 10000
-        "Dangerous World Gen Dist From Spawn" = 2000
-        #How far away dangerous structures(dragon roosts, cyclops caves, etc.) must be from the last generated structure.
-        #Range: 1 ~ 10000
-        "Dangerous World Gen Dist Seperation" = 500
-        #Whether to generate glacier biomes or not
-        "Generate Glaciers" = true
-        #Glacier Spawn Weight. Higher number = more common
-        #Range: 1 ~ 10000
-        "Glacier Spawn Weight" = 4
-        #True if mausoleums are allowed to generate
-        "Generate Mausoleums" = true
-        #One out of this number chance per chunk to generate a mausoleum.
-        #Range: 1 ~ 10000
-        "Mausoleum Gen Chance" = 5000
-        #Whether to generate graveyards or not
-        "Generate Graveyards" = true
-        #Graveyard rarity.
-        #Range: 2 ~ 10000
-        "Graveyard Chance" = 100
-
-[Dragons]
-
-    [Dragons.Griefing]
-        #Dragon griefing - 2 is no griefing, 1 is breaking weak blocks, 0 is default
-        #Range: 0 ~ 2
-        "Dragon Griefing" = 2
-        #True if tamed dragons can follow the griefing rules.
-        "Tamed Dragon Griefing" = false
-        #The percentage chance for a block to drop as an item when a dragon breaks it.
-        #Range: 0.0 ~ 1.0
-        "Dragon Block Breaking Drop Chance" = 0.10000000149011612
-        #Blocks that a dragon cannot break. Use the format like "minecraft:chest" or "rats:block_of_cheese" 
-        blacklistedBreakBlocks = []
-        #Blocks that a dragon can break, but won't spawn drops for. Use the format like "minecraft:stone" or "rats:block_of_cheese" 
-        noDropBreakBlocks = ["minecraft:stone", "minecraft:dirt", "minecraft:grass_block"]
-
-    [Dragons.Attributes]
-        #How long it takes(in ticks) for a dragon egg to hatch
-        #Range: > 1
-        "Dragon Egg Hatch Time" = 7200
-        #Dragon Flap Noise Distance - Larger number, further away you can hear it
-        #Range: 0 ~ 10000
-        "Dragon Flap Noise Distance" = 4
-        #Dragon Flute Distance - how many chunks away is the dragon flute effective?
-        #Range: 0 ~ 10000
-        "Dragon Flute Distance" = 4
-        #Max dragon health. Health is scaled to this
-        #Range: 1.0 ~ 100000.0
-        "Dragon Health" = 500.0
-        #Max dragon attack damage. Attack Damage is scaled to this
-        #Range: 1 ~ 10000
-        "Dragon Attack Damage" = 17
-        #Damage dealt from a successful fire breath attack. Attack Damage is scaled to by age, so a stage 5 dragon will deal 5x as much as this number
-        #Range: 0.0 ~ 10000.0
-        "Dragon Attack Damage(Fire breath)" = 2.0
-        #Damage dealt from a successful ice breath attack. Attack Damage is scaled to by age, so a stage 5 dragon will deal 5x as much as this number
-        #Range: 0.0 ~ 10000.0
-        "Dragon Attack Damage(Ice breath)" = 2.5
-        #Damage dealt from a successful lightning breath attack. Attack Damage is scaled to by age, so a stage 5 dragon will deal 5x as much as this number
-        #Range: 0.0 ~ 10000.0
-        "Dragon Attack Damage(Lightning breath)" = 3.5
-        #Change this to slow down or speed up dragon or amphithere flight.
-        #Range: 0.0 ~ 2.0
-        "Dragon Flight Speed Modifier" = 1.0
-        #Enable this if your server is being bombarded with moved wrongly or moved too fast console messages. REQUIRES RESTART!
-        "Dragon Moved Wrongly Error Fix" = false
-
-    [Dragons.Behaviour]
-        #How high dragons can fly, in Y height.
-        #Range: > 100
-        "Max Dragon Flight Height" = 128
-        #How far away dragons will detect gold blocks being destroyed or chests being opened
-        #Range: 0 ~ 10000
-        "Dragon Gold Search Length" = 30
-        #True if dragons can despawn. Note that if this is false there may be SERIOUS lag issues.
-        "Dragons Despawn" = true
-        #True if tamed dragons go to sleep at night.
-        "Tamed Dragons Sleep" = true
-        #True if dragons can break blocks if they get stuck. Turn this off if your dragons randomly explode.
-        "Dragons Dig When Stuck" = true
-        #True if dragons can drop their skull on death.
-        "Dragons Drop Skull" = true
-        #True if dragons can drop their heart on death.
-        "Dragons Drop Heart" = true
-        #True if dragons can drop their blood on death.
-        "Dragons Drop Blood" = true
-        #True if dragons fire/ice charges create secondary explosions that launch blocks everywhere. Turn this to true if you like unfair explosions. Or lag.
-        "Explosive Dragon Breath" = false
-        #How many blocks away can dragons spot potential prey. Note that increasing this could cause lag.
-        #Range: 1 ~ 10000
-        "Dragon Target Search Length" = 128
-        #How many blocks away can dragons wander from their defined "home" position.
-        #Range: 1 ~ 10000
-        "Dragon Wander From Home Distance" = 40
-        #Every interval of this number in ticks, dragon hunger decreases.
-        #Range: 1 ~ 10000
-        "Dragon Hunger Tick Rate" = 3000
-        #Every interval of this number in ticks, dragon allowed to break blocks.
-        #Range: 0 ~ 10000
-        "Dragon Block Break Cooldown" = 5
-        #True if villagers should run away and hide from dragons and other hostile Ice and Fire mobs.
-        "Villagers Fear Dragons" = true
-        #True if animals should run away and hide from dragons and other hostile Ice and Fire mobs.
-        "Animals Fear Dragons" = true
-        #A more intelligent dragon pathfinding system, but is also laggier. Turn this on if you think dragons are too stupid.
-        "Intelligent Dragon Pathfinding" = false
-
-[Mobs]
-
-    [Mobs.Pixies]
-        #True if pixie villages are allowed to spawn
-        "Spawn Pixies" = true
-        #1 out of this number chance per chunk for generation
-        #Range: 1 ~ 10000
-        "Spawn Pixies Chance" = 800
-        #size of pixie villages
-        #Range: 1 ~ 10000
-        "Pixie Village Size" = 5
-        #True if pixies are allowed to steal from players
-        "Pixies Steal Items" = true
-
-    [Mobs.Cyclops]
-        #True if cyclops caves are allowed to spawn
-        "Spawn Cyclopes Caves" = true
-        #1 out of this number chance per chunk for generation
-        #Range: 1 ~ 10000
-        "Spawn Cyclops Cave Chance" = 1000
-        #True if wandering cyclopes are allowed to spawn
-        "Spawn Wandering Cyclopes" = true
-        #1 out of this number chance per chunk for generation
-        #Range: 1 ~ 10000
-        "Spawn Wandering Cyclops Chance" = 300
-        #Maximum cyclops health
-        #Range: 1.0 ~ 10000.0
-        "Cyclops Max Health" = 150.0
-        #How many blocks away can cyclopes detect sheep. Note that increasing this could cause lag.
-        #Range: 1 ~ 10000
-        "Cyclopes Sheep Search Length" = 17
-        #Cyclops attack strength
-        #Range: 1.0 ~ 10000.0
-        "Cyclops Attack Strength" = 15.0
-        #Amount of damage done with cyclops bite attack.
-        #Range: 1.0 ~ 10000.0
-        "Cyclops Bite Strength" = 40.0
-        #Whether or not cyclops can break logs or leaves in their way
-        "Cyclops Griefing" = false
-
-    [Mobs.Sirens]
-        #Maximum siren health
-        #Range: 1.0 ~ 10000.0
-        "Siren Max Health" = 50.0
-        #True if siren islands are allowed to spawn
-        "Spawn Sirens" = true
-        #True to make the screen pink when sirens attract players
-        "Use Siren Shader" = true
-        #1 out of this number chance per chunk for generation
-        #Range: 1 ~ 10000
-        "Spawn Sirens Chance" = 400
-        #how long(in ticks) can a siren use its sing effect on a player, without a cooldown.
-        #Range: 100 ~ 24000
-        "Siren Max Sing Time" = 12000
-        #how long(in ticks) a siren has to wait after failing to lure in a player
-        #Range: 100 ~ 24000
-        "Siren Time Between Songs" = 2000
-
-    [Mobs.DeathWorms]
-        #How many blocks away can death worms spot potential prey. Note that increasing this could cause lag
-        #Range: 1 ~ 10000
-        "Death Worm Target Search Length" = 64
-        #Default deathworm health, this is scaled to the worm's particular size
-        #Range: 1.0 ~ 10000.0
-        "Death Worm Base Health" = 10.0
-        #Default deathworm attack strength, this is scaled to the worm's particular size
-        #Range: 1.0 ~ 10000.0
-        "Death Worm Base Attack Strength" = 3.0
-        #True if deathworms are allowed to spawn
-        "Spawn Death Worms" = true
-        #True if wild deathworms are allowed to target and attack monsters
-        "Death Worms Target Monsters" = true
-        #Deathworm spawn weight. Higher = lower chance to spawn
-        #Range: 1 ~ 10000
-        "Death Worm Spawn Weight" = 100
-        #A double check to see if the game can spawn death worms. Higher number = lower chance to spawn.
-        #Range: 0 ~ 10000
-        "Death Worm Spawn Check Chance" = 3
-
-    [Mobs.Cockatrice]
-        #Maximum cockatrice health
-        #Range: 1.0 ~ 10000.0
-        "Cockatrice Health" = 40.0
-        #1 out of this number chance per 6000 ticks for a chicken to lay a cockatrice egg.
-        #Range: > 1
-        "Cockatrice chicken Search Length" = 30
-        #True if chickens lay rotten eggs.
-        "Chickens Lay Rotten Eggs" = true
-        #True if cockatrices are allowed to spawn
-        "Spawn Cockatrices" = true
-        #Cockatrice spawn weight. Lower = lower chance to spawn
-        #Range: 1 ~ 10000
-        "Cockatrice Spawn Weight" = 4
-        #A double check to see if the game can spawn cockatrices. Higher number = lower chance to spawn.
-        #Range: 0 ~ 10000
-        "Cockatrice Spawn Check Chance" = 1000
-
-    [Mobs.Stymphalians]
-        #How many blocks away can stymphalian birds spot potential prey. Note that increasing this could cause lag.
-        #Range: 1 ~ 10000
-        "Stymphalian Bird Target Search Length" = 64
-        #1/this number chance for a stymphalian feather to turn into an item before despawning. Zero means never.
-        #Range: 0 ~ 10000
-        "Stymphalian Bird Feather Drop Chance" = 25
-        #Stymphalian bird feather attack strength.
-        #Range: 0.0 ~ 10000.0
-        "Stymphalian Bird Feather Attack Strength" = 1.0
-        #How far away stymphalian birds will consider other birds to be in the same flock.
-        #Range: 1 ~ 10000
-        "Stymphalian Bird Flock Length" = 40
-        #How high stymphalian birds can fly, in Y height.
-        #Range: > 10
-        "Max Stymphalian Bird Flight Height" = 80
-        #True if stymphalian birds are allowed to spawn
-        "Spawn Stymphalian Birds" = true
-        #True if stymphalian birds can drop items registered in the ore dictionary to ingotCopper, ingotBronze, nuggetCopper, nuggetBronze.
-        "Stymphalian Birds drop ore dict items" = true
-        #True if stymphalian birds are allowed to target and attack animals
-        "Stymphalian Birds Target Animals" = false
-        #1 out of this number chance per chunk for generation
-        #Range: 1 ~ 10000
-        "Spawn Stymhphalian Bird Chance" = 500
-
-    [Mobs.Trolls]
-        #True if trolls are allowed to spawn
-        "Spawn Trolls" = true
-        #True if trolls are allowed to drop their weapon on death.
-        "Trolls Drop Weapon" = true
-        #Troll spawn weight. Lower = lower chance to spawn
-        #Range: 1 ~ 10000
-        "Troll Spawn Weight" = 40
-        #A double check to see if the game can spawn trolls. Higher number = lower chance to spawn.
-        #Range: 0 ~ 10000
-        "Troll Spawn Check Chance" = 10
-        #Maximum troll health
-        #Range: 1.0 ~ 10000.0
-        "Troll Max Health" = 50.0
-        #Troll attack strength
-        #Range: 1.0 ~ 10000.0
-        "Troll Attack Strength" = 10.0
-
-    [Mobs.Myrmex]
-        #True if myrmex colonies are allowed to spawn
-        "Spawn Myrmex" = true
-        #How many ticks it takes for a Myrmex Queen to produce an egg.
-        #Range: 1 ~ 10000
-        "Myrmex Gestation Length" = 2500
-        #How many ticks it takes for a Myrmex to move from a larva to a pupa, and from a pupa to an adult.
-        #Range: 1 ~ 100000
-        "Myrmex Hatch Length" = 35000
-        #One out of this number chance per chunk to generate a myrmex hive.
-        #Range: 1 ~ 10000
-        "Myrmex Colony Gen Chance" = 1500
-        #How many maximum individuals a myrmex colony can have.
-        #Range: 10 ~ 10000
-        "Myrmex Colony Max Size" = 80
-        #Base Myrmex(worker) attack strength
-        #Range: 1.0 ~ 10000.0
-        "Myrmex Base Attack Strength" = 3.0
-        #The maximum radius myrmex area allowed to wander/forage
-        #Range: 100 ~ 20000
-        "Myrmex Maximum Wnader Radius" = 4000
-
-    [Mobs.Amphitheres]
-        #True if amphitheres are allowed to spawn
-        "Spawn Amphitheres" = true
-        #Amphithere spawn weight. Lower = lower chance to spawn
-        #Range: 1 ~ 10000
-        "Amphithere Spawn Weight" = 50
-        #How many blocks away can ampitheres detect villagers being hurt. Note that increasing this could cause lag.
-        #Range: 1 ~ 10000
-        "Amphithere Villager Search Length" = 64
-        #How many ticks it takes while riding an untamed amphithere to tame it.
-        #Range: 1 ~ 10000
-        "Amphithere Tame Time" = 400
-        #How fast amphitheres fly.
-        #Range: 0.0 ~ 3.0
-        "Amphithere Flight Speed" = 1.75
-        #Maximum amphithere health
-        #Range: 1.0 ~ 10000.0
-        "Amphithere Max Health" = 50.0
-        #Amphithere attack strength
-        #Range: 1.0 ~ 10000.0
-        "Amphithere Attack Strength" = 7.0
-
-    [Mobs.SeaSerpents]
-        #True if sea serpents are allowed to spawn
-        "Spawn Sea Serpents" = true
-        #1 out of this number chance per chunk for generation
-        #Range: 1 ~ 10000
-        "Spawn Sea Serpent Chance" = 2500
-        #Whether or not sea serpents can break weak blocks in their way
-        "Sea Serpent Griefing" = false
-        #Default sea serpent health, this is scaled to the sea serpent's particular size
-        #Range: 1.0 ~ 10000.0
-        "Sea Serpent Base Health" = 20.0
-        #Default sea serpent attack strength, this is scaled to the sea serpent's particular size
-        #Range: 1.0 ~ 10000.0
-        "Sea Serpent Base Attack Strength" = 4.0
-
-    [Mobs.Hippocampus]
-        #True if hippocampi are allowed to spawn
-        "Spawn Hippocampus" = true
-        #1 out of this number chance per chunk for generation
-        #Range: 1 ~ 10000
-        "Spawn Hippocampus Chance" = 200
-        #Change this to slow down or speed up hippocampus swimming.
-        #Range: 0.0 ~ 2.0
-        "Hippocampus Swim Speed Modifier" = 1.0
-
-    [Mobs.Hippogryph]
-        #True if hippogryphs are allowed to spawn
-        "Spawn Hippogryphs" = true
-        #Hippogryph spawn weight. Lower = lower chance to spawn.
-        #Range: 1 ~ 10000
-        "Hippogryph Spawn Weight" = 1
-        #Change this to slow down or speed up hippogryph flight.
-        #Range: 0.0 ~ 2.0
-        "Hippogryph Flight Speed Modifier" = 1.0
-
-    [Mobs.Gorgons]
-        #True if gorgon temples are allowed to spawn
-        "Spawn Gorgons" = true
-        #1 out of this number chance per chunk for generation
-        #Range: 1 ~ 10000
-        "Spawn Gorgon Chance" = 10000
-        #Maximum gorgon health
-        #Range: 1.0 ~ 10000.0
-        "Gorgon Max Health" = 100.0
-
-    [Mobs.Others]
-        #True if dread liches are allowed to spawn
-        "Spawn Liches" = true
-        #Dread Lich spawn weight. Lower = lower chance to spawn
-        #Range: 1 ~ 10000
-        "Lich Spawn Weight" = 2
-        #Maximum hydra health
-        #Range: 1.0 ~ 10000.0
-        "Hydra Max Health" = 250.0
-        #True if hydra caves are allowed to generate
-        "Generate Hydra Caves" = true
-        #One out of this number chance per chunk to generate a hydra cave.
-        #Range: 1 ~ 10000
-        "Hydra Caves Gen Chance" = 1000
-        #Maximum ghost health.
-        #Range: 1.0 ~ 10000.0
-        "Ghost Max Health" = 30.0
-        #Maximum ghost attack strength.
-        #Range: 0.0 ~ 10000.0
-        "Ghost Attack Strength" = 3.0
-        #True if ghosts can rarely spawn from brutal PvP deaths.
-        "Ghost Spawn from PvP deaths" = true
-        #Villager Scribe House generation weight. Lower = lower chance to spawn
-        #Range: 30 ~ 10000
-        "Villager Scribe House Weight" = 30
-
-[Items]
-    #Default attack strength of a dragonsteel sword.
-    #Range: 5.0 ~ 2.147483647E9
-    "Dragonsteel Sword Base Attack Strength" = 25.0
-    #Default armor value of dragonsteel chestplate.
-    #Range: > 7
-    "Dragonsteel Base Armor" = 12
-    #Default durability value of dragonsteel tools.
-    #Range: > 1
-    "Dragonsteel Base Durability" = 8000
-    #Default durability value of dragonsteel equipment.
-    #Range: > 1
-    "Dragonsteel Base Durability Equipment" = 8000
-    #Disable this to remove easter egg with tinkers installed.
-    Weezer = true
-    #Percentage of critical strike that will disarm with easter egg tinkers material.
-    #Range: 0.0 ~ 1.0
-    "Easter Egg Tinkers Tool Disarm chance" = 0.20000000298023224
-    #True if the summon crystal can load chunks to find dragons.
-    "Chunk Load Summon Crystal" = true
-    #True if the dragon bone fire sword ignites attackers.
-    "Dragon Bone Fire Abilities" = true
-    #True if the dragon bone ice sword freezes attackers.
-    "Dragon Bone Ice Abilities" = true
-    #True if the dragon bone lightning sword strikes attackers.
-    "Dragon Bone Lightning Abilities" = true
-
-[Pathfinding]
-    #Maximum threads to use for dragon/myrmex pathfinding. Increase this number if pathing is slow and you have many cores.
-    #Range: > 1
-    "Dragon Pathfinding Threads" = 3
-    #Maximum nodes for dragons/myrmex to path too. Decrease this is dragon pathfinding is super slow or intensive.
-    #Range: > 1
-    "Dragon Max Pathfinding Nodes" = 5000
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/amethyst_gen_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/amethyst_gen_biomes.json
deleted file mode 100644
index a74daf4..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/amethyst_gen_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "savanna"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "savanna"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/amphithere_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/amphithere_biomes.json
deleted file mode 100644
index ab82bf2..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/amphithere_biomes.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "jungle"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/cockatrice_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/cockatrice_biomes.json
deleted file mode 100644
index a74daf4..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/cockatrice_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "savanna"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "savanna"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/cyclops_cave_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/cyclops_cave_biomes.json
deleted file mode 100644
index 38e6e45..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/cyclops_cave_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "beach"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "beach"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/deathworm_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/deathworm_biomes.json
deleted file mode 100644
index 7f73edd..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/deathworm_biomes.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "desert"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/desert_myrmex_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/desert_myrmex_biomes.json
deleted file mode 100644
index 7f73edd..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/desert_myrmex_biomes.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "desert"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_dragon_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_dragon_biomes.json
deleted file mode 100644
index 0473537..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_dragon_biomes.json
+++ /dev/null
@@ -1,73 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "hot"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "jungle"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "mesa"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "savanna"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "plains"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "wet"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "cold"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "jungle"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "mesa"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "savanna"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "forest"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_dragon_skeleton_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_dragon_skeleton_biomes.json
deleted file mode 100644
index 7f73edd..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_dragon_skeleton_biomes.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "desert"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_lily_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_lily_biomes.json
deleted file mode 100644
index 53b1af0..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/fire_lily_biomes.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "hot"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/forest_troll_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/forest_troll_biomes.json
deleted file mode 100644
index f2356ca..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/forest_troll_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "forest"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "forest"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/gorgon_temple_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/gorgon_temple_biomes.json
deleted file mode 100644
index 38e6e45..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/gorgon_temple_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "beach"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "beach"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/graveyard_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/graveyard_biomes.json
deleted file mode 100644
index 343fa29..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/graveyard_biomes.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "ocean"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": true,
-        "value": "ocean"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "beach"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": true,
-        "value": "beach"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippocampus_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippocampus_biomes.json
deleted file mode 100644
index 3fba906..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippocampus_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "ocean"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "ocean"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_biomes.json
deleted file mode 100644
index 21e99bd..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_biomes.json
+++ /dev/null
@@ -1,52 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "mesa"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "mountain"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "hills"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "extreme_hills"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_black_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_black_biomes.json
deleted file mode 100644
index eac1949..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_black_biomes.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:desert_hills"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_brown_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_brown_biomes.json
deleted file mode 100644
index 8b33d39..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_brown_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "mountains"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "extreme_hills"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_chestnut_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_chestnut_biomes.json
deleted file mode 100644
index 21211b2..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_chestnut_biomes.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:wooded_mountains"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_creamy_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_creamy_biomes.json
deleted file mode 100644
index 48b78bd..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_creamy_biomes.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:savanna_plateau"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_dark_brown_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_dark_brown_biomes.json
deleted file mode 100644
index 3bdc692..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_dark_brown_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:taiga_mountains"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:taiga_hills"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_gray_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_gray_biomes.json
deleted file mode 100644
index 718a68a..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_gray_biomes.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:dark_forest_hills"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_white_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_white_biomes.json
deleted file mode 100644
index ac739b4..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hippogryph_white_biomes.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:snowy_mountains"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:snowy_taiga_hills"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "REGISTRY_NAME",
-        "negate": false,
-        "value": "minecraft:snowy_taiga_mountains"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hydra_cave_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hydra_cave_biomes.json
deleted file mode 100644
index b696ee0..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/hydra_cave_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "swamp"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "swamp"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_dragon_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_dragon_biomes.json
deleted file mode 100644
index 196b79b..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_dragon_biomes.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "icy"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "snowy"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "cold"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_dragon_skeleton_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_dragon_skeleton_biomes.json
deleted file mode 100644
index 6d766c7..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_dragon_skeleton_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "snowy"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "icy"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_lily_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_lily_biomes.json
deleted file mode 100644
index 6d766c7..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ice_lily_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "snowy"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "icy"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/jungle_myrmex_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/jungle_myrmex_biomes.json
deleted file mode 100644
index ab82bf2..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/jungle_myrmex_biomes.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "jungle"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_dragon_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_dragon_biomes.json
deleted file mode 100644
index d5109e2..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_dragon_biomes.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "jungle"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "mesa"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "savanna"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_dragon_skeleton_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_dragon_skeleton_biomes.json
deleted file mode 100644
index a74daf4..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_dragon_skeleton_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "savanna"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "savanna"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_lily_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_lily_biomes.json
deleted file mode 100644
index a74daf4..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/lightning_lily_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "savanna"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "savanna"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/mausoleum_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/mausoleum_biomes.json
deleted file mode 100644
index 6d766c7..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/mausoleum_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "snowy"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "icy"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/mountain_troll_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/mountain_troll_biomes.json
deleted file mode 100644
index 8b33d39..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/mountain_troll_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "mountains"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "extreme_hills"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ore_gen_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ore_gen_biomes.json
deleted file mode 100644
index fda5d7f..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/ore_gen_biomes.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/pixie_village_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/pixie_village_biomes.json
deleted file mode 100644
index 6110f7b..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/pixie_village_biomes.json
+++ /dev/null
@@ -1,73 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "rare"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "magical"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "dense"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "forest"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "mountain"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "hills"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "wet"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "hot"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "cold"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": true,
-        "value": "dry"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": true,
-        "value": "taiga"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/sapphire_gen_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/sapphire_gen_biomes.json
deleted file mode 100644
index 6d766c7..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/sapphire_gen_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "snowy"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "icy"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/sea_serpent_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/sea_serpent_biomes.json
deleted file mode 100644
index 3fba906..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/sea_serpent_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "ocean"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "ocean"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/siren_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/siren_biomes.json
deleted file mode 100644
index 3fba906..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/siren_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "ocean"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "ocean"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/snowy_troll_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/snowy_troll_biomes.json
deleted file mode 100644
index e4db8f7..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/snowy_troll_biomes.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "snowy"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/stymphalian_bird_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/stymphalian_bird_biomes.json
deleted file mode 100644
index b696ee0..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/stymphalian_bird_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "swamp"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "swamp"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/wandering_cyclops_biomes.json b/configuration/services/configs/minecraft/voor-kia/config/iceandfire/wandering_cyclops_biomes.json
deleted file mode 100644
index 8d890df..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/iceandfire/wandering_cyclops_biomes.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "biomes": [
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "plains"
-      }
-    ],
-    [
-      {
-        "type": "BIOME_DICT",
-        "negate": false,
-        "value": "overworld"
-      },
-      {
-        "type": "BIOME_CATEGORY",
-        "negate": false,
-        "value": "plains"
-      }
-    ]
-  ]
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/ironfurnaces-client.toml b/configuration/services/configs/minecraft/voor-kia/config/ironfurnaces-client.toml
deleted file mode 100644
index c93ee65..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/ironfurnaces-client.toml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-#Update Checker Settings
-[updates]
-
-	[updates.check_updates]
-		# true = check for updates, false = don't check for updates.
-		# Default: true.
-		updates = false
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/ironfurnaces.toml b/configuration/services/configs/minecraft/voor-kia/config/ironfurnaces.toml
deleted file mode 100644
index df164ab..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/ironfurnaces.toml
+++ /dev/null
@@ -1,142 +0,0 @@
-
-#Modded Furnace Settings
-[modded_furnaces]
-
-	[modded_furnaces.vibranium_furnace]
-		# Number of items that can be smelted at once. The regular furnace only smelts 1 item at once of course.
-		# Default: 32
-		#Range: 1 ~ 64
-		mult = 32
-		# Number of ticks to complete one smelting operation.
-		# 200 ticks is what a regular furnace takes.
-		# Default: 3
-		#Range: 1 ~ 72000
-		speed = 3
-
-	[modded_furnaces.allthemodium_furnace]
-		# Number of items that can be smelted at once. The regular furnace only smelts 1 item at once of course.
-		# Default: 16
-		#Range: 1 ~ 64
-		mult = 16
-		# Number of ticks to complete one smelting operation.
-		# 200 ticks is what a regular furnace takes.
-		# Default: 5
-		#Range: 1 ~ 72000
-		speed = 5
-
-	[modded_furnaces.unobtanium_furnace]
-		# Number of items that can be smelted at once. The regular furnace only smelts 1 item at once of course.
-		# Default: 64
-		#Range: 1 ~ 64
-		mult = 64
-		# Number of ticks to complete one smelting operation.
-		# 200 ticks is what a regular furnace takes.
-		# Default: 1
-		#Range: 1 ~ 72000
-		speed = 1
-
-#Furnace Settings
-[furnaces]
-
-	[furnaces.iron_furnace]
-		# Number of ticks to complete one smelting operation.
-		# 200 ticks is what a regular furnace takes.
-		# Default: 160
-		#Range: 2 ~ 72000
-		speed = 160
-
-	[furnaces.obsidian_furnace]
-		# Number of ticks to complete one smelting operation.
-		# 200 ticks is what a regular furnace takes.
-		# Default: 20
-		#Range: 2 ~ 72000
-		speed = 20
-
-	[furnaces.crystal_furnace]
-		# Number of ticks to complete one smelting operation.
-		# 200 ticks is what a regular furnace takes.
-		# Default: 40
-		#Range: 2 ~ 72000
-		speed = 40
-
-	[furnaces.netherite_furnace]
-		# Number of ticks to complete one smelting operation.
-		# 200 ticks is what a regular furnace takes.
-		# Default: 5
-		#Range: 2 ~ 72000
-		speed = 5
-
-	[furnaces.diamond_furnace]
-		# Number of ticks to complete one smelting operation.
-		# 200 ticks is what a regular furnace takes.
-		# Default: 80
-		#Range: 2 ~ 72000
-		speed = 80
-
-	[furnaces.copper_furnace]
-		# Number of ticks to complete one smelting operation.
-		# 200 ticks is what a regular furnace takes.
-		# Default: 180
-		#Range: 2 ~ 72000
-		speed = 180
-
-	[furnaces.furance_xp_drop]
-		# This value indicates when the furnace should 'overload' and spit out the xp stored. 
-		# Default: 10, Recipes
-		#Range: 1 ~ 500
-		value = 10
-		# This value indicates when the furnace should 'overload' and spit out the xp stored. 
-		# Default: 100000, Single recipe uses
-		#Range: 1 ~ 1000000
-		value_two = 100000
-
-	[furnaces.emerald_furnace]
-		# Number of ticks to complete one smelting operation.
-		# 200 ticks is what a regular furnace takes.
-		# Default: 40
-		#Range: 2 ~ 72000
-		speed = 40
-
-	[furnaces.silver_furnace]
-		# Number of ticks to complete one smelting operation.
-		# 200 ticks is what a regular furnace takes.
-		# Default: 140
-		#Range: 2 ~ 72000
-		speed = 140
-
-	[furnaces.rainbow_furnace]
-		# Number of ticks to complete one smelting operation.
-		# 200 ticks is what a regular furnace takes.
-		# Default: 20
-		#Range: 2 ~ 72000
-		speed = 200
-
-	[furnaces.gold_furnace]
-		# Number of ticks to complete one smelting operation.
-		# 200 ticks is what a regular furnace takes.
-		# Default: 120
-		#Range: 2 ~ 72000
-		speed = 120
-
-#JEI Settings
-[jei]
-
-	[jei.jei]
-		# Enable or disable the Click Area inside the GUI in all of Iron Furnaces' furnaces.
-		enable_jei_click_area = true
-		# Enable or disable the Catalysts in Jei for Iron Furnaces.
-		enable_jei_catalysts = true
-		# Enable or disable the JeiPlugin of Iron Furnaces.
-		enable_jei = true
-
-#Misc
-[misc]
-
-	[misc.misc]
-		# Enable or disable the Rainbow Content
-		rainbow = true
-		# Given or not given the Rainbow Coal to our champion
-		coal = false
-		# Show furnace settings errors in chat, used for debugging
-		errors = false
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/jeresources-common.toml b/configuration/services/configs/minecraft/voor-kia/config/jeresources-common.toml
deleted file mode 100644
index 0dd954f..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/jeresources-common.toml
+++ /dev/null
@@ -1,11 +0,0 @@
-#Range: 1 ~ 4
-itemsPerColumn = 4
-#Range: 1 ~ 4
-itemsPerRow = 4
-diyData = true
-showDevData = false
-enchantsBlacklist = ["flimflam", "soulBound"]
-hiddenTabs = []
-dimensionsBlacklist = [-11]
-disableLootManagerReloading = false
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/jeresources.toml b/configuration/services/configs/minecraft/voor-kia/config/jeresources.toml
deleted file mode 100644
index a4f9f5b..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/jeresources.toml
+++ /dev/null
@@ -1,11 +0,0 @@
-disableLootManagerReloading = false
-hiddenTabs = []
-#Range: 1 ~ 4
-itemsPerRow = 4
-enchantsBlacklist = ["flimflam", "soulBound"]
-showDevData = false
-dimensionsBlacklist = [-11]
-diyData = true
-#Range: 1 ~ 4
-itemsPerColumn = 4
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/lottaterracotta-common.toml b/configuration/services/configs/minecraft/voor-kia/config/lottaterracotta-common.toml
deleted file mode 100644
index 2210d90..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/lottaterracotta-common.toml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-[general]
-	#Enable terracotta pressure plates
-	enablePressurePlates = true
-	#Enable terracotta levers
-	enableLevers = true
-	#Enable terracotta buttons
-	enableButtons = true
-	#Enable terracotta signs
-	enableSigns = true
-	#Enable terracotta stairs
-	enableStairs = true
-	#Enable terracotta tiles
-	enableTiles = true
-	#Enable terracotta vertical slabs
-	enableVerticalSlabs = true
-	#Enable terracotta walls
-	enableWalls = true
-	#Enable terracotta fences
-	enableFences = true
-	#Enable terracotta slabs
-	enableSlabs = true
-	#Enable terracotta ladders
-	enableLadders = true
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/overworldtwo.json b/configuration/services/configs/minecraft/voor-kia/config/overworldtwo.json
deleted file mode 100644
index 623db10..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/overworldtwo.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "generate_nether": true,
-  "fast_ores": true
-}
\ No newline at end of file
diff --git a/configuration/services/configs/minecraft/voor-kia/config/pamhc2crops.toml b/configuration/services/configs/minecraft/voor-kia/config/pamhc2crops.toml
deleted file mode 100644
index 0f5a672..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/pamhc2crops.toml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-["Miscellaneous Features"]
-	#Disable/enable fern blocks dropping seeds.
-	"Enable fern blocks dropping seeds" = false
-	#Disable/enable tall grass blocks dropping seeds.
-	"Enable tall grass blocks dropping seeds" = false
-	#Disable/enable right-click harvesting of crops.
-	"Enable both for right-click harvesting for crops" = true
-	#Disable/enable grass blocks dropping seeds.
-	"Enable grass blocks dropping seeds" = false
-
-["Dimensions Settings"]
-	#Enter a dimension id to whitelist feature generation
-	white_dim = ["minecraft:overworld"]
-	#Enter a dimension id to blacklist feature generation
-	black_dim = ["minecraft:the_end", "minecraft:the_nether"]
-
-["Tweak Garden Cluster Sizes"]
-	#Amount of gardens that spawn together. Higher numbers indicate larger clusters; 32 is about 3-7ish (Default: 32)
-	#Range: 1 ~ 1000000000
-	"Probability of gardens generating" = 32
-
-["Tweak Garden World Generation Rates"]
-	#Chance of gardens generating in the world. Higher numbers indicate a lower probability; just 4 is very rare (Default: 2)
-	#Range: 1 ~ 1000000000
-	"Probability of gardens generating" = 2
-
-["Tweak Garden Cluster Rates"]
-	#Chance of gardens generating in the world. Higher numbers indicate a lower probability; just 4 is very rare (Default: 2)
-	#Range: 1 ~ 1000000000
-	"Probability of gardens generating" = 2
-
-["Enable/Disable Garden World Generation"]
-	#Should frost gardens should generate in world
-	"Generate frost gardens" = true
-	#Should arid gardens should generate in world
-	"Generate arid gardens" = true
-	#Should soggy gardens should generate in world
-	"Generate soggy gardens" = true
-	#Should shaded gardens should generate in world
-	"Generate shaded gardens" = true
-	#Should windy gardens should generate in world
-	"Generate windy gardens" = true
-	#Should tropical gardens should generate in world
-	"Generate tropical gardens" = true
-
-["Right-click Harvesting Settings"]
-	#Disable/enable right-click harvesting of crops
-	"Enable both for right-click harvesting for crops" = true
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/pamhc2trees.toml b/configuration/services/configs/minecraft/voor-kia/config/pamhc2trees.toml
deleted file mode 100644
index d04d4fe..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/pamhc2trees.toml
+++ /dev/null
@@ -1,126 +0,0 @@
-
-["Miscellaneous Features"]
-	#Disable/enable fern blocks dropping seeds.
-	"Enable fern blocks dropping seeds" = false
-	#Disable/enable tall grass blocks dropping seeds.
-	"Enable tall grass blocks dropping seeds" = false
-	#Disable/enable grass blocks dropping seeds.
-	"Enable grass blocks dropping seeds" = false
-
-["Dimensions Settings"]
-	#Enter a dimension id to whitelist feature generation
-	white_dim = ["minecraft:overworld"]
-	#Enter a dimension id to blacklist feature generation
-	black_dim = ["minecraft:the_end", "minecraft:the_nether"]
-
-["Tweak World Generation Rates"]
-	#Chance of warm fruit trees generating in the world. Higher numbers indicate a lower probability (Default: 5000)
-	#Range: 1 ~ 1000000000
-	"Probability of warm fruit trees generating" = 5000
-	#Chance of cold fruit trees generating in the world. Higher numbers indicate a lower probability (Default: 5000)
-	#Range: 1 ~ 1000000000
-	"Probability of cold fruit trees generating" = 5000
-	#Chance of temperate fruit trees generating in the world. Higher numbers indicate a lower probability (Default: 5000)
-	#Range: 1 ~ 1000000000
-	"Probability of temperate fruit trees generating" = 5000
-
-["Enable/Disable Garden World Generation"]
-	#Should hazelnut trees generate in world
-	"Generate hazelnut trees" = true
-	#Should guava trees generate in world
-	"Generate guava trees" = true
-	#Should almond trees generate in world
-	"Generate almond trees" = true
-	#Should walnut trees generate in world
-	"Generate walnut trees" = true
-	#Should tamarind trees generate in world
-	"Generate tamarind trees" = true
-	#Should maple trees generate in world
-	"Generate maple trees" = true
-	#Should spiderweb trees generate in world
-	"Generate spiderweb trees" = true
-	#Should peach trees generate in world
-	"Generate peach trees" = true
-	#Should vanillabean trees generate in world
-	"Generate vanillabean trees" = true
-	#Should pomegranate trees generate in world
-	"Generate pomegranate trees" = true
-	#Should apricot trees generate in world
-	"Generate apricot trees" = true
-	#Should passionfruit trees generate in world
-	"Generate passionfruit trees" = true
-	#Should pear trees generate in world
-	"Generate pear trees" = true
-	#Should pawpaw trees generate in world
-	"Generate pawpaw trees" = true
-	#Should coconut trees generate in world
-	"Generate coconut trees" = true
-	#Should breadfruit trees generate in world
-	"Generate breadfruit trees" = true
-	#Should pinenut trees generate in world
-	"Generate pinenut trees" = true
-	#Should jackfruit trees generate in world
-	"Generate jackfruit trees" = true
-	#Should mango trees generate in world
-	"Generate mango trees" = true
-	#Should lychee trees generate in world
-	"Generate lychee trees" = true
-	#Should orange trees generate in world
-	"Generate orange trees" = true
-	#Should plum trees generate in world
-	"Generate plum trees" = true
-	#Should soursop trees generate in world
-	"Generate soursop trees" = true
-	#Should lemon trees generate in world
-	"Generate lemon trees" = true
-	#Should rambutan trees generate in world
-	"Generate rambutan trees" = true
-	#Should gooseberry trees generate in world
-	"Generate gooseberry trees" = true
-	#Should papaya trees generate in world
-	"Generate papaya trees" = true
-	#Should avocado trees generate in world
-	"Generate avocado trees" = true
-	#Should apple trees generate in world
-	"Generate apple trees" = true
-	#Should peppercorn trees generate in world
-	"Generate peppercorn trees" = true
-	#Should banana trees generate in world
-	"Generate banana trees" = true
-	#Should fig trees generate in world
-	"Generate fig trees" = true
-	#Should olive trees generate in world
-	"Generate olive trees" = true
-	#Should cinnamon trees generate in world
-	"Generate cinnamon trees" = true
-	#Should pecan trees generate in world
-	"Generate pecan trees" = true
-	#Should almond date generate in world
-	"Generate date trees" = true
-	#Should grapefruit trees generate in world
-	"Generate grapefruit trees" = true
-	#Should candlenut trees generate in world
-	"Generate candlenut trees" = true
-	#Should cherry trees generate in world
-	"Generate cherry trees" = true
-	#Should pistachio trees generate in world
-	"Generate pistachio trees" = true
-	#Should dragonfruit trees generate in world
-	"Generate dragonfruit trees" = true
-	#Should chestnut trees generate in world
-	"Generate chestnut trees" = true
-	#Should lime trees generate in world
-	"Generate lime trees" = true
-	#Should nutmeg trees generate in world
-	"Generate nutmeg trees" = true
-	#Should durian trees generate in world
-	"Generate durian trees" = true
-	#Should cashew trees generate in world
-	"Generate cashew trees" = true
-	#Should persimmon trees generate in world
-	"Generate persimmon trees" = true
-	#Should starfruit trees generate in world
-	"Generate starfruit trees" = true
-	#Should paperbark trees generate in world
-	"Generate paperbark trees" = true
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/passablefoliage-common.toml b/configuration/services/configs/minecraft/voor-kia/config/passablefoliage-common.toml
deleted file mode 100644
index cf51d2f..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/passablefoliage-common.toml
+++ /dev/null
@@ -1,24 +0,0 @@
-#The percentage of normal damage taken when taking damage from falling into leaves.
-#The damage will be reduced by a further 10% with the Jump Boost potion effect.
-#Range: 0.0 ~ 1.0
-fallDamageReduction = 0.5
-#When falling into leaves, the (block) distance a player or mob has to fall before taking damage.
-#Range: 5 ~ 255
-fallDamageThreshold = 20
-#The reduced horizontal speed when passing through leaves. (% of normal)
-#Range: 0.0 ~ 1.0
-speedReductionHorizontal = 0.8999999761581421
-#The reduced vertical speed when passing through leaves. (% of normal)
-#Range: 0.0 ~ 1.0
-speedReductionVertical = 0.8999999761581421
-#Should entities recognize leaves as air
-modifyPathFinding = true
-#Leaves only passable for players
-playerOnly = false
-
-[sounds]
-	#Range: 0.0 ~ 10.0
-	volume = 1.0
-	#Only players can make noises
-	playerOnly = false
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/performant-common.toml b/configuration/services/configs/minecraft/voor-kia/config/performant-common.toml
deleted file mode 100644
index 07a2e01..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/performant-common.toml
+++ /dev/null
@@ -1,138 +0,0 @@
-#Enables logging the too large packets causing disconnects. , default = true
-displayTooLargePackets = true
-
-["Load balancing settings"]
-
-	["Load balancing settings"."Tile entities load balancing settings"]
-		#Requires TELoadBalancing = true. Enables dealing with lag caused by tile entities during chunk unload. This is normally not needed. default = false
-		TEUnloadLag = false
-		#Enables Tile entity load balancing. default: true
-		TELoadBalancing = true
-		#Mean tick time at which load balancing takes effect, 1000 / mean tick time = TPS. default: 55
-		#Range: 1 ~ 200
-		meanTickTH = 55
-		#Enables debug log output for lagging tile entities, default = false
-		TEDebugOutput = false
-
-	["Load balancing settings"."Event load balancing settings"]
-		#Mean tick time at which event load balancing takes effect, 1000 / mean tick time = TPS. default: 55
-		#Range: 1 ~ 200
-		meanTickEvent = 60
-		#Enables debug log output for lagging event subscribers, default = false
-		eventDebugOutput = true
-		#Enables event load balancing, this is mostly stuff which is happening outside entityAI/Tile entities on world ticks. default: false
-		eventLoadBalancing = false
-
-	# Load balancing is a mechanic which profiles and throttles down lagging entities, tileentities and event subscribers.
-	# It is used to prevent a certain laggy mob or block from lagging out the whole game. Since this is rather invasive and may cause the lagging
-	# entity/block to not work nicely it is only done once the game goes over the configured lagging threshold.
-	# Those thresholds as set in miliseconds, anything below 50ms is 20 TPS (1s = 1000ms, 1000 / 50 = 20).
-	# Above 50ms ticks is where your game starts to lag, as it hits 100% cpu and starts skipping ticks.
-	# This is where load balancing comes in and reduces the lag caused by specific entities and blocks.
-	# If you run into trouble with some of the entities or blocks not working correctly you can disable it here
-	#
-	["Load balancing settings"."Entity AI Load balancing settings"]
-		#Mean tick time at which AI load balancing takes effect, 1000 / mean tick time = TPS. default: 55
-		#Range: 1 ~ 200
-		meanTickAITH = 55
-		#Enables load balancing for entity AI. default = true
-		AILoadBalancing = true
-		#Whether to debug lagging entities and log offenders, requires load balancing to be enabled. default = true
-		logEntityAILag = true
-
-["Entity settings"]
-	#Entity spawn interval setting, determines how frequently entities are spawned overall. 1 = Vanilla default, default = 10
-	#Range: 1 ~ 1000
-	spawnInterval = 10
-	#List of entities excluded from beeing affected by dynamic entity updates: e.g. format :  ["minecraft:zombie", "minecraft:creeper"]
-	excludedTickDistanceMobs = []
-	#Fix leash lag from entities on a leash, default = true
-	fixLeash = true
-	#Enable multithreading support for entities, requires fastCollisions to be enabled. default = true
-	multiEntities = true
-	#Disables block changes notifying all entity paths in the world, to possibly adjust their paths, disable with IE, incompat, default = true
-	disableNotifyOnBlockChange = true
-	#Slower updating of armor stands, default = true
-	slowArmorStands = true
-	#Enables improved entity collision and movement calculations for any non item entity, default = true
-	fastCollisions = true
-	#Enables less laggy entity item pickup, default = true
-	noLagItemPickup = true
-	#Enables dynamic update distance, it will reduces entity updates when far away from the player, respecting the entities own update range. default = true. Requires restart
-	enableDynamicEntityUpdates = true
-	#Enables fast itemstack comparisons
-	fastItemCompare = true
-	#Entity density setting, determines how many entities are spawned overall. 1 = Vanilla default, 0.1 e.g 10x less than vanilla. 10 = 10x more than vanilla, default = 1
-	#Range: 0.01 ~ 100.0
-	entityDensity = 1.0
-	#Enables dynamic entity rendering, stops non-visible entities from beeing rendered but can sometimes cause a slight phasing-in delay. Usually a large boost to fps, default = true. Require restart
-	enableDynamicEntityRendering = true
-	#Enable fast inventory advancement triggers, many advancements based on items tend to lag the players, default = true
-	fastInventoryAdvancement = true
-	#Adapt entity speed to tps, makes entities struggle less with lag. default = true
-	adaptiveSpeed = true
-	#Entity dynamic update distance setting, reduces the entities own update range from players at which entities get slowed down, in chunks(16blocks). The higher you set this, the closer to the player entities will get slower updates. Default = 0
-	#Range: 0 ~ 1000
-	entityUpdateDistanceReduction = 0
-	#Enable faster pathfinding, default = true
-	fastPathFinding = true
-
-["Entity AI Settings"]
-	#Sets the tick interval in which non-running AI tasks are rechecked. Vanilla default is 1(starting with 1.13+), this mods suggested default is 4(as it was in vanilla 1.12)
-	#Range: 1 ~ 500
-	goalselectorrate = 4
-	#Enables a slower updated AI Fox find shelter goal, which causes too much load. default = true
-	slowFindShelter = true
-	#Enables a slower updated AI Panic entity goal, panic is used for chickens/other animals running away e.g. on fire. default = true
-	optimizePanic = true
-	#Enables a slower updated AI Breed entity goal, breed is used for searching nearby similar animals and doesnt have to be checked that often. default = true
-	optimizeBreed = true
-	#Enables a slower updated AI tempt goal, tempt is used e.g. for luring sheep with wheat. default = true
-	optimizeTempt = true
-	#Enables a slower updated AI avoid entity goal, avoid is used e.g. for villagers avoiding zombies so it constantly searches for mobs in the area. default = true
-	optimizeAvoid = true
-	#Fix chunkloading and lag caused by the block break goal, mostly used by zombies or endermen. default = true
-	fixBlockBreakGoal = true
-
-["General performance improvements settings"]
-	#If true hoppers are causing less lag
-	fasterHoppers = true
-	#Reduces crafting lag by caching recipe lookups, helps a lot with autocrafting/crafting related lag. default = true
-	cacheRecipes = true
-	#Enable fast spawn radius check, this makes entity spawn mechanics lag less. default = true
-	fastSpawnRadius = true
-	#Set how many scheduled blocks are updated each tick, scheduled block updates are for example fluid flowing. default = 1000, vanilla default = 65536
-	#Range: 1 ~ 65536
-	blockTicks = 3000
-	#Enable fast chunk save, unmodified chunks are saved a lot faster and cause less lag when saving to disk. default = true
-	fastChunkSave = true
-	#Enable FPS improvements, default = true
-	betterFps = true
-	#Enable fast chunk block ticks, reduces lag on random block ticks in the world but keeps the same growth e.g. on crops. default = true
-	fastChunkBlocks = true
-
-["Utility settings, debugging and other"]
-	#Set the max login timeout during connection in ticks. 20 ticks = 1 sec, default = 120 seconds
-	#Range: 600 ~ 20000
-	logintimeout = 2400
-	#Set the amount of items at which too many stacked items report their position. Default = 100 items
-	#Range: 2 ~ 1000
-	maxItems = 100
-	#Enable various debugging error logs, like chunkloading etc. , default = false
-	debugOptionsEnabled = false
-	#Disables the config reload during the game, can cause performance issues on some linux systems, default = false
-	disableConfigReload = false
-	#Enable printing of world/chunk saves for debugging purposes, those normally happen every 5minutes. default = false
-	printWorldSaves = false
-	#Set the watchdog timeout for the integrated server in miliseconds, -1 Disables it. 1 second = 1000 miliseconds, default = 180000
-	#Range: -1 ~ 500000
-	singlePlayerWatchDogTimeout = 180000
-	#Set the ingame disconnect timeout for disconnecting players. Default = 60sec
-	#Range: 15 ~ 400
-	disconnectTimeout = 60
-	#Set the maximum allowed amount of same sounds playing at the same time. Lowers e.g. lag of flowing water and other cases where a sound is repeated a lot at once. Default = 10
-	#Range: 1 ~ 4000
-	maxSameSounds = 10
-	#List of mobs disallowed from spawning: e.g. format :  ["minecraft:zombie", "minecraft:creeper"]
-	forbiddenMobs = []
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/platter-common.toml b/configuration/services/configs/minecraft/voor-kia/config/platter-common.toml
deleted file mode 100644
index a9330d1..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/platter-common.toml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-#Platter Settings
-[general]
-	#Radius for the platter to feed [default: 5]
-	#Range: 0 ~ 32
-	platter_radius = 5
-	#Item slots for the platter [default: 9]
-	#Range: > 0
-	platter_slots = 9
-	#Time (in seconds) to wait between platter searches [default: 60]
-	#Range: > 0
-	platter_period = 60
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/ender_cell.toml b/configuration/services/configs/minecraft/voor-kia/config/powah/energy/ender_cell.toml
deleted file mode 100644
index 4a3d9dc..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/ender_cell.toml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-[Energy_Capacity]
-	#Range: 0 ~ 9000000000000000000
-	spiritedCap = 0
-	#Range: 0 ~ 9000000000000000000
-	blazingCap = 0
-	#Range: 0 ~ 9000000000000000000
-	basicCap = 0
-	#Range: 0 ~ 9000000000000000000
-	nioticCap = 0
-	#Range: 0 ~ 9000000000000000000
-	nitroCap = 0
-	#Range: 0 ~ 9000000000000000000
-	hardenedCap = 0
-	#Range: 0 ~ 9000000000000000000
-	starterCap = 0
-
-[Energy_Transfer]
-	#Range: 0 ~ 9000000000000000000
-	spiritedTransfer = 100000
-	#Range: 0 ~ 9000000000000000000
-	starterTransfer = 200
-	#Range: 0 ~ 9000000000000000000
-	basicTransfer = 2500
-	#Range: 0 ~ 9000000000000000000
-	hardenedTransfer = 8000
-	#Range: 0 ~ 9000000000000000000
-	nioticTransfer = 50000
-	#Range: 0 ~ 9000000000000000000
-	blazingTransfer = 20000
-	#Range: 0 ~ 9000000000000000000
-	nitroTransfer = 400000
-
-[Channels]
-	#Range: 1 ~ 12
-	hardenedChannels = 3
-	#Range: 1 ~ 12
-	basicChannels = 2
-	#Range: 1 ~ 12
-	spiritedChannels = 9
-	#Range: 1 ~ 12
-	starterChannels = 1
-	#Range: 1 ~ 12
-	nioticChannels = 7
-	#Range: 1 ~ 12
-	blazingChannels = 5
-	#Range: 1 ~ 12
-	nitroChannels = 12
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/ender_gate.toml b/configuration/services/configs/minecraft/voor-kia/config/powah/energy/ender_gate.toml
deleted file mode 100644
index 26e85a7..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/ender_gate.toml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-[Energy_Capacity]
-	#Range: 0 ~ 9000000000000000000
-	spiritedCap = 0
-	#Range: 0 ~ 9000000000000000000
-	blazingCap = 0
-	#Range: 0 ~ 9000000000000000000
-	basicCap = 0
-	#Range: 0 ~ 9000000000000000000
-	nioticCap = 0
-	#Range: 0 ~ 9000000000000000000
-	nitroCap = 0
-	#Range: 0 ~ 9000000000000000000
-	hardenedCap = 0
-	#Range: 0 ~ 9000000000000000000
-	starterCap = 0
-
-[Energy_Transfer]
-	#Range: 0 ~ 9000000000000000000
-	spiritedTransfer = 90000
-	#Range: 0 ~ 9000000000000000000
-	starterTransfer = 100
-	#Range: 0 ~ 9000000000000000000
-	basicTransfer = 1400
-	#Range: 0 ~ 9000000000000000000
-	hardenedTransfer = 5000
-	#Range: 0 ~ 9000000000000000000
-	nioticTransfer = 40000
-	#Range: 0 ~ 9000000000000000000
-	blazingTransfer = 18000
-	#Range: 0 ~ 9000000000000000000
-	nitroTransfer = 200000
-
-[Channels]
-	#Range: 1 ~ 12
-	hardenedChannels = 3
-	#Range: 1 ~ 12
-	basicChannels = 2
-	#Range: 1 ~ 12
-	spiritedChannels = 9
-	#Range: 1 ~ 12
-	starterChannels = 1
-	#Range: 1 ~ 12
-	nioticChannels = 7
-	#Range: 1 ~ 12
-	blazingChannels = 5
-	#Range: 1 ~ 12
-	nitroChannels = 12
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/energizing.toml b/configuration/services/configs/minecraft/voor-kia/config/powah/energy/energizing.toml
deleted file mode 100644
index 8988674..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/energizing.toml
+++ /dev/null
@@ -1,36 +0,0 @@
-#No comment
-#Range: 1 ~ 32
-range = 4
-
-[Energy_Capacity]
-	#Range: 0 ~ 9000000000000000000
-	spiritedCap = 4000000
-	#Range: 0 ~ 9000000000000000000
-	blazingCap = 800000
-	#Range: 0 ~ 9000000000000000000
-	basicCap = 100000
-	#Range: 0 ~ 9000000000000000000
-	nioticCap = 1500000
-	#Range: 0 ~ 9000000000000000000
-	nitroCap = 10000000
-	#Range: 0 ~ 9000000000000000000
-	hardenedCap = 250000
-	#Range: 0 ~ 9000000000000000000
-	starterCap = 10000
-
-[Energy_Transfer]
-	#Range: 0 ~ 9000000000000000000
-	spiritedTransfer = 1200
-	#Range: 0 ~ 9000000000000000000
-	starterTransfer = 10
-	#Range: 0 ~ 9000000000000000000
-	basicTransfer = 50
-	#Range: 0 ~ 9000000000000000000
-	hardenedTransfer = 120
-	#Range: 0 ~ 9000000000000000000
-	nioticTransfer = 700
-	#Range: 0 ~ 9000000000000000000
-	blazingTransfer = 300
-	#Range: 0 ~ 9000000000000000000
-	nitroTransfer = 3000
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/energy_cable.toml b/configuration/services/configs/minecraft/voor-kia/config/powah/energy/energy_cable.toml
deleted file mode 100644
index 5a43061..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/energy_cable.toml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-[Energy_Capacity]
-	#Range: 0 ~ 9000000000000000000
-	spiritedCap = 0
-	#Range: 0 ~ 9000000000000000000
-	blazingCap = 0
-	#Range: 0 ~ 9000000000000000000
-	basicCap = 0
-	#Range: 0 ~ 9000000000000000000
-	nioticCap = 0
-	#Range: 0 ~ 9000000000000000000
-	nitroCap = 0
-	#Range: 0 ~ 9000000000000000000
-	hardenedCap = 0
-	#Range: 0 ~ 9000000000000000000
-	starterCap = 0
-
-[Energy_Transfer]
-	#Range: 0 ~ 9000000000000000000
-	spiritedTransfer = 90000
-	#Range: 0 ~ 9000000000000000000
-	starterTransfer = 100
-	#Range: 0 ~ 9000000000000000000
-	basicTransfer = 1400
-	#Range: 0 ~ 9000000000000000000
-	hardenedTransfer = 5000
-	#Range: 0 ~ 9000000000000000000
-	nioticTransfer = 40000
-	#Range: 0 ~ 9000000000000000000
-	blazingTransfer = 18000
-	#Range: 0 ~ 9000000000000000000
-	nitroTransfer = 200000
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/energy_cell.toml b/configuration/services/configs/minecraft/voor-kia/config/powah/energy/energy_cell.toml
deleted file mode 100644
index 2ced90e..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/energy_cell.toml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-[Energy_Capacity]
-	#Range: 0 ~ 9000000000000000000
-	spiritedCap = 60000000
-	#Range: 0 ~ 9000000000000000000
-	blazingCap = 10000000
-	#Range: 0 ~ 9000000000000000000
-	basicCap = 1000000
-	#Range: 0 ~ 9000000000000000000
-	nioticCap = 25000000
-	#Range: 0 ~ 9000000000000000000
-	nitroCap = 140000000
-	#Range: 0 ~ 9000000000000000000
-	hardenedCap = 4000000
-	#Range: 0 ~ 9000000000000000000
-	starterCap = 100000
-
-[Energy_Transfer]
-	#Range: 0 ~ 9000000000000000000
-	spiritedTransfer = 100000
-	#Range: 0 ~ 9000000000000000000
-	starterTransfer = 200
-	#Range: 0 ~ 9000000000000000000
-	basicTransfer = 2500
-	#Range: 0 ~ 9000000000000000000
-	hardenedTransfer = 8000
-	#Range: 0 ~ 9000000000000000000
-	nioticTransfer = 50000
-	#Range: 0 ~ 9000000000000000000
-	blazingTransfer = 20000
-	#Range: 0 ~ 9000000000000000000
-	nitroTransfer = 400000
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/energy_discharger.toml b/configuration/services/configs/minecraft/voor-kia/config/powah/energy/energy_discharger.toml
deleted file mode 100644
index 2ced90e..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/energy_discharger.toml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-[Energy_Capacity]
-	#Range: 0 ~ 9000000000000000000
-	spiritedCap = 60000000
-	#Range: 0 ~ 9000000000000000000
-	blazingCap = 10000000
-	#Range: 0 ~ 9000000000000000000
-	basicCap = 1000000
-	#Range: 0 ~ 9000000000000000000
-	nioticCap = 25000000
-	#Range: 0 ~ 9000000000000000000
-	nitroCap = 140000000
-	#Range: 0 ~ 9000000000000000000
-	hardenedCap = 4000000
-	#Range: 0 ~ 9000000000000000000
-	starterCap = 100000
-
-[Energy_Transfer]
-	#Range: 0 ~ 9000000000000000000
-	spiritedTransfer = 100000
-	#Range: 0 ~ 9000000000000000000
-	starterTransfer = 200
-	#Range: 0 ~ 9000000000000000000
-	basicTransfer = 2500
-	#Range: 0 ~ 9000000000000000000
-	hardenedTransfer = 8000
-	#Range: 0 ~ 9000000000000000000
-	nioticTransfer = 50000
-	#Range: 0 ~ 9000000000000000000
-	blazingTransfer = 20000
-	#Range: 0 ~ 9000000000000000000
-	nitroTransfer = 400000
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/energy_hopper.toml b/configuration/services/configs/minecraft/voor-kia/config/powah/energy/energy_hopper.toml
deleted file mode 100644
index 1be5567..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/energy_hopper.toml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-[Energy_Capacity]
-	#Range: 0 ~ 9000000000000000000
-	spiritedCap = 15000000
-	#Range: 0 ~ 9000000000000000000
-	blazingCap = 5000000
-	#Range: 0 ~ 9000000000000000000
-	basicCap = 1000000
-	#Range: 0 ~ 9000000000000000000
-	nioticCap = 10000000
-	#Range: 0 ~ 9000000000000000000
-	nitroCap = 40000000
-	#Range: 0 ~ 9000000000000000000
-	hardenedCap = 3000000
-	#Range: 0 ~ 9000000000000000000
-	starterCap = 100000
-
-[Energy_Transfer]
-	#Range: 0 ~ 9000000000000000000
-	spiritedTransfer = 100000
-	#Range: 0 ~ 9000000000000000000
-	starterTransfer = 500
-	#Range: 0 ~ 9000000000000000000
-	basicTransfer = 2500
-	#Range: 0 ~ 9000000000000000000
-	hardenedTransfer = 8000
-	#Range: 0 ~ 9000000000000000000
-	nioticTransfer = 50000
-	#Range: 0 ~ 9000000000000000000
-	blazingTransfer = 20000
-	#Range: 0 ~ 9000000000000000000
-	nitroTransfer = 400000
-
-[Charging_Speed]
-	#Range: 0 ~ 9000000000000000000
-	nitroChargingSpeed = 50000
-	#Range: 0 ~ 9000000000000000000
-	blazingChargingSpeed = 8000
-	#Range: 0 ~ 9000000000000000000
-	basicChargingSpeed = 1000
-	#Range: 0 ~ 9000000000000000000
-	hardenedChargingSpeed = 3000
-	#Range: 0 ~ 9000000000000000000
-	nioticChargingSpeed = 12000
-	#Range: 0 ~ 9000000000000000000
-	spiritedChargingSpeed = 20000
-	#Range: 0 ~ 9000000000000000000
-	starterChargingSpeed = 100
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/furnator.toml b/configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/furnator.toml
deleted file mode 100644
index aac79b4..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/furnator.toml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-[Energy_Capacity]
-	#Range: 0 ~ 9000000000000000000
-	spiritedCap = 5000000
-	#Range: 0 ~ 9000000000000000000
-	blazingCap = 900000
-	#Range: 0 ~ 9000000000000000000
-	basicCap = 100000
-	#Range: 0 ~ 9000000000000000000
-	nioticCap = 2000000
-	#Range: 0 ~ 9000000000000000000
-	nitroCap = 10000000
-	#Range: 0 ~ 9000000000000000000
-	hardenedCap = 500000
-	#Range: 0 ~ 9000000000000000000
-	starterCap = 10000
-
-[Energy_Transfer]
-	#Range: 0 ~ 9000000000000000000
-	spiritedTransfer = 7000
-	#Range: 0 ~ 9000000000000000000
-	starterTransfer = 80
-	#Range: 0 ~ 9000000000000000000
-	basicTransfer = 200
-	#Range: 0 ~ 9000000000000000000
-	hardenedTransfer = 700
-	#Range: 0 ~ 9000000000000000000
-	nioticTransfer = 5000
-	#Range: 0 ~ 9000000000000000000
-	blazingTransfer = 1200
-	#Range: 0 ~ 9000000000000000000
-	nitroTransfer = 10000
-
-[Energy_Generation]
-	#Range: 0 ~ 9000000000000000000
-	blazingGeneration = 400
-	#Range: 0 ~ 9000000000000000000
-	starterGeneration = 15
-	#Range: 0 ~ 9000000000000000000
-	nitroGeneration = 4800
-	#Range: 0 ~ 9000000000000000000
-	hardenedGeneration = 180
-	#Range: 0 ~ 9000000000000000000
-	spiritedGeneration = 2000
-	#Range: 0 ~ 9000000000000000000
-	basicGeneration = 70
-	#Range: 0 ~ 9000000000000000000
-	nioticGeneration = 900
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/magmator.toml b/configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/magmator.toml
deleted file mode 100644
index 0b24653..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/magmator.toml
+++ /dev/null
@@ -1,56 +0,0 @@
-#
-#List of fluids used in the Magmator.
-#fluid registry name = heat per 100 mb eg: ["minecraft:lava=10000", "examplemod:fluid=1000"]
-#Min = 1, max = 900000000
-magmaticFluids = ["minecraft:lava=10000"]
-#Enable this to allow other mods to add their fluids. [default:true]
-magmaticFluidsAPI = true
-
-[Energy_Capacity]
-	#Range: 0 ~ 9000000000000000000
-	spiritedCap = 5000000
-	#Range: 0 ~ 9000000000000000000
-	blazingCap = 900000
-	#Range: 0 ~ 9000000000000000000
-	basicCap = 100000
-	#Range: 0 ~ 9000000000000000000
-	nioticCap = 2000000
-	#Range: 0 ~ 9000000000000000000
-	nitroCap = 10000000
-	#Range: 0 ~ 9000000000000000000
-	hardenedCap = 500000
-	#Range: 0 ~ 9000000000000000000
-	starterCap = 10000
-
-[Energy_Transfer]
-	#Range: 0 ~ 9000000000000000000
-	spiritedTransfer = 7000
-	#Range: 0 ~ 9000000000000000000
-	starterTransfer = 80
-	#Range: 0 ~ 9000000000000000000
-	basicTransfer = 200
-	#Range: 0 ~ 9000000000000000000
-	hardenedTransfer = 700
-	#Range: 0 ~ 9000000000000000000
-	nioticTransfer = 5000
-	#Range: 0 ~ 9000000000000000000
-	blazingTransfer = 1200
-	#Range: 0 ~ 9000000000000000000
-	nitroTransfer = 10000
-
-[Energy_Generation]
-	#Range: 0 ~ 9000000000000000000
-	blazingGeneration = 400
-	#Range: 0 ~ 9000000000000000000
-	starterGeneration = 15
-	#Range: 0 ~ 9000000000000000000
-	nitroGeneration = 4800
-	#Range: 0 ~ 9000000000000000000
-	hardenedGeneration = 180
-	#Range: 0 ~ 9000000000000000000
-	spiritedGeneration = 2000
-	#Range: 0 ~ 9000000000000000000
-	basicGeneration = 70
-	#Range: 0 ~ 9000000000000000000
-	nioticGeneration = 900
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/reactor.toml b/configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/reactor.toml
deleted file mode 100644
index f5e36b0..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/reactor.toml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-[Energy_Capacity]
-	#Range: 0 ~ 9000000000000000000
-	spiritedCap = 50000000
-	#Range: 0 ~ 9000000000000000000
-	blazingCap = 18000000
-	#Range: 0 ~ 9000000000000000000
-	basicCap = 4000000
-	#Range: 0 ~ 9000000000000000000
-	nioticCap = 30000000
-	#Range: 0 ~ 9000000000000000000
-	nitroCap = 80000000
-	#Range: 0 ~ 9000000000000000000
-	hardenedCap = 10000000
-	#Range: 0 ~ 9000000000000000000
-	starterCap = 1000000
-
-[Energy_Transfer]
-	#Range: 0 ~ 9000000000000000000
-	spiritedTransfer = 400000
-	#Range: 0 ~ 9000000000000000000
-	starterTransfer = 10000
-	#Range: 0 ~ 9000000000000000000
-	basicTransfer = 50000
-	#Range: 0 ~ 9000000000000000000
-	hardenedTransfer = 160000
-	#Range: 0 ~ 9000000000000000000
-	nioticTransfer = 140000
-	#Range: 0 ~ 9000000000000000000
-	blazingTransfer = 100000
-	#Range: 0 ~ 9000000000000000000
-	nitroTransfer = 800000
-
-[Energy_Generation]
-	#Range: 0 ~ 9000000000000000000
-	blazingGeneration = 1200
-	#Range: 0 ~ 9000000000000000000
-	starterGeneration = 100
-	#Range: 0 ~ 9000000000000000000
-	nitroGeneration = 5400
-	#Range: 0 ~ 9000000000000000000
-	hardenedGeneration = 840
-	#Range: 0 ~ 9000000000000000000
-	spiritedGeneration = 3800
-	#Range: 0 ~ 9000000000000000000
-	basicGeneration = 400
-	#Range: 0 ~ 9000000000000000000
-	nioticGeneration = 2700
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/solar_panel.toml b/configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/solar_panel.toml
deleted file mode 100644
index bbe8571..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/solar_panel.toml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-[Energy_Capacity]
-	#Range: 0 ~ 9000000000000000000
-	spiritedCap = 2500000
-	#Range: 0 ~ 9000000000000000000
-	blazingCap = 500000
-	#Range: 0 ~ 9000000000000000000
-	basicCap = 25000
-	#Range: 0 ~ 9000000000000000000
-	nioticCap = 1000000
-	#Range: 0 ~ 9000000000000000000
-	nitroCap = 8000000
-	#Range: 0 ~ 9000000000000000000
-	hardenedCap = 100000
-	#Range: 0 ~ 9000000000000000000
-	starterCap = 5000
-
-[Energy_Transfer]
-	#Range: 0 ~ 9000000000000000000
-	spiritedTransfer = 2000
-	#Range: 0 ~ 9000000000000000000
-	starterTransfer = 50
-	#Range: 0 ~ 9000000000000000000
-	basicTransfer = 150
-	#Range: 0 ~ 9000000000000000000
-	hardenedTransfer = 300
-	#Range: 0 ~ 9000000000000000000
-	nioticTransfer = 1000
-	#Range: 0 ~ 9000000000000000000
-	blazingTransfer = 700
-	#Range: 0 ~ 9000000000000000000
-	nitroTransfer = 4000
-
-[Energy_Generation]
-	#Range: 0 ~ 9000000000000000000
-	blazingGeneration = 90
-	#Range: 0 ~ 9000000000000000000
-	starterGeneration = 5
-	#Range: 0 ~ 9000000000000000000
-	nitroGeneration = 1200
-	#Range: 0 ~ 9000000000000000000
-	hardenedGeneration = 40
-	#Range: 0 ~ 9000000000000000000
-	spiritedGeneration = 500
-	#Range: 0 ~ 9000000000000000000
-	basicGeneration = 12
-	#Range: 0 ~ 9000000000000000000
-	nioticGeneration = 220
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/thermo_gen.toml b/configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/thermo_gen.toml
deleted file mode 100644
index 233ef77..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/generators/thermo_gen.toml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-[Energy_Capacity]
-	#Range: 0 ~ 9000000000000000000
-	spiritedCap = 2500000
-	#Range: 0 ~ 9000000000000000000
-	blazingCap = 500000
-	#Range: 0 ~ 9000000000000000000
-	basicCap = 25000
-	#Range: 0 ~ 9000000000000000000
-	nioticCap = 1000000
-	#Range: 0 ~ 9000000000000000000
-	nitroCap = 8000000
-	#Range: 0 ~ 9000000000000000000
-	hardenedCap = 100000
-	#Range: 0 ~ 9000000000000000000
-	starterCap = 5000
-
-[Energy_Transfer]
-	#Range: 0 ~ 9000000000000000000
-	spiritedTransfer = 2000
-	#Range: 0 ~ 9000000000000000000
-	starterTransfer = 50
-	#Range: 0 ~ 9000000000000000000
-	basicTransfer = 150
-	#Range: 0 ~ 9000000000000000000
-	hardenedTransfer = 300
-	#Range: 0 ~ 9000000000000000000
-	nioticTransfer = 1000
-	#Range: 0 ~ 9000000000000000000
-	blazingTransfer = 700
-	#Range: 0 ~ 9000000000000000000
-	nitroTransfer = 4000
-
-[Energy_Generation]
-	#Range: 0 ~ 9000000000000000000
-	blazingGeneration = 42
-	#Range: 0 ~ 9000000000000000000
-	starterGeneration = 3
-	#Range: 0 ~ 9000000000000000000
-	nitroGeneration = 800
-	#Range: 0 ~ 9000000000000000000
-	hardenedGeneration = 18
-	#Range: 0 ~ 9000000000000000000
-	spiritedGeneration = 200
-	#Range: 0 ~ 9000000000000000000
-	basicGeneration = 8
-	#Range: 0 ~ 9000000000000000000
-	nioticGeneration = 90
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/items/battery.toml b/configuration/services/configs/minecraft/voor-kia/config/powah/energy/items/battery.toml
deleted file mode 100644
index 2ced90e..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/items/battery.toml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-[Energy_Capacity]
-	#Range: 0 ~ 9000000000000000000
-	spiritedCap = 60000000
-	#Range: 0 ~ 9000000000000000000
-	blazingCap = 10000000
-	#Range: 0 ~ 9000000000000000000
-	basicCap = 1000000
-	#Range: 0 ~ 9000000000000000000
-	nioticCap = 25000000
-	#Range: 0 ~ 9000000000000000000
-	nitroCap = 140000000
-	#Range: 0 ~ 9000000000000000000
-	hardenedCap = 4000000
-	#Range: 0 ~ 9000000000000000000
-	starterCap = 100000
-
-[Energy_Transfer]
-	#Range: 0 ~ 9000000000000000000
-	spiritedTransfer = 100000
-	#Range: 0 ~ 9000000000000000000
-	starterTransfer = 200
-	#Range: 0 ~ 9000000000000000000
-	basicTransfer = 2500
-	#Range: 0 ~ 9000000000000000000
-	hardenedTransfer = 8000
-	#Range: 0 ~ 9000000000000000000
-	nioticTransfer = 50000
-	#Range: 0 ~ 9000000000000000000
-	blazingTransfer = 20000
-	#Range: 0 ~ 9000000000000000000
-	nitroTransfer = 400000
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/player_transmitter.toml b/configuration/services/configs/minecraft/voor-kia/config/powah/energy/player_transmitter.toml
deleted file mode 100644
index 1be5567..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/powah/energy/player_transmitter.toml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-[Energy_Capacity]
-	#Range: 0 ~ 9000000000000000000
-	spiritedCap = 15000000
-	#Range: 0 ~ 9000000000000000000
-	blazingCap = 5000000
-	#Range: 0 ~ 9000000000000000000
-	basicCap = 1000000
-	#Range: 0 ~ 9000000000000000000
-	nioticCap = 10000000
-	#Range: 0 ~ 9000000000000000000
-	nitroCap = 40000000
-	#Range: 0 ~ 9000000000000000000
-	hardenedCap = 3000000
-	#Range: 0 ~ 9000000000000000000
-	starterCap = 100000
-
-[Energy_Transfer]
-	#Range: 0 ~ 9000000000000000000
-	spiritedTransfer = 100000
-	#Range: 0 ~ 9000000000000000000
-	starterTransfer = 500
-	#Range: 0 ~ 9000000000000000000
-	basicTransfer = 2500
-	#Range: 0 ~ 9000000000000000000
-	hardenedTransfer = 8000
-	#Range: 0 ~ 9000000000000000000
-	nioticTransfer = 50000
-	#Range: 0 ~ 9000000000000000000
-	blazingTransfer = 20000
-	#Range: 0 ~ 9000000000000000000
-	nitroTransfer = 400000
-
-[Charging_Speed]
-	#Range: 0 ~ 9000000000000000000
-	nitroChargingSpeed = 50000
-	#Range: 0 ~ 9000000000000000000
-	blazingChargingSpeed = 8000
-	#Range: 0 ~ 9000000000000000000
-	basicChargingSpeed = 1000
-	#Range: 0 ~ 9000000000000000000
-	hardenedChargingSpeed = 3000
-	#Range: 0 ~ 9000000000000000000
-	nioticChargingSpeed = 12000
-	#Range: 0 ~ 9000000000000000000
-	spiritedChargingSpeed = 20000
-	#Range: 0 ~ 9000000000000000000
-	starterChargingSpeed = 100
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/powah/general_common.toml b/configuration/services/configs/minecraft/voor-kia/config/powah/general_common.toml
deleted file mode 100644
index a1dd03c..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/powah/general_common.toml
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-#Enable this to get Player Aerial Pearl by right clicking a Zombie or Husk with a Aerial Pearl. [default:true]
-player_aerial_pearl = true
-#
-#Enable this to get Dimensional Binding card by right clicking an Enderman or Endermite with a Binding card. [default:true]
-binding_card_dim = true
-#
-#Enable this to get Lens Of Ender by right clicking an Enderman or Endermite with a Photoelectric Pane. [default:true]
-lens_of_ender = true
-
-["World Gen"]
-	#Enable/Disable ore generation. [default:true]
-	oreGen = true
-	#Dry Ice Ore generation chance
-	#Range: 1 ~ 64
-	dryIceGenChance = 9
-	#Poor Uraninite Ore generation chance
-	#Range: 1 ~ 64
-	poorUraniniteGenChance = 8
-	#Dense Uraninite Ore generation chance
-	#Range: 1 ~ 64
-	denseUraniniteGenChance = 3
-	#Uraninite Ore generation chance
-	#Range: 1 ~ 64
-	uraniniteGenChance = 6
-
-[Materials]
-	#
-	#List of coolant fluids used in the Reactor and the Thermo Generator.
-	#Fluid registry name = cooling per mb, eg: ["minecraft:water=1", "examplemod:fluid=-1"]
-	#Less number more cold, min = -100, max = 1
-	coolantFluids = ["minecraft:water=1"]
-	#
-	#List of heat source blocks used under Thermo Generator.
-	#Block registry name = heat, eg: ["minecraft:lava=1000", "minecraft:magma_block=800"]
-	#Min = 1, max = 900000000
-	heatSources = ["minecraft:lava=1000", "minecraft:magma_block=800", "powah:blazing_crystal_block=2800"]
-	#Energy per solid fuel tick. [default: 30]
-	#Eg: Coal has 1600 fuel tick, so will generate 48000 FE.
-	#Range: 1 ~ 1000000
-	solidFuelEnergyBase = 30
-	#Enable this to allow other mods to add their coolant fluids. [default:true]
-	coolantFluidsAPI = true
-	#Enable this to allow other mods to add their heat source blocks. [default:true]
-	heatBlocksAPI = true
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/quark-common-1.toml.bak b/configuration/services/configs/minecraft/voor-kia/config/quark-common-1.toml.bak
deleted file mode 100644
index 9b65931..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/quark-common-1.toml.bak
+++ /dev/null
@@ -1,2128 +0,0 @@
-
-[general]
-	"'q' Button on the Right" = false
-	#
-	#Allowed values: (0,)
-	"Piston Push Limit" = 12
-	#
-	#Set to true to make the quark big worldgen features such as stone clusters or underground biomes generate as spheres rather than unique shapes. It's faster, but won't look as cool
-	"Use Fast Worldgen" = false
-	"Enable 'q' Button" = true
-	#
-	#A list of screens that don't play well with quark's buttons. Use "Print Screen Classnames" to find the names of any others you'd want to add.
-	"Ignored Screens" = ["blusunrize.immersiveengineering.client.gui.CraftingTableScreen", "com.tfar.craftingstation.client.CraftingStationScreen", "com.refinedmods.refinedstorage.screen.grid.GridScreen", "appeng.client.gui.implementations.CraftingTermScreen", "appeng.client.gui.implementations.PatternTermScreen", "com.blakebr0.extendedcrafting.client.screen.EliteTableScreen", "com.blakebr0.extendedcrafting.client.screen.EliteAutoTableScreen", "com.blakebr0.extendedcrafting.client.screen.UltimateTableScreen", "com.blakebr0.extendedcrafting.client.screen.UltimateAutoTableScreen", "me.desht.modularrouters.client.gui.filter.GuiFilterScreen", "com.resourcefulbees.resourcefulbees.client.gui.screen.CentrifugeScreen", "com.resourcefulbees.resourcefulbees.client.gui.screen.MechanicalCentrifugeScreen", "com.resourcefulbees.resourcefulbees.client.gui.screen.CentrifugeMultiblockScreen"]
-	"Use Anti Overlap" = true
-	#
-	#Quark messes with the Stonecutter to allow any item that can be used in it to be shift clicked in. Set this to false to turn it off.
-	"Hack Stonecutter Shift Click" = true
-	#
-	#Enables quark network profiling features. Do not enable this unless requested to.
-	"Enable Network Profiling" = false
-	#
-	#Quark replaces the Piston logic to allow for its piston features to work. If you're having troubles, try turning this off.
-	"Use Piston Logic Replacement" = true
-	#
-	#Set to true if you need to find the class name for a screen that's causing problems
-	"Print Screen Classnames" = false
-	#
-	#Blocks that Quark should treat as Shulker Boxes.
-	"Shulker Boxes" = ["minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box", "minecraft:light_gray_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box", "minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box"]
-	#
-	#Set to true to enable a system that debugs quark's worldgen features. This should ONLY be used if you're asked to by a dev.
-	"Enable Worldgen Watchdog" = false
-	#
-	#Should Quark treat anything with 'shulker_box' in its item identifier as a shulker box?
-	"Interpret Shulker Box Like Blocks" = true
-
-[categories]
-	Building = true
-	Automation = true
-	Oddities = true
-	Tweaks = true
-	Experimental = true
-	Mobs = true
-	Tools = true
-	Management = true
-	World = true
-	Client = true
-
-[automation]
-	Chute = true
-	"Iron Rod" = true
-	"Weather Sensor" = true
-	"Ender Watcher" = true
-	"Endermites Form Shulkers" = true
-	"Chains Connect Blocks" = true
-	"Color Slime" = true
-	"Dispensers Place Blocks" = true
-	"Redstone Circuit" = true
-	"Chain Linkage" = true
-	Gravisand = true
-	"Metal Buttons" = true
-	"Obsidian Plate" = true
-	"Pistons Move Tile Entities" = true
-	"Feeding Trough" = true
-
-	[automation.dispensers_place_blocks]
-		Blacklist = ["minecraft:water", "minecraft:lava", "minecraft:fire"]
-
-	[automation.chain_linkage]
-		#
-		#Can vehicle-linking chains be used for crafting chain armor?
-		"Crafts Armor" = true
-
-	[automation.redstone_circuit]
-		"Enable Inductor" = true
-		"Enable Randomizer" = true
-
-	[automation.metal_buttons]
-		"Enable Iron" = true
-		"Enable Gold" = true
-
-	[automation.endermites_form_shulkers]
-		Chance = 0.005
-
-	[automation.pistons_move_tile_entities]
-		"Render Blacklist" = ["psi:programmer", "botania:starfield"]
-		"Movement Blacklist" = ["minecraft:spawner", "integrateddynamics:cable", "randomthings:blockbreaker", "minecraft:ender_chest", "minecraft:enchanting_table", "minecraft:trapped_chest", "quark:spruce_trapped_chest", "quark:birch_trapped_chest", "quark:jungle_trapped_chest", "quark:acacia_trapped_chest", "quark:dark_oak_trapped_chest", "endergetic:bolloom_bud"]
-		"Delayed Update List" = ["minecraft:dispenser", "minecraft:dropper"]
-
-	[automation.color_slime]
-		"Change Name" = true
-
-	[automation.feeding_trough]
-		#
-		#The chance (between 0 and 1) for an animal to enter love mode when eating from the trough
-		#Allowed values: (0,1]
-		"Love Chance" = 0.333333333
-		#
-		#How long, in game ticks, between animals being able to eat from the trough
-		#Allowed values: [1,)
-		Cooldown = 30
-		#
-		#The maximum amount of animals allowed around the trough's range for an animal to enter love mode
-		"Max Animals" = 32
-		Range = 10.0
-
-[building]
-	"Duskbound Blocks" = true
-	"Bamboo Mat" = true
-	"Cobblestone Bricks" = true
-	"More Brick Types" = true
-	"Gold Bars" = true
-	"Soul Sandstone" = true
-	"Burn Vines" = true
-	"Quilted Wool" = true
-	"Compressed Blocks" = true
-	Stools = true
-	Thatch = true
-	"Variant Chests" = true
-	"Variant Ladders" = true
-	Hedges = true
-	"Vertical Slabs" = true
-	Shingles = true
-	"Nether Brick Fence Gate" = true
-	"Item Frames" = true
-	"Stained Planks" = true
-	"Wooden Posts" = true
-	"Leaf Carpet" = true
-	"Lit Lamp" = true
-	"Vertical Planks" = true
-	Midori = true
-	"Tie Leads To Fences" = true
-	"Shallow Dirt" = true
-	"More Stone Variants" = true
-	"Framed Glass" = true
-	"Tallow And Candles" = true
-	Turf = true
-	"Paper Decor" = true
-	Rope = true
-	"Iron Plates" = true
-	"Sturdy Stone" = true
-	"More Potted Plants" = true
-	Grate = true
-	"Variant Bookshelves" = true
-
-	[building.rope]
-		"Enable Dispenser Behavior" = true
-		#
-		#Set to true to allow ropes to move Tile Entities even if Pistons Push TEs is disabled.
-		#Note that ropes will still use the same blacklist.
-		"Force Enable Move Tile Entities" = false
-
-	[building.more_stone_variants]
-		"Enable Bricks" = true
-		"Enable Pillar" = true
-		"Enable Chiseled Bricks" = true
-		"Enable Pavement" = true
-
-	[building.thatch]
-		#
-		#Allowed values: [0,1]
-		"Fall Damage Multiplier" = 0.5
-
-	[building.variant_ladders]
-		"Change Names" = true
-		"Enable Iron Ladder" = true
-
-	[building.compressed_blocks]
-		"Enable Cocoa Bean Sack" = true
-		"Enable Cactus Block" = true
-		"Enable Apple Crate" = true
-		"Charcoal Block and Blaze Lantern Stay On Fire Forever" = true
-		"Enable Bonded Rabbit Hide" = true
-		"Enable Charcoal Block" = true
-		"Enable Gunpowder Sack" = true
-		"Enable Potato Crate" = true
-		"Enable Stick Block" = true
-		"Enable Carrot Crate" = true
-		"Enable Beetroot Crate" = true
-		"Enable Nether Wart Sack" = true
-		"Enable Chorus Fruit Block" = true
-		"Enable Blaze Lantern" = true
-		"Enable Bamboo Block" = true
-		"Enable Berry Sack" = true
-		#
-		#Allowed values: [0,)
-		"Bamboo Bundle Fuel Time" = 500
-		"Enable Golden Apple Crate" = true
-		"Enable Sugar Cane Block" = true
-		"Enable Bonded Leather" = true
-		#
-		#Allowed values: [0,)
-		"Blaze Lantern Fuel Time" = 24000
-		#
-		#Allowed values: [0,)
-		"Charcoal Block Fuel Time" = 16000
-		#
-		#Allowed values: [0,)
-		"Stick Block Fuel Time" = 900
-
-	[building.variant_chests]
-		"Replace Worldgen Chests" = true
-		#
-		#Chests to put in each structure. The format per entry is "structure=chest", where "structure" is a structure ID, and "chest" is a block ID, which must correspond to a standard chest block.
-		"Structure Chests" = ["minecraft:village_plains=quark:oak_chest", "minecraft:igloo=quark:spruce_chest", "minecraft:village_snowy=quark:spruce_chest", "minecraft:village_taiga=quark:spruce_chest", "minecraft:desert_pyramid=quark:birch_chest", "minecraft:jungle_pyramid=quark:jungle_chest", "minecraft:village_desert=quark:jungle_chest", "minecraft:village_savanna=quark:acacia_chest", "minecraft:mansion=quark:dark_oak_chest", "minecraft:pillager_outpost=quark:dark_oak_chest", "minecraft:ruined_portal=quark:crimson_chest", "minecraft:bastion_remnant=quark:crimson_chest", "minecraft:fortress=quark:nether_brick_chest", "minecraft:endcity=quark:purpur_chest", "bettermineshafts:mineshaft=quark:oak_chest", "cobbler:shulker_factory=quark:purpur_chest", "conjurer_illager:theatre=quark:dark_oak_chest", "dungeoncrawl:dungeon=quark:oak_chest", "dungeons_plus:bigger_dungeon=quark:oak_chest", "dungeons_plus:end_ruins=quark:purpur_chest", "dungeons_plus:leviathan=quark:jungle_chest", "dungeons_plus:snowy_temple=quark:spruce_chest", "dungeons_plus:soul_prison=quark:warped_chest", "dungeons_plus:tower=quark:oak_chest", "dungeons_plus:warped_garden=quark:warped__chest", "hunterillager:hunterhouse=quark:oak_chest", "iceandfire:gorgon_temple=quark:jungle_chest", "pandoras_creatures:end_prison=quark:purpur_chest", "repurposed_structures:fortress_jungle=quark:jungle_chest", "repurposed_structures:igloo_grassy=quark:oak_chest", "repurposed_structures:igloo_stone=quark:spruce_chest", "repurposed_structures:mineshaft_birch=quark:birch_chest", "repurposed_structures:mineshaft_desert=quark:jungle_chest", "repurposed_structures:mineshaft_end=quark:purpur_chest", "repurposed_structures:mineshaft_icy=quark:spruce_chest", "repurposed_structures:mineshaft_jungle=quark:jungle_chest", "repurposed_structures:mineshaft_nether=quark:nether_brick_chest", "repurposed_structures:mineshaft_ocean=quark:prismarine_chest", "repurposed_structures:mineshaft_savanna=quark:acacia_chest", "repurposed_structures:mineshaft_stone=quark:spruce_chest", "repurposed_structures:mineshaft_swamp_or_dark_forest=quark:dark_oak_chest", "repurposed_structures:mineshaft_taiga=quark:spruce_chest", "repurposed_structures:outpost_badlands=quark:dark_oak_chest", "repurposed_structures:outpost_birch=quark:birch_chest", "repurposed_structures:outpost_crimson=quark:crimson_chest", "repurposed_structures:outpost_desert=quark:jungle_chest", "repurposed_structures:outpost_giant_tree_taiga=quark:spruce_chest", "repurposed_structures:outpost_icy=quark:spruce_chest", "repurposed_structures:outpost_jungle=quark:jungle_chest", "repurposed_structures:outpost_nether_brick=quark:nether_brick_chest", "repurposed_structures:outpost_snowy=quark:spruce_chest", "repurposed_structures:outpost_warped=quark:warped_chest", "repurposed_structures:pyramid_badlands=quark:dark_oak_chest", "repurposed_structures:pyramid_nether=quark:nether_brick_chest", "repurposed_structures:ruined_portal_end=quark:purpur_chest", "repurposed_structures:shipwreck_crimson=quark:crimson_chest", "repurposed_structures:shipwreck_end=quark:purpur_chest", "repurposed_structures:shipwreck_nether_bricks=quark:nether_brick_chest", "repurposed_structures:shipwreck_warped=quark:warped_chest", "repurposed_structures:stronghold_nether=quark:nether_brick_chest", "repurposed_structures:stronghold_stonebrick=quark:oak_chest", "repurposed_structures:temple_nether_basalt=quark:nether_brick_chest", "repurposed_structures:temple_nether_crimson=quark:crimson_chest", "repurposed_structures:temple_nether_soul=quark:warped_chest", "repurposed_structures:temple_nether_warped=quark:warped_chest", "repurposed_structures:temple_nether_wasteland=quark:nether_brick_chest", "repurposed_structures:village_badlands=quark:dark_oak_chest", "repurposed_structures:village_birch=quark:birch_chest", "repurposed_structures:village_crimson=quark:crimson_chest", "repurposed_structures:village_dark_oak=quark:dark_oak_chest", "repurposed_structures:village_giant_taiga=quark:spruce_chest", "repurposed_structures:village_jungle=quark:jungle_chest", "repurposed_structures:village_mountains=quark:spruce_chest", "repurposed_structures:village_oak=quark:oak_chest", "repurposed_structures:village_swamp=quark:oak_chest", "repurposed_structures:village_warped=quark:warped_chest", "valhelsia_structures:castle=quark:spruce_chest", "valhelsia_structures:castle_ruin=quark:oak_chest", "valhelsia_structures:desert_house=quark:spruce_chest", "valhelsia_structures:forge=quark:spruce_chest", "valhelsia_structures:player_house=quark:oak_chest", "valhelsia_structures:small_castle=quark:oak_chest", "valhelsia_structures:small_dungeon=quark:oak_chest", "valhelsia_structures:tower_ruin=quark:spruce_chest"]
-
-	[building.more_brick_types]
-		"Enable Magma Bricks" = true
-		"Enable Sandy Bricks" = true
-		#
-		#This also comes with a utility recipe for Red Nether Bricks
-		"Enable Blue Nether Bricks" = true
-		"Enable Blackstone Variant Bricks" = true
-		"Enable Charred Nether Bricks" = true
-		"Enable Snow Bricks" = true
-		#
-		#This also includes Red Sandstone Bricks and Soul Sandstone Bricks
-		"Enable Sandstone Bricks" = true
-
-	[building.tallow_and_candles]
-		"Candles Fall" = true
-		#
-		#Allowed values: [0,)
-		"Tallow Burn Time" = 200
-		#
-		#Allowed values: [0,)
-		"Max Drop" = 3
-		#
-		#Allowed values: [0,15]
-		"Enchant Power" = 1.0
-		#
-		#Allowed values: [0,)
-		"Min Drop" = 1
-
-	[building.variant_bookshelves]
-		"Change Names" = true
-
-[management]
-	"Chests In Boats" = true
-	"Inventory Sorting" = true
-	"Shulker Box Right Click" = true
-	"Hotbar Changer" = true
-	"Item Sharing" = true
-	"Right Click Armor" = true
-	"Easy Transfering" = true
-
-	[management.inventory_sorting]
-		#
-		#Play a click when sorting inventories using keybindings
-		"Satisfying Click" = true
-		"Enable Chests" = true
-		"Enable Player Inventory In Chests" = true
-		"Enable Player Inventory" = true
-
-	[management.easy_transfering]
-		"Enable Shift Lock" = true
-
-	[management.item_sharing]
-		"Render Items In Chat" = true
-
-[tools]
-	Pickarang = true
-	"Seed Pouch" = true
-	"Pathfinder Maps" = true
-	"Bottled Cloud" = true
-	"Color Runes" = true
-	"Ancient Tomes" = true
-	"Slime In A Bucket" = true
-	Camera = true
-	Trowel = true
-
-	[tools.trowel]
-		#
-		#Amount of blocks placed is this value + 1. Default is 255 (4 stacks).
-		#Set to 0 to make the Trowel unbreakable
-		#Allowed values: [0,)
-		"Trowel Max Durability" = 255
-
-	[tools.bottled_cloud]
-		"Cloud Level Top" = 132
-		"Cloud Level Bottom" = 127
-
-	[tools.ancient_tomes]
-		#
-		#Set to 0 to not generate in Underwater Ruins
-		"Underwater Ruin Weight" = 0
-		#
-		#Set to 0 to not generate in Woodland Mansions
-		"Woodland Mansion Weight" = 15
-		"Valid Enchantments" = ["minecraft:feather_falling", "minecraft:thorns", "minecraft:sharpness", "minecraft:smite", "minecraft:bane_of_arthropods", "minecraft:knockback", "minecraft:fire_aspect", "minecraft:looting", "minecraft:sweeping", "minecraft:efficiency", "minecraft:unbreaking", "minecraft:fortune", "minecraft:power", "minecraft:punch", "minecraft:luck_of_the_sea", "minecraft:lure", "minecraft:loyalty", "minecraft:riptide", "minecraft:impaling", "minecraft:piercing"]
-		#
-		#Set to 0 to not generate in Dungeons
-		"Dungeon Weight" = 20
-		"Item Quality" = 2
-		"Apply Cost" = 35
-		#
-		#Set to 0 to not generate in Stronghold Libraries
-		"Library Weight" = 30
-		#
-		#Set to 0 to not generate in Nether Fortresses
-		"Nether Fortress Weight" = 0
-		#
-		#Set to 0 to not generate in Bastions
-		"Bastion Weight" = 25
-		#
-		#Set to 0 to not generate in Monster Boxes
-		"Monster Box Weight" = 5
-		"Merge Cost" = 35
-
-	[tools.pathfinder_maps]
-		#
-		#In this section you can add custom Pathfinder Maps. This works for both vanilla and modded biomes.
-		#Each custom map must be on its own line.
-		#The format for a custom map is as follows:
-		#<id>,<level>,<min_price>,<max_price>,<color>,<name>
-		#
-		#With the following descriptions:
-		# - <id> being the biome's ID NAME. You can find vanilla names here - https://minecraft.gamepedia.com/Biome#Biome_IDs
-		# - <level> being the Cartographer villager level required for the map to be unlockable
-		# - <min_price> being the cheapest (in Emeralds) the map can be
-		# - <max_price> being the most expensive (in Emeralds) the map can be
-		# - <color> being a hex color (without the #) for the map to display. You can generate one here - http://htmlcolorcodes.com/
-		# - <name> being the display name of the map
-		#
-		#Here's an example of a map to locate Ice Mountains:
-		#minecraft:ice_mountains,2,8,14,7FE4FF,Ice Mountains Pathfinder Map
-		Customs = []
-		"Xp From Trade" = 5
-
-	[tools.seed_pouch]
-		"Show All Variants In Creative" = true
-		"Shift Range" = 3
-		"Max Items" = 640
-
-	[tools.color_runes]
-		"Jungle Temple Weight" = 8
-		"Desert Temple Weight" = 8
-		"Dungeon Weight" = 10
-		"Item Quality" = 0
-		"Apply Cost" = 15
-		"Nether Fortress Weight" = 8
-
-	[tools.pickarang]
-		#
-		#22.5 is ender chests, 25.0 is monster boxes, 50 is obsidian. Most things are below 5.
-		"Max Hardness" = 20.0
-		#
-		#2 is Iron, 3 is Diamond.
-		"Harvest Level" = 3
-		#
-		#2 is Iron, 3 is Diamond.
-		"Netherite Harvest Level" = 3
-		#
-		#How long it takes before the pickarang starts returning to the player if it doesn't hit anything.
-		Timeout = 20
-		#
-		#Set to -1 to have the Pickarang be unbreakable.
-		Durability = 800
-		#
-		#Set this to true to disable the short cooldown between throwing pickarangs.
-		"No Cooldown" = false
-		#
-		#Set to -1 to have the Flamerang be unbreakable.
-		"Netherite Durability" = 1040
-		#
-		#Set this to true to use the recipe without the Heart of Diamond, even if the Heart of Diamond is enabled.
-		"Never Use Heart Of Diamond" = false
-
-[tweaks]
-	"Armed Armor Stands" = true
-	"Lock Rotation" = true
-	"Dragon Scales" = true
-	"Replace Scaffolding" = true
-	"Axe Leaf Harvesting" = true
-	"Sign Editing" = true
-	"Dirt To Path" = true
-	"Simple Harvest" = true
-	"Hoe Harvesting" = true
-	"Reacharound Placing" = true
-	"Villagers Follow Emeralds" = true
-	"Compasses Work Everywhere" = true
-	"Skull Pikes" = true
-	"Note Block Mob Sounds" = true
-	"Double Door Opening" = true
-	"Automatic Recipe Unlock" = true
-	"Poison Potato Usage" = true
-	"Lava Bucket As Trash" = true
-	"Improved Sleeping" = true
-	"Infinity Bucket" = true
-	"Springy Slime" = true
-	Emotes = true
-	"Utility Recipes" = true
-	"Pat The Dogs" = true
-	"Enhanced Ladders" = true
-	"Snow Golem Player Heads" = true
-	"Glass Shard" = true
-	"Campfires Boost Elytra" = true
-
-	[tweaks.sign_editing]
-		"Requires Empty Hand" = false
-
-	[tweaks.pat_the_dogs]
-		#
-		#How many ticks it takes for a dog to want affection after being pet/tamed; leave -1 to disable
-		"Dogs Want Love" = -1
-
-	[tweaks.automatic_recipe_unlock]
-		#
-		#A list of recipe names that should NOT be added in by default
-		"Ignored Recipes" = []
-		"Disable Recipe Book" = false
-		"Force Limited Crafting" = false
-
-	[tweaks.hoe_harvesting]
-		"Hoes Can Have Fortune" = true
-
-	[tweaks.skull_pikes]
-		"Pike Range" = 5.0
-
-	[tweaks.infinity_bucket]
-		#
-		#Set this to false to prevent dispensers from using infinite water buckets
-		"Allow Dispensers To Use" = true
-		Cost = 10
-
-	[tweaks.poison_potato_usage]
-		"Poison Effect" = true
-		Chance = 0.1
-
-	[tweaks.utility_recipes]
-		#
-		#Can you craft four chests at once using logs?
-		"Logs To Chests" = true
-		#
-		#Can other stone-like materials be used for crafting stone tools?
-		"Better Stone Tool Crafting" = true
-		#
-		#Can a dispenser be crafted by adding a bow to a dropper?
-		"Enable Dispenser" = true
-		#
-		#Can cookies, paper, and bread be crafted in a 2x2 crafting table?
-		"Bent Recipes" = true
-		#
-		#Can Rotten Flesh and Poisonous Potatoes be composted?
-		"Compostable Toxins" = true
-		#
-		#Can bones be smelted down to bone meal?
-		"Bone Meal Utility" = true
-		#
-		#Can any wool color be dyed?
-		"Dye Any Wool" = true
-		#
-		#Can Coral be crafted into dye?
-		"Coral To Dye" = true
-		#
-		#Can torches can be used as fuel in furnaces?
-		"Torches Burn" = true
-		#
-		#Can a repeater be crafted with the pattern for a redstone torch?
-		"Enable Repeater" = true
-		#
-		#Can you craft a minecart around blocks which can be placed inside?
-		"Enable Minecarts" = true
-		#
-		#Does Dragon Breath return a bottle when used as a reagent or material?
-		"Effective Dragon Breath" = true
-
-	[tweaks.reacharound_placing]
-		#
-		#Allowed values: [0,1]
-		Leniency = 0.5
-		Whitelist = []
-		"Display Horizontal" = "<  >"
-		Display = "[  ]"
-
-	[tweaks.improved_sleeping]
-		"Enable Afk" = true
-		#
-		#Allowed values: (0,)
-		"Afk Time" = 2400
-		#
-		#Allowed values: (0,1]
-		"Percent Req" = 1.0
-
-	[tweaks.emotes]
-		#
-		#The enabled default emotes. Remove from this list to disable them. You can also re-order them, if you feel like it.
-		"Enabled Emotes" = ["no", "yes", "wave", "salute", "cheer", "clap", "think", "point", "shrug", "headbang", "weep", "facepalm"]
-		#
-		#Enable this to make custom emotes read the file every time they're triggered so you can edit on the fly.
-		#DO NOT ship enabled this in a modpack, please.
-		"Custom Emote Debug" = false
-		#
-		#The list of Custom Emotes to be loaded.
-		#Watch the tutorial on Custom Emotes to learn how to make your own: https://youtu.be/ourHUkan6aQ
-		"Custom Emotes" = []
-
-	[tweaks.simple_harvest]
-		#
-		#Can players harvest crops with empty hand clicks?
-		"Empty Hand Harvest" = true
-		#
-		#Does harvesting crops with a hoe cost durability?
-		"Harvesting Costs Durability" = false
-		#
-		#Should Quark look for (nonvanilla) crops, and handle them?
-		"Do Harvesting Search" = true
-		#
-		#Which crops can be harvested?
-		#Format is: "harvestState[,afterHarvest]", i.e. "minecraft:wheat[age=7]" or "minecraft:cocoa[age=2,facing=north],minecraft:cocoa[age=0,facing=north]"
-		"Harvestable Blocks" = ["minecraft:wheat[age=7]", "minecraft:carrots[age=7]", "minecraft:potatoes[age=7]", "minecraft:beetroots[age=3]", "minecraft:nether_wart[age=3]", "minecraft:cocoa[age=2,facing=north],minecraft:cocoa[age=0,facing=north]", "minecraft:cocoa[age=2,facing=south],minecraft:cocoa[age=0,facing=south]", "minecraft:cocoa[age=2,facing=east],minecraft:cocoa[age=0,facing=east]", "minecraft:cocoa[age=2,facing=west],minecraft:cocoa[age=0,facing=west]"]
-
-	[tweaks.enhanced_ladders]
-		#
-		#Allowed values: (,0]
-		"Fall Speed" = -0.2
-
-	[tweaks.compasses_work_everywhere]
-		"Enable Nether" = true
-		"Enable Compass Nerf" = true
-		"Enable End" = true
-		"Enable Clock Nerf" = true
-
-	[tweaks.campfires_boost_elytra]
-		"Boost Strength" = 0.5
-		"Max Speed" = 1.0
-
-	[tweaks.replace_scaffolding]
-		#
-		#How many times the algorithm for finding out where a block would be placed is allowed to turn. If you set this to large values (> 3) it may start producing weird effects.
-		"Max Bounces" = 1
-
-[world]
-	"New Stone Types" = true
-	"Lush Underground Biome" = true
-	"Big Dungeon" = true
-	Speleothems = true
-	"Elder Prismarine Underground Biome" = true
-	"Blossom Trees" = true
-	"Sandstone Underground Biome" = true
-	"Glowshroom Underground Biome" = true
-	"Permafrost Underground Biome" = true
-	"Underground Clay" = true
-	"Slime Underground Biome" = true
-	"Fairy Rings" = true
-	"Chorus Vegetation" = true
-	Crevices = true
-	"Nether Obsidian Spikes" = true
-	"Mega Caves" = true
-	"Realistic World Gen" = true
-	Biotite = true
-	"Big Stone Clusters" = true
-	"Brimstone Underground Biome" = true
-	"Cave Crystal Underground Biome" = true
-	"Spiral Spires" = true
-	"Overgrown Underground Biome" = true
-	"Cave Roots" = true
-	"Spider Nest Underground Biome" = true
-	"Monster Box" = true
-
-	[world.monster_box]
-		#
-		#The chance for the monster box generator to try and place one in a chunk, 1 is 100%
-		#This can be higher than 100% if you want multiple per chunk, , 0 is 0%
-		"Chance Per Chunk" = 0.8
-		"Min Mob Count" = 5
-		"Min Y" = 5
-		"Max Y" = 30
-		"Max Mob Count" = 8
-		"Enable Extra Loot Table" = true
-		#
-		#How many blocks to search vertically from a position before trying to place a block. Higher means you'll get more boxes in open spaces.
-		"Search Range" = 6
-
-		[world.monster_box.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-	[world.cave_crystal_underground_biome]
-		#
-		#The chance that a crystal can grow, this is on average 1 in X world ticks, set to a higher value to make them grow slower. Minimum is 1, for every tick. Set to 0 to disable growth.
-		"Cave Crystal Growth Chance" = 5
-		"Crystals Grow In Lava" = false
-		#
-		#Allowed values: [0,1]
-		"Crystal Spawn Chance" = 0.025
-		"Crystals Craft Runes" = true
-
-		[world.cave_crystal_underground_biome.biome_settings]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 42
-			#
-			#Allowed values: [0,)
-			Rarity = 400
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 22
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 18
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 8
-
-			[world.cave_crystal_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["ocean"]
-				"Is Blacklist" = true
-
-			[world.cave_crystal_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.speleothems]
-		"Tries Per Chunk In Nether" = 4
-		"Speleothems Per Chunk In Nether" = 12
-		"Speleothems Per Chunk" = 12
-		"Max Ylevel" = 55
-		"Tries Per Chunk" = 60
-
-		[world.speleothems.dimensions]
-			Dimensions = []
-			"Is Blacklist" = true
-
-	[world.sandstone_underground_biome]
-
-		[world.sandstone_underground_biome.biome_settings]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#
-			#Allowed values: [0,)
-			Rarity = 80
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.sandstone_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["desert"]
-				"Is Blacklist" = false
-
-			[world.sandstone_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.spiral_spires]
-		Radius = 15
-		Rarity = 200
-		#
-		#Set to 0 to turn off Myalite Conduits
-		"Myalite Conduit Distance" = 24
-		"Renewable Myalite" = true
-
-		[world.spiral_spires.biomes]
-			Biomes = ["minecraft:end_highlands"]
-			"Is Blacklist" = false
-
-		[world.spiral_spires.dimensions]
-			Dimensions = ["minecraft:the_end"]
-			"Is Blacklist" = false
-
-	[world.nether_obsidian_spikes]
-		#
-		#The chance for a chunk to contain spikes (1 is 100%, 0 is 0%)
-		"Chance Per Chunk" = 0.1
-		"Big Spike Spawners" = true
-		#
-		#Should a chunk have spikes, how many would the generator try to place
-		"Tries Per Chunk" = 4
-		#
-		#The chance for a spike to be big (1 is 100%, 0 is 0%)
-		"Big Spike Chance" = 0.03
-
-		[world.nether_obsidian_spikes.dimensions]
-			Dimensions = ["minecraft:the_nether"]
-			"Is Blacklist" = false
-
-	[world.biotite]
-		"Clusters Per Dragon Tick" = 16
-		"Generate On Dragon Death" = true
-		"Dragon Ticks Per Cluster" = 1
-		"Generate Naturally" = false
-
-		[world.biotite.dimensions]
-			Dimensions = ["minecraft:the_end"]
-			"Is Blacklist" = false
-
-		[world.biotite.ore_settings]
-			#
-			#Allowed values: [0,255]
-			"Max Height" = 64
-			#
-			#Allowed values: [0,)
-			"Cluster Count" = 16
-			#
-			#Allowed values: [0,255]
-			"Min Height" = 1
-			#
-			#Allowed values: [0,)
-			"Cluster Size" = 14
-
-	[world.crevices]
-
-		[world.crevices.spawn_settings]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 60
-			#
-			#Allowed values: [0,)
-			Rarity = 120
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 15
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 20
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 50
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 4
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 1
-
-			[world.crevices.spawn_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["ocean", "beach"]
-				"Is Blacklist" = true
-
-			[world.crevices.spawn_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.crevices.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-	[world.cave_roots]
-		"Min Y" = 16
-		"Chunk Attempts" = 300
-		"Max Y" = 52
-		"Enable Brewing" = true
-
-		[world.cave_roots.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-	[world.new_stone_types]
-		"Enable Marble" = true
-		"Enable Myalite" = true
-		"Enable Jasper" = true
-		"Enable Voidstone" = true
-		"Enable Slate" = true
-		"Enable Limestone" = true
-
-		[world.new_stone_types.marble]
-
-			[world.new_stone_types.marble.oregen]
-				#
-				#Allowed values: [0,255]
-				"Max Height" = 256
-				#
-				#Allowed values: [0,)
-				"Cluster Count" = 10
-				#
-				#Allowed values: [0,255]
-				"Min Height" = 0
-				#
-				#Allowed values: [0,)
-				"Cluster Size" = 33
-
-			[world.new_stone_types.marble.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.new_stone_types.limestone]
-
-			[world.new_stone_types.limestone.oregen]
-				#
-				#Allowed values: [0,255]
-				"Max Height" = 256
-				#
-				#Allowed values: [0,)
-				"Cluster Count" = 10
-				#
-				#Allowed values: [0,255]
-				"Min Height" = 0
-				#
-				#Allowed values: [0,)
-				"Cluster Size" = 33
-
-			[world.new_stone_types.limestone.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.new_stone_types.myalite]
-
-			[world.new_stone_types.myalite.oregen]
-				#
-				#Allowed values: [0,255]
-				"Max Height" = 256
-				#
-				#Allowed values: [0,)
-				"Cluster Count" = 10
-				#
-				#Allowed values: [0,255]
-				"Min Height" = 0
-				#
-				#Allowed values: [0,)
-				"Cluster Size" = 33
-
-			[world.new_stone_types.myalite.dimensions]
-				Dimensions = ["minecraft:the_end"]
-				"Is Blacklist" = false
-
-		[world.new_stone_types.voidstone]
-
-			[world.new_stone_types.voidstone.oregen]
-				#
-				#Allowed values: [0,255]
-				"Max Height" = 256
-				#
-				#Allowed values: [0,)
-				"Cluster Count" = 10
-				#
-				#Allowed values: [0,255]
-				"Min Height" = 0
-				#
-				#Allowed values: [0,)
-				"Cluster Size" = 33
-
-			[world.new_stone_types.voidstone.dimensions]
-				Dimensions = ["minecraft:the_end"]
-				"Is Blacklist" = false
-
-		[world.new_stone_types.slate]
-
-			[world.new_stone_types.slate.oregen]
-				#
-				#Allowed values: [0,255]
-				"Max Height" = 256
-				#
-				#Allowed values: [0,)
-				"Cluster Count" = 10
-				#
-				#Allowed values: [0,255]
-				"Min Height" = 0
-				#
-				#Allowed values: [0,)
-				"Cluster Size" = 33
-
-			[world.new_stone_types.slate.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.new_stone_types.jasper]
-
-			[world.new_stone_types.jasper.oregen]
-				#
-				#Allowed values: [0,255]
-				"Max Height" = 256
-				#
-				#Allowed values: [0,)
-				"Cluster Count" = 10
-				#
-				#Allowed values: [0,255]
-				"Min Height" = 0
-				#
-				#Allowed values: [0,)
-				"Cluster Size" = 33
-
-			[world.new_stone_types.jasper.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.spider_nest_underground_biome]
-		"Enabled Wrapped" = true
-
-		[world.spider_nest_underground_biome.biome_settings]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#
-			#Allowed values: [0,)
-			Rarity = 80
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.spider_nest_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["plains"]
-				"Is Blacklist" = false
-
-			[world.spider_nest_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.blossom_trees]
-
-		[world.blossom_trees.orange]
-			Rarity = 100
-
-			[world.blossom_trees.orange.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-			[world.blossom_trees.orange.biome_types]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["savanna"]
-				"Is Blacklist" = false
-
-		[world.blossom_trees.red]
-			Rarity = 30
-
-			[world.blossom_trees.red.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-			[world.blossom_trees.red.biome_types]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["mesa"]
-				"Is Blacklist" = false
-
-		[world.blossom_trees.pink]
-			Rarity = 100
-
-			[world.blossom_trees.pink.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-			[world.blossom_trees.pink.biome_types]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["extreme_hills"]
-				"Is Blacklist" = false
-
-		[world.blossom_trees.blue]
-			Rarity = 200
-
-			[world.blossom_trees.blue.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-			[world.blossom_trees.blue.biome_types]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["icy"]
-				"Is Blacklist" = false
-
-		[world.blossom_trees.yellow]
-			Rarity = 200
-
-			[world.blossom_trees.yellow.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-			[world.blossom_trees.yellow.biome_types]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["plains"]
-				"Is Blacklist" = false
-
-		[world.blossom_trees.lavender]
-			Rarity = 100
-
-			[world.blossom_trees.lavender.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-			[world.blossom_trees.lavender.biome_types]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["swamp"]
-				"Is Blacklist" = false
-
-	[world.mega_caves]
-
-		[world.mega_caves.spawn_settings]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 80
-			#
-			#Allowed values: [0,)
-			Rarity = 800
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 10
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 30
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 20
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 25
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 10
-
-			[world.mega_caves.spawn_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["ocean", "beach"]
-				"Is Blacklist" = true
-
-			[world.mega_caves.spawn_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.mega_caves.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-	[world.elder_prismarine_underground_biome]
-		#
-		#Allowed values: [0,1]
-		"Lantern Chance" = 0.0085
-		#
-		#Allowed values: [0,1]
-		"Water Chance" = 0.25
-
-		[world.elder_prismarine_underground_biome.biome_settings]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#
-			#Allowed values: [0,)
-			Rarity = 200
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.elder_prismarine_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["ocean"]
-				"Is Blacklist" = false
-
-			[world.elder_prismarine_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.glowshroom_underground_biome]
-		#
-		#Allowed values: [0,1]
-		"Glowshroom Spawn Chance" = 0.0625
-		#
-		#Allowed values: (0,)
-		"Glowshroom Growth Rate" = 20
-		"Enable Danger Sight" = true
-		"Enable Huge Glowshrooms" = true
-
-		[world.glowshroom_underground_biome.biome_settings]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#
-			#Allowed values: [0,)
-			Rarity = 80
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.glowshroom_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["extreme_hills", "mushroom"]
-				"Is Blacklist" = false
-
-			[world.glowshroom_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.big_stone_clusters]
-		#
-		#Blocks that stone clusters can replace. If you want to make it so it only replaces in one dimension,
-		#do "block|dimension", as we do for netherrack and end stone by default.
-		"Blocks To Replace" = ["minecraft:stone", "minecraft:andesite", "minecraft:diorite", "minecraft:granite", "minecraft:netherrack|minecraft:the_nether", "minecraft:end_stone|minecraft:the_end", "quark:marble", "quark:limestone", "quark:jasper", "quark:slate", "quark:basalt"]
-
-		[world.big_stone_clusters.marble]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 14
-			#
-			#Allowed values: [0,)
-			Rarity = 4
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 20
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 9
-			Enabled = true
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 80
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 9
-
-			[world.big_stone_clusters.marble.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["plains"]
-				"Is Blacklist" = false
-
-			[world.big_stone_clusters.marble.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.big_stone_clusters.limestone]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 14
-			#
-			#Allowed values: [0,)
-			Rarity = 4
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 20
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 9
-			Enabled = true
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 80
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 9
-
-			[world.big_stone_clusters.limestone.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["swamp", "ocean"]
-				"Is Blacklist" = false
-
-			[world.big_stone_clusters.limestone.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.big_stone_clusters.granite]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 14
-			#
-			#Allowed values: [0,)
-			Rarity = 4
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 20
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 9
-			Enabled = true
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 80
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 9
-
-			[world.big_stone_clusters.granite.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["extreme_hills"]
-				"Is Blacklist" = false
-
-			[world.big_stone_clusters.granite.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.big_stone_clusters.myalite]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 20
-			#
-			#Allowed values: [0,)
-			Rarity = 100
-			"Generate In Air" = true
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 58
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 6
-			Enabled = true
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 62
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 40
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 10
-
-			[world.big_stone_clusters.myalite.biomes]
-				Biomes = ["minecraft:end_highlands"]
-				"Is Blacklist" = false
-
-			[world.big_stone_clusters.myalite.dimensions]
-				Dimensions = ["minecraft:the_end"]
-				"Is Blacklist" = false
-
-		[world.big_stone_clusters.voidstone]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 19
-			#
-			#Allowed values: [0,)
-			Rarity = 20
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 6
-			Enabled = true
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 40
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 19
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.big_stone_clusters.voidstone.biomes]
-				Biomes = ["minecraft:end_highlands", "minecraft:end_midlands", "minecraft:end_barrens"]
-				"Is Blacklist" = false
-
-			[world.big_stone_clusters.voidstone.dimensions]
-				Dimensions = ["minecraft:the_end"]
-				"Is Blacklist" = false
-
-		[world.big_stone_clusters.andesite]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 14
-			#
-			#Allowed values: [0,)
-			Rarity = 4
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 20
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 9
-			Enabled = true
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 80
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 9
-
-			[world.big_stone_clusters.andesite.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["forest"]
-				"Is Blacklist" = false
-
-			[world.big_stone_clusters.andesite.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.big_stone_clusters.slate]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 14
-			#
-			#Allowed values: [0,)
-			Rarity = 4
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 20
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 9
-			Enabled = true
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 80
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 9
-
-			[world.big_stone_clusters.slate.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["icy"]
-				"Is Blacklist" = false
-
-			[world.big_stone_clusters.slate.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.big_stone_clusters.diorite]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 14
-			#
-			#Allowed values: [0,)
-			Rarity = 4
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 20
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 9
-			Enabled = true
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 80
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 9
-
-			[world.big_stone_clusters.diorite.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["savanna", "jungle", "mushroom"]
-				"Is Blacklist" = false
-
-			[world.big_stone_clusters.diorite.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.big_stone_clusters.jasper]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 14
-			#
-			#Allowed values: [0,)
-			Rarity = 4
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 20
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 9
-			Enabled = true
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 80
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 9
-
-			[world.big_stone_clusters.jasper.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["mesa", "desert"]
-				"Is Blacklist" = false
-
-			[world.big_stone_clusters.jasper.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.overgrown_underground_biome]
-
-		[world.overgrown_underground_biome.biome_settings]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#
-			#Allowed values: [0,)
-			Rarity = 80
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.overgrown_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["forest"]
-				"Is Blacklist" = false
-
-			[world.overgrown_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.permafrost_underground_biome]
-
-		[world.permafrost_underground_biome.biome_settings]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#
-			#Allowed values: [0,)
-			Rarity = 80
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.permafrost_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["icy"]
-				"Is Blacklist" = false
-
-			[world.permafrost_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.lush_underground_biome]
-
-		[world.lush_underground_biome.biome_settings]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#
-			#Allowed values: [0,)
-			Rarity = 80
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.lush_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["jungle"]
-				"Is Blacklist" = false
-
-			[world.lush_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.brimstone_underground_biome]
-
-		[world.brimstone_underground_biome.biome_settings]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#
-			#Allowed values: [0,)
-			Rarity = 80
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.brimstone_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["mesa"]
-				"Is Blacklist" = false
-
-			[world.brimstone_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.big_dungeon]
-		"Loot Table" = "minecraft:chests/simple_dungeon"
-		#
-		#The chance that a big dungeon spawn candidate will be allowed to spawn. 0.2 is 20%, which is the same as the Pillager Outpost.
-		"Spawn Chance" = 0.1
-		"Max Rooms" = 10
-		"Chest Chance" = 0.5
-
-		[world.big_dungeon.biome_types]
-			#
-			#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-			# icy, the_end, beach, forest, ocean, desert, river, swamp,
-			# mushroom, nether]
-			"Biome Categories" = ["ocean", "beach", "nether", "the_end"]
-			"Is Blacklist" = true
-
-	[world.chorus_vegetation]
-		"Teleport Duplication Chance" = 0.01
-		Radius = 7
-		Rarity = 150
-		"Chunk Attempts" = 120
-		"Highlands Chance" = 1.0
-		"Midlands Chance" = 0.2
-		"Endermite Spawn Chance" = 0.01
-		"Passive Teleport Chance" = 0.2
-		"Other End Biomes Chance" = 0.0
-
-	[world.fairy_rings]
-		"Forest Chance" = 0.00625
-		Ores = ["minecraft:emerald_ore", "minecraft:diamond_ore"]
-		"Plains Chance" = 0.0025
-
-		[world.fairy_rings.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-	[world.underground_clay]
-
-		[world.underground_clay.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-		[world.underground_clay.ore_settings]
-			#
-			#Allowed values: [0,255]
-			"Max Height" = 60
-			#
-			#Allowed values: [0,)
-			"Cluster Count" = 3
-			#
-			#Allowed values: [0,255]
-			"Min Height" = 20
-			#
-			#Allowed values: [0,)
-			"Cluster Size" = 20
-
-	[world.slime_underground_biome]
-
-		[world.slime_underground_biome.biome_settings]
-			#
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#
-			#Allowed values: [0,)
-			Rarity = 120
-			#
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.slime_underground_biome.biome_settings.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["swamp"]
-				"Is Blacklist" = false
-
-			[world.slime_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-[mobs]
-	Frogs = true
-	Crabs = true
-	Stonelings = true
-	Foxhound = true
-	Forgotten = true
-	Wraith = true
-	Toretoise = true
-
-	[mobs.toretoise]
-		"Max Y Level" = 32
-
-		[mobs.toretoise.spawn_config]
-			#
-			#Allowed values: (0,)
-			"Spawn Weight" = 100
-			#
-			#Allowed values: [1,)
-			"Min Group Size" = 1
-			#
-			#Allowed values: [1,)
-			"Max Group Size" = 1
-
-			[mobs.toretoise.spawn_config.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["none", "nether", "the_end"]
-				"Is Blacklist" = true
-
-		[mobs.toretoise.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-	[mobs.crabs]
-		"Enable Brewing" = true
-
-		[mobs.crabs.spawn_config]
-			#
-			#Allowed values: (0,)
-			"Spawn Weight" = 5
-			#
-			#Allowed values: [1,)
-			"Min Group Size" = 1
-			#
-			#Allowed values: [1,)
-			"Max Group Size" = 3
-
-			[mobs.crabs.spawn_config.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["beach"]
-				"Is Blacklist" = false
-
-	[mobs.foxhound]
-		#
-		#The chance coal will tame a foxhound
-		"Tame Chance" = 0.05
-
-		[mobs.foxhound.lesser_spawn_config]
-			#
-			#Allowed values: (0,)
-			"Spawn Weight" = 2
-			"Max Cost" = 0.7
-			#
-			#Allowed values: [1,)
-			"Min Group Size" = 1
-			"Spawn Cost" = 0.15
-			#
-			#Allowed values: [1,)
-			"Max Group Size" = 1
-
-			[mobs.foxhound.lesser_spawn_config.biomes]
-				Biomes = ["minecraft:soul_sand_valley"]
-				"Is Blacklist" = false
-
-		[mobs.foxhound.spawn_config]
-			#
-			#Allowed values: (0,)
-			"Spawn Weight" = 30
-			#
-			#Allowed values: [1,)
-			"Min Group Size" = 1
-			#
-			#Allowed values: [1,)
-			"Max Group Size" = 2
-
-			[mobs.foxhound.spawn_config.biomes]
-				Biomes = ["minecraft:nether_wastes", "minecraft:basalt_deltas"]
-				"Is Blacklist" = false
-
-	[mobs.wraith]
-		#
-		#List of sound sets to use with wraiths.
-		#Three sounds must be provided per entry, separated by | (in the format idle|hurt|death). Leave blank for no sound (i.e. if a mob has no ambient noise)
-		"Wraith Sounds" = ["entity.sheep.ambient|entity.sheep.hurt|entity.sheep.death", "entity.cow.ambient|entity.cow.hurt|entity.cow.death", "entity.pig.ambient|entity.pig.hurt|entity.pig.death", "entity.chicken.ambient|entity.chicken.hurt|entity.chicken.death", "entity.horse.ambient|entity.horse.hurt|entity.horse.death", "entity.cat.ambient|entity.cat.hurt|entity.cat.death", "entity.wolf.ambient|entity.wolf.hurt|entity.wolf.death", "entity.villager.ambient|entity.villager.hurt|entity.villager.death", "entity.polar_bear.ambient|entity.polar_bear.hurt|entity.polar_bear.death", "entity.zombie.ambient|entity.zombie.hurt|entity.zombie.death", "entity.skeleton.ambient|entity.skeleton.hurt|entity.skeleton.death", "entity.spider.ambient|entity.spider.hurt|entity.spider.death", "|entity.creeper.hurt|entity.creeper.death", "entity.endermen.ambient|entity.endermen.hurt|entity.endermen.death", "entity.zombie_pig.ambient|entity.zombie_pig.hurt|entity.zombie_pig.death", "entity.witch.ambient|entity.witch.hurt|entity.witch.death", "entity.blaze.ambient|entity.blaze.hurt|entity.blaze.death", "entity.llama.ambient|entity.llama.hurt|entity.llama.death", "|quark:entity.stoneling.cry|quark:entity.stoneling.die", "quark:entity.frog.idle|quark:entity.frog.hurt|quark:entity.frog.die"]
-
-		[mobs.wraith.spawn_config]
-			#
-			#Allowed values: (0,)
-			"Spawn Weight" = 8
-			"Max Cost" = 0.7
-			#
-			#Allowed values: [1,)
-			"Min Group Size" = 1
-			"Spawn Cost" = 0.15
-			#
-			#Allowed values: [1,)
-			"Max Group Size" = 3
-
-			[mobs.wraith.spawn_config.biomes]
-				Biomes = ["minecraft:soul_sand_valley"]
-				"Is Blacklist" = false
-
-	[mobs.stonelings]
-		"Cautious Stonelings" = true
-		"Enable Diamond Heart" = true
-		"Max Y Level" = 24
-		"Tamable Stonelings" = true
-
-		[mobs.stonelings.spawn_config]
-			#
-			#Allowed values: (0,)
-			"Spawn Weight" = 80
-			#
-			#Allowed values: [1,)
-			"Min Group Size" = 1
-			#
-			#Allowed values: [1,)
-			"Max Group Size" = 1
-
-			[mobs.stonelings.spawn_config.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["none", "nether", "the_end"]
-				"Is Blacklist" = true
-
-		[mobs.stonelings.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-	[mobs.forgotten]
-		#
-		#1 in this many Skeletons that spawn under the threshold are replaced with Forgotten.
-		"Forgotten Spawn Rate" = 0.05
-		"Max Height For Spawn" = 20
-
-	[mobs.frogs]
-		"Enable Brewing" = true
-		"Enable Big Funny" = false
-
-		[mobs.frogs.spawn_config]
-			#
-			#Allowed values: (0,)
-			"Spawn Weight" = 40
-			#
-			#Allowed values: [1,)
-			"Min Group Size" = 1
-			#
-			#Allowed values: [1,)
-			"Max Group Size" = 3
-
-			[mobs.frogs.spawn_config.biomes]
-				#
-				#Allowed values: [[none, taiga, extreme_hills, jungle, mesa, plains, savanna,
-				# icy, the_end, beach, forest, ocean, desert, river, swamp,
-				# mushroom, nether]
-				"Biome Categories" = ["swamp"]
-				"Is Blacklist" = false
-
-[client]
-	"Greener Grass" = true
-	"Variant Animal Textures" = true
-	"Back Button Keybind" = true
-	"Improved Tooltips" = true
-	"Improved Mount Hud" = true
-	"Usage Ticker" = true
-	"Auto Walk Keybind" = true
-	"Chest Searching" = true
-
-	[client.usage_ticker]
-		#
-		#Switch the armor display to the off hand side and the hand display to the main hand side
-		Invert = false
-		"Shift Right" = 0
-		"Enable Armor" = true
-		"Enable Off Hand" = true
-		"Shift Left" = 0
-		"Enable Main Hand" = true
-
-	[client.variant_animal_textures]
-		"Enable Shiny Llama" = true
-		"Every Bee Is L G B T" = false
-		#
-		#The chance for an animal to have a special "Shiny" skin, like a shiny pokemon. This is 1 in X. Set to 0 to disable.
-		"Shiny Animal Chance" = 2048
-		"Enable Pig" = true
-		"Enable Chicken" = true
-		"Enable Shiny Rabbit" = true
-		"Enable L G B T Bees" = true
-		"Enable Cow" = true
-
-	[client.improved_tooltips]
-		"Shulker Box Require Shift" = false
-		"Shulker Box Use Colors" = true
-		"Attribute Tooltips" = true
-		"Enchanting Tooltips" = true
-		#
-		#The value of each shank of food. Tweak this when using mods like Hardcore Hunger which change that value.
-		"Food Divisor" = 2
-		#
-		#A list of additional stacks to display on each enchantment
-		#The format is as follows:
-		#enchant_id=item1,item2,item3...
-		#So to display a carrot on a stick on a mending book, for example, you use:
-		#minecraft:mending=minecraft:carrot_on_a_stick
-		"Enchanting Additional Stacks" = []
-		"Food Compression Threshold" = 4
-		"Shulker Tooltips" = true
-		"Map Require Shift" = false
-		"Food Tooltips" = true
-		"Show Saturation" = true
-		"Map Tooltips" = true
-		"Enchanting Stacks" = ["minecraft:diamond_sword", "minecraft:diamond_pickaxe", "minecraft:diamond_shovel", "minecraft:diamond_axe", "minecraft:diamond_hoe", "minecraft:diamond_helmet", "minecraft:diamond_chestplate", "minecraft:diamond_leggings", "minecraft:diamond_boots", "minecraft:shears", "minecraft:bow", "minecraft:fishing_rod", "minecraft:crossbow", "minecraft:trident", "minecraft:elytra", "quark:pickarang"]
-
-	[client.greener_grass]
-		"Leaves List" = ["minecraft:spruce_leaves", "minecraft:birch_leaves", "minecraft:oak_leaves", "minecraft:jungle_leaves", "minecraft:acacia_leaves", "minecraft:dark_oak_leaves", "atmospheric:rosewood_leaves", "atmospheric:morado_leaves", "atmospheric:yucca_leaves", "autumnity:maple_leaves", "environmental:willow_leaves", "environmental:hanging_willow_leaves", "minecraft:vine"]
-		"Green Shift" = 30
-		"Blue Shift" = -30
-		"Block List" = ["minecraft:large_fern", "minecraft:tall_grass", "minecraft:grass_block", "minecraft:fern", "minecraft:grass", "minecraft:potted_fern", "minecraft:sugar_cane", "environmental:giant_tall_grass"]
-		"Alpha Grass" = false
-		"Absolute Values" = false
-		"Red Shift" = -30
-		"Affect Leaves" = true
-
-[oddities]
-	"Totem Of Holding" = true
-	Backpack = true
-	Crate = false
-	"Matrix Enchanting" = true
-	Magnets = true
-	Pipes = true
-
-	[oddities.totem_of_holding]
-		#
-		#Set this to false to remove the behaviour where totems destroy themselves if the player dies again.
-		"Dark Souls Mode" = true
-		"Spawn Totem on PVP Kill" = false
-		#
-		#Set this to true to make it so that if a totem is destroyed, the items it holds are destroyed alongside it rather than dropped
-		"Destroy Lost Items" = false
-		"Enable Soul Compass" = true
-		#
-		#Set this to false to only allow the owner of a totem to collect its items rather than any player
-		"Allow Anyone To Collect" = true
-
-	[oddities.magnets]
-		"Magnetic Blacklist" = ["minecraft:tripwire_hook"]
-		"Magnetic Whitelist" = ["minecraft:chipped_anvil", "minecraft:damaged_anvil"]
-		#
-		#Any items you place in this list will be derived so that any block made of it will become magnetizable
-		"Magnetic Derivation List" = ["minecraft:iron_ingot"]
-
-	[oddities.matrix_enchanting]
-		#
-		#Set to false to disable the ability to influence enchantment outcomes with candles (requires the Tallow and Candles module enabled)
-		"Allow Influencing" = true
-		#
-		#A list of enchantment IDs you don't want the enchantment table to be able to create
-		"Disallowed Enchantments" = []
-		#
-		#The maximum enchanting power the matrix enchanter can accept
-		"Max Bookshelves" = 15
-		#
-		#How much to multiply the frequency of pieces where at least one of the same type has been generated
-		"Dupe Multiplier" = 1.4
-		#
-		#How much the min level requirement for adding a new piece to a book should increase per each bookshelf being used
-		"Min Level Scale Factor Book" = 2.0
-		#
-		#At which piece count the calculation for the min level should default to increasing one per piece rather than using the scale factor
-		"Min Level Cutoff" = 10
-		#
-		#Should this be X, the price of a piece increase by 1 every X pieces you generate
-		"Piece Price Scale" = 9
-		#
-		#Matrix Enchanting can be done with water instead of air around the enchanting table. Set this to false to disable this behaviour.
-		"Allow Underwater Enchanting" = true
-		#
-		#How many pieces you can generate without any bookshelves
-		"Base Max Piece Count" = 3
-		#
-		#How much each candle influences an enchantment. This works as a multiplier to its weight
-		"Influence Power" = 0.125
-		#
-		#Set to false to disable the tooltip for items with pending enchantments
-		"Show Tooltip" = true
-		#
-		#Set to false to disable the ability to create Enchanted Books
-		"Allow Books" = true
-		#
-		#The higher this is, the better enchantments you'll get on books
-		"Book Enchantability" = 12
-		#
-		#An array of influences each candle should apply. This list must be 16 elements long, and is in order of wool colors.
-		"Influences List" = ["minecraft:unbreaking", "minecraft:fire_protection", "minecraft:knockback,minecraft:punch", "minecraft:feather_falling", "minecraft:looting,minecraft:fortune,minecraft:luck_of_the_sea", "minecraft:blast_protection", "minecraft:silk_touch,minecraft:channeling", "minecraft:bane_of_arthropods", "minecraft:protection", "minecraft:respiration,minecraft:loyalty,minecraft:infinity", "minecraft:sweeping,minecraft:multishot", "minecraft:efficiency,minecraft:sharpness,minecraft:lure,minecraft:power,minecraft:impaling,minecraft:quick_charge", "minecraft:aqua_affinity,minecraft:depth_strider,minecraft:riptide", "minecraft:thorns,minecraft:piercing", "minecraft:fire_aspect,minecraft:flame", "minecraft:smite,minecraft:projectile_protection"]
-		#
-		#How many pieces a single Lapis can generate
-		"Charge Per Lapis" = 4
-		#
-		#How many pieces you can generate without any bookshelves (for Books)
-		"Base Max Piece Count Book" = 1
-		#
-		#How much to multiply the frequency of pieces where incompatible pieces have been generated
-		"Incompatible Multiplier" = 0.0
-		#
-		#How much the min level requirement for adding a new piece should increase for each piece added (up until the value of Min Level Cutoff)
-		"Min Level Scale Factor" = 1.5
-		#
-		#Set this to true to allow treasure enchantments to be rolled as pieces
-		"Allow Treasures" = false
-		#
-		#By default, enchantment rarities are fuzzed a bit to feel better with the new system. Set this to false to override this behaviour.
-		"Normalize Rarity" = true
-		#
-		#The max amount of candles that can influence a single enchantment
-		"Influence Max" = 4
-
-	[oddities.backpack]
-		"Enable Ravager Hide" = true
-		"Base Ravager Hide Drop" = 1
-		"Extra Chance Per Looting" = 0.5
-		#
-		#Set this to true to allow the backpacks to be unequipped even with items in them
-		"Super Op Mode" = false
-
-	[oddities.crate]
-		"Max Items" = 640
-
-	[oddities.pipes]
-		#
-		#Set to 0 if you don't want pipes to have a max amount of items
-		"Max Pipe Items" = 16
-		#
-		#When items eject or are absorbed by pipes, should they make sounds?
-		"Do Pipes Whoosh" = true
-		#
-		#How long it takes for an item to cross a pipe. Bigger = slower.
-		"Pipe Speed" = 5
-
-[experimental]
-	"Adjustable Chat" = false
-	"Narrator Readout" = false
-	"Overlay Shader" = false
-	"Custom Underground Biome" = false
-	"Game Nerfs" = false
-
-	[experimental.adjustable_chat]
-		"Horizontal Shift" = 0
-		"Vertical Shift" = 0
-
-	[experimental.custom_underground_biome]
-		#
-		#The format for these definitions is:
-		#dimensions;isDimensionBlacklist;biomeTypews;isBiomeBlacklist;rarity;minY..maxY;horizontalSize,verticalSize;horizontalVariation,verticalVariation;floorBlocks@weight;ceilingBlocks@weight;wallBlocks@weight;mimicInside
-		#That's a lot to take in, so here's an example. This would be for the default config of the Slime underground biome. (Spaces are allowed.)
-		#minecraft:overworld; false; SWAMP; false; 120; 10..40; 26,14; 14,6; minecraft:water@915, minecraft:slime_block@85; minecraft:green_terracotta@2, minecraft:lime_terracotta@3, minecraft:light_blue_terracotta@1; CEILING; false
-		"Biome Definitions" = []
-
-	[experimental.game_nerfs]
-		#
-		#Makes Mending act like the Unmending mod
-		#https://www.curseforge.com/minecraft/mc-mods/unmending
-		"Nerf Mending" = true
-		#
-		#Makes Iron Golems not drop Iron Ingots
-		"Disable Iron Farms" = true
-		#
-		#Makes Sheep not drop Wool when killed
-		"Disable Wool Drops" = true
-		#
-		#Makes Boats not glide on ice
-		"Disable Ice Roads" = true
-		#
-		#Resets all villager discounts when zombified to prevent reducing prices to ridiculous levels
-		"Nerf Villager Discount" = true
-
-	[experimental.overlay_shader]
-		#
-		#Sets the name of the shader to load on a regular basis. This can load any shader the Camera module can (and requires the Camera module enabled to apply said logic).
-		#Some useful shaders include 'desaturate', 'oversaturate', 'bumpy'
-		#Colorblind simulation shaders are available in the form of 'deuteranopia', 'protanopia', 'tritanopia', and 'achromatopsia'
-		Shader = "none"
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/quark-common-2.toml.bak b/configuration/services/configs/minecraft/voor-kia/config/quark-common-2.toml.bak
deleted file mode 100644
index e69de29..0000000
diff --git a/configuration/services/configs/minecraft/voor-kia/config/quark-common-3.toml.bak b/configuration/services/configs/minecraft/voor-kia/config/quark-common-3.toml.bak
deleted file mode 100644
index e69de29..0000000
diff --git a/configuration/services/configs/minecraft/voor-kia/config/quark-common-4.toml.bak b/configuration/services/configs/minecraft/voor-kia/config/quark-common-4.toml.bak
deleted file mode 100644
index e69de29..0000000
diff --git a/configuration/services/configs/minecraft/voor-kia/config/quark-common-5.toml.bak b/configuration/services/configs/minecraft/voor-kia/config/quark-common-5.toml.bak
deleted file mode 100644
index e69de29..0000000
diff --git a/configuration/services/configs/minecraft/voor-kia/config/quark-common.toml b/configuration/services/configs/minecraft/voor-kia/config/quark-common.toml
deleted file mode 100644
index 8a6398b..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/quark-common.toml
+++ /dev/null
@@ -1,2078 +0,0 @@
-
-[general]
-	#Allowed values: (0,)
-	"Advancement Visibility Depth" = 2
-	"'q' Button on the Right" = false
-	#Allowed values: (0,)
-	"Piston Push Limit" = 12
-	#Set to true to make the quark big worldgen features such as stone clusters or underground biomes generate as spheres rather than unique shapes. It's faster, but won't look as cool
-	"Use Fast Worldgen" = false
-	"Enable 'q' Button" = true
-	#A list of screens that don't play well with quark's buttons. Use "Print Screen Classnames" to find the names of any others you'd want to add.
-	"Ignored Screens" = ["blusunrize.immersiveengineering.client.gui.CraftingTableScreen", "com.tfar.craftingstation.client.CraftingStationScreen", "com.refinedmods.refinedstorage.screen.grid.GridScreen", "appeng.client.gui.implementations.CraftingTermScreen", "appeng.client.gui.implementations.PatternTermScreen", "com.blakebr0.extendedcrafting.client.screen.EliteTableScreen", "com.blakebr0.extendedcrafting.client.screen.EliteAutoTableScreen", "com.blakebr0.extendedcrafting.client.screen.UltimateTableScreen", "com.blakebr0.extendedcrafting.client.screen.UltimateAutoTableScreen", "me.desht.modularrouters.client.gui.filter.GuiFilterScreen", "com.resourcefulbees.resourcefulbees.client.gui.screen.CentrifugeScreen", "com.resourcefulbees.resourcefulbees.client.gui.screen.MechanicalCentrifugeScreen", "com.resourcefulbees.resourcefulbees.client.gui.screen.CentrifugeMultiblockScreen"]
-	"Use Anti Overlap" = true
-	#Enables quark network profiling features. Do not enable this unless requested to.
-	"Enable Network Profiling" = false
-	#Quark replaces the Piston logic to allow for its piston features to work. If you're having troubles, try turning this off.
-	"Use Piston Logic Replacement" = true
-	#Set to true if you need to find the class name for a screen that's causing problems
-	"Print Screen Classnames" = false
-	#Blocks that Quark should treat as Shulker Boxes.
-	"Shulker Boxes" = ["minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box", "minecraft:light_gray_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box", "minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box"]
-	#Set to true to enable a system that debugs quark's worldgen features. This should ONLY be used if you're asked to by a dev.
-	"Enable Worldgen Watchdog" = false
-	#Should Quark treat anything with 'shulker_box' in its item identifier as a shulker box?
-	"Interpret Shulker Box Like Blocks" = true
-
-[categories]
-	Building = true
-	Automation = true
-	Oddities = true
-	Tweaks = true
-	Experimental = true
-	Mobs = true
-	Tools = true
-	Management = true
-	World = true
-	Client = true
-
-[automation]
-	Chute = true
-	"Iron Rod" = true
-	"Weather Sensor" = true
-	"Ender Watcher" = true
-	"Endermites Form Shulkers" = true
-	"Jukebox Automation" = true
-	"Chains Connect Blocks" = true
-	"Color Slime" = true
-	"Dispensers Place Blocks" = true
-	"Redstone Circuit" = true
-	"Chain Linkage" = true
-	Gravisand = true
-	"Metal Buttons" = true
-	"Obsidian Plate" = true
-	"Pistons Move Tile Entities" = true
-	"Feeding Trough" = true
-
-	[automation.dispensers_place_blocks]
-		Blacklist = ["minecraft:water", "minecraft:lava", "minecraft:fire"]
-
-	[automation.chain_linkage]
-		#Can vehicle-linking chains be used for crafting chain armor?
-		"Crafts Armor" = true
-
-	[automation.redstone_circuit]
-		"Enable Inductor" = true
-		"Enable Randomizer" = true
-
-	[automation.metal_buttons]
-		"Enable Iron" = true
-		"Enable Gold" = true
-
-	[automation.endermites_form_shulkers]
-		Chance = 0.005
-
-	[automation.pistons_move_tile_entities]
-		"Enable Chests Moving Together" = true
-		"Render Blacklist" = ["psi:programmer", "botania:starfield"]
-		"Movement Blacklist" = ["minecraft:spawner", "integrateddynamics:cable", "randomthings:blockbreaker", "minecraft:ender_chest", "minecraft:enchanting_table", "minecraft:trapped_chest", "quark:spruce_trapped_chest", "quark:birch_trapped_chest", "quark:jungle_trapped_chest", "quark:acacia_trapped_chest", "quark:dark_oak_trapped_chest", "endergetic:bolloom_bud"]
-		"Delayed Update List" = ["minecraft:dispenser", "minecraft:dropper"]
-
-	[automation.color_slime]
-		"Change Name" = true
-
-	[automation.feeding_trough]
-		#The chance (between 0 and 1) for an animal to enter love mode when eating from the trough
-		#Allowed values: (0,1]
-		"Love Chance" = 0.333333333
-		#How long, in game ticks, between animals being able to eat from the trough
-		#Allowed values: [1,)
-		Cooldown = 30
-		#The maximum amount of animals allowed around the trough's range for an animal to enter love mode
-		"Max Animals" = 32
-		Range = 10.0
-
-[building]
-	"Cobblestone Bricks" = true
-	"Burn Vines" = true
-	"Quilted Wool" = true
-	"Celebratory Lamps" = true
-	"Variant Chests" = true
-	Hedges = true
-	"Vertical Slabs" = true
-	"Nether Brick Fence Gate" = true
-	"Lit Lamp" = true
-	"Vertical Planks" = true
-	"Tie Leads To Fences" = true
-	"Shallow Dirt" = true
-	"More Stone Variants" = true
-	Turf = true
-	"Paper Decor" = true
-	Rope = true
-	"Iron Plates" = true
-	"Sturdy Stone" = true
-	"More Potted Plants" = true
-	Grate = true
-	"Variant Bookshelves" = true
-	"Duskbound Blocks" = true
-	"Bamboo Mat" = true
-	"More Brick Types" = true
-	"Gold Bars" = true
-	"Soul Sandstone" = true
-	"Compressed Blocks" = true
-	Stools = true
-	Thatch = true
-	"Variant Ladders" = true
-	Shingles = true
-	"Item Frames" = true
-	"Stained Planks" = true
-	"Wooden Posts" = true
-	"Leaf Carpet" = true
-	Midori = true
-	"Framed Glass" = true
-	"Tallow And Candles" = true
-
-	[building.thatch]
-		#Allowed values: [0,1]
-		"Fall Damage Multiplier" = 0.5
-
-	[building.item_frames]
-		"Glass Item Frames Update Maps" = true
-
-	[building.cobblestone_bricks]
-		"Enable Basalt Bricks" = true
-		"Enable Netherrack Bricks" = true
-		"Enable Dirt Bricks" = true
-		"Enable Blackstone Bricks" = true
-
-	[building.rope]
-		"Enable Dispenser Behavior" = true
-		#Set to true to allow ropes to move Tile Entities even if Pistons Push TEs is disabled.
-		#Note that ropes will still use the same blacklist.
-		"Force Enable Move Tile Entities" = false
-
-	[building.more_stone_variants]
-		"Enable Bricks" = true
-		"Enable Pillar" = true
-		"Enable Chiseled Bricks" = true
-		"Enable Pavement" = true
-
-	[building.variant_ladders]
-		"Change Names" = true
-		"Enable Iron Ladder" = true
-
-	[building.compressed_blocks]
-		"Enable Cocoa Bean Sack" = true
-		"Enable Cactus Block" = true
-		"Enable Apple Crate" = true
-		"Charcoal Block and Blaze Lantern Stay On Fire Forever" = true
-		"Enable Bonded Rabbit Hide" = true
-		"Enable Charcoal Block" = true
-		"Enable Gunpowder Sack" = true
-		"Enable Potato Crate" = true
-		"Enable Stick Block" = true
-		"Enable Carrot Crate" = true
-		"Enable Beetroot Crate" = true
-		"Enable Nether Wart Sack" = true
-		"Enable Chorus Fruit Block" = true
-		"Enable Blaze Lantern" = true
-		"Enable Bamboo Block" = true
-		"Enable Berry Sack" = true
-		#Allowed values: [0,)
-		"Bamboo Bundle Fuel Time" = 500
-		"Enable Golden Apple Crate" = true
-		"Enable Sugar Cane Block" = true
-		"Enable Bonded Leather" = true
-		#Allowed values: [0,)
-		"Blaze Lantern Fuel Time" = 24000
-		#Allowed values: [0,)
-		"Charcoal Block Fuel Time" = 16000
-		#Allowed values: [0,)
-		"Stick Block Fuel Time" = 900
-
-	[building.variant_chests]
-		"Enable Reverting Wooden Chests" = true
-		"Replace Worldgen Chests" = true
-		#Chests to put in each structure. The format per entry is "structure=chest", where "structure" is a structure ID, and "chest" is a block ID, which must correspond to a standard chest block.
-		"Structure Chests" = ["minecraft:village_plains=quark:oak_chest", "minecraft:igloo=quark:spruce_chest", "minecraft:village_snowy=quark:spruce_chest", "minecraft:village_taiga=quark:spruce_chest", "minecraft:desert_pyramid=quark:birch_chest", "minecraft:jungle_pyramid=quark:jungle_chest", "minecraft:village_desert=quark:jungle_chest", "minecraft:village_savanna=quark:acacia_chest", "minecraft:mansion=quark:dark_oak_chest", "minecraft:pillager_outpost=quark:dark_oak_chest", "minecraft:ruined_portal=quark:crimson_chest", "minecraft:bastion_remnant=quark:crimson_chest", "minecraft:fortress=quark:nether_brick_chest", "minecraft:endcity=quark:purpur_chest", "bettermineshafts:mineshaft=quark:oak_chest", "cobbler:shulker_factory=quark:purpur_chest", "conjurer_illager:theatre=quark:dark_oak_chest", "dungeoncrawl:dungeon=quark:oak_chest", "dungeons_plus:bigger_dungeon=quark:oak_chest", "dungeons_plus:end_ruins=quark:purpur_chest", "dungeons_plus:leviathan=quark:jungle_chest", "dungeons_plus:snowy_temple=quark:spruce_chest", "dungeons_plus:soul_prison=quark:warped_chest", "dungeons_plus:tower=quark:oak_chest", "dungeons_plus:warped_garden=quark:warped__chest", "hunterillager:hunterhouse=quark:oak_chest", "iceandfire:gorgon_temple=quark:jungle_chest", "pandoras_creatures:end_prison=quark:purpur_chest", "repurposed_structures:fortress_jungle=quark:jungle_chest", "repurposed_structures:igloo_grassy=quark:oak_chest", "repurposed_structures:igloo_stone=quark:spruce_chest", "repurposed_structures:mineshaft_birch=quark:birch_chest", "repurposed_structures:mineshaft_desert=quark:jungle_chest", "repurposed_structures:mineshaft_end=quark:purpur_chest", "repurposed_structures:mineshaft_icy=quark:spruce_chest", "repurposed_structures:mineshaft_jungle=quark:jungle_chest", "repurposed_structures:mineshaft_nether=quark:nether_brick_chest", "repurposed_structures:mineshaft_ocean=quark:prismarine_chest", "repurposed_structures:mineshaft_savanna=quark:acacia_chest", "repurposed_structures:mineshaft_stone=quark:spruce_chest", "repurposed_structures:mineshaft_swamp_or_dark_forest=quark:dark_oak_chest", "repurposed_structures:mineshaft_taiga=quark:spruce_chest", "repurposed_structures:outpost_badlands=quark:dark_oak_chest", "repurposed_structures:outpost_birch=quark:birch_chest", "repurposed_structures:outpost_crimson=quark:crimson_chest", "repurposed_structures:outpost_desert=quark:jungle_chest", "repurposed_structures:outpost_giant_tree_taiga=quark:spruce_chest", "repurposed_structures:outpost_icy=quark:spruce_chest", "repurposed_structures:outpost_jungle=quark:jungle_chest", "repurposed_structures:outpost_nether_brick=quark:nether_brick_chest", "repurposed_structures:outpost_snowy=quark:spruce_chest", "repurposed_structures:outpost_warped=quark:warped_chest", "repurposed_structures:pyramid_badlands=quark:dark_oak_chest", "repurposed_structures:pyramid_nether=quark:nether_brick_chest", "repurposed_structures:ruined_portal_end=quark:purpur_chest", "repurposed_structures:shipwreck_crimson=quark:crimson_chest", "repurposed_structures:shipwreck_end=quark:purpur_chest", "repurposed_structures:shipwreck_nether_bricks=quark:nether_brick_chest", "repurposed_structures:shipwreck_warped=quark:warped_chest", "repurposed_structures:stronghold_nether=quark:nether_brick_chest", "repurposed_structures:stronghold_stonebrick=quark:oak_chest", "repurposed_structures:temple_nether_basalt=quark:nether_brick_chest", "repurposed_structures:temple_nether_crimson=quark:crimson_chest", "repurposed_structures:temple_nether_soul=quark:warped_chest", "repurposed_structures:temple_nether_warped=quark:warped_chest", "repurposed_structures:temple_nether_wasteland=quark:nether_brick_chest", "repurposed_structures:village_badlands=quark:dark_oak_chest", "repurposed_structures:village_birch=quark:birch_chest", "repurposed_structures:village_crimson=quark:crimson_chest", "repurposed_structures:village_dark_oak=quark:dark_oak_chest", "repurposed_structures:village_giant_taiga=quark:spruce_chest", "repurposed_structures:village_jungle=quark:jungle_chest", "repurposed_structures:village_mountains=quark:spruce_chest", "repurposed_structures:village_oak=quark:oak_chest", "repurposed_structures:village_swamp=quark:oak_chest", "repurposed_structures:village_warped=quark:warped_chest", "valhelsia_structures:castle=quark:spruce_chest", "valhelsia_structures:castle_ruin=quark:oak_chest", "valhelsia_structures:desert_house=quark:spruce_chest", "valhelsia_structures:forge=quark:spruce_chest", "valhelsia_structures:player_house=quark:oak_chest", "valhelsia_structures:small_castle=quark:oak_chest", "valhelsia_structures:small_dungeon=quark:oak_chest", "valhelsia_structures:tower_ruin=quark:spruce_chest"]
-
-	[building.more_brick_types]
-		"Enable Magma Bricks" = true
-		"Enable Sandy Bricks" = true
-		#This also comes with a utility recipe for Red Nether Bricks
-		"Enable Blue Nether Bricks" = true
-		"Enable Blackstone Variant Bricks" = true
-		"Enable Charred Nether Bricks" = true
-		"Enable Snow Bricks" = true
-		#This also includes Red Sandstone Bricks and Soul Sandstone Bricks
-		"Enable Sandstone Bricks" = true
-
-	[building.tallow_and_candles]
-		"Candles Fall" = true
-		#Allowed values: [0,)
-		"Tallow Burn Time" = 200
-		#Allowed values: [0,)
-		"Max Drop" = 3
-		#Allowed values: [0,15]
-		"Enchant Power" = 1.0
-		#Allowed values: [0,)
-		"Min Drop" = 1
-
-	[building.celebratory_lamps]
-		"Light Level" = 15
-
-	[building.variant_bookshelves]
-		"Change Names" = true
-
-[management]
-	"Chests In Boats" = true
-	"Inventory Sorting" = true
-	"Shulker Box Right Click" = true
-	"Hotbar Changer" = true
-	"Item Sharing" = true
-	"Right Click Armor" = true
-	"Easy Transfering" = true
-
-	[management.inventory_sorting]
-		#Play a click when sorting inventories using keybindings
-		"Satisfying Click" = true
-		"Enable Chests" = true
-		"Enable Player Inventory In Chests" = true
-		"Enable Player Inventory" = true
-
-	[management.easy_transfering]
-		"Enable Shift Lock" = true
-
-	[management.item_sharing]
-		"Render Items In Chat" = true
-
-[tools]
-	Pickarang = true
-	"Ambient Discs" = true
-	"Seed Pouch" = true
-	"Pathfinder Maps" = true
-	"Bottled Cloud" = true
-	"Color Runes" = true
-	"Ancient Tomes" = true
-	"Slime In A Bucket" = true
-	Camera = true
-	Trowel = true
-	Abacus = true
-
-	[tools.ambient_discs]
-		"Drop On Spider Kill" = true
-
-	[tools.trowel]
-		#Amount of blocks placed is this value + 1.
-		#Set to 0 to make the Trowel unbreakable
-		#Allowed values: [0,)
-		"Trowel Max Durability" = 255
-
-	[tools.bottled_cloud]
-		"Cloud Level Top" = 132
-		"Cloud Level Bottom" = 127
-
-	[tools.ancient_tomes]
-		"Normal Upgrade Cost" = 10
-		"Valid Enchantments" = ["minecraft:feather_falling", "minecraft:thorns", "minecraft:sharpness", "minecraft:smite", "minecraft:bane_of_arthropods", "minecraft:knockback", "minecraft:fire_aspect", "minecraft:looting", "minecraft:sweeping", "minecraft:efficiency", "minecraft:unbreaking", "minecraft:fortune", "minecraft:power", "minecraft:punch", "minecraft:luck_of_the_sea", "minecraft:lure", "minecraft:loyalty", "minecraft:riptide", "minecraft:impaling", "minecraft:piercing"]
-		"Item Quality" = 2
-		#Set to 0 to not generate in Underwater Ruins
-		"Underwater Ruin Weight" = 0
-		#Set to 0 to not generate in Woodland Mansions
-		"Woodland Mansion Weight" = 15
-		#Set to 0 to not generate in Dungeons
-		"Dungeon Weight" = 20
-		"Limit Break Upgrade Cost" = 30
-		#Set to 0 to not generate in Stronghold Libraries
-		"Library Weight" = 30
-		#Set to 0 to not generate in Nether Fortresses
-		"Nether Fortress Weight" = 0
-		#Set to 0 to not generate in Bastions
-		"Bastion Weight" = 25
-		#Set to 0 to not generate in Monster Boxes
-		"Monster Box Weight" = 5
-
-	[tools.pathfinder_maps]
-		#In this section you can add custom Pathfinder Maps. This works for both vanilla and modded biomes.
-		#Each custom map must be on its own line.
-		#The format for a custom map is as follows:
-		#<id>,<level>,<min_price>,<max_price>,<color>,<name>
-		#
-		#With the following descriptions:
-		# - <id> being the biome's ID NAME. You can find vanilla names here - https://minecraft.gamepedia.com/Biome#Biome_IDs
-		# - <level> being the Cartographer villager level required for the map to be unlockable
-		# - <min_price> being the cheapest (in Emeralds) the map can be
-		# - <max_price> being the most expensive (in Emeralds) the map can be
-		# - <color> being a hex color (without the #) for the map to display. You can generate one here - http://htmlcolorcodes.com/
-		# - <name> being the display name of the map
-		#
-		#Here's an example of a map to locate Ice Mountains:
-		#minecraft:ice_mountains,2,8,14,7FE4FF,Ice Mountains Pathfinder Map
-		Customs = []
-		"Search Radius" = 6400
-		"Search Distance Increment" = 8
-		"Xp From Trade" = 5
-
-	[tools.seed_pouch]
-		"Show All Variants In Creative" = true
-		"Shift Range" = 3
-		"Max Items" = 640
-
-	[tools.color_runes]
-		"Jungle Temple Weight" = 8
-		"Desert Temple Weight" = 8
-		"Dungeon Weight" = 10
-		"Item Quality" = 0
-		"Apply Cost" = 15
-		"Nether Fortress Weight" = 8
-
-	[tools.pickarang]
-		#22.5 is ender chests, 25.0 is monster boxes, 50 is obsidian. Most things are below 5.
-		"Max Hardness" = 20.0
-		#2 is Iron, 3 is Diamond.
-		"Harvest Level" = 3
-		#2 is Iron, 3 is Diamond.
-		"Netherite Harvest Level" = 3
-		#How long it takes before the pickarang starts returning to the player if it doesn't hit anything.
-		Timeout = 20
-		#Set to -1 to have the Pickarang be unbreakable.
-		Durability = 800
-		#Set this to true to disable the short cooldown between throwing pickarangs.
-		"No Cooldown" = false
-		#Set to -1 to have the Flamerang be unbreakable.
-		"Netherite Durability" = 1040
-		#Set this to true to use the recipe without the Heart of Diamond, even if the Heart of Diamond is enabled.
-		"Never Use Heart Of Diamond" = false
-
-[tweaks]
-	"Armed Armor Stands" = true
-	"Lock Rotation" = true
-	"Dragon Scales" = true
-	"Replace Scaffolding" = true
-	"Axe Leaf Harvesting" = true
-	"Sign Editing" = true
-	"Dirt To Path" = true
-	"Simple Harvest" = true
-	"Hoe Harvesting" = true
-	"Reacharound Placing" = true
-	"Villagers Follow Emeralds" = true
-	"Compasses Work Everywhere" = true
-	"Skull Pikes" = true
-	"Note Block Mob Sounds" = true
-	"Double Door Opening" = true
-	"Automatic Recipe Unlock" = true
-	"Poison Potato Usage" = true
-	"Lava Bucket As Trash" = true
-	"Improved Sleeping" = true
-	"Infinity Bucket" = true
-	"Springy Slime" = true
-	Emotes = true
-	"Utility Recipes" = true
-	"Pat The Dogs" = true
-	"Enhanced Ladders" = true
-	"Snow Golem Player Heads" = true
-	"Glass Shard" = true
-	"Campfires Boost Elytra" = true
-	"More Banner Layers" = true
-	"Better Elytra Rocket" = true
-
-	[tweaks.sign_editing]
-		"Requires Empty Hand" = false
-
-	[tweaks.pat_the_dogs]
-		#How many ticks it takes for a dog to want affection after being pet/tamed; leave -1 to disable
-		"Dogs Want Love" = -1
-
-	[tweaks.automatic_recipe_unlock]
-		#A list of recipe names that should NOT be added in by default
-		"Ignored Recipes" = []
-		"Disable Recipe Book" = false
-		"Force Limited Crafting" = false
-
-	[tweaks.hoe_harvesting]
-		"Hoes Can Have Fortune" = true
-
-	[tweaks.skull_pikes]
-		"Pike Range" = 5.0
-
-	[tweaks.infinity_bucket]
-		#Set this to false to prevent dispensers from using infinite water buckets
-		"Allow Dispensers To Use" = true
-		Cost = 10
-
-	[tweaks.poison_potato_usage]
-		"Poison Effect" = true
-		Chance = 0.1
-
-	[tweaks.utility_recipes]
-		#Can you craft four chests at once using logs?
-		"Logs To Chests" = true
-		#Can other stone-like materials be used for crafting stone tools?
-		"Better Stone Tool Crafting" = true
-		#Can a dispenser be crafted by adding a bow to a dropper?
-		"Enable Dispenser" = true
-		#Can cookies, paper, and bread be crafted in a 2x2 crafting table?
-		"Bent Recipes" = true
-		#Can Rotten Flesh and Poisonous Potatoes be composted?
-		"Compostable Toxins" = true
-		#Can bones be smelted down to bone meal?
-		"Bone Meal Utility" = true
-		#Can any wool color be dyed?
-		"Dye Any Wool" = true
-		#Can Coral be crafted into dye?
-		"Coral To Dye" = true
-		#Can torches can be used as fuel in furnaces?
-		"Torches Burn" = true
-		#Can a repeater be crafted with the pattern for a redstone torch?
-		"Enable Repeater" = true
-		#Can you craft a minecart around blocks which can be placed inside?
-		"Enable Minecarts" = true
-		#Does Dragon Breath return a bottle when used as a reagent or material?
-		"Effective Dragon Breath" = true
-
-	[tweaks.reacharound_placing]
-		#Allowed values: [0,1]
-		Leniency = 0.5
-		Whitelist = []
-		"Display Horizontal" = "<  >"
-		Display = "[  ]"
-
-	[tweaks.improved_sleeping]
-		"Enable Afk" = true
-		#Allowed values: (0,)
-		"Afk Time" = 2400
-		#Allowed values: (0,1]
-		"Percent Req" = 0.5
-
-	[tweaks.emotes]
-		#The enabled default emotes. Remove from this list to disable them. You can also re-order them, if you feel like it.
-		"Enabled Emotes" = ["no", "yes", "wave", "salute", "cheer", "clap", "think", "point", "shrug", "headbang", "weep", "facepalm"]
-		#Enable this to make custom emotes read the file every time they're triggered so you can edit on the fly.
-		#DO NOT ship enabled this in a modpack, please.
-		"Custom Emote Debug" = false
-		#The list of Custom Emotes to be loaded.
-		#Watch the tutorial on Custom Emotes to learn how to make your own: https://youtu.be/ourHUkan6aQ
-		"Custom Emotes" = []
-
-	[tweaks.simple_harvest]
-		#Can players harvest crops with empty hand clicks?
-		"Empty Hand Harvest" = true
-		#Does harvesting crops with a hoe cost durability?
-		"Harvesting Costs Durability" = false
-		#Should Quark look for (nonvanilla) crops, and handle them?
-		"Do Harvesting Search" = true
-		#Which crops can be harvested?
-		#Format is: "harvestState[,afterHarvest]", i.e. "minecraft:wheat[age=7]" or "minecraft:cocoa[age=2,facing=north],minecraft:cocoa[age=0,facing=north]"
-		"Harvestable Blocks" = ["minecraft:wheat[age=7]", "minecraft:carrots[age=7]", "minecraft:potatoes[age=7]", "minecraft:beetroots[age=3]", "minecraft:nether_wart[age=3]", "minecraft:cocoa[age=2,facing=north],minecraft:cocoa[age=0,facing=north]", "minecraft:cocoa[age=2,facing=south],minecraft:cocoa[age=0,facing=south]", "minecraft:cocoa[age=2,facing=east],minecraft:cocoa[age=0,facing=east]", "minecraft:cocoa[age=2,facing=west],minecraft:cocoa[age=0,facing=west]"]
-
-	[tweaks.enhanced_ladders]
-		#Allowed values: (,0]
-		"Fall Speed" = -0.2
-
-	[tweaks.compasses_work_everywhere]
-		"Enable Nether" = true
-		"Enable Compass Nerf" = true
-		"Enable End" = true
-		"Enable Clock Nerf" = true
-
-	[tweaks.campfires_boost_elytra]
-		"Boost Strength" = 0.5
-		"Max Speed" = 1.0
-
-	[tweaks.replace_scaffolding]
-		#How many times the algorithm for finding out where a block would be placed is allowed to turn. If you set this to large values (> 3) it may start producing weird effects.
-		"Max Bounces" = 1
-
-	[tweaks.more_banner_layers]
-		#Allowed values: [1,16]
-		"Layer Limit" = 16
-
-[world]
-	"New Stone Types" = true
-	"Lush Underground Biome" = true
-	"Big Dungeon" = true
-	Speleothems = true
-	"Elder Prismarine Underground Biome" = true
-	"Blossom Trees" = true
-	"Sandstone Underground Biome" = true
-	"Glowshroom Underground Biome" = true
-	"Permafrost Underground Biome" = true
-	"Underground Clay" = true
-	"Slime Underground Biome" = true
-	"Fairy Rings" = true
-	"Chorus Vegetation" = true
-	Crevices = true
-	"Nether Obsidian Spikes" = true
-	"Mega Caves" = true
-	"Realistic World Gen" = true
-	Biotite = true
-	"Big Stone Clusters" = true
-	"Brimstone Underground Biome" = true
-	"Cave Crystal Underground Biome" = true
-	"Spiral Spires" = true
-	"Overgrown Underground Biome" = true
-	"Cave Roots" = true
-	"Spider Nest Underground Biome" = true
-	Deepslate = true
-	"Monster Box" = true
-
-	[world.monster_box]
-		#The chance for the monster box generator to try and place one in a chunk, 1 is 100%
-		#This can be higher than 100% if you want multiple per chunk, , 0 is 0%
-		"Chance Per Chunk" = 0.8
-		"Min Mob Count" = 5
-		"Min Y" = 5
-		"Max Y" = 30
-		"Max Mob Count" = 8
-		"Enable Extra Loot Table" = true
-		#How many blocks to search vertically from a position before trying to place a block. Higher means you'll get more boxes in open spaces.
-		"Search Range" = 6
-
-		[world.monster_box.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-	[world.cave_crystal_underground_biome]
-		#The chance that a crystal can grow, this is on average 1 in X world ticks, set to a higher value to make them grow slower. Minimum is 1, for every tick. Set to 0 to disable growth.
-		"Cave Crystal Growth Chance" = 5
-		#Allowed values: [0,1]
-		"Crystal Chance" = 0.16
-		#Allowed values: [0,1]
-		"Crystal Cluster On Sides Chance" = 0.6
-		#Allowed values: [0,1]
-		"Crystal Cluster Chance" = 0.2
-		#Allowed values: [0,1]
-		"Double Crystal Chance" = 0.2
-		"Enable Collateral Movement" = true
-		"Enable Beacon Redirection" = true
-		"Crystals Craft Runes" = true
-
-		[world.cave_crystal_underground_biome.biome_settings]
-			#Allowed values: [0,)
-			"Horizontal Size" = 42
-			#Allowed values: [0,)
-			Rarity = 400
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#Allowed values: [0,)
-			"Horizontal Variation" = 22
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#Allowed values: [0,)
-			"Vertical Size" = 18
-			#Allowed values: [0,)
-			"Vertical Variation" = 8
-
-			[world.cave_crystal_underground_biome.biome_settings.biomes]
-				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-				# jungle, spooky, dead, lush, mushroom, magical, rare,
-				# plateau, modified, ocean, river, water, mesa, forest,
-				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-				# beach, void, overworld, nether, end]
-				"Biome Types" = ["ocean"]
-				"Is Blacklist" = true
-
-			[world.cave_crystal_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.speleothems]
-		"Tries Per Chunk In Nether" = 4
-		"Speleothems Per Chunk In Nether" = 12
-		"Small Speleothems Increase Fall Damage" = true
-		"Speleothems Per Chunk" = 12
-		"Max Ylevel" = 55
-		"Tries Per Chunk" = 60
-
-		[world.speleothems.dimensions]
-			Dimensions = []
-			"Is Blacklist" = true
-
-	[world.sandstone_underground_biome]
-
-		[world.sandstone_underground_biome.biome_settings]
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#Allowed values: [0,)
-			Rarity = 80
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.sandstone_underground_biome.biome_settings.biomes]
-				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-				# jungle, spooky, dead, lush, mushroom, magical, rare,
-				# plateau, modified, ocean, river, water, mesa, forest,
-				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-				# beach, void, overworld, nether, end]
-				"Biome Types" = ["sandy"]
-				"Is Blacklist" = false
-
-			[world.sandstone_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.spiral_spires]
-		Radius = 15
-		Rarity = 200
-		#Set to 0 to turn off Myalite Conduits
-		"Myalite Conduit Distance" = 24
-		"Renewable Myalite" = true
-
-		[world.spiral_spires.biomes]
-
-			[world.spiral_spires.biomes.types]
-				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-				# jungle, spooky, dead, lush, mushroom, magical, rare,
-				# plateau, modified, ocean, river, water, mesa, forest,
-				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-				# beach, void, overworld, nether, end]
-				"Biome Types" = []
-				"Is Blacklist" = true
-
-			[world.spiral_spires.biomes.biomes]
-				Biomes = ["minecraft:end_highlands"]
-				"Is Blacklist" = false
-
-		[world.spiral_spires.dimensions]
-			Dimensions = ["minecraft:the_end"]
-			"Is Blacklist" = false
-
-	[world.nether_obsidian_spikes]
-		#The chance for a chunk to contain spikes (1 is 100%, 0 is 0%)
-		"Chance Per Chunk" = 0.1
-		"Big Spike Spawners" = true
-		#Should a chunk have spikes, how many would the generator try to place
-		"Tries Per Chunk" = 4
-		#The chance for a spike to be big (1 is 100%, 0 is 0%)
-		"Big Spike Chance" = 0.03
-
-		[world.nether_obsidian_spikes.dimensions]
-			Dimensions = ["minecraft:the_nether"]
-			"Is Blacklist" = false
-
-	[world.biotite]
-		"Clusters Per Dragon Tick" = 16
-		"Generate On Dragon Death" = true
-		"Dragon Ticks Per Cluster" = 1
-		"Generate Naturally" = false
-
-		[world.biotite.dimensions]
-			Dimensions = ["minecraft:the_end"]
-			"Is Blacklist" = false
-
-		[world.biotite.ore_settings]
-			#Allowed values: [0,255]
-			"Max Height" = 64
-			#Allowed values: [0,)
-			"Cluster Count" = 16
-			#Allowed values: [0,255]
-			"Min Height" = 1
-			#Allowed values: [0,)
-			"Cluster Size" = 14
-
-	[world.crevices]
-
-		[world.crevices.spawn_settings]
-			#Allowed values: [0,)
-			"Horizontal Size" = 60
-			#Allowed values: [0,)
-			Rarity = 120
-			#Allowed values: [0,255]
-			"Min Y Level" = 15
-			#Allowed values: [0,)
-			"Horizontal Variation" = 20
-			#Allowed values: [0,255]
-			"Max Y Level" = 50
-			#Allowed values: [0,)
-			"Vertical Size" = 4
-			#Allowed values: [0,)
-			"Vertical Variation" = 1
-
-			[world.crevices.spawn_settings.biomes]
-				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-				# jungle, spooky, dead, lush, mushroom, magical, rare,
-				# plateau, modified, ocean, river, water, mesa, forest,
-				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-				# beach, void, overworld, nether, end]
-				"Biome Types" = ["ocean", "beach"]
-				"Is Blacklist" = true
-
-			[world.crevices.spawn_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.crevices.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-	[world.cave_roots]
-		"Min Y" = 16
-		"Chunk Attempts" = 300
-		"Max Y" = 52
-		"Enable Brewing" = true
-
-		[world.cave_roots.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-	[world.new_stone_types]
-		"Enable Marble" = true
-		"Enable Myalite" = true
-		"Enable Jasper" = true
-		"Enable Voidstone" = true
-		"Enable Slate" = true
-		"Enable Limestone" = true
-
-		[world.new_stone_types.marble]
-
-			[world.new_stone_types.marble.oregen]
-				#Allowed values: [0,255]
-				"Max Height" = 255
-				#Allowed values: [0,)
-				"Cluster Count" = 10
-				#Allowed values: [0,255]
-				"Min Height" = 0
-				#Allowed values: [0,)
-				"Cluster Size" = 33
-
-			[world.new_stone_types.marble.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.new_stone_types.limestone]
-
-			[world.new_stone_types.limestone.oregen]
-				#Allowed values: [0,255]
-				"Max Height" = 255
-				#Allowed values: [0,)
-				"Cluster Count" = 10
-				#Allowed values: [0,255]
-				"Min Height" = 0
-				#Allowed values: [0,)
-				"Cluster Size" = 33
-
-			[world.new_stone_types.limestone.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.new_stone_types.myalite]
-
-			[world.new_stone_types.myalite.oregen]
-				#Allowed values: [0,255]
-				"Max Height" = 255
-				#Allowed values: [0,)
-				"Cluster Count" = 10
-				#Allowed values: [0,255]
-				"Min Height" = 0
-				#Allowed values: [0,)
-				"Cluster Size" = 33
-
-			[world.new_stone_types.myalite.dimensions]
-				Dimensions = ["minecraft:the_end"]
-				"Is Blacklist" = false
-
-		[world.new_stone_types.voidstone]
-
-			[world.new_stone_types.voidstone.oregen]
-				#Allowed values: [0,255]
-				"Max Height" = 255
-				#Allowed values: [0,)
-				"Cluster Count" = 10
-				#Allowed values: [0,255]
-				"Min Height" = 0
-				#Allowed values: [0,)
-				"Cluster Size" = 33
-
-			[world.new_stone_types.voidstone.dimensions]
-				Dimensions = ["minecraft:the_end"]
-				"Is Blacklist" = false
-
-		[world.new_stone_types.slate]
-
-			[world.new_stone_types.slate.oregen]
-				#Allowed values: [0,255]
-				"Max Height" = 255
-				#Allowed values: [0,)
-				"Cluster Count" = 10
-				#Allowed values: [0,255]
-				"Min Height" = 0
-				#Allowed values: [0,)
-				"Cluster Size" = 33
-
-			[world.new_stone_types.slate.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.new_stone_types.jasper]
-
-			[world.new_stone_types.jasper.oregen]
-				#Allowed values: [0,255]
-				"Max Height" = 255
-				#Allowed values: [0,)
-				"Cluster Count" = 10
-				#Allowed values: [0,255]
-				"Min Height" = 0
-				#Allowed values: [0,)
-				"Cluster Size" = 33
-
-			[world.new_stone_types.jasper.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.spider_nest_underground_biome]
-		"Enabled Wrapped" = true
-
-		[world.spider_nest_underground_biome.biome_settings]
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#Allowed values: [0,)
-			Rarity = 80
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.spider_nest_underground_biome.biome_settings.biomes]
-				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-				# jungle, spooky, dead, lush, mushroom, magical, rare,
-				# plateau, modified, ocean, river, water, mesa, forest,
-				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-				# beach, void, overworld, nether, end]
-				"Biome Types" = ["plains"]
-				"Is Blacklist" = false
-
-			[world.spider_nest_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.deepslate]
-		"Sheet Height Variance" = 6
-		"Sheet Y Start" = 0
-		"Sheet Height" = 18
-
-		[world.deepslate.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-	[world.blossom_trees]
-
-		[world.blossom_trees.orange]
-			Rarity = 100
-
-			[world.blossom_trees.orange.biome_config]
-
-				[world.blossom_trees.orange.biome_config.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["savanna"]
-					"Is Blacklist" = false
-
-				[world.blossom_trees.orange.biome_config.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-			[world.blossom_trees.orange.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.blossom_trees.red]
-			Rarity = 30
-
-			[world.blossom_trees.red.biome_config]
-
-				[world.blossom_trees.red.biome_config.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["mesa"]
-					"Is Blacklist" = false
-
-				[world.blossom_trees.red.biome_config.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-			[world.blossom_trees.red.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.blossom_trees.pink]
-			Rarity = 100
-
-			[world.blossom_trees.pink.biome_config]
-
-				[world.blossom_trees.pink.biome_config.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["mountain"]
-					"Is Blacklist" = false
-
-				[world.blossom_trees.pink.biome_config.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-			[world.blossom_trees.pink.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.blossom_trees.blue]
-			Rarity = 200
-
-			[world.blossom_trees.blue.biome_config]
-
-				[world.blossom_trees.blue.biome_config.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["snowy"]
-					"Is Blacklist" = false
-
-				[world.blossom_trees.blue.biome_config.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-			[world.blossom_trees.blue.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.blossom_trees.yellow]
-			Rarity = 200
-
-			[world.blossom_trees.yellow.biome_config]
-
-				[world.blossom_trees.yellow.biome_config.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["plains"]
-					"Is Blacklist" = false
-
-				[world.blossom_trees.yellow.biome_config.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-			[world.blossom_trees.yellow.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.blossom_trees.lavender]
-			Rarity = 100
-
-			[world.blossom_trees.lavender.biome_config]
-
-				[world.blossom_trees.lavender.biome_config.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["swamp"]
-					"Is Blacklist" = false
-
-				[world.blossom_trees.lavender.biome_config.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-			[world.blossom_trees.lavender.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.mega_caves]
-
-		[world.mega_caves.spawn_settings]
-			#Allowed values: [0,)
-			"Horizontal Size" = 80
-			#Allowed values: [0,)
-			Rarity = 800
-			#Allowed values: [0,255]
-			"Min Y Level" = 10
-			#Allowed values: [0,)
-			"Horizontal Variation" = 30
-			#Allowed values: [0,255]
-			"Max Y Level" = 20
-			#Allowed values: [0,)
-			"Vertical Size" = 25
-			#Allowed values: [0,)
-			"Vertical Variation" = 10
-
-			[world.mega_caves.spawn_settings.biomes]
-				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-				# jungle, spooky, dead, lush, mushroom, magical, rare,
-				# plateau, modified, ocean, river, water, mesa, forest,
-				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-				# beach, void, overworld, nether, end]
-				"Biome Types" = ["ocean", "beach"]
-				"Is Blacklist" = true
-
-			[world.mega_caves.spawn_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.mega_caves.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-	[world.elder_prismarine_underground_biome]
-		#Allowed values: [0,1]
-		"Lantern Chance" = 0.0085
-		#Allowed values: [0,1]
-		"Water Chance" = 0.25
-
-		[world.elder_prismarine_underground_biome.biome_settings]
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#Allowed values: [0,)
-			Rarity = 200
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.elder_prismarine_underground_biome.biome_settings.biomes]
-				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-				# jungle, spooky, dead, lush, mushroom, magical, rare,
-				# plateau, modified, ocean, river, water, mesa, forest,
-				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-				# beach, void, overworld, nether, end]
-				"Biome Types" = ["ocean"]
-				"Is Blacklist" = false
-
-			[world.elder_prismarine_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.glowshroom_underground_biome]
-		#Allowed values: [0,1]
-		"Glowshroom Spawn Chance" = 0.0625
-		#Allowed values: (0,)
-		"Glowshroom Growth Rate" = 20
-		"Enable Danger Sight" = true
-		"Enable Huge Glowshrooms" = true
-
-		[world.glowshroom_underground_biome.biome_settings]
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#Allowed values: [0,)
-			Rarity = 80
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.glowshroom_underground_biome.biome_settings.biomes]
-				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-				# jungle, spooky, dead, lush, mushroom, magical, rare,
-				# plateau, modified, ocean, river, water, mesa, forest,
-				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-				# beach, void, overworld, nether, end]
-				"Biome Types" = ["mountain", "mushroom"]
-				"Is Blacklist" = false
-
-			[world.glowshroom_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.big_stone_clusters]
-		#Blocks that stone clusters can replace. If you want to make it so it only replaces in one dimension,
-		#do "block|dimension", as we do for netherrack and end stone by default.
-		"Blocks To Replace" = ["minecraft:stone", "minecraft:andesite", "minecraft:diorite", "minecraft:granite", "minecraft:netherrack|minecraft:the_nether", "minecraft:end_stone|minecraft:the_end", "quark:marble", "quark:limestone", "quark:jasper", "quark:slate", "quark:basalt"]
-
-		[world.big_stone_clusters.marble]
-			#Allowed values: [0,)
-			"Horizontal Size" = 14
-			#Allowed values: [0,)
-			Rarity = 4
-			#Allowed values: [0,255]
-			"Min Y Level" = 20
-			#Allowed values: [0,)
-			"Horizontal Variation" = 9
-			Enabled = true
-			#Allowed values: [0,255]
-			"Max Y Level" = 80
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#Allowed values: [0,)
-			"Vertical Variation" = 9
-
-			[world.big_stone_clusters.marble.biomes]
-
-				[world.big_stone_clusters.marble.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["plains"]
-					"Is Blacklist" = false
-
-				[world.big_stone_clusters.marble.biomes.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-			[world.big_stone_clusters.marble.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.big_stone_clusters.limestone]
-			#Allowed values: [0,)
-			"Horizontal Size" = 14
-			#Allowed values: [0,)
-			Rarity = 4
-			#Allowed values: [0,255]
-			"Min Y Level" = 20
-			#Allowed values: [0,)
-			"Horizontal Variation" = 9
-			Enabled = true
-			#Allowed values: [0,255]
-			"Max Y Level" = 80
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#Allowed values: [0,)
-			"Vertical Variation" = 9
-
-			[world.big_stone_clusters.limestone.biomes]
-
-				[world.big_stone_clusters.limestone.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["swamp", "ocean"]
-					"Is Blacklist" = false
-
-				[world.big_stone_clusters.limestone.biomes.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-			[world.big_stone_clusters.limestone.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.big_stone_clusters.granite]
-			#Allowed values: [0,)
-			"Horizontal Size" = 14
-			#Allowed values: [0,)
-			Rarity = 4
-			#Allowed values: [0,255]
-			"Min Y Level" = 20
-			#Allowed values: [0,)
-			"Horizontal Variation" = 9
-			Enabled = true
-			#Allowed values: [0,255]
-			"Max Y Level" = 80
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#Allowed values: [0,)
-			"Vertical Variation" = 9
-
-			[world.big_stone_clusters.granite.biomes]
-
-				[world.big_stone_clusters.granite.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["mountain"]
-					"Is Blacklist" = false
-
-				[world.big_stone_clusters.granite.biomes.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-			[world.big_stone_clusters.granite.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.big_stone_clusters.myalite]
-			#Allowed values: [0,)
-			"Horizontal Size" = 20
-			#Allowed values: [0,)
-			Rarity = 100
-			"Generate In Air" = true
-			#Allowed values: [0,255]
-			"Min Y Level" = 58
-			#Allowed values: [0,)
-			"Horizontal Variation" = 6
-			Enabled = true
-			#Allowed values: [0,255]
-			"Max Y Level" = 62
-			#Allowed values: [0,)
-			"Vertical Size" = 40
-			#Allowed values: [0,)
-			"Vertical Variation" = 10
-
-			[world.big_stone_clusters.myalite.biomes]
-
-				[world.big_stone_clusters.myalite.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = []
-					"Is Blacklist" = true
-
-				[world.big_stone_clusters.myalite.biomes.biomes]
-					Biomes = ["minecraft:end_highlands"]
-					"Is Blacklist" = false
-
-			[world.big_stone_clusters.myalite.dimensions]
-				Dimensions = ["minecraft:the_end"]
-				"Is Blacklist" = false
-
-		[world.big_stone_clusters.voidstone]
-			#Allowed values: [0,)
-			"Horizontal Size" = 19
-			#Allowed values: [0,)
-			Rarity = 20
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#Allowed values: [0,)
-			"Horizontal Variation" = 6
-			Enabled = true
-			#Allowed values: [0,255]
-			"Max Y Level" = 40
-			#Allowed values: [0,)
-			"Vertical Size" = 19
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.big_stone_clusters.voidstone.biomes]
-
-				[world.big_stone_clusters.voidstone.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = []
-					"Is Blacklist" = true
-
-				[world.big_stone_clusters.voidstone.biomes.biomes]
-					Biomes = ["minecraft:end_highlands", "minecraft:end_midlands", "minecraft:end_barrens"]
-					"Is Blacklist" = false
-
-			[world.big_stone_clusters.voidstone.dimensions]
-				Dimensions = ["minecraft:the_end"]
-				"Is Blacklist" = false
-
-		[world.big_stone_clusters.andesite]
-			#Allowed values: [0,)
-			"Horizontal Size" = 14
-			#Allowed values: [0,)
-			Rarity = 4
-			#Allowed values: [0,255]
-			"Min Y Level" = 20
-			#Allowed values: [0,)
-			"Horizontal Variation" = 9
-			Enabled = true
-			#Allowed values: [0,255]
-			"Max Y Level" = 80
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#Allowed values: [0,)
-			"Vertical Variation" = 9
-
-			[world.big_stone_clusters.andesite.biomes]
-
-				[world.big_stone_clusters.andesite.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["forest"]
-					"Is Blacklist" = false
-
-				[world.big_stone_clusters.andesite.biomes.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-			[world.big_stone_clusters.andesite.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.big_stone_clusters.slate]
-			#Allowed values: [0,)
-			"Horizontal Size" = 14
-			#Allowed values: [0,)
-			Rarity = 4
-			#Allowed values: [0,255]
-			"Min Y Level" = 20
-			#Allowed values: [0,)
-			"Horizontal Variation" = 9
-			Enabled = true
-			#Allowed values: [0,255]
-			"Max Y Level" = 80
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#Allowed values: [0,)
-			"Vertical Variation" = 9
-
-			[world.big_stone_clusters.slate.biomes]
-
-				[world.big_stone_clusters.slate.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["snowy"]
-					"Is Blacklist" = false
-
-				[world.big_stone_clusters.slate.biomes.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-			[world.big_stone_clusters.slate.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.big_stone_clusters.diorite]
-			#Allowed values: [0,)
-			"Horizontal Size" = 14
-			#Allowed values: [0,)
-			Rarity = 4
-			#Allowed values: [0,255]
-			"Min Y Level" = 20
-			#Allowed values: [0,)
-			"Horizontal Variation" = 9
-			Enabled = true
-			#Allowed values: [0,255]
-			"Max Y Level" = 80
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#Allowed values: [0,)
-			"Vertical Variation" = 9
-
-			[world.big_stone_clusters.diorite.biomes]
-
-				[world.big_stone_clusters.diorite.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["savanna", "jungle", "mushroom"]
-					"Is Blacklist" = false
-
-				[world.big_stone_clusters.diorite.biomes.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-			[world.big_stone_clusters.diorite.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-		[world.big_stone_clusters.jasper]
-			#Allowed values: [0,)
-			"Horizontal Size" = 14
-			#Allowed values: [0,)
-			Rarity = 4
-			#Allowed values: [0,255]
-			"Min Y Level" = 20
-			#Allowed values: [0,)
-			"Horizontal Variation" = 9
-			Enabled = true
-			#Allowed values: [0,255]
-			"Max Y Level" = 80
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#Allowed values: [0,)
-			"Vertical Variation" = 9
-
-			[world.big_stone_clusters.jasper.biomes]
-
-				[world.big_stone_clusters.jasper.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["mesa", "sandy"]
-					"Is Blacklist" = false
-
-				[world.big_stone_clusters.jasper.biomes.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-			[world.big_stone_clusters.jasper.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.overgrown_underground_biome]
-
-		[world.overgrown_underground_biome.biome_settings]
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#Allowed values: [0,)
-			Rarity = 80
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.overgrown_underground_biome.biome_settings.biomes]
-				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-				# jungle, spooky, dead, lush, mushroom, magical, rare,
-				# plateau, modified, ocean, river, water, mesa, forest,
-				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-				# beach, void, overworld, nether, end]
-				"Biome Types" = ["forest"]
-				"Is Blacklist" = false
-
-			[world.overgrown_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.permafrost_underground_biome]
-
-		[world.permafrost_underground_biome.biome_settings]
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#Allowed values: [0,)
-			Rarity = 80
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.permafrost_underground_biome.biome_settings.biomes]
-				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-				# jungle, spooky, dead, lush, mushroom, magical, rare,
-				# plateau, modified, ocean, river, water, mesa, forest,
-				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-				# beach, void, overworld, nether, end]
-				"Biome Types" = ["snowy"]
-				"Is Blacklist" = false
-
-			[world.permafrost_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.lush_underground_biome]
-
-		[world.lush_underground_biome.biome_settings]
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#Allowed values: [0,)
-			Rarity = 80
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.lush_underground_biome.biome_settings.biomes]
-				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-				# jungle, spooky, dead, lush, mushroom, magical, rare,
-				# plateau, modified, ocean, river, water, mesa, forest,
-				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-				# beach, void, overworld, nether, end]
-				"Biome Types" = ["jungle"]
-				"Is Blacklist" = false
-
-			[world.lush_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.brimstone_underground_biome]
-
-		[world.brimstone_underground_biome.biome_settings]
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#Allowed values: [0,)
-			Rarity = 80
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.brimstone_underground_biome.biome_settings.biomes]
-				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-				# jungle, spooky, dead, lush, mushroom, magical, rare,
-				# plateau, modified, ocean, river, water, mesa, forest,
-				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-				# beach, void, overworld, nether, end]
-				"Biome Types" = ["mesa"]
-				"Is Blacklist" = false
-
-			[world.brimstone_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-	[world.big_dungeon]
-		"Loot Table" = "minecraft:chests/simple_dungeon"
-		#The chance that a big dungeon spawn candidate will be allowed to spawn. 0.2 is 20%, which is the same as the Pillager Outpost.
-		"Spawn Chance" = 0.1
-		"Max Rooms" = 10
-		"Chest Chance" = 0.5
-
-		[world.big_dungeon.biome_config]
-
-			[world.big_dungeon.biome_config.types]
-				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-				# jungle, spooky, dead, lush, mushroom, magical, rare,
-				# plateau, modified, ocean, river, water, mesa, forest,
-				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-				# beach, void, overworld, nether, end]
-				"Biome Types" = ["ocean", "beach", "nether", "end"]
-				"Is Blacklist" = true
-
-			[world.big_dungeon.biome_config.biomes]
-				Biomes = []
-				"Is Blacklist" = true
-
-	[world.chorus_vegetation]
-		"Teleport Duplication Chance" = 0.01
-		Radius = 7
-		Rarity = 150
-		"Chunk Attempts" = 120
-		"Highlands Chance" = 1.0
-		"Midlands Chance" = 0.2
-		"Endermite Spawn Chance" = 0.01
-		"Passive Teleport Chance" = 0.2
-		"Other End Biomes Chance" = 0.0
-
-	[world.fairy_rings]
-		"Forest Chance" = 0.00625
-		Ores = ["minecraft:emerald_ore", "minecraft:diamond_ore"]
-		"Plains Chance" = 0.0025
-
-		[world.fairy_rings.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-	[world.underground_clay]
-
-		[world.underground_clay.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-		[world.underground_clay.ore_settings]
-			#Allowed values: [0,255]
-			"Max Height" = 60
-			#Allowed values: [0,)
-			"Cluster Count" = 3
-			#Allowed values: [0,255]
-			"Min Height" = 20
-			#Allowed values: [0,)
-			"Cluster Size" = 20
-
-	[world.slime_underground_biome]
-
-		[world.slime_underground_biome.biome_settings]
-			#Allowed values: [0,)
-			"Horizontal Size" = 26
-			#Allowed values: [0,)
-			Rarity = 120
-			#Allowed values: [0,255]
-			"Min Y Level" = 0
-			#Allowed values: [0,)
-			"Horizontal Variation" = 14
-			#Allowed values: [0,255]
-			"Max Y Level" = 64
-			#Allowed values: [0,)
-			"Vertical Size" = 14
-			#Allowed values: [0,)
-			"Vertical Variation" = 6
-
-			[world.slime_underground_biome.biome_settings.biomes]
-				#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-				# jungle, spooky, dead, lush, mushroom, magical, rare,
-				# plateau, modified, ocean, river, water, mesa, forest,
-				# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-				# beach, void, overworld, nether, end]
-				"Biome Types" = ["swamp"]
-				"Is Blacklist" = false
-
-			[world.slime_underground_biome.biome_settings.dimensions]
-				Dimensions = ["minecraft:overworld"]
-				"Is Blacklist" = false
-
-[mobs]
-	Frogs = true
-	Crabs = true
-	Stonelings = true
-	Foxhound = true
-	Forgotten = true
-	Wraith = true
-	Toretoise = true
-
-	[mobs.toretoise]
-		"Max Y Level" = 32
-
-		[mobs.toretoise.spawn_config]
-			#Allowed values: (0,)
-			"Spawn Weight" = 100
-			#Allowed values: [1,)
-			"Min Group Size" = 1
-			#Allowed values: [1,)
-			"Max Group Size" = 1
-
-			[mobs.toretoise.spawn_config.biomes]
-
-				[mobs.toretoise.spawn_config.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["void", "nether", "end"]
-					"Is Blacklist" = true
-
-				[mobs.toretoise.spawn_config.biomes.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-		[mobs.toretoise.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-	[mobs.crabs]
-		"Enable Brewing" = true
-
-		[mobs.crabs.spawn_config]
-			#Allowed values: (0,)
-			"Spawn Weight" = 5
-			#Allowed values: [1,)
-			"Min Group Size" = 1
-			#Allowed values: [1,)
-			"Max Group Size" = 3
-
-			[mobs.crabs.spawn_config.biomes]
-
-				[mobs.crabs.spawn_config.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["beach"]
-					"Is Blacklist" = false
-
-				[mobs.crabs.spawn_config.biomes.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-	[mobs.foxhound]
-		#The chance coal will tame a foxhound
-		"Tame Chance" = 0.05
-
-		[mobs.foxhound.lesser_spawn_config]
-			#Allowed values: (0,)
-			"Spawn Weight" = 2
-			"Max Cost" = 0.7
-			#Allowed values: [1,)
-			"Min Group Size" = 1
-			"Spawn Cost" = 0.15
-			#Allowed values: [1,)
-			"Max Group Size" = 1
-
-			[mobs.foxhound.lesser_spawn_config.biomes]
-
-				[mobs.foxhound.lesser_spawn_config.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = []
-					"Is Blacklist" = true
-
-				[mobs.foxhound.lesser_spawn_config.biomes.biomes]
-					Biomes = ["minecraft:soul_sand_valley"]
-					"Is Blacklist" = false
-
-		[mobs.foxhound.spawn_config]
-			#Allowed values: (0,)
-			"Spawn Weight" = 30
-			#Allowed values: [1,)
-			"Min Group Size" = 1
-			#Allowed values: [1,)
-			"Max Group Size" = 2
-
-			[mobs.foxhound.spawn_config.biomes]
-
-				[mobs.foxhound.spawn_config.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = []
-					"Is Blacklist" = true
-
-				[mobs.foxhound.spawn_config.biomes.biomes]
-					Biomes = ["minecraft:nether_wastes", "minecraft:basalt_deltas"]
-					"Is Blacklist" = false
-
-	[mobs.wraith]
-		#List of sound sets to use with wraiths.
-		#Three sounds must be provided per entry, separated by | (in the format idle|hurt|death). Leave blank for no sound (i.e. if a mob has no ambient noise)
-		"Wraith Sounds" = ["entity.sheep.ambient|entity.sheep.hurt|entity.sheep.death", "entity.cow.ambient|entity.cow.hurt|entity.cow.death", "entity.pig.ambient|entity.pig.hurt|entity.pig.death", "entity.chicken.ambient|entity.chicken.hurt|entity.chicken.death", "entity.horse.ambient|entity.horse.hurt|entity.horse.death", "entity.cat.ambient|entity.cat.hurt|entity.cat.death", "entity.wolf.ambient|entity.wolf.hurt|entity.wolf.death", "entity.villager.ambient|entity.villager.hurt|entity.villager.death", "entity.polar_bear.ambient|entity.polar_bear.hurt|entity.polar_bear.death", "entity.zombie.ambient|entity.zombie.hurt|entity.zombie.death", "entity.skeleton.ambient|entity.skeleton.hurt|entity.skeleton.death", "entity.spider.ambient|entity.spider.hurt|entity.spider.death", "|entity.creeper.hurt|entity.creeper.death", "entity.endermen.ambient|entity.endermen.hurt|entity.endermen.death", "entity.zombie_pig.ambient|entity.zombie_pig.hurt|entity.zombie_pig.death", "entity.witch.ambient|entity.witch.hurt|entity.witch.death", "entity.blaze.ambient|entity.blaze.hurt|entity.blaze.death", "entity.llama.ambient|entity.llama.hurt|entity.llama.death", "|quark:entity.stoneling.cry|quark:entity.stoneling.die", "quark:entity.frog.idle|quark:entity.frog.hurt|quark:entity.frog.die"]
-
-		[mobs.wraith.spawn_config]
-			#Allowed values: (0,)
-			"Spawn Weight" = 8
-			"Max Cost" = 0.7
-			#Allowed values: [1,)
-			"Min Group Size" = 1
-			"Spawn Cost" = 0.15
-			#Allowed values: [1,)
-			"Max Group Size" = 3
-
-			[mobs.wraith.spawn_config.biomes]
-
-				[mobs.wraith.spawn_config.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = []
-					"Is Blacklist" = true
-
-				[mobs.wraith.spawn_config.biomes.biomes]
-					Biomes = ["minecraft:soul_sand_valley"]
-					"Is Blacklist" = false
-
-	[mobs.stonelings]
-		"Cautious Stonelings" = true
-		"Enable Diamond Heart" = true
-		"Max Y Level" = 24
-		"Tamable Stonelings" = true
-
-		[mobs.stonelings.spawn_config]
-			#Allowed values: (0,)
-			"Spawn Weight" = 80
-			#Allowed values: [1,)
-			"Min Group Size" = 1
-			#Allowed values: [1,)
-			"Max Group Size" = 1
-
-			[mobs.stonelings.spawn_config.biomes]
-
-				[mobs.stonelings.spawn_config.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["void", "nether", "end"]
-					"Is Blacklist" = true
-
-				[mobs.stonelings.spawn_config.biomes.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-		[mobs.stonelings.dimensions]
-			Dimensions = ["minecraft:overworld"]
-			"Is Blacklist" = false
-
-	[mobs.forgotten]
-		#1 in this many Skeletons that spawn under the threshold are replaced with Forgotten.
-		"Forgotten Spawn Rate" = 0.05
-		"Max Height For Spawn" = 20
-
-	[mobs.frogs]
-		"Enable Brewing" = true
-		"Enable Big Funny" = false
-
-		[mobs.frogs.spawn_config]
-			#Allowed values: (0,)
-			"Spawn Weight" = 40
-			#Allowed values: [1,)
-			"Min Group Size" = 1
-			#Allowed values: [1,)
-			"Max Group Size" = 3
-
-			[mobs.frogs.spawn_config.biomes]
-
-				[mobs.frogs.spawn_config.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["swamp"]
-					"Is Blacklist" = false
-
-				[mobs.frogs.spawn_config.biomes.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-[client]
-	"Greener Grass" = true
-	"Variant Animal Textures" = true
-	"Back Button Keybind" = true
-	"Improved Tooltips" = true
-	"Improved Mount Hud" = true
-	"Usage Ticker" = true
-	"Auto Walk Keybind" = true
-	"Chest Searching" = true
-
-	[client.usage_ticker]
-		#Switch the armor display to the off hand side and the hand display to the main hand side
-		Invert = false
-		"Shift Right" = 0
-		"Enable Armor" = true
-		"Enable Off Hand" = true
-		"Shift Left" = 0
-		"Enable Main Hand" = true
-
-	[client.variant_animal_textures]
-		"Enable Shiny Llama" = true
-		"Every Bee Is L G B T" = false
-		#The chance for an animal to have a special "Shiny" skin, like a shiny pokemon. This is 1 in X. Set to 0 to disable.
-		"Shiny Animal Chance" = 2048
-		"Enable Pig" = true
-		"Enable Chicken" = true
-		"Enable Shiny Rabbit" = true
-		"Enable L G B T Bees" = true
-		"Enable Cow" = true
-
-	[client.improved_tooltips]
-		"Shulker Box Require Shift" = false
-		"Shulker Box Use Colors" = true
-		"Attribute Tooltips" = true
-		"Enchanting Tooltips" = true
-		#The value of each shank of food. Tweak this when using mods like Hardcore Hunger which change that value.
-		"Food Divisor" = 2
-		#A list of additional stacks to display on each enchantment
-		#The format is as follows:
-		#enchant_id=item1,item2,item3...
-		#So to display a carrot on a stick on a mending book, for example, you use:
-		#minecraft:mending=minecraft:carrot_on_a_stick
-		"Enchanting Additional Stacks" = []
-		"Food Compression Threshold" = 4
-		"Shulker Tooltips" = true
-		"Map Require Shift" = false
-		"Food Tooltips" = true
-		"Show Saturation" = true
-		"Map Tooltips" = true
-		"Enchanting Stacks" = ["minecraft:diamond_sword", "minecraft:diamond_pickaxe", "minecraft:diamond_shovel", "minecraft:diamond_axe", "minecraft:diamond_hoe", "minecraft:diamond_helmet", "minecraft:diamond_chestplate", "minecraft:diamond_leggings", "minecraft:diamond_boots", "minecraft:shears", "minecraft:bow", "minecraft:fishing_rod", "minecraft:crossbow", "minecraft:trident", "minecraft:elytra", "quark:pickarang"]
-
-	[client.greener_grass]
-		"Leaves List" = ["minecraft:spruce_leaves", "minecraft:birch_leaves", "minecraft:oak_leaves", "minecraft:jungle_leaves", "minecraft:acacia_leaves", "minecraft:dark_oak_leaves", "atmospheric:rosewood_leaves", "atmospheric:morado_leaves", "atmospheric:yucca_leaves", "autumnity:maple_leaves", "environmental:willow_leaves", "environmental:hanging_willow_leaves", "minecraft:vine"]
-		"Block List" = ["minecraft:large_fern", "minecraft:tall_grass", "minecraft:grass_block", "minecraft:fern", "minecraft:grass", "minecraft:potted_fern", "minecraft:sugar_cane", "environmental:giant_tall_grass"]
-		"Affect Leaves" = true
-
-		[client.greener_grass.color_matrix]
-			R = [0.89, 0.0, 0.0]
-			B = [0.0, 0.0, 0.89]
-			G = [0.0, 1.11, 0.0]
-
-[oddities]
-	"Totem Of Holding" = true
-	Backpack = true
-	Crate = false
-	"Matrix Enchanting" = false
-	Magnets = true
-	Pipes = true
-
-	[oddities.totem_of_holding]
-		#Set this to false to remove the behaviour where totems destroy themselves if the player dies again.
-		"Dark Souls Mode" = true
-		"Spawn Totem on PVP Kill" = false
-		#Set this to true to make it so that if a totem is destroyed, the items it holds are destroyed alongside it rather than dropped
-		"Destroy Lost Items" = false
-		"Enable Soul Compass" = true
-		#Set this to false to only allow the owner of a totem to collect its items rather than any player
-		"Allow Anyone To Collect" = true
-
-	[oddities.magnets]
-		"Magnetic Blacklist" = ["minecraft:tripwire_hook"]
-		"Magnetic Whitelist" = ["minecraft:chipped_anvil", "minecraft:damaged_anvil"]
-		#Any items you place in this list will be derived so that any block made of it will become magnetizable
-		"Magnetic Derivation List" = ["minecraft:iron_ingot"]
-
-	[oddities.matrix_enchanting]
-		#Set to false to disable the ability to influence enchantment outcomes with candles (requires the Tallow and Candles module enabled)
-		"Allow Influencing" = true
-		#A list of enchantment IDs you don't want the enchantment table to be able to create
-		"Disallowed Enchantments" = []
-		#The maximum enchanting power the matrix enchanter can accept
-		"Max Bookshelves" = 15
-		#How much to multiply the frequency of pieces where at least one of the same type has been generated
-		"Dupe Multiplier" = 1.4
-		#How much the min level requirement for adding a new piece to a book should increase per each bookshelf being used
-		"Min Level Scale Factor Book" = 2.0
-		#At which piece count the calculation for the min level should default to increasing one per piece rather than using the scale factor
-		"Min Level Cutoff" = 10
-		#Should this be X, the price of a piece increase by 1 every X pieces you generate
-		"Piece Price Scale" = 9
-		#Matrix Enchanting can be done with water instead of air around the enchanting table. Set this to false to disable this behaviour.
-		"Allow Underwater Enchanting" = true
-		#How many pieces you can generate without any bookshelves
-		"Base Max Piece Count" = 3
-		#How much each candle influences an enchantment. This works as a multiplier to its weight
-		"Influence Power" = 0.125
-		#Set to false to disable the tooltip for items with pending enchantments
-		"Show Tooltip" = true
-		#Set to false to disable the ability to create Enchanted Books
-		"Allow Books" = true
-		#If you set this to false, the vanilla Enchanting Table will no longer automatically convert to the Matrix Enchanting table. You'll have to add a recipe for the Matrix Enchanting Table to make use of this.
-		"Automatically Convert" = true
-		#The higher this is, the better enchantments you'll get on books
-		"Book Enchantability" = 12
-		#An array of influences each candle should apply. This list must be 16 elements long, and is in order of wool colors.
-		"Influences List" = ["minecraft:unbreaking", "minecraft:fire_protection", "minecraft:knockback,minecraft:punch", "minecraft:feather_falling", "minecraft:looting,minecraft:fortune,minecraft:luck_of_the_sea", "minecraft:blast_protection", "minecraft:silk_touch,minecraft:channeling", "minecraft:bane_of_arthropods", "minecraft:protection", "minecraft:respiration,minecraft:loyalty,minecraft:infinity", "minecraft:sweeping,minecraft:multishot", "minecraft:efficiency,minecraft:sharpness,minecraft:lure,minecraft:power,minecraft:impaling,minecraft:quick_charge", "minecraft:aqua_affinity,minecraft:depth_strider,minecraft:riptide", "minecraft:thorns,minecraft:piercing", "minecraft:fire_aspect,minecraft:flame", "minecraft:smite,minecraft:projectile_protection"]
-		#How many pieces a single Lapis can generate
-		"Charge Per Lapis" = 4
-		#How many pieces you can generate without any bookshelves (for Books)
-		"Base Max Piece Count Book" = 1
-		#How much to multiply the frequency of pieces where incompatible pieces have been generated
-		"Incompatible Multiplier" = 0.0
-		#How much the min level requirement for adding a new piece should increase for each piece added (up until the value of Min Level Cutoff)
-		"Min Level Scale Factor" = 1.5
-		#Set this to true to allow treasure enchantments to be rolled as pieces
-		"Allow Treasures" = false
-		#By default, enchantment rarities are fuzzed a bit to feel better with the new system. Set this to false to override this behaviour.
-		"Normalize Rarity" = true
-		#The max amount of candles that can influence a single enchantment
-		"Influence Max" = 4
-
-	[oddities.backpack]
-		"Enable Ravager Hide" = true
-		"Base Ravager Hide Drop" = 1
-		"Extra Chance Per Looting" = 0.5
-		#Set this to true to allow the backpacks to be unequipped even with items in them
-		"Super Op Mode" = false
-
-	[oddities.crate]
-		"Max Items" = 640
-
-	[oddities.pipes]
-		#Set to 0 if you don't want pipes to have a max amount of items
-		"Max Pipe Items" = 16
-		#When items eject or are absorbed by pipes, should they make sounds?
-		"Do Pipes Whoosh" = true
-		#How long it takes for an item to cross a pipe. Bigger = slower.
-		"Pipe Speed" = 5
-
-[experimental]
-	Shiba = false
-	"Adjustable Chat" = false
-	"Narrator Readout" = false
-	"Overlay Shader" = false
-	"Custom Underground Biome" = false
-	"Game Nerfs" = false
-
-	[experimental.adjustable_chat]
-		"Horizontal Shift" = 0
-		"Vertical Shift" = 0
-
-	[experimental.custom_underground_biome]
-		#The format for these definitions is:
-		#dimensions;isDimensionBlacklist;biomeTypews;isBiomeBlacklist;rarity;minY..maxY;horizontalSize,verticalSize;horizontalVariation,verticalVariation;floorBlocks@weight;ceilingBlocks@weight;wallBlocks@weight;mimicInside
-		#That's a lot to take in, so here's an example. This would be for the default config of the Slime underground biome. (Spaces are allowed.)
-		#minecraft:overworld; false; SWAMP; false; 120; 10..40; 26,14; 14,6; minecraft:water@915, minecraft:slime_block@85; minecraft:green_terracotta@2, minecraft:lime_terracotta@3, minecraft:light_blue_terracotta@1; CEILING; false
-		"Biome Definitions" = []
-
-	[experimental.game_nerfs]
-		#Makes Mending act like the Unmending mod
-		#https://www.curseforge.com/minecraft/mc-mods/unmending
-		"Nerf Mending" = true
-		#Makes Iron Golems not drop Iron Ingots
-		"Disable Iron Farms" = true
-		#Makes Sheep not drop Wool when killed
-		"Disable Wool Drops" = true
-		#Makes Boats not glide on ice
-		"Disable Ice Roads" = true
-		#Resets all villager discounts when zombified to prevent reducing prices to ridiculous levels
-		"Nerf Villager Discount" = true
-
-	[experimental.shiba]
-
-		[experimental.shiba.spawn_config]
-			#Allowed values: (0,)
-			"Spawn Weight" = 40
-			#Allowed values: [1,)
-			"Min Group Size" = 1
-			#Allowed values: [1,)
-			"Max Group Size" = 3
-
-			[experimental.shiba.spawn_config.biomes]
-
-				[experimental.shiba.spawn_config.biomes.types]
-					#Allowed values: [[hot, cold, sparse, dense, wet, dry, savanna, coniferous,
-					# jungle, spooky, dead, lush, mushroom, magical, rare,
-					# plateau, modified, ocean, river, water, mesa, forest,
-					# plains, mountain, hills, swamp, sandy, snowy, wasteland,
-					# beach, void, overworld, nether, end]
-					"Biome Types" = ["mountain"]
-					"Is Blacklist" = false
-
-				[experimental.shiba.spawn_config.biomes.biomes]
-					Biomes = []
-					"Is Blacklist" = true
-
-	[experimental.overlay_shader]
-		#Sets the name of the shader to load on a regular basis. This can load any shader the Camera module can (and requires the Camera module enabled to apply said logic).
-		#Some useful shaders include 'desaturate', 'oversaturate', 'bumpy'
-		#Colorblind simulation shaders are available in the form of 'deuteranopia', 'protanopia', 'tritanopia', and 'achromatopsia'
-		Shader = "none"
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/repairchests-common.toml b/configuration/services/configs/minecraft/voor-kia/config/repairchests-common.toml
deleted file mode 100644
index 84d35f4..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/repairchests-common.toml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-["Repair Times"]
-	#How many seconds to repair 1 point of damage
-	ultimateRepairTime = 2
-	#How many seconds to repair 1 point of damage
-	advancedRepairTime = 5
-	#How many seconds to repair 1 point of damage
-	basicRepairTime = 10
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/rsgauges-common.toml b/configuration/services/configs/minecraft/voor-kia/config/rsgauges-common.toml
deleted file mode 100644
index 1cd76d1..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/rsgauges-common.toml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-#Settings affecting the logical server side, but are also configurable in single player.
-[server]
-
-	#Opt-out settings
-	[server.optout]
-		#Disables switch remote linking.
-		without_switch_linking = false
-		#Opt-out any block by its registry name ('*' wildcard matching, comma separated list, whitespaces ignored. You must match the whole name, means maybe add '*' also at the begin and end. Example: '*wood*,*steel*' excludes everything that has 'wood' or 'steel' in the registry name. The matching result is also traced in the log file. 
-		pattern_excludes = ""
-		#Prevent blocks from being opt'ed by registry name ('*' wildcard matching, comma separated list, whitespaces ignored. Evaluated before all other opt-out checks. You must match the whole name, means maybe add '*' also at the begin and end. Example: '*wood*,*steel*' includes everything that has 'wood' or 'steel' in the registry name.The matching result is also traced in the log file.
-		pattern_includes = ""
-
-	#Miscellaneous settings
-	[server.miscellaneous]
-		#Enables experimental features. Use at own risk.
-		with_experimental = false
-		#Comma separated list of items names that can be used alter configurable blocks of this mod. This applies when the display side of the block is right click (activated) with the item in the main hand.
-		accepted_wrenches = "minecraft:redstone_torch,immersiveengineering:screwdriver,immersiveengineering:hammer"
-		#Defines how far you or a link source switch can be away from the target to activate it. The value 0 means 'no limitation',  as long as the target chunk is loaded.
-		#Range: 0 ~ 64
-		max_switch_linking_distance = 48
-		#Enable detailed logging of the config values and resulting calculations in each mod feature config.
-		with_config_logging = false
-
-	#Settings to tweak the performance, or use cases normally no change should be required here.
-	[server.tweaks]
-		#Sample interval of the gauges in ticks. Lower values decrease the display latency for indirect weak power measurements. Minor performance impact for values >= 5.
-		#Range: 2 ~ 100
-		gauge_update_interval = 8
-		#Sample interval of the linear switches in ticks (like laser pointer based sensors). Lower values make the switches reacting faster, but also have an impact on the server performance due to ray tracing. Has much less impact
-		#as the volumetric autoswitch interval.
-		#Range: 1 ~ 50
-		autoswitch_linear_update_interval = 4
-		#Sample interval of volume sensing automatic switches in ticks (e.g infrared motion detector). Lower values make the switches reacting faster, but also have an impact on the server performance due to ray tracing.
-		#Range: 5 ~ 50
-		autoswitch_volumetric_update_interval = 10
-		#Gauges shall not frequently lookup weak power provided to the block they are attached to.
-		without_gauge_weak_power_measurement = false
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/snowrealmagic-common.toml b/configuration/services/configs/minecraft/voor-kia/config/snowrealmagic-common.toml
deleted file mode 100644
index 06d5d7c..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/snowrealmagic-common.toml
+++ /dev/null
@@ -1,25 +0,0 @@
-placeSnowInBlock = true
-snowGravity = true
-snowAlwaysReplaceable = true
-#Unavailable if TerraForged mod installed
-snowAccumulationDuringSnowstorm = true
-#Unavailable if TerraForged mod installed
-snowAccumulationDuringSnowfall = false
-#Unavailable if TerraForged mod installed
-thinnerBoundingBox = true
-snowMakingIce = true
-snowOnIce = false
-snowNeverMelt = false
-snowMeltsInWarmBiomes = false
-#Should snow melt if layers are more than 1
-snowNaturalMelt = true
-snowReduceFallDamage = true
-replaceWorldFeature = true
-sustainGrassIfLayerMoreThanOne = true
-#If you want to uninstall this mod, you probably want to make snow-covered blocks back to normal via random tick.
-retainOriginalBlocks = false
-#9 = Unlimited
-#Range: 1 ~ 9
-snowAccumulationMaxLayers = 8
-advancedBlockInteraction = true
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/snowundertrees-common.toml b/configuration/services/configs/minecraft/voor-kia/config/snowundertrees-common.toml
deleted file mode 100644
index 8939bd3..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/snowundertrees-common.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-#Set this to false to disable snow under trees when first generating chunks.
-enable_biome_feature = true
-#Set this to false to disable snow under trees when it's snowing.
-enable_when_snowing = true
-#Add biome IDs here to exempt biomes from being affected by the mod (surrounded by ""). You can find the biome ID of the biome you're currently in on the F3 screen.
-#For example, the biome ID of the plains biome looks like this: minecraft:plains
-filtered_biomes = []
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/storagedrawers-common.toml b/configuration/services/configs/minecraft/voor-kia/config/storagedrawers-common.toml
deleted file mode 100644
index 06afa69..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/storagedrawers-common.toml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-[General]
-	#List of rules in format "domain:item1, domain:item2, n".
-	#Causes a compacting drawer convert n of item1 into 1 of item2.
-	compactingRules = ["minecraft:clay, minecraft:clay_ball, 4"]
-	enableUI = true
-	debugTrace = false
-	enableItemConversion = true
-	enableSidedInput = true
-	#The number of item stacks held in a basic unit of storage.
-	#1x1 drawers hold 8 units, 1x2 drawers hold 4 units, 2x2 drawers hold 2 units.
-	#Half-depth drawers hold half those amounts.
-	baseStackStorage = 4
-	enableExtraCompactingRules = true
-	#Range: 1 ~ 50
-	controllerRange = 12
-	enableSidedOutput = true
-
-[StorageUpgrades]
-	level2Mult = 4
-	#Storage upgrades multiply storage capacity by the given amount.
-	#When multiple storage upgrades are used together, their multipliers are added before being applied.
-	level1Mult = 2
-	level3Mult = 8
-	level5Mult = 32
-	level4Mult = 16
-
-[Integration]
-	wailaStackRemainder = true
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/supplementaries-common.toml b/configuration/services/configs/minecraft/voor-kia/config/supplementaries-common.toml
deleted file mode 100644
index 4de24d6..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/supplementaries-common.toml
+++ /dev/null
@@ -1,274 +0,0 @@
-
-#Server side blocks configs
-[blocks]
-
-	[blocks.globe]
-		#how many globe trades to give to the wandering trader. This will effectively increase the chance of him having a globe trader. Increase this if you have other mods that add stuff to that trader
-		#Range: 0 ~ 50
-		chance = 2
-		#chanche of finding a globe in a shipwreck treasure chest.
-		#Range: 0.0 ~ 1.0
-		shipwreck_treasure_chance = 0.25
-
-	[blocks.speaker_block]
-		#maximum range
-		#Range: 0 ~ 256
-		range = 64
-
-	[blocks.bellows]
-		#bellows pushes air following this equation: 
-		#air=(sin(2PI*ticks/period)<0), with period = base_period-(redstone_power-1)*power_scaling 
-		#represents base period at 1 power
-		#Range: 1 ~ 512
-		base_period = 78
-		#entities with velocity greated than this won't be pushed
-		#Range: 0.0 ~ 16.0
-		power_scaling = 2.0
-		#velocity increase uses this equation: 
-		#vel = base_vel*((range-entity_distance)/range) with base_vel = base_velocity_scaling/period 
-		#note that the block will push further the faster it's pulsing
-		#Range: 0.0 ~ 64.0
-		base_velocity_scaling = 5.0
-		#sets velocity changed flag when pushing entities +
-		#causes pushing animation to be smooth client side but also restricts player movement when being pushed
-		velocity_changed_flag = true
-		#note that it will still only keep alive the two fire blocks closer to it
-		#Range: 0 ~ 16
-		range = 5
-
-	[blocks.spring_launcher]
-		#spring launcher launch speed
-		#Range: 0.0 ~ 16.0
-		velocity = 1.5
-		#fall distance needed to trigger the automatic spring launch
-		#Range: 0 ~ 512
-		fall_height_required = 5
-
-	[blocks.turn_table]
-		#can rotate entities standing on it?
-		rotate_entities = true
-		#blocks that can't be rotated. Some special ones like chests, beds and pistons are already hardcoded
-		blacklist = ["minecraft:end_portal_frame"]
-
-	[blocks.jar]
-		#jar liquid capacity: leave at 12 for pixel accuracy
-		#Range: 0 ~ 1024
-		capacity = 12
-		#allow right click to instantly eat or drink food or potions inside a jar.
-		#Disable if you think this ability is op. Cookies are excluded
-		drink_from_jar = true
-
-	[blocks.cage]
-		#allow all entities to be captured by cages and jars. Not meant for survival
-		cage_allow_all_mobs = false
-		#allow all baby mobs to be captured by cages
-		cage_allow_all_babies = false
-
-	[blocks.notice_board]
-		#allow notice boards to accept and display any item, not just maps and books
-		allow_any_item = false
-
-	[blocks.sack]
-		#Penalize the player with slowness effect when carrying too many sacks
-		sack_penality = true
-		#maximum number of sacks after which the slowness effect will be applied. each multiple of this number will further slow the player down
-		#Range: 0 ~ 50
-		sack_increment = 2
-		#How many slots should a sack have
-		#Range: 1 ~ 27
-		slots = 9
-
-	[blocks.safe]
-		#Makes safes only breakable by their owner or by a player in creative
-		prevent_breaking = false
-		#Make safes simpler so they do not require keys:
-		#they will be bound to the first person that opens one and only that person will be able to interact with them
-		simple_safes = false
-
-	[blocks.blackboard]
-		#Enable to draw directly on a blackboard using any dye. Gui still only works in black and white
-		colored_blackboard = false
-
-	[blocks.candle_holder]
-		#Candle holder light level
-		#Range: 1 ~ 15
-		light_level = 12
-
-	[blocks.timber_frame]
-		#Replace a timber frame with wattle and daub block when daub is placed in it
-		replace_daub = true
-
-	[blocks.hourglass]
-		#Time in ticks for sugar
-		#Range: 0 ~ 10000
-		sugar_time = 40
-		#Time in ticks for sand blocks
-		#Range: 0 ~ 10000
-		sand_time = 70
-		#Time in ticks for concrete blocks
-		#Range: 0 ~ 10000
-		concrete_time = 105
-		#Time in ticks for generic dust
-		#Range: 0 ~ 10000
-		dust_time = 150
-		#Time in ticks for glowstone dust
-		#Range: 0 ~ 10000
-		glowstone_time = 190
-		#Time in ticks for blaze powder
-		#Range: 0 ~ 10000
-		blaze_powder_time = 277
-		#Time in ticks for redstone dust
-		#Range: 0 ~ 10000
-		redstone_time = 400
-		#Time in ticks for slime balls
-		#Range: 0 ~ 10000
-		slime_time = 1750
-		#Time in ticks for honey
-		#Range: 0 ~ 10000
-		honey_time = 2000
-
-	[blocks.item_shelf]
-		#Makes item shelves climbable
-		climbable_shelves = false
-
-	[blocks.iron_gate]
-		#Allows two iron gates to be opened simultaneously when on top of the other
-		double_opening = true
-
-#Configure spawning conditions
-[spawns]
-
-	[spawns.firefly]
-		#Spawnable biomes
-		biomes = ["minecraft:swamp", "minecraft:swamp_hills", "minecraft:plains", "minecraft:sunflower_plains", "minecraft:dark_forest", "minecraft:dark_forest_hills", "byg:bayou", "byg:cypress_swamplands", "byg:glowshroom_bayou", "byg:mangrove_marshes", "byg:vibrant_swamplands", "byg:fresh_water_lake", "byg:grassland_plateau", "byg:wooded_grassland_plateau", "byg:flowering_grove", "byg:guiana_shield", "byg:guiana_clearing", "byg:meadow", "byg:orchard", "byg:seasonal_birch_forest", "byg:seasonal_deciduous_forest", "byg:seasonal_forest", "biomesoplenty:flower_meadow", "biomesoplenty:fir_clearing", "biomesoplenty:grove_lakes", "biomesoplenty:grove", "biomesoplenty:highland_moor", "biomesoplenty:wetland_marsh", "biomesoplenty:deep_bayou", "biomesoplenty:wetland"]
-		#Whitelisted mods. All biomes from said mods will be able to spawn fireflies. Use the one above for more control
-		mod_whitelist = []
-		#Spawn weight 
-		#Set to 0 to disable spawning entirely
-		#Range: 0 ~ 100
-		weight = 3
-		#Minimum group size
-		#Range: 0 ~ 64
-		min = 5
-		#Maximum group size
-		#Range: 0 ~ 64
-		max = 9
-
-	[spawns.structures]
-
-		[spawns.structures.way_sign]
-			#Average distance apart in chunks between spawn attempts
-			#Range: 0 ~ 1001
-			average_distance = 19
-			#Minimum distance apart in chunks between spawn attempts. 1001 to disable them entirely
-			#Range: 0 ~ 1001
-			minimum_distance = 10
-			#With this option road signs will display the distance to the structure that they are pointing to
-			show_distance_text = true
-			#list of structure that a sign can point to. Note that they will only spawn in dimensions where vanilla villages can
-			villages = ["minecraft:village", "repurposed_structures:village_badlands", "repurposed_structures:village_dark_oak", "repurposed_structures:village_birch", "repurposed_structures:village_giant_taiga", "repurposed_structures:village_jungle", "repurposed_structures:village_mountains", "repurposed_structures:village_oak", "repurposed_structures:village_swamp", "pokecube:village", "pokecube_legends:village", "pokecube_legends:village/ocean", "valhelsia_structures:castle", "valhelsia_structures:castle_ruin", "valhelsia_structures:small_castle", "valhelsia_structures:tower_ruin", "stoneholm:underground_village"]
-
-#entities parameters
-[entities]
-
-	[entities.firefly]
-		#firefly animation period
-		#note that actual period will be this + a random number between 0 and 10
-		#this needs to be here to allow correct despawning of the entity when it's not glowing
-		#check client configs come more animation settings
-		#Range: 1 ~ 200
-		period = 65
-		#firefly flying speed
-		#Range: 0.0 ~ 10.0
-		speed = 0.3
-		#despawn during the day
-		despawn = true
-
-#Vanilla tweaks
-[tweaks]
-
-	[tweaks.cake_tweaks]
-		#allows you to place a cake ontop of another
-		double_cake = true
-		#replaces normal cake placement with a directional one
-		directional_cake = true
-
-	[tweaks.hanging_flower_pots]
-		#allows you to place hanging flower pots. Works with any modded pot too
-		enabled = true
-
-	[tweaks.throwable_bricks]
-		#throw bricks at your foes! Might break glass blocks
-		enabled = true
-
-	[tweaks.wall_lantern]
-		#allow wall lanterns placement
-		enabled = true
-		#mod ids of mods that have lantern block that extend the base lantern class but don't look like one
-		mod_blacklist = ["extlights", "betterendforge", "tconstruct"]
-
-	[tweaks.bells_tweaks]
-		#ring a bell by clicking on a chain that's connected to it
-		chain_ringing = true
-		#max chain length that allows a bell to ring
-		#Range: 0 ~ 1024
-		chain_length = 16
-
-	[tweaks.raked_gravel]
-		#allow gravel to be raked with a hoe
-		enabled = true
-
-	[tweaks.bottle_xp]
-		#Allow bottling up xp by using a bottle on an enchanting table
-		enabled = true
-		#bottling health cost
-		#Range: 0 ~ 20
-		cost = 2
-
-	[tweaks.map_tweaks]
-		#In this section you can add custom structure maps to cartographers
-		#The format required is as follows:
-		#[[<structure>,<level>,<min_price>,<max_price>,<map_name>,<map_color>,<map_marker>],[<structure>,...,<map_marker>],...]
-		#With the following parameters:
-		# - <structure> structure id to be located (ie: minecraft:igloo)
-		# - <level> villager trading level at which the map will be sold. Must be between 1 and 5
-		# - <min_price> minimum emerald price
-		# - <max_price> maximum emerald price
-		# - <map_name> map item name
-		# - <map_color> hex color of the map item overlay texture
-		# - <map_marker> id of the map marker to be used (ie: supplementaries:igloo). 
-		#See texture folder for all the names. Leave empty for default ones
-		#Note that ony the first parameter is required, each of the others others can me removed and will be defaulted to reasonable values
-		#example: ['minecraft:swamp_hut','2','5','7','witch hut map','0x00ff33']
-		custom_adventurer_maps = [[""]]
-		#Cartographers will sell 'adventurer maps' that will lead to a random vanilla structure (choosen from a thought out preset list).
-		#Best kept disabled if you are adding custom adventurer maps with its config
-		random_adventurer_maps = true
-		#enables beacons, lodestones, respawn anchors, beds, conduits, portals to be displayed on maps by clicking one of them with a map
-		block_map_markers = true
-
-	[tweaks.ceiling_banners]
-		#Allow banners to be placed on ceilings
-		enabled = true
-
-	[tweaks.zombie_horse]
-		#Feed a stack of rotten flesh to a skeleton horse to buff him up to a zombie horse
-		zombie_horse_conversion = true
-		#Amount of rotten flesh needed
-		#Range: 1 ~ 1000
-		rotten_flesh = 64
-
-[items]
-
-	[items.rope_arrow]
-		#If you really don't like my ropes you can specify here the block id ofa rope from another mod which will get deployed by rope arrows instead of mine
-		rope_arrow_override = "supplementaries:rope"
-
-	[items.flute]
-		#radius in which an unbound flute will search pets
-		#Range: 0 ~ 500
-		unbound_radius = 64
-		#max distance at which a bound flute will allow a pet to teleport
-		#Range: 0 ~ 500
-		bound_distance = 64
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/supplementaries-registry.toml b/configuration/services/configs/minecraft/voor-kia/config/supplementaries-registry.toml
deleted file mode 100644
index f38da67..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/supplementaries-registry.toml
+++ /dev/null
@@ -1,73 +0,0 @@
-#Here are configs that need reloading to take effect
-[initialization]
-
-    [initialization.general]
-        #Enable Creative Tab
-        creative_tab = false
-        #Set to false to disable custom dispenser behaviors (i.e: filling jars) if for some reason they are causing trouble
-        dispensers = true
-        #Creates a creative tab full of filled jars
-        jar_tab = false
-        #Enables custom Configured config screen
-        custom_configured_screen = true
-
-    [initialization.blocks]
-        planter = true
-        clock_block = false
-        pedestal = true
-        wind_vane = true
-        redstone_illuminator = true
-        notice_board = true
-        crank = false
-        jar = true
-        faucet = false
-        turn_table = false
-        piston_launcher = false
-        speaker_block = true
-        sign_post = true
-        hanging_sign = true
-        bellows = false
-        sconce = true
-        sconce_green = false
-        sconce_ender = true
-        sconce_soul = true
-        candelabra = true
-        cage = true
-        item_shelf = true
-        sconce_lever = true
-        cog_block = false
-        candle_holder = true
-        globe = true
-        hourglass = true
-        sack = true
-        blackboard = true
-        safe = true
-        copper_lantern = true
-        flute = false
-        gold_trapdoor = true
-        gold_door = true
-        bamboo_spikes = true
-        stone_lamp = true
-        checker_block = true
-        netherite_door = true
-        netherite_trapdoor = true
-        pancake = true
-        lock_block = true
-        flax = false
-        rope = false
-        rope_arrow = false
-        pulley_block = false
-        fodder = true
-        bomb = true
-        crimson_lantern = true
-        magma_cream_block = true
-        goblet = true
-        raked_gravel = true
-        statue = true
-        iron_gate = true
-        #WIP
-        laser_block = false
-        flag = false
-
-    [initialization.entities]
-        firefly = true
diff --git a/configuration/services/configs/minecraft/voor-kia/config/sweetconcrete-common.toml b/configuration/services/configs/minecraft/voor-kia/config/sweetconcrete-common.toml
deleted file mode 100644
index 135b45c..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/sweetconcrete-common.toml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-[general]
-	#Enable concrete pressure plates
-	enablePressurePlates = true
-	#Enable concrete levers
-	enableLevers = true
-	#Enable concrete buttons
-	enableButtons = true
-	#Enable concrete signs
-	enableSigns = true
-	#Enable concrete powder layers
-	enablePowderLayers = true
-	#Enable concrete stairs
-	enableStairs = true
-	#Enable concrte vertical slabs
-	enableVerticalSlabs = true
-	#Enable concrete walls
-	enableWalls = true
-	#Enable concrete cake
-	enableCake = true
-	#Enable concrete fences
-	enableFences = true
-	#Enable concrete slabs
-	enableSlabs = true
-	#Enable concrete ladders
-	enableLadders = true
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/the_bumblezone-mod_compatibility.toml b/configuration/services/configs/minecraft/voor-kia/config/the_bumblezone-mod_compatibility.toml
deleted file mode 100644
index 5f599b6..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/the_bumblezone-mod_compatibility.toml
+++ /dev/null
@@ -1,262 +0,0 @@
-
-["Mod Compatibility Options"]
-
-	["Mod Compatibility Options"."Productive Bees Options"]
-		# 
-		#-----------------------------------------------------
-		#
-		# Allow Honey Treat to be able to feed bees and Honeycomb Brood Blocks.
-		#
-		allowHoneyTreatCompat = true
-		# 
-		#-----------------------------------------------------
-		#
-		# How much of Bee Dungeons is made of ore-based honeycombs.
-		# 0 is no or honeycombs, 1 is max ore honeycombs, and default is 0.3D
-		#
-		#Range: 0.0 ~ 1.0
-		PBOreHoneycombSpawnRateBeeDungeon = 0.3
-		# 
-		#-----------------------------------------------------
-		#
-		# Spawn Productive Bees in The Bumblezone and from Honey Brood Blocks
-		# alongside regular bees at a 1/15th chance when spawning regular bees.
-		#
-		spawnProductiveBeesBeesMob = true
-		# 
-		#-----------------------------------------------------
-		#
-		# Blacklist what Productive Bees bees should not spawn in Bumblezone. 
-		# Separate each entry with a comma. Example: "productivebees:iron,productivebees:coal"
-		# 
-		# Note: this is only for the entities. To blacklist blocks as well,
-		# use a datapack to add blacklisted blocks to this tag:
-		# data/the_bumblezone/tags/blocks/blacklisted_productive_bees_combs.json
-		#
-		PBBlacklistedBees = ""
-		# 
-		#-----------------------------------------------------
-		#
-		# Spawn Productive Bees's various honeycomb variants in The Bumblezone
-		# at all kinds of heights and height bands. Start exploring to find 
-		# where they spawn! 
-		# NOTE: Will require a restart of the world to take effect. 
-		#
-		spawnProductiveBeesHoneycombVariants = true
-		# 
-		#-----------------------------------------------------
-		#
-		# How rare good ore-based Honeycombs (diamonds, ender, emerald, etc) are 
-		# in Spider Infested Bee Dungeons. 
-		# Higher numbers means more rare. Default rate is 2.
-		#
-		#Range: 1 ~ 1001
-		PBGreatHoneycombRaritySpiderBeeDungeon = 2
-		# 
-		#-----------------------------------------------------
-		#
-		# How much of Spider Infested Bee Dungeons is made of ore-based honeycombs.
-		# 0 is no or honeycombs, 1 is max ore honeycombs, and default is 0.1D
-		#
-		#Range: 0.0 ~ 1.0
-		PBOreHoneycombSpawnRateSpiderBeeDungeon = 0.1
-		# 
-		#-----------------------------------------------------
-		#
-		# How rare good ore-based Honeycombs (diamonds, ender, emerald, etc) are 
-		# in Bee Dungeons. 
-		# Higher numbers means more rare. Default rate is 3.
-		#
-		#Range: 1 ~ 1001
-		PBGreatHoneycombRarityBeeDungeon = 2
-
-	["Mod Compatibility Options"."Buzzier Bees Options"]
-		# 
-		#-----------------------------------------------------
-		#
-		# Allow Bee Dungeons to have normal unscented candles./r/n
-		allowRegularCandlesBeeDungeon = true
-		# 
-		#-----------------------------------------------------
-		#
-		# Allow Bee Dungeons to have scented candles that gives status effects./r/n
-		allowScentedCandlesBeeDungeon = true
-		# 
-		#-----------------------------------------------------
-		#
-		# Allow Bottles Bees item to turn Empty Honeycomb Brood blocks 
-		# back into Honeycomb Brood Blocks with a larva in it. (affects Dispenser too)
-		#
-		allowBottledBeesCompat = true
-		# 
-		#-----------------------------------------------------
-		#
-		# Place Buzzier Bees's Crystallized Honey Blocks on the /r/n surface of land around sea level and above.
-		#
-		crystallizedHoneyWorldgen = true
-		# 
-		#-----------------------------------------------------
-		#
-		# How rare are powerful candles in Spider Infested Bee Dungeons. 
-		# Higher numbers means more rare.
-		# Default rate is 2.
-		#
-		#Range: 0 ~ 10
-		powerfulCandlesRaritySpiderBeeDungeon = 0
-		# 
-		#-----------------------------------------------------
-		#
-		# Allow Spider Infested Bee Dungeons to have scented candles that gives status effects./r/n
-		allowScentedCandlesSpiderBeeDungeon = true
-		# 
-		#-----------------------------------------------------
-		#
-		# Add new trades to Buzzier Bees's Beekeeper Villager.
-		#
-		allowBuzzierBeesTradeCompat = true
-		# 
-		#-----------------------------------------------------
-		#
-		# How rare are powerful candles in Bee Dungeons. 
-		# Higher numbers means more rare.
-		# Default rate is 2.
-		#
-		#Range: 0 ~ 10
-		powerfulCandlesRarityBeeDungeon = 2
-		# 
-		#-----------------------------------------------------
-		#
-		# Allow Honey Wand to take honey from Filled Porous Honeycomb Block 
-		# and put honey into Porous Honeycomb Block without angering bees.
-		#
-		allowHoneyWandCompat = true
-
-	["Mod Compatibility Options"."Resourceful Bees Options"]
-		# 
-		#-----------------------------------------------------
-		#
-		# How rare good ore-based Honeycombs (diamonds, ender, emerald, etc) are 
-		# in Spider Infested Bee Dungeons. 
-		# Higher numbers means more rare. Default rate is 2.
-		#
-		#Range: 1 ~ 1001
-		RBGreatHoneycombRaritySpiderBeeDungeon = 2
-		# 
-		#-----------------------------------------------------
-		#
-		# Spawn Resourceful Bees's Wax Block as part of The Bumblezone's worldgen.
-		#
-		RBBeesWaxWorldgen = true
-		# 
-		#-----------------------------------------------------
-		#
-		# Blacklist what Resourceful Bees bees should not spawn in Bumblezone. 
-		# Separate each entry with a comma. Example: "resourcefulbees:iron,resourcefulbees:coal"
-		# 
-		# Note: Blacklisted bees will automatically blacklist their respective combs from worldgen too.
-		RBBlacklistedBees = ""
-		# 
-		#-----------------------------------------------------
-		#
-		# Spawn Resourceful Bees's various honeycomb variants in The Bumblezone
-		# at all kinds of heights and height bands. Start exploring to find 
-		# where they spawn!
-		# 
-		# NOTE: Will require a restart of the world to take effect. 
-		#
-		spawnResourcefulBeesHoneycombVariants = true
-		# 
-		#-----------------------------------------------------
-		#
-		# Add new trades to Resourceful Bees's Beekeeper Villager.
-		#
-		allowResorucefulBeesTradeCompat = true
-		# 
-		#-----------------------------------------------------
-		#
-		# How much of Bee Dungeons is made of ore-based honeycombs.
-		# 0 is no or honeycombs, 1 is max ore honeycombs, and default is 0.3D
-		#
-		#Range: 0.0 ~ 1.0
-		RBOreHoneycombSpawnRateBeeDungeon = 0.3
-		# 
-		#-----------------------------------------------------
-		#
-		# How much of Spider Infested Bee Dungeons is made of ore-based honeycombs.
-		# 0 is no or honeycombs, 1 is max ore honeycombs, and default is 0.1D
-		#
-		#Range: 0.0 ~ 1.0
-		RBOreHoneycombSpawnRateSpiderBeeDungeon = 0.1
-		# 
-		#-----------------------------------------------------
-		#
-		# Use Resourceful Bees's canSpawnInWorld config on their bee data
-		# to know what bees to spawn in Bumblezone. This will stack with
-		# RBBlacklistedBees config entry that Bumblezone uses.
-		# Bees blacklisted from either will not spawn and their combs will not spawn either.
-		# 
-		# NOTE: Will require a restart of the world to take effect. 
-		#
-		useSpawnInWorldConfigFromRB = false
-		# 
-		#-----------------------------------------------------
-		#
-		# Spawn Resourceful Bees in The Bumblezone and from Honey Brood Blocks
-		# alongside regular bees at a 1/15th chance when spawning regular bees.
-		#
-		spawnResourcefulBeesBeesMob = true
-		# 
-		#-----------------------------------------------------
-		#
-		# How rare good ore-based Honeycombs (diamonds, ender, emerald, etc) are 
-		# in Bee Dungeons. 
-		# Higher numbers means more rare. Default rate is 3.
-		#
-		#Range: 1 ~ 1001
-		RBGreatHoneycombRarityBeeDungeon = 2
-
-	["Mod Compatibility Options"."Potion of Bees Options"]
-		# 
-		#-----------------------------------------------------
-		#
-		# Allow Splash Potion of Bees item to turn Empty Honeycomb Brood 
-		# blocks back into Honeycomb Brood Blocks with a larva in it when 
-		# the potion is thrown and splashed near the block. (affects Dispenser too)
-		#
-		allowSplashPotionOfBeesCompat = true
-		# 
-		#-----------------------------------------------------
-		#
-		# Allow Potion of Bees item to turn Empty Honeycomb Brood blocks 
-		# back into Honeycomb Brood Blocks with a larva in it. (affects Dispenser too)
-		#
-		allowPotionOfBeesCompat = true
-
-	["Mod Compatibility Options"."Pokecube Options"]
-		# 
-		#-----------------------------------------------------
-		#
-		# Spawn Pokecube's bee-like pokemon in The Bumblezone and from Honey Brood Blocks.
-		#
-		spawnPokecubeBeePokemon = true
-
-	["Mod Compatibility Options"."Charm Options"]
-		# 
-		#-----------------------------------------------------
-		#
-		# Spawn Charm Candles in Spider Infested Bee Dungeons.
-		#
-		allowCCandlesSpiderBeeDungeon = true
-		# 
-		#-----------------------------------------------------
-		#
-		# Add new trades to Charm's Beekeeper Villager.
-		#
-		allowCharmTradeCompat = true
-		# 
-		#-----------------------------------------------------
-		#
-		# Spawn Charm Candles in Bee Dungeons.
-		#
-		allowCCandlesBeeDungeon = true
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/towers_of_the_wild-common.toml b/configuration/services/configs/minecraft/voor-kia/config/towers_of_the_wild-common.toml
deleted file mode 100644
index 68b08de..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/towers_of_the_wild-common.toml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-[towers]
-	#A list of biomes where the towers will not spawn. Default: Rivers, Beaches
-	biomeBlackList = ["minecraft:river", "minecraft:frozen_river", "minecraft:beach", "minecraft:stone_shore", "minecraft:snowy_beach", "biomesoplenty:gravel_beach", "biomesoplenty:white_beach"]
-	#Make towers spawn in the ocean. Default: true
-	spawnOceanTowers = true
-	#If the Waytones mod is installed and this is set to true, towers will spawn with a waystone at the top. If the Waystone mod is not installed, this will have no effect. Default: true
-	waystonesCompat = true
-	#A list of mod ids. In each and every biome added by those mods, the towers will not spawn. Default : The Midnight.
-	allModBiomesBlackList = ["midnight", "the_bumblezone"]
-	#How rarely the towers will spawn (low: common, high: rare). Default: 20
-	#Range: 3 ~ 200
-	towerRarity = 20
-	#How rarely the derelict towers will spawn (low: common, high: rare). Default: 72
-	#Range: 3 ~ 200
-	derelictTowerRarity = 72
-	#How rarely the ocean towers will spawn (low: common, high: rare). Default: 32
-	#Range: 3 ~ 200
-	oceanTowerRarity = 32
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/travelersbackpack-common.toml b/configuration/services/configs/minecraft/voor-kia/config/travelersbackpack-common.toml
deleted file mode 100644
index 44a5e95..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/travelersbackpack-common.toml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-#Common config settings
-[common]
-	#Places backpack at place where player died
-	backpackDeathPlace = true
-	#Enables button in backpack gui, which allows to empty tank
-	enableEmptyTankButton = true
-	enableBackpackAbilities = true
-	#If true, backpack can only be worn by placing it in curios 'Back' slot
-	#WARNING - Remember to TAKE OFF BACKPACK BEFORE enabling or disabling this integration!! - if not you'll lose your backpack
-	curiosIntegration = false
-	enableSleepingBagSpawnPoint = false
-
diff --git a/configuration/services/configs/minecraft/voor-kia/config/wstweaks-common.toml b/configuration/services/configs/minecraft/voor-kia/config/wstweaks-common.toml
deleted file mode 100644
index a60ab70..0000000
--- a/configuration/services/configs/minecraft/voor-kia/config/wstweaks-common.toml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-#Server configuration
-[server]
-	#If skeletons outside of hell can be transformed into wither skeletons.
-	allbiomes = false
-	#If stone swords that would be dropped are deleted.
-	delswords = true
-	#The 1/n chance for a wither skeleton to drop a fragment.
-	#Range: 1 ~ 32767
-	fragchance = 1
-	#The 1/n chance for wither skeletons outside hell to be transformed.  Requires allbiomes == true.
-	#Range: 1 ~ 32767
-	allbiomechance = 1
-	#How many fragments are required to make a skull.
-	#Range: 1 ~ 9
-	fragvalue = 9
-	#If transformed skeletons are given bows instead of stone swords.
-	givebows = true
-
diff --git a/configuration/services/configs/minecraft/voor-kia/defaultconfigs/solcarrot-server.toml b/configuration/services/configs/minecraft/voor-kia/defaultconfigs/solcarrot-server.toml
deleted file mode 100644
index 86ba950..0000000
--- a/configuration/services/configs/minecraft/voor-kia/defaultconfigs/solcarrot-server.toml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-[milestones]
-	#Number of hearts you gain for reaching a new milestone.
-	#Range: 0 ~ 1000
-	heartsPerMilestone = 1
-	#A list of numbers of unique foods you need to eat to unlock each milestone, in ascending order. Naturally, adding more milestones lets you earn more hearts.
-	milestones = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80]
-	#Number of hearts you start out with.
-	#Range: 0 ~ 1000
-	baseHearts = 7
-
-[filtering]
-	#The minimum hunger value foods need to provide in order to count for milestones, in half drumsticks.
-	#Range: 0 ~ 1000
-	minimumFoodValue = 4
-	#Foods in this list won't affect the player's health nor show up in the food book.
-	blacklist = []
-	#When this list contains anything, the blacklist is ignored and instead only foods from here count.
-	whitelist = []
-
-[miscellaneous]
-	#If true, eating foods outside of survival mode (e.g. creative/adventure) is not tracked and thus does not contribute towards progression.
-	limitProgressionToSurvival = true
-	#Whether or not to reset the food list on death, effectively losing all bonus hearts.
-	resetOnDeath = false
-
diff --git a/configuration/services/configs/minecraft/voor-kia/server-icon.png b/configuration/services/configs/minecraft/voor-kia/server-icon.png
deleted file mode 100644
index 934c5f41c6a1f7e746dac917e370e52202e738df..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 23263
zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4kiW$23787oeT`BCRHI3B|(Yh3I#>^X_+~x
z3MG{VsS2qTnQ06R6}Q&T$=)Punb-3Fy4IeSN3&!2<_q3yoc><_VDY*uufFxjCT2$M
zvg+5G#2_@2A#2{>`2Usj{yzw>o?V}$Wx9P%eBDv8+3)`Z-2a_@WB$9|Z_EF7&ENjx
zdwg7d-MtTcM1EM`sW<yyS^Ifco!$KF_U486&)4gJ`FpUm&TId@7x(ph_V2UX_kC@B
z+>6ak5A4e0=Iht!iTtU(TRY9}^Iz-jQU5k=y;^_!&~MB6=j(44S6T0V#BF_6asHkk
zb3f^o-Tb(7W!RrTKbvGT9^ME~Qat!uHm2g|W%l}Ti7)fH=k8~&e-*p!>xV^u58u-$
zd!e89Mc;n+d9!oZyJVicfBxz7_ur8h=kNdbblR)?u}=23|DOok+y8wi6!UDK+`p`i
z=JnxI{{L%>)&2Xi>c`IB|9_7ytq*_l|JO0;z5h?g)o*@cxq9B__wTCC%uv0*cIW)H
zH~eb^=64_5H|=Na5B-nD8}GM>+J7&96#jbdkLM4bKl{^su&+CB=exe!-@cbjR(0E7
z`!N5#`n7A>rXu(M9NDGk^0(~x^b3c$On<2R)Tn&e^gptD^KY}=_e-W)>mPUD`#8z(
z-xvS=^Z&o>{r@_D_XW#f_b2y$6^E@k%{M3YMA5Iw{)qzRcImUuWbWJl|Jj6de{4S)
z$`+?K|CRkNq`WhJpXix$jptSW^?i3*x8^*nh0?pZ5k1@y56<eTOurkwNB>-5pD1%_
z*gNMh%-lPs{7IT<XQ!Cb6TJ7`+48Q<=YKtUe_BDU%|o%hDL3kcg!ZwP|5GA9E}ZAo
zrMdLal1W)vD}@6mW}MoY;+U_$@W>=Dy`@(!d97b~Y*yB~rPpp{<?myiV7c{<*Xp&l
zYs>R)?JRkId#?W%yFVPteI}nY7WbL`I#Qc9C-Yfk+T7f4Ps1Y;crV6;#quWH&U@@-
z{ca2A``Gf^e;;J4&#Aa{a`~L9TQBXyen)&=zkmLH!>9M7&epDZb~fl&%+FNQIK8LU
zoaz>yn<T|PUrhX{#QoqxoLTki?u)03Hc75*Ti`Lzb(#CINI$X95-Ha6`+je{tAF}$
z^ln?t|LfmA`#<%m+{}0X4;S_Ov_Jiqx4nMDtflKR#dZg-Fs^03Sbk{oB=3K3FBaNq
zPIB0u|EE7B`p4>PkACYV>V2EA$A0PbS6S-HJmUP}UVpsjZ;8mRGB0A<vqjCb@A2(<
zd*?Xxd_H+B^2JvR&)Bv7+xu%Dt<i1SR&395ck}nC$=YmZ?g(?P_-0U^nf`NM+R4S|
zjL*N+G~0A3@%!&B2TQ%*oh>Xmy42FCJ}UCuTEXgA<);?KkCfA&emi#M+_zm1cKhA!
zR_>`j(;Djh-8$4Sv3J|)&b@2f>%Xp=op>f7!uxIAB&q4?#&!93Ex)g9-Pt_%UYlUr
z19t_@{W*dQ5<>ewXFn4%xFk0*w{N3`+r#A7Z;$f2cNNO)FW|FT^+0pt_0t|q%jJG9
zik7y2)Ka`g-BohQ<EhCLEzSf?d|YJc%jCuG*S6w~&Xw|I23f~vpUCg@H}(4$8L{#G
z!S8YAm0x2In(GMdO#Gz!_0;M)lg>AOc<im0CMI2;*TU&;$=#Oy`{gG|yYAzYSEbh0
zM;)GhGyhIH&*o{?JJ*&*T#z_g==Nsz1BGK@%GE+m=Nam}?|keDiJEP-v`c^azA_nC
z$qy{+c8Y)J_YAWtQmL7H`S_uQz0b;G{SOFM$rbZCbq2r4PW^UV{P5}0LkUwO=Bt*c
zdhK~o5VG!}&y2liY>plLc<6D^11|ag%+3=%F5BnSwimg5lYMsVc42$)*Si;P?PlEd
z^jlJ?)!$uVH6NCTr5vc*U+37Pb1rdXNzTgGs*1gj4sJiXcVAiPzUNswb@nnp3feau
zzj)6sm`|d7>Rf~W=Ui5bSy>!b-k=(C=-e^Rlq7SpZSpmX?JV@;HvCkHu!!ExCv$MI
zQuvpLaar1~#lqho#of^P-o-4hcU;aa?(>&V-&nph`OD~>tbe^Yf`Oyhs`23Mb?;QV
zmxml+Ryv(?UF+MC!?DTDF&PQBBfqHf?Go8Ly>s$aZ|~%sqw}NZHpClFJY;>Ra^4&E
zf?Hx1D}2}gjX8dkZ^eP~PiMS03JHmc_9y+-W_ZQIJi$O}r_73nc}WZt_StD)wE9)a
zlYPf8b<W)>u5b8aEZBWC8<hE%u<Sg%$ad!H$K2fYi7V%rCMdtDi2HWA^PN${uA3k2
zui0AiTv+#9>wtEy5~oP%&l|I2q!*-bmi0PteS+${hYS9mifR?m|6O{maBB2}cZ&KC
z3TKFZKloWM#P{6+X{Y$sx}y_g>QCscN!(VoEaueXpvKEenhP(q@V7H3O<yxrmu*ig
z^V1zx6YM-PPVTw6wY_$-^6f(LZ;!sDPW#OD?8K(#(DM9$yFRGh(C=23oWEuV+q1}a
zZKsRNk8W^0_<<|=fXB7I$NNJqx{cTVZ9L?g!IWtoemr{4^{VCx>@`eVy6S&PavSG~
zDBjObxe)cc;kjzek~caGk763HUpYBpVMBNGmjix3yMtLG6okHZ?p`j~xWwh!Jd1m)
zqO{C(PdUf1^)QQdyy<FOQd+oiuBf>~*uMlON9{XWc5AuT${c<q!|fba7VyvSlh}qt
z)`rQ&Yc?+sX5M+~vB4Vu@`JPbkE%=v-|(AZGP}aNDI(J+Jvza;Em*nH;aRXBS74dN
zk;AT!%|kP|UvlJLkKnj|m)FOvy}P;PRPRGic8}vrf4H|qamH_1`RdH)C-*bL_S_Uy
zIwTQ(?_ossEl>FZwo3_0ZPuY}?|z?ckdgEFc6_mA<%vLT`Q-<9&)b^gZkWaxBD2K)
z)2<_ynX`)bdOz6b{Cw4Imjf%LTbMS<UiV&5S(&Avz;oi@Er#mqpFTD9HYPm}Kd;#^
zRVN{n(c>k<gC8pIwig*J`0uQDcecdm2T~h2r#>k9*;;**X-BQ}rzg9`Oz!yYJkao@
zciIKjXCDr+E3nN~5NOJft$xsVp~?4z^NE68PV1(YeO_e0penvAA$G=$0=Hnc8MQ`B
zmdEVdY^B3cpJ#ELK{@DFfq36`rh*TTL-e#ieRSw{)VU$~NAL>w^Mjp2ojRwZ6<PiG
zW*Fa|e$uwW<mA3Jnvqp;4eXuoOs;(_+ao%mHBG3=|8k?l+sQFz3pbrgF>HRyTbZ%u
zfNW*6j`HKlR&4*aEP7#)&LFpUc1X0@MgEwhC9}%fYV{J9mK?gSck-a@hl?{SmbNTB
zE1a;S-tpL+9UW6&&2N%Scv@*;7j@w9g5)^?svjh;L@IK8ea^<gAo1eF&94Q51_wT|
zYui0(X;0;RvD4(=?ZdM!FTZuE>frf3i}vKKJyf{v{Pj)I3m#e4-D<t#E5`h=-CRie
zmwH;$!w3E88}BPTkmXBxEYLgI!NzX&(SLhas4YBNX5prE?L<@Im!n_Hwxn=4>Gt(H
z+pQ41;6LX}N9*)&Pj!>!6e2!yPPQ}j**Nj;u6IZ7otU@U$Hru~`uvRDY0{^+8ODe|
zsO<2Uzr2<82Ji1B+Wejuu4?=;DxdmIszv|!q<pq-!HG<-p7KY2F1F-r=uLQ`rqi*Z
z^_slN4kfh>;sMG%N?X1ccihx?-7>p()rDXV)}<Tux4mfn#?b%gMs~KhrU`TX59L#5
z_%C)iw9QJ^|0q~w-zgZ>u=?SxB<?*Ip9-W12o)x``*XWY><{GAc;v9|g!7H_;y;D%
zE9qDYZ7ONY_w1Y_J(D>woRM?sf6E)U4!sGyxw5B?OF6G&-xBTuwhc|SnT!Gr%R5@4
z+~&6&I&wvaIX~k$<N5D9*KJ*w&A5ERFT;}p8M750R<4`+)Y+oWUgfz@)J(1ujJqBL
z@xT9kcY?IgjvYo5S_|@C{>y!r=Q861%k_m7D#bsqFwCej{%(`P_V;f{Ym<?h`mTo$
zk48-J`*TM|VRdeW?9I|-$)l@X84vO#dhXfqVaw+g+X}W%@%SY8z-=bet_t3tf%hC9
zJig?*t8wd^IY|ux2fGw|nzl$c^KU%8I#BE4Yt;g#DVJ*xi`D2#aCG-2@UM(;S+2s+
z@ug<hf^9dq-jLEhSx~QXjyGDuKUQ=<yWNGC!JZwdoH9#X=K4)vz;yX*rRBbJFIBDx
zuF&&l4@u4vm0>OJ(A;TqO?SD8vwV@aN8UoojmDL%Vl9(5Djal_<o7=Q*UfZCZd0@<
zuj7pt=8o<bFN-RU&}PpKa@W+(sYRzp2*q`o*uNFL)Nt>CO$W#Ci4wLsg?>|PdH%Eh
z<cV<A4*xjGocm1Hu45iC;>(q-ZN$R2Zjt7+eY7#Ov*qwa4_5_&eSr_7Js#fbUYdI4
zlb?=D*NU#0_N<0m0z?i-bNx(um$W_cx45-mj)1P~#?lu)(;ZrF9{MlprJut4(J;0~
zq+Y?akNt)2inm6q_*gb7$<(a$S^0UY{VC&RHllURJEgg^CalY=V!1i(qvym3=JxI9
ze|&nTwWw`2n`a6K_ojJw<!Y~8>OC6aF8c7*!-JN=liy9qQtjTf_PX}zw$88zRw~EW
zK30~PYh)TS@$cbD>8ug~{at@~ugLAGUH`gb+98Ld2|c~e9DM%1_kU~asuV3XO7VOa
z`*QM<OU<&@Z{(T}uMPe3==ZUA>sKlA*8Hq?Woa{ru>Ha|LBH&mH>>uKqs=yji&w^N
zo-=ucme9*NMK{ELznrp%r%3pXmU?c-;p5NCLzYc0I{4ya<<TQ$M>Z!cywDYuV=U&G
zJmW5>e@g%1$mI=J9T&!_$}H%${+P&Qsr*Nz{7&sgVW9(;*ad|4=+BN%oH})9|7-TC
zdT$k#xI2{uj$CD~Ot7z!$^Yt=y!}K2`wQh0Gyf=cM1)R0z%(cE#t)e#C;a#g*Nd>q
z-_Dr*tKh^Ytye+sd@ntGaZ+c(^us3;y_}^B7WKsm6*LDun)3DDgx*%k1^X12EUM<c
zf9H_qqRj;v$Lc$RC72~+swd9<AaZ)o6XplJZHW%i?^+M6*3VRWCVs}VJ$6d_p;qe^
z#*MQdeDkoV>C9+oo^ZW&!hC<56TLankCOrd)F*LVF!{k*qUaKlGAs6GY3;pJY2UKc
zO+yqMTYDAFm=35M$<f|CX;NZEm9$$=h)Os2{8>M2Tns&IURHD@Jh<d3=RVc(Pt}ff
zTIF+AO}e*1tG}~LcV}xd*UXPIRs`L+s(izg?@&f+{S(GRTmQUJJG*mzgR)<2LpOs<
zLk|1Z4Hni#E!y$*>~))5&M7>Yo&Ad?nnVA9+C<f+dmO6gj+Sp(y|GHBA*1mZ^Qjp#
zr<}f<n7FFc><`2H;4QqIK}PSH4fqmgUF*nAwYLzLtlA*;GURAPBIg2`%7vQws>@lJ
zWV?<UaK%2B|7h=YBPe#V$?08NTU!GbFG}i}aQOIgFH_#S$3d@!SFM@qe4EE#PQ#h?
zRB;%SvbuJo=qFt>$Jpq*hZfIEN?Lq*%c52z!%xrrc8Tb9r3-CwEtT?1*K*Fkx^Znl
z*y5`zPUy_o9?rAu&g{H9JVo!l99yHk%Pza{N;gcN+#2}et$Ig57Q-a|yN<gzo!aNX
zAa3G+Y&-KLBb5$Caiwy*cs91br}DI!|18O9aVVZ(R#a$k$^F8^f{42ldpY8?V`ilU
zzYE`+n_=r2sw*QK^KDhcv&F`*jTnrWyM>qWHhL-XpJFpmFIXe6Waab^2jW5l_r5-0
z`LkkU%_@!W%l9M{<aY^w4zFoD{Al~CGc})9gt@KQ#@_$<&6{2Nrv(=OnPM06=i9`+
z4$-0c#%Hd~`nm7D)11WG))jYrE_|Cbdt0}YaY%%de>>xYSz1S(wiq`~Ph|h_dEqyf
zjCM86S{G3^pIcv+t7T+fyv6Gr8Y-2N=@8VJyJ3~U!QeeD5xY)`e0V2wURQ(VA=|u<
z5$C*uc3zrsb1`p$-6qY8xAz@gZMyqiYJ+@|@Fd~D0_VE6<3+6>4k~N=?_I;2TrxLR
zaQc+Q=>DHt3vv{!EvKYieOdVI?hVm8Z<)z9#kX3|2&(72Exjan$xY(m-;h&{Yf|dc
z12vD%^js+XRYCLCHuZlO&%P05JM_~lLD=Kn*{6#{%A36xsI$yp<#Y06w4KMB3x^$c
zWZp@RF?D`Z;eLwk@~QA$(O!xrEUZ8N?N-^l-{^yT(Gzjc4^!fLHCL!L+&;4Om!XQ!
zIkoLuerV3wkR=|*?y~3;yT0%gZp+XX^Uoi-_?@};#m@aD5}<hU=f88V923s3*I*QT
z)NPtz!}m>os`ZJuFzFLtC+2cQq%8k2|LVPkEgy14%vT(;`o?$3FiE~h@P)gJQTpW=
zfuzDMmBJ~v);xQ={f4MT!BV^0mt36(e{;wlQT?yMmF2M}R4SzE$mtI!ZpyRVD@;x(
zv*@yXDJYa<T)z92^v<1@!pwZ8?#rI(UXc;cQ}kC}_hZ5V(RAmpjM@5Eqo+Rzxge(D
z$#`XBp4j!TDc0v^zGyC5d3D2)nx93Fdrs(GHd5izVJ%Hv6T4$-Ku>3m7|%hSFwG$4
z<9v+L8+E?;xhd%L+e;lYVG)QfEn(quIjY=HlTooM*jJeEt&i1l!@m<B<S8u*%e^bX
z>3dp?%WK`ymi-H4TA3@_uFT3xoBDTudV!S8yH5|MRooPfSR{MtFl&eJ`KqZOu1?Wi
z=RJ>`OY}*4)V=uD(~BiuU%143V+U_}Bj@C!Aq<<8UIjZ$TlmXe{fx@1Y0rIrzVlX7
zxNYet!+tNUbL!q_%d4tvE{4h^u0404#;WM_D)0Swc&);t+0EKK>K}-l`;u!dS~Q_$
zgJ6baiCFu=I<I>YzXiV@%++fQ&YQU+*J*Ehsr`ekL8Xrx-5aWvF7^~Y)Ai60eY|1O
z^i8u``i<{PJ=t#%$|(5$cG7|!r@9wE6Ww_C(PeMR*%w+k+7$GbFIe@uGcMZVnB>yH
z?Vp(18`GYZ8X8XyTd`%u9bFOE%IDD<%Ih~oTmNo<5-Q5Qj9W3N^@YKA_Z>6WDLUm_
z#^oqI>H1L-I%(#rx|8W^>q6(h;7BkH-+Z(qV*V7NsER#HL<?6hlUfws>F(;f$06uY
zWbYbpANNV_RS{)H>$SMGj_jNBdik#xj91cP4_~>zQ18_0clvtPoW^`9S&mXqgnSwM
zd6-<)%a4B*F#r8H>B+5*rT3Pcdb3<Z)HTxM&6<B_ms#k(d!T>*VCilJ-CU-4)|C0_
zXM%G>e$0QObZWNk%J9Fdr1-v`+q}0=Ube(~C0o!j=9%30#Z02EEIj$(!#mT92QT&L
zclN&P+7Z}zY70kIc%|XS1o4A+K1kTR#IM?Bzt(;k&(64F^V1S;=iGc`--rta{5^jB
zY1<>C#jYnW@$&sN+%|Pfd&u9}yB_ZepPn-F*5^GbL7k<)7Or}9X=kC!*Hf>OW~`mk
zSr-r@D>`3A-|fkP16dL)`=>tc&w0%A)z0JR^RN#sf-{7UsLU1ElE`_Xc+Ll-PC@In
zYr<p&k3N;*Sn;b$e9z=vhfTyh*bdxUZnm}jc}<p!-m*KprfhunLhY7=>%B^C&82L5
zi&?I(xyQ9#u~#8-m&8qx(}r&<kJS|V30fK&1uechGpXgku2&J?u1G(fbb7@~<~eg^
zeYbLM<`Gg!{=PU%v$H@d_t5NYC58w)Gyg1|3Cot8U3!x<-Em?9b6=0-tX=E8?i_DF
zp7GS^@4TwlS|?0fw*{YF&>ZUZm{D<W)0JzJ-aO-KTFBQQUVFND(uy|;XS3Sh1w`2t
zHT&QH72KhJL{?(`o9B!Ln|&N3HXdKoB%m&1yycm~(mu=8R_QU@cQ81zEfo9jwyY{u
zVA4c}$S)@st@getsw&~JHuP`O?#rCVyX{vWGm27P9GNX0#vGY>_R8T#zWwbfh9)-_
z=!dh+*kaxnIWN^zA++q!myDM=*VTmuQWtUETW~t{#{TERf`w~$osjiDp&G`+wd)M~
z<wxh&3zt4Lo{<wB<HeKm<Gk7mOT``G@_xz8En&Sbj9g*HRx*{L{U3L}HRdm1P_DHS
z3Tjk0e|_Z+uZC{)^T@3?6(f^<zLnknBA*~VzcM@EmDuJ>{>njbMXvmk<ZVoTn*Jvz
zzwyDz1g1A73r|i@>v{0SX^#7@tk~F6o+mfV*C|f2U$<hHOr|++K0`#}gxgo_y|iN9
z{mk5KAKN1H>gm#xb)nOm*trwl1^?rJd~$EmC8+}f*OUa5+9pQ??rqH|?(Yw~I#YJF
zxcBO3_8lpuVJD66b+x%S&nVK~mYlvgk>{-UouWilmo-LfEYF<{+Rnjjv!wLVe~*HU
zTh4OJ^g6nJG5-(JJ?0f3mJ`-&)6*`zX~Le+gpH@K?&tM*Z8hmYj_Wke)&BEu$sQ5%
z$vjy)o4?`L-GgFB+SpnX%5I)|m1WuSa;BBjdyn-CCe8M*_Swsy5g~bfmx0WTrf<$W
z{}$xtrnES)F<gAorO~~HJNzSuekjY?ziU`ZCS*xX3u3mkbCpr|e{9iIo?h$m$Nuo=
z!sfN7rnen?!ruG%g5}Dq&Br|NuKx8*fL+Dohh@jUwSVt;?M>}U63Jg}bE8@RYI7c!
zZA0vn-RXxLt}?`K5Pc;!?~`wn=E|_8t7`M_rB6*{G!R<A+Q{0?9JJ`#Q@>r0B_4Ts
zZFOhfCF{lP)!EUJ?3Apv{^2EwYpWgG9^JU6#^`gUK4_y{V)x(5z^Bvo_-3{{Mb_w8
zy|yd=dUQ>E;=!XQEmqIVIL7sS&b68PS{_%|zhZg!>9F{0^?Mt4HeXfzv375V&k?p|
z(^$GB96p)Nz2EUjO`U)7g%7@bv*&2e+Ho>FLeoQ@(OK!f)?T)g^Y0$e`?RP%YUzdI
zD>h6s<%`w`@-gMCb7wWz(OkFs*4l}&b44GmY?A%4_4Ur#IuG35gniUVW0joH(X8gZ
zlws?JPqo>Tvn<Oh41Js~ny$SmqTBLATuL)4{%vTWd7s`r+p9Y99c|xkw10j(_wF~|
zb<FBdN(%IMH->(kxbJ~0LsVegg{GB{HZ#U<?7Ph@*q^o9<n`kwk%@=HAN^(EEm6AX
zm1_Kd)5b$n?ndS8%U%+E<L5%tUjO+yN4amj=$Grew#Q4+ePbl=9af&zryMo*H22)F
z3c0KIg#BHwka+hxndxmIBIivfX(lkrvR&a(IlkvMyOw9g=W|JnQX5wuxSaU!$L>|k
zwf+TD9*dlKmV20K-=gyCrMs5;9cVZ7Y+$!j-Lc(f^M0*p<%aipEi5hJhv#Lzi;mcL
z$!ePBS`C)VDr?;XrPxa^KD;6pYG1wV+8PEPt!XPtLRV?ZYd_HJ>2zGUzv>YKqo$hH
zr8(z{oHYBb{I)G(j8fy>ZYj-uXvV+3Nq2WWZ=G>rTh*QNHWSsg>t{%;ncx$WSI5DB
zW!kF=r(aE2G$X9tCqG2ieD)ooNU`j&h1VnJmajAr^Ne#|?7Y+_Z02prx6dYfY^l;v
zdc>m1vn%4nx%U^G%I}}hv!7V|TET6L$Spp}OQo|Mtt0gpXdG2LAL3cC`iQpcqM2=p
zudEiYd${2di)iG>2|IlDt-2L!-KS-l{+5TuI_kmc+a}x=`JHE?-O`!M6P$P2?s&ee
zw$$I)%xU_Q?Pp$G)w&?9)&F_ovLvyE6Rwm=i<NLieGD~_-hKADS;m#1@Ls>;D<|4b
zO<Sn)L1OCHKd<eY^=F)UXr6I4_wKg**~O7R4Q2|kKHU%<kSk|+#YV<cwX*Ni*-3W~
zO-?%6vBsz)D0uJAl^J&=cG~H68o$(iTKRMHvwI&zduvu}UYM{b<K|oTkL)p78Ujlu
zOZHtkQppf|*wUfxwI9cGr-IbONoQ48=u7357e(InXkPgDL5lBR|L*jk_dd^_&fsNG
z#&5KGcH*N0UE6m!mPi@hJAHC}o9P{e;8`BbIx5RgD|a%*?H1U!hbKPxu}l!}c868{
z>!kSZ?0?ktJbi-WW91#QB^=hyYO?F+ZB;yN@@<9UXGNE}HTJ9h70w2pT5dRP4!_Q=
z14RdTul&g9o3n=Pn6jAFQI0nL4%^TJZ*NJ}|9lp1$Z+E9pEEH`r2!4AZZ;}6<{n*m
zT&=uYUhcqOADgcqA2u^Tt%};TY4yUc5SD|_CQUI5@!ovnrd90kM%T;`*QpPGteUk_
z=+lK@Mn~f-p1O@I4(gYNrgywJbi-nk_rs`b608i<=fC^uWnq>ezFTeg$GRB>!7DvF
za^H3rOB)HCSYV{sSj#SP=g*bw%fZ@h87Xcdy}lQ2cVtKke|DY0KT~o4^K+h-xz4;C
z922v2giIPLLlosC482}l?bN&`c8!5~NBD;58G%##9@;ZA9S>9WRZC|mXti|OvU#3B
zj*0kP4GXb+@$*;rwp}&T{hEH7H#s}#>`RX?Qw}suymh6WGjB$H@hts|&u-`Lk-z*}
z_~*Pe>+d%4N(w0d;+$P^RcQH=C2H>l4##|t{CZA&;cwH!K^`kO%T_1Kt~blt_;A^G
zr|cl@O5WL3r?ccH_1*qDb$K>Nv`^cNo6ZfJ_dc^K(v5k`*R+c7ddR$hwO`KFubSC8
zMR~_v?m%0vD2L4vo4u#XuXCOAbXMe^&9CNd_h&hrsjBh9ce`9@(8`4@p{H*Ja_@>}
zo4vp`+kREw%H$2prp8EbEI)YY{=2-aK8YDJORM(jN_1;XbN!IEe%;d_A`>|#ylC1L
zSX4J>(d$W?y4#n3>L|Fw_VcK!rJK2xT5Vgx*_#K>{1e%I`cj61*u*(LqFdQB`D(Af
z2(9WkxNO75DcS$p_uH6;Zkp-paY42HtlNsCCbOe6F086-w&rwsWY|@`&>;6vwueB&
zj>n464^Q?@Ut*snu*z#&?7NKC(sd_8y!{_fxO`79f3LC7%eik0RqMKDzPh^k=dawh
zFP?`&yY*|MYL4X2-nhzO&8fL;C+(c~9@yn3d5ZT6LuO#?v0o>i2yocF*lTCJPUZY{
zm;QOpf;awMeCg)2V%8E#w%Jv_FOA=>UiY<j&aq`e)jIbrFWOr<m&;h#tz8|En#$5!
z)4is`a^Wd9*Uj^)0@UkQF4b^4Hbp7>(aQ2yj=igvXWuF0usXK=X2_H$pO#j4J^IF|
zpC?{hc!1k(lS|vJD<(U-ezE9sp1#>^D8MYX{mPxBOd0;=6Rs*xH_d-K{Yr7p1+#30
z)6XJ91OgA$x>yHESN-uX-jIBQ<&bW%+x(ALe_jsQ(cjtk^;hjXt1zY;XR_sZS1Has
z`k!O9d4`o?M#jlgW)|_&O3EB_T$Q=pZRO6Te$BkBe%0|~iK6yW&t9iZo^v_BUwx9v
z(UDYCb79%JP&1((j+~3`OTX2$tA8xEW&Yf8@>#LyHQByEg*LYPn<w?jS_iE1vbgtO
z^ynMO9M&yNkBoh6pEj4?PqQr&J+L|SyP%xHr8R8JZ+nIOm|$w~v9)~d>kh5NwbmVG
za=gJU)29f%&dJH!I=A)4k>7&vEo^UfoQsvefAMg_OrL<GyrvEdm|U#<9bZ*S=)8I0
z{bPAr{lbsI|BSNPiahnj<=^j^e)j*0J-heWKKxlB+P#YHlY(EQqwkxVw2E9YZ{hX!
z%Dr*5i}Q8uZ&_$Wwl8St-63F_nNYCXuC&9tZt4mCj+Z_xqMv_;)xTD@TwZiW*5t7q
z|H-`zl@=_T^&<T0v*-_k>id#p8djCdnB0A6$mCkrGbhyk?yZ*oV>>@SKgG0KWK!RQ
zU{%$c=^GN-{dvR|{rmGkwD4Y@zR-IiIoAlWw)lw;`ow-bm;NCz<6rG3msN}*dzFqq
zKKwh)Lb_k+@+AAJ9FDygHnE?4`*5Fm)YKCPST}MSYusPSZ8-a;e%tl#!i+rg`4eq<
zKG_u&yca8ZDE)ZXOrZ%@x4->4uWFv=%cS|)bM=l#Q~Y23zWjUdqLS_Q@*iK+d`)iV
zs18oFTsbd2)Ok~O$%T1;S7eqN&q|r*+g!t$@y#pX`F10wZrP(1fg94ouPOUne!lNA
zv%{T&J*AOfOV7V+3z}ubk(KuG-H#=!K4cb{EtiY@XXk(E_hx0I-rpG_F}kU<&;2bp
z#lpSqnD5r0<!PFaf->(Keb#4_6R*;}@@-pIRY1Sbnz*axTxOkJ<<-1DBDIds?+jbM
zP+63JUAPL<sW#b8(=RPX^Ok+w_;SO#)>qs!QX1<{syY0ss&~@KJf(B{G21Nvp!|&)
z5_0^Gdi!$%TV>U+>Rihe{j>OrnuwFN^Q~Dz`-K8F{`?;u*l=|c=cW@GL5*zTpA_6e
zS9?r|HZd1pv$=r%;o0>eU)~>{^*KWLzoI2a)Y9u~SPzGOoiX>*-mmwLi`RzA2l+Q1
z-4i4n_@AA7`|Jh5SBuNFt0(>be2dw7O-SkX8qU)Jf%opdOZa<r<NF6KcOnB@V|JhK
z4)ti2E309N&UwYW`dpss{-0e3yHYk=D$Xtu@tmP^JJoif&6;y1cP05GCwJ8TyuzpO
z`&BXTlqJ3Yv%WdiChZG0*)PApYwg4}Cst^sZ?TSH6k%hzxFcceu1CR1+~+*@JejC2
zQX9SSbPI#m%p;uftA6bd{9)7CDZkQVxl`t)<OZX8e~u@8Vlrmfd8<5T&Qs^2<LkNR
z?7Dy8MAZ58dlDBuzKY-RD0XwX-Q^E~0$-{vzs{Y0GG<E4rA(K5nLn<yO#Z|ZEv>u7
zs;4rtp`_Qi<@c9|eM)x@F<sX3?SC<)Al>Rw7`K$`Ov_tYS6$DltTLC0+4i$8z;RZ_
znq|w3Q!ZxpM^+Wai0l@2aPqK?S!1+Bu13#~U!(S5;%b+hc?&N(#9h61-)run%Zfa^
z4=)$D+GwiN>QKDhtXO>6uX~2d|9K~#au2`tSnc=EQ@ILz#ICJsdi!>zv#RX87oDp!
zmtHF4T{`iU!pnbWqXPNg+nRBz{au%&wa_AWkyquKMGGuD>L19(9nP<t<1dz(pY?O&
zug-Z23O^TS1__=Exx@U_kn42s=W4sPY_{TxU41@cukQwGuqb;tJ2%H4lZli6vf@r{
zKwry?cH3I^OWX4$yVh^`mvcUb@6i?a<@X-ye0$=!>D{y3T@}95vkm?{?mzwP%9~4}
z>M@UhniVVyoniOrO{R|X_G9lK{h2%a{fbikYQIjMAAigz-7Q>H6MwRvfq}6*)7d$|
z-P1QfA*nPor$je1PoX%--HCyrVovQuTaUvIGDqWsU3Ep-tvf7SR``jzxXNtha$O;i
z)fy)2qxZK-jn}iQd+~#)f)B|XUp;uVW_9yw1&+Fg9Xl;GcX@RF_vX?~vaxt~e0O#K
z?(&8JedDvQB-l;vngw_6m~nDlSL}KYB^E|oiD@%a&v*t2?R)%Mj&a|;qZQNs@3ePc
zKWnpufIw&Z%*0zqq>o&lz3pJ-e2YU}o4jiLY|<{VcFONuSMlfA&Ig+g7%Qh)nfl8p
zigD+z*<z?YOX{OYVaU~zQ{qN)tLJRD$bPDoeQ)x9gE^POr|tAB=HS#x;uLbxSh1+Z
zDCbDVRnLtR7X97PUw`4N_miL#p-jrhnY1n_?5_J@|Ksl3sq^Q2m~^Oc!RMoec5V&p
zViyD!&v~DGJaZ1i!Sn}S`9HNw6P``}66M`3$5?y&z|m6g;BO75WfLBpoZx$NYLiK8
zja-HO;`~!gf44hioPE7^Xa8k(1>acJ{Dx-dge?v?U)#NZm-qhdedDwL>KK0ADk?uH
z$kfEZAP}7y5>XQ2>tmIipR1RclAn~SSCL!500K7l6$OdO*{LN8NvY|XdA3ULckfqH
z$V{<S3ODsN@GWpo&B*kqDoPEm@(W3>%1*XSQL?w=vZ=7D$SufCElE_U$j!+swyLmI
z0-I}<S8N3m)>l#hD=EpgRf_NpP;kyKN>wn?Gto29b*;!OGg7kSQm`pXNwW%aaf2FB
zl#*tvlu=SrV5P5LUS6(OZmgGIl&)`RX=$l%V5Dzkq+67drdwQ@SCUwvn^&w1G6G_T
zOKNd)QD#9&W`3Rm$jro~{L&IzB_%Ee1qG<#nFS@ut`#M43qX9Z@x>)6`kn<P$tD%K
z1+En(`bGu@7P<yTx<;1z$oeaC3w(Xyy7P*mp_rVXt6z~=pl_&Wpr4zIqNBLPwG3e&
zRvpD5l?AE#L8-<0rA5i9u4SotCCbQ_7UYx`BimV8oC*>GyE`W(O}`=+Vl%QHQ09Z{
z0R>}vW^Msk2S_!t%9Lcdx`NW89I%>{Wc}2f)ZEm(l45;BJwp@^m1L$NA_&DlAQ^BF
zARAwiTL3p7MKvtEz>2})YUPrjTne(()5TT^<X)?k{N&6OD=;%T)xyj$ImuMlAlW2E
z*CaJLO*hdjDM>fkB+(+(!pO)x)zk>dD9^m&lEl2^RFF{>xdnQenJHF@CW*;LriLlH
zM#e^Ix+ZA`#=41#W|q1J#+HVONvReFiK%8tM)((Hrf23Q<{-NYWK>FKidAZwiLrU2
zVUn(qVREvrNn(njZlZ}%qONJGnW?d9nxUn+Q5x7NP&`;U26);k8R;1yL;`XWOVaX-
za&47-GV@9+5E3Doxv9Y=iJ(9;G&3|cHZd|Xu&^{YH8z0w4s2dnYEf}!ejdn7Ljye{
zh)hbdm0NyMZeoe8Qf6*qda8awUOL!ZP_$V27iFgAl_Y}lhOLqzSiB;)z{<HOHL)bW
zC?r2W$5shswt|tKp#eBcDcFEAhigTNl}~;$SR+_*YKk2=KY??tQ)0S4m}{etPceo`
z!5R7Gd0>r@oQuaCgi^REjzuNq`9<0OMgB=ysmUey&B3M^Zc<QcdS-D+QKcsVPob%^
zfh1Rt%;J*#qDmzDgHsD3Jcze)GQmNmpa3oetP+zU!C#zMmYM>N0tJ{<az<iadTNTT
z5;Uv9#51uZW0SN*gG9?zb6t}(OJiLVV`Br|#MHz@T|*N?3$wJO6cY<0V^q_N^V3So
z6N^$E(^K<GY?a(Ia|^)nte^o-eVVAM%QI5*Y?ZVP46F<clpxWoKuiA^S{NCnB^ny&
zCM6jf>6#>)8|hjk85!s%Cz%+Vm>U}ynj4v;x{z}J*yw{Qh+t@R*?@{rUtcTa2(<wf
zu~wd-oD^JIP>_?ES_Fw&aKaBxErf)OjXn-_NczF~CZC{oWMvTD&iMtEMVaXtCI01k
zc&*2x5MqK)W^!s?F<!fol|X_8sUEfCQh<mBxwzSJ+315Sb5O+&2@6ogN=ppQKD4w#
zL1EMqlEQa1xJHAEq!1uU@o4HA4K9*GfF#AEsf%jC#f2C#NX<*JRVr7qxAT2sd4K`W
z=#R$4(b1m)82zb#_ToGP0|RG)M`SSr1K$x4W}K?cC(XdXz+U3%>&pI=nTv^wBlH8`
zX9flau@cva66gF}P*0p8DKjszs8S&r!ae$AK@|go0)wZEV@Sq5(_NltawE&sw(Q#b
z{pGv8|Ns8JzF$1oZE~-%veDd^MW$k@Q#Bhyj21ZQF$yUdI`D8ArXHB%q;PPFnw&x?
zBU3P|&=eLAi?=?B>1md8XZpFj?dcHz`0IQ5cI&tIs&(1wf4t!7`!;jU=eJ*Lv*&NM
z`|}`rzuy@jmW~z|9|jK>4hNTx6K7ml7(9;nEMu$xdg_czgp0t$&N;$qX@`EU;XF8V
zS+&Kz_-hS!_?TzR%8U(DtS~lVaA7o1JG08=oF%_UnwO4;&zpwMj%2@v4u=yS4oXfw
zDre4c=(wD5Ves&9$Y5~c;AnZW_q?UDk`fb>Ak%?(SN`kr3$oIVojJmiaOOzQqYSYp
zW=AZ4>ZP3yemTd&%v4bE@Qffff%gu%U6c7$CriwDmeG;bwkkuoG1$~8MNCQQk$$7A
ziL$ASfuh=v)dGU+H>R@~EXm2@U|6uKp<_WqOMF~H+I4GYhBUS`rE}HdT$-PLuswB<
z*c^H4#Fm$CVnStRy*^Lo3aiHj7%vp*lbCTuVJ2gMgVLiZ!Pkzcxa7>bD&oWF;o>5r
zlwzzT!oc$9lbZ{RQj#+>LvV5$i-EC|N>W4igQ*=ePx6EmpSx+Pu5_<janHjyj*4+A
zeuhhP7-pT>d5H6PX3&C`t`j$l{LK7>xs?}K=%3N)>4_9JZhdfMXU>YOn^!h|KDb)b
zA<R`!Orcrl`hj?NHiiZs7nhV(Y-PNrf-AL@tkhkm1hMT<V~ufcVqiEnL%v{-H;-1V
zIH!Y4$BY@j5*0qVKIDEckkG}+D3B0#UDGw`xzmL?m!~Wh5cAWteq!Om5X>OnHRrN{
zlrgiAa-))<(ZZO==gyp&QxwKvkZjDtuq5YL$B~pYoty;AbS0M~*<KwTtG4Av8~iyt
z`S4{e9z)4l0!OAOF3wUrx{F6?($%&#O)t6+ar!@AAr@(1;o{?U;-26{aYmH@hedN1
z3#V%uPF|T7>@qK?NU0;^OjAcgMuTQEqcVfiDk+5pD<>#02`Sb}?y5PdzUQ7{+P$s0
zg2(UguwK4!Z^-#WO(!~3wnUuyy-rn)Db+VMP^n?%qLrx%&*q$|W-<uTZc<KD_dDn_
zxgsnyHR$w$7m+8bjW4WWTae|)!N4NOd!gX~!$<ERrG+z<Ce4&eIQMhblXx#JCc|b%
z!KZWb3;u1L-F@kEip9}46J(Vdr*6J^^J?hR*jSOKXEPS5x#+xBTD^?ttwGbGv^iH8
z445sBA5!tr(K*Ag%prl{fTTcC3JYf(FQaEDqocsfS&KT_I2uyYt{1tuB%C@Fzm6fs
zeukv5a+23afm{6Vb?07KCw*h1)GZ56rONB?%FfuRG$-;LEcUu*$$F#rqIH?$v~@-Y
zmMmH38n|+n@U=Br(-hs$+}l{3vC6YJtmK^Xq^w<O^DTtZ3>kJ`lT0%{tbcRODmDh6
z3B_Td>P<dMPA&{-3zDzzzx<$jyT8dYnaB5%&iO4%+!YpO^qEETSU^~?4?_T}`O_;V
zzCA17wgpV#2xGBd-!(@lB2B-I#lxe=L&e9ZtAS;jl5v-FaIk9V+@de{mQVR{ZSHkf
z7KV<1mV-W~ofp2oW2n>oe9lskjiK<-9+tUw7CQHAXI6X9+fm@Oz)*YD!X1WbZo*E9
zVl3?`WwBZd-dY(82$~AK=PkVc-8EEjv(^R=`(snCv<fVr5@e*Tp!QK`67L*~=S_+N
z-AuC>@9+J8taO`##^usXqfi$W!DX*o68$t|y>qYCxO|+=e)P~mgQca`xr_4J3wzR@
z2s9iJ^VOZkn=wP^_XOU~9jjhj_$n!#Nt+Nn?^x%=qBG9+QVwC>s{|u>museNPCS*o
zX@!+<r{|2j7RzRAW>j}zWlBp-3*BocE0GZ9`sDSZoQ7pHJ7#bSI&&0C-COfxZR`12
z<`*Z-T_wu2PopFCh4q&@iDf-UIMOD6zGs;3n;Lnn&|t$Ffp)_dApx%U-2y&F-OL6m
zeTI@6yPY<xoo+K(syUP4#*CzwTteH{oVXsvyzs;Ilg<nicuZ84%#5Gy5AymK#5=*j
z_weuHy8p-GuKTy?Mavw&IGHh`Yw_vJaW6R?BQJ0YrS4s4y?`zEdR5|arE`{CLQNL;
zdH-&c=I}9zHcR<<&b)QK6GOuawvO5}Zw&+!6E?~yXPkL8r{evYoLOpyn_r8lZ+<;%
z!7_%lRc<RRXKGn4Gx_(dH!V=~{CV@s1{GyKyXKtl+T>%o{cnOtvN?xS=+t>9e7ukQ
zX;_?6QAtWOT$W+B>Y)K+AV(aBfM>_ta>bTHncsz8TrCN!;wl7B?L8!H_|ssiNV3s^
z*TPXuXVMmBxm@q;TNN2$#1P@8be1j6aJlpHczZ3GCwVffH}M?0$9f^t+Gn+)vkdpd
zL>aI5(?1`x7B6NKbD8(6@ye@6*Mt@yR>6}?1U9c~JjOYf<$chpHj6%kqcW!^b?|yJ
z3Vlj2`J$}wYlgtY1FtseoIVu7t1!Eh!}#*n45hABLQFFnUrH=av(|facbCZAGc|I*
zMTC{A9vZ4Stl_fHno~3@H1y%l(`8rlnhFZy4!&CTO>c?e#?Q(sA&oYIn;8uff`2Jh
zFv#f4UKM4u)uOjeQ&Xuyze!L@SYdGmGs6<bioIC}8#pBb1a#9`H%KrFx@359GPbmK
z=70EbZjNQI^RluT-)5b%Hav1RFS<>k<#1VSYrr(qhNl*mY2teXd)qeOyys9*w)K?Z
zuT4x1Gjcr&gEp_(ylRH|**zzk0@%aFSQiKicE4YIbjm~-!{u`XJ6nGjZds#p#&c6z
znjoi}ip%x%!`Z4^3w<IP1B<2h?R)=TL{;ILgky2!l;kaE%VfD6C*2h|SQI?<o~MlZ
za~I8+++UkMY>v#d+&Wvk<kO3!ze!uG_uZSDYc1Y1i}!L!)%H2(4{Ry=^We#kYxmwH
zTzqqWmQ{tc``NG-0WL!)S4I_vGpl@9S`6Jxm5*dfZJybn)hNiU<QLrKnLKBjTweQ@
zGo1^yR<m6&ag7hTYa!%x%5v!mpGPS{S2eFG_Cyx@bz6lT+&Y`ru$1lo|D((0_eZUk
z6z(i|c~l@tMkihI%`%&(FCRWV+He0`hIh}0xsMm`X8--&zyE#cW-}&kqiDa$E7{(=
zXdIQW>DEv3S*)gh=6ihg<e9~0X_9S)U4@B{+mAndw?}6V%fxMO^}=4yn3VkC(C1|-
zCeP<EwFo%mo{HoRbm2WVMK~zv_s`F#|9^hoe=Ye|{;I{UwyV3=y|uZ$MnF;KSmw2s
z#24Jpcdc8`#oyszapcF%)u;DYe0r3#H!dVqQbwsV-Xrjv<T6e5=0m$@2sz}P3b1%K
zd;5D~Lx!?g``*X1m)8DOF=$e<crMX6$J)kbjw!ET+1)Gr%~~_k^dk(X9-OYI@xXv5
zjjQ8z*^htg=hf7diONhp*x0xE(%G#2`&TSayfORwcE4|{FGXK_x+myB`19$$qRTSx
zY_0YBnYGpJfcyFQn4H_U)sL(Hu4Z7HrJx?-t(m64$-1M;XGX}6b9>E0a%UyU9sfS-
z&(_IRf_K(@;ajV<rz?0;;;gp94ohVx!LGkgC;12(rrpiEt(az<d|?xZ=Uesu^Kp5*
zC#Np9d~2H8_3_Q4RquB#e){G`!uwBItFzpzKd&+9xqL85tVzD@qM^T`)C-fNSF3zo
zp0B>TexA+y;}-XCCqF;3d)2D6&21b(vrOCq=6-6~|4;gV*Q}3M>VKb@ANI&)j)1_b
zL?eOsPrlqc`1ZC`boTby;m`lBd;2T#vcG5P^cPq2UIgj6Fx`q%oc_4tYU%Oc-PPrJ
zax!vf(>AZWUH7GX{@ZP_AKpEAF+q~!LDFUMg$#>wZ;Ky{k6YWl>Ce&ib~D3MgCve=
z*clXmsN1={e3$wEbG!5J+uZ0kRK2iiP0Pv;_pCEtb>-jNw|~Kp+2*IMKPLrp%xrZy
zWF+ZlnR#u-C3pY0gsmMx7uMY5`hRnIfBnar&mW4uKgrrI^=O;)IrH1oU%$QlHP5`q
zyzkq-Ut8CodEWiB=>N;-@kdNz=FFdZ@VwW_tl3|GJt^3CCpso(tyuRh6XVOTvRWrx
zwwRh)xb>Eme9MfP-HSB37R`S2T>pHY{;b87!CgLwJ33Zb_!Mrv^`ZR!p6_>O`!-5V
z{-&w^Y(~xuH5VsS<6@SZZ%(e>{5ZN?eX`G<?Q_niT|M01e`KS<_gd?tg)(hNb^hEk
zzZa<^b~UH+@v*m8f8Lzz&VPHKz4d-4-|Eeqc-FnGO4IR@TplB`?{(W8cbC*d;o`5C
zX_>z*sH)LWI@09A(YDO)hvD<+-`@H%bDmfjW(Yi=`?&tY!`anKXI~F}XshsKj{DY&
z1s>BTBzv6{Ns<cQcPA&l{<m$}zsK$KC#o8+J(cvLn!(y;#_Xr&al0?Svl9D0_4~cu
zrN8f`%l}nfQ2Xs@u=nMnK!#7<pF<;C-<I7DY5jg>o3nsQOIgR8J((qbNvBRfRnqn`
z>=tHOy{b!~EZODJ-dzP}&TWk9(=-&W|M2VX^3`{5Uagwbw&=s=U2D2Fn6H1eYF3E*
z)x@s0HAkH1oM7hWOaA`hvVPF1^z`RGFXnVSe!DD`xiE+=T>QuC_<v2E`z!t>ZNF_8
z#c_{&TI=n2lXE*If*(3t`>fz{>HfJ#$NBcRV6St(AH)VJ2&yC{rNy0-3XT1$Y#@G4
zTgYhjtW}@h*Ztl*`S0IVc@ABhzrK69diCb7WwVrKu}!pUIka(s;EkxYD^A(}|9O7C
zO=Z~ivsbffw?^rHpSADpv&~hTU(fM~WJ#(ht$VmvViCXM(k*w(cE=viU};Eb;7HKh
z!BbMWHLO{Sg;~@4ep&N(RsnTaQ|;5MI2ap(t{EQn{5tu#|M&FGhkqX8;mDk!c5|!l
z*I<(pCG~3K`W<K3)ZP_s-dpvLN$}MHcHgZf@6yl5m9oX&H-2o;w@@R#{;%H5JhR<<
zU6VU@Z}XpZ)#rq-p>6fIpBE1vJbQb4`R=;CyWSkjnX#^H^|F-`xmVp3QpygmSe=`H
zgk{(E?d5el_m<Y|kzKYXKul3py1njt*^xsYu8|ru3`|oW3S`{l*ziL@>)DiL59ZEH
zIydLd3NH7vnO>fu>&xDj-94F8`1nag==R*%B6Dwx&Wp3FU)U9Ee`i-^P2J9&g;ib?
z_`ZqvrPjy2-*))r$&XoEW!u)tE_-St;=1!@uge4zIa%2+x%=O?)tz#0KYhG^{#+UP
z@KV+jzM)?q3p6o2i9NOOL+M=!C)tz}hP<y=e`^Zl@kndcmf8L|B_T36;k8e>vx``w
z)*Rs@i#S5fZK}3fR{wl;ZS8E=$kM|VH9Knl{du`fx;Bz|`sQUir<FuPpH_zb5?_C=
z_2aRFHDS}t^XA0F&RxIGZ2tZmcPwM|o_+oNnO9ND!CuwjV;n<*;rzF{ueRT>Gf<Ig
z+bDe~Ywzpb_bkI&SFM@5Bzn8w^>AIGyEYajel9KlpY6^s`&;lgm~9&S)4EeGE`0)u
zE5BNnC*R?Fd^*p<CSucvwU-ZX-rRj-`*wdm{qSh!J*A(&tj@nH-!8|Pf8XMqrts(V
z`L>mR-<@3h*mlyVPg$(9j;Fl-+UMF5JLgf(HJ-ySWbRu;#l)=Xn|_r&zJ9U)0*~q8
zs~2e;c=M^q)K6GQEc9l`75?B^TP7@$zr5`2_1*J+Y4YA|(_Ed!X4v|mgOfSvq0B6!
zNwX9e_D<~JeA9jWyk9^6zHit5ey#dDH-BIG4vqVJN&|j8njQcD)>-M}{qy&lY~HoT
z=i$4()%kmVK3E-JUB7XL@}Yx8cK7c~FN>M7FmKi7(_26LDX=%*cJKae-rw{+_3Du+
z6H@lx)SI;{^VBAu(%2=1yZ2w;^X=AO-`hu*)V6)i5U+joe&1g=rWNU%J2uHCn+Y7L
zl-%?Et--P>n>95Rl$6)BKm73HNw4|+h<W#_U;oXwuPsY^{Hj`hpZ)4P%l+5?>#hH8
zf6IPf?G6pG&(BUiUj9A4`osGF(fi9E|BF67*?PYHFOzR~E&4dN+}pA}U$*wc*?gP&
zO0ncwS6!u!?>6uE>k~Ws>BHmY;kV7|KK?kl_VMAndE9A_maKYp`Lgr#X3rfvV&ub9
zU$QU=be`H|b;JHm@V!34NDmpS`m6ru^}`!xToLe`x#{2@t@g9u7VrO&@nU&??T_pG
ze%`(RXDh#*#*KF}=kjFrzI~tdv*zQu>i73|es{ZmRNDOAzi<1$edo)+xB6S&w6lk-
z#plevzEoK0QG5Tq&D!@WpU>SU&2iB<B1iXmdb;$-r<=v~#XjG>dGyuE$Lf}D!Ebk!
zZN0hH?C|`*U#9EF?F%`ZA|@d-Q)Hg`Y+p7H&1?IznxxzAF-*K`;lljlxXlyJhDop1
z?mfCXuj0$g=cShwE^XiU^{n{(KW~=Te|%9;|3Cik-20lRjhMsE{&_856JdU~xBB}G
z4u+y@H*@-0Tz1_4s<<OE^v@4<`~TMU-^=a(y_o*_(p{U3xaxw(55Bxp7q8r5V}0lT
z{yjVHtO;-ZVd1Mahe2O2JhE_B(yL{+6eq`;+pN5ud$Q<oMe;_41E=4X%}APcEXad#
z(#I*L+A-Vji9UGnLPDTyc5cr`%N<`2-v4KQ{(Rfx^19E*!tEqB^VR0h`p*B2-_Jk7
zhJoqEjrZGDuU4`UlT1z%``D;pTl3|{bl*VH<LuSdztxq^U+cxk#FaeW@cP!m_r0oV
zZ*Mg&iIBS+mH+GRy0zZ^3sy`{4-T$;ono)GZuyqi>StG~6gIhB@yj${wq|k~??G4R
z30_={4}#9w|5^NBTyPJ6>yG??*Y4X|Sylb|@HopXcy0ra3xmYOs|**n-F|Dp6Z!V$
z&sSNu?`b%j-7WjO*nR%izX5mmRaU&ujgX0t$-DM?b!4z@^}kgsyCOx~*8M%VzP{r3
zyS=md@7?SDIsf1H{rBhhr#@`U(3vK1d!x89hZ6U+Th-!wX08oey?UGU=9O74K@T+<
zjre!Z)$fYDEaLlfvHidLUsqR`->ba-`_lrx!s3;ztKP+24Efr0WOZVg>gj|V-`}R~
zt@`vzDQ$Q0^R#n2rG-|-)_kkHe8u*hoo#>Bw>u?w@~+*^t^WPxMCJbnTiLhg$<#l-
zUB5O`rb52%SGs-f?rrkNJvPh<)yXq=F`Y2q=Fg)P!+1UMg&MxXM?#D;9{%Q$TAOYC
zk*~9@Fe8nd<KffQpQ}zwEsy{EN4?s&;{D<L>7lBJJQhT<u0MWuO;)7wvnk7V?6P2P
zShHjMjPk=GO&vRCy!kh`dVc+{55MbwIJ@wqetmFo?{fY4JwI>lmENBB_t^a(uk-i(
z3=0g?5mlNQIp^1|m8){!%5X-#-63Mgw6pm2v1M=TKb=%&nsNPWU9goKt3hFFGG|>^
z<?h=*H+d~v{W<*gS2g{#^?S=+e_g-l^E>nXyX#Ay>@{FkT(Z(U!6{WKSo*i2we0W2
z(!#pZ%F>#mH%=c9w#%PO|9ti8)1v<$j;*cU|Ns6!^Z9#fgywwMQu}B6{u@1)&+mG8
zFgjlG<0{U8_3V+4E&hFp|F`7sSARMCt<6vQ>%VzEeOgifzQAz$;>cQ~)%UG#zHfW?
z^y#mUt2fu33KbMPyXIc}yKT;08zavgPrS4B?}cr*zh-q^Zr;BC(>wEh<pni|#Sd1i
zuSx6V2=4Ki_2@~A!PUC$(!c&a`kBo7<M#f)x9|VF_noibuj7wJpWhSzegE5EFOQcw
zGwbiJ4~GnI=Xr%6{-Xcy=l{Bznv&<&UQQ2AXt-N8Ie1UyXSXm8&AQL4<3$&pKKtx)
zxc1F0)*YG_g(>`f-{ocAZ-2Z+@|f=#`T9?t9yjc5Ubfr$2TQdT?&dt_8~c5+{m+Yc
z&F}qOuqMsS_^hy2)5@qhYF8O^3KlA)on96Edux8J!qq?8@Ap~H*Y9ZQIK8Rs@`umz
z|1+L(bRVmJ-^ui9&8EL0Jo{=suQgx2Os(vC^0)r_uNUS2e&oMZ_Tip*oXqo6ft6c!
z6mEI){rx?eVyVqah72nl*|eM@rX5|ocyDBIY}}q*x3<mR);!1QgPTK3rBvO|=k@<i
z9(E6(E?y{cye^~s?yFCqK3!d%xBYaXl4Ee`z4iyqkN4d@JFWfm(M!J{RZXe*`RXYD
z|LgxxX6CG##1Jv(`_YUW&41qQ|1ZDi|G(R=rp{Un4?aD5RR8;V{fBh>zek_P+tmL2
z^ylyH<=uz!ch}8Pa}W@mKQn4;?(`BVu~z<bhQgaxJiGCId381W*DW{So-@CFI<JS*
zHAd1#!RFUz`TtM-|G9K+S~I)K%>5Ai`n$XTKR9^u<w@yM*C%GL-~PP0`gHhuyZ?VK
z-Zj7Pe=^AE`GGU@?0&7e9V6&@a8LO4lL^=RPd+$&|5tQ;<!`auVhh+-gnrep|9RS9
z-i~F-<ja@ycDK&4d0b=WT(~=L%DVTbH!(QK?^yRN@armh0mq04(Hp$US2UF#)djyb
zZ*AI|yenq=Y|pu$Q$ssEa<1P#n;NwD&!fxp|2^ox*=oIh|Gw?@1(jw09=*JrDdqFz
zZ~X6sef2#mCI>E*+W-0|f7W@$YA3;8GmbBbe7pMo&u{VnqxT1TD7i7aUhtQ<`;%V(
zf&F%FH$!~Q$D=PF9^8BRai#6-Mc;Pw8l7IFvB@dlYr*r|`-GmmP7q+cc6UN!sHv~;
zif1`JEGefW_uik9Wp<?IYVZ26Xt8z8{Ab>9bcz&IeEad}>g7crzKgk9Ke}1<z5cKK
z|3x~pf7X1wdD#EoQ~rJY)AhC9>;3M?*gAP{<<56MpZvSKY~?A}qkbGa-~ayqO8)O+
zfBSzGbB^V891_|cEBNPVnzM&eP=)%FjO+d_Dp{eCPo^YYN|cff7Cp4&R{u`#1#Syo
zamsv{;LFgm<I^OEu0^vd*)HeJ33E1?aA{{{=#+!Tm#0kSko<VjzwXEV+Ardpf68rp
z-5eQv_3Mnr)}x*w72D*_Z=3zS^U)Q5TMxc@rwe5Qzdrcz;%N8u)mMLB_`d(^zw1)^
zp$|_lGFq}u{>j?gzu(S?kI6GSaCKekq{s)ZH;+uYJ*9odGK;DAmd<I6@w(};sLA~*
zPp(hxDc=vJ54{!RLQ(}c9W3+EH-EeN^W5UPn<jBGVqv0oX}ZO`@66XvHx^5qWcXBZ
zX$sqd1>X+K|2dh>|E|-+pr`Qbm!nr7tM@OT5t_R*=AF;|-L+MlW+)b3=dax+G1<oM
zKIe;*dvt76SC<9vyT!NOOqY>Oz1P5Pj)}I!4AFDdYEBZ9_!@*0%vhJyommhOKF@=z
z@ON)@LD2-kU50jc@wS$?4Ib27lR5W%^Rii?rt!B88TJ$;gdI8ev-I}=H~#g1n%Vi|
z>K`AxTfP1N7ytkJ>p$85+dTjOqs0LgPCkbJkL_N6KJD}J=h??&IL@vPniVul!SMAe
z>5c6EKNqb0#y>mn%WcEhEtf6)&V+0fV>1j^@^P7^EYNi;?%@`JVCjhtg36Lg>bfS?
z>U}>q@Rfgm{zWc6=a&DxdG>Yx4mIS-%ggFd-@MEvG1Nn|KY7+8k>FX!UdsP}e1HA)
z-|Xz{{dV<twl{aI37f6d@;z_<p8Dq@mqXeYt<zGu)0=$1uV|mNl>YMHytDmQrPs0?
zG4WgaAyYMYf#R`?JEYy!KA%vUBY10{yLeA$h<LAfinAmy8>i*+vQ1nI4Z3F?4NTm2
z{fhh^<NwE^FZ905*<4%o?a`yhZy(-!bMNeB0jDz``Rl)3bk{#8dco&m(eICk&ljJ|
zX>jq0F#6Z~J-+_`JKwZdo8PtR9n*QlCI8|7KmC7)-!AEok9(Fm>uT$FyQMZg!Sjo(
zeJr0IaAG-m#(Mj$EqAA^K2*)76nI2)8IOui-^3f0@fHs?Z%Z6slF(p2YZ2cgmbB1^
zE|VA;Ig-x&OuD{r*Daf>!jDJ0SNosS+nsarz?pTuAsq@Hn-AT$kJ(fE`%Crv{mIMH
z8aOuZDq1*WQ|aTD`VaH}-fk^--0`-(bpH9W+Mbn~HKH+WvXl4jxwZAKiqFA92QH_J
z3R>SZEt~#EzMXrzE7?p{E@_q1hZL79anhG{j?cL8Y0auxt3(c65@f7UQ!;BXe7^eZ
zyUpq6>%KmDdi=cJEyFGkNvBgU*WO;9e{W~u`yUDU`&Kw}_z4)M&7M@|%-^xB>;KdJ
z-*<Z!D_6y|AKJXI_vE=UXSP?zA}Y^iB_wp*_H3^^GH1GPAgg}LiA`^p_gw1znGiQ$
zXZC};DJ2_k&dvXwbA=_mrQmI@&tndsi~zBv#X;4d&djq+<4s`_c)UfbZTa)?^ZM7%
z>s|Bta&NEo_x!o<^u=`^-a6xw(9+?uY|0g(lt1$SF4te^uk@(gdQ&o?vFdrnG6v13
zXH!;hlU_dM$~50t*5`9>e=WRwJX2zp1N-O5*b3)+s?3)QyP7JBHs~~WXNAY!`szI2
zWcibhRjW$QNjmiyYFaq4hloDh)hy2;<sYcKa^qypXzQb=eSiNrx_V!3zKrZ$J4>qw
zy=H#DmWez*XE$m6d%pj7`LwO}b}Ix8(q)tO-6)G(E8wJ{ZlQm~a@VWRc_-p_e9${O
zBUtGOXR3sHyomeeU&l6a-CKDpt!Mh~%ooRwuK99KQjuv*+1<Pj!`T-5XI%AZIbo>E
ze0r6cPwB&HrJfv*BqoTs2ztG@X?#|)@n+q}SC2k!o}Q`^x4ZWDlZ1N1d>QX^lK)@V
zKYzb;O4;KVH5pp+60?@QXx}4wX`Q^lMj?xvtLJn$OD|rxe2c7_`=tuO=LdKqcV$>E
zfAFIs@T#K3Cc(16`SI(v-_E-i^80gD7~AtZr$e{DYO_;wn{_?3;E2b~gf7pkH@19=
zo3p_pO|My>h4l<Kr?AkPTkkGE*O#}e+<13O{{7w6pPxwle_8+Md$O6Sgs6c?dbqYp
z?740&3+6LvhA;EZ1os#>{@tY`BOEz9!8(mWqxs4`?rLYRwB3fKe>)O>m##Q{h~05o
zuKBv%oIF0Ci>|di5XtDOy#75han`bB8mp8#JlHaBmwC<Nc@}E9{#5qtM8yCOLnGlf
zg$}bLKaSq~soo#|;QuH7`hJ&Nj#oF$TDoNNtFlv^g>kK^s&Wrk$xc?XyzhT8Nh|XE
zDyJEzj24`DTK1~FQ}Feo35yDp0x$29)w{jY;l}F2|KftHk_unj<=raWnkiVAZ#aMI
zx&j;3y?5SBTBu;&c>0iV=fW+A4UW0AG_KU?dLX03F;PLx$L~aCQPU6m|A+6tZd=i2
zXVIL!@=1~l0|R3<Xf1&GioW1ilQl0+NW9Lg`TUZn@SJic4%a}x;GV|@+*|f%a9Bz*
zd`P|i{ck{J`HmUslYGylY{`vgE<UrhJT$gNfG6R$|LU({S8bjh-dh<f>Q`}Q$GhX*
zt9z66YGzzrDxmp!O3-!wv;z#Acj?VhXJPr!v{n3%`u~&n=TDV8vrDm0^Zcq!YYv}Y
zEfyJ~>$g$1c(qlUXj=aZ*6FSq-0Uv575Oe+y71QY>C2)vmvcJ}pXGJ!u2VT28GLo~
zuU!new?D3W%UBRMy)-c9_PXS2x!08^Ij`NL-@U+t!D88-d%Q=^u=&PvZ8l)|_;gvQ
zDa(q}r*5bQ|Czh~PW|U=FaJ({`tjc!o;@Ct0W~*{?s=&s{N`6jM_bF0nH87&EweL!
z7UVyhlbj~D>lUw}Z|Mio%m4Q1F*Dy-@#$06WxmUCZ__thwJ4>B9^m-&=uMVH+pUWy
zFV+c4bc$A7=g+<Ue8#DOGqbfU*p4W^K7E>3*!sfWn{(y{JF~uCX0f8|?vMY>8Mm$3
UTsmj5fHv@Wy85}Sb4q9e09}xt?EnA(

diff --git a/configuration/services/configs/minecraft/voor-kia/server.properties b/configuration/services/configs/minecraft/voor-kia/server.properties
deleted file mode 100644
index 84a8cd5..0000000
--- a/configuration/services/configs/minecraft/voor-kia/server.properties
+++ /dev/null
@@ -1,52 +0,0 @@
-#Minecraft server properties
-#Thu Apr 08 21:07:16 BST 2021
-allow-flight=true
-allow-nether=true
-broadcast-console-to-ops=true
-broadcast-rcon-to-ops=true
-difficulty=normal
-enable-command-block=true
-enable-jmx-monitoring=false
-enable-query=false
-enable-rcon=false
-enable-status=true
-enforce-whitelist=true
-entity-broadcast-range-percentage=100
-force-gamemode=false
-function-permission-level=2
-gamemode=survival
-generate-structures=true
-generator-settings=
-hardcore=false
-level-name=world
-level-seed=
-level-type=default
-max-build-height=256
-max-players=5
-max-tick-time=-1
-max-world-size=29999984
-motd=Minecraft met Kia en die broers
-network-compression-threshold=256
-online-mode=true
-op-permission-level=4
-player-idle-timeout=0
-prevent-proxy-connections=false
-pvp=false
-query.port=25565
-rate-limit=0
-rcon.password=
-rcon.port=25575
-resource-pack=
-resource-pack-sha1=
-server-ip=
-server-port=25565
-snooper-enabled=true
-spawn-animals=true
-spawn-monsters=true
-spawn-npcs=true
-spawn-protection=1
-sync-chunk-writes=true
-text-filtering-config=
-use-native-transport=true
-view-distance=10
-white-list=true
diff --git a/configuration/services/minecraft.nix b/configuration/services/minecraft.nix
deleted file mode 100644
index c19335c..0000000
--- a/configuration/services/minecraft.nix
+++ /dev/null
@@ -1,141 +0,0 @@
-{
-  config,
-  pkgs,
-  lib,
-  ...
-}: let
-  minecraft-server-args = [
-    "-Xms2G"
-    "-Xmx2G"
-    "-Dsun.rmi.dgc.server.gcInterval=2157583646"
-    "-XX:+UseG1GC"
-    "-XX:+ParallelRefProcEnabled"
-    "-XX:MaxGCPauseMillis=200"
-    "-XX:+UnlockExperimentalVMOptions"
-    "-XX:+DisableExplicitGC"
-    "-XX:+AlwaysPreTouch"
-    "-XX:G1NewSizePercent=30"
-    "-XX:G1MaxNewSizePercent=40"
-    "-XX:G1HeapRegionSize=8M"
-    "-XX:G1ReservePercent=20"
-    "-XX:G1HeapWastePercent=5"
-    "-XX:G1MixedGCCountTarget=4"
-    "-XX:InitiatingHeapOccupancyPercent=15"
-    "-XX:G1MixedGCLiveThresholdPercent=90"
-    "-XX:G1RSetUpdatingPauseTimePercent=5"
-    "-XX:SurvivorRatio=32"
-    "-XX:+PerfDisableSharedMem"
-    "-XX:MaxTenuringThreshold=1"
-  ];
-  ops = pkgs.writeText "ops.json" (builtins.toJSON [
-    {
-      uuid = "140d177a-966f-41b8-a4c0-e305babd291b";
-      name = "TLATER";
-      level = 4;
-      bypassesPlayerLimit = true;
-    }
-  ]);
-  whitelist = pkgs.writeText "whitelist.json" (builtins.toJSON [
-    {
-      uuid = "59cd1648-14a4-4bcf-8f5a-2e1bde678f2c";
-      name = "romino25";
-    }
-    {
-      uuid = "0ab6e3d1-544a-47e7-8538-2e6c248e49a4";
-      name = "lasi25";
-    }
-    {
-      uuid = "01c9e737-fc9d-4d55-b8c2-610ca80eb4be";
-      name = "Nampeyo25";
-    }
-    {
-      uuid = "140d177a-966f-41b8-a4c0-e305babd291b";
-      name = "tlater";
-    }
-  ]);
-  eula = pkgs.writeText "eula.txt" "eula=true";
-in {
-  users = {
-    extraUsers.minecraft = {
-      uid = config.ids.uids.minecraft;
-      group = config.users.extraGroups.minecraft.name;
-      isSystemUser = true;
-      description = "Minecraft server user";
-    };
-    extraGroups.minecraft = {gid = config.ids.gids.minecraft;};
-  };
-
-  virtualisation.oci-containers.containers.minecraft-voor-kia = let
-    properties = ./configs/minecraft/voor-kia/server.properties;
-    icon = ./configs/minecraft/voor-kia/server-icon.png;
-  in {
-    image = "tlaternet/minecraft-voor-kia";
-
-    imageFile = pkgs.dockerTools.buildImage {
-      name = "tlaternet/minecraft-voor-kia";
-      tag = "latest";
-      contents = [
-        (pkgs.local.forge-server.override {
-          jre_headless = pkgs.jdk11_headless;
-          mods = pkgs.local.voor-kia;
-          modConfig = ./configs/minecraft/voor-kia/config;
-          defaultconfigs = ./configs/minecraft/voor-kia/defaultconfigs;
-        })
-      ];
-
-      config = let
-        uid = toString config.users.extraUsers.minecraft.uid;
-        gid = toString config.users.extraGroups.minecraft.gid;
-      in {
-        Cmd = ["forge-server"] ++ minecraft-server-args;
-        WorkingDir = "/var/lib/minecraft";
-        Volumes = {
-          "/var/lib/minecraft" = {};
-          # Required because some things will try to write to /tmp,
-          # which doesn't exist if it's not defined as a volume.
-          "/tmp" = {};
-        };
-        ExposedPorts = {"25565" = {};};
-        User = "${uid}:${gid}";
-      };
-    };
-
-    extraOptions = ["--cpus=1.0"];
-    autoStart = false;
-    ports = ["25565:25565"];
-    volumes = [
-      "minecraft:/var/lib/minecraft"
-      "${eula}:/var/lib/minecraft/eula.txt:ro"
-      "${icon}:/var/lib/minecraft/server-icon.png:ro"
-      "${ops}:/var/lib/minecraft/ops.json:ro"
-      "${properties}:/var/lib/minecraft/server.properties:ro"
-      "${whitelist}:/var/lib/minecraft/whitelist.json:ro"
-    ];
-  };
-
-  systemd.timers.podman-minecraft-voor-kia-off = {
-    description = "Turns off the minecraft server every day at 4 am";
-    wantedBy = ["podman-minecraft-voor-kia.service"];
-    timerConfig = {
-      Unit = "podman-minecraft-voor-kia-starter@stop.service";
-      OnCalendar = "04:00:00";
-    };
-  };
-
-  systemd.timers.podman-minecraft-voor-kia-on = {
-    description = "Turns on the minecraft server every day at 2 pm";
-    wantedBy = ["podman-minecraft-voor-kia.service"];
-    timerConfig = {
-      Unit = "podman-minecraft-voor-kia-starter@start.service";
-      OnCalendar = "14:00:00";
-    };
-  };
-
-  systemd.services."podman-minecraft-voor-kia-starter@" = {
-    description = "Unit to stop/start the minecraft server";
-    serviceConfig = {
-      ExecStart = "${pkgs.systemd}/bin/systemctl %i podman-minecraft-voor-kia.service";
-      Type = "oneshot";
-    };
-  };
-}
diff --git a/flake.nix b/flake.nix
index 3f0ad1b..1ae56cc 100644
--- a/flake.nix
+++ b/flake.nix
@@ -44,7 +44,6 @@
           tlaternet-templates.legacyPackages.${prev.system}.packages;
         local = import ./pkgs {
           pkgs = prev;
-          local-lib = self.lib.${prev.system};
         };
       })
     ];
@@ -118,29 +117,6 @@
           nixfmt
           git-lfs
           sops-init-gpg-key
-
-          # For the minecraft mod update script
-          (python3.withPackages (pypkgs:
-            with pypkgs; [
-              dateutil
-              requests
-
-              ipython
-
-              python3.withPackages
-              (ppkgs:
-                with pkgs; [
-                  python-lsp-server
-                  python-lsp-black
-                  pyls-isort
-                  pyls-mypy
-                  rope
-                  pyflakes
-                  mccabe
-                  pycodestyle
-                  pydocstyle
-                ])
-            ]))
         ];
         shellHook = let
           inherit (pkgs.lib.attrsets) mapAttrsToList;
@@ -167,14 +143,6 @@
         '';
       };
 
-      packages = import ./pkgs {
-        inherit pkgs;
-        local-lib = self.lib.${system};
-      };
-
-      lib = import ./lib {
-        inherit pkgs inputs;
-        lib = nixpkgs.lib;
-      };
+      packages = import ./pkgs {inherit pkgs;};
     });
 }
diff --git a/lib/default.nix b/lib/default.nix
deleted file mode 100644
index 2a5d54f..0000000
--- a/lib/default.nix
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  inputs,
-  lib,
-  pkgs,
-  ...
-}: let
-  inherit (lib) makeExtensible foldr attrValues;
-  tlater-lib = makeExtensible (self: let
-    callLibs = file: import file {inherit self lib pkgs inputs;};
-  in {minecraft = callLibs ./minecraft.nix;});
-in
-  tlater-lib.extend (self: super: foldr (a: b: a // b) {} (attrValues super))
diff --git a/lib/minecraft.nix b/lib/minecraft.nix
deleted file mode 100644
index e3f8c4e..0000000
--- a/lib/minecraft.nix
+++ /dev/null
@@ -1,61 +0,0 @@
-{
-  lib,
-  pkgs,
-  ...
-}: {
-  # Make a modpack given its mod inputs.
-  #
-  # Mods should be attrsets in this format:
-  #   {
-  #     project = "";
-  #     id = "";
-  #     filename = "";
-  #     sha256 = "";
-  #   }
-  #
-  # This may be nice to read from a json ;)
-  #
-  mkModpack = {
-    name,
-    version,
-    mods,
-  }:
-    pkgs.stdenv.mkDerivation {
-      inherit name version;
-      srcs = map pkgs.local.fetchFromCurseForge mods;
-
-      sourceRoot = "src/";
-      preUnpack = "mkdir -p src/";
-      unpackCmd = "cp $curSrc src/";
-
-      installPhase = ''
-        mkdir -p $out/mods/
-        cp * $out/mods
-      '';
-    };
-
-  mkModpackZip = {
-    name,
-    version,
-    mods,
-  }:
-    pkgs.stdenv.mkDerivation {
-      inherit name version;
-      srcs = map pkgs.local.fetchFromCurseForge mods;
-
-      sourceRoot = "src/";
-      preUnpack = "mkdir -p src/";
-      unpackCmd = "cp $curSrc src/";
-
-      buildInputs = [pkgs.zip];
-
-      buildPhase = ''
-        zip voor-kia-mods.zip *.jar
-      '';
-
-      installPhase = ''
-        mkdir -p $out/
-        cp voor-kia-mods.zip $out/
-      '';
-    };
-}
diff --git a/pkgs/build-support/fetchFromCurseForge.nix b/pkgs/build-support/fetchFromCurseForge.nix
deleted file mode 100644
index 674803f..0000000
--- a/pkgs/build-support/fetchFromCurseForge.nix
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  lib,
-  fetchurl,
-}:
-with builtins;
-  {
-    project,
-    id,
-    filename,
-    ...
-  } @ args: let
-    # I think this is supposed to be some weak automation
-    # protection. This split "id" is simply part of the download URL.
-    #
-    # Note that if it's zero-prefixed we need to remove the zeroes. It's
-    # really an odd one...
-    a = head (match "0*([[:digit:]]+)" (substring 0 4 (toString id)));
-    b = head (match "0*([[:digit:]]+)" (substring 4 7 (toString id)));
-    encoded-filename = replaceStrings [" "] ["%20"] filename;
-
-    url = "https://media.forgecdn.net/files/${a}/${b}/${encoded-filename}";
-    otherArgs = removeAttrs args ["project" "project_id" "id" "filename"];
-  in
-    fetchurl (otherArgs
-      // {
-        inherit url;
-        # Rename files to avoid names incompatible with the nix store
-        name = "${project}.jar";
-        # Avoid accidental URL globbing
-        curlOpts = "--globoff";
-      })
diff --git a/pkgs/default.nix b/pkgs/default.nix
index ef226db..c92874b 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -1,21 +1,5 @@
-{
-  pkgs,
-  local-lib,
-  ...
-}: let
-  inherit (pkgs.lib) callPackageWith;
-  callPackage = callPackageWith (pkgs // {inherit local-lib;});
+{pkgs, ...}: let
+  inherit (pkgs.lib) callPackage;
 in {
-  # Forge
-  forge-server = callPackage ./minecraft/forge-server.nix {};
-
-  # Build support
-  fetchFromCurseForge = callPackage ./build-support/fetchFromCurseForge.nix {};
-
-  # Minecraft modpacks
-  voor-kia = callPackage ./minecraft/voor-kia.nix {};
-  voor-kia-client = callPackage ./minecraft/voor-kia-client.nix {};
-
-  # Starbound
   starbound = callPackage ./starbound {};
 }
diff --git a/pkgs/minecraft/forge-server.nix b/pkgs/minecraft/forge-server.nix
deleted file mode 100644
index 5d7a8c2..0000000
--- a/pkgs/minecraft/forge-server.nix
+++ /dev/null
@@ -1,120 +0,0 @@
-{
-  lib,
-  stdenv,
-  fetchurl,
-  busybox,
-  coreutils,
-  jre_headless,
-  runtimeShell,
-  mods ? null,
-  modConfig ? null,
-  defaultconfigs ? null,
-}: let
-  name = "forge-server";
-  version = "1.16.5-36.2.2";
-  mirror = "https://files.minecraftforge.net/maven/net/minecraftforge/forge";
-  src = fetchurl {
-    url = "${mirror}/${version}/forge-${version}-installer.jar";
-    curlOpts = "--globoff";
-    # Forge doesn't seem to like newer shas
-    sha1 = "sha1-oHNpyrgHluRrAXWZJg9j+OInAwA=";
-  };
-
-  unpackCmd = "mkdir -p src; cp $curSrc src/forge-${version}-installer.jar";
-
-  nativeBuildInputs = [jre_headless];
-
-  # Somewhat evil pre-install step to run through the network
-  # dependency resolution forge needs. This is also common for gradle
-  # projects, so I think this is ok-ish here, though ideally I'd
-  # identify all the dependencies and package them as well.
-  deps = stdenv.mkDerivation {
-    name = "${name}-deps";
-    inherit src unpackCmd nativeBuildInputs;
-
-    buildPhase = ''
-      java -jar forge-${version}-installer.jar --installServer installation
-    '';
-    installPhase = ''
-      mkdir -p $out
-
-      # The installer will patch the Minecraft server jar in some
-      # fashion, and include it in "libraries". This'd be fine, if the
-      # patch was bit-for-bit reproducible. Sadly it is not, so we
-      # defer this to the *real* package build.
-      rm -r installation/libraries/net/minecraft/
-
-      cp -r installation/* $out
-    '';
-
-    outputHashAlgo = "sha256";
-    outputHashMode = "recursive";
-    outputHash = "VuUGc5JnzcRhDt9aaGrU+yUrJILVdU2vzv1PxLwdAig=";
-  };
-in
-  stdenv.mkDerivation rec {
-    inherit name version src unpackCmd nativeBuildInputs;
-
-    buildPhase = ''
-      mkdir -p installation
-
-      # Take the input deps and patch the Minecraft server jar into our
-      # libraries to create the package.
-      cp -rv ${deps}/* installation/
-      chmod -R +w installation/
-      java -jar forge-${version}-installer.jar --offline --installServer installation/
-    '';
-
-    installPhase = ''
-      mkdir -p $out/{bin,lib/forge}
-
-      cp -r installation/{forge-${version}.jar,libraries} $out/lib/forge/
-
-      cat > $out/bin/forge-server << EOF
-      #!${runtimeShell}
-      set -eu
-
-      # Delete any previous mods directory so that it can be updated
-      ${busybox}/bin/rm -fr mods
-
-      ${lib.optionalString (mods != null) ''
-        # Copy the specified mods into the directory. Note that, sadly,
-        # forge doesn't support symlinks here.
-        ${busybox}/bin/mkdir -p mods
-        ${busybox}/bin/cp -r '${mods}/mods/'*.jar mods
-      ''}
-
-      # Delete any previous config directories so that they can be updated
-      ${busybox}/bin/rm -fr config defaultconfigs
-
-      ${lib.optionalString (modConfig != null) ''
-        # Copy the specified configs into the directory. Forge (and
-        # mods) will try to write here, so we cannot symlink.
-        ${busybox}/bin/mkdir -p config
-        ${busybox}/bin/cp -r '${modConfig}'/* config
-        ${busybox}/bin/chmod -R u+w config
-      ''}
-
-      ${lib.optionalString (defaultconfigs != null) ''
-        # Copy the specified configs into the directory. Forge (and
-        # mods) will try to write here, so we cannot symlink.
-        ${busybox}/bin/mkdir -p defaultconfigs
-        ${busybox}/bin/cp -r '${defaultconfigs}'/* defaultconfigs
-        ${busybox}/bin/chmod -R u+w defaultconfigs
-      ''}
-
-      exec ${jre_headless}/bin/java \$@ -jar $out'/lib/forge/forge-${version}.jar' nogui
-      EOF
-
-      chmod +x $out/bin/forge-server
-    '';
-
-    meta = with lib; {
-      description = "Forge Minecraft Server";
-      homepage = "https://files.minecraftforge.net/";
-      # Forge itself is open source, but this package pulls in
-      # minecraft.
-      license = licenses.unfreeRedistributable;
-      platforms = platforms.unix;
-    };
-  }
diff --git a/pkgs/minecraft/voor-kia-client.nix b/pkgs/minecraft/voor-kia-client.nix
deleted file mode 100644
index fea9879..0000000
--- a/pkgs/minecraft/voor-kia-client.nix
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  lib,
-  local-lib,
-  stdenv,
-}:
-local-lib.minecraft.mkModpackZip {
-  name = "voor-kia-client";
-  version = "1.1";
-  mods =
-    (builtins.fromJSON (builtins.readFile ./voor-kia/mods.json))
-    ++ (builtins.fromJSON (builtins.readFile ./voor-kia/client-mods.json));
-}
diff --git a/pkgs/minecraft/voor-kia.nix b/pkgs/minecraft/voor-kia.nix
deleted file mode 100644
index 4bbd433..0000000
--- a/pkgs/minecraft/voor-kia.nix
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  lib,
-  local-lib,
-  stdenv,
-}:
-local-lib.minecraft.mkModpack {
-  name = "voor-kia";
-  version = "1.0";
-  mods = builtins.fromJSON (builtins.readFile ./voor-kia/mods.json);
-}
diff --git a/pkgs/minecraft/voor-kia/client-mods.json b/pkgs/minecraft/voor-kia/client-mods.json
deleted file mode 100644
index 960f7ab..0000000
--- a/pkgs/minecraft/voor-kia/client-mods.json
+++ /dev/null
@@ -1,86 +0,0 @@
-[
-  {
-    "filename": "AmbientSounds_v3.1.9_mc1.16.5.jar",
-    "id": 3334857,
-    "project": "ambientsounds",
-    "project_id": 254284,
-    "sha256": "c8ed21587fe96745695aa9a8f23b6effbcc6a5c5340aed11b8515c0e0aa2c310"
-  },
-  {
-    "filename": "BackTools-1.16.5-10.1.0.jar",
-    "id": 3224955,
-    "project": "back-tools",
-    "project_id": 229061,
-    "sha256": "cd5ed82919dd8acf2874c7edadba5bacfaffa898e572f8574241329e4478518e"
-  },
-  {
-    "filename": "BetterAdvancements-1.16.5-0.1.1.111.jar",
-    "id": 3400299,
-    "project": "better-advancements",
-    "project_id": 272515,
-    "sha256": "83c159f83bebc1d0f72c9de465bdcbeb2b02a56b88dcaa6661fe54df50a9aab5"
-  },
-  {
-    "filename": "Controlling-7.0.0.23.jar",
-    "id": 3348514,
-    "project": "controlling",
-    "project_id": 250398,
-    "sha256": "627308ed0b4fc1fdcc75113db8412c0684c3a774d1c6a07ae993543e605f5655"
-  },
-  {
-    "filename": "EntityCulling-1.16.5-2.1.6.jar",
-    "id": 3328602,
-    "project": "entity-culling",
-    "project_id": 409087,
-    "sha256": "eede3bfc68f48acb3e06fec2ea280510287cd5d492a02b8ace8e0dda742d7342"
-  },
-  {
-    "filename": "ftb-library-forge-1605.3.1-build.48.jar",
-    "id": 3373833,
-    "project": "ftb-library-forge",
-    "project_id": 404465,
-    "sha256": "f4f87f464796ee6ff7c80fb1fbc5753ac191138b6aa6b1a30c1b55252b3bf0a8"
-  },
-  {
-    "filename": "InventoryHud_[1.16.2-1.16.5].forge-3.3.0.jar",
-    "id": 3296748,
-    "project": "inventory-hud-forge",
-    "project_id": 357540,
-    "sha256": "2b3a4f02fe84b717c9273ea14cea0912267c2c093fc2cdfcde2b6f032c9762e7"
-  },
-  {
-    "filename": "MouseTweaks-2.14-mc1.16.2.jar",
-    "id": 3202662,
-    "project": "mouse-tweaks",
-    "project_id": 60089,
-    "sha256": "9d7e1aaee9f814c26d896e084e6e86930ab99e19fe547a1d350a6e25e4267092"
-  },
-  {
-    "filename": "namepain-1.4.0 forge-1.16.x.jar",
-    "id": 3356725,
-    "project": "name-pain",
-    "project_id": 366263,
-    "sha256": "5cc9e83b6d06810cbfcc155ddcfbe417cd4553a2665025affd1b71bee0138f68"
-  },
-  {
-    "filename": "overloadedarmorbar-5.1.0.jar",
-    "id": 3055679,
-    "project": "overloaded-armor-bar",
-    "project_id": 314002,
-    "sha256": "8aff59f170ef2c7598dc0f2367842f4384e57c13111507468da32498fc0ac4ea"
-  },
-  {
-    "filename": "shutupexperimentalsettings-1.0.3.jar",
-    "id": 3188120,
-    "project": "shutup-experimental-settings",
-    "project_id": 407174,
-    "sha256": "22ce84a0d424c2d48e483cb873909ac5c8c322bc793d09365ad44b901f43de62"
-  },
-  {
-    "filename": "Toast-Control-1.16.4-4.3.1.jar",
-    "id": 3172881,
-    "project": "toast-control",
-    "project_id": 271740,
-    "sha256": "b1cb36b7615c846f08c72423b2b52417b55eea91ca812bb7629a8f3060f5efae"
-  }
-]
\ No newline at end of file
diff --git a/pkgs/minecraft/voor-kia/mods.json b/pkgs/minecraft/voor-kia/mods.json
deleted file mode 100644
index 794a1ab..0000000
--- a/pkgs/minecraft/voor-kia/mods.json
+++ /dev/null
@@ -1,625 +0,0 @@
-[
-  {
-    "filename": "AI-Improvements-1.16.2-0.3.0.jar",
-    "id": 3031978,
-    "project": "ai-improvements",
-    "project_id": 233019,
-    "sha256": "47526292ea2f11dd18a8da8863b40ba81a93601f03aa4abcc742ac62ea599c69"
-  },
-  {
-    "filename": "alexsmobs-1.11.1.jar",
-    "id": 3371504,
-    "project": "alexs-mobs",
-    "project_id": 426558,
-    "sha256": "4daf19a04317c5a399d38c2c397ead8cce9a9eb6c09fdb5bd7bd6dec8c911167"
-  },
-  {
-    "filename": "Apotheosis-1.16.4-4.6.1.jar",
-    "id": 3332235,
-    "project": "apotheosis",
-    "project_id": 313970,
-    "sha256": "a15e9faf743d237063221c0d9ab0b75acf86ba5c3bfde08a42922c3b108bca80"
-  },
-  {
-    "filename": "appleskin-forge-mc1.16.x-2.1.0.jar",
-    "id": 3395800,
-    "project": "appleskin",
-    "project_id": 248787,
-    "sha256": "d98f34b1a97a66ea5e33eda7e744f1382d325c7de51db57285d1a0888c0e8496"
-  },
-  {
-    "filename": "architectury-1.20.28-forge.jar",
-    "id": 3385660,
-    "project": "architectury-forge",
-    "project_id": 419699,
-    "sha256": "0a89b6a6d12596bf288411fd740cbc44f3fe63c3f4665f7fd3f46f65f52cf138"
-  },
-  {
-    "filename": "Artifacts-1.16.5-2.10.0.jar",
-    "id": 3374317,
-    "project": "artifacts",
-    "project_id": 312353,
-    "sha256": "70e2945f8200f7ad3cb46436a998acd37ebec318d08e7a578ca39e8115414b1c"
-  },
-  {
-    "filename": "AttributeFix-1.16.5-10.1.3.jar",
-    "id": 3348562,
-    "project": "attributefix",
-    "project_id": 280510,
-    "sha256": "aabf99d65e4ccfc08a67dc378f447eef613ac50924587a33aef68d4467e1a7c0"
-  },
-  {
-    "filename": "AutoRegLib-1.6-49.jar",
-    "id": 3326041,
-    "project": "autoreglib",
-    "project_id": 250363,
-    "sha256": "2760b765dccf1fad36e74f747ee9b1a2923e2d09eb281c72258c15bb4ed427d5"
-  },
-  {
-    "filename": "bedspreads-forge-1.16.5-5.1.0.2.jar",
-    "id": 3258439,
-    "project": "bedspreads",
-    "project_id": 308653,
-    "sha256": "fa823abf9efef6818079d1c0cf123e9edccdac81fddf09b2ef931f21f4c58e9d"
-  },
-  {
-    "filename": "BetterBurning-1.16.5-6.0.7.jar",
-    "id": 3348573,
-    "project": "better-burning",
-    "project_id": 353434,
-    "sha256": "4b089ce99e48cf72bf817cbc26a0e23b297b5b451bbd80b46091cd5a290524ff"
-  },
-  {
-    "filename": "BetterCaves-Forge-1.16.4-1.1.2.jar",
-    "id": 3307879,
-    "project": "yungs-better-caves",
-    "project_id": 340583,
-    "sha256": "5182379427440bb4198790856c01f28c085365cc37ad3a05a9cd82dfdf068454"
-  },
-  {
-    "filename": "BetterMineshafts-Forge-1.16.4-2.0.4.jar",
-    "id": 3344719,
-    "project": "yungs-better-mineshafts-forge",
-    "project_id": 389665,
-    "sha256": "19b9b7f87da2bb76574e9f3e3d18d445189a4627cfd0d8188ae88eb681b578b8"
-  },
-  {
-    "filename": "BetterPortals-1.16.4-0.3.7.jar",
-    "id": 3396844,
-    "project": "yungs-better-portals",
-    "project_id": 443723,
-    "sha256": "4695da7e9212d79c9fc8350e9b4ec2600631ff858ee10d146d4a69f20dfc9c6e"
-  },
-  {
-    "filename": "Bookshelf-1.16.5-10.2.15.jar",
-    "id": 3402183,
-    "project": "bookshelf",
-    "project_id": 228525,
-    "sha256": "0674174797835d3371d1421cbf6232276451edca0b6f16b85bb3519e65622ea4"
-  },
-  {
-    "filename": "bwncr-1.16.4-3.9.16.jar",
-    "id": 3101531,
-    "project": "bad-wither-no-cookie-reloaded",
-    "project_id": 261251,
-    "sha256": "91c4df24466b958d36d41ce886e5d8b0839a07b73d58248a0dcb84a67279b81f"
-  },
-  {
-    "filename": "byg-1.2.9.jar",
-    "id": 3337158,
-    "project": "oh-the-biomes-youll-go",
-    "project_id": 247560,
-    "sha256": "13007c914d142b4e19f92213970edf22094ad9f48e1e7e7c27e1355eb7248086"
-  },
-  {
-    "filename": "callablehorses-1.16.3-1.2.1.4.jar",
-    "id": 3090832,
-    "project": "callable-horses",
-    "project_id": 331746,
-    "sha256": "639778fd58667aa560d333a2490352e34c1c32e897d9f8204e52df305ca5e879"
-  },
-  {
-    "filename": "citadel-1.7.1-1.16.5.jar",
-    "id": 3346836,
-    "project": "citadel",
-    "project_id": 331936,
-    "sha256": "2977c084dcbd23c4fa1ea00ea152f1792b38781eff8f0234de4d67b1ee35b849"
-  },
-  {
-    "filename": "cloth-config-4.11.26-forge.jar",
-    "id": 3311352,
-    "project": "cloth-config-forge",
-    "project_id": 348521,
-    "sha256": "815ba5d61416d9bbd53b830509b9f3d74d59c1720cf9a6b002a3e66eb1453196"
-  },
-  {
-    "filename": "Clumps-6.0.0.25.jar",
-    "id": 3348509,
-    "project": "clumps",
-    "project_id": 256717,
-    "sha256": "1039d9ae78873107ee82c799e586c71dfe284d5bb58f89895a3a510f8f33c765"
-  },
-  {
-    "filename": "flywheel-1.16-0.1.1.jar",
-    "id": 3389159,
-    "project": "flywheel",
-    "project_id": 486392,
-    "sha256": "ac0cc92d6ef491cc88ca3fbc3cb2c3180fe58ad1ce1c6f91dcfb996324d7331e"
-  },
-  {
-    "filename": "expandability-2.0.1-forge.jar",
-    "id": 3277762,
-    "project": "expandability",
-    "project_id": 465066,
-    "sha256": "0959cffb3a545730e6b2e1377bb89b59ff96e7f9142f54cc8035ab4fa2fc76e1"
-  },
-  {
-    "filename": "CodeChickenLib-1.16.5-4.0.2.429-universal.jar",
-    "id": 3398096,
-    "project": "codechicken-lib-1-8",
-    "project_id": 242818,
-    "sha256": "0254c780c5f20653cab34f6bc8178b1de1ce44de082dcd42ff1e1ee9ba9d5e3a"
-  },
-  {
-    "filename": "CookingForBlockheads_1.16.5-9.3.3.jar",
-    "id": 3368022,
-    "project": "cooking-for-blockheads",
-    "project_id": 231484,
-    "sha256": "6adc6a882c2647ecda2345321ec77572a7f0a3fcdeadae24fa5dc71f0e5af9bb"
-  },
-  {
-    "filename": "CosmeticArmorReworked-1.16.5-v4.jar",
-    "id": 3398000,
-    "project": "cosmetic-armor-reworked",
-    "project_id": 237307,
-    "sha256": "83a24d226acd7c86b94b4a8eac716b8a306c96e7d76a1a06bdcc2e2be9df9b21"
-  },
-  {
-    "filename": "craftingstation-4.1.1.jar",
-    "id": 3084325,
-    "project": "crafting-station",
-    "project_id": 318551,
-    "sha256": "a3516650a1c5e76b47b9efd69a4cfa9cda4f85250bf217fa7186f74ef375a7e4"
-  },
-  {
-    "filename": "create-mc1.16.5_v0.3.2b.jar",
-    "id": 3386319,
-    "project": "create",
-    "project_id": 328085,
-    "sha256": "7b0180bf62abe862f7dcb83a4281447b00fd7a26d488cfc17e4d6f590782cc8f"
-  },
-  {
-    "filename": "CreativeCore_v2.2.0_mc1.16.5.jar",
-    "id": 3338971,
-    "project": "creativecore",
-    "project_id": 257814,
-    "sha256": "8155f7a84695a68fd2e8b8f6fab0377b9d78cfbab9d8c125e6a9b58238d1eacc"
-  },
-  {
-    "filename": "curios-forge-1.16.5-4.0.5.2.jar",
-    "id": 3343065,
-    "project": "curios",
-    "project_id": 309927,
-    "sha256": "08d7558df6c621fca29758c349b95b137d2977cf1f3f61323fff4d85630d0641"
-  },
-  {
-    "filename": "dankstorage-3.16.jar",
-    "id": 3250771,
-    "project": "dank-storage",
-    "project_id": 335673,
-    "sha256": "bd5734d8ee8caf3a20574699d91f95b9e53df6b4d13f196f087d3f4bfe867621"
-  },
-  {
-    "filename": "decorative_blocks-1.16.4-1.7.2.jar",
-    "id": 3166283,
-    "project": "decorative-blocks",
-    "project_id": 362528,
-    "sha256": "f12dbfe76e36cdec65b8a575fc671f0291323a0de5ff420ff196d16bd19e6f84"
-  },
-  {
-    "filename": "DoggyTalents-1.16.5-2.0.1.10.jar",
-    "id": 3399830,
-    "project": "doggy-talents",
-    "project_id": 271050,
-    "sha256": "dab81029d8e1155749ec7144b39e578980456fd8b59461e218ed930d72e80cbd"
-  },
-  {
-    "filename": "easy_piglins-1.16.5-1.0.2.jar",
-    "id": 3309363,
-    "project": "easy-piglins",
-    "project_id": 419372,
-    "sha256": "66ac62e343203ed217a27a9038155192d4b3ee87908f7000347c5ee50526e5b5"
-  },
-  {
-    "filename": "easy_villagers-1.16.5-1.0.11.jar",
-    "id": 3327024,
-    "project": "easy-villagers",
-    "project_id": 400514,
-    "sha256": "845e937a59e1c3b2423aff0129248b82ae9bdd3a618f43645cc7be6fe974c183"
-  },
-  {
-    "filename": "EnchantmentDescriptions-1.16.5-7.0.14.jar",
-    "id": 3363585,
-    "project": "enchantment-descriptions",
-    "project_id": 250419,
-    "sha256": "60405ac61dbfb1e3c5d90479c2248f3e9408ca1089c524cefd021760c152f50c"
-  },
-  {
-    "filename": "EnderStorage-1.16.5-2.8.0.168-universal.jar",
-    "id": 3361748,
-    "project": "ender-storage-1-8",
-    "project_id": 245174,
-    "sha256": "31725d5af63fda688f38c7546a1e210332339fadd5fedc3144f9fb0b643bf8d2"
-  },
-  {
-    "filename": "extlights-3.3.jar",
-    "id": 3144281,
-    "project": "extended-lights-mod",
-    "project_id": 335051,
-    "sha256": "7f210f8e8bc451df301a6a2c22f81e434dd1835699444e5c0ed2bb2620847a6b"
-  },
-  {
-    "filename": "ExtraStorage-1.16.5-1.4.1.jar",
-    "id": 3336746,
-    "project": "extrastorage",
-    "project_id": 410168,
-    "sha256": "0c3ecafbcc4c7f8a91479d389add57d0db2943cf182352065535d6b5511bce4f"
-  },
-  {
-    "filename": "FarmingForBlockheads_1.16.5-7.3.1.jar",
-    "id": 3332379,
-    "project": "farming-for-blockheads",
-    "project_id": 261924,
-    "sha256": "94668c62457b655cf4bb2ff651adc43a2c2379e1ee4d545c57ff0d01c45db61e"
-  },
-  {
-    "filename": "FastLeafDecay-v25.jar",
-    "id": 3052146,
-    "project": "fast-leaf-decay",
-    "project_id": 230976,
-    "sha256": "0abd12217bd7e83d5427a4aca6acec27241bb4a7272ef79958a692bd60fe1d86"
-  },
-  {
-    "filename": "FastWorkbench-1.16.4-4.5.1.jar",
-    "id": 3245271,
-    "project": "fastworkbench",
-    "project_id": 288885,
-    "sha256": "99488d96c13fb062fc7d1281957d72f69fca0f1fa07f54c480337282a5092f23"
-  },
-  {
-    "filename": "fishingreal-1.16.3-1.0.0.jar",
-    "id": 3074201,
-    "project": "fishing-real",
-    "project_id": 348834,
-    "sha256": "1c2f868ee221e59407f6c8f1ec07fa7ccca49a819559dad818713a6778291fc5"
-  },
-  {
-    "filename": "HardcoreRevival_1.16.5-6.0.1.jar",
-    "id": 3344257,
-    "project": "hardcore-revival",
-    "project_id": 274036,
-    "sha256": "4a76642dd343070261f9151a37c2deb7e2c9efc031d4127f91b8b6d9b7614670"
-  },
-  {
-    "filename": "iceandfire-2.1.8-1.16.5.jar",
-    "id": 3361256,
-    "project": "ice-and-fire-dragons",
-    "project_id": 264231,
-    "sha256": "37d849bc66e32b1de6ff52c2002714a49673b08f4fd84f36a7e1a6fdbf20f69e"
-  },
-  {
-    "filename": "iChunUtil-1.16.5-10.4.1.jar",
-    "id": 3346209,
-    "project": "ichunutil",
-    "project_id": 229060,
-    "sha256": "d5a1be183d5f68ff520ddfa6a5db55dfe7d76f327fa98fd0a82209330815b5d9"
-  },
-  {
-    "filename": "ironchest-1.16.5-11.2.13.jar",
-    "id": 3405717,
-    "project": "iron-chests",
-    "project_id": 228756,
-    "sha256": "535b48cc3f12acacf42c2daff8709e45131d34bcc218a05203f62ce091e92a11"
-  },
-  {
-    "filename": "ironfurnaces-1.16.5-2.6.9.jar",
-    "id": 3387531,
-    "project": "iron-furnaces",
-    "project_id": 237664,
-    "sha256": "f9347a04dece94e645b581091f94cd33396e93a91209eb55cc6933e09196b0a1"
-  },
-  {
-    "filename": "jei-1.16.5-7.7.1.116.jar",
-    "id": 3401260,
-    "project": "jei",
-    "project_id": 238222,
-    "sha256": "d2c8b8e08646e060a053cb9eaba70229540a7fc0204287e561dfd91bbff2c29b"
-  },
-  {
-    "filename": "jeiintegration_1.16.5-7.0.1.15.jar",
-    "id": 3202331,
-    "project": "jei-integration",
-    "project_id": 265917,
-    "sha256": "0b45fe2858a8e9f97bf10fb218975a48a7d228ca27d274194c4dfaa91534bdfd"
-  },
-  {
-    "filename": "JustEnoughResources-1.16.5-0.12.1.121.jar",
-    "id": 3336760,
-    "project": "just-enough-resources-jer",
-    "project_id": 240630,
-    "sha256": "1fa5dce078ff98fb172ca658aa7c70345fb8af969c506d5125b419da93448d61"
-  },
-  {
-    "filename": "Kiwi-1.16.5-3.5.2.jar",
-    "id": 3377053,
-    "project": "kiwi",
-    "project_id": 303657,
-    "sha256": "1a175d5f6ca5329c5ef92c853b3112a6a4d4284b7896aeb4b60c21381f2c8caf"
-  },
-  {
-    "filename": "Lollipop-1.16.5-3.2.9.jar",
-    "id": 3232534,
-    "project": "lollipop",
-    "project_id": 347954,
-    "sha256": "bba84ef5f76510595f1ee693f650d4ee4202cea290b4139233ca26060a14e12b"
-  },
-  {
-    "filename": "lottaterracotta-1.16.5-1.3.2.jar",
-    "id": 3364628,
-    "project": "lotta-terracotta",
-    "project_id": 351060,
-    "sha256": "2a305378e261dee335fb680b4ac1cc362bed0b599a9fce6e248decbe1fa56c84"
-  },
-  {
-    "filename": "mcw-doors-1.0.3-mc1.16.5.jar",
-    "id": 3340793,
-    "project": "macaws-doors",
-    "project_id": 378646,
-    "sha256": "fb23ffda5f8407a01bbb8a1ec5b08dff1a8772a6e7a726dd085920be62337982"
-  },
-  {
-    "filename": "mcw-furniture-2.0.1-mc1.16.5.jar",
-    "id": 3182349,
-    "project": "macaws-furniture",
-    "project_id": 359540,
-    "sha256": "7f81b95c128ce97f3c41e29a4e98618c591f96321b53b718b5c3b6b8d3cb619e"
-  },
-  {
-    "filename": "metalbarrels-3.3a.jar",
-    "id": 3055811,
-    "project": "metal-barrels",
-    "project_id": 324985,
-    "sha256": "9bec62579ec71be41a303519e3b7944df0f3ee23a5b03ac7c0d0b27fe7c66150"
-  },
-  {
-    "filename": "overworld_two-1.0-Forge-1.16.4.jar",
-    "id": 3149167,
-    "project": "overworld-two-forge",
-    "project_id": 431157,
-    "sha256": "4995b774537ab31de6b98eb15aad3fbbfe6d3aa4e57108a9b3fe3abbe3d8da59"
-  },
-  {
-    "filename": "pamhc2crops-1.16.3-1.0.2.jar",
-    "id": 3276350,
-    "project": "pams-harvestcraft-2-crops",
-    "project_id": 361385,
-    "sha256": "5ebb51293d3e56ccf93875b7a4943577d78c1ee79401115230bb28cebbc7e832"
-  },
-  {
-    "filename": "pamhc2foodcore-1.16.3-1.0.2.jar",
-    "id": 3190867,
-    "project": "pams-harvestcraft-2-food-core",
-    "project_id": 372534,
-    "sha256": "e4414d35013e746e5b06256a08dd957a814b17cebcb035899a84a3692d08b544"
-  },
-  {
-    "filename": "pamhc2foodextended-1.16.3-1.0.2.jar",
-    "id": 3260454,
-    "project": "pams-harvestcraft-2-food-extended",
-    "project_id": 402231,
-    "sha256": "886ec5e6dca66382b99765b0033d17e270b792171a75dd8eb41fcfd86a5641e9"
-  },
-  {
-    "filename": "pamhc2trees-1.16.3-1.0.1.jar",
-    "id": 3281234,
-    "project": "pams-harvestcraft-2-trees",
-    "project_id": 365460,
-    "sha256": "e0f38f6a61e1da87981a249d520f2a8e43c4cefd29693076caf74ab8c5fe697f"
-  },
-  {
-    "filename": "PassableFoliage-1.16.5-2.3.1.jar",
-    "id": 3378277,
-    "project": "passable-foliage",
-    "project_id": 379887,
-    "sha256": "b18d228f6c8e34b8de54a0b0aa257e1be1eef7b65f8b7f75b3186e46f1b2118b"
-  },
-  {
-    "filename": "performant-1.16.2-5-3.72m.jar",
-    "id": 3401152,
-    "project": "performant",
-    "project_id": 354143,
-    "sha256": "cb3ef5fbedc6c9d7a0e379f7da400e22893a82425f27bd00bfd62e8cd8b35e20"
-  },
-  {
-    "filename": "Placebo-1.16.4-4.5.0.jar",
-    "id": 3331459,
-    "project": "placebo",
-    "project_id": 283644,
-    "sha256": "4a1bebf13a3dde1870fee6da242598f9a1c8005161fdd795052506e0c38fd5da"
-  },
-  {
-    "filename": "Platter-1.16-1.0.0.jar",
-    "id": 3115114,
-    "project": "platter",
-    "project_id": 381581,
-    "sha256": "6e4aee987ac4efa41a1b9cc26a4e4588c79a56bb200402b9fee71e43ab45a533"
-  },
-  {
-    "filename": "Powah-1.16.5-2.3.16.jar",
-    "id": 3232535,
-    "project": "powah",
-    "project_id": 352656,
-    "sha256": "78b652caa055f67f0479bac9a44e3ed67704bf4e59a48d06c7fd3cfe9ecb2b72"
-  },
-  {
-    "filename": "QuarkOddities-1.16.3.jar",
-    "id": 3088871,
-    "project": "quark-oddities",
-    "project_id": 301051,
-    "sha256": "5eafd942f2eb9b13edde3bff451ee968c1d0fe549c8decd2f8551e59a079711d"
-  },
-  {
-    "filename": "Quark-r2.4-316.jar",
-    "id": 3394265,
-    "project": "quark",
-    "project_id": 243121,
-    "sha256": "e5cea2e0aa0c229913dfb2735cc52c3889ad8d448bc1bdd64aa0dda3077b3676"
-  },
-  {
-    "filename": "refinedstorage-1.9.15.jar",
-    "id": 3400575,
-    "project": "refined-storage",
-    "project_id": 243076,
-    "sha256": "d49fc8ff38b973517e60bc5d17a1e98bc8b4c6870ec58d3df7a36ac780474180"
-  },
-  {
-    "filename": "RepairChests-1.16.5-1.7.jar",
-    "id": 3211620,
-    "project": "repair-chests",
-    "project_id": 401644,
-    "sha256": "d25687ae8c7a9caf7491b506852eb7a6edc827230794dca4ddd45628b5674df9"
-  },
-  {
-    "filename": "rsgauges-1.16.4-1.2.11.jar",
-    "id": 3390492,
-    "project": "redstone-gauges-and-switches",
-    "project_id": 296686,
-    "sha256": "65e6e7a7fac64130de455b8b8e3ec1a16ee48411df0ab3963790038019f69a25"
-  },
-  {
-    "filename": "selene-1.16.5-1.3.jar",
-    "id": 3377212,
-    "project": "selene",
-    "project_id": 499980,
-    "sha256": "49a08a86b9f63170fb1a9bf9c81d6a91157eecfbf150ac04bb010207a0133485"
-  },
-  {
-    "filename": "SnowRealMagic-1.16.4-2.5.8.jar",
-    "id": 3391417,
-    "project": "snow-real-magic",
-    "project_id": 308663,
-    "sha256": "153ba7328acbc0818361bb6f84fe4546aa1e9ddcd350ab5b6c97c6f7209b36b5"
-  },
-  {
-    "filename": "snowundertrees-1.16.5-v1.1.4.jar",
-    "id": 3247710,
-    "project": "snow-under-trees",
-    "project_id": 353942,
-    "sha256": "66cf77b4f9b654648e890fe6c55a3be9b3693f1be505d1c1e7b6ff1b91a1a54d"
-  },
-  {
-    "filename": "SoL-Carrot-1.16.5-1.10.0.jar",
-    "id": 3355731,
-    "project": "spice-of-life-carrot-edition",
-    "project_id": 277616,
-    "sha256": "b92f394d72b58e59e14d6cc337edf93d79617b02169ac44a3ec2a68820543d3a"
-  },
-  {
-    "filename": "spark-forge.jar",
-    "id": 3337641,
-    "project": "spark",
-    "project_id": 361579,
-    "sha256": "a162f9caf81073429bcb8df4844ef8eb43828c57d2956f55675499bc004e4802"
-  },
-  {
-    "filename": "StorageDrawers-1.16.3-8.3.0.jar",
-    "id": 3402515,
-    "project": "storage-drawers",
-    "project_id": 223852,
-    "sha256": "79ab53ab8d46aa517025fc4ecbb05b8492daff5f252aa4884ba46e8fefc3b794"
-  },
-  {
-    "filename": "supplementaries-1.16.5-0.14.3.jar",
-    "id": 3377218,
-    "project": "supplementaries",
-    "project_id": 412082,
-    "sha256": "42e91d1c58b9bd292263410e75971de8a59ce0c1f2d7979a2222591fc55eba28"
-  },
-  {
-    "filename": "sweetconcrete-1.16.5-1.7.2.jar",
-    "id": 3364624,
-    "project": "sweet-concrete",
-    "project_id": 351052,
-    "sha256": "6836f7f2a6f04edf6fe1efd4a6341c3c486c6c1ff824a858927375a45a121e33"
-  },
-  {
-    "filename": "swingthroughgrass-1.16.4-1.5.3.jar",
-    "id": 3103028,
-    "project": "swingthroughgrass",
-    "project_id": 264353,
-    "sha256": "d47132c8e97989f6f1b4c3c2c0736bf9e16e9a72970b3953fc80dcf8b1a4e31d"
-  },
-  {
-    "filename": "the_bumblezone-1.16.5-2.4.10-forge.jar",
-    "id": 3404007,
-    "project": "the-bumblezone-forge",
-    "project_id": 362479,
-    "sha256": "71fb56ddca8d5f671b1c5e588b60e352bb80fba135aab74056b4daa0ed44cefd"
-  },
-  {
-    "filename": "The_Undergarden-1.16.5-0.5.4.jar",
-    "id": 3361666,
-    "project": "the-undergarden",
-    "project_id": 379849,
-    "sha256": "b596836a5c1d50cf1c65c50ea728b0e295965cf9a4091a8eb1caac517aad5c50"
-  },
-  {
-    "filename": "towers_of_the_wild-1.16.4-2.0.1.jar",
-    "id": 3103750,
-    "project": "towers-of-the-wild",
-    "project_id": 386415,
-    "sha256": "fcd0e3f808569f0e547313a1ea3563c9a5d2fa8fbb638678eed6e46c1d8cfaf1"
-  },
-  {
-    "filename": "TravelersBackpack-1.16.5-5.4.2.jar",
-    "id": 3316664,
-    "project": "travelers-backpack",
-    "project_id": 321117,
-    "sha256": "e07aad8653f037ad96639a602fa260684f89757c905d6a47e1193154d274875e"
-  },
-  {
-    "filename": "weirdinggadget-1.16.(2-4)-2.2.7.jar",
-    "id": 3116235,
-    "project": "the-weirding-gadget",
-    "project_id": 258914,
-    "sha256": "fe9b2d4f39020a4239a19ea0e7229beec29eb8f1ef2b2b198b9aa5aad0b13318"
-  },
-  {
-    "filename": "Wither-Skeleton-Tweaks-1.16.4-5.3.0.jar",
-    "id": 3172803,
-    "project": "wither-skeleton-tweaks",
-    "project_id": 255902,
-    "sha256": "e6375312aeb188cda4951a4c4935343a64785303129dbb47f49f59768d0865d3"
-  },
-  {
-    "filename": "Xaeros_Minimap_21.14.1_Forge_1.16.5.jar",
-    "id": 3405505,
-    "project": "xaeros-minimap",
-    "project_id": 263420,
-    "sha256": "97278ddc89fe70b81387fc2ae45d986eb07e373b49977de5d358b8addf1103a2"
-  },
-  {
-    "filename": "XaerosWorldMap_1.16.0_Forge_1.16.5.jar",
-    "id": 3405517,
-    "project": "xaeros-world-map",
-    "project_id": 317780,
-    "sha256": "b4bceb6ebebf9a6c67a2e750e98d5cf2c1fe53fc66e487a79ac0d7a0664a8a12"
-  },
-  {
-    "filename": "YungsApi-1.16.4-Forge-11.jar",
-    "id": 3386962,
-    "project": "yungs-api",
-    "project_id": 421850,
-    "sha256": "d280edabd1f83ff45831e8c79dfdc5e9ca17158fa2ed1d05025afcea23ad83a9"
-  }
-]
diff --git a/pkgs/minecraft/voor-kia/update-mods.py b/pkgs/minecraft/voor-kia/update-mods.py
deleted file mode 100644
index 36722be..0000000
--- a/pkgs/minecraft/voor-kia/update-mods.py
+++ /dev/null
@@ -1,156 +0,0 @@
-import argparse
-import json
-import hashlib
-import pathlib
-from copy import deepcopy
-from datetime import datetime
-from enum import Enum
-from typing import Any, Dict, Generator, List, NamedTuple, Optional, Union
-
-import requests
-from dateutil import parser
-
-
-API = "https://addons-ecs.forgesvc.net/api/v2"
-JSON = Union[List[Dict[str, Any]], Dict[str, Any]]
-
-
-class ModLoader(Enum):
-    FORGE = 1
-    FABRIC = 4
-
-
-class File(NamedTuple):
-    id: int
-    gameVersions: List[str]
-    name: str
-    modLoader: Optional[ModLoader]
-    date: datetime
-
-    @classmethod
-    def from_json(cls, f: JSON):
-        assert isinstance(f, dict)
-
-        assert isinstance(f.get("gameVersion"), list)
-        assert isinstance(f.get("id"), int)
-        assert isinstance(f.get("fileName"), str)
-        assert isinstance(f.get("fileDate"), str)
-
-        modLoader = (
-            ModLoader.FORGE
-            if "Forge" in f["gameVersion"]
-            else ModLoader.FABRIC
-            if "Fabric" in f["gameVersion"]
-            else None
-        )
-
-        return cls(
-            f["id"],
-            f["gameVersion"],
-            f["fileName"],
-            modLoader,
-            parser.isoparse(f["fileDate"]),
-        )
-
-
-class CurseAPI:
-    def __init__(self):
-        self._session = requests.Session()
-        self._session.headers[
-            "User-Agent"
-        ] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0"
-
-    def get_latest_files(self, mod_id: int) -> Generator[File, None, None]:
-        res = self._session.get(f"{API}/addon/{mod_id}/files")
-        res.raise_for_status()
-
-        latest_files = res.json()
-
-        return (File.from_json(f) for f in latest_files)
-
-    def get_file_url(self, mod_id: int, file_id: int) -> str:
-        res = self._session.get(f"{API}/addon/{mod_id}/file/{file_id}/download-url")
-        res.raise_for_status()
-        return res.text.rstrip("\n")
-
-    def download_file(self, mod_id: int, file_id: int) -> bytes:
-        url = self.get_file_url(mod_id, file_id)
-        file_ = self._session.get(url)
-        file_.raise_for_status()
-        return file_.content
-
-
-def main():
-    parser = argparse.ArgumentParser()
-    parser.add_argument("version", help="The minecraft version to limit updates to")
-    parser.add_argument(
-        "--mod-loader", choices=["none", "forge", "fabric"], default="forge"
-    )
-    parser.add_argument("--infile", type=pathlib.Path)
-    args = parser.parse_args()
-
-    if args.mod_loader == "forge":
-        mod_loader = ModLoader.FORGE
-    elif args.mod_loader == "fabric":
-        mod_loader = ModLoader.FABRIC
-    else:
-        raise AssertionError("Unreachable")
-
-    update(args.infile, args.version, mod_loader)
-
-
-def update(infile: pathlib.Path, version: str, mod_loader: ModLoader):
-    with open(infile) as mods_json:
-        mods = json.load(mods_json)
-
-    curse = CurseAPI()
-    new_mods = []
-
-    for mod in mods:
-        print(f"Checking for updates to {mod['project']}...")
-
-        try:
-            latest_files = list(curse.get_latest_files(mod["project_id"]))
-        except requests.HTTPError as err:
-            print(f"WARNING: Could not access curse API for {mod['project']}: {err}")
-            latest_files = [_ for _ in []]
-
-        def compatible(file_: File) -> bool:
-            return (
-                mod_loader is None
-                or file_.modLoader is None
-                or file_.modLoader == mod_loader
-            ) and any(
-                file_version.startswith(version) for file_version in file_.gameVersions
-            )
-
-        compatible_files = list(filter(compatible, latest_files))
-        if compatible_files:
-            latest = max(compatible_files, key=lambda f: f.date)
-            if latest.id != mod["id"]:
-                print(
-                    f"Updating {mod['project']} {mod['filename']} -> {latest.name}..."
-                )
-                contents = curse.download_file(mod["project_id"], latest.id)
-                sha256 = hashlib.sha256(contents).hexdigest()
-
-                new_mod = deepcopy(mod)
-                new_mod.update(
-                    {"filename": latest.name, "id": latest.id, "sha256": sha256}
-                )
-                new_mods.append(new_mod)
-            else:
-                new_mods.append(mod)
-        else:
-            print(f"WARNING: No compatible files found for {mod['project']}")
-            print(
-                f"Versions available: {[(f.name, f.gameVersions) for f in latest_files]}"
-            )
-            new_mods.append(mod)
-
-    with open("temp.json", "w") as out:
-        json.dump(new_mods, out, sort_keys=True, indent=2)
-
-
-if __name__ == "__main__":
-    main()

From e512e73b5eb66de52f04aaa996d6cce67c0d90c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 12 Oct 2022 01:17:49 +0100
Subject: [PATCH 047/212] flake.nix: Clean up and refactor

---
 flake.lock |  30 ++++++---
 flake.nix  | 191 ++++++++++++++++++++++++-----------------------------
 2 files changed, 107 insertions(+), 114 deletions(-)

diff --git a/flake.lock b/flake.lock
index 5c75d61..c6f9923 100644
--- a/flake.lock
+++ b/flake.lock
@@ -2,11 +2,26 @@
   "nodes": {
     "flake-utils": {
       "locked": {
-        "lastModified": 1649676176,
-        "narHash": "sha256-OWKJratjt2RW151VUlJPRALb7OU2S5s+f0vLj4o1bHM=",
+        "lastModified": 1659877975,
+        "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "a4b154ebbdc88c8498a5c7b01589addc9e9cb678",
+        "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "flake-utils_2": {
+      "locked": {
+        "lastModified": 1659877975,
+        "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
         "type": "github"
       },
       "original": {
@@ -70,7 +85,6 @@
     },
     "root": {
       "inputs": {
-        "flake-utils": "flake-utils",
         "nixos-hardware": "nixos-hardware",
         "nixpkgs": "nixpkgs",
         "sops-nix": "sops-nix",
@@ -125,9 +139,7 @@
     },
     "tlaternet-templates": {
       "inputs": {
-        "flake-utils": [
-          "flake-utils"
-        ],
+        "flake-utils": "flake-utils",
         "nixpkgs": [
           "nixpkgs"
         ]
@@ -148,9 +160,7 @@
     },
     "tlaternet-webserver": {
       "inputs": {
-        "flake-utils": [
-          "flake-utils"
-        ],
+        "flake-utils": "flake-utils_2",
         "naersk": "naersk",
         "nixpkgs": [
           "nixpkgs"
diff --git a/flake.nix b/flake.nix
index 1ae56cc..e1f2353 100644
--- a/flake.nix
+++ b/flake.nix
@@ -4,7 +4,6 @@
   inputs = {
     nixpkgs.url = "github:nixos/nixpkgs/nixos-21.11";
     nixos-hardware.url = "github:nixos/nixos-hardware/master";
-    flake-utils.url = "github:numtide/flake-utils";
     sops-nix = {
       url = "github:Mic92/sops-nix";
       inputs.nixpkgs.follows = "nixpkgs";
@@ -12,17 +11,11 @@
 
     tlaternet-webserver = {
       url = "git+https://gitea.tlater.net/tlaternet/tlaternet.git";
-      inputs = {
-        flake-utils.follows = "flake-utils";
-        nixpkgs.follows = "nixpkgs";
-      };
+      inputs.nixpkgs.follows = "nixpkgs";
     };
     tlaternet-templates = {
       url = "git+https://gitea.tlater.net/tlaternet/tlaternet-templates.git";
-      inputs = {
-        flake-utils.follows = "flake-utils";
-        nixpkgs.follows = "nixpkgs";
-      };
+      inputs.nixpkgs.follows = "nixpkgs";
     };
   };
 
@@ -30,12 +23,12 @@
     self,
     nixpkgs,
     nixos-hardware,
-    flake-utils,
     sops-nix,
     tlaternet-webserver,
     tlaternet-templates,
-    ...
-  } @ inputs: let
+  }: let
+    system = "x86_64-linux";
+
     overlays = [
       (final: prev: {
         tlaternet-webserver =
@@ -47,102 +40,92 @@
         };
       })
     ];
-  in
-    {
-      nixosConfigurations = {
-        tlaternet = let
-          system = "x86_64-linux";
-        in
-          nixpkgs.lib.nixosSystem {
-            inherit system;
 
-            modules = [
-              ({modulesPath, ...}: {
-                imports = [(modulesPath + "/profiles/headless.nix")];
-                nixpkgs.overlays = overlays;
-              })
-              (import ./modules)
+    pkgs = import nixpkgs {inherit system overlays;};
+    sops-pkgs = sops-nix.packages.${system};
+  in {
+    nixosConfigurations = {
+      tlaternet = nixpkgs.lib.nixosSystem {
+        inherit system;
 
-              (import ./configuration)
-              (import ./configuration/linode.nix)
-              (import ./configuration/hardware-configuration.nix)
-              sops-nix.nixosModules.sops
-            ];
-          };
+        modules = [
+          ({modulesPath, ...}: {
+            imports = [(modulesPath + "/profiles/headless.nix")];
+            nixpkgs.overlays = overlays;
+          })
+          (import ./modules)
 
-        vm = let
-          system = "x86_64-linux";
-        in
-          nixpkgs.lib.nixosSystem {
-            inherit system;
-
-            modules = [
-              ({modulesPath, ...}: {
-                imports = [(modulesPath + "/profiles/headless.nix")];
-                nixpkgs.overlays = overlays;
-              })
-              (import ./modules)
-
-              (import ./configuration)
-              sops-nix.nixosModules.sops
-              ({lib, ...}: {
-                users.users.tlater.password = "insecure";
-
-                # Disable graphical tty so -curses works
-                boot.kernelParams = ["nomodeset"];
-
-                # Sets the base domain for nginx to localhost so that we
-                # can easily test locally with the VM.
-                services.nginx.domain = lib.mkOverride 99 "localhost";
-
-                # # Set up VM settings to match real VPS
-                # virtualisation.memorySize = 3941;
-                # virtualisation.cores = 2;
-              })
-            ];
-          };
-      };
-    }
-    // flake-utils.lib.eachDefaultSystem (system: let
-      pkgs = import nixpkgs {inherit system overlays;};
-      sops-pkgs = sops-nix.packages.${system};
-    in {
-      devShell = pkgs.mkShell {
-        sopsPGPKeyDirs = ["./keys/hosts/" "./keys/users/"];
-        nativeBuildInputs = with sops-pkgs; [
-          sops-import-keys-hook
+          (import ./configuration)
+          (import ./configuration/linode.nix)
+          (import ./configuration/hardware-configuration.nix)
+          sops-nix.nixosModules.sops
         ];
-        buildInputs = with pkgs;
-        with sops-pkgs; [
-          nixfmt
-          git-lfs
-          sops-init-gpg-key
-        ];
-        shellHook = let
-          inherit (pkgs.lib.attrsets) mapAttrsToList;
-          inherit (pkgs.lib.strings) concatStringsSep;
-          ports = {
-            "3022" = "2222";
-            "3080" = "80";
-            "3443" = "443";
-            "3021" = "2221";
-            "25565" = "25565";
-            "21025" = "21025"; # Starbound
-          };
-          QEMU_NET_OPTS =
-            concatStringsSep ","
-            (mapAttrsToList
-              (host: vm: "hostfwd=::${host}-:${vm}")
-              ports);
-        in ''
-          export QEMU_OPTS="-m 3941 -smp 2 -curses"
-          export QEMU_NET_OPTS="${QEMU_NET_OPTS}"
-
-          # Work around sudo requiring a full terminal
-          export NIX_SSHOPTS="-t"
-        '';
       };
 
-      packages = import ./pkgs {inherit pkgs;};
-    });
+      vm = nixpkgs.lib.nixosSystem {
+        inherit system;
+
+        modules = [
+          ({modulesPath, ...}: {
+            imports = [(modulesPath + "/profiles/headless.nix")];
+            nixpkgs.overlays = overlays;
+          })
+          (import ./modules)
+
+          (import ./configuration)
+          sops-nix.nixosModules.sops
+          ({lib, ...}: {
+            users.users.tlater.password = "insecure";
+
+            # Disable graphical tty so -curses works
+            boot.kernelParams = ["nomodeset"];
+
+            # Sets the base domain for nginx to localhost so that we
+            # can easily test locally with the VM.
+            services.nginx.domain = lib.mkOverride 99 "localhost";
+
+            # # Set up VM settings to match real VPS
+            # virtualisation.memorySize = 3941;
+            # virtualisation.cores = 2;
+          })
+        ];
+      };
+    };
+
+    devShells.${system}.default = pkgs.mkShell {
+      sopsPGPKeyDirs = ["./keys/hosts/" "./keys/users/"];
+      nativeBuildInputs = [
+        sops-pkgs.sops-import-keys-hook
+      ];
+      buildInputs = with pkgs; [
+        nixfmt
+        git-lfs
+        sops-pkgs.sops-init-gpg-key
+      ];
+
+      shellHook = let
+        inherit (pkgs.lib.attrsets) mapAttrsToList;
+        inherit (pkgs.lib.strings) concatStringsSep;
+        ports = {
+          "2222" = "2222";
+          "3080" = "80";
+          "3443" = "443";
+          "2221" = "2221";
+          "21025" = "21025"; # Starbound
+        };
+        QEMU_NET_OPTS =
+          concatStringsSep ","
+          (mapAttrsToList
+            (host: vm: "hostfwd=::${host}-:${vm}")
+            ports);
+      in ''
+        export QEMU_OPTS="-m 3941 -smp 2 -curses"
+        export QEMU_NET_OPTS="${QEMU_NET_OPTS}"
+
+        # Work around sudo requiring a full terminal when deploying to
+        # a remote host
+        export NIX_SSHOPTS="-t"
+      '';
+    };
+  };
 }

From dea9032530f80b8defd4251f23277f947aec9901 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 12 Oct 2022 13:11:11 +0100
Subject: [PATCH 048/212] flake.nix: Add app to start VM through `nix run`

---
 flake.nix | 46 +++++++++++++++++++++++++++-------------------
 1 file changed, 27 insertions(+), 19 deletions(-)

diff --git a/flake.nix b/flake.nix
index e1f2353..852694f 100644
--- a/flake.nix
+++ b/flake.nix
@@ -92,6 +92,32 @@
       };
     };
 
+    apps.${system}.default = let
+      inherit (self.nixosConfigurations.vm.config.system.build) vm;
+      inherit (nixpkgs.legacyPackages.${system}) writeShellScript;
+      inherit (nixpkgs.lib.attrsets) mapAttrsToList;
+      inherit (nixpkgs.lib.strings) concatStringsSep;
+      ports = {
+        "2222" = "2222";
+        "3080" = "80";
+        "3443" = "443";
+        "2221" = "2221";
+        "21025" = "21025"; # Starbound
+      };
+      QEMU_NET_OPTS =
+        concatStringsSep ","
+        (mapAttrsToList
+          (host: vm: "hostfwd=::${host}-:${vm}")
+          ports);
+    in {
+      type = "app";
+      program = builtins.toString (writeShellScript "run-vm" ''
+        export QEMU_OPTS="-m 3941 -smp 2 -curses"
+        export QEMU_NET_OPTS="${QEMU_NET_OPTS}"
+        "${vm}/bin/run-tlaternet-vm"
+      '');
+    };
+
     devShells.${system}.default = pkgs.mkShell {
       sopsPGPKeyDirs = ["./keys/hosts/" "./keys/users/"];
       nativeBuildInputs = [
@@ -103,25 +129,7 @@
         sops-pkgs.sops-init-gpg-key
       ];
 
-      shellHook = let
-        inherit (pkgs.lib.attrsets) mapAttrsToList;
-        inherit (pkgs.lib.strings) concatStringsSep;
-        ports = {
-          "2222" = "2222";
-          "3080" = "80";
-          "3443" = "443";
-          "2221" = "2221";
-          "21025" = "21025"; # Starbound
-        };
-        QEMU_NET_OPTS =
-          concatStringsSep ","
-          (mapAttrsToList
-            (host: vm: "hostfwd=::${host}-:${vm}")
-            ports);
-      in ''
-        export QEMU_OPTS="-m 3941 -smp 2 -curses"
-        export QEMU_NET_OPTS="${QEMU_NET_OPTS}"
-
+      shellHook = ''
         # Work around sudo requiring a full terminal when deploying to
         # a remote host
         export NIX_SSHOPTS="-t"

From ab3aa1948196e694f633133be326986e3dec9565 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 12 Oct 2022 01:24:54 +0100
Subject: [PATCH 049/212] treewide: Perform another nitpicking sweep

---
 configuration/default.nix | 11 ++++++-----
 configuration/linode.nix  |  5 -----
 modules/default.nix       | 11 +++++------
 3 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index b008454..4b9bfa1 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -13,7 +13,6 @@
   ];
 
   nix = {
-    # Enable flakes
     package = pkgs.nixFlakes;
     extraOptions = ''
       experimental-features = nix-command flakes
@@ -31,6 +30,8 @@
     secrets.steam = {};
   };
 
+  # Optimization for minecraft servers, see:
+  # https://bugs.mojang.com/browse/MC-183518
   boot.kernelParams = ["highres=off" "nohz=off"];
 
   networking = {
@@ -71,7 +72,7 @@
     domain = "tlater.net";
 
     virtualHosts = let
-      host = port: extra:
+      proxyPassToPort = port: extra:
         lib.recursiveUpdate {
           forceSSL = true;
           enableACME = true;
@@ -83,9 +84,9 @@
         extra;
       domain = config.services.nginx.domain;
     in {
-      "${domain}" = host 3002 {serverAliases = ["www.${domain}"];};
-      "gitea.${domain}" = host 3000 {};
-      "nextcloud.${domain}" = host 3001 {};
+      "${domain}" = proxyPassToPort 3002 {serverAliases = ["www.${domain}"];};
+      "gitea.${domain}" = proxyPassToPort 3000 {};
+      "nextcloud.${domain}" = proxyPassToPort 3001 {};
     };
   };
 
diff --git a/configuration/linode.nix b/configuration/linode.nix
index 4224cfe..7d6a780 100644
--- a/configuration/linode.nix
+++ b/configuration/linode.nix
@@ -1,9 +1,4 @@
 {
-  config,
-  lib,
-  pkgs,
-  ...
-}: {
   # Required for the lish console
   boot.kernelParams = ["console=ttyS0,19200n8"];
 
diff --git a/modules/default.nix b/modules/default.nix
index 46f5e10..55e356c 100644
--- a/modules/default.nix
+++ b/modules/default.nix
@@ -1,9 +1,8 @@
-{lib, ...}:
-with lib; {
-  imports = [./virtualisation/pods.nix];
-
-  options.services.nginx.domain = mkOption {
-    type = types.str;
+{lib, ...}: let
+  inherit (lib) mkOption types;
+in {
+  options.services.nginx.domain = lib.mkOption {
+    type = lib.types.str;
     description = "The base domain name to append to virtual domain names";
   };
 }

From 6a81ce4c1d2605127a707286852d07cb48bb6384 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 12 Oct 2022 02:03:22 +0100
Subject: [PATCH 050/212] sops: Improve secrets provisioning to split out
 staging

---
 .sops.yaml                           |  9 ++++-
 configuration/default.nix            |  6 +---
 configuration/services/starbound.nix |  2 +-
 configuration/sops.nix               | 10 ++++++
 flake.nix                            |  3 ++
 keys/hosts/staging.asc               | 28 ++++++++++++++++
 keys/production.yaml                 | 50 ++++++++++++++++++++++++++++
 keys/staging.yaml                    | 50 ++++++++++++++++++++++++++++
 8 files changed, 151 insertions(+), 7 deletions(-)
 create mode 100644 configuration/sops.nix
 create mode 100644 keys/hosts/staging.asc
 create mode 100644 keys/production.yaml
 create mode 100644 keys/staging.yaml

diff --git a/.sops.yaml b/.sops.yaml
index ad56f8b..4c17c75 100644
--- a/.sops.yaml
+++ b/.sops.yaml
@@ -1,9 +1,16 @@
 keys:
   - &tlater 535B61015823443941C744DD12264F6BBDFABA89
   - &server_tlaternet 8a3737d48f1035fe6c3a0a8fd6a1976ca74c7f3b
+  - &server_staging 7762ec55a5727cabada621d961e53f94caa314e4
 
 creation_rules:
-  - key_groups:
+  - path_regex: keys/production.yaml
+    key_groups:
       - pgp:
           - *tlater
           - *server_tlaternet
+  - path_regex: keys/staging.yaml
+    key_groups:
+      - pgp:
+          - *tlater
+          - *server_staging
diff --git a/configuration/default.nix b/configuration/default.nix
index 4b9bfa1..d84302a 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -10,6 +10,7 @@
     ./services/webserver.nix
     ./services/starbound.nix
     ./ids.nix
+    ./sops.nix
   ];
 
   nix = {
@@ -25,11 +26,6 @@
   nixpkgs.config.allowUnfreePredicate = pkg:
     builtins.elem (lib.getName pkg) ["steam-runtime" "steamcmd"];
 
-  sops = {
-    defaultSopsFile = ../keys/external.yaml;
-    secrets.steam = {};
-  };
-
   # Optimization for minecraft servers, see:
   # https://bugs.mojang.com/browse/MC-183518
   boot.kernelParams = ["highres=off" "nohz=off"];
diff --git a/configuration/services/starbound.nix b/configuration/services/starbound.nix
index e8a0772..5dc0961 100644
--- a/configuration/services/starbound.nix
+++ b/configuration/services/starbound.nix
@@ -16,7 +16,7 @@ in {
 
       # Credential loading for steam auth (if necessary; prefer
       # anonymous login wherever possible).
-      LoadCredential = "steam:/run/secrets/steam";
+      LoadCredential = "steam:/run/secrets/steam/tlater";
 
       # Security settings
       DynamicUser = true;
diff --git a/configuration/sops.nix b/configuration/sops.nix
new file mode 100644
index 0000000..8efa3af
--- /dev/null
+++ b/configuration/sops.nix
@@ -0,0 +1,10 @@
+{
+  sops = {
+    defaultSopsFile = ../keys/production.yaml;
+    secrets."nextcloud/tlater" = {
+      owner = "nextcloud";
+      group = "nextcloud";
+    };
+    secrets."steam/tlater" = {};
+  };
+}
diff --git a/flake.nix b/flake.nix
index 852694f..5ff0a51 100644
--- a/flake.nix
+++ b/flake.nix
@@ -84,6 +84,9 @@
             # can easily test locally with the VM.
             services.nginx.domain = lib.mkOverride 99 "localhost";
 
+            # Use the staging secrets
+            sops.defaultSopsFile = lib.mkOverride 99 ./keys/staging.yaml;
+
             # # Set up VM settings to match real VPS
             # virtualisation.memorySize = 3941;
             # virtualisation.cores = 2;
diff --git a/keys/hosts/staging.asc b/keys/hosts/staging.asc
new file mode 100644
index 0000000..fbabfe2
--- /dev/null
+++ b/keys/hosts/staging.asc
@@ -0,0 +1,28 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+xsFNBAAAAAABEAC32/CXnt4LDPdPZppQ0GcJAxVFHFu8SCl5WnU/PVPEnwgRkV8V
+ZeyQN4qgT5LPWgPYyDyAqUHBUwRxvVcguw0fOlDBZ3nECKQxZ53OVlay7xfhgXO1
+luNu657u5VYtxfLqx7lVHfY/TWp5DBOOEpOtoKfz031Zbg11+kdxW5eEg2ypCTvn
++MVQgRH9AQI+0+jegQ9On3X9UaVdc8etuY/F8BAEwLCCbYpLUEUXwOo4YLB36Kg3
+P27q15Nl6g5P/oFEdS3fhHbh9636lJnxJcTTjAfJaDoQJ5rGDASiT8HJnkNWfrf/
+yzLMOiy6fRRIz8HTXKeZNeRvCPu1uHaWYi0RprWMu1HZ0cLzr5N2lHKcWgL8En5b
+fPyqldFfJBlY36L59F7hTk10QBgqFhibcXB44iK96jnYw6LgSuFkbfrJr7fx67JN
+lM2Xi4WXvzkp3gboDxd2Xy3ChQrQXmXcVAl8XNs78f5AQh5MJP6iC7ayiIsHq4aH
+rGVLhbncfKpw4OL9jVNTyRinwpvl5qibLAJbDA7arn8XqT6FT0KjeLa91jTFLHGn
+9IkJol+L0/zYrpyiid5ZKNJMousxJoXymzRkeYllr+nLjKNLv0L3MCnsiPEZ23iL
+y2/UZ6Vcjrs50L46VuiewCEaVbBp1H9Ps5eUa2YoJ65sfe7wnscXI8oOpQARAQAB
+zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT
+AQgAFgUCAAAAAAkQYeU/lMqjFOQCGw8CGQEAAEKvEABZo9JRHnwrKr7UGmynctmF
+aR+1KApeWrqahhobgfvMjJLfnUV7UDSeiuf3juoZC+L1d8LqEp0czcqU1YuGtjTT
+Yk/4WDwc7G9MjHDgVXPZlQ/qxSYBFwowbUkfhj49UA4Np2PW3yLtoZnBHLz6tmaD
+mTtdNjzEw+L0GQ9Wi2pQYSUV4I9URF/NH7NGmurNl8Y5SHb3rqFQ4CPGXk5UQYL5
+s0ZdArwgWNH+ceC1Kq0baKu5WJINFfCIJbJajATBqgPy6FPEmhUdgt8awOp01oEc
+zs2930sc6YY5GJVEGnxR/qBLTA5lANS1mpqHd9s4YF7jj8h/q8SV4iegTeKHrLox
+v1bP+QzHquCn7BpO9V6GD/eaqBKfx6k6+HDb5YmKnBvBV/c3yJ6wiv1H32nauWs1
+CgiJNYV+A/+YnWf0uPRqelAzT06JUtnSBZ0ppKLR68X3IKisXVNzW/3pM/ZWWfFM
+uKHCoppH2iuStn2wPkdjJD4UHduAFyF1oj1jFwP9r+EuhhPH1qr40405jRdOR98P
+RuPhrSkLBdWiUlNintDOyFzNbKXMZlreZeATeT5y/H+IF3CDvgAhBo7KqhfBfgUK
+6P/1xk8DozTmlsKY/cOsK0aL47CJcg8LU6tHrxa8uP6qV2HbUD31WbCRr1eL8k2G
+xszxEVPuKG8ckw58WpT4vA==
+=kJ/7
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/keys/production.yaml b/keys/production.yaml
new file mode 100644
index 0000000..bfc494f
--- /dev/null
+++ b/keys/production.yaml
@@ -0,0 +1,50 @@
+nextcloud:
+    tlater: ENC[AES256_GCM,data:zNsPm4uFaIRe3LjcwmayRg==,iv:5wam6bP5zP708jC9UrLV0s8qspl3Pm4fPzbMFYBUyPQ=,tag:apnJUMeJwMn9q0NhO4ptmA==,type:str]
+steam:
+    tlater: ENC[AES256_GCM,data:HNsve/Wid40ftclO9n09yXg=,iv:VQxAz4eR9lfxEvM0zl1FpJpbKrEFxjIYLyCqL9Aool0=,tag:LHcpHCXAHe8p2kOvOnKXyw==,type:str]
+sops:
+    kms: []
+    gcp_kms: []
+    azure_kv: []
+    hc_vault: []
+    age: []
+    lastmodified: "2022-10-12T13:13:37Z"
+    mac: ENC[AES256_GCM,data:+EuA0rblxZYk+0tZs3vUFtr1cVKhdrLi4Ww0QjeITZn2k+SL8Y2gRl3gNVQOe00WHUgSKN53QKhxDj4q6Rd0LfwASxRRjz78Mk8yHDRDIfdDS960EasgKON4HPW/eMd2Fp4+flv57KYywQQWp3AlD8JqxIf5wNhyywn5LlW3PCQ=,iv:YFIk0LrRjV8417QJ5cp5EuIm7bezyG8ZulKcu1xhIF4=,tag:vtq5hCuLEXOvRjE2D/5cCQ==,type:str]
+    pgp:
+        - created_at: "2022-10-12T00:46:51Z"
+          enc: |
+            -----BEGIN PGP MESSAGE-----
+
+            hQEMA7x7stsXx45CAQf9Hivg5x2NEKp3icdAIXKoBVTp5jnqJ2S5xDpK4cbCUwRd
+            Z2VyNjxAXdTgKsviXseWbtsEbqo41oqjtpZwXK36gT/miKSPYyBSLb689L70RpWR
+            aC4QzOHbYr1Trr1whkTVaQG1vd2u9ZEyxsi13ItiYVylu7tgMqaDqzE4Y47RPZtz
+            FWFY4chO5Tq/DL0blP8oCTLFx4LSL82JbZswCfqrSHX44HGZ/OELHqNhYNF6hkCr
+            DgYYh7l7s08farE+PnTbWt808Kd3kP8fCRaLm9nt1X1c5QQElaWBjGIscK9fOsV4
+            iVFQfPBdwBi8aawCmwvXOcg6sX050Ow3NeYQBJVICtJeAeHyetxxEYip6CrADsiq
+            UG1Np+p6Pcbq/k6E1vT6bsRrhUWPYC4yuh6Edg5p/jxa4DAlsq/OgDI9pquE9aIt
+            F8cQMHfIkNP8/HiM/KwmdHoTJiy8YCwqP/UalSJdVw==
+            =lnlW
+            -----END PGP MESSAGE-----
+          fp: 535B61015823443941C744DD12264F6BBDFABA89
+        - created_at: "2022-10-12T00:46:51Z"
+          enc: |
+            -----BEGIN PGP MESSAGE-----
+
+            hQIMA9ahl2ynTH87AQ/+ID/6Dcbat+YRvT8VpfKpZf2O6EFbI3dlPDkZ+f4yFW0R
+            uGKkLR69utM8FoEn1XUkPG3klDk5t/gQikS/d1lPZ6cPOsVzY4P2Te6LizP25vCE
+            cHkztZG/IuBCBfLp8xsEjF1OXEDnb7Klqd3aJuYrvJNm3SreNydRAGyM1E94+iQL
+            zLrHF0WbD+dVdVG+ZoHKouGHVVmcxTkfi8Ce63pHKxOiMgqJLnImC357mle4DlJV
+            1My0CPV9Y1ElY+W5s+a7sRgursR0AVOkuvWYT39VW+RmFpUZyRCgyW+L6ilCEcOV
+            VXJHf0IFylkqevh11BssIetHAtT8anqZ+wo3ON4gEHjcahufc1h8rOxEEsWe/qUC
+            XZzfwilOsY/vKJ+GTz5Cp8XAviozQL5o2O5H9PiHxQl019QHZgprJclGMlukCBkR
+            Uo3h1Rl2na8JqcolAlFGQ1/QxsOnJ/KAmOpUZ7fZqG2qnsXnFjXcuqo+0e58odaT
+            sZLIspvsEHBHKzsvUa6BT8bTc+GlsB3hFolBVdX4y9kTWuzxy0K6bKA9HMTf4FPW
+            w2hIlvYhlgEx9MVqKLbemN3ye2rC3GRUBXxVXmlXBmb7nXPZCOGqL6nrvtsQ1E4h
+            D9+sN+cvYh5lYPByjXYinT8TqFVpqX++qnpgHC+5c6WtDHlhRAyfIQK51wCyiZbS
+            UAG6iDEbCWwD7uHZjDmVycC2R/0HnO+o9xMBI6teKYziFhvn8m7R9gzr7zn/0x3t
+            dVMXtojhfbMPzYK0gT6xOn8SbYGH0MV7ddOm7+Kl3Z8Y
+            =zDer
+            -----END PGP MESSAGE-----
+          fp: 8a3737d48f1035fe6c3a0a8fd6a1976ca74c7f3b
+    unencrypted_suffix: _unencrypted
+    version: 3.7.2
diff --git a/keys/staging.yaml b/keys/staging.yaml
new file mode 100644
index 0000000..14a683a
--- /dev/null
+++ b/keys/staging.yaml
@@ -0,0 +1,50 @@
+nextcloud:
+    tlater: ENC[AES256_GCM,data:91kDcO4hpng=,iv:ayuILRmRru4ZxTCur9H2xHuLjkDzwPdS/4lEog/tesU=,tag:qYhJxnNDcCwUM7xe7Tlcjw==,type:str]
+steam:
+    tlater: ENC[AES256_GCM,data:jcW4wacGzOQ=,iv:KstKGHflscSWDFXGbnAZUcsqGN4Ot+w7sRbsAUwZNHQ=,tag:n9sRWvaKSgagpIgV/NF/Og==,type:str]
+sops:
+    kms: []
+    gcp_kms: []
+    azure_kv: []
+    hc_vault: []
+    age: []
+    lastmodified: "2022-10-12T13:14:20Z"
+    mac: ENC[AES256_GCM,data:IlU8Jr+HD/ZHHsd7eaaSGp3tRxGy8/yhbSejkWmHFeL1WsvdWsToHM7yah2WzX+uY7s/i7atHQdhbHITCi6gBIFociVVPwziK5YOmTXv1fHlcD60U4ClRbTtgMVMtvc5tXrxdLQGhaX+DJ5xXBhTlCSwwqgYP0I7vJmEUF9mz7g=,iv:IM1ebqQB1UO5EN92kipHL20iGtFTKJhUiN/XR6psWBM=,tag:WweauZ5pA7/YMuUuq8C/xQ==,type:str]
+    pgp:
+        - created_at: "2022-10-12T16:48:23Z"
+          enc: |
+            -----BEGIN PGP MESSAGE-----
+
+            hQEMA7x7stsXx45CAQf/QKXxlgFzUn5ZS02JDiOLds6wjsiTbwQeIy+den+qH9KF
+            CyfC/8WhxojyhliG0zUzQ7oHtYYkbknF2DyrR7J4+S3SyvMS6MDGTUUn5dIcGwBO
+            2/Q2bt4ayOJFNTPePA0IfuMYNUiMl5B/0GCFRV9DE+gG/dcsOzM5q1Uya/yJ1966
+            RndWwbnE4j5yP4Nj2o3OiZFhlNi6W6UffYB0hsTTPmmebIZltDRbmLSSpKcfNEYw
+            h3st3WaJ0BCuQC5i/kvYTfJyBCoYnvFrb3RmXm3h+MvW0JZwHzfbST3nJCBHh5XJ
+            fVquF17oDJzn5S7EdWMhUbWwHgZwz2J6sZMgGEQ6WdJeAf2IlCuRYGjQMcB1WhxH
+            GCgbzUGoOGrxT3euzz9R1J98d1HQqtpFgeg9JgWndUdhoF80+AU7Wpyy6qOg2n/4
+            wCcb4pcqG1OqFezauEu8+sFdE07vfLoWzxJIark8WA==
+            =pc2z
+            -----END PGP MESSAGE-----
+          fp: 535B61015823443941C744DD12264F6BBDFABA89
+        - created_at: "2022-10-12T16:48:23Z"
+          enc: |
+            -----BEGIN PGP MESSAGE-----
+
+            hQIMA2HlP5TKoxTkARAAl+2Y+pd5oraYLgiiJ0CbMFef0zCpFwBwUCyzykMOICGa
+            TWCYs8K6hChjepe0p8+oZnp0wi8U1qrmgRtFljQfHoXq5EXDYKydkz8XHHDI7/W7
+            1BmETajv9Mx7j4BFNB3z0XvLJTPeNhygemuHhox5pA8CUt5FkYahpzYR9AlLiAwx
+            NtU+csrcGUqYllT5WYIKFVIwFk07IvgK/7vj3filO5G2GMiH7lsV6p7W/MYqCFTV
+            grE383/bGCT18XmHpe3Uu0NcotexiqKSXpnFNntWOgd/KynBn8Oa/DMr8ci/4QSF
+            rEV4+IGJSmfAzQYaIfzNRGyTQJKBFiXWQv53GWT9Y5EbdEYEBhyqlIaV5fp/61X+
+            8zhLz3b6QMkNkI6mNVVLK96g2p0dhVoq+R3Wlj/RIVDw/BzH+vJIArQhc8T2NEOX
+            lmLFTMoTRXPrw/UZKMoO+JSDwt2p3WI0sb/ThS+bd7eymxt5lFW1Ikc4Jgd/iHHu
+            JtUZ78i8jAV/nBJPaAYXoRxfpcAMFqJCnxTwCoF7vYP6hHeYW9PPqsClPxQ97TrO
+            /Ei01e9YSfdtIzKcwkOThffRr+7hxwEGQ3EZ+2ShOW9ASfLkIo4MgoLtDAoHCK5E
+            vc2JGWP+vlylTVnZ46Hp8BMRlSjdkS/qGU0lSTPC3q+PllCF2gkN6ZcdLv5L2DDS
+            UAFD70TIN2QAiYEZW6jxg2UtO9ULLT5NgrvfHD9aGAk7jIxeY+nH3S7KqFgmA21c
+            IkNZJSX/J85d13+kJADms3vI7uMOcSUiInaQHy9Cqjrr
+            =fnOr
+            -----END PGP MESSAGE-----
+          fp: 7762ec55a5727cabada621d961e53f94caa314e4
+    unencrypted_suffix: _unencrypted
+    version: 3.7.2

From 3cedb9f97881b53c74757712817dcaffb8db6b08 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 12 Oct 2022 18:04:06 +0100
Subject: [PATCH 051/212] nextcloud: Use a hardened systemd unit instead of a
 container

---
 configuration/default.nix                     |   2 +-
 .../services/configs/nginx-nextcloud.conf     | 167 ------------------
 configuration/services/nextcloud.nix          | 130 +++++++++-----
 configuration/services/postgres.nix           |  31 ++++
 4 files changed, 120 insertions(+), 210 deletions(-)
 delete mode 100644 configuration/services/configs/nginx-nextcloud.conf
 create mode 100644 configuration/services/postgres.nix

diff --git a/configuration/default.nix b/configuration/default.nix
index d84302a..bbe474c 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -9,6 +9,7 @@
     ./services/nextcloud.nix
     ./services/webserver.nix
     ./services/starbound.nix
+    ./services/postgres.nix
     ./ids.nix
     ./sops.nix
   ];
@@ -82,7 +83,6 @@
     in {
       "${domain}" = proxyPassToPort 3002 {serverAliases = ["www.${domain}"];};
       "gitea.${domain}" = proxyPassToPort 3000 {};
-      "nextcloud.${domain}" = proxyPassToPort 3001 {};
     };
   };
 
diff --git a/configuration/services/configs/nginx-nextcloud.conf b/configuration/services/configs/nginx-nextcloud.conf
deleted file mode 100644
index 7c6ad78..0000000
--- a/configuration/services/configs/nginx-nextcloud.conf
+++ /dev/null
@@ -1,167 +0,0 @@
-worker_processes auto;
-
-error_log  /var/log/nginx/error.log warn;
-pid        /var/run/nginx.pid;
-
-
-events {
-    worker_connections  1024;
-}
-
-
-http {
-    include       /etc/nginx/mime.types;
-    default_type  application/octet-stream;
-
-    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
-                      '$status $body_bytes_sent "$http_referer" '
-                      '"$http_user_agent" "$http_x_forwarded_for"';
-
-    access_log  /var/log/nginx/access.log  main;
-
-    sendfile        on;
-    #tcp_nopush     on;
-
-    keepalive_timeout  65;
-
-    #gzip  on;
-
-    upstream php-handler {
-        server localhost:9000;
-    }
-
-    server {
-        listen 80;
-
-        # HSTS settings
-        # WARNING: Only add the preload option once you read about
-        # the consequences in https://hstspreload.org/. This option
-        # will add the domain to a hardcoded list that is shipped
-        # in all major browsers and getting removed from this list
-        # could take several months.
-        #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
-
-        # HTTP response headers borrowed from Nextcloud `.htaccess`
-        add_header Referrer-Policy                      "no-referrer"   always;
-        add_header X-Content-Type-Options               "nosniff"       always;
-        add_header X-Download-Options                   "noopen"        always;
-        add_header X-Frame-Options                      "SAMEORIGIN"    always;
-        add_header X-Permitted-Cross-Domain-Policies    "none"          always;
-        add_header X-Robots-Tag                         "none"          always;
-        add_header X-XSS-Protection                     "1; mode=block" always;
-
-        # Remove X-Powered-By, which is an information leak
-        fastcgi_hide_header X-Powered-By;
-
-        # Path to the root of your installation
-        root /var/www/html;
-
-        # Specify how to handle directories -- specifying `/index.php$request_uri`
-        # here as the fallback means that Nginx always exhibits the desired behaviour
-        # when a client requests a path that corresponds to a directory that exists
-        # on the server. In particular, if that directory contains an index.php file,
-        # that file is correctly served; if it doesn't, then the request is passed to
-        # the front-end controller. This consistent behaviour means that we don't need
-        # to specify custom rules for certain paths (e.g. images and other assets,
-        # `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
-        # `try_files $uri $uri/ /index.php$request_uri`
-        # always provides the desired behaviour.
-        index index.php index.html /index.php$request_uri;
-
-        # Rule borrowed from `.htaccess` to handle Microsoft DAV clients
-        location = / {
-            if ( $http_user_agent ~ ^DavClnt ) {
-                return 302 /remote.php/webdav/$is_args$args;
-            }
-        }
-
-        location = /robots.txt {
-            allow all;
-            log_not_found off;
-            access_log off;
-        }
-
-        # Make a regex exception for `/.well-known` so that clients can still
-        # access it despite the existence of the regex rule
-        # `location ~ /(\.|autotest|...)` which would otherwise handle requests
-        # for `/.well-known`.
-        location ^~ /.well-known {
-            # The rules in this block are an adaptation of the rules
-            # in `.htaccess` that concern `/.well-known`.
-
-            location = /.well-known/carddav { return 301 /remote.php/dav/; }
-            location = /.well-known/caldav  { return 301 /remote.php/dav/; }
-
-            location /.well-known/acme-challenge    { try_files $uri $uri/ =404; }
-            location /.well-known/pki-validation    { try_files $uri $uri/ =404; }
-
-            # Let Nextcloud's API for `/.well-known` URIs handle all other
-            # requests by passing them to the front-end controller.
-            return 301 /index.php$request_uri;
-        }
-
-        # set max upload size
-        client_max_body_size 10G;
-        fastcgi_buffers 64 4K;
-
-        # Enable gzip but do not remove ETag headers
-        gzip on;
-        gzip_vary on;
-        gzip_comp_level 4;
-        gzip_min_length 256;
-        gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
-        gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
-
-        # Pagespeed is not supported by Nextcloud, so if your server is built
-        # with the `ngx_pagespeed` module, uncomment this line to disable it.
-        #pagespeed off;
-
-        # Rules borrowed from `.htaccess` to hide certain paths from clients
-        location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; }
-        location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)                { return 404; }
-
-        # Ensure this block, which passes PHP files to the PHP process, is above the blocks
-        # which handle static assets (as seen below). If this block is not declared first,
-        # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
-        # to the URI, resulting in a HTTP 500 error response.
-        location ~ \.php(?:$|/) {
-            fastcgi_split_path_info ^(.+?\.php)(/.*)$;
-            set $path_info $fastcgi_path_info;
-
-            try_files $fastcgi_script_name =404;
-
-            include fastcgi_params;
-            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
-            fastcgi_param PATH_INFO $path_info;
-            #fastcgi_param HTTPS on;
-
-            fastcgi_param modHeadersAvailable true;         # Avoid sending the security headers twice
-            fastcgi_param front_controller_active true;     # Enable pretty urls
-            fastcgi_pass php-handler;
-
-            fastcgi_intercept_errors on;
-            fastcgi_request_buffering off;
-        }
-
-        location ~ \.(?:css|js|svg|gif)$ {
-            try_files $uri /index.php$request_uri;
-            expires 6M;         # Cache-Control policy borrowed from `.htaccess`
-            access_log off;     # Optional: Don't log access to assets
-        }
-
-        location ~ \.woff2?$ {
-            try_files $uri /index.php$request_uri;
-            expires 7d;         # Cache-Control policy borrowed from `.htaccess`
-            access_log off;     # Optional: Don't log access to assets
-        }
-
-        # Rule borrowed from `.htaccess`
-        location /remote {
-            return 301 /remote.php$request_uri;
-        }
-
-        location / {
-            try_files $uri $uri/ /index.php$request_uri;
-        }
-    }
-}
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 5b32cf2..9b08af9 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -1,53 +1,99 @@
-{config, ...}: {
-  virtualisation.pods.nextcloud = {
-    hostname = "nextcloud.tlater.net";
-    publish = ["3001:80"];
-    network = "slirp4netns";
+{
+  pkgs,
+  config,
+  ...
+}: let
+  inherit (pkgs) fetchNextcloudApp;
+  nextcloud = pkgs.nextcloud23;
+  hostName = "nextcloud.${config.services.nginx.domain}";
+in {
+  services.nextcloud = {
+    inherit hostName;
 
-    containers = {
-      nextcloud = {
-        image = "nextcloud:fpm-alpine";
-        dependsOn = ["postgres"];
-        volumes = [
-          "nextcloud-root:/var/www/html"
-          "nextcloud-apps:/var/www/html/custom_apps"
-          "nextcloud-config:/var/www/html/config"
-          "nextcloud-data:/var/www/html/data"
-        ];
-        environment = {
-          POSTGRES_DB = "nextcloud";
-          POSTGRES_USER = "nextcloud";
-          POSTGRES_HOST = "localhost";
-          OVERWRITEPROTOCOL = "https";
-          TRUSTED_PROXIES = "127.0.0.1";
-        };
+    package = nextcloud;
+    enable = true;
+    maxUploadSize = "2G";
+    https = true;
+
+    config = {
+      overwriteProtocol = "https";
+
+      dbtype = "pgsql";
+      dbhost = "/run/postgresql";
+
+      adminuser = "tlater";
+      adminpassFile = config.sops.secrets."nextcloud/tlater".path;
+
+      defaultPhoneRegion = "AT";
+    };
+
+    extraApps = {
+      # TODO(tlater): Seems like this won't work anymore from
+      # Nextcloud 25 onwards.
+      #
+      # Adopt whatever upstream does with this:
+      # https://github.com/nextcloud/server/issues/4917
+      apporder = pkgs.fetchNextcloudApp {
+        name = "apporder";
+        url = "https://github.com/juliushaertl/apporder/releases/download/v0.15.0/apporder.tar.gz";
+        version = "0.15.0";
+        sha256 = "sha256-p3VWxTYDCO2NePq6oLM8tBVqYkvoB7itqxp7IZwGDnE=";
       };
 
-      cron = {
-        image = "nextcloud:fpm-alpine";
-        entrypoint = "/cron.sh";
-        dependsOn = ["postgres" "nextcloud"];
-        extraOptions = ["--volumes-from=nextcloud-nextcloud"];
+      bookmarks = pkgs.fetchNextcloudApp {
+        name = "bookmarks";
+        url = "https://github.com/nextcloud/bookmarks/releases/download/v11.0.4/bookmarks-11.0.4.tar.gz";
+        version = "11.0.4";
+        sha256 = "sha256-URqtzaCx8FEZHCDP1wSBUFNs+x50jesRtWi+xOU1oXM=";
       };
 
-      nginx = {
-        image = "nginx:alpine";
-        dependsOn = ["nextcloud"];
-        volumes = [
-          "nextcloud-root:/var/www/html:ro"
-          "${./configs/nginx-nextcloud.conf}:/etc/nginx/nginx.conf:ro"
-        ];
-        extraOptions = ["--volumes-from=nextcloud-nextcloud"];
+      calendar = pkgs.fetchNextcloudApp {
+        name = "calendar";
+        url = "https://github.com/nextcloud-releases/calendar/releases/download/v3.5.0/calendar-v3.5.0.tar.gz";
+        version = "3.5.0";
+        sha256 = "sha256-+LRGl9h40AQdWN9SW+NqGwTafAGwV07Af8nVs3pUCm0=";
       };
 
-      postgres = {
-        image = "postgres:alpine";
-        environment = {
-          POSTGRES_DB = "nextcloud";
-          POSTGRES_USER = "nextcloud";
-        };
-        volumes = ["nextcloud-postgres-14:/var/lib/postgresql/data"];
+      contacts = pkgs.fetchNextcloudApp {
+        name = "contacts";
+        url = "https://github.com/nextcloud-releases/contacts/releases/download/v4.2.2/contacts-v4.2.2.tar.gz";
+        version = "4.2.2";
+        sha256 = "sha256-GTiyZsUHBXPgQ17DHAihmt2W/ZnAjDwfgwnujkRwk6A=";
+      };
+
+      cookbook = pkgs.fetchNextcloudApp {
+        name = "cookbook";
+        url = "https://github.com/nextcloud/cookbook/releases/download/v0.9.15/Cookbook-0.9.15.tar.gz";
+        version = "0.9.15";
+        sha256 = "sha256-v64rLGyMQOdStyivpJsKrNxwumVQvyK3CnHtZ+K+elE=";
+      };
+
+      news = pkgs.fetchNextcloudApp {
+        name = "news";
+        url = "https://github.com/nextcloud/news/releases/download/18.2.0/news.tar.gz";
+        version = "18.2.0";
+        sha256 = "sha256-eS0cFwJmYfGGJmA02AOWO/OXfqfyI71u2GataDj18DE=";
+      };
+
+      notes = pkgs.fetchNextcloudApp {
+        name = "notes";
+        url = "https://github.com/nextcloud/notes/releases/download/v4.5.1/notes.tar.gz";
+        version = "4.5.1";
+        sha256 = "sha256-rd3uVkVtARX4enRAWm1ivV468lboYZnYe7/zsqaHYpk=";
       };
     };
+
+    # TODO(tlater): Add redis config. This will be much easier
+    # starting with 22.11, since this will add an `extraOptions` where
+    # the necessary redis config can go.
+  };
+
+  # Ensure that this service doesn't start before postgres is ready
+  systemd.services.nextcloud-setup.after = ["postgresql.service"];
+
+  # Set up SSL
+  services.nginx.virtualHosts."${hostName}" = {
+    forceSSL = true;
+    enableACME = true;
   };
 }
diff --git a/configuration/services/postgres.nix b/configuration/services/postgres.nix
new file mode 100644
index 0000000..6c584bb
--- /dev/null
+++ b/configuration/services/postgres.nix
@@ -0,0 +1,31 @@
+{pkgs, ...}: {
+  services.postgresql = {
+    package = pkgs.postgresql_14;
+    enable = true;
+
+    # Only enable connections via the unix socket, and check with the
+    # OS to make sure the user matches the database name.
+    #
+    # See https://www.postgresql.org/docs/current/auth-pg-hba-conf.html
+    authentication = ''
+      local sameuser all peer
+    '';
+
+    # Note: The following options with ensure.* are set-only; i.e.,
+    # when permissions/users/databases are removed from these lists,
+    # that operation needs to be performed manually on the system as
+    # well.
+    ensureUsers = [
+      {
+        name = "nextcloud";
+        ensurePermissions = {
+          "DATABASE nextcloud" = "ALL PRIVILEGES";
+        };
+      }
+    ];
+
+    ensureDatabases = [
+      "nextcloud"
+    ];
+  };
+}

From b6594cea5472189d98f40714b94ab10bb0df1ac7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 12 Oct 2022 19:43:24 +0100
Subject: [PATCH 052/212] gitea: Use a hardened systemd unit instead of a
 container

---
 configuration/default.nix        |  3 +-
 configuration/services/gitea.nix | 69 ++++++++++++--------------------
 2 files changed, 27 insertions(+), 45 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index bbe474c..0e854c6 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -38,7 +38,7 @@
     useDHCP = false;
     interfaces.eth0.useDHCP = true;
 
-    firewall.allowedTCPPorts = [80 443 2222 2221 21025];
+    firewall.allowedTCPPorts = [80 443 2222 21025];
   };
 
   time.timeZone = "Europe/London";
@@ -82,7 +82,6 @@
       domain = config.services.nginx.domain;
     in {
       "${domain}" = proxyPassToPort 3002 {serverAliases = ["www.${domain}"];};
-      "gitea.${domain}" = proxyPassToPort 3000 {};
     };
   };
 
diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index 5f9ebd0..cd99951 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -1,48 +1,31 @@
-{config, ...}: {
-  users = {
-    extraUsers.gitea = {
-      uid = config.ids.uids.git;
-      isSystemUser = true;
-      description = "Gitea Service";
-      group = config.users.extraGroups.gitea.name;
-    };
-    extraGroups.gitea = {gid = config.ids.gids.git;};
+{config, ...}: let
+  domain = "gitea.${config.services.nginx.domain}";
+in {
+  services.gitea = {
+    inherit domain;
+    enable = true;
+
+    httpAddress = "127.0.0.1";
+    database.type = "postgres";
+
+    ssh.clonePort = 2222;
+    rootUrl = "https://${domain}/";
+    cookieSecure = true;
+
+    appName = "Gitea: Git with a cup of tea";
+    disableRegistration = true;
   };
 
-  virtualisation.pods.gitea = {
-    hostname = "gitea.tlater.net";
-    publish = ["3000:3000" "2221:2221"];
-    network = "slirp4netns";
+  # Set up SSL
+  services.nginx.virtualHosts."${domain}" = let
+    inherit (config.services.gitea) httpAddress httpPort;
+  in {
+    forceSSL = true;
+    enableACME = true;
+    extraConfig = ''
+      add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
+    '';
 
-    containers = {
-      gitea = {
-        image = "gitea/gitea:latest";
-        volumes = ["gitea:/data:Z" "/etc/localtime:/etc/localtime:ro"];
-        dependsOn = ["postgres"];
-
-        environment = {
-          DB_TYPE = "postgres";
-          DB_HOST = "localhost:5432";
-          DB_NAME = "gitea";
-          DB_USER = "gitea";
-
-          USER_UID = toString config.users.extraUsers.gitea.uid;
-          USER_GID = toString config.users.extraGroups.gitea.gid;
-
-          RUN_MODE = "prod";
-          DOMAIN = "gitea.tlater.net";
-          SSH_PORT = "2221";
-        };
-      };
-
-      postgres = {
-        image = "postgres:alpine";
-        environment = {
-          POSTGRES_DB = "gitea";
-          POSTGRES_USER = "gitea";
-        };
-        volumes = ["gitea-postgres-14:/var/lib/postgresql/data"];
-      };
-    };
+    locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}";
   };
 }

From 068e6d5d77f7db3cba04ddea246d7adc766f65ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 12 Oct 2022 19:58:09 +0100
Subject: [PATCH 053/212] webserver: Use a hardened systemd unit instead of a
 container

---
 configuration/default.nix            |  22 +-
 configuration/ids.nix                |  11 -
 configuration/services/webserver.nix |  59 ++--
 flake.lock                           | 395 ++++++++++++++++++++-------
 flake.nix                            |  13 +-
 modules/virtualisation/pods.nix      | 222 ---------------
 6 files changed, 321 insertions(+), 401 deletions(-)
 delete mode 100644 configuration/ids.nix
 delete mode 100644 modules/virtualisation/pods.nix

diff --git a/configuration/default.nix b/configuration/default.nix
index 0e854c6..8f51f0b 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -1,5 +1,4 @@
 {
-  config,
   pkgs,
   lib,
   ...
@@ -10,7 +9,6 @@
     ./services/webserver.nix
     ./services/starbound.nix
     ./services/postgres.nix
-    ./ids.nix
     ./sops.nix
   ];
 
@@ -67,30 +65,12 @@
     recommendedProxySettings = true;
     clientMaxBodySize = "10G";
     domain = "tlater.net";
-
-    virtualHosts = let
-      proxyPassToPort = port: extra:
-        lib.recursiveUpdate {
-          forceSSL = true;
-          enableACME = true;
-          locations."/".proxyPass = "http://127.0.0.1:${toString port}";
-          extraConfig = ''
-            add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
-          '';
-        }
-        extra;
-      domain = config.services.nginx.domain;
-    in {
-      "${domain}" = proxyPassToPort 3002 {serverAliases = ["www.${domain}"];};
-    };
   };
 
   security.acme = {
-    email = "tm@tlater.net";
+    defaults.email = "tm@tlater.net";
     acceptTerms = true;
   };
 
-  virtualisation.oci-containers.backend = "podman";
-
   system.stateVersion = "20.09";
 }
diff --git a/configuration/ids.nix b/configuration/ids.nix
deleted file mode 100644
index 352b4d3..0000000
--- a/configuration/ids.nix
+++ /dev/null
@@ -1,11 +0,0 @@
-{...}: {
-  ids.uids = {
-    # System user ids start at 400 (see nixos/modules/programs/shadow.nix)
-    webserver = 400;
-    # The limit is 999
-  };
-
-  ids.gids = {
-    webserver = 400;
-  };
-}
diff --git a/configuration/services/webserver.nix b/configuration/services/webserver.nix
index 093da3d..4a8bee4 100644
--- a/configuration/services/webserver.nix
+++ b/configuration/services/webserver.nix
@@ -1,47 +1,26 @@
-{
-  config,
-  pkgs,
-  ...
-}: {
-  users = {
-    extraUsers.webserver = {
-      uid = config.ids.uids.webserver;
-      group = config.users.extraGroups.webserver.name;
-      isSystemUser = true;
-      description = "tlater.net web server user";
+{config, ...}: let
+  domain = config.services.nginx.domain;
+in {
+  services.tlaternet-webserver = {
+    enable = true;
+    listen = {
+      addr = "127.0.0.1";
+      port = 8000;
     };
-    extraGroups.webserver = {gid = config.ids.gids.webserver;};
   };
 
-  virtualisation.oci-containers.containers.webserver = {
-    image = "tlaternet/webserver";
+  # Set up SSL
+  services.nginx.virtualHosts."${domain}" = let
+    inherit (config.services.tlaternet-webserver.listen) addr port;
+  in {
+    serverAliases = ["www.${domain}"];
 
-    imageFile = pkgs.dockerTools.buildImage {
-      name = "tlaternet/webserver";
-      tag = "latest";
-      contents = pkgs.tlaternet-webserver.webserver;
+    forceSSL = true;
+    enableACME = true;
+    extraConfig = ''
+      add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
+    '';
 
-      config = let
-        uid = toString config.users.extraUsers.webserver.uid;
-        gid = toString config.users.extraGroups.webserver.gid;
-      in {
-        Cmd = ["tlaternet-webserver"];
-        Volumes = {"/srv/mail" = {};};
-        Env = [
-          "ROCKET_PORT=3002"
-          "ROCKET_TEMPLATE_DIR=${pkgs.tlaternet-templates.templates}/browser/"
-        ];
-        ExposedPorts = {"3002" = {};};
-        User = "${uid}:${gid}";
-      };
-    };
-
-    ports = ["3002:3002"];
-    volumes = ["tlaternet-mail:/srv/mail"];
-    extraOptions = [
-      "--hostname=tlater.net"
-      # Rocket 0.4 doesn't support SIGTERM anyway, so SIGKILL is the cleanest exit possible.
-      "--stop-signal=SIGKILL"
-    ];
+    locations."/".proxyPass = "http://${addr}:${toString port}";
   };
 }
diff --git a/flake.lock b/flake.lock
index c6f9923..11b5c2c 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1,63 +1,202 @@
 {
   "nodes": {
-    "flake-utils": {
-      "locked": {
-        "lastModified": 1659877975,
-        "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
-        "type": "github"
-      },
-      "original": {
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "type": "github"
-      }
-    },
-    "flake-utils_2": {
-      "locked": {
-        "lastModified": 1659877975,
-        "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
-        "type": "github"
-      },
-      "original": {
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "type": "github"
-      }
-    },
-    "naersk": {
+    "alejandra": {
       "inputs": {
+        "fenix": "fenix",
+        "flakeCompat": "flakeCompat",
         "nixpkgs": [
           "tlaternet-webserver",
+          "dream2nix",
           "nixpkgs"
         ]
       },
       "locked": {
-        "lastModified": 1632266297,
-        "narHash": "sha256-J1yeJk6Gud9ef2pEf6aKQemrfg1pVngYDSh+SAY94xk=",
-        "owner": "nmattia",
-        "repo": "naersk",
-        "rev": "ee7edec50b49ab6d69b06d62f1de554efccb1ccd",
+        "lastModified": 1658427149,
+        "narHash": "sha256-ToD/1z/q5VHsLMrS2h96vjJoLho59eNRtknOUd19ey8=",
+        "owner": "kamadorueda",
+        "repo": "alejandra",
+        "rev": "f5a22afd2adfb249b4e68e0b33aa1f0fb73fb1be",
         "type": "github"
       },
       "original": {
-        "owner": "nmattia",
-        "repo": "naersk",
+        "owner": "kamadorueda",
+        "repo": "alejandra",
         "type": "github"
       }
     },
+    "crane": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1661875961,
+        "narHash": "sha256-f1h/2c6Teeu1ofAHWzrS8TwBPcnN+EEu+z1sRVmMQTk=",
+        "owner": "ipetkov",
+        "repo": "crane",
+        "rev": "d9f394e4e20e97c2a60c3ad82c2b6ef99be19e24",
+        "type": "github"
+      },
+      "original": {
+        "owner": "ipetkov",
+        "repo": "crane",
+        "type": "github"
+      }
+    },
+    "devshell": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1653917170,
+        "narHash": "sha256-FyxOnEE/V4PNEcMU62ikY4FfYPo349MOhMM97HS0XEo=",
+        "owner": "numtide",
+        "repo": "devshell",
+        "rev": "fc7a3e3adde9bbcab68af6d1e3c6eb738e296a92",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "devshell",
+        "type": "github"
+      }
+    },
+    "dream2nix": {
+      "inputs": {
+        "alejandra": "alejandra",
+        "crane": "crane",
+        "devshell": "devshell",
+        "flake-utils-pre-commit": "flake-utils-pre-commit",
+        "gomod2nix": "gomod2nix",
+        "mach-nix": "mach-nix",
+        "nixpkgs": "nixpkgs_2",
+        "poetry2nix": "poetry2nix",
+        "pre-commit-hooks": "pre-commit-hooks"
+      },
+      "locked": {
+        "lastModified": 1663323895,
+        "narHash": "sha256-ZmI9C8HNVz2w3OnB79WR/LIgVEY8tDnR8tEPi3hMiJk=",
+        "owner": "nix-community",
+        "repo": "dream2nix",
+        "rev": "25be741ec92c77b8308ca6a7ab89593fe37b6542",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "repo": "dream2nix",
+        "type": "github"
+      }
+    },
+    "fenix": {
+      "inputs": {
+        "nixpkgs": [
+          "tlaternet-webserver",
+          "dream2nix",
+          "alejandra",
+          "nixpkgs"
+        ],
+        "rust-analyzer-src": "rust-analyzer-src"
+      },
+      "locked": {
+        "lastModified": 1657607339,
+        "narHash": "sha256-HaqoAwlbVVZH2n4P3jN2FFPMpVuhxDy1poNOR7kzODc=",
+        "owner": "nix-community",
+        "repo": "fenix",
+        "rev": "b814c83d9e6aa5a28d0cf356ecfdafb2505ad37d",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "repo": "fenix",
+        "type": "github"
+      }
+    },
+    "fenix_2": {
+      "inputs": {
+        "nixpkgs": [
+          "tlaternet-webserver",
+          "nixpkgs"
+        ],
+        "rust-analyzer-src": "rust-analyzer-src_2"
+      },
+      "locked": {
+        "lastModified": 1663396212,
+        "narHash": "sha256-dlK10QPTDYNpJ/vl2QPKOTrqEbQwAR/v2f4+xsetTkw=",
+        "owner": "nix-community",
+        "repo": "fenix",
+        "rev": "263cd7f991c07a9592a6e825bfc37b23b00eb244",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "repo": "fenix",
+        "type": "github"
+      }
+    },
+    "flake-utils-pre-commit": {
+      "locked": {
+        "lastModified": 1644229661,
+        "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "flakeCompat": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1650374568,
+        "narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=",
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "rev": "b4a34015c698c7793d592d66adbab377907a2be8",
+        "type": "github"
+      },
+      "original": {
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "type": "github"
+      }
+    },
+    "gomod2nix": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1627572165,
+        "narHash": "sha256-MFpwnkvQpauj799b4QTBJQFEddbD02+Ln5k92QyHOSk=",
+        "owner": "tweag",
+        "repo": "gomod2nix",
+        "rev": "67f22dd738d092c6ba88e420350ada0ed4992ae8",
+        "type": "github"
+      },
+      "original": {
+        "owner": "tweag",
+        "repo": "gomod2nix",
+        "type": "github"
+      }
+    },
+    "mach-nix": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1634711045,
+        "narHash": "sha256-m5A2Ty88NChLyFhXucECj6+AuiMZPHXNbw+9Kcs7F6Y=",
+        "owner": "DavHau",
+        "repo": "mach-nix",
+        "rev": "4433f74a97b94b596fa6cd9b9c0402104aceef5d",
+        "type": "github"
+      },
+      "original": {
+        "id": "mach-nix",
+        "type": "indirect"
+      }
+    },
     "nixos-hardware": {
       "locked": {
-        "lastModified": 1650522846,
-        "narHash": "sha256-SxWHXRI3qJwswyXAtzsi6PKVY3KLNNnb072KaJthII8=",
+        "lastModified": 1665321371,
+        "narHash": "sha256-0SO6MTW0bX6lxZmz1AZW/Xmk+hnTd7/hp1vF7Tp7jg0=",
         "owner": "nixos",
         "repo": "nixos-hardware",
-        "rev": "6b4ebea9093c997c5f275c820e679108de4871ab",
+        "rev": "236ba4df714131059945d7754c0aa3fbe9d2f74c",
         "type": "github"
       },
       "original": {
@@ -69,51 +208,134 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1650501692,
-        "narHash": "sha256-ApKf0/dc0SyB7zZ6yiiOQgcXAhCXxbSDyihHfRDIzx0=",
+        "lastModified": 1665466769,
+        "narHash": "sha256-L+qcHpb4Ac3PipMXJY/Ktbu1+KXy23WCZ8pXWmsf7zY=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "9887f024766aa27704d1f89f623efd1d063da92a",
+        "rev": "0b20bf89e0035b6d62ad58f9db8fdbc99c2b01e8",
         "type": "github"
       },
       "original": {
         "owner": "nixos",
-        "ref": "nixos-21.11",
+        "ref": "nixos-22.05",
         "repo": "nixpkgs",
         "type": "github"
       }
     },
+    "nixpkgs-22_05": {
+      "locked": {
+        "lastModified": 1665279158,
+        "narHash": "sha256-TpbWNzoJ5RaZ302dzvjY2o//WxtOJuYT3CnDj5N69Hs=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "b3783bcfb8ec54e0de26feccfc6cc36b8e202ed5",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "release-22.05",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs_2": {
+      "locked": {
+        "lastModified": 1657638268,
+        "narHash": "sha256-blBNtQSslAFkg0Gym9fWNJk+bPxGSZib4SOcPrmTPi4=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "d80993b5f885515254746ba6d1917276ee386149",
+        "type": "github"
+      },
+      "original": {
+        "id": "nixpkgs",
+        "ref": "nixos-unstable",
+        "type": "indirect"
+      }
+    },
+    "poetry2nix": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1632969109,
+        "narHash": "sha256-jPDclkkiAy5m2gGLBlKgH+lQtbF7tL4XxBrbSzw+Ioc=",
+        "owner": "nix-community",
+        "repo": "poetry2nix",
+        "rev": "aee8f04296c39d88155e05d25cfc59dfdd41cc77",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "ref": "1.21.0",
+        "repo": "poetry2nix",
+        "type": "github"
+      }
+    },
+    "pre-commit-hooks": {
+      "inputs": {
+        "flake-utils": [
+          "tlaternet-webserver",
+          "dream2nix",
+          "flake-utils-pre-commit"
+        ],
+        "nixpkgs": [
+          "tlaternet-webserver",
+          "dream2nix",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1646153636,
+        "narHash": "sha256-AlWHMzK+xJ1mG267FdT8dCq/HvLCA6jwmx2ZUy5O8tY=",
+        "owner": "cachix",
+        "repo": "pre-commit-hooks.nix",
+        "rev": "b6bc0b21e1617e2b07d8205e7fae7224036dfa4b",
+        "type": "github"
+      },
+      "original": {
+        "owner": "cachix",
+        "repo": "pre-commit-hooks.nix",
+        "type": "github"
+      }
+    },
     "root": {
       "inputs": {
         "nixos-hardware": "nixos-hardware",
         "nixpkgs": "nixpkgs",
         "sops-nix": "sops-nix",
-        "tlaternet-templates": "tlaternet-templates",
         "tlaternet-webserver": "tlaternet-webserver"
       }
     },
-    "rust-overlay": {
-      "inputs": {
-        "flake-utils": [
-          "tlaternet-webserver",
-          "flake-utils"
-        ],
-        "nixpkgs": [
-          "tlaternet-webserver",
-          "nixpkgs"
-        ]
-      },
+    "rust-analyzer-src": {
+      "flake": false,
       "locked": {
-        "lastModified": 1633400100,
-        "narHash": "sha256-kHQV7jZ2vVHVI9sfda1mUROVBbQbdfKcbIpKG9WdqGo=",
-        "owner": "oxalica",
-        "repo": "rust-overlay",
-        "rev": "9c2fc6a62ccbc6f420d71ecac6bf0b84dbbee64f",
+        "lastModified": 1657557289,
+        "narHash": "sha256-PRW+nUwuqNTRAEa83SfX+7g+g8nQ+2MMbasQ9nt6+UM=",
+        "owner": "rust-lang",
+        "repo": "rust-analyzer",
+        "rev": "caf23f29144b371035b864a1017dbc32573ad56d",
         "type": "github"
       },
       "original": {
-        "owner": "oxalica",
-        "repo": "rust-overlay",
+        "owner": "rust-lang",
+        "ref": "nightly",
+        "repo": "rust-analyzer",
+        "type": "github"
+      }
+    },
+    "rust-analyzer-src_2": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1662896065,
+        "narHash": "sha256-1LkSsXzI1JTAmP/GMTz4fTJd8y/tw8R79l96q+h7mu8=",
+        "owner": "rust-lang",
+        "repo": "rust-analyzer",
+        "rev": "2e9f1204ca01c3e20898d4a67c8b84899d394a88",
+        "type": "github"
+      },
+      "original": {
+        "owner": "rust-lang",
+        "ref": "nightly",
+        "repo": "rust-analyzer",
         "type": "github"
       }
     },
@@ -121,14 +343,15 @@
       "inputs": {
         "nixpkgs": [
           "nixpkgs"
-        ]
+        ],
+        "nixpkgs-22_05": "nixpkgs-22_05"
       },
       "locked": {
-        "lastModified": 1649756291,
-        "narHash": "sha256-KTll8bCINAzIUGaaMrbn9wb5nfhkXRLgmFrWGR/Dku0=",
+        "lastModified": 1665289655,
+        "narHash": "sha256-j1Q9mNBhbzeJykhObiXwEGres9qvP4vH7gxdJ+ihkLI=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "c2614c4fe61943b3d280ac1892fcebe6e8eaf8c8",
+        "rev": "0ce0449e6404c4ff9d1b7bd657794ae5ca54deb3",
         "type": "github"
       },
       "original": {
@@ -137,42 +360,20 @@
         "type": "github"
       }
     },
-    "tlaternet-templates": {
-      "inputs": {
-        "flake-utils": "flake-utils",
-        "nixpkgs": [
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1633432574,
-        "narHash": "sha256-IjGaJAQuFIJ1Is9gtHXsryPOnTDE6tlA61PUKuS8dzw=",
-        "ref": "master",
-        "rev": "555a2949bdf643c74b535bd0c623d98f99d33628",
-        "revCount": 61,
-        "type": "git",
-        "url": "https://gitea.tlater.net/tlaternet/tlaternet-templates.git"
-      },
-      "original": {
-        "type": "git",
-        "url": "https://gitea.tlater.net/tlaternet/tlaternet-templates.git"
-      }
-    },
     "tlaternet-webserver": {
       "inputs": {
-        "flake-utils": "flake-utils_2",
-        "naersk": "naersk",
+        "dream2nix": "dream2nix",
+        "fenix": "fenix_2",
         "nixpkgs": [
           "nixpkgs"
-        ],
-        "rust-overlay": "rust-overlay"
+        ]
       },
       "locked": {
-        "lastModified": 1633433130,
-        "narHash": "sha256-jkW+HV8cJvE86gppOEXQl2ke+bDHJ7SAp8eJp8pJ0N8=",
+        "lastModified": 1665402451,
+        "narHash": "sha256-zWaEzUJh0WFVoaLQsMoIj2D+QFhUBJw+f+XzoYqw3es=",
         "ref": "master",
-        "rev": "1232950c06ae16bf17fb16ac1f5f2231e971936b",
-        "revCount": 16,
+        "rev": "6c29bc5db001e75f5ca06fec726369b87d007a03",
+        "revCount": 47,
         "type": "git",
         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git"
       },
diff --git a/flake.nix b/flake.nix
index 5ff0a51..5603e08 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,7 +2,7 @@
   description = "tlater.net host configuration";
 
   inputs = {
-    nixpkgs.url = "github:nixos/nixpkgs/nixos-21.11";
+    nixpkgs.url = "github:nixos/nixpkgs/nixos-22.05";
     nixos-hardware.url = "github:nixos/nixos-hardware/master";
     sops-nix = {
       url = "github:Mic92/sops-nix";
@@ -13,10 +13,6 @@
       url = "git+https://gitea.tlater.net/tlaternet/tlaternet.git";
       inputs.nixpkgs.follows = "nixpkgs";
     };
-    tlaternet-templates = {
-      url = "git+https://gitea.tlater.net/tlaternet/tlaternet-templates.git";
-      inputs.nixpkgs.follows = "nixpkgs";
-    };
   };
 
   outputs = {
@@ -25,16 +21,11 @@
     nixos-hardware,
     sops-nix,
     tlaternet-webserver,
-    tlaternet-templates,
   }: let
     system = "x86_64-linux";
 
     overlays = [
       (final: prev: {
-        tlaternet-webserver =
-          tlaternet-webserver.legacyPackages.${prev.system}.packages;
-        tlaternet-templates =
-          tlaternet-templates.legacyPackages.${prev.system}.packages;
         local = import ./pkgs {
           pkgs = prev;
         };
@@ -59,6 +50,7 @@
           (import ./configuration/linode.nix)
           (import ./configuration/hardware-configuration.nix)
           sops-nix.nixosModules.sops
+          tlaternet-webserver.nixosModules.default
         ];
       };
 
@@ -74,6 +66,7 @@
 
           (import ./configuration)
           sops-nix.nixosModules.sops
+          tlaternet-webserver.nixosModules.default
           ({lib, ...}: {
             users.users.tlater.password = "insecure";
 
diff --git a/modules/virtualisation/pods.nix b/modules/virtualisation/pods.nix
deleted file mode 100644
index 5a96cc8..0000000
--- a/modules/virtualisation/pods.nix
+++ /dev/null
@@ -1,222 +0,0 @@
-{
-  lib,
-  config,
-  options,
-  ...
-}:
-with lib; let
-  cfg = config.virtualisation.pods;
-  list-to-args = arg: list:
-    concatStringsSep " " (map (e: "--${arg}=${escapeShellArg e}") list);
-  possibly-unset-arg = arg: val: (optionalString (val != null) "--${arg}=${escapeShellArg val}");
-
-  mkPod = name: pod: rec {
-    path = [config.virtualisation.podman.package];
-
-    wants = ["network.target"];
-    after = ["network-online.target"];
-    wantedBy = ["multi-user.target" "default.target"];
-
-    environment.PODMAN_SYSTEMD_UNIT = "%n";
-
-    preStart = concatStringsSep " " [
-      "mkdir -p /run/podman/pods/ ;"
-      "podman pod create"
-      "--infra-conmon-pidfile=${escapeShellArg "/run/podman/pods/${name}.pid"}"
-      "--name=${escapeShellArg name}"
-      "--replace"
-      (list-to-args "add-host" pod.added-hosts)
-      (possibly-unset-arg "cgroup-parent" pod.cgroup-parent)
-      (list-to-args "dns" pod.dns)
-      (list-to-args "dns-opt" pod.dns-opt)
-      (list-to-args "dns-search" pod.dns-search)
-      (possibly-unset-arg "hostname" pod.hostname)
-      (possibly-unset-arg "infra" pod.infra)
-      (possibly-unset-arg "infra-command" pod.infra-command)
-      (possibly-unset-arg "infra-image" pod.infra-image)
-      (possibly-unset-arg "ip" pod.ip)
-      (possibly-unset-arg "mac-address" pod.mac-address)
-      (possibly-unset-arg "network" pod.network)
-      (possibly-unset-arg "network-alias" pod.network-alias)
-      (possibly-unset-arg "no-hosts" pod.no-hosts)
-      (list-to-args "publish" pod.publish)
-      (list-to-args "share" pod.share)
-    ];
-
-    script = "podman pod start ${escapeShellArg name}";
-    preStop = "podman pod stop ${escapeShellArg name}";
-    # `podman generate systemd` generates a second stop after the
-    # first; not sure why but clearly it's recommended.
-    postStop = preStop;
-
-    serviceConfig = rec {
-      Type = "forking";
-      TimeoutStopSec = 70;
-      Restart = "on-failure";
-      PIDFile = "/run/podman/pods/${name}.pid";
-    };
-  };
-in {
-  options.virtualisation.pods = mkOption {
-    type = with types;
-      attrsOf (submodule {
-        options = {
-          added-hosts = mkOption {
-            type = listOf str;
-            default = [];
-            description = "Additional hosts to add to /etc/hosts for each container.";
-            example = literalExample ''
-              [ "database:10.0.0.1" ]
-            '';
-          };
-
-          cgroup-parent = mkOption {
-            type = nullOr str;
-            default = null;
-            description = "The cgroups path under which the pod cgroup will be created.";
-          };
-
-          dns = mkOption {
-            type = listOf str;
-            default = [];
-            description = "The dns servers to set in /etc/resolv.conf.";
-          };
-
-          dns-opt = mkOption {
-            type = listOf str;
-            default = [];
-            description = "dns options to set in /etc/resolv.conf.";
-          };
-
-          dns-search = mkOption {
-            type = listOf str;
-            default = [];
-            description = "Search domains to set in /etc/resolv.conf.";
-          };
-
-          hostname = mkOption {
-            type = nullOr str;
-            default = null;
-            description = "The pod hostname.";
-          };
-
-          infra = mkOption {
-            type = nullOr bool;
-            default = null;
-            description = "Whether to create the infra container for the pod.";
-          };
-
-          infra-command = mkOption {
-            type = nullOr str;
-            default = null;
-            description = "The command to run in the infra container.";
-          };
-
-          infra-image = mkOption {
-            type = nullOr str;
-            default = null;
-            description = "The image to use for the infra container.";
-          };
-
-          ip = mkOption {
-            type = nullOr str;
-            default = null;
-            description = "A static IP address for the pod network.";
-          };
-
-          # TODO: set up label file stuff.
-          #
-          # labels = mkOption {};
-
-          mac-address = mkOption {
-            type = nullOr str;
-            default = null;
-            description = "A static mac address for the pod network.";
-          };
-
-          network = mkOption {
-            type = nullOr str;
-            default = null;
-            description = "Network configuration for the pod.";
-          };
-
-          network-alias = mkOption {
-            type = nullOr str;
-            default = null;
-            description = "DNS alias for the pod.";
-          };
-
-          no-hosts = mkOption {
-            type = nullOr bool;
-            default = null;
-            description = "Whether to disable /etc/hosts creation for the pod.";
-          };
-
-          publish = mkOption {
-            type = listOf str;
-            default = [];
-            description = "List of ports to publish from the pod.";
-          };
-
-          share = mkOption {
-            type = listOf str;
-            default = [];
-            description = "List of kernel namespaces to share.";
-          };
-
-          containers = options.virtualisation.oci-containers.containers;
-        };
-      });
-    default = {};
-    description = "Podman pods to run as systemd services.";
-  };
-
-  config = let
-    # Merge a list of attribute sets together
-    #
-    # TODO: See if there's a generic version for this somewhere in the
-    # pkgs lib?
-    mergeAttrs = attrList: foldr (a: b: a // b) {} attrList;
-
-    # Create services for all defined pods
-    pod-services = mapAttrs' (n: v: nameValuePair "pod-${n}" (mkPod n v)) cfg;
-
-    # Override the systemd-specific settings of containers defined in
-    # pods.
-    #
-    # I.e., make a systemd unit dependency on the pod service.
-    pod-container-services = mergeAttrs (mapAttrsToList (pname: pod:
-      mapAttrs' (cname: container:
-        nameValuePair "podman-${pname}-${cname}" rec {
-          after = ["pod-${pname}.service"];
-          requires = after;
-        })
-      pod.containers)
-    cfg);
-
-    # Override the oci-container settings for containers defined in pods.
-    #
-    # I.e., set the --pod=podname setting, and update the dependsOn so
-    # it points to containers in the same pod.
-    podifyContainer = container: podname:
-      container
-      // {
-        dependsOn =
-          map (dependency: "${podname}-${dependency}") container.dependsOn;
-        extraOptions = container.extraOptions ++ ["--pod=${podname}"];
-      };
-  in
-    lib.mkIf (cfg != {}) {
-      virtualisation.podman.enable = true;
-      virtualisation.oci-containers.backend = "podman";
-
-      systemd.services = pod-services // pod-container-services;
-
-      virtualisation.oci-containers.containers = mergeAttrs (mapAttrsToList
-        (pname: pod:
-          mapAttrs' (cname: container:
-            nameValuePair "${pname}-${cname}" (podifyContainer container pname))
-          pod.containers)
-        cfg);
-    };
-}

From e8b16459d95d45d4581e159d970e5dd7c9d4d977 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Thu, 13 Oct 2022 00:03:32 +0100
Subject: [PATCH 054/212] treewide: Refactor in order to clean up flake.nix

---
 configuration/default.nix                     |  12 ++
 .../linode/default.nix}                       |   4 +
 .../linode}/hardware-configuration.nix        |   0
 configuration/hardware-specific/vm.nix        |  17 +++
 flake.lock                                    |  17 ---
 flake.nix                                     | 139 ++++++++----------
 lib/default.nix                               |  10 ++
 7 files changed, 101 insertions(+), 98 deletions(-)
 rename configuration/{linode.nix => hardware-specific/linode/default.nix} (87%)
 rename configuration/{ => hardware-specific/linode}/hardware-configuration.nix (100%)
 create mode 100644 configuration/hardware-specific/vm.nix
 create mode 100644 lib/default.nix

diff --git a/configuration/default.nix b/configuration/default.nix
index 8f51f0b..cc51bac 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -1,9 +1,13 @@
 {
   pkgs,
   lib,
+  modulesPath,
   ...
 }: {
   imports = [
+    "${modulesPath}/profiles/headless.nix"
+    (import ../modules)
+
     ./services/gitea.nix
     ./services/nextcloud.nix
     ./services/webserver.nix
@@ -12,6 +16,14 @@
     ./sops.nix
   ];
 
+  nixpkgs.overlays = [
+    (final: prev: {
+      local = import ../pkgs {
+        pkgs = prev;
+      };
+    })
+  ];
+
   nix = {
     package = pkgs.nixFlakes;
     extraOptions = ''
diff --git a/configuration/linode.nix b/configuration/hardware-specific/linode/default.nix
similarity index 87%
rename from configuration/linode.nix
rename to configuration/hardware-specific/linode/default.nix
index 7d6a780..3cd3570 100644
--- a/configuration/linode.nix
+++ b/configuration/hardware-specific/linode/default.nix
@@ -1,4 +1,8 @@
 {
+  imports = [
+    ./hardware-configuration.nix
+  ];
+
   # Required for the lish console
   boot.kernelParams = ["console=ttyS0,19200n8"];
 
diff --git a/configuration/hardware-configuration.nix b/configuration/hardware-specific/linode/hardware-configuration.nix
similarity index 100%
rename from configuration/hardware-configuration.nix
rename to configuration/hardware-specific/linode/hardware-configuration.nix
diff --git a/configuration/hardware-specific/vm.nix b/configuration/hardware-specific/vm.nix
new file mode 100644
index 0000000..aed39e4
--- /dev/null
+++ b/configuration/hardware-specific/vm.nix
@@ -0,0 +1,17 @@
+{lib, ...}: {
+  users.users.tlater.password = "insecure";
+
+  # Disable graphical tty so -curses works
+  boot.kernelParams = ["nomodeset"];
+
+  # Sets the base domain for nginx to localhost so that we
+  # can easily test locally with the VM.
+  services.nginx.domain = lib.mkOverride 99 "localhost";
+
+  # Use the staging secrets
+  sops.defaultSopsFile = lib.mkOverride 99 ../../keys/staging.yaml;
+
+  # # Set up VM settings to match real VPS
+  # virtualisation.memorySize = 3941;
+  # virtualisation.cores = 2;
+}
diff --git a/flake.lock b/flake.lock
index 11b5c2c..c44d4a0 100644
--- a/flake.lock
+++ b/flake.lock
@@ -190,22 +190,6 @@
         "type": "indirect"
       }
     },
-    "nixos-hardware": {
-      "locked": {
-        "lastModified": 1665321371,
-        "narHash": "sha256-0SO6MTW0bX6lxZmz1AZW/Xmk+hnTd7/hp1vF7Tp7jg0=",
-        "owner": "nixos",
-        "repo": "nixos-hardware",
-        "rev": "236ba4df714131059945d7754c0aa3fbe9d2f74c",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nixos",
-        "ref": "master",
-        "repo": "nixos-hardware",
-        "type": "github"
-      }
-    },
     "nixpkgs": {
       "locked": {
         "lastModified": 1665466769,
@@ -299,7 +283,6 @@
     },
     "root": {
       "inputs": {
-        "nixos-hardware": "nixos-hardware",
         "nixpkgs": "nixpkgs",
         "sops-nix": "sops-nix",
         "tlaternet-webserver": "tlaternet-webserver"
diff --git a/flake.nix b/flake.nix
index 5603e08..a67b314 100644
--- a/flake.nix
+++ b/flake.nix
@@ -3,12 +3,10 @@
 
   inputs = {
     nixpkgs.url = "github:nixos/nixpkgs/nixos-22.05";
-    nixos-hardware.url = "github:nixos/nixos-hardware/master";
     sops-nix = {
       url = "github:Mic92/sops-nix";
       inputs.nixpkgs.follows = "nixpkgs";
     };
-
     tlaternet-webserver = {
       url = "git+https://gitea.tlater.net/tlaternet/tlaternet.git";
       inputs.nixpkgs.follows = "nixpkgs";
@@ -18,118 +16,97 @@
   outputs = {
     self,
     nixpkgs,
-    nixos-hardware,
     sops-nix,
     tlaternet-webserver,
   }: let
     system = "x86_64-linux";
-
-    overlays = [
-      (final: prev: {
-        local = import ./pkgs {
-          pkgs = prev;
-        };
-      })
-    ];
-
-    pkgs = import nixpkgs {inherit system overlays;};
-    sops-pkgs = sops-nix.packages.${system};
   in {
-    nixosConfigurations = {
-      tlaternet = nixpkgs.lib.nixosSystem {
-        inherit system;
-
-        modules = [
-          ({modulesPath, ...}: {
-            imports = [(modulesPath + "/profiles/headless.nix")];
-            nixpkgs.overlays = overlays;
-          })
-          (import ./modules)
-
-          (import ./configuration)
-          (import ./configuration/linode.nix)
-          (import ./configuration/hardware-configuration.nix)
+    ##################
+    # Configurations #
+    ##################
+    nixosConfigurations = let
+      # Modules that should be generic to all systems
+      genericModule = {...}: {
+        imports = [
+          # Inject flake dependencies
           sops-nix.nixosModules.sops
           tlaternet-webserver.nixosModules.default
+
+          # Import actual configuration
+          (import ./configuration)
+        ];
+      };
+    in {
+      # The actual system definition
+      tlaternet = nixpkgs.lib.nixosSystem {
+        inherit system;
+        modules = [
+          genericModule
+          (import ./configuration/hardware-specific/linode)
         ];
       };
 
+      # A qemu VM to test the above with
       vm = nixpkgs.lib.nixosSystem {
         inherit system;
-
         modules = [
-          ({modulesPath, ...}: {
-            imports = [(modulesPath + "/profiles/headless.nix")];
-            nixpkgs.overlays = overlays;
-          })
-          (import ./modules)
-
-          (import ./configuration)
-          sops-nix.nixosModules.sops
-          tlaternet-webserver.nixosModules.default
-          ({lib, ...}: {
-            users.users.tlater.password = "insecure";
-
-            # Disable graphical tty so -curses works
-            boot.kernelParams = ["nomodeset"];
-
-            # Sets the base domain for nginx to localhost so that we
-            # can easily test locally with the VM.
-            services.nginx.domain = lib.mkOverride 99 "localhost";
-
-            # Use the staging secrets
-            sops.defaultSopsFile = lib.mkOverride 99 ./keys/staging.yaml;
-
-            # # Set up VM settings to match real VPS
-            # virtualisation.memorySize = 3941;
-            # virtualisation.cores = 2;
-          })
+          genericModule
+          (import ./configuration/hardware-specific/vm.nix)
         ];
       };
     };
 
+    ####################
+    # Helper functions #
+    ####################
+    lib = import ./lib {lib = nixpkgs.lib;};
+
+    ####################
+    # VM launch script #
+    ####################
     apps.${system}.default = let
       inherit (self.nixosConfigurations.vm.config.system.build) vm;
       inherit (nixpkgs.legacyPackages.${system}) writeShellScript;
-      inherit (nixpkgs.lib.attrsets) mapAttrsToList;
-      inherit (nixpkgs.lib.strings) concatStringsSep;
-      ports = {
+      qemuNetOpts = self.lib.makeQemuNetOpts {
         "2222" = "2222";
         "3080" = "80";
         "3443" = "443";
-        "2221" = "2221";
         "21025" = "21025"; # Starbound
       };
-      QEMU_NET_OPTS =
-        concatStringsSep ","
-        (mapAttrsToList
-          (host: vm: "hostfwd=::${host}-:${vm}")
-          ports);
     in {
       type = "app";
       program = builtins.toString (writeShellScript "run-vm" ''
         export QEMU_OPTS="-m 3941 -smp 2 -curses"
-        export QEMU_NET_OPTS="${QEMU_NET_OPTS}"
+        export QEMU_NET_OPTS="${qemuNetOpts}"
         "${vm}/bin/run-tlaternet-vm"
       '');
     };
 
-    devShells.${system}.default = pkgs.mkShell {
-      sopsPGPKeyDirs = ["./keys/hosts/" "./keys/users/"];
-      nativeBuildInputs = [
-        sops-pkgs.sops-import-keys-hook
-      ];
-      buildInputs = with pkgs; [
-        nixfmt
-        git-lfs
-        sops-pkgs.sops-init-gpg-key
-      ];
+    ###########################
+    # Development environment #
+    ###########################
+    devShells.${system}.default = let
+      inherit (sops-nix.packages.${system}) sops-import-keys-hook sops-init-gpg-key;
+      deploy-rs-bin = deploy-rs.packages.${system}.default;
+      pkgs = nixpkgs.legacyPackages.${system};
+    in
+      nixpkgs.legacyPackages.${system}.mkShell {
+        sopsPGPKeyDirs = ["./keys/hosts/" "./keys/users/"];
+        nativeBuildInputs = [
+          sops-import-keys-hook
+        ];
+        packages = with pkgs; [
+          nixfmt
+          git-lfs
+          sops-init-gpg-key
+          deploy-rs-bin
+        ];
 
-      shellHook = ''
-        # Work around sudo requiring a full terminal when deploying to
-        # a remote host
-        export NIX_SSHOPTS="-t"
-      '';
-    };
+        shellHook = ''
+          # Work around sudo requiring a full terminal when deploying to
+          # a remote host
+          export NIX_SSHOPTS="-t"
+        '';
+      };
   };
 }
diff --git a/lib/default.nix b/lib/default.nix
new file mode 100644
index 0000000..20d874d
--- /dev/null
+++ b/lib/default.nix
@@ -0,0 +1,10 @@
+{lib}: let
+  inherit (lib.attrsets) mapAttrsToList;
+  inherit (lib.strings) concatStringsSep;
+in {
+  makeQemuNetOpts = portMapping:
+    concatStringsSep ","
+    (mapAttrsToList
+      (host: vm: "hostfwd=::${host}-:${vm}")
+      portMapping);
+}

From 78ecfd63a184284e67db3cae98d0e478f7ab1945 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Thu, 13 Oct 2022 00:30:07 +0100
Subject: [PATCH 055/212] starbound: Fix post-update issues

---
 configuration/default.nix | 2 +-
 pkgs/default.nix          | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index cc51bac..52be9a1 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -35,7 +35,7 @@
   };
 
   nixpkgs.config.allowUnfreePredicate = pkg:
-    builtins.elem (lib.getName pkg) ["steam-runtime" "steamcmd"];
+    builtins.elem (lib.getName pkg) ["steam-original" "steam-runtime" "steamcmd"];
 
   # Optimization for minecraft servers, see:
   # https://bugs.mojang.com/browse/MC-183518
diff --git a/pkgs/default.nix b/pkgs/default.nix
index c92874b..55bf74a 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -1,5 +1,5 @@
 {pkgs, ...}: let
-  inherit (pkgs.lib) callPackage;
+  inherit (pkgs) callPackage;
 in {
   starbound = callPackage ./starbound {};
 }

From 1ddf23bd01cc5031622d17dcc9acdc208cafbd24 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Thu, 13 Oct 2022 00:30:29 +0100
Subject: [PATCH 056/212] nextcloud: Update nextcloud version

---
 configuration/services/nextcloud.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 9b08af9..ce43280 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -4,7 +4,7 @@
   ...
 }: let
   inherit (pkgs) fetchNextcloudApp;
-  nextcloud = pkgs.nextcloud23;
+  nextcloud = pkgs.nextcloud24;
   hostName = "nextcloud.${config.services.nginx.domain}";
 in {
   services.nextcloud = {

From 325e8a0ea115a95ea7babe68a6461f2ed0161ad7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Thu, 13 Oct 2022 00:31:08 +0100
Subject: [PATCH 057/212] flake.nix: Add deploy-rs for deployment management

---
 flake.lock | 84 ++++++++++++++++++++++++++++++++++++++++++++++++------
 flake.nix  | 34 +++++++++++++++++-----
 2 files changed, 103 insertions(+), 15 deletions(-)

diff --git a/flake.lock b/flake.lock
index c44d4a0..d144fcb 100644
--- a/flake.lock
+++ b/flake.lock
@@ -40,6 +40,26 @@
         "type": "github"
       }
     },
+    "deploy-rs": {
+      "inputs": {
+        "flake-compat": "flake-compat",
+        "nixpkgs": "nixpkgs",
+        "utils": "utils"
+      },
+      "locked": {
+        "lastModified": 1659725433,
+        "narHash": "sha256-1ZxuK67TL29YLw88vQ18Y2Y6iYg8Jb7I6/HVzmNB6nM=",
+        "owner": "serokell",
+        "repo": "deploy-rs",
+        "rev": "41f15759dd8b638e7b4f299730d94d5aa46ab7eb",
+        "type": "github"
+      },
+      "original": {
+        "owner": "serokell",
+        "repo": "deploy-rs",
+        "type": "github"
+      }
+    },
     "devshell": {
       "flake": false,
       "locked": {
@@ -64,7 +84,7 @@
         "flake-utils-pre-commit": "flake-utils-pre-commit",
         "gomod2nix": "gomod2nix",
         "mach-nix": "mach-nix",
-        "nixpkgs": "nixpkgs_2",
+        "nixpkgs": "nixpkgs_3",
         "poetry2nix": "poetry2nix",
         "pre-commit-hooks": "pre-commit-hooks"
       },
@@ -128,6 +148,22 @@
         "type": "github"
       }
     },
+    "flake-compat": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1648199409,
+        "narHash": "sha256-JwPKdC2PoVBkG6E+eWw3j6BMR6sL3COpYWfif7RVb8Y=",
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "rev": "64a525ee38886ab9028e6f61790de0832aa3ef03",
+        "type": "github"
+      },
+      "original": {
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "type": "github"
+      }
+    },
     "flake-utils-pre-commit": {
       "locked": {
         "lastModified": 1644229661,
@@ -192,16 +228,16 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1665466769,
-        "narHash": "sha256-L+qcHpb4Ac3PipMXJY/Ktbu1+KXy23WCZ8pXWmsf7zY=",
-        "owner": "nixos",
+        "lastModified": 1648219316,
+        "narHash": "sha256-Ctij+dOi0ZZIfX5eMhgwugfvB+WZSrvVNAyAuANOsnQ=",
+        "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "0b20bf89e0035b6d62ad58f9db8fdbc99c2b01e8",
+        "rev": "30d3d79b7d3607d56546dd2a6b49e156ba0ec634",
         "type": "github"
       },
       "original": {
-        "owner": "nixos",
-        "ref": "nixos-22.05",
+        "owner": "NixOS",
+        "ref": "nixpkgs-unstable",
         "repo": "nixpkgs",
         "type": "github"
       }
@@ -223,6 +259,22 @@
       }
     },
     "nixpkgs_2": {
+      "locked": {
+        "lastModified": 1665466769,
+        "narHash": "sha256-L+qcHpb4Ac3PipMXJY/Ktbu1+KXy23WCZ8pXWmsf7zY=",
+        "owner": "nixos",
+        "repo": "nixpkgs",
+        "rev": "0b20bf89e0035b6d62ad58f9db8fdbc99c2b01e8",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nixos",
+        "ref": "nixos-22.05",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs_3": {
       "locked": {
         "lastModified": 1657638268,
         "narHash": "sha256-blBNtQSslAFkg0Gym9fWNJk+bPxGSZib4SOcPrmTPi4=",
@@ -283,7 +335,8 @@
     },
     "root": {
       "inputs": {
-        "nixpkgs": "nixpkgs",
+        "deploy-rs": "deploy-rs",
+        "nixpkgs": "nixpkgs_2",
         "sops-nix": "sops-nix",
         "tlaternet-webserver": "tlaternet-webserver"
       }
@@ -364,6 +417,21 @@
         "type": "git",
         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git"
       }
+    },
+    "utils": {
+      "locked": {
+        "lastModified": 1648297722,
+        "narHash": "sha256-W+qlPsiZd8F3XkzXOzAoR+mpFqzm3ekQkJNa+PIh1BQ=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "0f8662f1319ad6abf89b3380dd2722369fc51ade",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
     }
   },
   "root": "root",
diff --git a/flake.nix b/flake.nix
index a67b314..ec91b53 100644
--- a/flake.nix
+++ b/flake.nix
@@ -3,6 +3,7 @@
 
   inputs = {
     nixpkgs.url = "github:nixos/nixpkgs/nixos-22.05";
+    deploy-rs.url = "github:serokell/deploy-rs";
     sops-nix = {
       url = "github:Mic92/sops-nix";
       inputs.nixpkgs.follows = "nixpkgs";
@@ -17,6 +18,7 @@
     self,
     nixpkgs,
     sops-nix,
+    deploy-rs,
     tlaternet-webserver,
   }: let
     system = "x86_64-linux";
@@ -56,6 +58,29 @@
       };
     };
 
+    ############################
+    # Deployment configuration #
+    ############################
+    deploy.nodes.tlaternet = {
+      hostname = "tlater.net";
+
+      profiles.system = {
+        user = "root";
+        path = deploy-rs.lib.${system}.activate.nixos self.nixosConfigurations.tlaternet;
+      };
+
+      sshUser = "tlater";
+      sshOpts = ["-t" "-p" "2222"];
+      fastConnection = true;
+      # Currently broken, see https://github.com/serokell/deploy-rs/issues/78
+      magicRollback = false;
+    };
+
+    #########
+    # Tests #
+    #########
+    checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
+
     ####################
     # Helper functions #
     ####################
@@ -76,7 +101,7 @@
     in {
       type = "app";
       program = builtins.toString (writeShellScript "run-vm" ''
-        export QEMU_OPTS="-m 3941 -smp 2 -curses"
+        export QEMU_OPTS="-m 3941 -smp 2 -display curses"
         export QEMU_NET_OPTS="${qemuNetOpts}"
         "${vm}/bin/run-tlaternet-vm"
       '');
@@ -95,18 +120,13 @@
         nativeBuildInputs = [
           sops-import-keys-hook
         ];
+
         packages = with pkgs; [
           nixfmt
           git-lfs
           sops-init-gpg-key
           deploy-rs-bin
         ];
-
-        shellHook = ''
-          # Work around sudo requiring a full terminal when deploying to
-          # a remote host
-          export NIX_SSHOPTS="-t"
-        '';
       };
   };
 }

From c4fa991b621d1008abea1958477d2a1c17ece531 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 14 Oct 2022 01:11:15 +0100
Subject: [PATCH 058/212] treewide: Add fail2ban

---
 configuration/default.nix            | 21 +++++++++++++++++++++
 configuration/services/gitea.nix     | 19 +++++++++++++++++++
 configuration/services/nextcloud.nix | 23 +++++++++++++++++++++++
 3 files changed, 63 insertions(+)

diff --git a/configuration/default.nix b/configuration/default.nix
index 52be9a1..da5b45b 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -84,5 +84,26 @@
     acceptTerms = true;
   };
 
+  services.fail2ban = {
+    enable = true;
+    extraPackages = [pkgs.ipset];
+    banaction = "iptables-ipset-proto6-allports";
+    bantime-increment.enable = true;
+
+    jails = {
+      nginx-botsearch = ''
+        enabled = true
+        logpath = /var/log/nginx/access.log
+      '';
+    };
+
+    ignoreIP = [
+      "127.0.0.0/8"
+      "10.0.0.0/8"
+      "172.16.0.0/12"
+      "192.168.0.0/16"
+    ];
+  };
+
   system.stateVersion = "20.09";
 }
diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index cd99951..f346097 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -28,4 +28,23 @@ in {
 
     locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}";
   };
+
+  # Block repeated failed login attempts
+  #
+  # TODO(tlater): Update to the new regex, since apparently this one
+  # is deprecated (but the new one doesn't work on the current version
+  # of gitea yet): https://docs.gitea.io/en-us/fail2ban-setup/
+  environment.etc = {
+    "fail2ban/filter.d/gitea.conf".text = ''
+      [Definition]
+      failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>
+      journalmatch = _SYSTEMD_UNIT=gitea.service + _COMM=gitea + SYSLOG_IDENTIFIER=gitea
+    '';
+  };
+
+  services.fail2ban.jails = {
+    gitea = ''
+      enabled = true
+    '';
+  };
 }
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index ce43280..070cd7e 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -96,4 +96,27 @@ in {
     forceSSL = true;
     enableACME = true;
   };
+
+  # Block repeated failed login attempts
+  environment.etc = {
+    "fail2ban/filter.d/nextcloud.conf".text = ''
+      [Definition]
+      _groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
+      failregex = \{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
+                  \{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error.
+      datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"
+      journalmatch = SYSLOG_IDENTIFIER=Nextcloud
+    '';
+  };
+
+  services.fail2ban.jails = {
+    nextcloud = ''
+      enabled = true
+
+      # Nextcloud does some throttling already, so we need to set
+      # these to something bigger.
+      findtime = 43200
+      bantime = 86400
+    '';
+  };
 }

From 61d3008bc3c95412d186ab9e9d384ac23251d764 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 17 Oct 2022 11:00:02 +0100
Subject: [PATCH 059/212] nextcloud: Fetch apps using nvfetcher

---
 configuration/default.nix              |   1 +
 configuration/services/nextcloud.nix   |  50 +-----------
 flake.lock                             |  54 +++++++++++++
 flake.nix                              |  46 +++++++----
 pkgs/_sources_nextcloud/generated.json | 107 +++++++++++++++++++++++++
 pkgs/_sources_nextcloud/generated.nix  |  60 ++++++++++++++
 pkgs/default.nix                       |  21 ++++-
 pkgs/mkNextcloudApp.nix                |  13 +++
 pkgs/nextcloud-apps.toml               |  32 ++++++++
 9 files changed, 318 insertions(+), 66 deletions(-)
 create mode 100644 pkgs/_sources_nextcloud/generated.json
 create mode 100644 pkgs/_sources_nextcloud/generated.nix
 create mode 100644 pkgs/mkNextcloudApp.nix
 create mode 100644 pkgs/nextcloud-apps.toml

diff --git a/configuration/default.nix b/configuration/default.nix
index da5b45b..f81357b 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -20,6 +20,7 @@
     (final: prev: {
       local = import ../pkgs {
         pkgs = prev;
+        lib = prev.lib;
       };
     })
   ];
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 070cd7e..fddddde 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -33,54 +33,8 @@ in {
       #
       # Adopt whatever upstream does with this:
       # https://github.com/nextcloud/server/issues/4917
-      apporder = pkgs.fetchNextcloudApp {
-        name = "apporder";
-        url = "https://github.com/juliushaertl/apporder/releases/download/v0.15.0/apporder.tar.gz";
-        version = "0.15.0";
-        sha256 = "sha256-p3VWxTYDCO2NePq6oLM8tBVqYkvoB7itqxp7IZwGDnE=";
-      };
-
-      bookmarks = pkgs.fetchNextcloudApp {
-        name = "bookmarks";
-        url = "https://github.com/nextcloud/bookmarks/releases/download/v11.0.4/bookmarks-11.0.4.tar.gz";
-        version = "11.0.4";
-        sha256 = "sha256-URqtzaCx8FEZHCDP1wSBUFNs+x50jesRtWi+xOU1oXM=";
-      };
-
-      calendar = pkgs.fetchNextcloudApp {
-        name = "calendar";
-        url = "https://github.com/nextcloud-releases/calendar/releases/download/v3.5.0/calendar-v3.5.0.tar.gz";
-        version = "3.5.0";
-        sha256 = "sha256-+LRGl9h40AQdWN9SW+NqGwTafAGwV07Af8nVs3pUCm0=";
-      };
-
-      contacts = pkgs.fetchNextcloudApp {
-        name = "contacts";
-        url = "https://github.com/nextcloud-releases/contacts/releases/download/v4.2.2/contacts-v4.2.2.tar.gz";
-        version = "4.2.2";
-        sha256 = "sha256-GTiyZsUHBXPgQ17DHAihmt2W/ZnAjDwfgwnujkRwk6A=";
-      };
-
-      cookbook = pkgs.fetchNextcloudApp {
-        name = "cookbook";
-        url = "https://github.com/nextcloud/cookbook/releases/download/v0.9.15/Cookbook-0.9.15.tar.gz";
-        version = "0.9.15";
-        sha256 = "sha256-v64rLGyMQOdStyivpJsKrNxwumVQvyK3CnHtZ+K+elE=";
-      };
-
-      news = pkgs.fetchNextcloudApp {
-        name = "news";
-        url = "https://github.com/nextcloud/news/releases/download/18.2.0/news.tar.gz";
-        version = "18.2.0";
-        sha256 = "sha256-eS0cFwJmYfGGJmA02AOWO/OXfqfyI71u2GataDj18DE=";
-      };
-
-      notes = pkgs.fetchNextcloudApp {
-        name = "notes";
-        url = "https://github.com/nextcloud/notes/releases/download/v4.5.1/notes.tar.gz";
-        version = "4.5.1";
-        sha256 = "sha256-rd3uVkVtARX4enRAWm1ivV468lboYZnYe7/zsqaHYpk=";
-      };
+      inherit (pkgs.local) apporder;
+      inherit (pkgs.local) bookmarks calendar contacts cookbook news notes;
     };
 
     # TODO(tlater): Add redis config. This will be much easier
diff --git a/flake.lock b/flake.lock
index d144fcb..a5fc6e4 100644
--- a/flake.lock
+++ b/flake.lock
@@ -164,6 +164,37 @@
         "type": "github"
       }
     },
+    "flake-compat_2": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1650374568,
+        "narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=",
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "rev": "b4a34015c698c7793d592d66adbab377907a2be8",
+        "type": "github"
+      },
+      "original": {
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "type": "github"
+      }
+    },
+    "flake-utils": {
+      "locked": {
+        "lastModified": 1659877975,
+        "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
     "flake-utils-pre-commit": {
       "locked": {
         "lastModified": 1644229661,
@@ -289,6 +320,28 @@
         "type": "indirect"
       }
     },
+    "nvfetcher": {
+      "inputs": {
+        "flake-compat": "flake-compat_2",
+        "flake-utils": "flake-utils",
+        "nixpkgs": [
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1664550666,
+        "narHash": "sha256-eXfMRd9uItEp3PsYI31FSVGPG9dVC6yF++65ZrGwW8A=",
+        "owner": "berberman",
+        "repo": "nvfetcher",
+        "rev": "9763ad40d59a044e90726653d9253efaeeb053b2",
+        "type": "github"
+      },
+      "original": {
+        "owner": "berberman",
+        "repo": "nvfetcher",
+        "type": "github"
+      }
+    },
     "poetry2nix": {
       "flake": false,
       "locked": {
@@ -337,6 +390,7 @@
       "inputs": {
         "deploy-rs": "deploy-rs",
         "nixpkgs": "nixpkgs_2",
+        "nvfetcher": "nvfetcher",
         "sops-nix": "sops-nix",
         "tlaternet-webserver": "tlaternet-webserver"
       }
diff --git a/flake.nix b/flake.nix
index ec91b53..35e3792 100644
--- a/flake.nix
+++ b/flake.nix
@@ -8,6 +8,10 @@
       url = "github:Mic92/sops-nix";
       inputs.nixpkgs.follows = "nixpkgs";
     };
+    nvfetcher = {
+      url = "github:berberman/nvfetcher";
+      inputs.nixpkgs.follows = "nixpkgs";
+    };
     tlaternet-webserver = {
       url = "git+https://gitea.tlater.net/tlaternet/tlaternet.git";
       inputs.nixpkgs.follows = "nixpkgs";
@@ -18,6 +22,7 @@
     self,
     nixpkgs,
     sops-nix,
+    nvfetcher,
     deploy-rs,
     tlaternet-webserver,
   }: let
@@ -89,22 +94,35 @@
     ####################
     # VM launch script #
     ####################
-    apps.${system}.default = let
-      inherit (self.nixosConfigurations.vm.config.system.build) vm;
+    apps.${system} = let
       inherit (nixpkgs.legacyPackages.${system}) writeShellScript;
-      qemuNetOpts = self.lib.makeQemuNetOpts {
-        "2222" = "2222";
-        "3080" = "80";
-        "3443" = "443";
-        "21025" = "21025"; # Starbound
-      };
     in {
-      type = "app";
-      program = builtins.toString (writeShellScript "run-vm" ''
-        export QEMU_OPTS="-m 3941 -smp 2 -display curses"
-        export QEMU_NET_OPTS="${qemuNetOpts}"
-        "${vm}/bin/run-tlaternet-vm"
-      '');
+      default = let
+        inherit (self.nixosConfigurations.vm.config.system.build) vm;
+        qemuNetOpts = self.lib.makeQemuNetOpts {
+          "2222" = "2222";
+          "3080" = "80";
+          "3443" = "443";
+          "21025" = "21025"; # Starbound
+        };
+      in {
+        type = "app";
+        program = builtins.toString (writeShellScript "run-vm" ''
+          export QEMU_OPTS="-m 3941 -smp 2 -display curses"
+          export QEMU_NET_OPTS="${qemuNetOpts}"
+          "${vm}/bin/run-tlaternet-vm"
+        '');
+      };
+
+      update-nextcloud-apps = let
+        nvfetcher-bin = "${nvfetcher.defaultPackage.${system}}/bin/nvfetcher";
+      in {
+        type = "app";
+        program = builtins.toString (writeShellScript "update-nextcloud-apps" ''
+          cd "$(git rev-parse --show-toplevel)/pkgs"
+          ${nvfetcher-bin} -o _sources_nextcloud -c nextcloud-apps.toml
+        '');
+      };
     };
 
     ###########################
diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
new file mode 100644
index 0000000..1faeeb8
--- /dev/null
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -0,0 +1,107 @@
+{
+    "apporder": {
+        "cargoLocks": null,
+        "date": null,
+        "extract": null,
+        "name": "apporder",
+        "passthru": null,
+        "pinned": false,
+        "src": {
+            "name": null,
+            "sha256": "sha256-2y2FHxli9mqlPvw9mABi09Z96OfB1AFD+XmuV5aOCxY=",
+            "type": "url",
+            "url": "https://github.com/juliushaertl/apporder/archive/v0.15.0.tar.gz"
+        },
+        "version": "v0.15.0"
+    },
+    "bookmarks": {
+        "cargoLocks": null,
+        "date": null,
+        "extract": null,
+        "name": "bookmarks",
+        "passthru": null,
+        "pinned": false,
+        "src": {
+            "name": null,
+            "sha256": "sha256-X6Mg0jQ8EYPctiZ3tDtG4LUPwXRnDj9CJrJZrUs3Z/8=",
+            "type": "url",
+            "url": "https://github.com/nextcloud/bookmarks/archive/v11.0.4.tar.gz"
+        },
+        "version": "v11.0.4"
+    },
+    "calendar": {
+        "cargoLocks": null,
+        "date": null,
+        "extract": null,
+        "name": "calendar",
+        "passthru": null,
+        "pinned": false,
+        "src": {
+            "name": null,
+            "sha256": "sha256-keeWi/o+mOV7z5QNATJKwrd0olbCNdrK7YpGHg9qolk=",
+            "type": "url",
+            "url": "https://github.com/nextcloud-releases/calendar/archive/v3.5.0.tar.gz"
+        },
+        "version": "v3.5.0"
+    },
+    "contacts": {
+        "cargoLocks": null,
+        "date": null,
+        "extract": null,
+        "name": "contacts",
+        "passthru": null,
+        "pinned": false,
+        "src": {
+            "name": null,
+            "sha256": "sha256-4dEEy8zSjZYsClO6u+oWfvIlPYJq9+m1+a/mHTQRlaY=",
+            "type": "url",
+            "url": "https://github.com/nextcloud-releases/contacts/archive/v4.2.2.tar.gz"
+        },
+        "version": "v4.2.2"
+    },
+    "cookbook": {
+        "cargoLocks": null,
+        "date": null,
+        "extract": null,
+        "name": "cookbook",
+        "passthru": null,
+        "pinned": false,
+        "src": {
+            "name": null,
+            "sha256": "sha256-TkUCCa7wP6leQbTsxKgD21Tf9CONVnbmvXCFhVBITZw=",
+            "type": "url",
+            "url": "https://github.com/nextcloud/cookbook/archive/v0.9.15.tar.gz"
+        },
+        "version": "v0.9.15"
+    },
+    "news": {
+        "cargoLocks": null,
+        "date": null,
+        "extract": null,
+        "name": "news",
+        "passthru": null,
+        "pinned": false,
+        "src": {
+            "name": null,
+            "sha256": "sha256-eS0cFwJmYfGGJmA02AOWO/OXfqfyI71u2GataDj18DE=",
+            "type": "url",
+            "url": "https://github.com/nextcloud/news/releases/download/18.2.0/news.tar.gz"
+        },
+        "version": "18.2.0"
+    },
+    "notes": {
+        "cargoLocks": null,
+        "date": null,
+        "extract": null,
+        "name": "notes",
+        "passthru": null,
+        "pinned": false,
+        "src": {
+            "name": null,
+            "sha256": "sha256-qhhaQyb9LgLza4CAcNZbl97xa271M7Wqmw8TtBEFpXk=",
+            "type": "url",
+            "url": "https://github.com/nextcloud/notes/archive/v4.5.1.tar.gz"
+        },
+        "version": "v4.5.1"
+    }
+}
\ No newline at end of file
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
new file mode 100644
index 0000000..5da7ca4
--- /dev/null
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -0,0 +1,60 @@
+# This file was generated by nvfetcher, please do not modify it manually.
+{ fetchgit, fetchurl, fetchFromGitHub }:
+{
+  apporder = {
+    pname = "apporder";
+    version = "v0.15.0";
+    src = fetchurl {
+      url = "https://github.com/juliushaertl/apporder/archive/v0.15.0.tar.gz";
+      sha256 = "sha256-2y2FHxli9mqlPvw9mABi09Z96OfB1AFD+XmuV5aOCxY=";
+    };
+  };
+  bookmarks = {
+    pname = "bookmarks";
+    version = "v11.0.4";
+    src = fetchurl {
+      url = "https://github.com/nextcloud/bookmarks/archive/v11.0.4.tar.gz";
+      sha256 = "sha256-X6Mg0jQ8EYPctiZ3tDtG4LUPwXRnDj9CJrJZrUs3Z/8=";
+    };
+  };
+  calendar = {
+    pname = "calendar";
+    version = "v3.5.0";
+    src = fetchurl {
+      url = "https://github.com/nextcloud-releases/calendar/archive/v3.5.0.tar.gz";
+      sha256 = "sha256-keeWi/o+mOV7z5QNATJKwrd0olbCNdrK7YpGHg9qolk=";
+    };
+  };
+  contacts = {
+    pname = "contacts";
+    version = "v4.2.2";
+    src = fetchurl {
+      url = "https://github.com/nextcloud-releases/contacts/archive/v4.2.2.tar.gz";
+      sha256 = "sha256-4dEEy8zSjZYsClO6u+oWfvIlPYJq9+m1+a/mHTQRlaY=";
+    };
+  };
+  cookbook = {
+    pname = "cookbook";
+    version = "v0.9.15";
+    src = fetchurl {
+      url = "https://github.com/nextcloud/cookbook/archive/v0.9.15.tar.gz";
+      sha256 = "sha256-TkUCCa7wP6leQbTsxKgD21Tf9CONVnbmvXCFhVBITZw=";
+    };
+  };
+  news = {
+    pname = "news";
+    version = "18.2.0";
+    src = fetchurl {
+      url = "https://github.com/nextcloud/news/releases/download/18.2.0/news.tar.gz";
+      sha256 = "sha256-eS0cFwJmYfGGJmA02AOWO/OXfqfyI71u2GataDj18DE=";
+    };
+  };
+  notes = {
+    pname = "notes";
+    version = "v4.5.1";
+    src = fetchurl {
+      url = "https://github.com/nextcloud/notes/archive/v4.5.1.tar.gz";
+      sha256 = "sha256-qhhaQyb9LgLza4CAcNZbl97xa271M7Wqmw8TtBEFpXk=";
+    };
+  };
+}
diff --git a/pkgs/default.nix b/pkgs/default.nix
index 55bf74a..545984a 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -1,5 +1,18 @@
-{pkgs, ...}: let
+{
+  pkgs,
+  lib,
+}: let
+  inherit (builtins) listToAttrs mapAttrs;
   inherit (pkgs) callPackage;
-in {
-  starbound = callPackage ./starbound {};
-}
+in
+  {
+    starbound = callPackage ./starbound {};
+  }
+  // (
+    # Add nextcloud apps
+    let
+      mkNextcloudApp = pkgs.callPackage ./mkNextcloudApp.nix {};
+      sources = pkgs.callPackage ./_sources_nextcloud/generated.nix {};
+    in
+      mapAttrs (_: source: mkNextcloudApp source) sources
+  )
diff --git a/pkgs/mkNextcloudApp.nix b/pkgs/mkNextcloudApp.nix
new file mode 100644
index 0000000..3c78a94
--- /dev/null
+++ b/pkgs/mkNextcloudApp.nix
@@ -0,0 +1,13 @@
+{
+  fetchNextcloudApp,
+  lib,
+}: let
+  inherit (lib) removePrefix;
+in
+  source:
+    fetchNextcloudApp {
+      name = source.pname;
+      version = removePrefix "v" source.version;
+      url = source.src.url;
+      sha256 = source.src.outputHash;
+    }
diff --git a/pkgs/nextcloud-apps.toml b/pkgs/nextcloud-apps.toml
new file mode 100644
index 0000000..6d49d79
--- /dev/null
+++ b/pkgs/nextcloud-apps.toml
@@ -0,0 +1,32 @@
+[apporder]
+src.github = "juliushaertl/apporder"
+fetch.url = "https://github.com/juliushaertl/apporder/archive/$ver.tar.gz"
+
+[bookmarks]
+src.github = "nextcloud/bookmarks"
+fetch.url = "https://github.com/nextcloud/bookmarks/archive/$ver.tar.gz"
+
+[calendar]
+src.manual = "v3.5.0" # Pinned until we update to nextcloud 25
+# src.github = "nextcloud-releases/calendar"
+fetch.url = "https://github.com/nextcloud-releases/calendar/archive/$ver.tar.gz"
+
+[contacts]
+src.manual = "v4.2.2" # Pinned until we update to nextcloud 25
+# src.github = "nextcloud-releases/contacts"
+fetch.url = "https://github.com/nextcloud-releases/contacts/archive/$ver.tar.gz"
+
+[cookbook]
+src.github = "nextcloud/cookbook"
+fetch.url = "https://github.com/nextcloud/cookbook/archive/$ver.tar.gz"
+
+[news]
+src.github = "nextcloud/news"
+# Sadly, the news app vendors things, and those are only included in
+# their tarball.
+fetch.url = "https://github.com/nextcloud/news/releases/download/$ver/news.tar.gz"
+
+[notes]
+src.manual = "v4.5.1" # Pinned until we update to nextcloud 25
+# src.github = "nextcloud/notes"
+fetch.url = "https://github.com/nextcloud/notes/archive/$ver.tar.gz"

From 59a44261b80edc1934de2d3fd2b5d62dd921eca2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 17 Oct 2022 14:22:08 +0100
Subject: [PATCH 060/212] flake.nix: Move vm out of `nixosConfigurations` so
 that checks work

---
 flake.nix       | 43 +++++++++++++------------------------------
 lib/default.nix | 22 +++++++++++++++++++++-
 2 files changed, 34 insertions(+), 31 deletions(-)

diff --git a/flake.nix b/flake.nix
index 35e3792..144e69f 100644
--- a/flake.nix
+++ b/flake.nix
@@ -31,35 +31,11 @@
     ##################
     # Configurations #
     ##################
-    nixosConfigurations = let
-      # Modules that should be generic to all systems
-      genericModule = {...}: {
-        imports = [
-          # Inject flake dependencies
-          sops-nix.nixosModules.sops
-          tlaternet-webserver.nixosModules.default
-
-          # Import actual configuration
-          (import ./configuration)
-        ];
-      };
-    in {
+    nixosConfigurations = {
       # The actual system definition
-      tlaternet = nixpkgs.lib.nixosSystem {
+      tlaternet = self.lib.makeNixosSystem {
         inherit system;
-        modules = [
-          genericModule
-          (import ./configuration/hardware-specific/linode)
-        ];
-      };
-
-      # A qemu VM to test the above with
-      vm = nixpkgs.lib.nixosSystem {
-        inherit system;
-        modules = [
-          genericModule
-          (import ./configuration/hardware-specific/vm.nix)
-        ];
+        extraModules = [(import ./configuration/hardware-specific/linode)];
       };
     };
 
@@ -89,7 +65,10 @@
     ####################
     # Helper functions #
     ####################
-    lib = import ./lib {lib = nixpkgs.lib;};
+    lib = import ./lib {
+      inherit nixpkgs sops-nix tlaternet-webserver;
+      lib = nixpkgs.lib;
+    };
 
     ####################
     # VM launch script #
@@ -98,7 +77,11 @@
       inherit (nixpkgs.legacyPackages.${system}) writeShellScript;
     in {
       default = let
-        inherit (self.nixosConfigurations.vm.config.system.build) vm;
+        vm = self.lib.makeNixosSystem {
+          inherit system;
+          extraModules = [(import ./configuration/hardware-specific/vm.nix)];
+        };
+
         qemuNetOpts = self.lib.makeQemuNetOpts {
           "2222" = "2222";
           "3080" = "80";
@@ -110,7 +93,7 @@
         program = builtins.toString (writeShellScript "run-vm" ''
           export QEMU_OPTS="-m 3941 -smp 2 -display curses"
           export QEMU_NET_OPTS="${qemuNetOpts}"
-          "${vm}/bin/run-tlaternet-vm"
+          "${vm.config.system.build.vm}/bin/run-tlaternet-vm"
         '');
       };
 
diff --git a/lib/default.nix b/lib/default.nix
index 20d874d..5f6b68f 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -1,4 +1,9 @@
-{lib}: let
+{
+  lib,
+  nixpkgs,
+  sops-nix,
+  tlaternet-webserver,
+}: let
   inherit (lib.attrsets) mapAttrsToList;
   inherit (lib.strings) concatStringsSep;
 in {
@@ -7,4 +12,19 @@ in {
     (mapAttrsToList
       (host: vm: "hostfwd=::${host}-:${vm}")
       portMapping);
+
+  makeNixosSystem = {
+    system,
+    extraModules,
+  }:
+    nixpkgs.lib.nixosSystem {
+      inherit system;
+      modules =
+        [
+          sops-nix.nixosModules.sops
+          tlaternet-webserver.nixosModules.default
+          (import ../configuration)
+        ]
+        ++ extraModules;
+    };
 }

From bec05bafb1ac8b6daa2dcdc7de0ca24e038c6d4d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 17 Oct 2022 14:29:56 +0100
Subject: [PATCH 061/212] README.md: Update to new and improved flake
 mechanisms

---
 README.md | 34 ++++++++--------------------------
 1 file changed, 8 insertions(+), 26 deletions(-)

diff --git a/README.md b/README.md
index d5f2ed4..3962a65 100644
--- a/README.md
+++ b/README.md
@@ -4,21 +4,16 @@ This is the NixOS configuration for [tlater.net](https://tlater.net/).
 
 ## Testing
 
-### Building
-
-Build the VM with:
+Run a test VM with:
 
 ```
-nixos-rebuild build-vm --flake '.#vm'
+nix run
 ```
 
 ### Running
 
 *Note: M-2 will bring up a console for poweroff and such*
 
-Running should *mostly* be as simple as running the command the build
-script echos.
-
 One caveat: create a larger disk image first. This can be done by
 running the following in the repository root:
 
@@ -26,31 +21,18 @@ running the following in the repository root:
 qemu-img create -f qcow2 ./tlaternet.qcow2 20G
 ```
 
-Everything else should be handled by the devShell.
-
 ### New services
 
-Whenever a new service is added, append an appropriate
-`,hostfwd=::3<port>:<port>` to the `QEMU_NET_OPTS` specified in
-`flake.nix` to bind the service to a host port.
+Whenever a new service is added, add an appropriate port binding to
+`qemuNetOpts` in the default app.
 
 There is no way to test this without binding to the host port, sadly.
 
 ## Deploying
 
-Currently the deployment process is fully manual because there is no
-CI system.
+Deployment is handled using
+[deploy-rs](https://github.com/serokell/deploy-rs):
 
-Nix makes this fairly painless, though, it's simply:
-
-```bash
-nixos-rebuild switch --use-remote-sudo --target-host tlater.net --build-host localhost --flake .#tlaternet
 ```
-
-This has the added benefit of running the build on the dev machine,
-which is 99% of the time much faster at building than the target
-(though artifact upload may take some time on slow connections).
-
-Note that this also requires the current local user to also be present
-on the target host, as well as for this user to be in the target
-host's wheel group. See `nix.trustedUsers`.
+deploy .#tlaternet
+```

From 3e13b575b0c2a8e28973caac0e88cfe1e03d21fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 22 Oct 2022 20:01:44 +0100
Subject: [PATCH 062/212] flake.nix: Clean up devshell

---
 flake.nix | 27 ++++++++++-----------------
 1 file changed, 10 insertions(+), 17 deletions(-)

diff --git a/flake.nix b/flake.nix
index 144e69f..1d6828b 100644
--- a/flake.nix
+++ b/flake.nix
@@ -111,23 +111,16 @@
     ###########################
     # Development environment #
     ###########################
-    devShells.${system}.default = let
-      inherit (sops-nix.packages.${system}) sops-import-keys-hook sops-init-gpg-key;
-      deploy-rs-bin = deploy-rs.packages.${system}.default;
-      pkgs = nixpkgs.legacyPackages.${system};
-    in
-      nixpkgs.legacyPackages.${system}.mkShell {
-        sopsPGPKeyDirs = ["./keys/hosts/" "./keys/users/"];
-        nativeBuildInputs = [
-          sops-import-keys-hook
-        ];
+    devShells.${system}.default = nixpkgs.legacyPackages.${system}.mkShell {
+      sopsPGPKeyDirs = ["./keys/hosts/" "./keys/users/"];
+      nativeBuildInputs = [
+        sops-nix.packages.${system}.sops-import-keys-hook
+      ];
 
-        packages = with pkgs; [
-          nixfmt
-          git-lfs
-          sops-init-gpg-key
-          deploy-rs-bin
-        ];
-      };
+      packages = [
+        sops-nix.packages.${system}.sops-init-gpg-key
+        deploy-rs.packages.${system}.default
+      ];
+    };
   };
 }

From c56de6cf7e849b0b9ad5d6fe69f24e3389ecac09 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 21 Oct 2022 20:48:14 +0100
Subject: [PATCH 063/212] conduit: Add new conduit service

---
 configuration/default.nix          | 13 +++++++-
 configuration/services/conduit.nix | 53 ++++++++++++++++++++++++++++++
 flake.lock                         | 17 ++++++++++
 flake.nix                          |  5 ++-
 lib/default.nix                    |  8 +++++
 5 files changed, 94 insertions(+), 2 deletions(-)
 create mode 100644 configuration/services/conduit.nix

diff --git a/configuration/default.nix b/configuration/default.nix
index f81357b..eb9d05e 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -8,6 +8,7 @@
     "${modulesPath}/profiles/headless.nix"
     (import ../modules)
 
+    ./services/conduit.nix
     ./services/gitea.nix
     ./services/nextcloud.nix
     ./services/webserver.nix
@@ -49,7 +50,17 @@
     useDHCP = false;
     interfaces.eth0.useDHCP = true;
 
-    firewall.allowedTCPPorts = [80 443 2222 21025];
+    firewall.allowedTCPPorts = [
+      # http
+      80
+      443
+      # ssh
+      2222
+      # matrix
+      8448
+      # starbound
+      21025
+    ];
   };
 
   time.timeZone = "Europe/London";
diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
new file mode 100644
index 0000000..e8bbb6e
--- /dev/null
+++ b/configuration/services/conduit.nix
@@ -0,0 +1,53 @@
+{config, ...}: let
+  cfg = config.services.matrix-conduit;
+  domain = "matrix.${config.services.nginx.domain}";
+in {
+  services.matrix-conduit = {
+    enable = true;
+    settings.global = {
+      address = "127.0.0.1";
+      server_name = domain;
+      database_backend = "rocksdb";
+    };
+  };
+
+  services.nginx.virtualHosts."${domain}" = {
+    enableACME = true;
+
+    listen = [
+      {
+        addr = "0.0.0.0";
+        port = 443;
+        ssl = true;
+      }
+      {
+        addr = "[::0]";
+        port = 443;
+        ssl = true;
+      }
+      {
+        addr = "0.0.0.0";
+        port = 8448;
+        ssl = true;
+      }
+      {
+        addr = "[::0]";
+        port = 8488;
+        ssl = true;
+      }
+    ];
+
+    addSSL = true;
+    extraConfig = ''
+      merge_slashes off;
+    '';
+
+    locations."/_matrix" = {
+      proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}";
+      # Recommended by conduit
+      extraConfig = ''
+        proxy_buffering off;
+      '';
+    };
+  };
+}
diff --git a/flake.lock b/flake.lock
index a5fc6e4..126fb51 100644
--- a/flake.lock
+++ b/flake.lock
@@ -289,6 +289,22 @@
         "type": "github"
       }
     },
+    "nixpkgs-unstable": {
+      "locked": {
+        "lastModified": 1666424192,
+        "narHash": "sha256-rb/a7Kg9s31jqkvdOQHFrUc5ig5kB+O2ZKB8mjU2kW8=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "4f8287f3d597c73b0d706cfad028c2d51821f64d",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixpkgs-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
     "nixpkgs_2": {
       "locked": {
         "lastModified": 1665466769,
@@ -390,6 +406,7 @@
       "inputs": {
         "deploy-rs": "deploy-rs",
         "nixpkgs": "nixpkgs_2",
+        "nixpkgs-unstable": "nixpkgs-unstable",
         "nvfetcher": "nvfetcher",
         "sops-nix": "sops-nix",
         "tlaternet-webserver": "tlaternet-webserver"
diff --git a/flake.nix b/flake.nix
index 1d6828b..f190d89 100644
--- a/flake.nix
+++ b/flake.nix
@@ -3,6 +3,7 @@
 
   inputs = {
     nixpkgs.url = "github:nixos/nixpkgs/nixos-22.05";
+    nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
     deploy-rs.url = "github:serokell/deploy-rs";
     sops-nix = {
       url = "github:Mic92/sops-nix";
@@ -21,6 +22,7 @@
   outputs = {
     self,
     nixpkgs,
+    nixpkgs-unstable,
     sops-nix,
     nvfetcher,
     deploy-rs,
@@ -66,7 +68,7 @@
     # Helper functions #
     ####################
     lib = import ./lib {
-      inherit nixpkgs sops-nix tlaternet-webserver;
+      inherit nixpkgs nixpkgs-unstable sops-nix tlaternet-webserver;
       lib = nixpkgs.lib;
     };
 
@@ -86,6 +88,7 @@
           "2222" = "2222";
           "3080" = "80";
           "3443" = "443";
+          "8448" = "8448"; # Matrix
           "21025" = "21025"; # Starbound
         };
       in {
diff --git a/lib/default.nix b/lib/default.nix
index 5f6b68f..da4031f 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -1,6 +1,7 @@
 {
   lib,
   nixpkgs,
+  nixpkgs-unstable,
   sops-nix,
   tlaternet-webserver,
 }: let
@@ -24,6 +25,13 @@ in {
           sops-nix.nixosModules.sops
           tlaternet-webserver.nixosModules.default
           (import ../configuration)
+          {
+            nixpkgs.overlays = [
+              (self: super: {
+                matrix-conduit = nixpkgs-unstable.legacyPackages.${system}.matrix-conduit;
+              })
+            ];
+          }
         ]
         ++ extraModules;
     };

From 7fb5aac33e39542af1567812f996453ea88f2f36 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 23 Oct 2022 23:35:32 +0100
Subject: [PATCH 064/212] nextcloud: Fix nextcloud app download links

---
 pkgs/_sources_nextcloud/generated.json | 34 +++++++++++++-------------
 pkgs/_sources_nextcloud/generated.nix  | 34 +++++++++++++-------------
 pkgs/nextcloud-apps.toml               | 14 ++++++-----
 3 files changed, 42 insertions(+), 40 deletions(-)

diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index 1faeeb8..c93a3b6 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -8,9 +8,9 @@
         "pinned": false,
         "src": {
             "name": null,
-            "sha256": "sha256-2y2FHxli9mqlPvw9mABi09Z96OfB1AFD+XmuV5aOCxY=",
+            "sha256": "sha256-p3VWxTYDCO2NePq6oLM8tBVqYkvoB7itqxp7IZwGDnE=",
             "type": "url",
-            "url": "https://github.com/juliushaertl/apporder/archive/v0.15.0.tar.gz"
+            "url": "https://github.com/juliushaertl/apporder/releases/download/v0.15.0/apporder.tar.gz"
         },
         "version": "v0.15.0"
     },
@@ -23,11 +23,11 @@
         "pinned": false,
         "src": {
             "name": null,
-            "sha256": "sha256-X6Mg0jQ8EYPctiZ3tDtG4LUPwXRnDj9CJrJZrUs3Z/8=",
+            "sha256": "sha256-URqtzaCx8FEZHCDP1wSBUFNs+x50jesRtWi+xOU1oXM=",
             "type": "url",
-            "url": "https://github.com/nextcloud/bookmarks/archive/v11.0.4.tar.gz"
+            "url": "https://github.com/nextcloud/bookmarks/releases/download/v11.0.4/bookmarks-11.0.4.tar.gz"
         },
-        "version": "v11.0.4"
+        "version": "11.0.4"
     },
     "calendar": {
         "cargoLocks": null,
@@ -38,9 +38,9 @@
         "pinned": false,
         "src": {
             "name": null,
-            "sha256": "sha256-keeWi/o+mOV7z5QNATJKwrd0olbCNdrK7YpGHg9qolk=",
+            "sha256": "sha256-+LRGl9h40AQdWN9SW+NqGwTafAGwV07Af8nVs3pUCm0=",
             "type": "url",
-            "url": "https://github.com/nextcloud-releases/calendar/archive/v3.5.0.tar.gz"
+            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v3.5.0/calendar-v3.5.0.tar.gz"
         },
         "version": "v3.5.0"
     },
@@ -53,9 +53,9 @@
         "pinned": false,
         "src": {
             "name": null,
-            "sha256": "sha256-4dEEy8zSjZYsClO6u+oWfvIlPYJq9+m1+a/mHTQRlaY=",
+            "sha256": "sha256-GTiyZsUHBXPgQ17DHAihmt2W/ZnAjDwfgwnujkRwk6A=",
             "type": "url",
-            "url": "https://github.com/nextcloud-releases/contacts/archive/v4.2.2.tar.gz"
+            "url": "https://github.com/nextcloud-releases/contacts/releases/download/v4.2.2/contacts-v4.2.2.tar.gz"
         },
         "version": "v4.2.2"
     },
@@ -68,11 +68,11 @@
         "pinned": false,
         "src": {
             "name": null,
-            "sha256": "sha256-TkUCCa7wP6leQbTsxKgD21Tf9CONVnbmvXCFhVBITZw=",
+            "sha256": "sha256-v64rLGyMQOdStyivpJsKrNxwumVQvyK3CnHtZ+K+elE=",
             "type": "url",
-            "url": "https://github.com/nextcloud/cookbook/archive/v0.9.15.tar.gz"
+            "url": "https://github.com/nextcloud/cookbook/releases/download/v0.9.15/Cookbook-0.9.15.tar.gz"
         },
-        "version": "v0.9.15"
+        "version": "0.9.15"
     },
     "news": {
         "cargoLocks": null,
@@ -83,11 +83,11 @@
         "pinned": false,
         "src": {
             "name": null,
-            "sha256": "sha256-eS0cFwJmYfGGJmA02AOWO/OXfqfyI71u2GataDj18DE=",
+            "sha256": "sha256-O6gaA+EN10dkfbDw5i6jV1NEyR4UP22Jj2DnWEzUcGg=",
             "type": "url",
-            "url": "https://github.com/nextcloud/news/releases/download/18.2.0/news.tar.gz"
+            "url": "https://github.com/nextcloud/news/releases/download/18.3.0/news.tar.gz"
         },
-        "version": "18.2.0"
+        "version": "18.3.0"
     },
     "notes": {
         "cargoLocks": null,
@@ -98,9 +98,9 @@
         "pinned": false,
         "src": {
             "name": null,
-            "sha256": "sha256-qhhaQyb9LgLza4CAcNZbl97xa271M7Wqmw8TtBEFpXk=",
+            "sha256": "sha256-rd3uVkVtARX4enRAWm1ivV468lboYZnYe7/zsqaHYpk=",
             "type": "url",
-            "url": "https://github.com/nextcloud/notes/archive/v4.5.1.tar.gz"
+            "url": "https://github.com/nextcloud/notes/releases/download/v4.5.1/notes.tar.gz"
         },
         "version": "v4.5.1"
     }
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index 5da7ca4..cb0c294 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -5,56 +5,56 @@
     pname = "apporder";
     version = "v0.15.0";
     src = fetchurl {
-      url = "https://github.com/juliushaertl/apporder/archive/v0.15.0.tar.gz";
-      sha256 = "sha256-2y2FHxli9mqlPvw9mABi09Z96OfB1AFD+XmuV5aOCxY=";
+      url = "https://github.com/juliushaertl/apporder/releases/download/v0.15.0/apporder.tar.gz";
+      sha256 = "sha256-p3VWxTYDCO2NePq6oLM8tBVqYkvoB7itqxp7IZwGDnE=";
     };
   };
   bookmarks = {
     pname = "bookmarks";
-    version = "v11.0.4";
+    version = "11.0.4";
     src = fetchurl {
-      url = "https://github.com/nextcloud/bookmarks/archive/v11.0.4.tar.gz";
-      sha256 = "sha256-X6Mg0jQ8EYPctiZ3tDtG4LUPwXRnDj9CJrJZrUs3Z/8=";
+      url = "https://github.com/nextcloud/bookmarks/releases/download/v11.0.4/bookmarks-11.0.4.tar.gz";
+      sha256 = "sha256-URqtzaCx8FEZHCDP1wSBUFNs+x50jesRtWi+xOU1oXM=";
     };
   };
   calendar = {
     pname = "calendar";
     version = "v3.5.0";
     src = fetchurl {
-      url = "https://github.com/nextcloud-releases/calendar/archive/v3.5.0.tar.gz";
-      sha256 = "sha256-keeWi/o+mOV7z5QNATJKwrd0olbCNdrK7YpGHg9qolk=";
+      url = "https://github.com/nextcloud-releases/calendar/releases/download/v3.5.0/calendar-v3.5.0.tar.gz";
+      sha256 = "sha256-+LRGl9h40AQdWN9SW+NqGwTafAGwV07Af8nVs3pUCm0=";
     };
   };
   contacts = {
     pname = "contacts";
     version = "v4.2.2";
     src = fetchurl {
-      url = "https://github.com/nextcloud-releases/contacts/archive/v4.2.2.tar.gz";
-      sha256 = "sha256-4dEEy8zSjZYsClO6u+oWfvIlPYJq9+m1+a/mHTQRlaY=";
+      url = "https://github.com/nextcloud-releases/contacts/releases/download/v4.2.2/contacts-v4.2.2.tar.gz";
+      sha256 = "sha256-GTiyZsUHBXPgQ17DHAihmt2W/ZnAjDwfgwnujkRwk6A=";
     };
   };
   cookbook = {
     pname = "cookbook";
-    version = "v0.9.15";
+    version = "0.9.15";
     src = fetchurl {
-      url = "https://github.com/nextcloud/cookbook/archive/v0.9.15.tar.gz";
-      sha256 = "sha256-TkUCCa7wP6leQbTsxKgD21Tf9CONVnbmvXCFhVBITZw=";
+      url = "https://github.com/nextcloud/cookbook/releases/download/v0.9.15/Cookbook-0.9.15.tar.gz";
+      sha256 = "sha256-v64rLGyMQOdStyivpJsKrNxwumVQvyK3CnHtZ+K+elE=";
     };
   };
   news = {
     pname = "news";
-    version = "18.2.0";
+    version = "18.3.0";
     src = fetchurl {
-      url = "https://github.com/nextcloud/news/releases/download/18.2.0/news.tar.gz";
-      sha256 = "sha256-eS0cFwJmYfGGJmA02AOWO/OXfqfyI71u2GataDj18DE=";
+      url = "https://github.com/nextcloud/news/releases/download/18.3.0/news.tar.gz";
+      sha256 = "sha256-O6gaA+EN10dkfbDw5i6jV1NEyR4UP22Jj2DnWEzUcGg=";
     };
   };
   notes = {
     pname = "notes";
     version = "v4.5.1";
     src = fetchurl {
-      url = "https://github.com/nextcloud/notes/archive/v4.5.1.tar.gz";
-      sha256 = "sha256-qhhaQyb9LgLza4CAcNZbl97xa271M7Wqmw8TtBEFpXk=";
+      url = "https://github.com/nextcloud/notes/releases/download/v4.5.1/notes.tar.gz";
+      sha256 = "sha256-rd3uVkVtARX4enRAWm1ivV468lboYZnYe7/zsqaHYpk=";
     };
   };
 }
diff --git a/pkgs/nextcloud-apps.toml b/pkgs/nextcloud-apps.toml
index 6d49d79..0620299 100644
--- a/pkgs/nextcloud-apps.toml
+++ b/pkgs/nextcloud-apps.toml
@@ -1,24 +1,26 @@
 [apporder]
 src.github = "juliushaertl/apporder"
-fetch.url = "https://github.com/juliushaertl/apporder/archive/$ver.tar.gz"
+fetch.url = "https://github.com/juliushaertl/apporder/releases/download/$ver/apporder.tar.gz"
 
 [bookmarks]
 src.github = "nextcloud/bookmarks"
-fetch.url = "https://github.com/nextcloud/bookmarks/archive/$ver.tar.gz"
+src.prefix = "v"
+fetch.url = "https://github.com/nextcloud/bookmarks/releases/download/v$ver/bookmarks-$ver.tar.gz"
 
 [calendar]
 src.manual = "v3.5.0" # Pinned until we update to nextcloud 25
 # src.github = "nextcloud-releases/calendar"
-fetch.url = "https://github.com/nextcloud-releases/calendar/archive/$ver.tar.gz"
+fetch.url = "https://github.com/nextcloud-releases/calendar/releases/download/$ver/calendar-$ver.tar.gz"
 
 [contacts]
 src.manual = "v4.2.2" # Pinned until we update to nextcloud 25
 # src.github = "nextcloud-releases/contacts"
-fetch.url = "https://github.com/nextcloud-releases/contacts/archive/$ver.tar.gz"
+fetch.url = "https://github.com/nextcloud-releases/contacts/releases/download/$ver/contacts-$ver.tar.gz"
 
 [cookbook]
 src.github = "nextcloud/cookbook"
-fetch.url = "https://github.com/nextcloud/cookbook/archive/$ver.tar.gz"
+src.prefix = "v"
+fetch.url = "https://github.com/nextcloud/cookbook/releases/download/v$ver/Cookbook-$ver.tar.gz"
 
 [news]
 src.github = "nextcloud/news"
@@ -29,4 +31,4 @@ fetch.url = "https://github.com/nextcloud/news/releases/download/$ver/news.tar.g
 [notes]
 src.manual = "v4.5.1" # Pinned until we update to nextcloud 25
 # src.github = "nextcloud/notes"
-fetch.url = "https://github.com/nextcloud/notes/archive/$ver.tar.gz"
+fetch.url = "https://github.com/nextcloud/notes/releases/download/$ver/notes.tar.gz"

From c72953e1ef3dbb6cff1e9944d2be142411aae526 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?=
 <tristan.maat@codethink.co.uk>
Date: Sat, 29 Oct 2022 00:13:44 +0100
Subject: [PATCH 065/212] matrix: Add coturn support for calls

---
 configuration/default.nix          | 40 ++++++++++++-----
 configuration/services/conduit.nix | 69 ++++++++++++++++++++++++++++++
 configuration/sops.nix             |  4 ++
 keys/production.yaml               |  9 ++--
 keys/staging.yaml                  |  9 ++--
 5 files changed, 114 insertions(+), 17 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index eb9d05e..ff97436 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -1,4 +1,5 @@
 {
+  config,
   pkgs,
   lib,
   modulesPath,
@@ -50,17 +51,34 @@
     useDHCP = false;
     interfaces.eth0.useDHCP = true;
 
-    firewall.allowedTCPPorts = [
-      # http
-      80
-      443
-      # ssh
-      2222
-      # matrix
-      8448
-      # starbound
-      21025
-    ];
+    firewall = {
+      allowedTCPPorts = [
+        # http
+        80
+        443
+        # ssh
+        2222
+        # matrix
+        8448
+        # starbound
+        21025
+
+        config.services.coturn.listening-port
+        config.services.coturn.tls-listening-port
+      ];
+
+      allowedUDPPorts = [
+        config.services.coturn.listening-port
+        config.services.coturn.tls-listening-port
+      ];
+
+      allowedUDPPortRanges = [
+        {
+          from = config.services.coturn.min-port;
+          to = config.services.coturn.max-port;
+        }
+      ];
+    };
   };
 
   time.timeZone = "Europe/London";
diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
index e8bbb6e..b60b668 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit.nix
@@ -1,6 +1,7 @@
 {config, ...}: let
   cfg = config.services.matrix-conduit;
   domain = "matrix.${config.services.nginx.domain}";
+  turn-realm = "turn.${config.services.nginx.domain}";
 in {
   services.matrix-conduit = {
     enable = true;
@@ -8,9 +9,77 @@ in {
       address = "127.0.0.1";
       server_name = domain;
       database_backend = "rocksdb";
+
+      turn_uris = let
+        address = "${config.services.coturn.realm}:${toString config.services.coturn.listening-port}";
+        tls-address = "${config.services.coturn.realm}:${toString config.services.coturn.tls-listening-port}";
+      in [
+        "turn:${address}?transport=udp"
+        "turn:${address}?transport=tcp"
+        "turns:${tls-address}?transport=udp"
+        "turns:${tls-address}?transport=tcp"
+      ];
     };
   };
 
+  # Pass in the TURN secret via EnvironmentFile, not supported by
+  # upstream module currently.
+  #
+  # See also https://gitlab.com/famedly/conduit/-/issues/314
+  systemd.services.conduit.serviceConfig.EnvironmentFile = config.sops.secrets."turn/env".path;
+
+  services.coturn = {
+    enable = true;
+    use-auth-secret = true;
+    static-auth-secret-file = config.sops.secrets."turn/secret".path;
+    realm = turn-realm;
+    relay-ips = [
+      "178.79.137.55"
+    ];
+
+    # Based on suggestions from
+    # https://github.com/matrix-org/synapse/blob/develop/docs/turn-howto.md
+    # and
+    # https://www.foxypossibilities.com/2018/05/19/setting-up-a-turn-sever-for-matrix-on-nixos/
+    no-tcp-relay = true;
+    secure-stun = true;
+    extraConfig = ''
+      # Deny various local IP ranges, see
+      # https://www.rtcsec.com/article/cve-2020-26262-bypass-of-coturns-access-control-protection/
+      no-multicast-peers
+      denied-peer-ip=0.0.0.0-0.255.255.255
+      denied-peer-ip=10.0.0.0-10.255.255.255
+      denied-peer-ip=100.64.0.0-100.127.255.255
+      denied-peer-ip=127.0.0.0-127.255.255.255
+      denied-peer-ip=169.254.0.0-169.254.255.255
+      denied-peer-ip=172.16.0.0-172.31.255.255
+      denied-peer-ip=192.0.0.0-192.0.0.255
+      denied-peer-ip=192.0.2.0-192.0.2.255
+      denied-peer-ip=192.88.99.0-192.88.99.255
+      denied-peer-ip=192.168.0.0-192.168.255.255
+      denied-peer-ip=198.18.0.0-198.19.255.255
+      denied-peer-ip=198.51.100.0-198.51.100.255
+      denied-peer-ip=203.0.113.0-203.0.113.255
+      denied-peer-ip=240.0.0.0-255.255.255.255 denied-peer-ip=::1
+      denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff
+      denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255
+      denied-peer-ip=100::-100::ffff:ffff:ffff:ffff
+      denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff
+      denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+      denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+      denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+      allowed-peer-ip=178.79.137.55
+
+      # Limit number of rooms
+      user-quota=12
+      total-quota=36
+
+      # Various other security settings
+      no-tlsv1
+      no-tlsv1_1
+    '';
+  };
+
   services.nginx.virtualHosts."${domain}" = {
     enableACME = true;
 
diff --git a/configuration/sops.nix b/configuration/sops.nix
index 8efa3af..6cc395b 100644
--- a/configuration/sops.nix
+++ b/configuration/sops.nix
@@ -6,5 +6,9 @@
       group = "nextcloud";
     };
     secrets."steam/tlater" = {};
+    secrets."turn/env" = {};
+    secrets."turn/secret" = {
+      owner = "turnserver";
+    };
   };
 }
diff --git a/keys/production.yaml b/keys/production.yaml
index bfc494f..d666be9 100644
--- a/keys/production.yaml
+++ b/keys/production.yaml
@@ -2,14 +2,17 @@ nextcloud:
     tlater: ENC[AES256_GCM,data:zNsPm4uFaIRe3LjcwmayRg==,iv:5wam6bP5zP708jC9UrLV0s8qspl3Pm4fPzbMFYBUyPQ=,tag:apnJUMeJwMn9q0NhO4ptmA==,type:str]
 steam:
     tlater: ENC[AES256_GCM,data:HNsve/Wid40ftclO9n09yXg=,iv:VQxAz4eR9lfxEvM0zl1FpJpbKrEFxjIYLyCqL9Aool0=,tag:LHcpHCXAHe8p2kOvOnKXyw==,type:str]
+turn:
+    env: ENC[AES256_GCM,data:kt5nhVo9pb/ZbPUEcqSYXxN9YMgQKnFb5VRfFFS/qoIaJ73uD2fuJKqcxAyVRrdLqnSAWSQBgTgunBzdP7xqLAK2qt8DYAQWHkIe9uxFbSXZpdmw,iv:9lq6SFwTFN4GGm6gPiJpUMasMdnHVF6XLGYrsyG3kjU=,tag:428Qf9DOiiHt/Wjb188b8g==,type:str]
+    secret: ENC[AES256_GCM,data:si7ee6Xfhdgdyzbp6aQpF7pz3TmTBb7iQ82lRPVXNDg9JfHI+lbmgAsSnRLX5qMCA6P9R045sSMosqidL8QwRg==,iv:SrhpZKK8D45yxCEfDb9P3TwtA14+qEI+wcRqcN/a6pw=,tag:PiwV+mOL9xHJgJft6sc61g==,type:str]
 sops:
     kms: []
     gcp_kms: []
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2022-10-12T13:13:37Z"
-    mac: ENC[AES256_GCM,data:+EuA0rblxZYk+0tZs3vUFtr1cVKhdrLi4Ww0QjeITZn2k+SL8Y2gRl3gNVQOe00WHUgSKN53QKhxDj4q6Rd0LfwASxRRjz78Mk8yHDRDIfdDS960EasgKON4HPW/eMd2Fp4+flv57KYywQQWp3AlD8JqxIf5wNhyywn5LlW3PCQ=,iv:YFIk0LrRjV8417QJ5cp5EuIm7bezyG8ZulKcu1xhIF4=,tag:vtq5hCuLEXOvRjE2D/5cCQ==,type:str]
+    lastmodified: "2022-10-28T22:53:26Z"
+    mac: ENC[AES256_GCM,data:fNcL/hQUsjSDULz9hOrr8268wNfRzARvuD+QQoUjhj5oDN3/zq800FjHrMBygTr962ueYdpfF7rW3exJqsf0TRVxlrSfvIX0U6Hwgpx7Ts6vMAmJeYdr28EuvbITuq9k14jhJrWmcqHOplJFSE1SoBedxF9LLor5gsc8WZDuBm8=,iv:d3roSZ//iosFzLj6dDWQl35Ya0Vlu2M9bAsWVWorBjI=,tag:8sX4R0WRoifYMJXiamSm9w==,type:str]
     pgp:
         - created_at: "2022-10-12T00:46:51Z"
           enc: |
@@ -47,4 +50,4 @@ sops:
             -----END PGP MESSAGE-----
           fp: 8a3737d48f1035fe6c3a0a8fd6a1976ca74c7f3b
     unencrypted_suffix: _unencrypted
-    version: 3.7.2
+    version: 3.7.3
diff --git a/keys/staging.yaml b/keys/staging.yaml
index 14a683a..9adfde8 100644
--- a/keys/staging.yaml
+++ b/keys/staging.yaml
@@ -2,14 +2,17 @@ nextcloud:
     tlater: ENC[AES256_GCM,data:91kDcO4hpng=,iv:ayuILRmRru4ZxTCur9H2xHuLjkDzwPdS/4lEog/tesU=,tag:qYhJxnNDcCwUM7xe7Tlcjw==,type:str]
 steam:
     tlater: ENC[AES256_GCM,data:jcW4wacGzOQ=,iv:KstKGHflscSWDFXGbnAZUcsqGN4Ot+w7sRbsAUwZNHQ=,tag:n9sRWvaKSgagpIgV/NF/Og==,type:str]
+turn:
+    env: ENC[AES256_GCM,data:xjIz/AY109lyiL5N01p5T3HcYco/rM5CJSRTtg==,iv:16bW6OpyOK/QL0QPGQp/Baa9xyT8E3ZsYkwqmjuofk0=,tag:J5re3uKxIykw3YunvQWBgg==,type:str]
+    secret: ENC[AES256_GCM,data:eQ7dAocoZtg=,iv:fgzjTPv30WqTKlLy+yMn5MsKQgjhPnwlGFFwYEg3gWs=,tag:1ze33U1NBkgMX/9SiaBNQg==,type:str]
 sops:
     kms: []
     gcp_kms: []
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2022-10-12T13:14:20Z"
-    mac: ENC[AES256_GCM,data:IlU8Jr+HD/ZHHsd7eaaSGp3tRxGy8/yhbSejkWmHFeL1WsvdWsToHM7yah2WzX+uY7s/i7atHQdhbHITCi6gBIFociVVPwziK5YOmTXv1fHlcD60U4ClRbTtgMVMtvc5tXrxdLQGhaX+DJ5xXBhTlCSwwqgYP0I7vJmEUF9mz7g=,iv:IM1ebqQB1UO5EN92kipHL20iGtFTKJhUiN/XR6psWBM=,tag:WweauZ5pA7/YMuUuq8C/xQ==,type:str]
+    lastmodified: "2022-10-28T22:54:01Z"
+    mac: ENC[AES256_GCM,data:1nsv+Dl7lzRZNNb9kSuqFrXrcncIklw/A2uwd/yQQ546Rm/4gzpBZqCi6cv5VBCdc1iNuBcAM74DnZHMDmeWAiW0WfACPJMQjCes21P6IUsP2gu+bV2f9qqqnP2a5voxzFHp1aclklzMiiZJBEB1Y3UNz0ZG7A43hsOAE0/fJ9o=,iv:kY10PF5ErkKHXx8m0OyX2eU6kcFQsrsP3V2scVBMsuA=,tag:Uth0XfP2c0LBJQ7+7Uc0BQ==,type:str]
     pgp:
         - created_at: "2022-10-12T16:48:23Z"
           enc: |
@@ -47,4 +50,4 @@ sops:
             -----END PGP MESSAGE-----
           fp: 7762ec55a5727cabada621d961e53f94caa314e4
     unencrypted_suffix: _unencrypted
-    version: 3.7.2
+    version: 3.7.3

From 5c89aa5b834df2b7133f1e529193d2dd1ad13563 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?=
 <tristan.maat@codethink.co.uk>
Date: Sun, 30 Oct 2022 17:13:15 +0000
Subject: [PATCH 066/212] Update

---
 flake.lock                             | 32 +++++++++++++-------------
 pkgs/_sources_nextcloud/generated.json | 12 +++++-----
 pkgs/_sources_nextcloud/generated.nix  | 12 +++++-----
 3 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/flake.lock b/flake.lock
index 126fb51..fd1773d 100644
--- a/flake.lock
+++ b/flake.lock
@@ -275,11 +275,11 @@
     },
     "nixpkgs-22_05": {
       "locked": {
-        "lastModified": 1665279158,
-        "narHash": "sha256-TpbWNzoJ5RaZ302dzvjY2o//WxtOJuYT3CnDj5N69Hs=",
+        "lastModified": 1667091951,
+        "narHash": "sha256-62sz0fn06Nq8OaeBYrYSR3Y6hUcp8/PC4dJ7HeGaOhU=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "b3783bcfb8ec54e0de26feccfc6cc36b8e202ed5",
+        "rev": "6440d13df2327d2db13d3b17e419784020b71d22",
         "type": "github"
       },
       "original": {
@@ -291,11 +291,11 @@
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1666424192,
-        "narHash": "sha256-rb/a7Kg9s31jqkvdOQHFrUc5ig5kB+O2ZKB8mjU2kW8=",
+        "lastModified": 1667055375,
+        "narHash": "sha256-xfSTHYxuKRiqF4dcuAFdti1OUvrC2lHpQqCHWUK5/JA=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "4f8287f3d597c73b0d706cfad028c2d51821f64d",
+        "rev": "7f9be6a505a31f88499c5d20d11f98accf5ae6ba",
         "type": "github"
       },
       "original": {
@@ -307,11 +307,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1665466769,
-        "narHash": "sha256-L+qcHpb4Ac3PipMXJY/Ktbu1+KXy23WCZ8pXWmsf7zY=",
+        "lastModified": 1666961615,
+        "narHash": "sha256-+Sqz6zQA85Q14U/KwsJO386oxd47zDte8dqBGOtRJGg=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "0b20bf89e0035b6d62ad58f9db8fdbc99c2b01e8",
+        "rev": "040c6d8374d090f46ab0e99f1f7c27a4529ecffd",
         "type": "github"
       },
       "original": {
@@ -454,11 +454,11 @@
         "nixpkgs-22_05": "nixpkgs-22_05"
       },
       "locked": {
-        "lastModified": 1665289655,
-        "narHash": "sha256-j1Q9mNBhbzeJykhObiXwEGres9qvP4vH7gxdJ+ihkLI=",
+        "lastModified": 1667102919,
+        "narHash": "sha256-DP5j4TwXe96eZf0PLgYSj1Hdyt7SPUoQ003iNBQSKpQ=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "0ce0449e6404c4ff9d1b7bd657794ae5ca54deb3",
+        "rev": "448ec3e7eb7c7e4563cc2471db748a71baaf9698",
         "type": "github"
       },
       "original": {
@@ -476,11 +476,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1665402451,
-        "narHash": "sha256-zWaEzUJh0WFVoaLQsMoIj2D+QFhUBJw+f+XzoYqw3es=",
+        "lastModified": 1665746303,
+        "narHash": "sha256-lDVy7aBsAaO5TyeoZS4wL6qcBNuU1bQCcHPJxiEKtao=",
         "ref": "master",
-        "rev": "6c29bc5db001e75f5ca06fec726369b87d007a03",
-        "revCount": 47,
+        "rev": "5d037f9122e68aaa5db62d04810bf0c5e1e4325e",
+        "revCount": 49,
         "type": "git",
         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git"
       },
diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index c93a3b6..23dc755 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -68,11 +68,11 @@
         "pinned": false,
         "src": {
             "name": null,
-            "sha256": "sha256-v64rLGyMQOdStyivpJsKrNxwumVQvyK3CnHtZ+K+elE=",
+            "sha256": "sha256-P3jgNAFcABwTBzOnW9/R6hp8Ak6XoXvz+B9GVS9/BeM=",
             "type": "url",
-            "url": "https://github.com/nextcloud/cookbook/releases/download/v0.9.15/Cookbook-0.9.15.tar.gz"
+            "url": "https://github.com/nextcloud/cookbook/releases/download/v0.9.16/Cookbook-0.9.16.tar.gz"
         },
-        "version": "0.9.15"
+        "version": "0.9.16"
     },
     "news": {
         "cargoLocks": null,
@@ -83,11 +83,11 @@
         "pinned": false,
         "src": {
             "name": null,
-            "sha256": "sha256-O6gaA+EN10dkfbDw5i6jV1NEyR4UP22Jj2DnWEzUcGg=",
+            "sha256": "sha256-lVF4H9v7bSw8137lfq4PsVg8e1TpcgvJVQU/UVQfSoY=",
             "type": "url",
-            "url": "https://github.com/nextcloud/news/releases/download/18.3.0/news.tar.gz"
+            "url": "https://github.com/nextcloud/news/releases/download/19.0.0/news.tar.gz"
         },
-        "version": "18.3.0"
+        "version": "19.0.0"
     },
     "notes": {
         "cargoLocks": null,
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index cb0c294..c1e35e7 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -35,18 +35,18 @@
   };
   cookbook = {
     pname = "cookbook";
-    version = "0.9.15";
+    version = "0.9.16";
     src = fetchurl {
-      url = "https://github.com/nextcloud/cookbook/releases/download/v0.9.15/Cookbook-0.9.15.tar.gz";
-      sha256 = "sha256-v64rLGyMQOdStyivpJsKrNxwumVQvyK3CnHtZ+K+elE=";
+      url = "https://github.com/nextcloud/cookbook/releases/download/v0.9.16/Cookbook-0.9.16.tar.gz";
+      sha256 = "sha256-P3jgNAFcABwTBzOnW9/R6hp8Ak6XoXvz+B9GVS9/BeM=";
     };
   };
   news = {
     pname = "news";
-    version = "18.3.0";
+    version = "19.0.0";
     src = fetchurl {
-      url = "https://github.com/nextcloud/news/releases/download/18.3.0/news.tar.gz";
-      sha256 = "sha256-O6gaA+EN10dkfbDw5i6jV1NEyR4UP22Jj2DnWEzUcGg=";
+      url = "https://github.com/nextcloud/news/releases/download/19.0.0/news.tar.gz";
+      sha256 = "sha256-lVF4H9v7bSw8137lfq4PsVg8e1TpcgvJVQU/UVQfSoY=";
     };
   };
   notes = {

From b3e8b0e85cf450386a4ff323b3ae079fbfbded2e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?=
 <tristan.maat@codethink.co.uk>
Date: Sun, 30 Oct 2022 17:43:52 +0000
Subject: [PATCH 067/212] default.nix: Turn on minimal profile

---
 configuration/default.nix            | 4 ++++
 configuration/services/starbound.nix | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/configuration/default.nix b/configuration/default.nix
index ff97436..f5d68fb 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -7,6 +7,7 @@
 }: {
   imports = [
     "${modulesPath}/profiles/headless.nix"
+    "${modulesPath}/profiles/minimal.nix"
     (import ../modules)
 
     ./services/conduit.nix
@@ -135,5 +136,8 @@
     ];
   };
 
+  # Remove some unneeded packages
+  environment.defaultPackages = [];
+
   system.stateVersion = "20.09";
 }
diff --git a/configuration/services/starbound.nix b/configuration/services/starbound.nix
index 5dc0961..419f0e4 100644
--- a/configuration/services/starbound.nix
+++ b/configuration/services/starbound.nix
@@ -5,6 +5,9 @@
 }: let
   inherit (lib) concatStringsSep;
 in {
+  # Sadly, steam-run requires some X libs
+  environment.noXlibs = false;
+
   systemd.services.starbound = {
     description = "Starbound";
     after = ["network.target"];

From 73023b817d76760c077e1ddab43d731d5ebc9fdb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?=
 <tristan.maat@codethink.co.uk>
Date: Mon, 31 Oct 2022 16:06:31 +0000
Subject: [PATCH 068/212] conduit: Use dependencies from stable

Partially to circumvent the upcoming openssl CVE, partially to reduce
the number of dependencies.
---
 lib/default.nix | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/lib/default.nix b/lib/default.nix
index da4031f..5cd7382 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -28,7 +28,9 @@ in {
           {
             nixpkgs.overlays = [
               (self: super: {
-                matrix-conduit = nixpkgs-unstable.legacyPackages.${system}.matrix-conduit;
+                matrix-conduit = nixpkgs-unstable.legacyPackages.${system}.matrix-conduit.override {
+                  inherit (self) stdenv lib fetchFromGitLab rustPlatform pkg-config rocksdb;
+                };
               })
             ];
           }

From 2304711359ff33551d00bc6a90ac1bd88a06ad68 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?=
 <tristan.maat@codethink.co.uk>
Date: Mon, 31 Oct 2022 16:07:41 +0000
Subject: [PATCH 069/212] config: Mitigate upcoming SSL CVE

See
https://mta.openssl.org/pipermail/openssl-announce/2022-October/000238.html

As 1.1 is unaffected, this override should be sufficient to evade this
problem.
---
 configuration/default.nix | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/configuration/default.nix b/configuration/default.nix
index f5d68fb..9c0ce68 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -25,6 +25,10 @@
         pkgs = prev;
         lib = prev.lib;
       };
+
+      # Mitigate
+      # https://mta.openssl.org/pipermail/openssl-announce/2022-October/000238.html
+      nginxStable = prev.nginxStable.override {openssl = prev.openssl_1_1;};
     })
   ];
 

From ea06138a9b856982b82611723e76e830e959af7a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?=
 <tristan.maat@codethink.co.uk>
Date: Sat, 5 Nov 2022 16:00:50 +0000
Subject: [PATCH 070/212] flake.nix: Add packages for utility scripts to enable
 `nix build`

---
 flake.nix | 40 ++++++++++++++++++++++++++--------------
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/flake.nix b/flake.nix
index f190d89..2dc31c0 100644
--- a/flake.nix
+++ b/flake.nix
@@ -72,13 +72,15 @@
       lib = nixpkgs.lib;
     };
 
-    ####################
-    # VM launch script #
-    ####################
-    apps.${system} = let
+    ###################
+    # Utility scripts #
+    ###################
+    packages.${system} = let
       inherit (nixpkgs.legacyPackages.${system}) writeShellScript;
     in {
-      default = let
+      default = self.packages.${system}.run-vm;
+
+      run-vm = let
         vm = self.lib.makeNixosSystem {
           inherit system;
           extraModules = [(import ./configuration/hardware-specific/vm.nix)];
@@ -91,23 +93,33 @@
           "8448" = "8448"; # Matrix
           "21025" = "21025"; # Starbound
         };
-      in {
-        type = "app";
-        program = builtins.toString (writeShellScript "run-vm" ''
+      in
+        writeShellScript "run-vm" ''
           export QEMU_OPTS="-m 3941 -smp 2 -display curses"
           export QEMU_NET_OPTS="${qemuNetOpts}"
           "${vm.config.system.build.vm}/bin/run-tlaternet-vm"
-        '');
-      };
+        '';
 
       update-nextcloud-apps = let
         nvfetcher-bin = "${nvfetcher.defaultPackage.${system}}/bin/nvfetcher";
-      in {
-        type = "app";
-        program = builtins.toString (writeShellScript "update-nextcloud-apps" ''
+      in
+        writeShellScript "update-nextcloud-apps" ''
           cd "$(git rev-parse --show-toplevel)/pkgs"
           ${nvfetcher-bin} -o _sources_nextcloud -c nextcloud-apps.toml
-        '');
+        '';
+    };
+
+    apps.${system} = let
+      inherit (nixpkgs.legacyPackages.${system}) writeShellScript;
+    in {
+      default = {
+        type = "app";
+        program = builtins.toString self.packages.${system}.run-vm;
+      };
+
+      update-nextcloud-apps = {
+        type = "app";
+        program = builtins.toString self.packages.${system}.update-nextcloud-apps;
       };
     };
 

From 598c4390024a0d2b4d9316bf83093707ff731314 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?=
 <tristan.maat@codethink.co.uk>
Date: Sat, 5 Nov 2022 16:01:18 +0000
Subject: [PATCH 071/212] conduit: Disable turns, remove the user limits and
 add all relay IPs

---
 configuration/services/conduit.nix | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
index b60b668..13be08f 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit.nix
@@ -1,4 +1,10 @@
-{config, ...}: let
+{
+  config,
+  lib,
+  ...
+}: let
+  inherit (lib.strings) concatMapStringsSep;
+
   cfg = config.services.matrix-conduit;
   domain = "matrix.${config.services.nginx.domain}";
   turn-realm = "turn.${config.services.nginx.domain}";
@@ -16,8 +22,6 @@ in {
       in [
         "turn:${address}?transport=udp"
         "turn:${address}?transport=tcp"
-        "turns:${tls-address}?transport=udp"
-        "turns:${tls-address}?transport=tcp"
       ];
     };
   };
@@ -68,11 +72,9 @@ in {
       denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff
       denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
       denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
-      allowed-peer-ip=178.79.137.55
 
-      # Limit number of rooms
-      user-quota=12
-      total-quota=36
+      # *Allow* any IP addresses that we explicitly set as relay IPs
+      ${concatMapStringsSep "\n" (ip: "allowed-peer-ip=${ip}") config.services.coturn.relay-ips}
 
       # Various other security settings
       no-tlsv1

From 85a989d3c8ccff9b880dfd1a63e3d03e9304cac6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?=
 <tristan.maat@codethink.co.uk>
Date: Sat, 5 Nov 2022 17:31:24 +0000
Subject: [PATCH 072/212] nvfetcher: Don't allow fetching rc versions of
 nextcloud cookbook

---
 pkgs/nextcloud-apps.toml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/pkgs/nextcloud-apps.toml b/pkgs/nextcloud-apps.toml
index 0620299..6e06432 100644
--- a/pkgs/nextcloud-apps.toml
+++ b/pkgs/nextcloud-apps.toml
@@ -18,8 +18,9 @@ src.manual = "v4.2.2" # Pinned until we update to nextcloud 25
 fetch.url = "https://github.com/nextcloud-releases/contacts/releases/download/$ver/contacts-$ver.tar.gz"
 
 [cookbook]
-src.github = "nextcloud/cookbook"
+src.github_tag = "nextcloud/cookbook"
 src.prefix = "v"
+src.exclude_regex = 'v\d+\.\d+\.\d+-rc\d+'
 fetch.url = "https://github.com/nextcloud/cookbook/releases/download/v$ver/Cookbook-$ver.tar.gz"
 
 [news]

From 4d5eaf34be2ee60bc1861587679dc6be56fa485f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?=
 <tristan.maat@codethink.co.uk>
Date: Sat, 5 Nov 2022 17:31:58 +0000
Subject: [PATCH 073/212] Update inputs

---
 flake.lock                             | 30 +++++++++++++-------------
 pkgs/_sources_nextcloud/generated.json |  6 +++---
 pkgs/_sources_nextcloud/generated.nix  |  8 +++----
 3 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/flake.lock b/flake.lock
index fd1773d..8507c27 100644
--- a/flake.lock
+++ b/flake.lock
@@ -182,11 +182,11 @@
     },
     "flake-utils": {
       "locked": {
-        "lastModified": 1659877975,
-        "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
+        "lastModified": 1667077288,
+        "narHash": "sha256-bdC8sFNDpT0HK74u9fUkpbf1MEzVYJ+ka7NXCdgBoaA=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
+        "rev": "6ee9ebb6b1ee695d2cacc4faa053a7b9baa76817",
         "type": "github"
       },
       "original": {
@@ -291,11 +291,11 @@
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1667055375,
-        "narHash": "sha256-xfSTHYxuKRiqF4dcuAFdti1OUvrC2lHpQqCHWUK5/JA=",
+        "lastModified": 1667610399,
+        "narHash": "sha256-XZd0f4ZWAY0QOoUSdiNWj/eFiKb4B9CJPtl9uO9SYY4=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "7f9be6a505a31f88499c5d20d11f98accf5ae6ba",
+        "rev": "1dd8696f96db47156e1424a49578fe7dd4ce99a4",
         "type": "github"
       },
       "original": {
@@ -307,11 +307,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1666961615,
-        "narHash": "sha256-+Sqz6zQA85Q14U/KwsJO386oxd47zDte8dqBGOtRJGg=",
+        "lastModified": 1667564121,
+        "narHash": "sha256-DlR65WyEW78cBmnOhxDzfvNQ9euJEGctSl77olqEaLg=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "040c6d8374d090f46ab0e99f1f7c27a4529ecffd",
+        "rev": "1404483f4531560aad73bdebae4096881c910ac0",
         "type": "github"
       },
       "original": {
@@ -345,11 +345,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1664550666,
-        "narHash": "sha256-eXfMRd9uItEp3PsYI31FSVGPG9dVC6yF++65ZrGwW8A=",
+        "lastModified": 1667620329,
+        "narHash": "sha256-v1Zk7rtEbAGpevBGPZvZBKpwbmw4I+uVwxvd+pBlp3o=",
         "owner": "berberman",
         "repo": "nvfetcher",
-        "rev": "9763ad40d59a044e90726653d9253efaeeb053b2",
+        "rev": "294826951113dcd3aa9abbcacfb1aa5b95a19116",
         "type": "github"
       },
       "original": {
@@ -454,11 +454,11 @@
         "nixpkgs-22_05": "nixpkgs-22_05"
       },
       "locked": {
-        "lastModified": 1667102919,
-        "narHash": "sha256-DP5j4TwXe96eZf0PLgYSj1Hdyt7SPUoQ003iNBQSKpQ=",
+        "lastModified": 1667427533,
+        "narHash": "sha256-MsgTnQEi1g7f8anlW5klHW2pJgam4CLbJaYyBw2ed58=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "448ec3e7eb7c7e4563cc2471db748a71baaf9698",
+        "rev": "486b4455da16272c1ed31bc82adcdbe7af829465",
         "type": "github"
       },
       "original": {
diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index 23dc755..c4a4b55 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -68,11 +68,11 @@
         "pinned": false,
         "src": {
             "name": null,
-            "sha256": "sha256-P3jgNAFcABwTBzOnW9/R6hp8Ak6XoXvz+B9GVS9/BeM=",
+            "sha256": "sha256-3lCqvmaMsgrFD5PzyHIcwxxGeC+qOMTGxbOi7nPFL6I=",
             "type": "url",
-            "url": "https://github.com/nextcloud/cookbook/releases/download/v0.9.16/Cookbook-0.9.16.tar.gz"
+            "url": "https://github.com/nextcloud/cookbook/releases/download/v0.9.17/Cookbook-0.9.17.tar.gz"
         },
-        "version": "0.9.16"
+        "version": "0.9.17"
     },
     "news": {
         "cargoLocks": null,
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index c1e35e7..324306d 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -1,5 +1,5 @@
 # This file was generated by nvfetcher, please do not modify it manually.
-{ fetchgit, fetchurl, fetchFromGitHub }:
+{ fetchgit, fetchurl, fetchFromGitHub, dockerTools }:
 {
   apporder = {
     pname = "apporder";
@@ -35,10 +35,10 @@
   };
   cookbook = {
     pname = "cookbook";
-    version = "0.9.16";
+    version = "0.9.17";
     src = fetchurl {
-      url = "https://github.com/nextcloud/cookbook/releases/download/v0.9.16/Cookbook-0.9.16.tar.gz";
-      sha256 = "sha256-P3jgNAFcABwTBzOnW9/R6hp8Ak6XoXvz+B9GVS9/BeM=";
+      url = "https://github.com/nextcloud/cookbook/releases/download/v0.9.17/Cookbook-0.9.17.tar.gz";
+      sha256 = "sha256-3lCqvmaMsgrFD5PzyHIcwxxGeC+qOMTGxbOi7nPFL6I=";
     };
   };
   news = {

From 0528f73187011e16e9cdc6c83924d59cb36480c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?=
 <tristan.maat@codethink.co.uk>
Date: Sat, 5 Nov 2022 17:33:28 +0000
Subject: [PATCH 074/212] nginx: Remove mitigation for openssl CVE

This has been fixed, instead we just update to the latest openssl.
---
 configuration/default.nix | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index 9c0ce68..f5d68fb 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -25,10 +25,6 @@
         pkgs = prev;
         lib = prev.lib;
       };
-
-      # Mitigate
-      # https://mta.openssl.org/pipermail/openssl-announce/2022-October/000238.html
-      nginxStable = prev.nginxStable.override {openssl = prev.openssl_1_1;};
     })
   ];
 

From 997707021b70aa694ef863f6ae088e4c6fb4c702 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?=
 <tristan.maat@codethink.co.uk>
Date: Sat, 5 Nov 2022 17:59:27 +0000
Subject: [PATCH 075/212] config: Enable authorization through ssh agent

This enables sudo-via-yubikey and therefore makes `-t` obsolete, in
turn fixing a whole sleuth of issues with deploy-rs.

*And* seems more secure and convenient at the same time.
---
 configuration/default.nix | 9 +++++++++
 flake.nix                 | 4 +---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index f5d68fb..fc1ba7a 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -100,6 +100,15 @@
     gatewayPorts = "yes";
   };
 
+  security = {
+    sudo.execWheelOnly = true;
+
+    pam = {
+      enableSSHAgentAuth = true;
+      services.sudo.sshAgentAuth = true;
+    };
+  };
+
   services.nginx = {
     enable = true;
     recommendedTlsSettings = true;
diff --git a/flake.nix b/flake.nix
index 2dc31c0..04aa990 100644
--- a/flake.nix
+++ b/flake.nix
@@ -53,10 +53,8 @@
       };
 
       sshUser = "tlater";
-      sshOpts = ["-t" "-p" "2222"];
+      sshOpts = ["-p" "2222" "-o" "ForwardAgent=yes"];
       fastConnection = true;
-      # Currently broken, see https://github.com/serokell/deploy-rs/issues/78
-      magicRollback = false;
     };
 
     #########

From a28d385b17c586b7e5bd2cf133ac79f9998a18d7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?=
 <tristan.maat@codethink.co.uk>
Date: Sat, 5 Nov 2022 22:26:52 +0000
Subject: [PATCH 076/212] conduit: Enable TURNS with a ZeroSSL-provided
 certificate

---
 configuration/default.nix          |  4 ++++
 configuration/services/conduit.nix | 10 ++++++++++
 configuration/sops.nix             |  6 ++++++
 keys/production.yaml               |  7 +++++--
 4 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index fc1ba7a..34a7868 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -66,11 +66,15 @@
 
         config.services.coturn.listening-port
         config.services.coturn.tls-listening-port
+        config.services.coturn.alt-listening-port
+        config.services.coturn.alt-tls-listening-port
       ];
 
       allowedUDPPorts = [
         config.services.coturn.listening-port
         config.services.coturn.tls-listening-port
+        config.services.coturn.alt-listening-port
+        config.services.coturn.alt-tls-listening-port
       ];
 
       allowedUDPPortRanges = [
diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
index 13be08f..6da82da 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit.nix
@@ -22,6 +22,8 @@ in {
       in [
         "turn:${address}?transport=udp"
         "turn:${address}?transport=tcp"
+        "turns:${tls-address}?transport=udp"
+        "turns:${tls-address}?transport=tcp"
       ];
     };
   };
@@ -34,6 +36,7 @@ in {
 
   services.coturn = {
     enable = true;
+    no-cli = true;
     use-auth-secret = true;
     static-auth-secret-file = config.sops.secrets."turn/secret".path;
     realm = turn-realm;
@@ -41,6 +44,13 @@ in {
       "178.79.137.55"
     ];
 
+    # SSL config
+    #
+    # TODO(tlater): Switch to letsencrypt once google fix:
+    #  https://github.com/vector-im/element-android/issues/1533
+    pkey = config.sops.secrets."turn/ssl-key".path;
+    cert = config.sops.secrets."turn/ssl-cert".path;
+
     # Based on suggestions from
     # https://github.com/matrix-org/synapse/blob/develop/docs/turn-howto.md
     # and
diff --git a/configuration/sops.nix b/configuration/sops.nix
index 6cc395b..21613b2 100644
--- a/configuration/sops.nix
+++ b/configuration/sops.nix
@@ -10,5 +10,11 @@
     secrets."turn/secret" = {
       owner = "turnserver";
     };
+    secrets."turn/ssl-key" = {
+      owner = "turnserver";
+    };
+    secrets."turn/ssl-cert" = {
+      owner = "turnserver";
+    };
   };
 }
diff --git a/keys/production.yaml b/keys/production.yaml
index d666be9..6bc16ad 100644
--- a/keys/production.yaml
+++ b/keys/production.yaml
@@ -5,14 +5,17 @@ steam:
 turn:
     env: ENC[AES256_GCM,data:kt5nhVo9pb/ZbPUEcqSYXxN9YMgQKnFb5VRfFFS/qoIaJ73uD2fuJKqcxAyVRrdLqnSAWSQBgTgunBzdP7xqLAK2qt8DYAQWHkIe9uxFbSXZpdmw,iv:9lq6SFwTFN4GGm6gPiJpUMasMdnHVF6XLGYrsyG3kjU=,tag:428Qf9DOiiHt/Wjb188b8g==,type:str]
     secret: ENC[AES256_GCM,data:si7ee6Xfhdgdyzbp6aQpF7pz3TmTBb7iQ82lRPVXNDg9JfHI+lbmgAsSnRLX5qMCA6P9R045sSMosqidL8QwRg==,iv:SrhpZKK8D45yxCEfDb9P3TwtA14+qEI+wcRqcN/a6pw=,tag:PiwV+mOL9xHJgJft6sc61g==,type:str]
+    ssl-key: ENC[AES256_GCM,data:CHFH8XTcyAkIDwclwUpAyDkvP0awoW7mtZ2PgR81DyQZrKIAjuhox7x+8Gl9vfjdug2WLISycwoCJ2w+Y6Qpuk+XgXOmZeBU4UyMX5sfwGYAt0fjyQPix3Xni3cfDPQ3bJ9Ez0Nn6pxmKvSUY2nCOPJe8gK5+kaMt3d2SWS1bteH/rOUXSx3hczdQ54M8kScTUHceG7G65rfrmpTIVS1GNRYm7N8F8uXToP3qdTJBF03qSfdbAvWw5RhkNQoF35Hc8HT2W5hYmUb6ceuo4b3tCyTVDGzNtqn760+VSqXcJ5acc4O22cH/TqeF7VSS7akUqZzYot92riqSL0lHbET6VlXuYdidNIgW5uoUgtJLj9KRkYljOHkP1H90acWTW0+T3jS9cesVBVDWCHaYt2rFKwQgViNvgU27f1u9PT4wGKyqQMnLE5iLdmUT4qAwNw8ErXnpIOlXDizZ0sYXtNEmlNGdOk3jrjW3C1TGBw77PmWzHHRBrRNMO/6s3QWuRgTdQixF/UzTvyRf5yjt7Cev8fDm16FL8c+2uduDTkxTKwEVrt6U1wsJMqS52u7jAj5xtpmWSGJRqxc/bu9l+fcRDrZt1EaktxKCc3zSFp8Mv+LwMdj6dXcYoFQZmh5N2rySmxdCeHT+Me8htReesVxDPG5/pIZJ7n5DYK60V84KnDaqiw0DM0XEY6Y9UJ0Vx6qvk8lVouQaPbxEnfwc3775jVojEA/nCBd7LiyRfUEILtSgm+IjhIvVjDr3qzzKo7Ao66trEN6Sb7UtYo11rUyGfKqOwAZTsb/bXk6pYWo/qhzwx9EfxCrrMt06mXjN7JGzIZeBlV0azHEw1jt/CJ2lPFSUuTWIjjtTfZzpx6jYBJmTN9rAMbKHMknO3hEKWwpzYG/w7TLO2JKkXrOdT58IdvfxOKwaQ/kJRycYvuWcF8NqdcRhbZvrVaKHRWhWldhWkOj5a+G0DnFsgak6D1FOvDx0doN8hibFemn1MfLzk6/UJ5AxAbPCRSaEumkMZ6n/Xx5M+C7TswWrYVkrIeRxSU6+B24ZmLeVvfvNq6jfBBgk3MBXHU6bwr/nsfcQ0wlJwYCc/YVP02d/oAhN/MobUSKY+bG+ZirmyRb3MZ5C5ZjLY60wcSSWpty7jPzMUu0AoJVs6CA04frw9FqmW+Y0f3apFfaPI8OSOqT8UUURORjWK0j35v9nrpoDGTqLdq1d0oVQW3vxQqE6gmyPv4/ZqPgdUZhZ6BYiDc9L79c4misxmxsy6pZBxwb0vY34PyCwpamTWZC8u7JxRoXYu1l/UTdz9Oj2z1smaouy7yNKMK/BitF4uv3sKi0lWOpE6oTtqNtEoC265RUot3CGjaI3aZnwgku8jztvSn0JVwQYZyWZx7eFRh1acNIt3zRP8Pc4SL+XCm8RSufH2+j1kF0rbhCGTngDaLWdz/1FIWTizj3sjLnMEQYYw02QE1W+b9TJAMmgdh6LFhjrIFXtQFQtNSgH6edh8nreFWnpDvI8nyT9w/cCfJhDZhEvOYIDOVlc0mPH2k0yNfpA4x0DOvBNZJx9Gu0CcyOLRZGlyAwlDTIqBYLLV7bqwTsOdfOYBE581T2r+o9w/tgRF4EORM29U1KjGjSl2/XBXQVZHbRnXBM5l7kypyJfHD7X5DUp2hkuSdmHgBI5psnZXSjHh95Nn5YjFAAPDapqdIJO2AJhXkaY57mSUFjLrI9DRFU8pcqeY33si4i1QOqsRdkfh72+vCwsj4gFteV0Sh6N2Tp92+NkY0to3hk6Za9O6ESzqCiokcf9DaCyWv4ELd6Wed2DVVfrPXLABF5hnfzYw/tvtpXMFOOofKyOYY4KT5FRVUGlsst/x0F9wr2hYJ1qwTIRpp9wEWjiecO+wBeuNbLHv727pMCPcLX7YEoa/fcQuesuEAXQDKFTVJmBAHk1J5GpOu0R5F6qXAxsR9MFDRMHo2en4jkTAWgWFa7n6UqRlTTu5lj9RtFgQekayC71GyTEqvBY2tdLfHYoNsKKVBand7fmpwGDG2kivEUMNDitT2AG2F2GxbM+zbLewu3WwlXCzyEYpPq34+WK+C+QZuY+b4bOVnNTl1aiyMTIauomDTdvUbGAlnoIeukc65O1nvlI5uEQwgcxA/nFGYPdiXJKlgW0rZPaJX+7xZUlosP9fYR+1purREYHJBFPGs7Qx3Fq/RuPEcA2S9+CynhXm3TRRLOfzKYXeny/qdpJw==,iv:lpQ/utPri3QEIvB8V5MzHmgyeyGmlVGbkbNKKrb10lM=,tag:eWFSV+nRqDfYERXTXT8eAQ==,type:str]
+    #ENC[AES256_GCM,data:DkvLWzxK8Xp/TXnJNZ15Wa+ojB7qGxh44zvwdm50ENgTPaqIl2468q+HeOUIUE7OiXCQWj2PVg==,iv:J9EkotYGBY1FZo62wieUSFaTCn1NnBb6aOKnUOCELS8=,tag:vmxNYyjCYfi6n9nBZ8DwPg==,type:comment]
+    ssl-cert: ENC[AES256_GCM,data:frN9jDBZA2gyrCASsw6T5f5ld0CH+2m1YQOPWh53UfQnr9RxQUhvBYvwMtNJ2+DaT7GHTxZDC7Ft48DkrCKOawt3Z9BKkukYz3Wy9ozDUQ6dB4Hil4O76TQ+Lb3Yn5rKrJWIyR/QUwnv/HdpjxbrHMYw6Uc04uLj4djE+l5e2Iof3gYX64TDaB0ZQkvSAGWO92a3K2cwOKORNltR6KlJ9VzWixHBX8INJaGlPAnHMQkwu9ppkz8waYiIC9sWqwlMep8gN9mvPpq7fxMOvb8az3CkTmLTgXlDx5wxIx56uHlHkNlYKMvz3/HV8PAAIrMod6DCESeDIIP/g004rQRVpxMP5+G9uWklNFDcSpVIzHvl1GLqw05FCQGk93Tj+NmPt7dJiZssPz4dtthXEHg7/phOQJykJkyNVHcfIheqJHK1EQ3WztDJR9hGHUVepnRKo4VseVu6wIeOPa4En9OQ850+AfiekWcivfH9QMW2H3hsknC6Z2+Nb6X6AQBX9GPYwSjmioSbMSOIJpbvTxiM5K9AP25o13NHRH1xwydOqpTPxk0tf47o7PUyJ5gM/0zK60IwRVjRHb4974bpX10K3zLDgin9/WfjetsCm5o7QSs0JfzhTwxZeIC14ZrVwutdR9/KevK+305F7wpQO2jI3WHxniJsc+ov2JbESlj+2VR5+c/zC6yH20cBAOWnM3hblkbsVhXWG/LJtUKR58PGAYAMjrz4xwwvwUhEyEsw55kM0pzggkUJMrYDhQwf2FUsOl06b0qfUf63E7V1nI0jEEfEserO7geSWWf5t0ZQoiCzPxzX/ILd5dqtuzHiaMRonD/gZ/fUWkr1pWuZzi3agRVJSpEglZHwZuPd0L8jFaIyyF4StPiBkt1Ez+OAVS1vKJAQCzQYiFduJtBlExayioyV6iMjlOdcIlneWcgcAvmBAkjkBI2GlDS1Dtaev89tLJUcFQXxKMYIPjoFMNgINxN2ShSAukd9SnsGKCstDa8iwNJ88Ue0YGBTYLPnUnaBW3TJEdQyFF7SwL2/4FHIbX7thlr9vWC4pPthArmQCUDR8iYldSSI96eNoS1YI6qFEuRwUEh08yuDyHMHIFAHO9IAWWc5vza+BXsMcOt/NTuwhUAVWx3NC+TxAwGQJfXqHtsqZpCRZtdtWtacH/eBCPlhb0GZ5wQvIfxNi/okqGfk26d357jxNBgzJEAo9N9KdF4Wys5FzY78lQTF9pZEm8/Vzmodc1b4DZWYFeX9cCFtlEnqDPvknXSn64W/Yg2vO1siZk/HgY8BMHviiI008UMxpzMNiV9X+7csTjbCrf1GDjv8QmZwTUKLJbDgX4++HGM9TK/+wy4sPSic4Y0E+9+Z1QSFaXCogjUUCBwuI8+YnvRwzrK7HXJG7NzW7FM1FSkYjotv6zEQJ1xOQJvxwSa8c15GQ1tdq0ZhXEAxaUjABjFdUKKsOJp/SwQZScEAXbznWeAPa12CevFrDkVv/JZCr55bg+PCbxXwblxq8dVoHzkxPbRiG2fS9ue8rlp8lL2IubrpPaKAYxlL+sK1uOSxfa2cGF91vzNIb+a9mxplsPnXzxODfS+KVqEHLXY81bjIytq5ex3Fow3+0B9BSNRQygayPqyEPHiLzbabWOv58oKlgbCGBLBtPN6CGyH/i6GwqvGf1de9lYsoYRYwdYJN/PZvfgzcIW97eirlXB1hdSxAKlicjejrqyZP8gGupTi/htm9jB+TzYTcsAUt29djdEIdgGgAb1/zHET1em1DSR1v5qmyiMG/YmwyE6dAoyPhiGrAOPwTgJUahNB+Ok7bbOp5ZAM5/uhFumF+5LsNWAZc50vuo1bbYxpP5RXxK7+eF1xZ+Jj5JgFuZ2tn0gZlLBNjHPMVLEUn3XbsaVgBplBuE04GpMRAk5Hia5CLJqB+x+KHDUrG2e1WeZttv2KLm+WaPdogF+n6CO684Om1JMga3pRF1EvHvUFVmKYtIn/Iwhh8fbfTrZmN02K+RH5ZVnCrfn4uFjOJ5FMuYCvEV6Bwbd5a5nDCY0MhYv6jzg5P+C00ZUXwE2e4Pa+vVy9t4IXatdWSfxVG6hKBu9EeJYEQ2/zcZmjV8sBXcHXczDlo3CD4lqQD4cCN42+Px9hKP9FfvOTgWSBpXOQsns0D2A+wXYdcN4DpCVVQ4Y/ESjwVzfUn3jwsirowYl2XOIeidS6wrQ2KvG3WxfPq2cFNflpe4jDx1fFuY2/r35XpYS5nf4Lderldef1dYhYOb9eN45U8NX6Nn8Vwmewd52fC600upp2R7LoSTfIZQbzK8/rU84pIClvs+UzpzByZqTrrDhwkvJlbMeZVekwBJj83gdzHHrHRjPnapsLBmQ4DnRNHeabr3i7q87aFFYntREeQdqx0/HSocT4bRNYbQXydKus2Q5/cZAL3ptXTTrJpM5Sjf6JTxuN8tPCJ024KGxzvQo1Q2NkMIPR6JhAHhfK4UerhRtwVDTusoEpM6I6izJ1l68b5KULAIujSOGxZCU43Zuggn6ECLIaFo+qe1AA9cnLApoXH4IQu19xXchETsyPqkJJnnXbTFssSkeuCrvdAwyxqUmAwbIIN8tlw+Kf2+CisUB2APqhy79S0Z/2ehJyq2jfHf6zw4ZI+syU8diA3OJQzVJj5dhcTCwEkvdgb692QGk4FWmpoUTRl5FhwfAyNBrQqvDDB1MIP61tWlahBpPLeLbYTlSzrnFPyThtwd+IEZt1mZze7OghuKLqa1hOxb7aFVjwuHYWLoNXbJ8lqdrlM/wNRuZemhwhH7p8bob2x6a+cZ+DEHnVNMCHv9vgks2k2ng6FRB2wsC9pMIU4nU/aMhC+B643RIqvGUkgqyeQcpgAdqDuovLwt4wWYWZAuTbwFm8rL+fzwwyb6a24FrHAfIbcPbZWtSoQl3mOiQi6NogqDUslEYoVwnAL5v/WRjSTO+Bg6AfOA9JeR1OUqTXW1k1w5zngN1aP6CxsHu1wuhgUiWCTwomA5eg989GgRXc85neP97+Gx+jij5QbOyOqh/45VtPeT7sMWCyJW9gDRkNKdT9DuTtySWvic02+Yf79xq6cv5JafuAgl6JGyTOqqmqDuhLDJ/62KQ4Tn0VHGWIKqOoitt31nouueZHnbKMJ9QsJO0Mucsch05MBdPVqwOgrIIYOpqS0/jZnonOh+O/tL0SeOLb2yc04T+TbeCVAlod7r9J9YjRjUq0+GN5ZkQ/jwW1JiwXYnr+qFy5sWoDZIpCXp7kQBOb9CYiXVXCdq/3x5hemj1fJ7Rsn/xopJZXTqych/o9Nydg89lJJwzaNVOA+Uru9UBBejb4+SIn17X2VDb78r93Fqu8dsBEnDMJsqPTz9sJAQTjJauX7Ty+JmDioio0oopJAqORea5pJFfPnaGkseIKUoRD0VmxWKBnGA0baiQgbA5j8CcoIZujZa7hIcyDinYUpQcdPeZto9UGF8qxH2++dL+lblFuO72UKEtq0UHqDF9ByhmtLDZuY5V34UeIQCa+63etBBg2T4+M5Ev99zhcjEh4ILhoRJ+TtzO9qk0n3edvnThT67igBsCTttsgKfINN3TNDqzrvQK+BscSq2WUKMBq3ySe2JWsk6Nw+XNoadjEWO8r8Xm0jP9R+aRoVbsmeYVOjr/uJ4DgXkR9LijIiAKHMeOuBlTNbEWEUVM89mLCvHO7w/+Pt9Z30DhHM0dCCB967rRrMCP+xUCBtpjM0b5dA1AAEp8v3EJtL14JGqvtd4PhKOlTDumVLTj2jz7rHwQj5ZUxa7aFKkvVWBDywGcwUB2jj5CtKdGtFNPYguivVIjBY7dkPDY+rFi7UwhpDKEqUu6F56P1Bbl/YrV7fejDLAZaM///sYd2pJmYb0J9Fm9f8DP1AGLvLWrX8l/Ewp+hFDXo0xDi7zfowpjjnCa4AQZ7ZT2WCGWixypojetpyo+VPbocuFTvlYQIb0VK9vn9cLgDOrSKsyb1q2vJ1t1T1LOJKcbvT+d4GUMlIgbmhqZKEHuIYu3UHShh7R2WcSuB4IXQYEKJlwm8seVVeLu8Yub8DNIgO8BcKas2dnaI6hIEELuS/lZ3uonPX1rGv4QOWA83E6fNHMEM1jLclkknho07NkIx90yjm6A+S6kDaxIVmtS7AuLYyqgsabYMwz2ruiH+HU2hoGQ4qWCywGti0zNrvTXjf4AOdvb+TD2BONVuWIWRZbQoq8hdiI2sOkk0jaFNqM4u5XA1qL/GG8s/ldvoWvkNygIQmTjLZt8gDq9QacZe7VN1JXQ71+cy2Kak3EawyGlzeP2UtAkOSoGlTzzN0rDVUY/kTJtTVOsGQv5A2ENS3O/uduy0d8zFv589h/fSOxnBsYy7X1Yn9r3fu7pN44WP+vUvoGGp9Rty735TqL4uf2bSbELBT60ukh+OQKQiSKC5fw9fpc7adGM46veLRuhdN9Wu8GpCbgcSmJ3YFXdLy2GGH7Y+w/9ZV6+q57FvobuegwJ1iKwxP9PJejLooElW1AIP7LuDfOz/KwfkrGcEhE5f3AdAB5StqoQhULwy7H/UnPrt6+cAFX8d+MLWOcBr9KxICE4VhZWg44JDVaoZU5P0KADb+e7oOMM9LsgcMEFFvtvQ7ULSHYGwy3Lo4rPGhAwsPP5XwPOBBdj9nd9SrfNWcBb+TsYPbGObfh7+BgjKShIy3r1E9wzkD2cQA1Lj6/fgK/zuIrXQiaQEY0YjjCYEBbCNpun/6tYgPN0bcZS2vzZEaiOQvUdvKO0Be+RGX27Sl+iPd7snNia4aZK59B0EaGGdLq/TOncNOjotEDRnPBrkq7De20kfGCp2L/zMf5L/y4VESCwnMqPdSFk/BTuySp9R53xbj+07KKcAy4kj9czHNE2F0ng/YgvjJqaYcz/xQMCZGZ2P+O91TCuV9MVNHjsJMuGYBadoPUT20RW5mCdqItZYe8MZyzhO9ryTUWJsNWEYRlNHREpoEYPHz00BPeiU9JYLInU2pVgsQuuv4MMMAWJ4j3MbGLyZGSnZ7Ln7vCOUBC4jIDleaLfz1keJJ/GZE5RNU0aM/6qFnaL6/QN66/pa/NGi7iNAzHArgckp/8qbnpM2gbsu43FypDwR9eHroMxkEY3F6qP7xZN1t72DkQVaoZc+91+d8TB3VSfxjtIOFLJZs6hr9+L9bLQ9P6803BPwhjqS/HrMybM3b7aJ5pL1QE9vIe3RO/FUMH8I+OXzZRJZUGLoyekj1gaffPgibU+m5WiGeh1y668wF7hTaz8CdZPS/0ADEXv0FWnnCsg6o2PfUxZvv9gHPJPWBEg2KSsBFE/kyaNWyvC2T0PWh8/RbiCyK4AhXXi/xFO/jFcoj8Fy1pAl5fRAN/dFdyLjuvwNSGbrYFl0ivkTpNhjmnxx92iJHcegkvP4bCKOfnMqcd62i/qdLIi7fCSRNZal+namZ0oloseiLt9vCAjj7J2nbexVVK+BxzszlhS+EFX8RLwekhZodPgXCbSEuOoRNm1Vdphn+40G1lCmbPAPb//onX2kaeloqQ+PTOY1YBbVbw1FTcw7mGH0lK7R3TN57hMZFJBqHyIPiZiOWSFoscktQ4fhJV5Wx1+MGfc0vmFEDoGS7srUGGJJjXtdCvnjINhD+khIWApVKGqJt84Z83Eh2MGxtyl5uymQl3vWbZe7h04ai2sAOA7+Cmjtg6AiYEDRF7pS46f/OFbTrDNumb7O2sF8W5oIMlNfSu79/EkNpVrtwjFrMFFAyNwsilW/GNr02eIzRy3yS6lek3NOvZ0yT37HCUNOvjJqzqTUAFg6hqUgVyjp41UBN1rLR7GZQl2gyhjNWCqeSb0lgL3btkMIzwokoOJlMO1KBX7UwXm3t0tKvNXPDlAXepvk8B7uH2ON9hhAbNfTdNkR84RjQ1sZ7g5QO62kKF4cFfxFK7DDSmpW732fvCKxFowDi2GGSn6E8Ay5uO2kPdXmwsX9EdwjjXEpsFxYWTOAtyjJIRGfpvMsroskNd8CaQT6yaG2pR/1ZE4pLiIICpMax8dHbukpK7WWE9cDvFz96BC1dsx14vbUfwkm0sKcSaWllVn5Elw9EP8FTVcEr/NejFQbYh5auG2JrpheCKuk+YvM8QvpC2vPASnG6ww7W1oiZFtqGZBo8I5kh7DYadOeE3sRXxLr0YDNusReEiWP3eWskoSMCBX7xSVtg9hfdzSDd3Y7EeiI/vEx8nllOSI0lVVu01CQAnVK1z7EtUEe7bFRY/bIinm/rPA184220rHlatQaNVo8MOmo4fK/SMJOPHNj8xoy7dA==,iv:JvoC84+dJ+sKdDDNvzIRWJUKHftgW4hhT6fiJQXR4rs=,tag:wrFQF7ZqG0us3E98i/gkyA==,type:str]
 sops:
     kms: []
     gcp_kms: []
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2022-10-28T22:53:26Z"
-    mac: ENC[AES256_GCM,data:fNcL/hQUsjSDULz9hOrr8268wNfRzARvuD+QQoUjhj5oDN3/zq800FjHrMBygTr962ueYdpfF7rW3exJqsf0TRVxlrSfvIX0U6Hwgpx7Ts6vMAmJeYdr28EuvbITuq9k14jhJrWmcqHOplJFSE1SoBedxF9LLor5gsc8WZDuBm8=,iv:d3roSZ//iosFzLj6dDWQl35Ya0Vlu2M9bAsWVWorBjI=,tag:8sX4R0WRoifYMJXiamSm9w==,type:str]
+    lastmodified: "2022-11-05T18:45:55Z"
+    mac: ENC[AES256_GCM,data:xPCfjqVkewEqrUjHroXa9RGHITntVj2uGPaRZfj0lqTUPFG6GQDn3Yq6L6cV3EPOYQ4OedJlaVXy05OHkzZwjYEbBQVGQ0aH/ZOP7X301eebBX5MvHLFU4mcnjMITWGH/E7SXz3pPF75s9eM/onx374PcQt6zevbBF+Jp0Fz71I=,iv:84JL69nF3ougygMAVFOoTaCn37thvm4lF6HYdgTiftg=,tag:ATQ18acehgUAE/dX+vYugQ==,type:str]
     pgp:
         - created_at: "2022-10-12T00:46:51Z"
           enc: |

From 7a2b862235db7964138dae2f31494742a09ed5f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?=
 <tristan.maat@codethink.co.uk>
Date: Sat, 5 Nov 2022 22:27:31 +0000
Subject: [PATCH 077/212] keys: Remove obsolete key file

---
 keys/external.yaml | 52 ----------------------------------------------
 1 file changed, 52 deletions(-)
 delete mode 100644 keys/external.yaml

diff --git a/keys/external.yaml b/keys/external.yaml
deleted file mode 100644
index c51d957..0000000
--- a/keys/external.yaml
+++ /dev/null
@@ -1,52 +0,0 @@
-steam: ENC[AES256_GCM,data:Jhk91uP3Ixo7H4I9kXEWeA==,iv:s8BcwGNF1vG8KI41FmQXOBbqZl8SnMZ9+YP6GKwHdtY=,tag:dW462jNJCtG4HWrkeQTUzw==,type:str]
-sops:
-    kms: []
-    gcp_kms: []
-    azure_kv: []
-    hc_vault: []
-    age: []
-    lastmodified: "2022-04-23T07:07:21Z"
-    mac: ENC[AES256_GCM,data:E9z+h2kejAobo3wIRBQFGyMfMHoeVREE+pEF9XoVZF8cQM4xC4tHub+eENsBIDeWoIcPtugLE9Xwzn9odyg92Vri/SzcaxrEXzsAcvFj6Ox2cN27h17OrkQBMKeA/tnMVg+uJxQesWZbrfcMsmd99X1W1RH5SMUwNrqjCsNxZ7s=,iv:pfi/EXgacNapdVlKP0UEMKdxi7s4YicfFcSopvwOrNA=,tag:RmMPwBYFZx2M5FJCVyhcLg==,type:str]
-    pgp:
-        - created_at: "2022-04-23T07:07:08Z"
-          enc: |
-            -----BEGIN PGP MESSAGE-----
-
-            hQIMAzWu0p84AOApAQ/8DeQLvWBjQn3mNfmiPyH0NNj0d70FKbm546jFjBuVHW9h
-            P3KWVJF8pWdg17W5Hlu8xDPCCYmX5Rew3JznbEpyxIMUAUPS+HpwEWXvpKUMNhIj
-            VDcQ5cVkfiOc81gRKXLiWNmBP2lRKrjjmFBEbwZgHxW2Y9yzmzqsR97VWrBhkz9r
-            Rsif8Mi29LAbpG0lgVZSji7pzs/4EbclSQsfv6JSJMoA0bD3OdtyAmJh4dfUV31i
-            kzkOJ8WIAwYpvKXI4Jf3DuUS7njzdw4SRCgf5nuC8Ml1Kb4IvCwTsPEOaYRhCZIX
-            jUTmQ4DwiIZ+618Wzi6SHgdH1QZaS5e71n0rxPxsYY6UbCyDhrGNcXgn/p0DHP04
-            p+Hscl75IqJiMzlAnQobx111vw1f3oGgTuWYS78Tccpy/QgMtVf99CeVwp4fVkeU
-            iPGr5oy5KO3WF3EWvuK/A/eoiK208YRMcL+0hrFDuhTB7qnyCRBjTv+4SJdY3FiC
-            KA/syZ/+DioUVyEXNn8cttk0U9Wf5zub7s/9Ei7MQVVUgCvyZZDHFE+50d5UeVRm
-            WW5T38D3G+v6py8gkC4/noKndr6SzRgPBAVW/Ba9CZZtEulhA39U9M4Q9cCSyLCM
-            nAiu0ikOiDif4w+1fxeEA+BXp7uBbW9vz09jetfDkp+i4hvt41a9dwJpTmxWm57S
-            XgFQDuO+HdFs44Yw1gyJQKLK3YejSyoKIo5pN36yMGuYPw9B75Cx+MWJJihL5IHl
-            gTqNPiD3cIyFw9U+FYfvqdQz9Vo/dD8gF0G5Y5MVH0E9xNsSFuSWoA9H2Zl+Ops=
-            =W5PZ
-            -----END PGP MESSAGE-----
-          fp: 535B61015823443941C744DD12264F6BBDFABA89
-        - created_at: "2022-04-23T07:07:08Z"
-          enc: |
-            -----BEGIN PGP MESSAGE-----
-
-            hQIMA9ahl2ynTH87ARAAwKoe5UHRlt86d47oCSvXVV0JvRdw6K5VKDIyZr5FEAZD
-            VHDvZb7a0qlKuJsKiq5+3hZPkw9W9DLtpacxQdEoTUDQVAfVAi1pIKaJIYP7pSC3
-            LbcqNXucqJoKLKXHE0zCPAJdbTYOo804Z6iLRJRYwuLHfE17lVPMoJD9OjwZn1LS
-            ksJnki68YqQcFocRuUF/pq+bcd0ceV7YQiBIdO/89YyVPgviORXzlRZ5+hTpFjqd
-            rYFzgNBkHVRHUso8S9YNiFsU8dKVXBDS6LiykcKe9C6kEYDCe24VVHyrlj2s3isH
-            68PefnfQY5ZIBSDm2uwGmym1pSwhR015Ely/gqRx+T4qfCcAwva9ZPusXHzHu2+z
-            vwO83yeBXFbs4YFdHhh9GNbOfbBKCdPU0FAqQCuU0P7iVrCfjtTXdg622hn7x2YW
-            YwH5nlcm14/U39jOzWNketmyAiaOJ32ko3Ec63ELkGCb8+LR0eCPDNUNCQcnKGaU
-            yrTYnqUG6ODxdkhvq1JCsPKlZ/0pqiSQKBE1dGZBrcshZZ6SvdhO6hSimg3m+Mqn
-            wh5pcx/P5k3VXPovTRkRAU/U6RdYKs+qH1tXCBSMwjz4EU9VCYZbqLb1Bp/NfsPa
-            0CL50HA617ID0ofxOL8eT49xQJZZFFAArOMZmRGgsKrPAEYijnQ/593nci4DdozS
-            UAFrki95hH3EFygU3KkVdpULaOwc/0SWIPLZgmpFq2H5bKOqi9TL0IV3G00qEf5G
-            bOFb1q7pCAWMe5b6JH7MQRmSWwaoE4qhtmOkjHMOuqhA
-            =hTbV
-            -----END PGP MESSAGE-----
-          fp: 8a3737d48f1035fe6c3a0a8fd6a1976ca74c7f3b
-    unencrypted_suffix: _unencrypted
-    version: 3.7.2

From 19576ffb1e91d37ea8a3e79ddcbd88215ae7dd90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 11 Jan 2023 01:58:00 +0000
Subject: [PATCH 078/212] matrix-conduit: Stop using the version from unstable

---
 flake.lock      | 17 -----------------
 flake.nix       |  4 +---
 lib/default.nix | 10 ----------
 3 files changed, 1 insertion(+), 30 deletions(-)

diff --git a/flake.lock b/flake.lock
index 8507c27..8d59020 100644
--- a/flake.lock
+++ b/flake.lock
@@ -289,22 +289,6 @@
         "type": "github"
       }
     },
-    "nixpkgs-unstable": {
-      "locked": {
-        "lastModified": 1667610399,
-        "narHash": "sha256-XZd0f4ZWAY0QOoUSdiNWj/eFiKb4B9CJPtl9uO9SYY4=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "1dd8696f96db47156e1424a49578fe7dd4ce99a4",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "nixpkgs-unstable",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
     "nixpkgs_2": {
       "locked": {
         "lastModified": 1667564121,
@@ -406,7 +390,6 @@
       "inputs": {
         "deploy-rs": "deploy-rs",
         "nixpkgs": "nixpkgs_2",
-        "nixpkgs-unstable": "nixpkgs-unstable",
         "nvfetcher": "nvfetcher",
         "sops-nix": "sops-nix",
         "tlaternet-webserver": "tlaternet-webserver"
diff --git a/flake.nix b/flake.nix
index 04aa990..7a5daf9 100644
--- a/flake.nix
+++ b/flake.nix
@@ -3,7 +3,6 @@
 
   inputs = {
     nixpkgs.url = "github:nixos/nixpkgs/nixos-22.05";
-    nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
     deploy-rs.url = "github:serokell/deploy-rs";
     sops-nix = {
       url = "github:Mic92/sops-nix";
@@ -22,7 +21,6 @@
   outputs = {
     self,
     nixpkgs,
-    nixpkgs-unstable,
     sops-nix,
     nvfetcher,
     deploy-rs,
@@ -66,7 +64,7 @@
     # Helper functions #
     ####################
     lib = import ./lib {
-      inherit nixpkgs nixpkgs-unstable sops-nix tlaternet-webserver;
+      inherit nixpkgs sops-nix tlaternet-webserver;
       lib = nixpkgs.lib;
     };
 
diff --git a/lib/default.nix b/lib/default.nix
index 5cd7382..5f6b68f 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -1,7 +1,6 @@
 {
   lib,
   nixpkgs,
-  nixpkgs-unstable,
   sops-nix,
   tlaternet-webserver,
 }: let
@@ -25,15 +24,6 @@ in {
           sops-nix.nixosModules.sops
           tlaternet-webserver.nixosModules.default
           (import ../configuration)
-          {
-            nixpkgs.overlays = [
-              (self: super: {
-                matrix-conduit = nixpkgs-unstable.legacyPackages.${system}.matrix-conduit.override {
-                  inherit (self) stdenv lib fetchFromGitLab rustPlatform pkg-config rocksdb;
-                };
-              })
-            ];
-          }
         ]
         ++ extraModules;
     };

From 411e075ef152e7d319800ccd81020641957e6c53 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 11 Jan 2023 02:11:01 +0000
Subject: [PATCH 079/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/a9eedea7232f5d00f0aca7267efb69a54da1b8a1' (2023-01-03)
  → 'github:nixos/nixpkgs/54644f409ab471e87014bb305eac8c50190bcf48' (2023-01-10)
• Updated input 'nvfetcher':
    'github:berberman/nvfetcher/294826951113dcd3aa9abbcacfb1aa5b95a19116' (2022-11-05)
  → 'github:berberman/nvfetcher/0a9ac5fd07b52467d81163b1f8c94c12e5c9aff9' (2023-01-06)
• Updated input 'nvfetcher/flake-compat':
    'github:edolstra/flake-compat/b4a34015c698c7793d592d66adbab377907a2be8' (2022-04-19)
  → 'github:edolstra/flake-compat/009399224d5e398d03b22badca40a37ac85412a1' (2022-11-17)
• Updated input 'nvfetcher/flake-utils':
    'github:numtide/flake-utils/6ee9ebb6b1ee695d2cacc4faa053a7b9baa76817' (2022-10-29)
  → 'github:numtide/flake-utils/5aed5285a952e0b949eb3ba02c12fa4fcfef535f' (2022-11-02)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/b35586cc5abacd4eba9ead138b53e2a60920f781' (2023-01-01)
  → 'github:Mic92/sops-nix/2253120d2a6147e57bafb5c689e086221df8032f' (2023-01-08)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/feda52be1d59f13b9aa02f064b4f14784b9a06c8' (2022-12-31)
  → 'github:NixOS/nixpkgs/9f11a2df77cb945c115ae2a65f53f38121597d73' (2023-01-07)
---
 flake.lock | 211 +++++++++++++++++++++++++++++++++++++----------------
 flake.nix  |   4 +-
 2 files changed, 152 insertions(+), 63 deletions(-)

diff --git a/flake.lock b/flake.lock
index 8d59020..e156a33 100644
--- a/flake.lock
+++ b/flake.lock
@@ -24,14 +24,31 @@
         "type": "github"
       }
     },
+    "all-cabal-json": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1665552503,
+        "narHash": "sha256-r14RmRSwzv5c+bWKUDaze6pXM7nOsiz1H8nvFHJvufc=",
+        "owner": "nix-community",
+        "repo": "all-cabal-json",
+        "rev": "d7c0434eebffb305071404edcf9d5cd99703878e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "ref": "hackage",
+        "repo": "all-cabal-json",
+        "type": "github"
+      }
+    },
     "crane": {
       "flake": false,
       "locked": {
-        "lastModified": 1661875961,
-        "narHash": "sha256-f1h/2c6Teeu1ofAHWzrS8TwBPcnN+EEu+z1sRVmMQTk=",
+        "lastModified": 1670900067,
+        "narHash": "sha256-VXVa+KBfukhmWizaiGiHRVX/fuk66P8dgSFfkVN4/MY=",
         "owner": "ipetkov",
         "repo": "crane",
-        "rev": "d9f394e4e20e97c2a60c3ad82c2b6ef99be19e24",
+        "rev": "59b31b41a589c0a65e4a1f86b0e5eac68081468b",
         "type": "github"
       },
       "original": {
@@ -47,11 +64,11 @@
         "utils": "utils"
       },
       "locked": {
-        "lastModified": 1659725433,
-        "narHash": "sha256-1ZxuK67TL29YLw88vQ18Y2Y6iYg8Jb7I6/HVzmNB6nM=",
+        "lastModified": 1672327199,
+        "narHash": "sha256-pFlngSHXKBhAmbaKZ4FYtu57LLunG+vWdL7a5vw1RvQ=",
         "owner": "serokell",
         "repo": "deploy-rs",
-        "rev": "41f15759dd8b638e7b4f299730d94d5aa46ab7eb",
+        "rev": "a5619f5660a00f58c2b7c16d89058e92327ac9b8",
         "type": "github"
       },
       "original": {
@@ -63,11 +80,11 @@
     "devshell": {
       "flake": false,
       "locked": {
-        "lastModified": 1653917170,
-        "narHash": "sha256-FyxOnEE/V4PNEcMU62ikY4FfYPo349MOhMM97HS0XEo=",
+        "lastModified": 1663445644,
+        "narHash": "sha256-+xVlcK60x7VY1vRJbNUEAHi17ZuoQxAIH4S4iUFUGBA=",
         "owner": "numtide",
         "repo": "devshell",
-        "rev": "fc7a3e3adde9bbcab68af6d1e3c6eb738e296a92",
+        "rev": "e3dc3e21594fe07bdb24bdf1c8657acaa4cb8f66",
         "type": "github"
       },
       "original": {
@@ -79,21 +96,25 @@
     "dream2nix": {
       "inputs": {
         "alejandra": "alejandra",
+        "all-cabal-json": "all-cabal-json",
         "crane": "crane",
         "devshell": "devshell",
+        "flake-parts": "flake-parts",
         "flake-utils-pre-commit": "flake-utils-pre-commit",
+        "ghc-utils": "ghc-utils",
         "gomod2nix": "gomod2nix",
         "mach-nix": "mach-nix",
+        "nix-pypi-fetcher": "nix-pypi-fetcher",
         "nixpkgs": "nixpkgs_3",
         "poetry2nix": "poetry2nix",
         "pre-commit-hooks": "pre-commit-hooks"
       },
       "locked": {
-        "lastModified": 1663323895,
-        "narHash": "sha256-ZmI9C8HNVz2w3OnB79WR/LIgVEY8tDnR8tEPi3hMiJk=",
+        "lastModified": 1672661134,
+        "narHash": "sha256-WqBUyKeiv+jI11ug+qP0OnZ4nngK6eBRVTGHgdzEGvc=",
         "owner": "nix-community",
         "repo": "dream2nix",
-        "rev": "25be741ec92c77b8308ca6a7ab89593fe37b6542",
+        "rev": "9f6911c78dcb0832f7fcc955e847db1a5a9ce29a",
         "type": "github"
       },
       "original": {
@@ -135,11 +156,11 @@
         "rust-analyzer-src": "rust-analyzer-src_2"
       },
       "locked": {
-        "lastModified": 1663396212,
-        "narHash": "sha256-dlK10QPTDYNpJ/vl2QPKOTrqEbQwAR/v2f4+xsetTkw=",
+        "lastModified": 1672813381,
+        "narHash": "sha256-PKt6orRiFO19KFKnOhzK26hbFLtimlRNE2dGwrTEhII=",
         "owner": "nix-community",
         "repo": "fenix",
-        "rev": "263cd7f991c07a9592a6e825bfc37b23b00eb244",
+        "rev": "eb6583fcd626051c4d284f2fb51cd2659a43e7f6",
         "type": "github"
       },
       "original": {
@@ -151,11 +172,11 @@
     "flake-compat": {
       "flake": false,
       "locked": {
-        "lastModified": 1648199409,
-        "narHash": "sha256-JwPKdC2PoVBkG6E+eWw3j6BMR6sL3COpYWfif7RVb8Y=",
+        "lastModified": 1668681692,
+        "narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=",
         "owner": "edolstra",
         "repo": "flake-compat",
-        "rev": "64a525ee38886ab9028e6f61790de0832aa3ef03",
+        "rev": "009399224d5e398d03b22badca40a37ac85412a1",
         "type": "github"
       },
       "original": {
@@ -167,11 +188,11 @@
     "flake-compat_2": {
       "flake": false,
       "locked": {
-        "lastModified": 1650374568,
-        "narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=",
+        "lastModified": 1668681692,
+        "narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=",
         "owner": "edolstra",
         "repo": "flake-compat",
-        "rev": "b4a34015c698c7793d592d66adbab377907a2be8",
+        "rev": "009399224d5e398d03b22badca40a37ac85412a1",
         "type": "github"
       },
       "original": {
@@ -180,13 +201,31 @@
         "type": "github"
       }
     },
+    "flake-parts": {
+      "inputs": {
+        "nixpkgs-lib": "nixpkgs-lib"
+      },
+      "locked": {
+        "lastModified": 1668450977,
+        "narHash": "sha256-cfLhMhnvXn6x1vPm+Jow3RiFAUSCw/l1utktCw5rVA4=",
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "rev": "d591857e9d7dd9ddbfba0ea02b43b927c3c0f1fa",
+        "type": "github"
+      },
+      "original": {
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "type": "github"
+      }
+    },
     "flake-utils": {
       "locked": {
-        "lastModified": 1667077288,
-        "narHash": "sha256-bdC8sFNDpT0HK74u9fUkpbf1MEzVYJ+ka7NXCdgBoaA=",
+        "lastModified": 1667395993,
+        "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "6ee9ebb6b1ee695d2cacc4faa053a7b9baa76817",
+        "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
         "type": "github"
       },
       "original": {
@@ -226,6 +265,22 @@
         "type": "github"
       }
     },
+    "ghc-utils": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1662774800,
+        "narHash": "sha256-1Rd2eohGUw/s1tfvkepeYpg8kCEXiIot0RijapUjAkE=",
+        "ref": "refs/heads/master",
+        "rev": "bb3a2d3dc52ff0253fb9c2812bd7aa2da03e0fea",
+        "revCount": 1072,
+        "type": "git",
+        "url": "https://gitlab.haskell.org/bgamari/ghc-utils"
+      },
+      "original": {
+        "type": "git",
+        "url": "https://gitlab.haskell.org/bgamari/ghc-utils"
+      }
+    },
     "gomod2nix": {
       "flake": false,
       "locked": {
@@ -257,13 +312,29 @@
         "type": "indirect"
       }
     },
+    "nix-pypi-fetcher": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1669065297,
+        "narHash": "sha256-UStjXjNIuIm7SzMOWvuYWIHBkPUKQ8Id63BMJjnIDoA=",
+        "owner": "DavHau",
+        "repo": "nix-pypi-fetcher",
+        "rev": "a9885ac6a091576b5195d547ac743d45a2a615ac",
+        "type": "github"
+      },
+      "original": {
+        "owner": "DavHau",
+        "repo": "nix-pypi-fetcher",
+        "type": "github"
+      }
+    },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1648219316,
-        "narHash": "sha256-Ctij+dOi0ZZIfX5eMhgwugfvB+WZSrvVNAyAuANOsnQ=",
+        "lastModified": 1671417167,
+        "narHash": "sha256-JkHam6WQOwZN1t2C2sbp1TqMv3TVRjzrdoejqfefwrM=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "30d3d79b7d3607d56546dd2a6b49e156ba0ec634",
+        "rev": "bb31220cca6d044baa6dc2715b07497a2a7c4bc7",
         "type": "github"
       },
       "original": {
@@ -273,45 +344,63 @@
         "type": "github"
       }
     },
-    "nixpkgs-22_05": {
+    "nixpkgs-lib": {
       "locked": {
-        "lastModified": 1667091951,
-        "narHash": "sha256-62sz0fn06Nq8OaeBYrYSR3Y6hUcp8/PC4dJ7HeGaOhU=",
+        "dir": "lib",
+        "lastModified": 1665349835,
+        "narHash": "sha256-UK4urM3iN80UXQ7EaOappDzcisYIuEURFRoGQ/yPkug=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "6440d13df2327d2db13d3b17e419784020b71d22",
+        "rev": "34c5293a71ffdb2fe054eb5288adc1882c1eb0b1",
+        "type": "github"
+      },
+      "original": {
+        "dir": "lib",
+        "owner": "NixOS",
+        "ref": "nixos-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs-stable": {
+      "locked": {
+        "lastModified": 1673100377,
+        "narHash": "sha256-mT76pTd0YFxT6CwtPhDgHJhuIgLY+ZLSMiQpBufwMG4=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "9f11a2df77cb945c115ae2a65f53f38121597d73",
         "type": "github"
       },
       "original": {
         "owner": "NixOS",
-        "ref": "release-22.05",
+        "ref": "release-22.11",
         "repo": "nixpkgs",
         "type": "github"
       }
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1667564121,
-        "narHash": "sha256-DlR65WyEW78cBmnOhxDzfvNQ9euJEGctSl77olqEaLg=",
+        "lastModified": 1673345971,
+        "narHash": "sha256-4DfFcKLRfVUTyuGrGNNmw37IeIZSoku9tgTVmu/iD98=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "1404483f4531560aad73bdebae4096881c910ac0",
+        "rev": "54644f409ab471e87014bb305eac8c50190bcf48",
         "type": "github"
       },
       "original": {
         "owner": "nixos",
-        "ref": "nixos-22.05",
+        "ref": "nixos-22.11",
         "repo": "nixpkgs",
         "type": "github"
       }
     },
     "nixpkgs_3": {
       "locked": {
-        "lastModified": 1657638268,
-        "narHash": "sha256-blBNtQSslAFkg0Gym9fWNJk+bPxGSZib4SOcPrmTPi4=",
+        "lastModified": 1665580254,
+        "narHash": "sha256-hO61XPkp1Hphl4HGNzj1VvDH5URt7LI6LaY/385Eul4=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "d80993b5f885515254746ba6d1917276ee386149",
+        "rev": "f634d427b0224a5f531ea5aa10c3960ba6ec5f0f",
         "type": "github"
       },
       "original": {
@@ -329,11 +418,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1667620329,
-        "narHash": "sha256-v1Zk7rtEbAGpevBGPZvZBKpwbmw4I+uVwxvd+pBlp3o=",
+        "lastModified": 1672979485,
+        "narHash": "sha256-LrY0K1yya3nvRlGDc98wm68ozVj7E6a1EXXEr7eHp8E=",
         "owner": "berberman",
         "repo": "nvfetcher",
-        "rev": "294826951113dcd3aa9abbcacfb1aa5b95a19116",
+        "rev": "0a9ac5fd07b52467d81163b1f8c94c12e5c9aff9",
         "type": "github"
       },
       "original": {
@@ -345,16 +434,16 @@
     "poetry2nix": {
       "flake": false,
       "locked": {
-        "lastModified": 1632969109,
-        "narHash": "sha256-jPDclkkiAy5m2gGLBlKgH+lQtbF7tL4XxBrbSzw+Ioc=",
+        "lastModified": 1666918719,
+        "narHash": "sha256-BkK42fjAku+2WgCOv2/1NrPa754eQPV7gPBmoKQBWlc=",
         "owner": "nix-community",
         "repo": "poetry2nix",
-        "rev": "aee8f04296c39d88155e05d25cfc59dfdd41cc77",
+        "rev": "289efb187123656a116b915206e66852f038720e",
         "type": "github"
       },
       "original": {
         "owner": "nix-community",
-        "ref": "1.21.0",
+        "ref": "1.36.0",
         "repo": "poetry2nix",
         "type": "github"
       }
@@ -415,11 +504,11 @@
     "rust-analyzer-src_2": {
       "flake": false,
       "locked": {
-        "lastModified": 1662896065,
-        "narHash": "sha256-1LkSsXzI1JTAmP/GMTz4fTJd8y/tw8R79l96q+h7mu8=",
+        "lastModified": 1672757238,
+        "narHash": "sha256-BK1njXsjprMT0f+1aQYmZ/ueN9D3Y3wrz9gw4UvieRQ=",
         "owner": "rust-lang",
         "repo": "rust-analyzer",
-        "rev": "2e9f1204ca01c3e20898d4a67c8b84899d394a88",
+        "rev": "a97c71f92d574cb5104e3e1246eb9038d1a214a2",
         "type": "github"
       },
       "original": {
@@ -434,14 +523,14 @@
         "nixpkgs": [
           "nixpkgs"
         ],
-        "nixpkgs-22_05": "nixpkgs-22_05"
+        "nixpkgs-stable": "nixpkgs-stable"
       },
       "locked": {
-        "lastModified": 1667427533,
-        "narHash": "sha256-MsgTnQEi1g7f8anlW5klHW2pJgam4CLbJaYyBw2ed58=",
+        "lastModified": 1673147300,
+        "narHash": "sha256-gR9OEfTzWfL6vG0qkbn1TlBAOlg4LuW8xK/u0V41Ihc=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "486b4455da16272c1ed31bc82adcdbe7af829465",
+        "rev": "2253120d2a6147e57bafb5c689e086221df8032f",
         "type": "github"
       },
       "original": {
@@ -459,11 +548,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1665746303,
-        "narHash": "sha256-lDVy7aBsAaO5TyeoZS4wL6qcBNuU1bQCcHPJxiEKtao=",
-        "ref": "master",
-        "rev": "5d037f9122e68aaa5db62d04810bf0c5e1e4325e",
-        "revCount": 49,
+        "lastModified": 1672884793,
+        "narHash": "sha256-biUbdKq8OaRQm25poaRJalrRq+M+/TrNr7J6rI65lNI=",
+        "ref": "refs/heads/master",
+        "rev": "b2894e4fefbdc1c9964ab47c931497a417562d8a",
+        "revCount": 53,
         "type": "git",
         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git"
       },
@@ -474,11 +563,11 @@
     },
     "utils": {
       "locked": {
-        "lastModified": 1648297722,
-        "narHash": "sha256-W+qlPsiZd8F3XkzXOzAoR+mpFqzm3ekQkJNa+PIh1BQ=",
+        "lastModified": 1667395993,
+        "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "0f8662f1319ad6abf89b3380dd2722369fc51ade",
+        "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
         "type": "github"
       },
       "original": {
diff --git a/flake.nix b/flake.nix
index 7a5daf9..de2ed54 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,7 +2,7 @@
   description = "tlater.net host configuration";
 
   inputs = {
-    nixpkgs.url = "github:nixos/nixpkgs/nixos-22.05";
+    nixpkgs.url = "github:nixos/nixpkgs/nixos-22.11";
     deploy-rs.url = "github:serokell/deploy-rs";
     sops-nix = {
       url = "github:Mic92/sops-nix";
@@ -97,7 +97,7 @@
         '';
 
       update-nextcloud-apps = let
-        nvfetcher-bin = "${nvfetcher.defaultPackage.${system}}/bin/nvfetcher";
+        nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher";
       in
         writeShellScript "update-nextcloud-apps" ''
           cd "$(git rev-parse --show-toplevel)/pkgs"

From b798efb2c05a4c30bcba0e7ad2fe523ccd76d017 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 11 Jan 2023 01:57:24 +0000
Subject: [PATCH 080/212] nextcloud: Update the service and apps for 22.11

---
 configuration/services/nextcloud.nix   | 10 +----
 pkgs/_sources_nextcloud/generated.json | 59 ++++++++++++--------------
 pkgs/_sources_nextcloud/generated.nix  | 52 +++++++++++------------
 pkgs/default.nix                       |  4 +-
 pkgs/mkNextcloudApp.nix                | 15 +++----
 pkgs/nextcloud-apps.toml               | 27 ++++--------
 6 files changed, 70 insertions(+), 97 deletions(-)

diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index fddddde..c25cfb2 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -3,14 +3,14 @@
   config,
   ...
 }: let
-  inherit (pkgs) fetchNextcloudApp;
-  nextcloud = pkgs.nextcloud24;
+  nextcloud = pkgs.nextcloud25;
   hostName = "nextcloud.${config.services.nginx.domain}";
 in {
   services.nextcloud = {
     inherit hostName;
 
     package = nextcloud;
+    enableBrokenCiphersForSSE = false;
     enable = true;
     maxUploadSize = "2G";
     https = true;
@@ -28,12 +28,6 @@ in {
     };
 
     extraApps = {
-      # TODO(tlater): Seems like this won't work anymore from
-      # Nextcloud 25 onwards.
-      #
-      # Adopt whatever upstream does with this:
-      # https://github.com/nextcloud/server/issues/4917
-      inherit (pkgs.local) apporder;
       inherit (pkgs.local) bookmarks calendar contacts cookbook news notes;
     };
 
diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index c4a4b55..7752f5e 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -7,9 +7,8 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "name": null,
-            "sha256": "sha256-p3VWxTYDCO2NePq6oLM8tBVqYkvoB7itqxp7IZwGDnE=",
-            "type": "url",
+            "sha256": "1nx1vdwlqyy3x5vw2h2xx51hmv7gsp8mam1fj813yc3655js9m96",
+            "type": "tarball",
             "url": "https://github.com/juliushaertl/apporder/releases/download/v0.15.0/apporder.tar.gz"
         },
         "version": "v0.15.0"
@@ -22,12 +21,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "name": null,
-            "sha256": "sha256-URqtzaCx8FEZHCDP1wSBUFNs+x50jesRtWi+xOU1oXM=",
-            "type": "url",
-            "url": "https://github.com/nextcloud/bookmarks/releases/download/v11.0.4/bookmarks-11.0.4.tar.gz"
+            "sha256": "0dkfjafbynkrymsq183sad7zynqr2qls0cld73nvzn3smnvdl2xx",
+            "type": "tarball",
+            "url": "https://github.com/nextcloud/bookmarks/releases/download/v12.0.0/bookmarks-12.0.0.tar.gz"
         },
-        "version": "11.0.4"
+        "version": "12.0.0"
     },
     "calendar": {
         "cargoLocks": null,
@@ -37,12 +35,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "name": null,
-            "sha256": "sha256-+LRGl9h40AQdWN9SW+NqGwTafAGwV07Af8nVs3pUCm0=",
-            "type": "url",
-            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v3.5.0/calendar-v3.5.0.tar.gz"
+            "sha256": "06p92w2idml5g3zc0xhp25rpgkxm3d5pmxpx7dmqlqvw8r6z07an",
+            "type": "tarball",
+            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.2.0/calendar-v4.2.0.tar.gz"
         },
-        "version": "v3.5.0"
+        "version": "v4.2.0"
     },
     "contacts": {
         "cargoLocks": null,
@@ -52,12 +49,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "name": null,
-            "sha256": "sha256-GTiyZsUHBXPgQ17DHAihmt2W/ZnAjDwfgwnujkRwk6A=",
-            "type": "url",
-            "url": "https://github.com/nextcloud-releases/contacts/releases/download/v4.2.2/contacts-v4.2.2.tar.gz"
+            "sha256": "097a71if6kkc7nphfc8b6llqlsskjwp1vg83134hzgfscvllvaj8",
+            "type": "tarball",
+            "url": "https://github.com/nextcloud-releases/contacts/releases/download/v5.0.2/contacts-v5.0.2.tar.gz"
         },
-        "version": "v4.2.2"
+        "version": "v5.0.2"
     },
     "cookbook": {
         "cargoLocks": null,
@@ -67,12 +63,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "name": null,
-            "sha256": "sha256-3lCqvmaMsgrFD5PzyHIcwxxGeC+qOMTGxbOi7nPFL6I=",
-            "type": "url",
-            "url": "https://github.com/nextcloud/cookbook/releases/download/v0.9.17/Cookbook-0.9.17.tar.gz"
+            "sha256": "1xpy060yi7pl8i91xjv2jj18yvsmjzwmv91y7i686qq8n2kc1fcg",
+            "type": "tarball",
+            "url": "https://github.com/nextcloud/cookbook/releases/download/v0.10.1/Cookbook-0.10.1.tar.gz"
         },
-        "version": "0.9.17"
+        "version": "0.10.1"
     },
     "news": {
         "cargoLocks": null,
@@ -82,12 +77,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "name": null,
-            "sha256": "sha256-lVF4H9v7bSw8137lfq4PsVg8e1TpcgvJVQU/UVQfSoY=",
-            "type": "url",
-            "url": "https://github.com/nextcloud/news/releases/download/19.0.0/news.tar.gz"
+            "sha256": "0pnriarr2iqci2v2hn6vpvszf4m4pkcxsd2i13bp7n1zqkg6swd7",
+            "type": "tarball",
+            "url": "https://github.com/nextcloud/news/releases/download/20.0.0/news.tar.gz"
         },
-        "version": "19.0.0"
+        "version": "20.0.0"
     },
     "notes": {
         "cargoLocks": null,
@@ -97,11 +91,10 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "name": null,
-            "sha256": "sha256-rd3uVkVtARX4enRAWm1ivV468lboYZnYe7/zsqaHYpk=",
-            "type": "url",
-            "url": "https://github.com/nextcloud/notes/releases/download/v4.5.1/notes.tar.gz"
+            "sha256": "1jcgv3awr45jq3n3qv851qlpbdl2plixba0iq2s54dmhciypdckl",
+            "type": "tarball",
+            "url": "https://github.com/nextcloud/notes/releases/download/v4.6.0/notes.tar.gz"
         },
-        "version": "v4.5.1"
+        "version": "v4.6.0"
     }
 }
\ No newline at end of file
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index 324306d..f3a0521 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -4,57 +4,57 @@
   apporder = {
     pname = "apporder";
     version = "v0.15.0";
-    src = fetchurl {
+    src = fetchTarball {
       url = "https://github.com/juliushaertl/apporder/releases/download/v0.15.0/apporder.tar.gz";
-      sha256 = "sha256-p3VWxTYDCO2NePq6oLM8tBVqYkvoB7itqxp7IZwGDnE=";
+      sha256 = "1nx1vdwlqyy3x5vw2h2xx51hmv7gsp8mam1fj813yc3655js9m96";
     };
   };
   bookmarks = {
     pname = "bookmarks";
-    version = "11.0.4";
-    src = fetchurl {
-      url = "https://github.com/nextcloud/bookmarks/releases/download/v11.0.4/bookmarks-11.0.4.tar.gz";
-      sha256 = "sha256-URqtzaCx8FEZHCDP1wSBUFNs+x50jesRtWi+xOU1oXM=";
+    version = "12.0.0";
+    src = fetchTarball {
+      url = "https://github.com/nextcloud/bookmarks/releases/download/v12.0.0/bookmarks-12.0.0.tar.gz";
+      sha256 = "0dkfjafbynkrymsq183sad7zynqr2qls0cld73nvzn3smnvdl2xx";
     };
   };
   calendar = {
     pname = "calendar";
-    version = "v3.5.0";
-    src = fetchurl {
-      url = "https://github.com/nextcloud-releases/calendar/releases/download/v3.5.0/calendar-v3.5.0.tar.gz";
-      sha256 = "sha256-+LRGl9h40AQdWN9SW+NqGwTafAGwV07Af8nVs3pUCm0=";
+    version = "v4.2.0";
+    src = fetchTarball {
+      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.2.0/calendar-v4.2.0.tar.gz";
+      sha256 = "06p92w2idml5g3zc0xhp25rpgkxm3d5pmxpx7dmqlqvw8r6z07an";
     };
   };
   contacts = {
     pname = "contacts";
-    version = "v4.2.2";
-    src = fetchurl {
-      url = "https://github.com/nextcloud-releases/contacts/releases/download/v4.2.2/contacts-v4.2.2.tar.gz";
-      sha256 = "sha256-GTiyZsUHBXPgQ17DHAihmt2W/ZnAjDwfgwnujkRwk6A=";
+    version = "v5.0.2";
+    src = fetchTarball {
+      url = "https://github.com/nextcloud-releases/contacts/releases/download/v5.0.2/contacts-v5.0.2.tar.gz";
+      sha256 = "097a71if6kkc7nphfc8b6llqlsskjwp1vg83134hzgfscvllvaj8";
     };
   };
   cookbook = {
     pname = "cookbook";
-    version = "0.9.17";
-    src = fetchurl {
-      url = "https://github.com/nextcloud/cookbook/releases/download/v0.9.17/Cookbook-0.9.17.tar.gz";
-      sha256 = "sha256-3lCqvmaMsgrFD5PzyHIcwxxGeC+qOMTGxbOi7nPFL6I=";
+    version = "0.10.1";
+    src = fetchTarball {
+      url = "https://github.com/nextcloud/cookbook/releases/download/v0.10.1/Cookbook-0.10.1.tar.gz";
+      sha256 = "1xpy060yi7pl8i91xjv2jj18yvsmjzwmv91y7i686qq8n2kc1fcg";
     };
   };
   news = {
     pname = "news";
-    version = "19.0.0";
-    src = fetchurl {
-      url = "https://github.com/nextcloud/news/releases/download/19.0.0/news.tar.gz";
-      sha256 = "sha256-lVF4H9v7bSw8137lfq4PsVg8e1TpcgvJVQU/UVQfSoY=";
+    version = "20.0.0";
+    src = fetchTarball {
+      url = "https://github.com/nextcloud/news/releases/download/20.0.0/news.tar.gz";
+      sha256 = "0pnriarr2iqci2v2hn6vpvszf4m4pkcxsd2i13bp7n1zqkg6swd7";
     };
   };
   notes = {
     pname = "notes";
-    version = "v4.5.1";
-    src = fetchurl {
-      url = "https://github.com/nextcloud/notes/releases/download/v4.5.1/notes.tar.gz";
-      sha256 = "sha256-rd3uVkVtARX4enRAWm1ivV468lboYZnYe7/zsqaHYpk=";
+    version = "v4.6.0";
+    src = fetchTarball {
+      url = "https://github.com/nextcloud/notes/releases/download/v4.6.0/notes.tar.gz";
+      sha256 = "1jcgv3awr45jq3n3qv851qlpbdl2plixba0iq2s54dmhciypdckl";
     };
   };
 }
diff --git a/pkgs/default.nix b/pkgs/default.nix
index 545984a..3818a26 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -2,7 +2,7 @@
   pkgs,
   lib,
 }: let
-  inherit (builtins) listToAttrs mapAttrs;
+  inherit (builtins) fromJSON mapAttrs readFile;
   inherit (pkgs) callPackage;
 in
   {
@@ -12,7 +12,7 @@ in
     # Add nextcloud apps
     let
       mkNextcloudApp = pkgs.callPackage ./mkNextcloudApp.nix {};
-      sources = pkgs.callPackage ./_sources_nextcloud/generated.nix {};
+      sources = fromJSON (readFile ./_sources_nextcloud/generated.json);
     in
       mapAttrs (_: source: mkNextcloudApp source) sources
   )
diff --git a/pkgs/mkNextcloudApp.nix b/pkgs/mkNextcloudApp.nix
index 3c78a94..6430ac1 100644
--- a/pkgs/mkNextcloudApp.nix
+++ b/pkgs/mkNextcloudApp.nix
@@ -1,13 +1,8 @@
 {
   fetchNextcloudApp,
   lib,
-}: let
-  inherit (lib) removePrefix;
-in
-  source:
-    fetchNextcloudApp {
-      name = source.pname;
-      version = removePrefix "v" source.version;
-      url = source.src.url;
-      sha256 = source.src.outputHash;
-    }
+}: source:
+fetchNextcloudApp {
+  url = source.src.url;
+  sha256 = source.src.sha256;
+}
diff --git a/pkgs/nextcloud-apps.toml b/pkgs/nextcloud-apps.toml
index 6e06432..69bccdc 100644
--- a/pkgs/nextcloud-apps.toml
+++ b/pkgs/nextcloud-apps.toml
@@ -1,35 +1,26 @@
-[apporder]
-src.github = "juliushaertl/apporder"
-fetch.url = "https://github.com/juliushaertl/apporder/releases/download/$ver/apporder.tar.gz"
-
 [bookmarks]
 src.github = "nextcloud/bookmarks"
 src.prefix = "v"
-fetch.url = "https://github.com/nextcloud/bookmarks/releases/download/v$ver/bookmarks-$ver.tar.gz"
+fetch.tarball = "https://github.com/nextcloud/bookmarks/releases/download/v$ver/bookmarks-$ver.tar.gz"
 
 [calendar]
-src.manual = "v3.5.0" # Pinned until we update to nextcloud 25
-# src.github = "nextcloud-releases/calendar"
-fetch.url = "https://github.com/nextcloud-releases/calendar/releases/download/$ver/calendar-$ver.tar.gz"
+src.github = "nextcloud-releases/calendar"
+fetch.tarball = "https://github.com/nextcloud-releases/calendar/releases/download/$ver/calendar-$ver.tar.gz"
 
 [contacts]
-src.manual = "v4.2.2" # Pinned until we update to nextcloud 25
-# src.github = "nextcloud-releases/contacts"
-fetch.url = "https://github.com/nextcloud-releases/contacts/releases/download/$ver/contacts-$ver.tar.gz"
+src.github = "nextcloud-releases/contacts"
+fetch.tarball = "https://github.com/nextcloud-releases/contacts/releases/download/$ver/contacts-$ver.tar.gz"
 
 [cookbook]
 src.github_tag = "nextcloud/cookbook"
 src.prefix = "v"
 src.exclude_regex = 'v\d+\.\d+\.\d+-rc\d+'
-fetch.url = "https://github.com/nextcloud/cookbook/releases/download/v$ver/Cookbook-$ver.tar.gz"
+fetch.tarball = "https://github.com/nextcloud/cookbook/releases/download/v$ver/Cookbook-$ver.tar.gz"
 
 [news]
 src.github = "nextcloud/news"
-# Sadly, the news app vendors things, and those are only included in
-# their tarball.
-fetch.url = "https://github.com/nextcloud/news/releases/download/$ver/news.tar.gz"
+fetch.tarball = "https://github.com/nextcloud/news/releases/download/$ver/news.tar.gz"
 
 [notes]
-src.manual = "v4.5.1" # Pinned until we update to nextcloud 25
-# src.github = "nextcloud/notes"
-fetch.url = "https://github.com/nextcloud/notes/releases/download/$ver/notes.tar.gz"
+src.github = "nextcloud/notes"
+fetch.tarball = "https://github.com/nextcloud/notes/releases/download/$ver/notes.tar.gz"

From 544bd0a721cf9cc31a38c36b4e7cddcc6969a9cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 11 Jan 2023 01:59:04 +0000
Subject: [PATCH 081/212] keys/staging: Add a few missing keys that made the vm
 break

---
 keys/staging.yaml | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/keys/staging.yaml b/keys/staging.yaml
index 9adfde8..069a405 100644
--- a/keys/staging.yaml
+++ b/keys/staging.yaml
@@ -5,14 +5,17 @@ steam:
 turn:
     env: ENC[AES256_GCM,data:xjIz/AY109lyiL5N01p5T3HcYco/rM5CJSRTtg==,iv:16bW6OpyOK/QL0QPGQp/Baa9xyT8E3ZsYkwqmjuofk0=,tag:J5re3uKxIykw3YunvQWBgg==,type:str]
     secret: ENC[AES256_GCM,data:eQ7dAocoZtg=,iv:fgzjTPv30WqTKlLy+yMn5MsKQgjhPnwlGFFwYEg3gWs=,tag:1ze33U1NBkgMX/9SiaBNQg==,type:str]
+    ssl-key: ENC[AES256_GCM,data:RYfwHjBvwFXgXxXIEuWUzaycTdrCvmPivsNvvUIwDRynS5G2Dl6RCVp1w9zuLvoNun5ncUPGGuLMmVqN2wkJlw==,iv:UKI3bVTY7iTDNvp5UqrZ3QlQkMZ5p2bjgODEc6DCBfQ=,tag:sz7VTyRWyZxAsP4nE48DnA==,type:str]
+    #ENC[AES256_GCM,data:bxhKzU5Tzezl749CDu8e8kxa7ahGuZFaPa9K3kxuD+4sg5Hi3apgDlC0n8oK0DeiK4Ks7+9Cyw==,iv:T/zVJUpNAv1rR0a9+6SDTG08ws2A1hFBs5Ia3TpT0uk=,tag:uGXb1VryM+lIJ8r0I5durA==,type:comment]
+    ssl-cert: ENC[AES256_GCM,data:xHUr14CjKslgbGh/n5jYSOuCw9JRxS6YXE4fxS+aJzFcNeSeGNqoipPeuJupZGBnQP/FCqohiHY=,iv:/OEsVqRshGL9NIvntMC42EPZSNL0u6EfhtUBqgV7qog=,tag:4pxtNjuvy/ibm6nDtKdSkw==,type:str]
 sops:
     kms: []
     gcp_kms: []
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2022-10-28T22:54:01Z"
-    mac: ENC[AES256_GCM,data:1nsv+Dl7lzRZNNb9kSuqFrXrcncIklw/A2uwd/yQQ546Rm/4gzpBZqCi6cv5VBCdc1iNuBcAM74DnZHMDmeWAiW0WfACPJMQjCes21P6IUsP2gu+bV2f9qqqnP2a5voxzFHp1aclklzMiiZJBEB1Y3UNz0ZG7A43hsOAE0/fJ9o=,iv:kY10PF5ErkKHXx8m0OyX2eU6kcFQsrsP3V2scVBMsuA=,tag:Uth0XfP2c0LBJQ7+7Uc0BQ==,type:str]
+    lastmodified: "2023-01-11T01:49:31Z"
+    mac: ENC[AES256_GCM,data:5IcHdNQ/mh6Jz60dlpgqbBtVGKYml4EOs7YXsBcejgAoPzZqEK+xb3f9+rq2G6sCcMXzROHJsdQUfp1wMgfp8DwVm4H+XO+SQh/E1kFuWO8G/IpXOT4P9RQC+wHxrVuxHd8pwl9CLv6uuMnO+FNg9TeWB2GAVxIBsY8JHwGN/BA=,iv:/Yqfij58LGNooyyhmr8aWCpknd4dN+b4iSvokVoDGls=,tag:XHm8Qcg75B1+pTOcgZubIQ==,type:str]
     pgp:
         - created_at: "2022-10-12T16:48:23Z"
           enc: |

From 77ddb15f22038cfe537167e81f984b1565a05178 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 11 Jan 2023 01:59:35 +0000
Subject: [PATCH 082/212] flake.nix: Build the VM using `nix build`

---
 flake.nix | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/flake.nix b/flake.nix
index de2ed54..2aa6c0b 100644
--- a/flake.nix
+++ b/flake.nix
@@ -73,15 +73,14 @@
     ###################
     packages.${system} = let
       inherit (nixpkgs.legacyPackages.${system}) writeShellScript;
+      vm = self.lib.makeNixosSystem {
+        inherit system;
+        extraModules = [(import ./configuration/hardware-specific/vm.nix)];
+      };
     in {
-      default = self.packages.${system}.run-vm;
+      default = vm.config.system.build.vm;
 
       run-vm = let
-        vm = self.lib.makeNixosSystem {
-          inherit system;
-          extraModules = [(import ./configuration/hardware-specific/vm.nix)];
-        };
-
         qemuNetOpts = self.lib.makeQemuNetOpts {
           "2222" = "2222";
           "3080" = "80";
@@ -105,9 +104,7 @@
         '';
     };
 
-    apps.${system} = let
-      inherit (nixpkgs.legacyPackages.${system}) writeShellScript;
-    in {
+    apps.${system} = {
       default = {
         type = "app";
         program = builtins.toString self.packages.${system}.run-vm;

From f6e39e09a5ce40f2235546ca59a95f361c2a4152 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 11 Jan 2023 01:59:54 +0000
Subject: [PATCH 083/212] gitea: Update configuration for 22.11

---
 configuration/services/gitea.nix | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index f346097..1d3308a 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -8,12 +8,15 @@ in {
     httpAddress = "127.0.0.1";
     database.type = "postgres";
 
-    ssh.clonePort = 2222;
     rootUrl = "https://${domain}/";
-    cookieSecure = true;
 
     appName = "Gitea: Git with a cup of tea";
-    disableRegistration = true;
+
+    settings = {
+      server.SSH_PORT = 2222;
+      service.DISABLE_REGISTRATION = true;
+      session.COOKIE_SECURE = true;
+    };
   };
 
   # Set up SSL

From 957ab110c5ae2f23771009fc0c33e16993c0bf5d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 11 Jan 2023 02:00:13 +0000
Subject: [PATCH 084/212] firewall: Open Minecraft ports for port forwarding

---
 configuration/default.nix | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/configuration/default.nix b/configuration/default.nix
index 34a7868..b84937e 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -63,6 +63,8 @@
         8448
         # starbound
         21025
+        # Minecraft
+        25565
 
         config.services.coturn.listening-port
         config.services.coturn.tls-listening-port
@@ -71,6 +73,9 @@
       ];
 
       allowedUDPPorts = [
+        # More minecraft
+        25565
+
         config.services.coturn.listening-port
         config.services.coturn.tls-listening-port
         config.services.coturn.alt-listening-port

From b7726af1c4d6c7bc7dc6874516aae809ceadd0f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 11 Jan 2023 02:00:33 +0000
Subject: [PATCH 085/212] config: Make changes suggested post 22.11 update

---
 configuration/default.nix | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index b84937e..d090cef 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -35,11 +35,11 @@
     '';
 
     # Enable remote builds from tlater
-    trustedUsers = ["@wheel"];
+    settings.trusted-users = ["@wheel"];
   };
 
   nixpkgs.config.allowUnfreePredicate = pkg:
-    builtins.elem (lib.getName pkg) ["steam-original" "steam-runtime" "steamcmd"];
+    builtins.elem (lib.getName pkg) ["steam-original" "steam-runtime" "steam-run" "steamcmd"];
 
   # Optimization for minecraft servers, see:
   # https://bugs.mojang.com/browse/MC-183518

From b7feffc52f25f75af8b20c7c0212475df028e983 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 11 Jan 2023 02:33:53 +0000
Subject: [PATCH 086/212] hardware-configuration: Update to new auto-generated
 settings

---
 .../linode/hardware-configuration.nix                | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/configuration/hardware-specific/linode/hardware-configuration.nix b/configuration/hardware-specific/linode/hardware-configuration.nix
index 2a33a67..c1776d5 100644
--- a/configuration/hardware-specific/linode/hardware-configuration.nix
+++ b/configuration/hardware-specific/linode/hardware-configuration.nix
@@ -8,7 +8,7 @@
     [ (modulesPath + "/profiles/qemu-guest.nix")
     ];
 
-  boot.initrd.availableKernelModules = [ "virtio_pci" "ahci" "sd_mod" ];
+  boot.initrd.availableKernelModules = [ "virtio_pci" "virtio_scsi" "ahci" "sd_mod" ];
   boot.initrd.kernelModules = [ ];
   boot.kernelModules = [ ];
   boot.extraModulePackages = [ ];
@@ -27,5 +27,13 @@
     [ { device = "/dev/disk/by-uuid/45c8ad29-3861-4e68-a566-47e6d9269dca"; }
     ];
 
-  nix.maxJobs = lib.mkDefault 2;
+  # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
+  # (the default) this is the recommended approach. When using systemd-networkd it's
+  # still possible to use this option, but it's recommended to use it in conjunction
+  # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
+  networking.useDHCP = lib.mkDefault true;
+  # networking.interfaces.eth0.useDHCP = lib.mkDefault true;
+
+  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
+  hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
 }

From bb397841eee0986be2b2e0949be83d28f9958d3d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 26 Feb 2023 05:44:54 +0000
Subject: [PATCH 087/212] refactoring: Use flake-inputs instead of awkwardly
 passing through

---
 configuration/default.nix |  4 ++++
 flake.nix                 | 27 +++++++++++++++++----------
 lib/default.nix           | 22 +---------------------
 3 files changed, 22 insertions(+), 31 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index d090cef..2a4ce63 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -3,9 +3,13 @@
   pkgs,
   lib,
   modulesPath,
+  flake-inputs,
   ...
 }: {
   imports = [
+    flake-inputs.sops-nix.nixosModules.sops
+    flake-inputs.tlaternet-webserver.nixosModules.default
+
     "${modulesPath}/profiles/headless.nix"
     "${modulesPath}/profiles/minimal.nix"
     (import ../modules)
diff --git a/flake.nix b/flake.nix
index 2aa6c0b..ec8a157 100644
--- a/flake.nix
+++ b/flake.nix
@@ -24,8 +24,8 @@
     sops-nix,
     nvfetcher,
     deploy-rs,
-    tlaternet-webserver,
-  }: let
+    ...
+  } @ inputs: let
     system = "x86_64-linux";
   in {
     ##################
@@ -33,9 +33,14 @@
     ##################
     nixosConfigurations = {
       # The actual system definition
-      tlaternet = self.lib.makeNixosSystem {
+      tlaternet = nixpkgs.lib.nixosSystem {
         inherit system;
-        extraModules = [(import ./configuration/hardware-specific/linode)];
+        specialArgs.flake-inputs = inputs;
+
+        modules = [
+          ./configuration
+          ./configuration/hardware-specific/linode
+        ];
       };
     };
 
@@ -63,19 +68,21 @@
     ####################
     # Helper functions #
     ####################
-    lib = import ./lib {
-      inherit nixpkgs sops-nix tlaternet-webserver;
-      lib = nixpkgs.lib;
-    };
+    lib = import ./lib {inherit (nixpkgs) lib;};
 
     ###################
     # Utility scripts #
     ###################
     packages.${system} = let
       inherit (nixpkgs.legacyPackages.${system}) writeShellScript;
-      vm = self.lib.makeNixosSystem {
+      vm = nixpkgs.lib.nixosSystem {
         inherit system;
-        extraModules = [(import ./configuration/hardware-specific/vm.nix)];
+        specialArgs.flake-inputs = inputs;
+
+        modules = [
+          ./configuration
+          ./configuration/hardware-specific/vm.nix
+        ];
       };
     in {
       default = vm.config.system.build.vm;
diff --git a/lib/default.nix b/lib/default.nix
index 5f6b68f..20d874d 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -1,9 +1,4 @@
-{
-  lib,
-  nixpkgs,
-  sops-nix,
-  tlaternet-webserver,
-}: let
+{lib}: let
   inherit (lib.attrsets) mapAttrsToList;
   inherit (lib.strings) concatStringsSep;
 in {
@@ -12,19 +7,4 @@ in {
     (mapAttrsToList
       (host: vm: "hostfwd=::${host}-:${vm}")
       portMapping);
-
-  makeNixosSystem = {
-    system,
-    extraModules,
-  }:
-    nixpkgs.lib.nixosSystem {
-      inherit system;
-      modules =
-        [
-          sops-nix.nixosModules.sops
-          tlaternet-webserver.nixosModules.default
-          (import ../configuration)
-        ]
-        ++ extraModules;
-    };
 }

From 33ec32a8da2fc55a9459eb3a8f1a1196e5da68de Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 26 Feb 2023 05:46:11 +0000
Subject: [PATCH 088/212] conduit: Update to 0.5.0

---
 configuration/services/conduit.nix |  2 ++
 flake.lock                         | 17 +++++++++++++++++
 flake.nix                          |  1 +
 3 files changed, 20 insertions(+)

diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
index 6da82da..bf63305 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit.nix
@@ -1,6 +1,7 @@
 {
   config,
   lib,
+  flake-inputs,
   ...
 }: let
   inherit (lib.strings) concatMapStringsSep;
@@ -11,6 +12,7 @@
 in {
   services.matrix-conduit = {
     enable = true;
+    package = flake-inputs.nixpkgs-unstable.legacyPackages.${pkgs.system}.matrix-conduit;
     settings.global = {
       address = "127.0.0.1";
       server_name = domain;
diff --git a/flake.lock b/flake.lock
index e156a33..5793ce8 100644
--- a/flake.lock
+++ b/flake.lock
@@ -378,6 +378,22 @@
         "type": "github"
       }
     },
+    "nixpkgs-unstable": {
+      "locked": {
+        "lastModified": 1677342105,
+        "narHash": "sha256-kv1fpkfCJGb0M+LZaCHFUuIS9kRIwyVgupHu86Y28nc=",
+        "owner": "nixos",
+        "repo": "nixpkgs",
+        "rev": "b1f87ca164a9684404c8829b851c3586c4d9f089",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nixos",
+        "ref": "nixos-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
     "nixpkgs_2": {
       "locked": {
         "lastModified": 1673345971,
@@ -479,6 +495,7 @@
       "inputs": {
         "deploy-rs": "deploy-rs",
         "nixpkgs": "nixpkgs_2",
+        "nixpkgs-unstable": "nixpkgs-unstable",
         "nvfetcher": "nvfetcher",
         "sops-nix": "sops-nix",
         "tlaternet-webserver": "tlaternet-webserver"
diff --git a/flake.nix b/flake.nix
index ec8a157..3f3865c 100644
--- a/flake.nix
+++ b/flake.nix
@@ -3,6 +3,7 @@
 
   inputs = {
     nixpkgs.url = "github:nixos/nixpkgs/nixos-22.11";
+    nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
     deploy-rs.url = "github:serokell/deploy-rs";
     sops-nix = {
       url = "github:Mic92/sops-nix";

From 74f38614a0816dc5d45012042279615ba5405765 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Thu, 23 Feb 2023 09:08:56 +0000
Subject: [PATCH 089/212] matrix: Add heisenbridge

---
 configuration/services/conduit.nix | 82 ++++++++++++++++++++++++++++++
 configuration/sops.nix             |  2 +
 keys/production.yaml               |  7 ++-
 keys/staging.yaml                  |  7 ++-
 4 files changed, 94 insertions(+), 4 deletions(-)

diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
index bf63305..871b5e2 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit.nix
@@ -1,4 +1,5 @@
 {
+  pkgs,
   config,
   lib,
   flake-inputs,
@@ -30,6 +31,87 @@ in {
     };
   };
 
+  systemd.services.heisenbridge = let
+    replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret";
+    registrationFile = builtins.toFile "heisenbridge-registration.yaml" (builtins.toJSON {
+      id = "heisenbridge";
+      url = "http://127.0.0.1:9898";
+      as_token = "@AS_TOKEN@";
+      hs_token = "@HS_TOKEN@";
+      rate_limited = false;
+      sender_localpart = "heisenbridge";
+      namespaces = {
+        users = [
+          {
+            regex = "@irc_.*";
+            exclusive = true;
+          }
+          {
+            regex = "@heisenbridge:.*";
+            exclusive = true;
+          }
+        ];
+        aliases = [];
+        rooms = [];
+      };
+    });
+
+    # TODO(tlater): Starting with systemd 253 it will become possible
+    # to do the credential setup as part of ExecStartPre/preStart
+    # instead.
+    #
+    # This will also make it possible to actually set caps on the
+    # heisenbridge process using systemd, so that we can run the
+    # identd process.
+    execScript = pkgs.writeShellScript "heisenbridge" ''
+      cp ${registrationFile} "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml"
+      chmod 600 $RUNTIME_DIRECTORY/heisenbridge-registration.yaml
+      ${replaceSecretBin} '@AS_TOKEN@' "$CREDENTIALS_DIRECTORY/heisenbridge_as-token" "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml"
+      ${replaceSecretBin} '@HS_TOKEN@' "$CREDENTIALS_DIRECTORY/heisenbridge_hs-token" "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml"
+      chmod 400 $RUNTIME_DIRECTORY/heisenbridge-registration.yaml
+
+      ${pkgs.heisenbridge}/bin/heisenbridge \
+          --config $RUNTIME_DIRECTORY/heisenbridge-registration.yaml \
+          --owner @tlater:matrix.tlater.net \
+          'http://localhost:${toString cfg.settings.global.port}'
+    '';
+  in {
+    description = "Matrix<->IRC bridge";
+    wantedBy = ["multi-user.target"];
+    after = ["conduit.service"];
+
+    serviceConfig = {
+      Type = "simple";
+
+      LoadCredential = "heisenbridge:/run/secrets/heisenbridge";
+
+      ExecStart = execScript;
+
+      DynamicUser = true;
+      RuntimeDirectory = "heisenbridge";
+      RuntimeDirectoryMode = "0700";
+
+      RestrictNamespaces = true;
+      PrivateUsers = true;
+      ProtectHostname = true;
+      ProtectClock = true;
+      ProtectKernelTunables = true;
+      ProtectKernelModules = true;
+      ProtectKernelLogs = true;
+      ProtectControlGroups = true;
+      RestrictAddressFamilies = ["AF_INET AF_INET6"];
+      LockPersonality = true;
+      RestrictRealtime = true;
+      ProtectProc = "invisible";
+      ProcSubset = "pid";
+      UMask = 0077;
+
+      # For the identd port
+      # CapabilityBoundingSet = ["CAP_NET_BIND_SERVICE"];
+      # AmbientCapabilities = ["CAP_NET_BIND_SERVICE"];
+    };
+  };
+
   # Pass in the TURN secret via EnvironmentFile, not supported by
   # upstream module currently.
   #
diff --git a/configuration/sops.nix b/configuration/sops.nix
index 21613b2..d02b3f0 100644
--- a/configuration/sops.nix
+++ b/configuration/sops.nix
@@ -6,6 +6,8 @@
       group = "nextcloud";
     };
     secrets."steam/tlater" = {};
+    secrets."heisenbridge/as-token" = {};
+    secrets."heisenbridge/hs-token" = {};
     secrets."turn/env" = {};
     secrets."turn/secret" = {
       owner = "turnserver";
diff --git a/keys/production.yaml b/keys/production.yaml
index 6bc16ad..666b893 100644
--- a/keys/production.yaml
+++ b/keys/production.yaml
@@ -2,6 +2,9 @@ nextcloud:
     tlater: ENC[AES256_GCM,data:zNsPm4uFaIRe3LjcwmayRg==,iv:5wam6bP5zP708jC9UrLV0s8qspl3Pm4fPzbMFYBUyPQ=,tag:apnJUMeJwMn9q0NhO4ptmA==,type:str]
 steam:
     tlater: ENC[AES256_GCM,data:HNsve/Wid40ftclO9n09yXg=,iv:VQxAz4eR9lfxEvM0zl1FpJpbKrEFxjIYLyCqL9Aool0=,tag:LHcpHCXAHe8p2kOvOnKXyw==,type:str]
+heisenbridge:
+    as-token: ENC[AES256_GCM,data:+2yo6T18j34622H8ZWblAFB2phLw1q0k0vUQEZ5sFj7dQaRnkEiAMi0R3p17Zq0pOtGEC0RRZuPLYkcZ1oKP0w==,iv:lGwrQYp//FufpmJocrLIVyy9RK7lEEVcpAi0wmkjr34=,tag:yV06UbhAYJQz36O2XdhY+A==,type:str]
+    hs-token: ENC[AES256_GCM,data:u52WpkQFd/J7JFoE/rfNluebyZQLOokvkVdL7+AEAvrhJhrkJli1ztkD79lbC+6tGUH4tT3T+nX9wvGKnrRUQg==,iv:as+9fVuvMg2IoE2WIKD9mHi+znhNcWRh5Zq+yr0xcDQ=,tag:mZ7fh7U0MfgI8hyq/28Bcg==,type:str]
 turn:
     env: ENC[AES256_GCM,data:kt5nhVo9pb/ZbPUEcqSYXxN9YMgQKnFb5VRfFFS/qoIaJ73uD2fuJKqcxAyVRrdLqnSAWSQBgTgunBzdP7xqLAK2qt8DYAQWHkIe9uxFbSXZpdmw,iv:9lq6SFwTFN4GGm6gPiJpUMasMdnHVF6XLGYrsyG3kjU=,tag:428Qf9DOiiHt/Wjb188b8g==,type:str]
     secret: ENC[AES256_GCM,data:si7ee6Xfhdgdyzbp6aQpF7pz3TmTBb7iQ82lRPVXNDg9JfHI+lbmgAsSnRLX5qMCA6P9R045sSMosqidL8QwRg==,iv:SrhpZKK8D45yxCEfDb9P3TwtA14+qEI+wcRqcN/a6pw=,tag:PiwV+mOL9xHJgJft6sc61g==,type:str]
@@ -14,8 +17,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2022-11-05T18:45:55Z"
-    mac: ENC[AES256_GCM,data:xPCfjqVkewEqrUjHroXa9RGHITntVj2uGPaRZfj0lqTUPFG6GQDn3Yq6L6cV3EPOYQ4OedJlaVXy05OHkzZwjYEbBQVGQ0aH/ZOP7X301eebBX5MvHLFU4mcnjMITWGH/E7SXz3pPF75s9eM/onx374PcQt6zevbBF+Jp0Fz71I=,iv:84JL69nF3ougygMAVFOoTaCn37thvm4lF6HYdgTiftg=,tag:ATQ18acehgUAE/dX+vYugQ==,type:str]
+    lastmodified: "2023-02-21T10:51:11Z"
+    mac: ENC[AES256_GCM,data:uMqT+7ljd6t1RpF9IH7illO62pq5cERoAtJlRic5BNOeawy/+7ufVorhhya15m39WTKnlGyIY0MEd3tDueHBm4rjf+Pmh6PQ+owRv+deXHv0jXYWX2sz/6i1aYbv9DDMWsvNbkdidKEme+ctY6EVgjSjN5nxxcx+vH+u1OyQ3t0=,iv:VKXznTlMH34SOS+4dpfOVaoiiUTRmIbUMnTPNpyawvY=,tag:onA5C4o/tcGjdBxO9JxMGw==,type:str]
     pgp:
         - created_at: "2022-10-12T00:46:51Z"
           enc: |
diff --git a/keys/staging.yaml b/keys/staging.yaml
index 069a405..41e20ac 100644
--- a/keys/staging.yaml
+++ b/keys/staging.yaml
@@ -2,6 +2,9 @@ nextcloud:
     tlater: ENC[AES256_GCM,data:91kDcO4hpng=,iv:ayuILRmRru4ZxTCur9H2xHuLjkDzwPdS/4lEog/tesU=,tag:qYhJxnNDcCwUM7xe7Tlcjw==,type:str]
 steam:
     tlater: ENC[AES256_GCM,data:jcW4wacGzOQ=,iv:KstKGHflscSWDFXGbnAZUcsqGN4Ot+w7sRbsAUwZNHQ=,tag:n9sRWvaKSgagpIgV/NF/Og==,type:str]
+heisenbridge:
+    as-token: ENC[AES256_GCM,data:tXbOeo7nv8I=,iv:wJAKcOXX9nGIw4n38ThOoj29u7dUWhsxSQG/p79JlEw=,tag:rTVaGS2UuWcea1uBa8YX2g==,type:str]
+    hs-token: ENC[AES256_GCM,data:VBwvwomv0Xg=,iv:q6INtJ+rg+QiXj8uBdBzQYQZUBBXp+9odxDHwvu8Jxc=,tag:XKhm8nxygAkKaiVPJ2Fcdg==,type:str]
 turn:
     env: ENC[AES256_GCM,data:xjIz/AY109lyiL5N01p5T3HcYco/rM5CJSRTtg==,iv:16bW6OpyOK/QL0QPGQp/Baa9xyT8E3ZsYkwqmjuofk0=,tag:J5re3uKxIykw3YunvQWBgg==,type:str]
     secret: ENC[AES256_GCM,data:eQ7dAocoZtg=,iv:fgzjTPv30WqTKlLy+yMn5MsKQgjhPnwlGFFwYEg3gWs=,tag:1ze33U1NBkgMX/9SiaBNQg==,type:str]
@@ -14,8 +17,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2023-01-11T01:49:31Z"
-    mac: ENC[AES256_GCM,data:5IcHdNQ/mh6Jz60dlpgqbBtVGKYml4EOs7YXsBcejgAoPzZqEK+xb3f9+rq2G6sCcMXzROHJsdQUfp1wMgfp8DwVm4H+XO+SQh/E1kFuWO8G/IpXOT4P9RQC+wHxrVuxHd8pwl9CLv6uuMnO+FNg9TeWB2GAVxIBsY8JHwGN/BA=,iv:/Yqfij58LGNooyyhmr8aWCpknd4dN+b4iSvokVoDGls=,tag:XHm8Qcg75B1+pTOcgZubIQ==,type:str]
+    lastmodified: "2023-02-21T08:32:04Z"
+    mac: ENC[AES256_GCM,data:ZZtL4zYX7FsYeGJ1CcTq5AzRkrvOxIeCoVf77JyEj9k3gApm3k7z2eXe/D+8qvwahlleuvAqhVCUH/I5yHaQSjXXsHO1flULiTnQVk4hrX0fDwXp97NQwpvDovSRyGqx4F25dISfYLVhFpb+64yaPxqMzThVk+Q7Xn40GCY5PR8=,iv:xNeyqB5K2EBDDJEq72IDwpGqzKkAlcxHO6GlJY/iHmM=,tag:Qxz0GTQ/I4EsZhFZh2VxKg==,type:str]
     pgp:
         - created_at: "2022-10-12T16:48:23Z"
           enc: |

From 8ac5fa9357e9ff2c664585817f1be57fd951d040 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 28 Feb 2023 04:38:41 +0000
Subject: [PATCH 090/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'deploy-rs':
    'github:serokell/deploy-rs/a5619f5660a00f58c2b7c16d89058e92327ac9b8' (2022-12-29)
  → 'github:serokell/deploy-rs/8c9ea9605eed20528bf60fae35a2b613b901fd77' (2023-01-19)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/54644f409ab471e87014bb305eac8c50190bcf48' (2023-01-10)
  → 'github:nixos/nixpkgs/8bd260eb578e3fea6bce158b24c93ab158d031e7' (2023-02-26)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/b1f87ca164a9684404c8829b851c3586c4d9f089' (2023-02-25)
  → 'github:nixos/nixpkgs/7f5639fa3b68054ca0b062866dc62b22c3f11505' (2023-02-26)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/2253120d2a6147e57bafb5c689e086221df8032f' (2023-01-08)
  → 'github:Mic92/sops-nix/83fe25c8019db8216f5c6ffc65b394707784b4f3' (2023-02-26)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/9f11a2df77cb945c115ae2a65f53f38121597d73' (2023-01-07)
  → 'github:NixOS/nixpkgs/ea736343e4d4a052e023d54b23334cf685de479c' (2023-02-25)
• Updated input 'tlaternet-webserver':
    'git+https://gitea.tlater.net/tlaternet/tlaternet.git?ref=refs%2fheads%2fmaster&rev=b2894e4fefbdc1c9964ab47c931497a417562d8a' (2023-01-05)
  → 'git+https://gitea.tlater.net/tlaternet/tlaternet.git?ref=refs%2fheads%2fmaster&rev=d142e98788c2476b7df0a5c1e621f3f5c65c130f' (2023-01-21)
---
 flake.lock | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/flake.lock b/flake.lock
index 5793ce8..dd0c7bc 100644
--- a/flake.lock
+++ b/flake.lock
@@ -64,11 +64,11 @@
         "utils": "utils"
       },
       "locked": {
-        "lastModified": 1672327199,
-        "narHash": "sha256-pFlngSHXKBhAmbaKZ4FYtu57LLunG+vWdL7a5vw1RvQ=",
+        "lastModified": 1674127017,
+        "narHash": "sha256-QO1xF7stu5ZMDLbHN30LFolMAwY6TVlzYvQoUs1RD68=",
         "owner": "serokell",
         "repo": "deploy-rs",
-        "rev": "a5619f5660a00f58c2b7c16d89058e92327ac9b8",
+        "rev": "8c9ea9605eed20528bf60fae35a2b613b901fd77",
         "type": "github"
       },
       "original": {
@@ -364,11 +364,11 @@
     },
     "nixpkgs-stable": {
       "locked": {
-        "lastModified": 1673100377,
-        "narHash": "sha256-mT76pTd0YFxT6CwtPhDgHJhuIgLY+ZLSMiQpBufwMG4=",
+        "lastModified": 1677367679,
+        "narHash": "sha256-pOMXi7F9tcHls06Qv+7XCPASTJeXu47Jhd0Pk9du8T4=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "9f11a2df77cb945c115ae2a65f53f38121597d73",
+        "rev": "ea736343e4d4a052e023d54b23334cf685de479c",
         "type": "github"
       },
       "original": {
@@ -380,11 +380,11 @@
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1677342105,
-        "narHash": "sha256-kv1fpkfCJGb0M+LZaCHFUuIS9kRIwyVgupHu86Y28nc=",
+        "lastModified": 1677407201,
+        "narHash": "sha256-3blwdI9o1BAprkvlByHvtEm5HAIRn/XPjtcfiunpY7s=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "b1f87ca164a9684404c8829b851c3586c4d9f089",
+        "rev": "7f5639fa3b68054ca0b062866dc62b22c3f11505",
         "type": "github"
       },
       "original": {
@@ -396,11 +396,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1673345971,
-        "narHash": "sha256-4DfFcKLRfVUTyuGrGNNmw37IeIZSoku9tgTVmu/iD98=",
+        "lastModified": 1677447818,
+        "narHash": "sha256-dgXEUbz2hgaJL4xCD/5JLhA36UJOhP4qn7Cp6UZhB0I=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "54644f409ab471e87014bb305eac8c50190bcf48",
+        "rev": "8bd260eb578e3fea6bce158b24c93ab158d031e7",
         "type": "github"
       },
       "original": {
@@ -543,11 +543,11 @@
         "nixpkgs-stable": "nixpkgs-stable"
       },
       "locked": {
-        "lastModified": 1673147300,
-        "narHash": "sha256-gR9OEfTzWfL6vG0qkbn1TlBAOlg4LuW8xK/u0V41Ihc=",
+        "lastModified": 1677381477,
+        "narHash": "sha256-NLzWgll+Q0Af8gI1ha34OHt7Y1GtOMYhCWQWV9LXE9Y=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "2253120d2a6147e57bafb5c689e086221df8032f",
+        "rev": "83fe25c8019db8216f5c6ffc65b394707784b4f3",
         "type": "github"
       },
       "original": {
@@ -565,11 +565,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1672884793,
-        "narHash": "sha256-biUbdKq8OaRQm25poaRJalrRq+M+/TrNr7J6rI65lNI=",
+        "lastModified": 1674277771,
+        "narHash": "sha256-4zEc5BNWFZyxIEEeesE7PnbbdOPC0eF+SOiUPHmHnKI=",
         "ref": "refs/heads/master",
-        "rev": "b2894e4fefbdc1c9964ab47c931497a417562d8a",
-        "revCount": 53,
+        "rev": "d142e98788c2476b7df0a5c1e621f3f5c65c130f",
+        "revCount": 55,
         "type": "git",
         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git"
       },

From 8f4399c1dd44e5b83962e4001bf88fa5b13306fd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 28 Feb 2023 04:53:27 +0000
Subject: [PATCH 091/212] nextcloud: Update apps

---
 pkgs/_sources_nextcloud/generated.json | 32 ++++++++------------------
 pkgs/_sources_nextcloud/generated.nix  | 26 ++++++++-------------
 2 files changed, 18 insertions(+), 40 deletions(-)

diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index 7752f5e..c5b4538 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -1,18 +1,4 @@
 {
-    "apporder": {
-        "cargoLocks": null,
-        "date": null,
-        "extract": null,
-        "name": "apporder",
-        "passthru": null,
-        "pinned": false,
-        "src": {
-            "sha256": "1nx1vdwlqyy3x5vw2h2xx51hmv7gsp8mam1fj813yc3655js9m96",
-            "type": "tarball",
-            "url": "https://github.com/juliushaertl/apporder/releases/download/v0.15.0/apporder.tar.gz"
-        },
-        "version": "v0.15.0"
-    },
     "bookmarks": {
         "cargoLocks": null,
         "date": null,
@@ -35,11 +21,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "06p92w2idml5g3zc0xhp25rpgkxm3d5pmxpx7dmqlqvw8r6z07an",
+            "sha256": "0g29md9rg6a4qhh6hj1q5l7kji0afxmizfrybc1xif4lqbhglaw5",
             "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.2.0/calendar-v4.2.0.tar.gz"
+            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.2.4/calendar-v4.2.4.tar.gz"
         },
-        "version": "v4.2.0"
+        "version": "v4.2.4"
     },
     "contacts": {
         "cargoLocks": null,
@@ -49,11 +35,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "097a71if6kkc7nphfc8b6llqlsskjwp1vg83134hzgfscvllvaj8",
+            "sha256": "1m00r6cpqyrg2b0p8hg4wqkb3wn643fy63ax7qksp39rn18smrwk",
             "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/contacts/releases/download/v5.0.2/contacts-v5.0.2.tar.gz"
+            "url": "https://github.com/nextcloud-releases/contacts/releases/download/v5.1.0/contacts-v5.1.0.tar.gz"
         },
-        "version": "v5.0.2"
+        "version": "v5.1.0"
     },
     "cookbook": {
         "cargoLocks": null,
@@ -77,11 +63,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "0pnriarr2iqci2v2hn6vpvszf4m4pkcxsd2i13bp7n1zqkg6swd7",
+            "sha256": "0iz1yrl7h60yhc1d1gkalkzc5vlj8sq6lff0ggns6a6qpsdpn9c5",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/news/releases/download/20.0.0/news.tar.gz"
+            "url": "https://github.com/nextcloud/news/releases/download/20.0.1/news.tar.gz"
         },
-        "version": "20.0.0"
+        "version": "20.0.1"
     },
     "notes": {
         "cargoLocks": null,
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index f3a0521..5ad5f6b 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -1,14 +1,6 @@
 # This file was generated by nvfetcher, please do not modify it manually.
 { fetchgit, fetchurl, fetchFromGitHub, dockerTools }:
 {
-  apporder = {
-    pname = "apporder";
-    version = "v0.15.0";
-    src = fetchTarball {
-      url = "https://github.com/juliushaertl/apporder/releases/download/v0.15.0/apporder.tar.gz";
-      sha256 = "1nx1vdwlqyy3x5vw2h2xx51hmv7gsp8mam1fj813yc3655js9m96";
-    };
-  };
   bookmarks = {
     pname = "bookmarks";
     version = "12.0.0";
@@ -19,18 +11,18 @@
   };
   calendar = {
     pname = "calendar";
-    version = "v4.2.0";
+    version = "v4.2.4";
     src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.2.0/calendar-v4.2.0.tar.gz";
-      sha256 = "06p92w2idml5g3zc0xhp25rpgkxm3d5pmxpx7dmqlqvw8r6z07an";
+      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.2.4/calendar-v4.2.4.tar.gz";
+      sha256 = "0g29md9rg6a4qhh6hj1q5l7kji0afxmizfrybc1xif4lqbhglaw5";
     };
   };
   contacts = {
     pname = "contacts";
-    version = "v5.0.2";
+    version = "v5.1.0";
     src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/contacts/releases/download/v5.0.2/contacts-v5.0.2.tar.gz";
-      sha256 = "097a71if6kkc7nphfc8b6llqlsskjwp1vg83134hzgfscvllvaj8";
+      url = "https://github.com/nextcloud-releases/contacts/releases/download/v5.1.0/contacts-v5.1.0.tar.gz";
+      sha256 = "1m00r6cpqyrg2b0p8hg4wqkb3wn643fy63ax7qksp39rn18smrwk";
     };
   };
   cookbook = {
@@ -43,10 +35,10 @@
   };
   news = {
     pname = "news";
-    version = "20.0.0";
+    version = "20.0.1";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/news/releases/download/20.0.0/news.tar.gz";
-      sha256 = "0pnriarr2iqci2v2hn6vpvszf4m4pkcxsd2i13bp7n1zqkg6swd7";
+      url = "https://github.com/nextcloud/news/releases/download/20.0.1/news.tar.gz";
+      sha256 = "0iz1yrl7h60yhc1d1gkalkzc5vlj8sq6lff0ggns6a6qpsdpn9c5";
     };
   };
   notes = {

From 663054c293ac65b3c4dd92596c73ec2446419f5d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 17 Apr 2023 21:07:31 +0100
Subject: [PATCH 092/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/8bd260eb578e3fea6bce158b24c93ab158d031e7' (2023-02-26)
  → 'github:nixos/nixpkgs/de66115c552acc4e0c0f92c5a5efb32e37dfa216' (2023-04-17)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/7f5639fa3b68054ca0b062866dc62b22c3f11505' (2023-02-26)
  → 'github:nixos/nixpkgs/f294325aed382b66c7a188482101b0f336d1d7db' (2023-04-16)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/83fe25c8019db8216f5c6ffc65b394707784b4f3' (2023-02-26)
  → 'github:Mic92/sops-nix/de6514f8fe1b3c2b57307569a0898bc4be9ae1c5' (2023-04-17)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/ea736343e4d4a052e023d54b23334cf685de479c' (2023-02-25)
  → 'github:NixOS/nixpkgs/1040ce5f652b586da95dfd80d48a745e107b9eac' (2023-04-16)
• Updated input 'tlaternet-webserver':
    'git+https://gitea.tlater.net/tlaternet/tlaternet.git?ref=refs%2fheads%2fmaster&rev=d142e98788c2476b7df0a5c1e621f3f5c65c130f' (2023-01-21)
  → 'git+https://gitea.tlater.net/tlaternet/tlaternet.git?ref=refs%2fheads%2fmaster&rev=2ca66c4fe1b8cfdd5d873cadb2735cef555dacca' (2023-04-17)
• Updated input 'tlaternet-webserver/dream2nix':
    'github:nix-community/dream2nix/9f6911c78dcb0832f7fcc955e847db1a5a9ce29a' (2023-01-02)
  → 'github:nix-community/dream2nix/34a80ab215f1f24068ea9c76f3a7e5bc19478653' (2023-04-04)
• Removed input 'tlaternet-webserver/dream2nix/alejandra'
• Removed input 'tlaternet-webserver/dream2nix/alejandra/fenix'
• Removed input 'tlaternet-webserver/dream2nix/alejandra/fenix/nixpkgs'
• Removed input 'tlaternet-webserver/dream2nix/alejandra/fenix/rust-analyzer-src'
• Removed input 'tlaternet-webserver/dream2nix/alejandra/flakeCompat'
• Removed input 'tlaternet-webserver/dream2nix/alejandra/nixpkgs'
• Added input 'tlaternet-webserver/dream2nix/drv-parts':
    'github:davhau/drv-parts/ced8a52f62b0a94244713df2225c05c85b416110' (2023-03-30)
• Added input 'tlaternet-webserver/dream2nix/drv-parts/flake-compat':
    follows 'tlaternet-webserver/dream2nix/flake-compat'
• Added input 'tlaternet-webserver/dream2nix/drv-parts/flake-parts':
    follows 'tlaternet-webserver/dream2nix/flake-parts'
• Added input 'tlaternet-webserver/dream2nix/drv-parts/nixpkgs':
    follows 'tlaternet-webserver/dream2nix/nixpkgs'
• Added input 'tlaternet-webserver/dream2nix/flake-compat':
    'github:edolstra/flake-compat/35bb57c0c8d8b62bbfd284272c928ceb64ddbde9' (2023-01-17)
• Updated input 'tlaternet-webserver/dream2nix/flake-parts':
    'github:hercules-ci/flake-parts/d591857e9d7dd9ddbfba0ea02b43b927c3c0f1fa' (2022-11-14)
  → 'github:hercules-ci/flake-parts/47478a4a003e745402acf63be7f9a092d51b83d7' (2023-02-09)
• Updated input 'tlaternet-webserver/dream2nix/flake-parts/nixpkgs-lib':
    'github:NixOS/nixpkgs/34c5293a71ffdb2fe054eb5288adc1882c1eb0b1?dir=lib' (2022-10-09)
  → follows 'tlaternet-webserver/dream2nix/nixpkgs'
• Added input 'tlaternet-webserver/dream2nix/nixpkgsV1':
    'github:NixOS/nixpkgs/5eb98948b66de29f899c7fe27ae112a47964baf8' (2023-03-11)
• Added input 'tlaternet-webserver/dream2nix/pruned-racket-catalog':
    'github:nix-community/pruned-racket-catalog/c8b89557fb53b36efa2ee48a769c7364df0f6262' (2023-01-01)
• Updated input 'tlaternet-webserver/fenix':
    'github:nix-community/fenix/eb6583fcd626051c4d284f2fb51cd2659a43e7f6' (2023-01-04)
  → 'github:nix-community/fenix/0d8c0d08db5fe6e5d995f4584f991ad60bbb1673' (2023-04-17)
• Updated input 'tlaternet-webserver/fenix/rust-analyzer-src':
    'github:rust-lang/rust-analyzer/a97c71f92d574cb5104e3e1246eb9038d1a214a2' (2023-01-03)
  → 'github:rust-lang/rust-analyzer/bab80dae445fd576cb4cc22ba208e9fbc39dc18d' (2023-04-16)
---
 flake.lock | 250 +++++++++++++++++++++++++----------------------------
 1 file changed, 119 insertions(+), 131 deletions(-)

diff --git a/flake.lock b/flake.lock
index dd0c7bc..13b0222 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1,29 +1,5 @@
 {
   "nodes": {
-    "alejandra": {
-      "inputs": {
-        "fenix": "fenix",
-        "flakeCompat": "flakeCompat",
-        "nixpkgs": [
-          "tlaternet-webserver",
-          "dream2nix",
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1658427149,
-        "narHash": "sha256-ToD/1z/q5VHsLMrS2h96vjJoLho59eNRtknOUd19ey8=",
-        "owner": "kamadorueda",
-        "repo": "alejandra",
-        "rev": "f5a22afd2adfb249b4e68e0b33aa1f0fb73fb1be",
-        "type": "github"
-      },
-      "original": {
-        "owner": "kamadorueda",
-        "repo": "alejandra",
-        "type": "github"
-      }
-    },
     "all-cabal-json": {
       "flake": false,
       "locked": {
@@ -95,10 +71,11 @@
     },
     "dream2nix": {
       "inputs": {
-        "alejandra": "alejandra",
         "all-cabal-json": "all-cabal-json",
         "crane": "crane",
         "devshell": "devshell",
+        "drv-parts": "drv-parts",
+        "flake-compat": "flake-compat_3",
         "flake-parts": "flake-parts",
         "flake-utils-pre-commit": "flake-utils-pre-commit",
         "ghc-utils": "ghc-utils",
@@ -106,15 +83,17 @@
         "mach-nix": "mach-nix",
         "nix-pypi-fetcher": "nix-pypi-fetcher",
         "nixpkgs": "nixpkgs_3",
+        "nixpkgsV1": "nixpkgsV1",
         "poetry2nix": "poetry2nix",
-        "pre-commit-hooks": "pre-commit-hooks"
+        "pre-commit-hooks": "pre-commit-hooks",
+        "pruned-racket-catalog": "pruned-racket-catalog"
       },
       "locked": {
-        "lastModified": 1672661134,
-        "narHash": "sha256-WqBUyKeiv+jI11ug+qP0OnZ4nngK6eBRVTGHgdzEGvc=",
+        "lastModified": 1680605243,
+        "narHash": "sha256-dUrxj653kcLvjNKRI7NoTJoj+Q7G+vOYsl4iuwtnIWo=",
         "owner": "nix-community",
         "repo": "dream2nix",
-        "rev": "9f6911c78dcb0832f7fcc955e847db1a5a9ce29a",
+        "rev": "34a80ab215f1f24068ea9c76f3a7e5bc19478653",
         "type": "github"
       },
       "original": {
@@ -123,44 +102,52 @@
         "type": "github"
       }
     },
+    "drv-parts": {
+      "inputs": {
+        "flake-compat": [
+          "tlaternet-webserver",
+          "dream2nix",
+          "flake-compat"
+        ],
+        "flake-parts": [
+          "tlaternet-webserver",
+          "dream2nix",
+          "flake-parts"
+        ],
+        "nixpkgs": [
+          "tlaternet-webserver",
+          "dream2nix",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1680172861,
+        "narHash": "sha256-QMyI338xRxaHFDlCXdLCtgelGQX2PdlagZALky4ZXJ8=",
+        "owner": "davhau",
+        "repo": "drv-parts",
+        "rev": "ced8a52f62b0a94244713df2225c05c85b416110",
+        "type": "github"
+      },
+      "original": {
+        "owner": "davhau",
+        "repo": "drv-parts",
+        "type": "github"
+      }
+    },
     "fenix": {
       "inputs": {
         "nixpkgs": [
           "tlaternet-webserver",
-          "dream2nix",
-          "alejandra",
           "nixpkgs"
         ],
         "rust-analyzer-src": "rust-analyzer-src"
       },
       "locked": {
-        "lastModified": 1657607339,
-        "narHash": "sha256-HaqoAwlbVVZH2n4P3jN2FFPMpVuhxDy1poNOR7kzODc=",
+        "lastModified": 1681712564,
+        "narHash": "sha256-14QeQU5m1iJg4v+HnLnH1X5W2V1d0lHfaHxDJP/6aig=",
         "owner": "nix-community",
         "repo": "fenix",
-        "rev": "b814c83d9e6aa5a28d0cf356ecfdafb2505ad37d",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nix-community",
-        "repo": "fenix",
-        "type": "github"
-      }
-    },
-    "fenix_2": {
-      "inputs": {
-        "nixpkgs": [
-          "tlaternet-webserver",
-          "nixpkgs"
-        ],
-        "rust-analyzer-src": "rust-analyzer-src_2"
-      },
-      "locked": {
-        "lastModified": 1672813381,
-        "narHash": "sha256-PKt6orRiFO19KFKnOhzK26hbFLtimlRNE2dGwrTEhII=",
-        "owner": "nix-community",
-        "repo": "fenix",
-        "rev": "eb6583fcd626051c4d284f2fb51cd2659a43e7f6",
+        "rev": "0d8c0d08db5fe6e5d995f4584f991ad60bbb1673",
         "type": "github"
       },
       "original": {
@@ -201,16 +188,36 @@
         "type": "github"
       }
     },
+    "flake-compat_3": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1673956053,
+        "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
+        "type": "github"
+      },
+      "original": {
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "type": "github"
+      }
+    },
     "flake-parts": {
       "inputs": {
-        "nixpkgs-lib": "nixpkgs-lib"
+        "nixpkgs-lib": [
+          "tlaternet-webserver",
+          "dream2nix",
+          "nixpkgs"
+        ]
       },
       "locked": {
-        "lastModified": 1668450977,
-        "narHash": "sha256-cfLhMhnvXn6x1vPm+Jow3RiFAUSCw/l1utktCw5rVA4=",
+        "lastModified": 1675933616,
+        "narHash": "sha256-/rczJkJHtx16IFxMmAWu5nNYcSXNg1YYXTHoGjLrLUA=",
         "owner": "hercules-ci",
         "repo": "flake-parts",
-        "rev": "d591857e9d7dd9ddbfba0ea02b43b927c3c0f1fa",
+        "rev": "47478a4a003e745402acf63be7f9a092d51b83d7",
         "type": "github"
       },
       "original": {
@@ -249,22 +256,6 @@
         "type": "github"
       }
     },
-    "flakeCompat": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1650374568,
-        "narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=",
-        "owner": "edolstra",
-        "repo": "flake-compat",
-        "rev": "b4a34015c698c7793d592d66adbab377907a2be8",
-        "type": "github"
-      },
-      "original": {
-        "owner": "edolstra",
-        "repo": "flake-compat",
-        "type": "github"
-      }
-    },
     "ghc-utils": {
       "flake": false,
       "locked": {
@@ -344,31 +335,13 @@
         "type": "github"
       }
     },
-    "nixpkgs-lib": {
-      "locked": {
-        "dir": "lib",
-        "lastModified": 1665349835,
-        "narHash": "sha256-UK4urM3iN80UXQ7EaOappDzcisYIuEURFRoGQ/yPkug=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "34c5293a71ffdb2fe054eb5288adc1882c1eb0b1",
-        "type": "github"
-      },
-      "original": {
-        "dir": "lib",
-        "owner": "NixOS",
-        "ref": "nixos-unstable",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
     "nixpkgs-stable": {
       "locked": {
-        "lastModified": 1677367679,
-        "narHash": "sha256-pOMXi7F9tcHls06Qv+7XCPASTJeXu47Jhd0Pk9du8T4=",
+        "lastModified": 1681613598,
+        "narHash": "sha256-Ogkoma0ytYcDoMR2N7CZFABPo+i0NNo26dPngru9tPc=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "ea736343e4d4a052e023d54b23334cf685de479c",
+        "rev": "1040ce5f652b586da95dfd80d48a745e107b9eac",
         "type": "github"
       },
       "original": {
@@ -380,11 +353,11 @@
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1677407201,
-        "narHash": "sha256-3blwdI9o1BAprkvlByHvtEm5HAIRn/XPjtcfiunpY7s=",
+        "lastModified": 1681648924,
+        "narHash": "sha256-pzi3HISK8+7mpEtv08Yr80wswyHKsz+RP1CROG1Qf6s=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "7f5639fa3b68054ca0b062866dc62b22c3f11505",
+        "rev": "f294325aed382b66c7a188482101b0f336d1d7db",
         "type": "github"
       },
       "original": {
@@ -394,13 +367,28 @@
         "type": "github"
       }
     },
+    "nixpkgsV1": {
+      "locked": {
+        "lastModified": 1678500271,
+        "narHash": "sha256-tRBLElf6f02HJGG0ZR7znMNFv/Uf7b2fFInpTHiHaSE=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "5eb98948b66de29f899c7fe27ae112a47964baf8",
+        "type": "github"
+      },
+      "original": {
+        "id": "nixpkgs",
+        "ref": "nixos-22.11",
+        "type": "indirect"
+      }
+    },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1677447818,
-        "narHash": "sha256-dgXEUbz2hgaJL4xCD/5JLhA36UJOhP4qn7Cp6UZhB0I=",
+        "lastModified": 1681696129,
+        "narHash": "sha256-Ba2y1lmsWmmAOAoTD5G9UnTS/UqV0ZFyzysgdfu7qag=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "8bd260eb578e3fea6bce158b24c93ab158d031e7",
+        "rev": "de66115c552acc4e0c0f92c5a5efb32e37dfa216",
         "type": "github"
       },
       "original": {
@@ -491,6 +479,23 @@
         "type": "github"
       }
     },
+    "pruned-racket-catalog": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1672537287,
+        "narHash": "sha256-SuOvXVcLfakw18oJB/PuRMyvGyGG1+CQD3R+TGHIv44=",
+        "owner": "nix-community",
+        "repo": "pruned-racket-catalog",
+        "rev": "c8b89557fb53b36efa2ee48a769c7364df0f6262",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "ref": "catalog",
+        "repo": "pruned-racket-catalog",
+        "type": "github"
+      }
+    },
     "root": {
       "inputs": {
         "deploy-rs": "deploy-rs",
@@ -504,28 +509,11 @@
     "rust-analyzer-src": {
       "flake": false,
       "locked": {
-        "lastModified": 1657557289,
-        "narHash": "sha256-PRW+nUwuqNTRAEa83SfX+7g+g8nQ+2MMbasQ9nt6+UM=",
+        "lastModified": 1681679582,
+        "narHash": "sha256-bijdVXzzfVSMHCjRuQ+PysNJt0Ei2mIhs+CPnR6yP4w=",
         "owner": "rust-lang",
         "repo": "rust-analyzer",
-        "rev": "caf23f29144b371035b864a1017dbc32573ad56d",
-        "type": "github"
-      },
-      "original": {
-        "owner": "rust-lang",
-        "ref": "nightly",
-        "repo": "rust-analyzer",
-        "type": "github"
-      }
-    },
-    "rust-analyzer-src_2": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1672757238,
-        "narHash": "sha256-BK1njXsjprMT0f+1aQYmZ/ueN9D3Y3wrz9gw4UvieRQ=",
-        "owner": "rust-lang",
-        "repo": "rust-analyzer",
-        "rev": "a97c71f92d574cb5104e3e1246eb9038d1a214a2",
+        "rev": "bab80dae445fd576cb4cc22ba208e9fbc39dc18d",
         "type": "github"
       },
       "original": {
@@ -543,11 +531,11 @@
         "nixpkgs-stable": "nixpkgs-stable"
       },
       "locked": {
-        "lastModified": 1677381477,
-        "narHash": "sha256-NLzWgll+Q0Af8gI1ha34OHt7Y1GtOMYhCWQWV9LXE9Y=",
+        "lastModified": 1681721408,
+        "narHash": "sha256-NWCbZKOQEXz1hA2YDFxdd+fVrrw9edbG1DvbbLf7KUY=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "83fe25c8019db8216f5c6ffc65b394707784b4f3",
+        "rev": "de6514f8fe1b3c2b57307569a0898bc4be9ae1c5",
         "type": "github"
       },
       "original": {
@@ -559,17 +547,17 @@
     "tlaternet-webserver": {
       "inputs": {
         "dream2nix": "dream2nix",
-        "fenix": "fenix_2",
+        "fenix": "fenix",
         "nixpkgs": [
           "nixpkgs"
         ]
       },
       "locked": {
-        "lastModified": 1674277771,
-        "narHash": "sha256-4zEc5BNWFZyxIEEeesE7PnbbdOPC0eF+SOiUPHmHnKI=",
+        "lastModified": 1681761148,
+        "narHash": "sha256-eub9HQGCCjxOc+u4p9Om8y5EcVlBJOQOoK4APxXAbhc=",
         "ref": "refs/heads/master",
-        "rev": "d142e98788c2476b7df0a5c1e621f3f5c65c130f",
-        "revCount": 55,
+        "rev": "2ca66c4fe1b8cfdd5d873cadb2735cef555dacca",
+        "revCount": 62,
         "type": "git",
         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git"
       },

From 317cdf0039a04ca66b64e07e9920a3947e9be5d1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 17 Apr 2023 23:35:28 +0100
Subject: [PATCH 093/212] nextcloud: Update nextcloud apps

---
 pkgs/_sources_nextcloud/generated.json | 36 +++++++++++++-------------
 pkgs/_sources_nextcloud/generated.nix  | 36 +++++++++++++-------------
 pkgs/nextcloud-apps.toml               |  4 ++-
 3 files changed, 39 insertions(+), 37 deletions(-)

diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index c5b4538..94d5c9a 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -7,11 +7,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "0dkfjafbynkrymsq183sad7zynqr2qls0cld73nvzn3smnvdl2xx",
+            "sha256": "1kdpma5f3rb9g29j364lqv6bkar5qgwlvcxmhpmzllwlkmjpc9w8",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/bookmarks/releases/download/v12.0.0/bookmarks-12.0.0.tar.gz"
+            "url": "https://github.com/nextcloud/bookmarks/releases/download/v12.1.0/bookmarks-12.1.0.tar.gz"
         },
-        "version": "12.0.0"
+        "version": "12.1.0"
     },
     "calendar": {
         "cargoLocks": null,
@@ -21,11 +21,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "0g29md9rg6a4qhh6hj1q5l7kji0afxmizfrybc1xif4lqbhglaw5",
+            "sha256": "0xhrpadzz73rdjyk4y1xm5hwc6k104rlpp9nmw08pq8phpfs12qa",
             "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.2.4/calendar-v4.2.4.tar.gz"
+            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.3.3/calendar-v4.3.3.tar.gz"
         },
-        "version": "v4.2.4"
+        "version": "v4.3.3"
     },
     "contacts": {
         "cargoLocks": null,
@@ -35,11 +35,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "1m00r6cpqyrg2b0p8hg4wqkb3wn643fy63ax7qksp39rn18smrwk",
+            "sha256": "1rdql3m7pg9m044hppyrm3xw329y8h0pzwcmpcinjbjs0vqjssxk",
             "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/contacts/releases/download/v5.1.0/contacts-v5.1.0.tar.gz"
+            "url": "https://github.com/nextcloud-releases/contacts/releases/download/v5.2.0/contacts-v5.2.0.tar.gz"
         },
-        "version": "v5.1.0"
+        "version": "v5.2.0"
     },
     "cookbook": {
         "cargoLocks": null,
@@ -49,11 +49,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "1xpy060yi7pl8i91xjv2jj18yvsmjzwmv91y7i686qq8n2kc1fcg",
+            "sha256": "18rzvdqd99nlkk3p0y9y8b17ihw5c4c9wsx8psq6xadspm97002y",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/cookbook/releases/download/v0.10.1/Cookbook-0.10.1.tar.gz"
+            "url": "https://github.com/nextcloud/cookbook/releases/download/v0.10.2/Cookbook-0.10.2.tar.gz"
         },
-        "version": "0.10.1"
+        "version": "0.10.2"
     },
     "news": {
         "cargoLocks": null,
@@ -63,11 +63,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "0iz1yrl7h60yhc1d1gkalkzc5vlj8sq6lff0ggns6a6qpsdpn9c5",
+            "sha256": "026ggjf6dqbjv8hnj6jj1nnqz0256ck2yg13zhln7zc84lhfzlfd",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/news/releases/download/20.0.1/news.tar.gz"
+            "url": "https://github.com/nextcloud/news/releases/download/21.1.0/news.tar.gz"
         },
-        "version": "20.0.1"
+        "version": "21.1.0"
     },
     "notes": {
         "cargoLocks": null,
@@ -77,10 +77,10 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "1jcgv3awr45jq3n3qv851qlpbdl2plixba0iq2s54dmhciypdckl",
+            "sha256": "0klqf8dixrrb8yp8cc60ggnvhmqb3yh9f6y1281jn8ia5jml622v",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/notes/releases/download/v4.6.0/notes.tar.gz"
+            "url": "https://github.com/nextcloud/notes/releases/download/v4.7.2/notes.tar.gz"
         },
-        "version": "v4.6.0"
+        "version": "v4.7.2"
     }
 }
\ No newline at end of file
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index 5ad5f6b..c29f6b5 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -3,50 +3,50 @@
 {
   bookmarks = {
     pname = "bookmarks";
-    version = "12.0.0";
+    version = "12.1.0";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/bookmarks/releases/download/v12.0.0/bookmarks-12.0.0.tar.gz";
-      sha256 = "0dkfjafbynkrymsq183sad7zynqr2qls0cld73nvzn3smnvdl2xx";
+      url = "https://github.com/nextcloud/bookmarks/releases/download/v12.1.0/bookmarks-12.1.0.tar.gz";
+      sha256 = "1kdpma5f3rb9g29j364lqv6bkar5qgwlvcxmhpmzllwlkmjpc9w8";
     };
   };
   calendar = {
     pname = "calendar";
-    version = "v4.2.4";
+    version = "v4.3.3";
     src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.2.4/calendar-v4.2.4.tar.gz";
-      sha256 = "0g29md9rg6a4qhh6hj1q5l7kji0afxmizfrybc1xif4lqbhglaw5";
+      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.3.3/calendar-v4.3.3.tar.gz";
+      sha256 = "0xhrpadzz73rdjyk4y1xm5hwc6k104rlpp9nmw08pq8phpfs12qa";
     };
   };
   contacts = {
     pname = "contacts";
-    version = "v5.1.0";
+    version = "v5.2.0";
     src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/contacts/releases/download/v5.1.0/contacts-v5.1.0.tar.gz";
-      sha256 = "1m00r6cpqyrg2b0p8hg4wqkb3wn643fy63ax7qksp39rn18smrwk";
+      url = "https://github.com/nextcloud-releases/contacts/releases/download/v5.2.0/contacts-v5.2.0.tar.gz";
+      sha256 = "1rdql3m7pg9m044hppyrm3xw329y8h0pzwcmpcinjbjs0vqjssxk";
     };
   };
   cookbook = {
     pname = "cookbook";
-    version = "0.10.1";
+    version = "0.10.2";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/cookbook/releases/download/v0.10.1/Cookbook-0.10.1.tar.gz";
-      sha256 = "1xpy060yi7pl8i91xjv2jj18yvsmjzwmv91y7i686qq8n2kc1fcg";
+      url = "https://github.com/nextcloud/cookbook/releases/download/v0.10.2/Cookbook-0.10.2.tar.gz";
+      sha256 = "18rzvdqd99nlkk3p0y9y8b17ihw5c4c9wsx8psq6xadspm97002y";
     };
   };
   news = {
     pname = "news";
-    version = "20.0.1";
+    version = "21.1.0";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/news/releases/download/20.0.1/news.tar.gz";
-      sha256 = "0iz1yrl7h60yhc1d1gkalkzc5vlj8sq6lff0ggns6a6qpsdpn9c5";
+      url = "https://github.com/nextcloud/news/releases/download/21.1.0/news.tar.gz";
+      sha256 = "026ggjf6dqbjv8hnj6jj1nnqz0256ck2yg13zhln7zc84lhfzlfd";
     };
   };
   notes = {
     pname = "notes";
-    version = "v4.6.0";
+    version = "v4.7.2";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/notes/releases/download/v4.6.0/notes.tar.gz";
-      sha256 = "1jcgv3awr45jq3n3qv851qlpbdl2plixba0iq2s54dmhciypdckl";
+      url = "https://github.com/nextcloud/notes/releases/download/v4.7.2/notes.tar.gz";
+      sha256 = "0klqf8dixrrb8yp8cc60ggnvhmqb3yh9f6y1281jn8ia5jml622v";
     };
   };
 }
diff --git a/pkgs/nextcloud-apps.toml b/pkgs/nextcloud-apps.toml
index 69bccdc..709633d 100644
--- a/pkgs/nextcloud-apps.toml
+++ b/pkgs/nextcloud-apps.toml
@@ -1,6 +1,8 @@
 [bookmarks]
-src.github = "nextcloud/bookmarks"
+# src.github = "nextcloud/bookmarks"
 src.prefix = "v"
+# TODO(tlater): Remove when we update to nextcloud 26
+src.manual = "v12.1.0"
 fetch.tarball = "https://github.com/nextcloud/bookmarks/releases/download/v$ver/bookmarks-$ver.tar.gz"
 
 [calendar]

From acd7cc802b2a3cfd19c97df53c22cccb4a99b8a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 23 Apr 2023 15:46:38 +0100
Subject: [PATCH 094/212] networking: Set up static IP address

---
 configuration/default.nix                     |  6 ++-
 .../hardware-specific/linode/default.nix      | 38 +++++++++++++++++++
 configuration/hardware-specific/vm.nix        |  5 +++
 3 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index 2a4ce63..f69ec09 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -15,9 +15,11 @@
     (import ../modules)
 
     ./services/conduit.nix
+    ./services/foundryvtt.nix
     ./services/gitea.nix
     ./services/nextcloud.nix
     ./services/webserver.nix
+    ./services/wireguard.nix
     ./services/starbound.nix
     ./services/postgres.nix
     ./sops.nix
@@ -51,10 +53,8 @@
 
   networking = {
     hostName = "tlaternet";
-
     usePredictableInterfaceNames = false;
     useDHCP = false;
-    interfaces.eth0.useDHCP = true;
 
     firewall = {
       allowedTCPPorts = [
@@ -95,6 +95,8 @@
     };
   };
 
+  systemd.network.enable = true;
+
   time.timeZone = "Europe/London";
 
   users.users.tlater = {
diff --git a/configuration/hardware-specific/linode/default.nix b/configuration/hardware-specific/linode/default.nix
index 3cd3570..b05fade 100644
--- a/configuration/hardware-specific/linode/default.nix
+++ b/configuration/hardware-specific/linode/default.nix
@@ -19,4 +19,42 @@
       '';
     };
   };
+
+  systemd.network.networks."10-eth0" = {
+    matchConfig.Name = "eth0";
+
+    networkConfig = {
+      DHCP = "no";
+
+      Address = "178.79.137.55/24";
+      Gateway = "178.79.137.1";
+
+      Domains = "ip.linodeusercontent.com";
+      DNS = [
+        "178.79.182.5"
+        "176.58.107.5"
+        "176.58.116.5"
+        "176.58.121.5"
+        "151.236.220.5"
+        "212.71.252.5"
+        "212.71.253.5"
+        "109.74.192.20"
+        "109.74.193.20"
+        "109.74.194.20"
+        "2a01:7e00::9"
+        "2a01:7e00::3"
+        "2a01:7e00::c"
+        "2a01:7e00::5"
+        "2a01:7e00::6"
+        "2a01:7e00::8"
+        "2a01:7e00::b"
+        "2a01:7e00::4"
+        "2a01:7e00::7"
+        "2a01:7e00::2"
+      ];
+
+      IPv6PrivacyExtensions = "no";
+      IPv6AcceptRA = "yes";
+    };
+  };
 }
diff --git a/configuration/hardware-specific/vm.nix b/configuration/hardware-specific/vm.nix
index aed39e4..8c93f30 100644
--- a/configuration/hardware-specific/vm.nix
+++ b/configuration/hardware-specific/vm.nix
@@ -11,6 +11,11 @@
   # Use the staging secrets
   sops.defaultSopsFile = lib.mkOverride 99 ../../keys/staging.yaml;
 
+  systemd.network.networks."10-eth0" = {
+    matchConfig.Name = "eth0";
+    networkConfig.DHCP = "yes";
+  };
+
   # # Set up VM settings to match real VPS
   # virtualisation.memorySize = 3941;
   # virtualisation.cores = 2;

From 14d29fa49dc31bc472306a6f840dd8aad7e5162e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 23 Apr 2023 23:42:25 +0100
Subject: [PATCH 095/212] services: Add wireguard service

---
 configuration/services/wireguard.nix | 74 ++++++++++++++++++++++++++++
 configuration/sops.nix               | 44 +++++++++++------
 keys/production.yaml                 |  6 ++-
 keys/staging.yaml                    |  6 ++-
 4 files changed, 110 insertions(+), 20 deletions(-)
 create mode 100644 configuration/services/wireguard.nix

diff --git a/configuration/services/wireguard.nix b/configuration/services/wireguard.nix
new file mode 100644
index 0000000..1ae6aac
--- /dev/null
+++ b/configuration/services/wireguard.nix
@@ -0,0 +1,74 @@
+{config, ...}: {
+  # iptables needs to permit forwarding from wg0 to wg0
+  networking.firewall.extraCommands = ''
+    iptables -A FORWARD -i wg0 -o wg0 -j ACCEPT
+    # This ensures that we send messages with the correct MTU to any
+    # connecting host; without it, the weirdest errors occur
+    iptables -A FORWARD -i wg0 -o wg0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
+  '';
+
+  systemd.network = {
+    netdevs = {
+      "20-wg0" = {
+        netdevConfig = {
+          Name = "wg0";
+          Kind = "wireguard";
+          Description = "wg0 - wireguard tunnel";
+        };
+
+        wireguardConfig = {
+          ListenPort = 51820;
+          PrivateKeyFile = config.sops.secrets."wireguard/server-key".path;
+          # Public key: 73z3Pga/2BCxETYM/qCT2FM1JUCUvQ+Cp+8ROxjhu0w=
+        };
+
+        wireguardPeers = [
+          {
+            # yui
+            wireguardPeerConfig = {
+              AllowedIPs = ["10.45.249.2/32"];
+              PublicKey = "5mlnqEVJWks5OqgeFA2bLIrvST9TlCE81Btl+j4myz0=";
+            };
+          }
+
+          {
+            # yuanyuan
+            wireguardPeerConfig = {
+              AllowedIPs = ["10.45.249.10/32"];
+              PublicKey = "0UsFE2atz/O5P3OKQ8UHyyyGQNJbp1MeIWUJLuoerwE=";
+            };
+          }
+        ];
+      };
+    };
+
+    networks = {
+      "20-wg0" = {
+        matchConfig.Name = "wg0";
+
+        networkConfig = {
+          Address = [
+            "10.45.249.1/32"
+            # TODO(tlater): Add IPv6 whenever that becomes relevant
+          ];
+
+          IPForward = "yes";
+          IPv4ProxyARP = "yes";
+        };
+
+        routes = [
+          {
+            routeConfig = {
+              Source = "10.45.249.0/24";
+              Destination = "10.45.249.0/24";
+              Gateway = "10.45.249.1";
+              GatewayOnLink = "no";
+            };
+          }
+        ];
+
+        linkConfig.RequiredForOnline = "no";
+      };
+    };
+  };
+}
diff --git a/configuration/sops.nix b/configuration/sops.nix
index d02b3f0..4becfd4 100644
--- a/configuration/sops.nix
+++ b/configuration/sops.nix
@@ -1,22 +1,34 @@
 {
   sops = {
     defaultSopsFile = ../keys/production.yaml;
-    secrets."nextcloud/tlater" = {
-      owner = "nextcloud";
-      group = "nextcloud";
-    };
-    secrets."steam/tlater" = {};
-    secrets."heisenbridge/as-token" = {};
-    secrets."heisenbridge/hs-token" = {};
-    secrets."turn/env" = {};
-    secrets."turn/secret" = {
-      owner = "turnserver";
-    };
-    secrets."turn/ssl-key" = {
-      owner = "turnserver";
-    };
-    secrets."turn/ssl-cert" = {
-      owner = "turnserver";
+
+    secrets = {
+      "nextcloud/tlater" = {
+        owner = "nextcloud";
+        group = "nextcloud";
+      };
+
+      "steam/tlater" = {};
+
+      "heisenbridge/as-token" = {};
+      "heisenbridge/hs-token" = {};
+
+      "wireguard/server-key" = {
+        owner = "root";
+        group = "systemd-network";
+        mode = "0440";
+      };
+
+      "turn/env" = {};
+      "turn/secret" = {
+        owner = "turnserver";
+      };
+      "turn/ssl-key" = {
+        owner = "turnserver";
+      };
+      "turn/ssl-cert" = {
+        owner = "turnserver";
+      };
     };
   };
 }
diff --git a/keys/production.yaml b/keys/production.yaml
index 666b893..6ef9ef7 100644
--- a/keys/production.yaml
+++ b/keys/production.yaml
@@ -5,6 +5,8 @@ steam:
 heisenbridge:
     as-token: ENC[AES256_GCM,data:+2yo6T18j34622H8ZWblAFB2phLw1q0k0vUQEZ5sFj7dQaRnkEiAMi0R3p17Zq0pOtGEC0RRZuPLYkcZ1oKP0w==,iv:lGwrQYp//FufpmJocrLIVyy9RK7lEEVcpAi0wmkjr34=,tag:yV06UbhAYJQz36O2XdhY+A==,type:str]
     hs-token: ENC[AES256_GCM,data:u52WpkQFd/J7JFoE/rfNluebyZQLOokvkVdL7+AEAvrhJhrkJli1ztkD79lbC+6tGUH4tT3T+nX9wvGKnrRUQg==,iv:as+9fVuvMg2IoE2WIKD9mHi+znhNcWRh5Zq+yr0xcDQ=,tag:mZ7fh7U0MfgI8hyq/28Bcg==,type:str]
+wireguard:
+    server-key: ENC[AES256_GCM,data:mXb7ZznJHf5CgV8rI4uzPBATMRbmd7LimgtCkQM9kAjbIaGwUBqJZBN3fXs=,iv:3Po1Orinzov9rnEm9cLzgJY1PeD+5Jl9115MriABHh8=,tag:E/2CjDO1JCvJzxCnqKcNyw==,type:str]
 turn:
     env: ENC[AES256_GCM,data:kt5nhVo9pb/ZbPUEcqSYXxN9YMgQKnFb5VRfFFS/qoIaJ73uD2fuJKqcxAyVRrdLqnSAWSQBgTgunBzdP7xqLAK2qt8DYAQWHkIe9uxFbSXZpdmw,iv:9lq6SFwTFN4GGm6gPiJpUMasMdnHVF6XLGYrsyG3kjU=,tag:428Qf9DOiiHt/Wjb188b8g==,type:str]
     secret: ENC[AES256_GCM,data:si7ee6Xfhdgdyzbp6aQpF7pz3TmTBb7iQ82lRPVXNDg9JfHI+lbmgAsSnRLX5qMCA6P9R045sSMosqidL8QwRg==,iv:SrhpZKK8D45yxCEfDb9P3TwtA14+qEI+wcRqcN/a6pw=,tag:PiwV+mOL9xHJgJft6sc61g==,type:str]
@@ -17,8 +19,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2023-02-21T10:51:11Z"
-    mac: ENC[AES256_GCM,data:uMqT+7ljd6t1RpF9IH7illO62pq5cERoAtJlRic5BNOeawy/+7ufVorhhya15m39WTKnlGyIY0MEd3tDueHBm4rjf+Pmh6PQ+owRv+deXHv0jXYWX2sz/6i1aYbv9DDMWsvNbkdidKEme+ctY6EVgjSjN5nxxcx+vH+u1OyQ3t0=,iv:VKXznTlMH34SOS+4dpfOVaoiiUTRmIbUMnTPNpyawvY=,tag:onA5C4o/tcGjdBxO9JxMGw==,type:str]
+    lastmodified: "2023-04-23T17:34:53Z"
+    mac: ENC[AES256_GCM,data:UaGB4uwmYGVbKud5KrvdKeYTnYrs8nnQsT590KIS/b/9JhpQo5JXFtHsm1AteEBg9ygmY6tYKDcK4AXwz/uR/m3CW5If03dBNG8F9Uy3dPL5KaebC/EsNVIaRavWTbSZgqhnBgYeM+HkeQPskSWuwviSNU0D7d1n98Q89Y0kQfA=,iv:kEsRh8hb1amd2qozyxwYHCHdX80c2mO5Mm7npKX3DKc=,tag:p5GPd0OZvowghT92pxxXeA==,type:str]
     pgp:
         - created_at: "2022-10-12T00:46:51Z"
           enc: |
diff --git a/keys/staging.yaml b/keys/staging.yaml
index 41e20ac..49b5a6a 100644
--- a/keys/staging.yaml
+++ b/keys/staging.yaml
@@ -5,6 +5,8 @@ steam:
 heisenbridge:
     as-token: ENC[AES256_GCM,data:tXbOeo7nv8I=,iv:wJAKcOXX9nGIw4n38ThOoj29u7dUWhsxSQG/p79JlEw=,tag:rTVaGS2UuWcea1uBa8YX2g==,type:str]
     hs-token: ENC[AES256_GCM,data:VBwvwomv0Xg=,iv:q6INtJ+rg+QiXj8uBdBzQYQZUBBXp+9odxDHwvu8Jxc=,tag:XKhm8nxygAkKaiVPJ2Fcdg==,type:str]
+wireguard:
+    server-key: ENC[AES256_GCM,data:FvY897XdKoa/mckE8JQLCkklsnYD6Wz1wpsu5t3uhEnW3iarnDQxF9msuYU=,iv:jqGXfekM+Vs+J9b5nlZ5Skd1ZKHajoUo2Dc4tMYPm1w=,tag:EehikjI/FCU8wqtpvJRamQ==,type:str]
 turn:
     env: ENC[AES256_GCM,data:xjIz/AY109lyiL5N01p5T3HcYco/rM5CJSRTtg==,iv:16bW6OpyOK/QL0QPGQp/Baa9xyT8E3ZsYkwqmjuofk0=,tag:J5re3uKxIykw3YunvQWBgg==,type:str]
     secret: ENC[AES256_GCM,data:eQ7dAocoZtg=,iv:fgzjTPv30WqTKlLy+yMn5MsKQgjhPnwlGFFwYEg3gWs=,tag:1ze33U1NBkgMX/9SiaBNQg==,type:str]
@@ -17,8 +19,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2023-02-21T08:32:04Z"
-    mac: ENC[AES256_GCM,data:ZZtL4zYX7FsYeGJ1CcTq5AzRkrvOxIeCoVf77JyEj9k3gApm3k7z2eXe/D+8qvwahlleuvAqhVCUH/I5yHaQSjXXsHO1flULiTnQVk4hrX0fDwXp97NQwpvDovSRyGqx4F25dISfYLVhFpb+64yaPxqMzThVk+Q7Xn40GCY5PR8=,iv:xNeyqB5K2EBDDJEq72IDwpGqzKkAlcxHO6GlJY/iHmM=,tag:Qxz0GTQ/I4EsZhFZh2VxKg==,type:str]
+    lastmodified: "2023-04-23T17:35:16Z"
+    mac: ENC[AES256_GCM,data:4cW8k6o3jET8k+yJGyApjOyuSUQb+d+4wX/RTNnpbt+867sExQrZUrOMif/u8S4WmcKVSJgvrzuxK9hpDPYhJ1d/5YuHH1Dyj7QDRdhbZYHhkpPus0ZVTEpSknZzx2eWH1ch/fyJJknlrBlfb/tz50Dv+w9mhkL7qteaIq+Vmsc=,iv:YMfAuGwu1kAM0wGkq3kzVMnC72yo7ZT04BuEwoLRPIA=,tag:6I1VRzteRaLuxN+sfLA5Mw==,type:str]
     pgp:
         - created_at: "2022-10-12T16:48:23Z"
           enc: |

From a3e2d2931c2a6b50049c4ccc06df1c0aa427591d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Thu, 11 May 2023 22:02:57 +0100
Subject: [PATCH 096/212] services: Add FoundryVTT service

---
 configuration/services/foundryvtt.nix | 35 +++++++++++++++++++++++++++
 flake.lock                            | 21 ++++++++++++++++
 flake.nix                             |  4 +++
 3 files changed, 60 insertions(+)
 create mode 100644 configuration/services/foundryvtt.nix

diff --git a/configuration/services/foundryvtt.nix b/configuration/services/foundryvtt.nix
new file mode 100644
index 0000000..7bb2286
--- /dev/null
+++ b/configuration/services/foundryvtt.nix
@@ -0,0 +1,35 @@
+{
+  lib,
+  config,
+  flake-inputs,
+  ...
+}: let
+  domain = "foundryvtt.${config.services.nginx.domain}";
+in {
+  imports = [flake-inputs.foundryvtt.nixosModules.foundryvtt];
+
+  services.foundryvtt = {
+    enable = true;
+    hostName = domain;
+    minifyStaticFiles = true;
+  };
+
+  # Want to start it manually when I need it, not have it constantly
+  # running
+  systemd.services.foundryvtt.wantedBy = lib.mkForce [];
+
+  services.nginx.virtualHosts."${domain}" = let
+    inherit (config.services.foundryvtt) port;
+  in {
+    forceSSL = true;
+    enableACME = true;
+    extraConfig = ''
+      add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
+    '';
+
+    locations."/" = {
+      proxyWebsockets = true;
+      proxyPass = "http://localhost:${toString port}";
+    };
+  };
+}
diff --git a/flake.lock b/flake.lock
index 13b0222..3fe3b91 100644
--- a/flake.lock
+++ b/flake.lock
@@ -256,6 +256,26 @@
         "type": "github"
       }
     },
+    "foundryvtt": {
+      "inputs": {
+        "nixpkgs": [
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1677026752,
+        "narHash": "sha256-cYeFDzb0kmKQhBuN0vYWoLulCqj3vf7QhvnsPBO66vc=",
+        "owner": "reckenrode",
+        "repo": "nix-foundryvtt",
+        "rev": "6c52bfc6824a3dba673df4894a71193ec32aa399",
+        "type": "github"
+      },
+      "original": {
+        "owner": "reckenrode",
+        "repo": "nix-foundryvtt",
+        "type": "github"
+      }
+    },
     "ghc-utils": {
       "flake": false,
       "locked": {
@@ -499,6 +519,7 @@
     "root": {
       "inputs": {
         "deploy-rs": "deploy-rs",
+        "foundryvtt": "foundryvtt",
         "nixpkgs": "nixpkgs_2",
         "nixpkgs-unstable": "nixpkgs-unstable",
         "nvfetcher": "nvfetcher",
diff --git a/flake.nix b/flake.nix
index 3f3865c..4c8a805 100644
--- a/flake.nix
+++ b/flake.nix
@@ -17,6 +17,10 @@
       url = "git+https://gitea.tlater.net/tlaternet/tlaternet.git";
       inputs.nixpkgs.follows = "nixpkgs";
     };
+    foundryvtt = {
+      url = "github:reckenrode/nix-foundryvtt";
+      inputs.nixpkgs.follows = "nixpkgs";
+    };
   };
 
   outputs = {

From 1e1f8f1e36e4a62ed0e2bc0a095ac375c15ad39e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 28 Jul 2023 11:03:25 +0200
Subject: [PATCH 097/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'deploy-rs':
    'github:serokell/deploy-rs/8c9ea9605eed20528bf60fae35a2b613b901fd77' (2023-01-19)
  → 'github:serokell/deploy-rs/724463b5a94daa810abfc64a4f87faef4e00f984' (2023-06-14)
• Updated input 'foundryvtt':
    'github:reckenrode/nix-foundryvtt/6c52bfc6824a3dba673df4894a71193ec32aa399' (2023-02-22)
  → 'github:reckenrode/nix-foundryvtt/440d3502d17c45d8dfeee5c1833d1ff03525a07b' (2023-07-06)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/f294325aed382b66c7a188482101b0f336d1d7db' (2023-04-16)
  → 'github:nixos/nixpkgs/ef99fa5c5ed624460217c31ac4271cfb5cb2502c' (2023-07-25)
• Updated input 'nvfetcher':
    'github:berberman/nvfetcher/0a9ac5fd07b52467d81163b1f8c94c12e5c9aff9' (2023-01-06)
  → 'github:berberman/nvfetcher/44196458acc2c28c32e456c50277d6148e71e708' (2023-06-22)
• Updated input 'nvfetcher/flake-compat':
    'github:edolstra/flake-compat/009399224d5e398d03b22badca40a37ac85412a1' (2022-11-17)
  → 'github:edolstra/flake-compat/35bb57c0c8d8b62bbfd284272c928ceb64ddbde9' (2023-01-17)
• Updated input 'nvfetcher/flake-utils':
    'github:numtide/flake-utils/5aed5285a952e0b949eb3ba02c12fa4fcfef535f' (2022-11-02)
  → 'github:numtide/flake-utils/abfb11bd1aec8ced1c9bb9adfe68018230f4fb3c' (2023-06-19)
• Added input 'nvfetcher/flake-utils/systems':
    'github:nix-systems/default/da67096a3b9bf56a91d16901293e51ba5b49a27e' (2023-04-09)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/de6514f8fe1b3c2b57307569a0898bc4be9ae1c5' (2023-04-17)
  → 'github:Mic92/sops-nix/c36df4fe4bf4bb87759b1891cab21e7a05219500' (2023-07-24)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/1040ce5f652b586da95dfd80d48a745e107b9eac' (2023-04-16)
  → 'github:NixOS/nixpkgs/ce45b591975d070044ca24e3003c830d26fea1c8' (2023-07-22)
• Updated input 'tlaternet-webserver':
    'git+https://gitea.tlater.net/tlaternet/tlaternet.git?ref=refs%2fheads%2fmaster&rev=2ca66c4fe1b8cfdd5d873cadb2735cef555dacca' (2023-04-17)
  → 'git+https://gitea.tlater.net/tlaternet/tlaternet.git?ref=refs%2fheads%2fmaster&rev=c573a6f81827594ceeffbfa058659e2fc20e4a1e' (2023-06-13)
• Updated input 'tlaternet-webserver/dream2nix':
    'github:nix-community/dream2nix/34a80ab215f1f24068ea9c76f3a7e5bc19478653' (2023-04-04)
  → 'github:nix-community/dream2nix/0c064fa9dd025069cc215b0a8b4eb5ea734aceb0' (2023-06-06)
• Updated input 'tlaternet-webserver/dream2nix/crane':
    'github:ipetkov/crane/59b31b41a589c0a65e4a1f86b0e5eac68081468b' (2022-12-13)
  → 'github:ipetkov/crane/445a3d222947632b5593112bb817850e8a9cf737' (2023-04-11)
• Updated input 'tlaternet-webserver/dream2nix/drv-parts':
    'github:davhau/drv-parts/ced8a52f62b0a94244713df2225c05c85b416110' (2023-03-30)
  → 'github:davhau/drv-parts/e8c2ec1157dc1edb002989669a0dbd935f430201' (2023-04-05)
• Updated input 'tlaternet-webserver/fenix':
    'github:nix-community/fenix/0d8c0d08db5fe6e5d995f4584f991ad60bbb1673' (2023-04-17)
  → 'github:nix-community/fenix/6fbeedcd2fc1fba77152e13fd7492824d77a4060' (2023-06-13)
• Updated input 'tlaternet-webserver/fenix/rust-analyzer-src':
    'github:rust-lang/rust-analyzer/bab80dae445fd576cb4cc22ba208e9fbc39dc18d' (2023-04-16)
  → 'github:rust-lang/rust-analyzer/1f1fe81f0db301124b3026bd2940294526cdd852' (2023-06-12)
---
 flake.lock | 115 +++++++++++++++++++++++++++++++----------------------
 1 file changed, 67 insertions(+), 48 deletions(-)

diff --git a/flake.lock b/flake.lock
index 3fe3b91..590dec9 100644
--- a/flake.lock
+++ b/flake.lock
@@ -20,15 +20,16 @@
     "crane": {
       "flake": false,
       "locked": {
-        "lastModified": 1670900067,
-        "narHash": "sha256-VXVa+KBfukhmWizaiGiHRVX/fuk66P8dgSFfkVN4/MY=",
+        "lastModified": 1681175776,
+        "narHash": "sha256-7SsUy9114fryHAZ8p1L6G6YSu7jjz55FddEwa2U8XZc=",
         "owner": "ipetkov",
         "repo": "crane",
-        "rev": "59b31b41a589c0a65e4a1f86b0e5eac68081468b",
+        "rev": "445a3d222947632b5593112bb817850e8a9cf737",
         "type": "github"
       },
       "original": {
         "owner": "ipetkov",
+        "ref": "v0.12.1",
         "repo": "crane",
         "type": "github"
       }
@@ -40,11 +41,11 @@
         "utils": "utils"
       },
       "locked": {
-        "lastModified": 1674127017,
-        "narHash": "sha256-QO1xF7stu5ZMDLbHN30LFolMAwY6TVlzYvQoUs1RD68=",
+        "lastModified": 1686747123,
+        "narHash": "sha256-XUQK9kwHpTeilHoad7L4LjMCCyY13Oq383CoFADecRE=",
         "owner": "serokell",
         "repo": "deploy-rs",
-        "rev": "8c9ea9605eed20528bf60fae35a2b613b901fd77",
+        "rev": "724463b5a94daa810abfc64a4f87faef4e00f984",
         "type": "github"
       },
       "original": {
@@ -89,11 +90,11 @@
         "pruned-racket-catalog": "pruned-racket-catalog"
       },
       "locked": {
-        "lastModified": 1680605243,
-        "narHash": "sha256-dUrxj653kcLvjNKRI7NoTJoj+Q7G+vOYsl4iuwtnIWo=",
+        "lastModified": 1686064783,
+        "narHash": "sha256-qyptOk4vDut2JkRMJ+815eJNqqd8gIfjpz3l4WCCtMY=",
         "owner": "nix-community",
         "repo": "dream2nix",
-        "rev": "34a80ab215f1f24068ea9c76f3a7e5bc19478653",
+        "rev": "0c064fa9dd025069cc215b0a8b4eb5ea734aceb0",
         "type": "github"
       },
       "original": {
@@ -121,11 +122,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1680172861,
-        "narHash": "sha256-QMyI338xRxaHFDlCXdLCtgelGQX2PdlagZALky4ZXJ8=",
+        "lastModified": 1680698112,
+        "narHash": "sha256-FgnobN/DvCjEsc0UAZEAdPLkL4IZi2ZMnu2K2bUaElc=",
         "owner": "davhau",
         "repo": "drv-parts",
-        "rev": "ced8a52f62b0a94244713df2225c05c85b416110",
+        "rev": "e8c2ec1157dc1edb002989669a0dbd935f430201",
         "type": "github"
       },
       "original": {
@@ -143,11 +144,11 @@
         "rust-analyzer-src": "rust-analyzer-src"
       },
       "locked": {
-        "lastModified": 1681712564,
-        "narHash": "sha256-14QeQU5m1iJg4v+HnLnH1X5W2V1d0lHfaHxDJP/6aig=",
+        "lastModified": 1686637310,
+        "narHash": "sha256-sGfKyioVsxQppDM0eDO62wtFiz+bZOD0cBMMIEjqn4I=",
         "owner": "nix-community",
         "repo": "fenix",
-        "rev": "0d8c0d08db5fe6e5d995f4584f991ad60bbb1673",
+        "rev": "6fbeedcd2fc1fba77152e13fd7492824d77a4060",
         "type": "github"
       },
       "original": {
@@ -175,11 +176,11 @@
     "flake-compat_2": {
       "flake": false,
       "locked": {
-        "lastModified": 1668681692,
-        "narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=",
+        "lastModified": 1673956053,
+        "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
         "owner": "edolstra",
         "repo": "flake-compat",
-        "rev": "009399224d5e398d03b22badca40a37ac85412a1",
+        "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
         "type": "github"
       },
       "original": {
@@ -227,12 +228,15 @@
       }
     },
     "flake-utils": {
+      "inputs": {
+        "systems": "systems"
+      },
       "locked": {
-        "lastModified": 1667395993,
-        "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
+        "lastModified": 1687171271,
+        "narHash": "sha256-BJlq+ozK2B1sJDQXS3tzJM5a+oVZmi1q0FlBK/Xqv7M=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
+        "rev": "abfb11bd1aec8ced1c9bb9adfe68018230f4fb3c",
         "type": "github"
       },
       "original": {
@@ -263,11 +267,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1677026752,
-        "narHash": "sha256-cYeFDzb0kmKQhBuN0vYWoLulCqj3vf7QhvnsPBO66vc=",
+        "lastModified": 1688686059,
+        "narHash": "sha256-1q+xdGil+mVkIMHovLv8bkXvwLjk92X6t0bvTpZVYb0=",
         "owner": "reckenrode",
         "repo": "nix-foundryvtt",
-        "rev": "6c52bfc6824a3dba673df4894a71193ec32aa399",
+        "rev": "440d3502d17c45d8dfeee5c1833d1ff03525a07b",
         "type": "github"
       },
       "original": {
@@ -357,27 +361,27 @@
     },
     "nixpkgs-stable": {
       "locked": {
-        "lastModified": 1681613598,
-        "narHash": "sha256-Ogkoma0ytYcDoMR2N7CZFABPo+i0NNo26dPngru9tPc=",
+        "lastModified": 1690066826,
+        "narHash": "sha256-6L2qb+Zc0BFkh72OS9uuX637gniOjzU6qCDBpjB2LGY=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "1040ce5f652b586da95dfd80d48a745e107b9eac",
+        "rev": "ce45b591975d070044ca24e3003c830d26fea1c8",
         "type": "github"
       },
       "original": {
         "owner": "NixOS",
-        "ref": "release-22.11",
+        "ref": "release-23.05",
         "repo": "nixpkgs",
         "type": "github"
       }
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1681648924,
-        "narHash": "sha256-pzi3HISK8+7mpEtv08Yr80wswyHKsz+RP1CROG1Qf6s=",
+        "lastModified": 1690272529,
+        "narHash": "sha256-MakzcKXEdv/I4qJUtq/k/eG+rVmyOZLnYNC2w1mB59Y=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "f294325aed382b66c7a188482101b0f336d1d7db",
+        "rev": "ef99fa5c5ed624460217c31ac4271cfb5cb2502c",
         "type": "github"
       },
       "original": {
@@ -404,16 +408,16 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1681696129,
-        "narHash": "sha256-Ba2y1lmsWmmAOAoTD5G9UnTS/UqV0ZFyzysgdfu7qag=",
+        "lastModified": 1690370995,
+        "narHash": "sha256-9z//23jGegLJrf3ITStLwVf715O39dq5u48Kr/XW14U=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "de66115c552acc4e0c0f92c5a5efb32e37dfa216",
+        "rev": "f3fbbc36b4e179a5985b9ab12624e9dfe7989341",
         "type": "github"
       },
       "original": {
         "owner": "nixos",
-        "ref": "nixos-22.11",
+        "ref": "nixos-23.05",
         "repo": "nixpkgs",
         "type": "github"
       }
@@ -442,11 +446,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1672979485,
-        "narHash": "sha256-LrY0K1yya3nvRlGDc98wm68ozVj7E6a1EXXEr7eHp8E=",
+        "lastModified": 1687440270,
+        "narHash": "sha256-aOAXvfVn+MBSkU+xlQEiyoGpRaF6NvQdpWIhw5OH/Dc=",
         "owner": "berberman",
         "repo": "nvfetcher",
-        "rev": "0a9ac5fd07b52467d81163b1f8c94c12e5c9aff9",
+        "rev": "44196458acc2c28c32e456c50277d6148e71e708",
         "type": "github"
       },
       "original": {
@@ -530,11 +534,11 @@
     "rust-analyzer-src": {
       "flake": false,
       "locked": {
-        "lastModified": 1681679582,
-        "narHash": "sha256-bijdVXzzfVSMHCjRuQ+PysNJt0Ei2mIhs+CPnR6yP4w=",
+        "lastModified": 1686586902,
+        "narHash": "sha256-+zfBFBmUxWutKbhdntI9uvF4D5Rh7BhcByM2l+ReyTw=",
         "owner": "rust-lang",
         "repo": "rust-analyzer",
-        "rev": "bab80dae445fd576cb4cc22ba208e9fbc39dc18d",
+        "rev": "1f1fe81f0db301124b3026bd2940294526cdd852",
         "type": "github"
       },
       "original": {
@@ -552,11 +556,11 @@
         "nixpkgs-stable": "nixpkgs-stable"
       },
       "locked": {
-        "lastModified": 1681721408,
-        "narHash": "sha256-NWCbZKOQEXz1hA2YDFxdd+fVrrw9edbG1DvbbLf7KUY=",
+        "lastModified": 1690199016,
+        "narHash": "sha256-yTLL72q6aqGmzHq+C3rDp3rIjno7EJZkFLof6Ika7cE=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "de6514f8fe1b3c2b57307569a0898bc4be9ae1c5",
+        "rev": "c36df4fe4bf4bb87759b1891cab21e7a05219500",
         "type": "github"
       },
       "original": {
@@ -565,6 +569,21 @@
         "type": "github"
       }
     },
+    "systems": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    },
     "tlaternet-webserver": {
       "inputs": {
         "dream2nix": "dream2nix",
@@ -574,11 +593,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1681761148,
-        "narHash": "sha256-eub9HQGCCjxOc+u4p9Om8y5EcVlBJOQOoK4APxXAbhc=",
+        "lastModified": 1686688441,
+        "narHash": "sha256-rcqAQzExGu0uV9Din8yy+Nn8FQvG/Itm8hp66amDj6o=",
         "ref": "refs/heads/master",
-        "rev": "2ca66c4fe1b8cfdd5d873cadb2735cef555dacca",
-        "revCount": 62,
+        "rev": "c573a6f81827594ceeffbfa058659e2fc20e4a1e",
+        "revCount": 66,
         "type": "git",
         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git"
       },

From ecbf382d4354a4b28aac026e9ca5a05a34ccc165 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 28 Jul 2023 11:23:35 +0200
Subject: [PATCH 098/212] Update to NixOS 23.05

---
 flake.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flake.nix b/flake.nix
index 4c8a805..801f601 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,7 +2,7 @@
   description = "tlater.net host configuration";
 
   inputs = {
-    nixpkgs.url = "github:nixos/nixpkgs/nixos-22.11";
+    nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
     nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
     deploy-rs.url = "github:serokell/deploy-rs";
     sops-nix = {

From 828d3f3878f71b642eb94abf204072abd7b93117 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 28 Jul 2023 11:23:56 +0200
Subject: [PATCH 099/212] services: Update outdated options

---
 configuration/default.nix            |  9 ++++++---
 configuration/services/gitea.nix     | 16 +++++++++-------
 configuration/services/nextcloud.nix |  2 +-
 3 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index f69ec09..1f7a276 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -108,11 +108,14 @@
   services.openssh = {
     enable = true;
     allowSFTP = false;
-    passwordAuthentication = false;
-    permitRootLogin = "no";
     ports = [2222];
     startWhenNeeded = true;
-    gatewayPorts = "yes";
+
+    settings = {
+      GatewayPorts = "yes";
+      PermitRootLogin = "no";
+      PasswordAuthentication = false;
+    };
   };
 
   security = {
diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index 1d3308a..c636078 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -2,18 +2,19 @@
   domain = "gitea.${config.services.nginx.domain}";
 in {
   services.gitea = {
-    inherit domain;
     enable = true;
-
-    httpAddress = "127.0.0.1";
     database.type = "postgres";
 
-    rootUrl = "https://${domain}/";
-
     appName = "Gitea: Git with a cup of tea";
 
     settings = {
-      server.SSH_PORT = 2222;
+      server = {
+        DOMAIN = domain;
+        HTTP_ADDR = "127.0.0.1";
+        ROOT_URL = "https://${domain}/";
+        SSH_PORT = 2222;
+      };
+
       service.DISABLE_REGISTRATION = true;
       session.COOKIE_SECURE = true;
     };
@@ -21,7 +22,8 @@ in {
 
   # Set up SSL
   services.nginx.virtualHosts."${domain}" = let
-    inherit (config.services.gitea) httpAddress httpPort;
+    httpAddress = config.services.gitea.settings.server.HTTP_ADDR;
+    httpPort = config.services.gitea.settings.server.HTTP_PORT;
   in {
     forceSSL = true;
     enableACME = true;
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index c25cfb2..4d81454 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -3,7 +3,7 @@
   config,
   ...
 }: let
-  nextcloud = pkgs.nextcloud25;
+  nextcloud = pkgs.nextcloud26;
   hostName = "nextcloud.${config.services.nginx.domain}";
 in {
   services.nextcloud = {

From 5aa7686ab5a9a59de9f156fc68c43a5d0d0d93d3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 28 Jul 2023 11:24:15 +0200
Subject: [PATCH 100/212] nextcloud: Update apps

---
 pkgs/_sources_nextcloud/generated.json | 32 +++++++++++++-------------
 pkgs/_sources_nextcloud/generated.nix  | 32 +++++++++++++-------------
 pkgs/nextcloud-apps.toml               |  4 +---
 3 files changed, 33 insertions(+), 35 deletions(-)

diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index 94d5c9a..e8bf16d 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -7,11 +7,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "1kdpma5f3rb9g29j364lqv6bkar5qgwlvcxmhpmzllwlkmjpc9w8",
+            "sha256": "sha256-aflxesvTOdNjPtHRtSPtImdmh4JmzM4s8iF5+lYYo3c=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/bookmarks/releases/download/v12.1.0/bookmarks-12.1.0.tar.gz"
+            "url": "https://github.com/nextcloud/bookmarks/releases/download/v13.0.1/bookmarks-13.0.1.tar.gz"
         },
-        "version": "12.1.0"
+        "version": "13.0.1"
     },
     "calendar": {
         "cargoLocks": null,
@@ -21,11 +21,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "0xhrpadzz73rdjyk4y1xm5hwc6k104rlpp9nmw08pq8phpfs12qa",
+            "sha256": "sha256-OAsM65aBJUA8toRSr3/UsdSTq/Rgn43s4nOabqoEoAI=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.3.3/calendar-v4.3.3.tar.gz"
+            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.4.3/calendar-v4.4.3.tar.gz"
         },
-        "version": "v4.3.3"
+        "version": "v4.4.3"
     },
     "contacts": {
         "cargoLocks": null,
@@ -35,11 +35,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "1rdql3m7pg9m044hppyrm3xw329y8h0pzwcmpcinjbjs0vqjssxk",
+            "sha256": "sha256-aG2wD4ioDYXwbyzZBpsEzz0PNvuF95V0JdJNw+kbMzk=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/contacts/releases/download/v5.2.0/contacts-v5.2.0.tar.gz"
+            "url": "https://github.com/nextcloud-releases/contacts/releases/download/v5.3.2/contacts-v5.3.2.tar.gz"
         },
-        "version": "v5.2.0"
+        "version": "v5.3.2"
     },
     "cookbook": {
         "cargoLocks": null,
@@ -49,7 +49,7 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "18rzvdqd99nlkk3p0y9y8b17ihw5c4c9wsx8psq6xadspm97002y",
+            "sha256": "sha256-XgBwUr26qW6wvqhrnhhhhcN4wkI+eXDHnNSm1HDbP6M=",
             "type": "tarball",
             "url": "https://github.com/nextcloud/cookbook/releases/download/v0.10.2/Cookbook-0.10.2.tar.gz"
         },
@@ -63,11 +63,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "026ggjf6dqbjv8hnj6jj1nnqz0256ck2yg13zhln7zc84lhfzlfd",
+            "sha256": "sha256-hhXPEITSbCiFs0o+TOsQnSasXBpjU9mA/OFsbzuaCPw=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/news/releases/download/21.1.0/news.tar.gz"
+            "url": "https://github.com/nextcloud/news/releases/download/22.0.0/news.tar.gz"
         },
-        "version": "21.1.0"
+        "version": "22.0.0"
     },
     "notes": {
         "cargoLocks": null,
@@ -77,10 +77,10 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "0klqf8dixrrb8yp8cc60ggnvhmqb3yh9f6y1281jn8ia5jml622v",
+            "sha256": "sha256-7GkTGyGTvtDbZsq/zOdbBE7xh6DZO183W6I5XX1ekbw=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/notes/releases/download/v4.7.2/notes.tar.gz"
+            "url": "https://github.com/nextcloud/notes/releases/download/v4.8.1/notes.tar.gz"
         },
-        "version": "v4.7.2"
+        "version": "v4.8.1"
     }
 }
\ No newline at end of file
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index c29f6b5..bab2e14 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -3,26 +3,26 @@
 {
   bookmarks = {
     pname = "bookmarks";
-    version = "12.1.0";
+    version = "13.0.1";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/bookmarks/releases/download/v12.1.0/bookmarks-12.1.0.tar.gz";
-      sha256 = "1kdpma5f3rb9g29j364lqv6bkar5qgwlvcxmhpmzllwlkmjpc9w8";
+      url = "https://github.com/nextcloud/bookmarks/releases/download/v13.0.1/bookmarks-13.0.1.tar.gz";
+      sha256 = "sha256-aflxesvTOdNjPtHRtSPtImdmh4JmzM4s8iF5+lYYo3c=";
     };
   };
   calendar = {
     pname = "calendar";
-    version = "v4.3.3";
+    version = "v4.4.3";
     src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.3.3/calendar-v4.3.3.tar.gz";
-      sha256 = "0xhrpadzz73rdjyk4y1xm5hwc6k104rlpp9nmw08pq8phpfs12qa";
+      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.4.3/calendar-v4.4.3.tar.gz";
+      sha256 = "sha256-OAsM65aBJUA8toRSr3/UsdSTq/Rgn43s4nOabqoEoAI=";
     };
   };
   contacts = {
     pname = "contacts";
-    version = "v5.2.0";
+    version = "v5.3.2";
     src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/contacts/releases/download/v5.2.0/contacts-v5.2.0.tar.gz";
-      sha256 = "1rdql3m7pg9m044hppyrm3xw329y8h0pzwcmpcinjbjs0vqjssxk";
+      url = "https://github.com/nextcloud-releases/contacts/releases/download/v5.3.2/contacts-v5.3.2.tar.gz";
+      sha256 = "sha256-aG2wD4ioDYXwbyzZBpsEzz0PNvuF95V0JdJNw+kbMzk=";
     };
   };
   cookbook = {
@@ -30,23 +30,23 @@
     version = "0.10.2";
     src = fetchTarball {
       url = "https://github.com/nextcloud/cookbook/releases/download/v0.10.2/Cookbook-0.10.2.tar.gz";
-      sha256 = "18rzvdqd99nlkk3p0y9y8b17ihw5c4c9wsx8psq6xadspm97002y";
+      sha256 = "sha256-XgBwUr26qW6wvqhrnhhhhcN4wkI+eXDHnNSm1HDbP6M=";
     };
   };
   news = {
     pname = "news";
-    version = "21.1.0";
+    version = "22.0.0";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/news/releases/download/21.1.0/news.tar.gz";
-      sha256 = "026ggjf6dqbjv8hnj6jj1nnqz0256ck2yg13zhln7zc84lhfzlfd";
+      url = "https://github.com/nextcloud/news/releases/download/22.0.0/news.tar.gz";
+      sha256 = "sha256-hhXPEITSbCiFs0o+TOsQnSasXBpjU9mA/OFsbzuaCPw=";
     };
   };
   notes = {
     pname = "notes";
-    version = "v4.7.2";
+    version = "v4.8.1";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/notes/releases/download/v4.7.2/notes.tar.gz";
-      sha256 = "0klqf8dixrrb8yp8cc60ggnvhmqb3yh9f6y1281jn8ia5jml622v";
+      url = "https://github.com/nextcloud/notes/releases/download/v4.8.1/notes.tar.gz";
+      sha256 = "sha256-7GkTGyGTvtDbZsq/zOdbBE7xh6DZO183W6I5XX1ekbw=";
     };
   };
 }
diff --git a/pkgs/nextcloud-apps.toml b/pkgs/nextcloud-apps.toml
index 709633d..69bccdc 100644
--- a/pkgs/nextcloud-apps.toml
+++ b/pkgs/nextcloud-apps.toml
@@ -1,8 +1,6 @@
 [bookmarks]
-# src.github = "nextcloud/bookmarks"
+src.github = "nextcloud/bookmarks"
 src.prefix = "v"
-# TODO(tlater): Remove when we update to nextcloud 26
-src.manual = "v12.1.0"
 fetch.tarball = "https://github.com/nextcloud/bookmarks/releases/download/v$ver/bookmarks-$ver.tar.gz"
 
 [calendar]

From 6b1e5dee567e0c3cfbc7a6d5567ebe7046d14bf9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 28 Jul 2023 12:05:59 +0200
Subject: [PATCH 101/212] deploy: Allow substituters

---
 flake.nix | 1 -
 1 file changed, 1 deletion(-)

diff --git a/flake.nix b/flake.nix
index 801f601..b6db610 100644
--- a/flake.nix
+++ b/flake.nix
@@ -62,7 +62,6 @@
 
       sshUser = "tlater";
       sshOpts = ["-p" "2222" "-o" "ForwardAgent=yes"];
-      fastConnection = true;
     };
 
     #########

From 88d96f198b60543c9fa00a55ee75973481497fb7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 28 Jul 2023 12:06:48 +0200
Subject: [PATCH 102/212] nextcloud: Apply recommended PHP setting

---
 configuration/services/nextcloud.nix | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 4d81454..207679a 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -1,6 +1,7 @@
 {
   pkgs,
   config,
+  options,
   ...
 }: let
   nextcloud = pkgs.nextcloud26;
@@ -27,6 +28,12 @@ in {
       defaultPhoneRegion = "AT";
     };
 
+    phpOptions =
+      options.services.nextcloud.phpOptions.default
+      // {
+        "opcache.interned_strings_buffer" = "16";
+      };
+
     extraApps = {
       inherit (pkgs.local) bookmarks calendar contacts cookbook news notes;
     };

From 0c5755d2f0293f9e975e966e52bab071ff408ab3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 29 Jul 2023 18:17:24 +0200
Subject: [PATCH 103/212] nextcloud: Upgrade to version 27

---
 configuration/services/nextcloud.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 207679a..133d1d1 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -4,7 +4,7 @@
   options,
   ...
 }: let
-  nextcloud = pkgs.nextcloud26;
+  nextcloud = pkgs.nextcloud27;
   hostName = "nextcloud.${config.services.nginx.domain}";
 in {
   services.nextcloud = {

From bb3ffbbd90d9465eeba20b59a32509b9dddcfb03 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 29 Jul 2023 18:17:39 +0200
Subject: [PATCH 104/212] nextcloud: Configure redis caching

---
 configuration/services/nextcloud.nix | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 133d1d1..7b87697 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -16,6 +16,8 @@ in {
     maxUploadSize = "2G";
     https = true;
 
+    configureRedis = true;
+
     config = {
       overwriteProtocol = "https";
 
@@ -37,12 +39,10 @@ in {
     extraApps = {
       inherit (pkgs.local) bookmarks calendar contacts cookbook news notes;
     };
-
-    # TODO(tlater): Add redis config. This will be much easier
-    # starting with 22.11, since this will add an `extraOptions` where
-    # the necessary redis config can go.
   };
 
+  services.redis.vmOverCommit = true;
+
   # Ensure that this service doesn't start before postgres is ready
   systemd.services.nextcloud-setup.after = ["postgresql.service"];
 

From 01b0327ca0ac865256b8995f5c8725f9f4f2e2c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 17 Sep 2023 21:25:14 +0200
Subject: [PATCH 105/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'deploy-rs':
    'github:serokell/deploy-rs/724463b5a94daa810abfc64a4f87faef4e00f984' (2023-06-14)
  → 'github:serokell/deploy-rs/31c32fb2959103a796e07bbe47e0a5e287c343a8' (2023-09-12)
• Updated input 'foundryvtt':
    'github:reckenrode/nix-foundryvtt/440d3502d17c45d8dfeee5c1833d1ff03525a07b' (2023-07-06)
  → 'github:reckenrode/nix-foundryvtt/3358ccef0ea3e06faabe8c54761fb8a0862b80d4' (2023-08-10)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/f3fbbc36b4e179a5985b9ab12624e9dfe7989341' (2023-07-26)
  → 'github:nixos/nixpkgs/5d017a8822e0907fb96f7700a319f9fe2434de02' (2023-09-17)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/ef99fa5c5ed624460217c31ac4271cfb5cb2502c' (2023-07-25)
  → 'github:nixos/nixpkgs/ace5093e36ab1e95cb9463863491bee90d5a4183' (2023-09-15)
• Updated input 'nvfetcher':
    'github:berberman/nvfetcher/44196458acc2c28c32e456c50277d6148e71e708' (2023-06-22)
  → 'github:berberman/nvfetcher/2bcf73dea96497ac9c36ed320b457caa705f9485' (2023-09-01)
• Updated input 'nvfetcher/flake-utils':
    'github:numtide/flake-utils/abfb11bd1aec8ced1c9bb9adfe68018230f4fb3c' (2023-06-19)
  → 'github:numtide/flake-utils/f9e7cf818399d17d347f847525c5a5a8032e4e44' (2023-08-23)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/c36df4fe4bf4bb87759b1891cab21e7a05219500' (2023-07-24)
  → 'github:Mic92/sops-nix/ea208e55f8742fdcc0986b256bdfa8986f5e4415' (2023-09-12)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/ce45b591975d070044ca24e3003c830d26fea1c8' (2023-07-22)
  → 'github:NixOS/nixpkgs/5601118d39ca9105f8e7b39d4c221d3388c0419d' (2023-09-02)
---
 flake.lock | 48 ++++++++++++++++++++++++------------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/flake.lock b/flake.lock
index 590dec9..b64bc75 100644
--- a/flake.lock
+++ b/flake.lock
@@ -41,11 +41,11 @@
         "utils": "utils"
       },
       "locked": {
-        "lastModified": 1686747123,
-        "narHash": "sha256-XUQK9kwHpTeilHoad7L4LjMCCyY13Oq383CoFADecRE=",
+        "lastModified": 1694513707,
+        "narHash": "sha256-wE5kHco3+FQjc+MwTPwLVqYz4hM7uno2CgXDXUFMCpc=",
         "owner": "serokell",
         "repo": "deploy-rs",
-        "rev": "724463b5a94daa810abfc64a4f87faef4e00f984",
+        "rev": "31c32fb2959103a796e07bbe47e0a5e287c343a8",
         "type": "github"
       },
       "original": {
@@ -232,11 +232,11 @@
         "systems": "systems"
       },
       "locked": {
-        "lastModified": 1687171271,
-        "narHash": "sha256-BJlq+ozK2B1sJDQXS3tzJM5a+oVZmi1q0FlBK/Xqv7M=",
+        "lastModified": 1692799911,
+        "narHash": "sha256-3eihraek4qL744EvQXsK1Ha6C3CR7nnT8X2qWap4RNk=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "abfb11bd1aec8ced1c9bb9adfe68018230f4fb3c",
+        "rev": "f9e7cf818399d17d347f847525c5a5a8032e4e44",
         "type": "github"
       },
       "original": {
@@ -267,11 +267,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1688686059,
-        "narHash": "sha256-1q+xdGil+mVkIMHovLv8bkXvwLjk92X6t0bvTpZVYb0=",
+        "lastModified": 1691701569,
+        "narHash": "sha256-7TK+sO+JC37OGTQDTiz9TriqbB5yTgoo7fyPyLtWvd8=",
         "owner": "reckenrode",
         "repo": "nix-foundryvtt",
-        "rev": "440d3502d17c45d8dfeee5c1833d1ff03525a07b",
+        "rev": "3358ccef0ea3e06faabe8c54761fb8a0862b80d4",
         "type": "github"
       },
       "original": {
@@ -361,11 +361,11 @@
     },
     "nixpkgs-stable": {
       "locked": {
-        "lastModified": 1690066826,
-        "narHash": "sha256-6L2qb+Zc0BFkh72OS9uuX637gniOjzU6qCDBpjB2LGY=",
+        "lastModified": 1693675694,
+        "narHash": "sha256-2pIOyQwGyy2FtFAUIb8YeKVmOCcPOTVphbAvmshudLE=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "ce45b591975d070044ca24e3003c830d26fea1c8",
+        "rev": "5601118d39ca9105f8e7b39d4c221d3388c0419d",
         "type": "github"
       },
       "original": {
@@ -377,11 +377,11 @@
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1690272529,
-        "narHash": "sha256-MakzcKXEdv/I4qJUtq/k/eG+rVmyOZLnYNC2w1mB59Y=",
+        "lastModified": 1694767346,
+        "narHash": "sha256-5uH27SiVFUwsTsqC5rs3kS7pBoNhtoy9QfTP9BmknGk=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "ef99fa5c5ed624460217c31ac4271cfb5cb2502c",
+        "rev": "ace5093e36ab1e95cb9463863491bee90d5a4183",
         "type": "github"
       },
       "original": {
@@ -408,11 +408,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1690370995,
-        "narHash": "sha256-9z//23jGegLJrf3ITStLwVf715O39dq5u48Kr/XW14U=",
+        "lastModified": 1694937365,
+        "narHash": "sha256-iHZSGrb9gVpZRR4B2ishUN/1LRKWtSHZNO37C8z1SmA=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "f3fbbc36b4e179a5985b9ab12624e9dfe7989341",
+        "rev": "5d017a8822e0907fb96f7700a319f9fe2434de02",
         "type": "github"
       },
       "original": {
@@ -446,11 +446,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1687440270,
-        "narHash": "sha256-aOAXvfVn+MBSkU+xlQEiyoGpRaF6NvQdpWIhw5OH/Dc=",
+        "lastModified": 1693539235,
+        "narHash": "sha256-ACmCq1+RnVq+EB7yeN6fThUR3cCJZb6lKEfv937WG84=",
         "owner": "berberman",
         "repo": "nvfetcher",
-        "rev": "44196458acc2c28c32e456c50277d6148e71e708",
+        "rev": "2bcf73dea96497ac9c36ed320b457caa705f9485",
         "type": "github"
       },
       "original": {
@@ -556,11 +556,11 @@
         "nixpkgs-stable": "nixpkgs-stable"
       },
       "locked": {
-        "lastModified": 1690199016,
-        "narHash": "sha256-yTLL72q6aqGmzHq+C3rDp3rIjno7EJZkFLof6Ika7cE=",
+        "lastModified": 1694495315,
+        "narHash": "sha256-sZEYXs9T1NVHZSSbMqBEtEm2PGa7dEDcx0ttQkArORc=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "c36df4fe4bf4bb87759b1891cab21e7a05219500",
+        "rev": "ea208e55f8742fdcc0986b256bdfa8986f5e4415",
         "type": "github"
       },
       "original": {

From 355ae4b70bd32bae21ce199c3253c2b51e04be9f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 18 Sep 2023 04:17:07 +0200
Subject: [PATCH 106/212] nextcloud: Update apps

---
 pkgs/_sources_nextcloud/generated.json | 24 ++++++++++++------------
 pkgs/_sources_nextcloud/generated.nix  | 24 ++++++++++++------------
 2 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index e8bf16d..1e731e8 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -7,11 +7,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-aflxesvTOdNjPtHRtSPtImdmh4JmzM4s8iF5+lYYo3c=",
+            "sha256": "sha256-7baI+vGBg48vZKZY0ikme+4PQl+PLUlC6JE0Air2s5E=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/bookmarks/releases/download/v13.0.1/bookmarks-13.0.1.tar.gz"
+            "url": "https://github.com/nextcloud/bookmarks/releases/download/v13.1.1/bookmarks-13.1.1.tar.gz"
         },
-        "version": "13.0.1"
+        "version": "13.1.1"
     },
     "calendar": {
         "cargoLocks": null,
@@ -21,11 +21,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-OAsM65aBJUA8toRSr3/UsdSTq/Rgn43s4nOabqoEoAI=",
+            "sha256": "sha256-8KwFmnFFlyYzKy2acCCjmpRj2W5pOrbQaPRPm16ZZ7g=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.4.3/calendar-v4.4.3.tar.gz"
+            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.5.0/calendar-v4.5.0.tar.gz"
         },
-        "version": "v4.4.3"
+        "version": "v4.5.0"
     },
     "contacts": {
         "cargoLocks": null,
@@ -35,11 +35,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-aG2wD4ioDYXwbyzZBpsEzz0PNvuF95V0JdJNw+kbMzk=",
+            "sha256": "sha256-dNim0PqUlEGB6J/OTsOjyUZ2JhOBhXC60HhjTstmF4s=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/contacts/releases/download/v5.3.2/contacts-v5.3.2.tar.gz"
+            "url": "https://github.com/nextcloud-releases/contacts/releases/download/v5.4.0/contacts-v5.4.0.tar.gz"
         },
-        "version": "v5.3.2"
+        "version": "v5.4.0"
     },
     "cookbook": {
         "cargoLocks": null,
@@ -63,11 +63,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-hhXPEITSbCiFs0o+TOsQnSasXBpjU9mA/OFsbzuaCPw=",
+            "sha256": "sha256-WrLikMN8jxu+vav9Xn8J1wUoGN5wQeQGr5pbVT6GLck=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/news/releases/download/22.0.0/news.tar.gz"
+            "url": "https://github.com/nextcloud/news/releases/download/23.0.0/news.tar.gz"
         },
-        "version": "22.0.0"
+        "version": "23.0.0"
     },
     "notes": {
         "cargoLocks": null,
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index bab2e14..ecdbdf3 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -3,26 +3,26 @@
 {
   bookmarks = {
     pname = "bookmarks";
-    version = "13.0.1";
+    version = "13.1.1";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/bookmarks/releases/download/v13.0.1/bookmarks-13.0.1.tar.gz";
-      sha256 = "sha256-aflxesvTOdNjPtHRtSPtImdmh4JmzM4s8iF5+lYYo3c=";
+      url = "https://github.com/nextcloud/bookmarks/releases/download/v13.1.1/bookmarks-13.1.1.tar.gz";
+      sha256 = "sha256-7baI+vGBg48vZKZY0ikme+4PQl+PLUlC6JE0Air2s5E=";
     };
   };
   calendar = {
     pname = "calendar";
-    version = "v4.4.3";
+    version = "v4.5.0";
     src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.4.3/calendar-v4.4.3.tar.gz";
-      sha256 = "sha256-OAsM65aBJUA8toRSr3/UsdSTq/Rgn43s4nOabqoEoAI=";
+      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.5.0/calendar-v4.5.0.tar.gz";
+      sha256 = "sha256-8KwFmnFFlyYzKy2acCCjmpRj2W5pOrbQaPRPm16ZZ7g=";
     };
   };
   contacts = {
     pname = "contacts";
-    version = "v5.3.2";
+    version = "v5.4.0";
     src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/contacts/releases/download/v5.3.2/contacts-v5.3.2.tar.gz";
-      sha256 = "sha256-aG2wD4ioDYXwbyzZBpsEzz0PNvuF95V0JdJNw+kbMzk=";
+      url = "https://github.com/nextcloud-releases/contacts/releases/download/v5.4.0/contacts-v5.4.0.tar.gz";
+      sha256 = "sha256-dNim0PqUlEGB6J/OTsOjyUZ2JhOBhXC60HhjTstmF4s=";
     };
   };
   cookbook = {
@@ -35,10 +35,10 @@
   };
   news = {
     pname = "news";
-    version = "22.0.0";
+    version = "23.0.0";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/news/releases/download/22.0.0/news.tar.gz";
-      sha256 = "sha256-hhXPEITSbCiFs0o+TOsQnSasXBpjU9mA/OFsbzuaCPw=";
+      url = "https://github.com/nextcloud/news/releases/download/23.0.0/news.tar.gz";
+      sha256 = "sha256-WrLikMN8jxu+vav9Xn8J1wUoGN5wQeQGr5pbVT6GLck=";
     };
   };
   notes = {

From ab5e088016d6576cfb01a9b4d6a842995728a5d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 18 Sep 2023 04:17:16 +0200
Subject: [PATCH 107/212] conduit: Add Element X support

---
 configuration/services/conduit.nix | 28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
index 871b5e2..2d341b7 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit.nix
@@ -207,12 +207,28 @@ in {
       merge_slashes off;
     '';
 
-    locations."/_matrix" = {
-      proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}";
-      # Recommended by conduit
-      extraConfig = ''
-        proxy_buffering off;
-      '';
+    locations = {
+      "/_matrix" = {
+        proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}";
+        # Recommended by conduit
+        extraConfig = ''
+          proxy_buffering off;
+        '';
+      };
+
+      # Add Element X support
+      # TODO(tlater): Remove when no longer required: https://github.com/vector-im/element-x-android/issues/1085
+      "=/.well-known/matrix/client" = {
+        alias = pkgs.writeText "well-known-matrix-client" (builtins.toJSON {
+          "m.homeserver".base_url = "https://${domain}";
+          "org.matrix.msc3575.proxy".url = "https://${domain}";
+        });
+
+        extraConfig = ''
+          default_type application/json;
+          add_header Access-Control-Allow-Origin "*";
+        '';
+      };
     };
   };
 }

From 87dd9daa4f6392c36504be8005422dc6bf0100fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 22 Sep 2023 06:20:36 +0200
Subject: [PATCH 108/212] backups: Add atomic backups with restic

---
 configuration/default.nix            |   1 +
 configuration/services/backups.nix   | 229 +++++++++++++++++++++++++++
 configuration/services/conduit.nix   |  10 ++
 configuration/services/gitea.nix     |  26 ++-
 configuration/services/nextcloud.nix |  29 ++++
 configuration/services/starbound.nix |   8 +
 configuration/sops.nix               |   6 +
 keys/production.yaml                 |   6 +-
 keys/staging.yaml                    |   6 +-
 9 files changed, 316 insertions(+), 5 deletions(-)
 create mode 100644 configuration/services/backups.nix

diff --git a/configuration/default.nix b/configuration/default.nix
index 1f7a276..5d491af 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -14,6 +14,7 @@
     "${modulesPath}/profiles/minimal.nix"
     (import ../modules)
 
+    ./services/backups.nix
     ./services/conduit.nix
     ./services/foundryvtt.nix
     ./services/gitea.nix
diff --git a/configuration/services/backups.nix b/configuration/services/backups.nix
new file mode 100644
index 0000000..3635a83
--- /dev/null
+++ b/configuration/services/backups.nix
@@ -0,0 +1,229 @@
+{
+  config,
+  pkgs,
+  lib,
+  ...
+}: let
+  inherit (lib) types optional singleton;
+  mkShutdownScript = service:
+    pkgs.writeShellScript "backup-${service}-shutdown" ''
+      if systemctl is-active --quiet '${service}'; then
+        touch '/tmp/${service}-was-active'
+        systemctl stop '${service}'
+      fi
+    '';
+  mkRestartScript = service:
+    pkgs.writeShellScript "backup-${service}-restart" ''
+      if [ -f '/tmp/${service}-was-active' ]; then
+        rm '/tmp/${service}-was-active'
+        systemctl start '${service}'
+      fi
+    '';
+  writeScript = name: packages: text:
+    lib.getExe (pkgs.writeShellApplication {
+      inherit name text;
+      runtimeInputs = packages;
+    });
+in {
+  options = {
+    services.backups = lib.mkOption {
+      description = lib.mdDoc ''
+        Configure restic backups with a specific tag.
+      '';
+      type = types.attrsOf (types.submodule ({
+        config,
+        name,
+        ...
+      }: {
+        options = {
+          user = lib.mkOption {
+            type = types.str;
+            description = ''
+              The user as which to run the backup.
+            '';
+          };
+          paths = lib.mkOption {
+            type = types.listOf types.str;
+            description = ''
+              The paths to back up.
+            '';
+          };
+          tag = lib.mkOption {
+            type = types.str;
+            description = ''
+              The restic tag to mark the backup with.
+            '';
+            default = name;
+          };
+          preparation = {
+            packages = lib.mkOption {
+              type = types.listOf types.package;
+              default = [];
+              description = ''
+                The list of packages to make available in the
+                preparation script.
+              '';
+            };
+            text = lib.mkOption {
+              type = types.nullOr types.str;
+              default = null;
+              description = ''
+                The preparation script to run before the backup.
+
+                This should include things like database dumps and
+                enabling maintenance modes. If a service needs to be
+                shut down for backups, use `pauseServices` instead.
+              '';
+            };
+          };
+          cleanup = {
+            packages = lib.mkOption {
+              type = types.listOf types.package;
+              default = [];
+              description = ''
+                The list of packages to make available in the
+                cleanup script.
+              '';
+            };
+            text = lib.mkOption {
+              type = types.nullOr types.str;
+              default = null;
+              description = ''
+                The cleanup script to run after the backup.
+
+                This should do things like cleaning up database dumps
+                and disabling maintenance modes.
+              '';
+            };
+          };
+          pauseServices = lib.mkOption {
+            type = types.listOf types.str;
+            default = [];
+            description = ''
+              The systemd services that need to be shut down before
+              the backup can run. Services will be restarted after the
+              backup is complete.
+
+              This is intended to be used for services that do not
+              support hot backups.
+            '';
+          };
+        };
+      }));
+    };
+  };
+
+  config = lib.mkIf (config.services.backups != {}) {
+    systemd.services =
+      {
+        restic-prune = {
+          # Doesn't hurt to finish the ongoing prune
+          restartIfChanged = false;
+
+          environment = {
+            RESTIC_PASSWORD_FILE = config.sops.secrets."restic/local-backups".path;
+            RESTIC_REPOSITORY = "/var/lib/backups/";
+            RESTIC_CACHE_DIR = "%C/restic-prune";
+          };
+
+          path = with pkgs; [
+            restic
+          ];
+
+          script = ''
+            # TODO(tlater): In an append-only setup, we should be
+            # careful with this; an attacker could delete backups by
+            # simply appending ad infinitum:
+            # https://restic.readthedocs.io/en/stable/060_forget.html#security-considerations-in-append-only-mode
+            restic forget --keep-last 3 --prune
+            restic check
+          '';
+
+          serviceConfig = {
+            DynamicUser = true;
+            Group = "backup";
+
+            CacheDirectory = "restic-prune";
+            CacheDirectoryMode = "0700";
+            ReadWritePaths = "/var/lib/backups/";
+
+            # Ensure we don't leave behind any files with the
+            # temporary UID of this service.
+            ExecStopPost = "+${pkgs.coreutils}/bin/chown -R root:backup /var/lib/backups/";
+          };
+        };
+      }
+      // lib.mapAttrs' (name: backup:
+        lib.nameValuePair "backup-${name}" {
+          # Don't want to restart mid-backup
+          restartIfChanged = false;
+
+          environment = {
+            RESTIC_CACHE_DIR = "%C/backup-${name}";
+            RESTIC_PASSWORD_FILE = config.sops.secrets."restic/local-backups".path;
+            # TODO(tlater): If I ever add more than one repo, service
+            # shutdown/restarting will potentially break if multiple
+            # backups for the same service overlap. A more clever
+            # sentinel file with reference counts would probably solve
+            # this.
+            RESTIC_REPOSITORY = "/var/lib/backups/";
+          };
+
+          serviceConfig = {
+            User = backup.user;
+            Group = "backup";
+            RuntimeDirectory = "backup-${name}";
+            CacheDirectory = "backup-${name}";
+            CacheDirectoryMode = "0700";
+            PrivateTmp = true;
+
+            ExecStart = [
+              (lib.concatStringsSep " " (["${pkgs.restic}/bin/restic" "backup" "--tag" name] ++ backup.paths))
+            ];
+
+            ExecStartPre =
+              map (service: "+${mkShutdownScript service}") backup.pauseServices
+              ++ singleton (writeScript "backup-${name}-repo-init" [pkgs.restic pkgs.coreutils] ''
+                restic snapshots || (restic init && chmod -R g+rwx "$RESTIC_REPOSITORY"/*)
+              '')
+              ++ optional (backup.preparation.text != null)
+              (writeScript "backup-${name}-prepare" backup.preparation.packages backup.preparation.text);
+
+            # TODO(tlater): Add repo pruning/checking
+            ExecStopPost =
+              map (service: "+${mkRestartScript service}") backup.pauseServices
+              ++ optional (backup.cleanup.text != null)
+              (writeScript "backup-${name}-cleanup" backup.cleanup.packages backup.cleanup.text);
+          };
+        })
+      config.services.backups;
+
+    systemd.timers =
+      {
+        restic-prune = {
+          wantedBy = ["timers.target"];
+          timerConfig.OnCalendar = "Thursday 03:00:00 UTC";
+          # Don't make this persistent, in case the server was offline
+          # for a while. This job cannot run at the same time as any
+          # of the backup jobs.
+        };
+      }
+      // lib.mapAttrs' (name: backup:
+        lib.nameValuePair "backup-${name}" {
+          wantedBy = ["timers.target"];
+          timerConfig = {
+            OnCalendar = "Wednesday 02:30:00 UTC";
+            RandomizedDelaySec = "1h";
+            FixedRandomDelay = true;
+            Persistent = true;
+          };
+        })
+      config.services.backups;
+
+    users.groups.backup = {};
+
+    systemd.tmpfiles.rules = [
+      "d /var/lib/backups/ 0770 root backup"
+    ];
+  };
+}
diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
index 2d341b7..3f8fd40 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit.nix
@@ -231,4 +231,14 @@ in {
       };
     };
   };
+
+  services.backups.conduit = {
+    user = "root";
+    paths = [
+      "/var/lib/private/matrix-conduit/"
+    ];
+    # Other services store their data in conduit, so no other services
+    # need to be shut down currently.
+    pauseServices = ["conduit.service"];
+  };
 }
diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index c636078..27353f6 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -1,4 +1,8 @@
-{config, ...}: let
+{
+  pkgs,
+  config,
+  ...
+}: let
   domain = "gitea.${config.services.nginx.domain}";
 in {
   services.gitea = {
@@ -52,4 +56,24 @@ in {
       enabled = true
     '';
   };
+
+  services.backups.gitea = {
+    user = "gitea";
+    paths = [
+      "/var/lib/gitea/gitea-db.sql"
+      "/var/lib/gitea/repositories/"
+      "/var/lib/gitea/data/"
+      "/var/lib/gitea/custom/"
+      # Conf is backed up via nix
+    ];
+    preparation = {
+      packages = [config.services.postgresql.package];
+      text = "pg_dump ${config.services.gitea.database.name} --file=/var/lib/gitea/gitea-db.sql";
+    };
+    cleanup = {
+      packages = [pkgs.coreutils];
+      text = "rm /var/lib/gitea/gitea-db.sql";
+    };
+    pauseServices = ["gitea.service"];
+  };
 }
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 7b87697..fbca607 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -74,4 +74,33 @@ in {
       bantime = 86400
     '';
   };
+
+  services.backups.nextcloud = {
+    user = "nextcloud";
+    paths = [
+      "/var/lib/nextcloud/nextcloud-db.sql"
+      "/var/lib/nextcloud/data/"
+      "/var/lib/nextcloud/config/config.php"
+    ];
+    preparation = {
+      packages = [
+        config.services.postgresql.package
+        config.services.nextcloud.occ
+      ];
+      text = ''
+        nextcloud-occ maintenance:mode --on
+        pg_dump ${config.services.nextcloud.config.dbname} --file=/var/lib/nextcloud/nextcloud-db.sql
+      '';
+    };
+    cleanup = {
+      packages = [
+        pkgs.coreutils
+        config.services.nextcloud.occ
+      ];
+      text = ''
+        rm /var/lib/nextcloud/nextcloud-db.sql
+        nextcloud-occ maintenance:mode --off
+      '';
+    };
+  };
 }
diff --git a/configuration/services/starbound.nix b/configuration/services/starbound.nix
index 419f0e4..6da890e 100644
--- a/configuration/services/starbound.nix
+++ b/configuration/services/starbound.nix
@@ -110,4 +110,12 @@ in {
       # ProtectHome = "read-only"; # See further up
     };
   };
+
+  services.backups.starbound = {
+    user = "root";
+    paths = [
+      "/var/lib/private/starbound/storage/universe/"
+    ];
+    pauseServices = ["starbound.service"];
+  };
 }
diff --git a/configuration/sops.nix b/configuration/sops.nix
index 4becfd4..269fa58 100644
--- a/configuration/sops.nix
+++ b/configuration/sops.nix
@@ -19,6 +19,12 @@
         mode = "0440";
       };
 
+      "restic/local-backups" = {
+        owner = "root";
+        group = "backup";
+        mode = "0440";
+      };
+
       "turn/env" = {};
       "turn/secret" = {
         owner = "turnserver";
diff --git a/keys/production.yaml b/keys/production.yaml
index 6ef9ef7..f8d259d 100644
--- a/keys/production.yaml
+++ b/keys/production.yaml
@@ -7,6 +7,8 @@ heisenbridge:
     hs-token: ENC[AES256_GCM,data:u52WpkQFd/J7JFoE/rfNluebyZQLOokvkVdL7+AEAvrhJhrkJli1ztkD79lbC+6tGUH4tT3T+nX9wvGKnrRUQg==,iv:as+9fVuvMg2IoE2WIKD9mHi+znhNcWRh5Zq+yr0xcDQ=,tag:mZ7fh7U0MfgI8hyq/28Bcg==,type:str]
 wireguard:
     server-key: ENC[AES256_GCM,data:mXb7ZznJHf5CgV8rI4uzPBATMRbmd7LimgtCkQM9kAjbIaGwUBqJZBN3fXs=,iv:3Po1Orinzov9rnEm9cLzgJY1PeD+5Jl9115MriABHh8=,tag:E/2CjDO1JCvJzxCnqKcNyw==,type:str]
+restic:
+    local-backups: ENC[AES256_GCM,data:NLNVlR9G9bLSZOkMoPvkbBbAZlKkmiUbdWHOFDnaefuy9wNLH53ctOIyS0rSsQLaJCSBTpgPSWIIXUSuzoK/eA==,iv:DzuujmyJJP4GiE5z7KOOGUEzUgOwmtf/7UYhwkyLe9g=,tag:cElFhpVC7S6HYlB6UyN7PQ==,type:str]
 turn:
     env: ENC[AES256_GCM,data:kt5nhVo9pb/ZbPUEcqSYXxN9YMgQKnFb5VRfFFS/qoIaJ73uD2fuJKqcxAyVRrdLqnSAWSQBgTgunBzdP7xqLAK2qt8DYAQWHkIe9uxFbSXZpdmw,iv:9lq6SFwTFN4GGm6gPiJpUMasMdnHVF6XLGYrsyG3kjU=,tag:428Qf9DOiiHt/Wjb188b8g==,type:str]
     secret: ENC[AES256_GCM,data:si7ee6Xfhdgdyzbp6aQpF7pz3TmTBb7iQ82lRPVXNDg9JfHI+lbmgAsSnRLX5qMCA6P9R045sSMosqidL8QwRg==,iv:SrhpZKK8D45yxCEfDb9P3TwtA14+qEI+wcRqcN/a6pw=,tag:PiwV+mOL9xHJgJft6sc61g==,type:str]
@@ -19,8 +21,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2023-04-23T17:34:53Z"
-    mac: ENC[AES256_GCM,data:UaGB4uwmYGVbKud5KrvdKeYTnYrs8nnQsT590KIS/b/9JhpQo5JXFtHsm1AteEBg9ygmY6tYKDcK4AXwz/uR/m3CW5If03dBNG8F9Uy3dPL5KaebC/EsNVIaRavWTbSZgqhnBgYeM+HkeQPskSWuwviSNU0D7d1n98Q89Y0kQfA=,iv:kEsRh8hb1amd2qozyxwYHCHdX80c2mO5Mm7npKX3DKc=,tag:p5GPd0OZvowghT92pxxXeA==,type:str]
+    lastmodified: "2023-09-23T18:55:44Z"
+    mac: ENC[AES256_GCM,data:psqgXozY9L7nduZ11GF+mbIrZ4RUySqBixkWL5z0cYeoLA3URb/dr028LCmNgQS9l8aJVsjVkyLBJIU/8wmiUNqRy/VI5iqV5mu+sxXhUVwFL0dAAWP1lOKwwT5uGK89/ioqkphgzuWD37vGe2vYddKkJF0M+zlz12fqkMjaisU=,iv:UyRoJbfuGU3K/Mp5DQ1kY0Z+nKSSo46BGNAcxt+vAvc=,tag:HkP6+qxQ8J/xAYJXYoG/6g==,type:str]
     pgp:
         - created_at: "2022-10-12T00:46:51Z"
           enc: |
diff --git a/keys/staging.yaml b/keys/staging.yaml
index 49b5a6a..a6b0849 100644
--- a/keys/staging.yaml
+++ b/keys/staging.yaml
@@ -7,6 +7,8 @@ heisenbridge:
     hs-token: ENC[AES256_GCM,data:VBwvwomv0Xg=,iv:q6INtJ+rg+QiXj8uBdBzQYQZUBBXp+9odxDHwvu8Jxc=,tag:XKhm8nxygAkKaiVPJ2Fcdg==,type:str]
 wireguard:
     server-key: ENC[AES256_GCM,data:FvY897XdKoa/mckE8JQLCkklsnYD6Wz1wpsu5t3uhEnW3iarnDQxF9msuYU=,iv:jqGXfekM+Vs+J9b5nlZ5Skd1ZKHajoUo2Dc4tMYPm1w=,tag:EehikjI/FCU8wqtpvJRamQ==,type:str]
+restic:
+    local-backups: ENC[AES256_GCM,data:3QjEv03t7wE=,iv:y/6Lv4eUbZZfGPwUONykz8VNL62cAJuWaJy9yk3aAmk=,tag:wMlGsepuG9JjwtUKGWSibw==,type:str]
 turn:
     env: ENC[AES256_GCM,data:xjIz/AY109lyiL5N01p5T3HcYco/rM5CJSRTtg==,iv:16bW6OpyOK/QL0QPGQp/Baa9xyT8E3ZsYkwqmjuofk0=,tag:J5re3uKxIykw3YunvQWBgg==,type:str]
     secret: ENC[AES256_GCM,data:eQ7dAocoZtg=,iv:fgzjTPv30WqTKlLy+yMn5MsKQgjhPnwlGFFwYEg3gWs=,tag:1ze33U1NBkgMX/9SiaBNQg==,type:str]
@@ -19,8 +21,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2023-04-23T17:35:16Z"
-    mac: ENC[AES256_GCM,data:4cW8k6o3jET8k+yJGyApjOyuSUQb+d+4wX/RTNnpbt+867sExQrZUrOMif/u8S4WmcKVSJgvrzuxK9hpDPYhJ1d/5YuHH1Dyj7QDRdhbZYHhkpPus0ZVTEpSknZzx2eWH1ch/fyJJknlrBlfb/tz50Dv+w9mhkL7qteaIq+Vmsc=,iv:YMfAuGwu1kAM0wGkq3kzVMnC72yo7ZT04BuEwoLRPIA=,tag:6I1VRzteRaLuxN+sfLA5Mw==,type:str]
+    lastmodified: "2023-09-22T21:07:02Z"
+    mac: ENC[AES256_GCM,data:gItC41S8MInLmikdH1okhPs+FVf8sCF/iQeJ5reigBunHkOngoc6nOFANyAcNZETszzhgTLXXtmVNEjW46v6K7D6nmoi/zwpedUxwzMwDC5I28VTMDHVMAThYSGtdo6kig8i2pi8rzEQd1DStxMv3TWML5y6DDTlFsd3lfudaHA=,iv:zXebvIVPR76GwUhpactwRgF/eEmx2OBkT18E8lkwzRA=,tag:6HyISACbFCGlpIIgkFeA/A==,type:str]
     pgp:
         - created_at: "2022-10-12T16:48:23Z"
           enc: |

From 78a9eac9bb972e4a918a2642d64e369d67cfbb18 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 2 Oct 2023 01:02:28 +0200
Subject: [PATCH 109/212] sops: Sort secrets alphabetically

---
 configuration/sops.nix | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/configuration/sops.nix b/configuration/sops.nix
index 269fa58..bf98433 100644
--- a/configuration/sops.nix
+++ b/configuration/sops.nix
@@ -3,28 +3,27 @@
     defaultSopsFile = ../keys/production.yaml;
 
     secrets = {
+      # Heisenbridge
+      "heisenbridge/as-token" = {};
+      "heisenbridge/hs-token" = {};
+
+      # Nextcloud
       "nextcloud/tlater" = {
         owner = "nextcloud";
         group = "nextcloud";
       };
 
-      "steam/tlater" = {};
-
-      "heisenbridge/as-token" = {};
-      "heisenbridge/hs-token" = {};
-
-      "wireguard/server-key" = {
-        owner = "root";
-        group = "systemd-network";
-        mode = "0440";
-      };
-
+      # Restic
       "restic/local-backups" = {
         owner = "root";
         group = "backup";
         mode = "0440";
       };
 
+      # Steam
+      "steam/tlater" = {};
+
+      # Turn
       "turn/env" = {};
       "turn/secret" = {
         owner = "turnserver";
@@ -35,6 +34,13 @@
       "turn/ssl-cert" = {
         owner = "turnserver";
       };
+
+      # Wireguard
+      "wireguard/server-key" = {
+        owner = "root";
+        group = "systemd-network";
+        mode = "0440";
+      };
     };
   };
 }

From 55a4aaf48b2333104f3adb2d6f6bc3afe5bd1ed7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 7 Oct 2023 22:14:43 +0200
Subject: [PATCH 110/212] metrics: Add metrics with victoriametrics + grafana

---
 configuration/default.nix                     |  55 +++--
 configuration/services/conduit.nix            |   4 +
 configuration/services/fail2ban.nix           |  42 ++++
 configuration/services/foundryvtt.nix         |   1 +
 configuration/services/gitea.nix              |  22 ++
 configuration/services/metrics/default.nix    |   9 +
 configuration/services/metrics/exporters.nix  | 101 +++++++++
 configuration/services/metrics/grafana.nix    |  48 +++++
 configuration/services/metrics/options.nix    | 204 ++++++++++++++++++
 .../services/metrics/victoriametrics.nix      |  13 ++
 configuration/services/nextcloud.nix          |   3 +
 configuration/services/postgres.nix           |   7 +
 configuration/services/webserver.nix          |   1 +
 configuration/sops.nix                        |  17 ++
 flake.nix                                     |  10 +-
 keys/production.yaml                          |   9 +-
 keys/staging.yaml                             |   9 +-
 pkgs/_sources_pkgs/generated.json             |  21 ++
 pkgs/_sources_pkgs/generated.nix              |  16 ++
 pkgs/default.nix                              |   3 +
 pkgs/nvfetcher.toml                           |   3 +
 pkgs/prometheus/fail2ban-exporter.nix         |   8 +
 22 files changed, 580 insertions(+), 26 deletions(-)
 create mode 100644 configuration/services/fail2ban.nix
 create mode 100644 configuration/services/metrics/default.nix
 create mode 100644 configuration/services/metrics/exporters.nix
 create mode 100644 configuration/services/metrics/grafana.nix
 create mode 100644 configuration/services/metrics/options.nix
 create mode 100644 configuration/services/metrics/victoriametrics.nix
 create mode 100644 pkgs/_sources_pkgs/generated.json
 create mode 100644 pkgs/_sources_pkgs/generated.nix
 create mode 100644 pkgs/nvfetcher.toml
 create mode 100644 pkgs/prometheus/fail2ban-exporter.nix

diff --git a/configuration/default.nix b/configuration/default.nix
index 5d491af..81e7241 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -16,8 +16,10 @@
 
     ./services/backups.nix
     ./services/conduit.nix
+    ./services/fail2ban.nix
     ./services/foundryvtt.nix
     ./services/gitea.nix
+    ./services/metrics
     ./services/nextcloud.nix
     ./services/webserver.nix
     ./services/wireguard.nix
@@ -136,34 +138,45 @@
     recommendedProxySettings = true;
     clientMaxBodySize = "10G";
     domain = "tlater.net";
+
+    statusPage = true; # For metrics, should be accessible only from localhost
+
+    commonHttpConfig = ''
+      log_format upstream_time '$remote_addr - $remote_user [$time_local] '
+                         '"$request" $status $body_bytes_sent '
+                         '"$http_referer" "$http_user_agent" '
+                         'rt=$request_time uct="$upstream_connect_time" '
+                         'uht="$upstream_header_time" urt="$upstream_response_time"';
+    '';
   };
 
+  services.logrotate = {
+    enable = true;
+
+    settings = lib.mapAttrs' (virtualHost: _:
+      lib.nameValuePair "/var/log/nginx/${virtualHost}/access.log" {
+        frequency = "daily";
+        rotate = 2;
+        compress = true;
+        delaycompress = true;
+        su = "${config.services.nginx.user} ${config.services.nginx.group}";
+        postrotate = "[ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`";
+      })
+    config.services.nginx.virtualHosts;
+  };
+  systemd.tmpfiles.rules =
+    lib.mapAttrsToList (
+      virtualHost: _:
+      #
+      "d /var/log/nginx/${virtualHost} 0750 ${config.services.nginx.user} ${config.services.nginx.group}"
+    )
+    config.services.nginx.virtualHosts;
+
   security.acme = {
     defaults.email = "tm@tlater.net";
     acceptTerms = true;
   };
 
-  services.fail2ban = {
-    enable = true;
-    extraPackages = [pkgs.ipset];
-    banaction = "iptables-ipset-proto6-allports";
-    bantime-increment.enable = true;
-
-    jails = {
-      nginx-botsearch = ''
-        enabled = true
-        logpath = /var/log/nginx/access.log
-      '';
-    };
-
-    ignoreIP = [
-      "127.0.0.0/8"
-      "10.0.0.0/8"
-      "172.16.0.0/12"
-      "192.168.0.0/16"
-    ];
-  };
-
   # Remove some unneeded packages
   environment.defaultPackages = [];
 
diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
index 3f8fd40..8257592 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit.nix
@@ -173,6 +173,9 @@ in {
       # Various other security settings
       no-tlsv1
       no-tlsv1_1
+
+      # Monitoring
+      prometheus
     '';
   };
 
@@ -205,6 +208,7 @@ in {
     addSSL = true;
     extraConfig = ''
       merge_slashes off;
+      access_log /var/log/nginx/${domain}/access.log upstream_time;
     '';
 
     locations = {
diff --git a/configuration/services/fail2ban.nix b/configuration/services/fail2ban.nix
new file mode 100644
index 0000000..ace3219
--- /dev/null
+++ b/configuration/services/fail2ban.nix
@@ -0,0 +1,42 @@
+{pkgs, ...}: {
+  services.fail2ban = {
+    enable = true;
+    extraPackages = [pkgs.ipset];
+    banaction = "iptables-ipset-proto6-allports";
+    bantime-increment.enable = true;
+
+    jails = {
+      nginx-botsearch = ''
+        enabled = true
+        logpath = /var/log/nginx/access.log
+      '';
+    };
+
+    ignoreIP = [
+      "127.0.0.0/8"
+      "10.0.0.0/8"
+      "172.16.0.0/12"
+      "192.168.0.0/16"
+    ];
+  };
+
+  # Allow metrics services to connect to the socket as well
+  users.groups.fail2ban = {};
+  systemd.services.fail2ban.serviceConfig = {
+    ExecStartPost =
+      "+"
+      + (pkgs.writeShellScript "fail2ban-post-start" ''
+        while ! [ -S /var/run/fail2ban/fail2ban.sock ]; do
+            sleep 1
+        done
+
+        while ! ${pkgs.netcat}/bin/nc -zU /var/run/fail2ban/fail2ban.sock; do
+            sleep 1
+        done
+
+        ${pkgs.coreutils}/bin/chown root:fail2ban /var/run/fail2ban /var/run/fail2ban/fail2ban.sock
+        ${pkgs.coreutils}/bin/chmod 660 /var/run/fail2ban/fail2ban.sock
+        ${pkgs.coreutils}/bin/chmod 710 /var/run/fail2ban
+      '');
+  };
+}
diff --git a/configuration/services/foundryvtt.nix b/configuration/services/foundryvtt.nix
index 7bb2286..d573480 100644
--- a/configuration/services/foundryvtt.nix
+++ b/configuration/services/foundryvtt.nix
@@ -25,6 +25,7 @@ in {
     enableACME = true;
     extraConfig = ''
       add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
+      access_log /var/log/nginx/${domain}/access.log upstream_time;
     '';
 
     locations."/" = {
diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index 27353f6..013842e 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -1,6 +1,7 @@
 {
   pkgs,
   config,
+  lib,
   ...
 }: let
   domain = "gitea.${config.services.nginx.domain}";
@@ -19,11 +20,23 @@ in {
         SSH_PORT = 2222;
       };
 
+      metrics = {
+        ENABLED = true;
+        TOKEN = "#metricstoken#";
+      };
       service.DISABLE_REGISTRATION = true;
       session.COOKIE_SECURE = true;
     };
   };
 
+  systemd.services.gitea.serviceConfig.ExecStartPre = let
+    replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret";
+    secretPath = config.sops.secrets."gitea/metrics-token".path;
+    runConfig = "${config.services.gitea.customDir}/conf/app.ini";
+  in [
+    "+${replaceSecretBin} '#metricstoken#' '${secretPath}' '${runConfig}'"
+  ];
+
   # Set up SSL
   services.nginx.virtualHosts."${domain}" = let
     httpAddress = config.services.gitea.settings.server.HTTP_ADDR;
@@ -33,9 +46,18 @@ in {
     enableACME = true;
     extraConfig = ''
       add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
+      access_log /var/log/nginx/${domain}/access.log upstream_time;
     '';
 
     locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}";
+    locations."/metrics" = {
+      extraConfig = ''
+        access_log off;
+        allow 127.0.0.1;
+        ${lib.optionalString config.networking.enableIPv6 "allow ::1;"}
+        deny all;
+      '';
+    };
   };
 
   # Block repeated failed login attempts
diff --git a/configuration/services/metrics/default.nix b/configuration/services/metrics/default.nix
new file mode 100644
index 0000000..84e126a
--- /dev/null
+++ b/configuration/services/metrics/default.nix
@@ -0,0 +1,9 @@
+{
+  imports = [
+    ./options.nix
+
+    ./exporters.nix
+    ./grafana.nix
+    ./victoriametrics.nix
+  ];
+}
diff --git a/configuration/services/metrics/exporters.nix b/configuration/services/metrics/exporters.nix
new file mode 100644
index 0000000..f3054db
--- /dev/null
+++ b/configuration/services/metrics/exporters.nix
@@ -0,0 +1,101 @@
+{
+  config,
+  pkgs,
+  lib,
+  ...
+}: let
+  yaml = pkgs.formats.yaml {};
+in {
+  services.prometheus = {
+    exporters = {
+      # Periodically check domain registration status
+      domain = {
+        enable = true;
+        listenAddress = "127.0.0.1";
+        extraFlags = let
+          conf.domains = [
+            "tlater.net"
+            "tlater.com"
+          ];
+        in [
+          "--config=${yaml.generate "domains.yml" conf}"
+        ];
+      };
+
+      # System statistics
+      node = {
+        enable = true;
+        listenAddress = "127.0.0.1";
+      };
+      systemd = {
+        enable = true;
+        listenAddress = "127.0.0.1";
+        extraFlags = [
+          # Disabled by default because only supported from systemd 235+
+          "--systemd.collector.enable-restart-count"
+          "--systemd.collector.enable-ip-accounting"
+        ];
+      };
+
+      # Various nginx metrics
+      nginx = {
+        enable = true;
+        listenAddress = "127.0.0.1";
+      };
+
+      nginxlog = {
+        enable = true;
+        listenAddress = "127.0.0.1";
+        group = "nginx";
+
+        settings.namespaces =
+          lib.mapAttrsToList (name: virtualHost: {
+            inherit name;
+            metrics_override.prefix = "nginxlog";
+            namespace_label = "vhost";
+
+            format = lib.concatStringsSep " " [
+              "$remote_addr - $remote_user [$time_local]"
+              ''"$request" $status $body_bytes_sent''
+              ''"$http_referer" "$http_user_agent"''
+              ''rt=$request_time uct="$upstream_connect_time"''
+              ''uht="$upstream_header_time" urt="$upstream_response_time"''
+            ];
+
+            source.files = [
+              "/var/log/nginx/${name}/access.log"
+            ];
+          })
+          config.services.nginx.virtualHosts;
+      };
+    };
+
+    extraExporters = {
+      fail2ban = let
+        cfg = config.services.prometheus.extraExporters.fail2ban;
+      in {
+        port = 9191;
+        serviceOpts = {
+          after = ["fail2ban.service"];
+          requires = ["fail2ban.service"];
+          serviceConfig = {
+            Group = "fail2ban";
+            RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"];
+            ExecStart = lib.concatStringsSep " " [
+              "${pkgs.local.prometheus-fail2ban-exporter}/bin/fail2ban-prometheus-exporter"
+              "--collector.f2b.socket=/var/run/fail2ban/fail2ban.sock"
+              "--web.listen-address='${cfg.listenAddress}:${toString cfg.port}'"
+              "--collector.f2b.exit-on-socket-connection-error=true"
+            ];
+          };
+        };
+      };
+    };
+
+    # TODO(tlater):
+    #   - wireguard (?)
+    #   - postgres (?)
+    #   - blackbox (?) (curl to see if http and similar is up)
+    #   - ssl_exporter (?)
+  };
+}
diff --git a/configuration/services/metrics/grafana.nix b/configuration/services/metrics/grafana.nix
new file mode 100644
index 0000000..8538dc7
--- /dev/null
+++ b/configuration/services/metrics/grafana.nix
@@ -0,0 +1,48 @@
+{config, ...}: let
+  domain = "metrics.${config.services.nginx.domain}";
+in {
+  services.grafana = {
+    enable = true;
+    settings = {
+      server.http_port = 3001; # Default overlaps with gitea
+
+      security = {
+        admin_user = "tlater";
+        admin_password = "$__file{${config.sops.secrets."grafana/adminPassword".path}}";
+        secret_key = "$__file{${config.sops.secrets."grafana/secretKey".path}}";
+        cookie_secure = true;
+        cookie_samesite = "strict";
+        content_security_policy = true;
+      };
+
+      database = {
+        user = "grafana";
+        name = "grafana";
+        type = "postgres";
+        host = "/run/postgresql";
+      };
+    };
+
+    provision = {
+      enable = true;
+
+      datasources.settings.datasources = [
+        {
+          name = "Victoriametrics - tlater.net";
+          url = "http://localhost:8428";
+          type = "prometheus";
+        }
+      ];
+    };
+  };
+
+  services.nginx.virtualHosts."${domain}" = {
+    forceSSL = true;
+    enableACME = true;
+    extraConfig = ''
+      add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
+      access_log /var/log/nginx/${domain}/access.log upstream_time;
+    '';
+    locations."/".proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}";
+  };
+}
diff --git a/configuration/services/metrics/options.nix b/configuration/services/metrics/options.nix
new file mode 100644
index 0000000..81f0865
--- /dev/null
+++ b/configuration/services/metrics/options.nix
@@ -0,0 +1,204 @@
+{
+  pkgs,
+  config,
+  lib,
+  ...
+}: let
+  inherit (lib) types mkOption mkDefault;
+  yaml = pkgs.formats.yaml {};
+in {
+  options = {
+    services.prometheus = {
+      extraExporters = mkOption {
+        type = types.attrsOf (types.submodule {
+          options = {
+            port = mkOption {
+              type = types.int;
+              description = "The port on which this exporter listens.";
+            };
+            listenAddress = mkOption {
+              type = types.str;
+              default = "127.0.0.1";
+              description = "Address to listen on.";
+            };
+            serviceOpts = mkOption {
+              type = types.attrs;
+              description = "An attrset to be merged with the exporter's systemd service.";
+            };
+          };
+        });
+      };
+    };
+
+    services.victoriametrics.scrapeConfigs = mkOption {
+      type = types.attrsOf (types.submodule ({
+        name,
+        self,
+        ...
+      }: {
+        options = {
+          job_name = mkOption {
+            type = types.str;
+            default = name;
+          };
+
+          extraSettings = mkOption {
+            type = types.anything;
+            description = ''
+              Other settings to set for this scrape config.
+            '';
+            default = {};
+          };
+
+          targets = mkOption {
+            type = types.listOf types.str;
+            description = lib.mdDoc ''
+              Addresses scrape targets for this config listen on.
+
+              Shortcut for `static_configs = lib.singleton {targets = [<targets>];}`
+            '';
+            default = [];
+          };
+
+          static_configs = mkOption {
+            default = [];
+            type = types.listOf (types.submodule {
+              options = {
+                targets = mkOption {
+                  type = types.listOf types.str;
+                  description = lib.mdDoc ''
+                    The addresses scrape targets for this config listen on.
+
+                    Must in `listenAddress:port` format.
+                  '';
+                };
+                labels = mkOption {
+                  type = types.attrsOf types.str;
+                  description = lib.mdDoc ''
+                    Labels to apply to all targets defined for this static config.
+                  '';
+                  default = {};
+                };
+              };
+            });
+          };
+        };
+      }));
+    };
+  };
+
+  config = {
+    systemd.services = lib.mkMerge [
+      (lib.mapAttrs' (name: exporter:
+        lib.nameValuePair "prometheus-${name}-exporter" (lib.mkMerge [
+          {
+            # Shamelessly copied from upstream because the upstream
+            # module is an intractable mess
+            wantedBy = ["multi-user.target"];
+            after = ["network.target"];
+            serviceConfig.Restart = mkDefault "always";
+            serviceConfig.PrivateTmp = mkDefault true;
+            serviceConfig.WorkingDirectory = mkDefault /tmp;
+            serviceConfig.DynamicUser = mkDefault true;
+            # Hardening
+            serviceConfig.CapabilityBoundingSet = mkDefault [""];
+            serviceConfig.DeviceAllow = [""];
+            serviceConfig.LockPersonality = true;
+            serviceConfig.MemoryDenyWriteExecute = true;
+            serviceConfig.NoNewPrivileges = true;
+            serviceConfig.PrivateDevices = mkDefault true;
+            serviceConfig.ProtectClock = mkDefault true;
+            serviceConfig.ProtectControlGroups = true;
+            serviceConfig.ProtectHome = true;
+            serviceConfig.ProtectHostname = true;
+            serviceConfig.ProtectKernelLogs = true;
+            serviceConfig.ProtectKernelModules = true;
+            serviceConfig.ProtectKernelTunables = true;
+            serviceConfig.ProtectSystem = mkDefault "strict";
+            serviceConfig.RemoveIPC = true;
+            serviceConfig.RestrictAddressFamilies = ["AF_INET" "AF_INET6"];
+            serviceConfig.RestrictNamespaces = true;
+            serviceConfig.RestrictRealtime = true;
+            serviceConfig.RestrictSUIDSGID = true;
+            serviceConfig.SystemCallArchitectures = "native";
+            serviceConfig.UMask = "0077";
+          }
+          exporter.serviceOpts
+        ]))
+      config.services.prometheus.extraExporters)
+
+      {
+        vmagent-scrape-exporters = let
+          listenAddress = config.services.victoriametrics.listenAddress;
+          vmAddr = (lib.optionalString (lib.hasPrefix ":" listenAddress) "127.0.0.1") + listenAddress;
+          promscrape = yaml.generate "prometheus.yml" {
+            scrape_configs = lib.mapAttrsToList (_: scrape:
+              lib.recursiveUpdate {
+                inherit (scrape) job_name;
+                static_configs =
+                  scrape.static_configs
+                  ++ lib.optional (scrape.targets != []) {targets = scrape.targets;};
+              }
+              scrape.extraSettings)
+            config.services.victoriametrics.scrapeConfigs;
+          };
+        in {
+          enable = true;
+          path = [pkgs.victoriametrics];
+          wantedBy = ["multi-user.target"];
+          after = ["network.target" "victoriametrics.service"];
+          serviceConfig = {
+            ExecStart = [
+              (lib.concatStringsSep " " [
+                "${pkgs.victoriametrics}/bin/vmagent"
+                "-promscrape.config=${promscrape}"
+                "-remoteWrite.url=http://${vmAddr}/api/v1/write"
+                "-remoteWrite.tmpDataPath=%t/vmagent"
+              ])
+            ];
+            SupplementaryGroups = "metrics";
+
+            DynamicUser = true;
+            RuntimeDirectory = "vmagent";
+            CapabilityBoundingSet = [""];
+            DeviceAllow = [""];
+            LockPersonality = true;
+            MemoryDenyWriteExecute = true;
+            NoNewPrivileges = true;
+            PrivateDevices = true;
+            ProtectClock = true;
+            ProtectControlGroups = true;
+            ProtectHome = true;
+            ProtectHostname = true;
+            ProtectKernelLogs = true;
+            ProtectKernelModules = true;
+            ProtectKernelTunables = true;
+            ProtectSystem = "strict";
+            RemoveIPC = true;
+            RestrictAddressFamilies = ["AF_INET" "AF_INET6"];
+            RestrictNamespaces = true;
+            RestrictRealtime = true;
+            RestrictSUIDSGID = true;
+            SystemCallArchitectures = "native";
+            UMask = "0077";
+          };
+        };
+      }
+    ];
+
+    users.groups.metrics = {};
+
+    services.victoriametrics.scrapeConfigs = let
+      allExporters =
+        lib.mapAttrs (name: exporter: {
+          inherit (exporter) listenAddress port;
+        }) ((lib.filterAttrs (_: exporter: builtins.isAttrs exporter && exporter.enable)
+          config.services.prometheus.exporters)
+        // config.services.prometheus.extraExporters);
+    in
+      lib.mapAttrs (_: exporter: {
+        targets = ["${exporter.listenAddress}:${toString exporter.port}"];
+      })
+      allExporters;
+  };
+}
diff --git a/configuration/services/metrics/victoriametrics.nix b/configuration/services/metrics/victoriametrics.nix
new file mode 100644
index 0000000..a5149f7
--- /dev/null
+++ b/configuration/services/metrics/victoriametrics.nix
@@ -0,0 +1,13 @@
+{config, ...}: {
+  config.services.victoriametrics = {
+    enable = true;
+
+    scrapeConfigs = {
+      gitea = {
+        targets = ["127.0.0.1:${toString config.services.gitea.settings.server.HTTP_PORT}"];
+        extraSettings.authorization.credentials_file = config.sops.secrets."gitea/metrics-token".path;
+      };
+      coturn.targets = ["127.0.0.1:9641"];
+    };
+  };
+}
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index fbca607..81f38a3 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -50,6 +50,9 @@ in {
   services.nginx.virtualHosts."${hostName}" = {
     forceSSL = true;
     enableACME = true;
+    extraConfig = ''
+      access_log /var/log/nginx/${hostName}/access.log upstream_time;
+    '';
   };
 
   # Block repeated failed login attempts
diff --git a/configuration/services/postgres.nix b/configuration/services/postgres.nix
index 6c584bb..923007d 100644
--- a/configuration/services/postgres.nix
+++ b/configuration/services/postgres.nix
@@ -16,6 +16,12 @@
     # that operation needs to be performed manually on the system as
     # well.
     ensureUsers = [
+      {
+        name = "grafana";
+        ensurePermissions = {
+          "DATABASE grafana" = "ALL PRIVILEGES";
+        };
+      }
       {
         name = "nextcloud";
         ensurePermissions = {
@@ -25,6 +31,7 @@
     ];
 
     ensureDatabases = [
+      "grafana"
       "nextcloud"
     ];
   };
diff --git a/configuration/services/webserver.nix b/configuration/services/webserver.nix
index 4a8bee4..085b1f7 100644
--- a/configuration/services/webserver.nix
+++ b/configuration/services/webserver.nix
@@ -19,6 +19,7 @@ in {
     enableACME = true;
     extraConfig = ''
       add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
+      access_log /var/log/nginx/${domain}/access.log upstream_time;
     '';
 
     locations."/".proxyPass = "http://${addr}:${toString port}";
diff --git a/configuration/sops.nix b/configuration/sops.nix
index bf98433..03faf82 100644
--- a/configuration/sops.nix
+++ b/configuration/sops.nix
@@ -3,6 +3,23 @@
     defaultSopsFile = ../keys/production.yaml;
 
     secrets = {
+      # Gitea
+      "gitea/metrics-token" = {
+        owner = "gitea";
+        group = "metrics";
+        mode = "0440";
+      };
+
+      # Grafana
+      "grafana/adminPassword" = {
+        owner = "grafana";
+        group = "grafana";
+      };
+      "grafana/secretKey" = {
+        owner = "grafana";
+        group = "grafana";
+      };
+
       # Heisenbridge
       "heisenbridge/as-token" = {};
       "heisenbridge/hs-token" = {};
diff --git a/flake.nix b/flake.nix
index b6db610..d8ff1a8 100644
--- a/flake.nix
+++ b/flake.nix
@@ -78,7 +78,7 @@
     # Utility scripts #
     ###################
     packages.${system} = let
-      inherit (nixpkgs.legacyPackages.${system}) writeShellScript;
+      inherit (nixpkgs.legacyPackages.${system}) writeShellScript writeShellScriptBin;
       vm = nixpkgs.lib.nixosSystem {
         inherit system;
         specialArgs.flake-inputs = inputs;
@@ -106,6 +106,14 @@
           "${vm.config.system.build.vm}/bin/run-tlaternet-vm"
         '';
 
+      update-pkgs = let
+        nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher";
+      in
+        writeShellScriptBin "update-pkgs" ''
+          cd "$(git rev-parse --show-toplevel)/pkgs"
+          ${nvfetcher-bin} -o _sources_pkgs -c nvfetcher.toml
+        '';
+
       update-nextcloud-apps = let
         nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher";
       in
diff --git a/keys/production.yaml b/keys/production.yaml
index f8d259d..efeea6a 100644
--- a/keys/production.yaml
+++ b/keys/production.yaml
@@ -1,3 +1,8 @@
+gitea:
+    metrics-token: ENC[AES256_GCM,data:/7/zvVl2ZOBoekrJR32vl/QQcG5XqTmltgpHEMUpbXVeqwnq29idzE2Qyjau96ZHObmSI73/ZtW95uXF6LH9Qw==,iv:iWZECCZSh1CN7wMBqstXR5QWtriR7QLKVqhekGnpXl0=,tag:HEr9km8VYmruBzf0I/5HuA==,type:str]
+grafana:
+    adminPassword: ENC[AES256_GCM,data:/qw//J7cOkIGa58bG4GgdzndvKof32AmQeWB00IX8WhA22PDCOc4VdUEoB3wVJJqI/ucoHFInYyhg2rFYoYBesBjAt0QS3+O+8WblIunUuYeqlBuYJJK1TLhy6ql6+aqvfiW/rJLm4LpgA7CboyDD2OYHcAbvGSD2GWwFcHTR/Y=,iv:KK6p8GKzc9SBDZZFkEwCdIjSxriPGNMDNcr97tfbwTI=,tag:gLRNSGdJWFD+V9K5TfJvXw==,type:str]
+    secretKey: ENC[AES256_GCM,data:OUXWOE6I3a26SrFEOczWNIwyR3Rx62fbsRBBcfh0xyEbxOIPhexH6lIqlVG9Ltwra9+rAldNM4/0BydtxIDj7A==,iv:fiNO/or5yZnhpDPMANDnEC5dtXmbKBZsV+BPmvCN/HI=,tag:Q0M0OtLWdWAJgQmUlL//fg==,type:str]
 nextcloud:
     tlater: ENC[AES256_GCM,data:zNsPm4uFaIRe3LjcwmayRg==,iv:5wam6bP5zP708jC9UrLV0s8qspl3Pm4fPzbMFYBUyPQ=,tag:apnJUMeJwMn9q0NhO4ptmA==,type:str]
 steam:
@@ -21,8 +26,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2023-09-23T18:55:44Z"
-    mac: ENC[AES256_GCM,data:psqgXozY9L7nduZ11GF+mbIrZ4RUySqBixkWL5z0cYeoLA3URb/dr028LCmNgQS9l8aJVsjVkyLBJIU/8wmiUNqRy/VI5iqV5mu+sxXhUVwFL0dAAWP1lOKwwT5uGK89/ioqkphgzuWD37vGe2vYddKkJF0M+zlz12fqkMjaisU=,iv:UyRoJbfuGU3K/Mp5DQ1kY0Z+nKSSo46BGNAcxt+vAvc=,tag:HkP6+qxQ8J/xAYJXYoG/6g==,type:str]
+    lastmodified: "2023-10-12T18:40:26Z"
+    mac: ENC[AES256_GCM,data:F+yQ20jCtLRKeQDFVKoqrYCgtwGkXxrK6aQO0MFZTIMJAnbTVPM2ZJGQ1RxXb+Zs4T+44EEc2xN4LjeANvgpE6MfOz2VTw+sEEjcYwUyB6RcXHia9XlFLa8lh7/Wx/9DxlSFjjSrxmDkNB6r+n5UF81cdRXF2E9ibdH346ST98A=,iv:xVxFN1IDKrLskaGqnWvOWx1zUII0jRSjQxEsaTf2GNw=,tag:lnp1AvgMOXXlg1vFjHEWUQ==,type:str]
     pgp:
         - created_at: "2022-10-12T00:46:51Z"
           enc: |
diff --git a/keys/staging.yaml b/keys/staging.yaml
index a6b0849..73f0f94 100644
--- a/keys/staging.yaml
+++ b/keys/staging.yaml
@@ -1,3 +1,8 @@
+gitea:
+    metrics-token: ENC[AES256_GCM,data:J4QdfI1wKyM=,iv:8fqCbftyhj90eIVFxjEp9RXKC1y1IaLnV1r2MOdY15M=,tag:8W/juv1OZh4hJco02qXO6g==,type:str]
+grafana:
+    adminPassword: ENC[AES256_GCM,data:dYfaxUpQpzA=,iv:j5wSem8C5+V4c5qRzXQJhsU7/FOtpvrnaEyFBmW6zJ4=,tag:oc8n3TkEbjF2gjuOobZuLA==,type:str]
+    secretKey: ENC[AES256_GCM,data:Atruvh2MsNY=,iv:y2MaCUCEzGIydHp6G0DJHfk289S1is0twKm2oUYwDhM=,tag:nAWeg+YqaYqk6k22oBkAhQ==,type:str]
 nextcloud:
     tlater: ENC[AES256_GCM,data:91kDcO4hpng=,iv:ayuILRmRru4ZxTCur9H2xHuLjkDzwPdS/4lEog/tesU=,tag:qYhJxnNDcCwUM7xe7Tlcjw==,type:str]
 steam:
@@ -21,8 +26,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2023-09-22T21:07:02Z"
-    mac: ENC[AES256_GCM,data:gItC41S8MInLmikdH1okhPs+FVf8sCF/iQeJ5reigBunHkOngoc6nOFANyAcNZETszzhgTLXXtmVNEjW46v6K7D6nmoi/zwpedUxwzMwDC5I28VTMDHVMAThYSGtdo6kig8i2pi8rzEQd1DStxMv3TWML5y6DDTlFsd3lfudaHA=,iv:zXebvIVPR76GwUhpactwRgF/eEmx2OBkT18E8lkwzRA=,tag:6HyISACbFCGlpIIgkFeA/A==,type:str]
+    lastmodified: "2023-10-07T02:17:50Z"
+    mac: ENC[AES256_GCM,data:vZDq33YIn0Nf1FQ2+ySezox6igiw6zNFCu3l3kaIsBKo1797pohmAxj2Lcc+OmlBjj98khaBIlbQuA5ULM+uPN5ILaz3NuXD5PZtsV+rL2PsLNMW9FBSmJ0m0YQrt0nZ0tpzifn12XghcSK2IXv+FnxlfrAJCxDvr5tRm90uUwU=,iv:ct8CzIWjaoJ1UjZcdFSr8lZ626vA0RvM883V6H5plWc=,tag:waJNtp/UbRDOfyzNElrung==,type:str]
     pgp:
         - created_at: "2022-10-12T16:48:23Z"
           enc: |
diff --git a/pkgs/_sources_pkgs/generated.json b/pkgs/_sources_pkgs/generated.json
new file mode 100644
index 0000000..b3faf9a
--- /dev/null
+++ b/pkgs/_sources_pkgs/generated.json
@@ -0,0 +1,21 @@
+{
+    "prometheus-fail2ban-exporter": {
+        "cargoLocks": null,
+        "date": null,
+        "extract": null,
+        "name": "prometheus-fail2ban-exporter",
+        "passthru": null,
+        "pinned": false,
+        "src": {
+            "deepClone": false,
+            "fetchSubmodules": false,
+            "leaveDotGit": false,
+            "name": null,
+            "rev": "v0.10.0",
+            "sha256": "sha256-8nIW1XaHCBqQCoLkV1ZYE3NTbVZ6c+UOqYD08XQiv+4=",
+            "type": "git",
+            "url": "https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter"
+        },
+        "version": "v0.10.0"
+    }
+}
\ No newline at end of file
diff --git a/pkgs/_sources_pkgs/generated.nix b/pkgs/_sources_pkgs/generated.nix
new file mode 100644
index 0000000..bb015b4
--- /dev/null
+++ b/pkgs/_sources_pkgs/generated.nix
@@ -0,0 +1,16 @@
+# This file was generated by nvfetcher, please do not modify it manually.
+{ fetchgit, fetchurl, fetchFromGitHub, dockerTools }:
+{
+  prometheus-fail2ban-exporter = {
+    pname = "prometheus-fail2ban-exporter";
+    version = "v0.10.0";
+    src = fetchgit {
+      url = "https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter";
+      rev = "v0.10.0";
+      fetchSubmodules = false;
+      deepClone = false;
+      leaveDotGit = false;
+      sha256 = "sha256-8nIW1XaHCBqQCoLkV1ZYE3NTbVZ6c+UOqYD08XQiv+4=";
+    };
+  };
+}
diff --git a/pkgs/default.nix b/pkgs/default.nix
index 3818a26..3130ae0 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -7,6 +7,9 @@
 in
   {
     starbound = callPackage ./starbound {};
+    prometheus-fail2ban-exporter = callPackage ./prometheus/fail2ban-exporter.nix {
+      sources = pkgs.callPackage ./_sources_pkgs/generated.nix {};
+    };
   }
   // (
     # Add nextcloud apps
diff --git a/pkgs/nvfetcher.toml b/pkgs/nvfetcher.toml
new file mode 100644
index 0000000..8c53200
--- /dev/null
+++ b/pkgs/nvfetcher.toml
@@ -0,0 +1,3 @@
+[prometheus-fail2ban-exporter]
+src.manual = "v0.10.0" # No gitlab support in nvfetcher
+fetch.git = "https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter"
diff --git a/pkgs/prometheus/fail2ban-exporter.nix b/pkgs/prometheus/fail2ban-exporter.nix
new file mode 100644
index 0000000..50b4973
--- /dev/null
+++ b/pkgs/prometheus/fail2ban-exporter.nix
@@ -0,0 +1,8 @@
+{
+  buildGoModule,
+  sources,
+}:
+buildGoModule {
+  inherit (sources.prometheus-fail2ban-exporter) pname src version;
+  vendorHash = "sha256-qU6opwhhvzbQOhfGVyiVgKhfCSB0Z4eSRAJnv6ht2I0=";
+}

From 759a9c7c0c088b1e65d22500bd66ffbae71f70ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 13 Oct 2023 06:08:26 +0200
Subject: [PATCH 111/212] conduit: Fix acme issue

letsencrypt will prod on port 80 to verify the domain. `listen`
overrides `addSSL`, so none of the NixOS modules' setup will actually
work.

This means the conduit virtualhost never listened on port 80, and
couldn't verify letsencrypt requests.

How this *ever* worked is beyond me, but this commit resolves the
problems (don't worry, `forceSSL` does what it says on the tin and
overrides the `listen` again).
---
 configuration/services/conduit.nix | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
index 8257592..6c84705 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit.nix
@@ -183,6 +183,14 @@ in {
     enableACME = true;
 
     listen = [
+      {
+        addr = "0.0.0.0";
+        port = 80;
+      }
+      {
+        addr = "[::0]";
+        port = 80;
+      }
       {
         addr = "0.0.0.0";
         port = 443;
@@ -200,12 +208,12 @@ in {
       }
       {
         addr = "[::0]";
-        port = 8488;
+        port = 8448;
         ssl = true;
       }
     ];
 
-    addSSL = true;
+    forceSSL = true;
     extraConfig = ''
       merge_slashes off;
       access_log /var/log/nginx/${domain}/access.log upstream_time;

From eb3bd485c40c9ea69f5c87a7b86c60dd934a0698 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 13 Oct 2023 03:43:03 +0200
Subject: [PATCH 112/212] metrics: Add size limit to victoriametrics

---
 configuration/services/metrics/victoriametrics.nix | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/configuration/services/metrics/victoriametrics.nix b/configuration/services/metrics/victoriametrics.nix
index a5149f7..4cdc770 100644
--- a/configuration/services/metrics/victoriametrics.nix
+++ b/configuration/services/metrics/victoriametrics.nix
@@ -1,6 +1,9 @@
 {config, ...}: {
   config.services.victoriametrics = {
     enable = true;
+    extraOptions = [
+      "-storage.minFreeDiskSpaceBytes=5GB"
+    ];
 
     scrapeConfigs = {
       gitea = {

From 95b5d4b3bd879783cef39f4d50f902e55548313f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 13 Oct 2023 10:16:10 +0200
Subject: [PATCH 113/212] nginx: Reduce number of rotated logs kept around

---
 configuration/default.nix | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index 81e7241..6f7cf41 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -153,16 +153,21 @@
   services.logrotate = {
     enable = true;
 
-    settings = lib.mapAttrs' (virtualHost: _:
-      lib.nameValuePair "/var/log/nginx/${virtualHost}/access.log" {
-        frequency = "daily";
-        rotate = 2;
-        compress = true;
-        delaycompress = true;
-        su = "${config.services.nginx.user} ${config.services.nginx.group}";
-        postrotate = "[ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`";
-      })
-    config.services.nginx.virtualHosts;
+    settings =
+      {
+        # Override the default, just keep fewer logs
+        nginx.rotate = 6;
+      }
+      // lib.mapAttrs' (virtualHost: _:
+        lib.nameValuePair "/var/log/nginx/${virtualHost}/access.log" {
+          frequency = "daily";
+          rotate = 2;
+          compress = true;
+          delaycompress = true;
+          su = "${config.services.nginx.user} ${config.services.nginx.group}";
+          postrotate = "[ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`";
+        })
+      config.services.nginx.virtualHosts;
   };
   systemd.tmpfiles.rules =
     lib.mapAttrsToList (

From 4a966412b879fcabff6e58a61df285765ef89238 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 29 Dec 2023 16:10:00 +0100
Subject: [PATCH 114/212] staging: Use a static ssh host key

---
 .sops.yaml                             |  2 +-
 configuration/hardware-specific/vm.nix | 16 +++++++
 keys/hosts/staging.asc                 | 50 ++++++++++-----------
 keys/hosts/staging.key                 | 49 +++++++++++++++++++++
 keys/hosts/staging.key.pub             |  1 +
 keys/staging.yaml                      | 60 +++++++++++++-------------
 6 files changed, 122 insertions(+), 56 deletions(-)
 create mode 100644 keys/hosts/staging.key
 create mode 100644 keys/hosts/staging.key.pub

diff --git a/.sops.yaml b/.sops.yaml
index 4c17c75..dc2021d 100644
--- a/.sops.yaml
+++ b/.sops.yaml
@@ -1,7 +1,7 @@
 keys:
   - &tlater 535B61015823443941C744DD12264F6BBDFABA89
   - &server_tlaternet 8a3737d48f1035fe6c3a0a8fd6a1976ca74c7f3b
-  - &server_staging 7762ec55a5727cabada621d961e53f94caa314e4
+  - &server_staging 2f5caa73e7ceea4fcc8d2881fde587e6737d2dbc
 
 creation_rules:
   - path_regex: keys/production.yaml
diff --git a/configuration/hardware-specific/vm.nix b/configuration/hardware-specific/vm.nix
index 8c93f30..32423ab 100644
--- a/configuration/hardware-specific/vm.nix
+++ b/configuration/hardware-specific/vm.nix
@@ -16,6 +16,22 @@
     networkConfig.DHCP = "yes";
   };
 
+  # Both so we have a predictable key for the staging env, as well as
+  # to have a static key for decrypting the sops secrets for the
+  # staging env.
+  environment.etc."staging.key" = {
+    mode = "0400";
+    source = ../../keys/hosts/staging.key;
+  };
+
+  services.openssh.hostKeys = lib.mkForce [
+    {
+      type = "rsa";
+      bits = 4096;
+      path = "/etc/staging.key";
+    }
+  ];
+
   # # Set up VM settings to match real VPS
   # virtualisation.memorySize = 3941;
   # virtualisation.cores = 2;
diff --git a/keys/hosts/staging.asc b/keys/hosts/staging.asc
index fbabfe2..4b376fe 100644
--- a/keys/hosts/staging.asc
+++ b/keys/hosts/staging.asc
@@ -1,28 +1,28 @@
 -----BEGIN PGP PUBLIC KEY BLOCK-----
 
-xsFNBAAAAAABEAC32/CXnt4LDPdPZppQ0GcJAxVFHFu8SCl5WnU/PVPEnwgRkV8V
-ZeyQN4qgT5LPWgPYyDyAqUHBUwRxvVcguw0fOlDBZ3nECKQxZ53OVlay7xfhgXO1
-luNu657u5VYtxfLqx7lVHfY/TWp5DBOOEpOtoKfz031Zbg11+kdxW5eEg2ypCTvn
-+MVQgRH9AQI+0+jegQ9On3X9UaVdc8etuY/F8BAEwLCCbYpLUEUXwOo4YLB36Kg3
-P27q15Nl6g5P/oFEdS3fhHbh9636lJnxJcTTjAfJaDoQJ5rGDASiT8HJnkNWfrf/
-yzLMOiy6fRRIz8HTXKeZNeRvCPu1uHaWYi0RprWMu1HZ0cLzr5N2lHKcWgL8En5b
-fPyqldFfJBlY36L59F7hTk10QBgqFhibcXB44iK96jnYw6LgSuFkbfrJr7fx67JN
-lM2Xi4WXvzkp3gboDxd2Xy3ChQrQXmXcVAl8XNs78f5AQh5MJP6iC7ayiIsHq4aH
-rGVLhbncfKpw4OL9jVNTyRinwpvl5qibLAJbDA7arn8XqT6FT0KjeLa91jTFLHGn
-9IkJol+L0/zYrpyiid5ZKNJMousxJoXymzRkeYllr+nLjKNLv0L3MCnsiPEZ23iL
-y2/UZ6Vcjrs50L46VuiewCEaVbBp1H9Ps5eUa2YoJ65sfe7wnscXI8oOpQARAQAB
+xsFNBAAAAAABEADFaVmT5Xt4+nCM2hZ+Zq7Uybg26TISSrpU/3nZ+qxZSC65mqfB
+qWNR1kCpJpDvhwUhaTC2x00L/ckRoPcF60AqYR632owQ0AgyuG+xR0HJR5rpWzRs
+cMINk1NOLQ4Vw9IaRykfx5YtKL3mPo8iLNQom6SkFG1hPqwoAzzWNLBLKMfKrDtW
+uBnsbGLrkAB/2eJBw9xDmpMpLV5f2lJDA89RQYV8YQhe4TBL9B0WSSc9CqX9TP6m
+30zY6jCWvfYL+Hi+YiR2K+dp9qXB55ViYcw8hRG99n5fSyZSB0hyttnIV76G0I27
+McFueWu6LzZ/lMEJM8OeFVgyMJFMVXHCBxLYHLqlJvxk4tV43Jkl4IOn4gBgG2oS
+7Sk1woz57UNug/AGcGAHL/YAbk+WcEut2RiwoTUEyQpRrP4QPnZivEkeTs0H4lf3
+3SHW6snMdcCDkjO6VCo9DTsSpX8eNLj9hW8UMuUMsU3jLtV4L2TMoDnqRHO7icbC
+r+3CIi/yA5EWry/AReOPTFY+etX3XrVUUdA/SJL/OXLB8QD2jW0XbVeaHLgdhlt5
+UeDwSWDYHn4LXYr8SXa3YKC2OmIAU8yNInPCGizHPm8IZVG4zjzPNjM3BihxpZjj
+IVajFe07INd8sM6RXE+YA0QTmEDoGW2QcltRyHdAPz5XVkRypbV5ONZLTQARAQAB
 zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT
-AQgAFgUCAAAAAAkQYeU/lMqjFOQCGw8CGQEAAEKvEABZo9JRHnwrKr7UGmynctmF
-aR+1KApeWrqahhobgfvMjJLfnUV7UDSeiuf3juoZC+L1d8LqEp0czcqU1YuGtjTT
-Yk/4WDwc7G9MjHDgVXPZlQ/qxSYBFwowbUkfhj49UA4Np2PW3yLtoZnBHLz6tmaD
-mTtdNjzEw+L0GQ9Wi2pQYSUV4I9URF/NH7NGmurNl8Y5SHb3rqFQ4CPGXk5UQYL5
-s0ZdArwgWNH+ceC1Kq0baKu5WJINFfCIJbJajATBqgPy6FPEmhUdgt8awOp01oEc
-zs2930sc6YY5GJVEGnxR/qBLTA5lANS1mpqHd9s4YF7jj8h/q8SV4iegTeKHrLox
-v1bP+QzHquCn7BpO9V6GD/eaqBKfx6k6+HDb5YmKnBvBV/c3yJ6wiv1H32nauWs1
-CgiJNYV+A/+YnWf0uPRqelAzT06JUtnSBZ0ppKLR68X3IKisXVNzW/3pM/ZWWfFM
-uKHCoppH2iuStn2wPkdjJD4UHduAFyF1oj1jFwP9r+EuhhPH1qr40405jRdOR98P
-RuPhrSkLBdWiUlNintDOyFzNbKXMZlreZeATeT5y/H+IF3CDvgAhBo7KqhfBfgUK
-6P/1xk8DozTmlsKY/cOsK0aL47CJcg8LU6tHrxa8uP6qV2HbUD31WbCRr1eL8k2G
-xszxEVPuKG8ckw58WpT4vA==
-=kJ/7
------END PGP PUBLIC KEY BLOCK-----
+AQgAFgUCAAAAAAkQ/eWH5nN9LbwCGw8CGQEAAM6kEACsZmMOZd5qMOOJReo/cu5p
+8JcXZ1c3wAUGm/Nw7xN68AGxHHWqUJqs5hGqICqSxnjtDD95H5tb9ahrEIxszfVd
+fj/CR1XRu4Scu7MZ45u4q/whLIwe1vqROmL1G0bR52WVvaHjcS+2h3NlxauO8bld
+uCwwQrCEBv86XjCZNtcVWEjqBffIfJQYAywyprqL3LGB5ypuW1tb/fnTZSd/1k9D
+3LZ26FRvPd8XsBAZ5zSilpTdE9yhDPQb49VLP4iVwPkIjbw0us1KxlGJapU1nYfx
+pX23F1f3tRGah/QOuZYa9J2dnr8A9FJQ+x616nrxnJ4DIRsS/mG+ES1HiVKa9u+2
+ZHxXqRHY+eb2QYaWI25F4BYrADOMcDLHvNL4T8E21Nt7QJ0hUeTeMCROICoVOtF9
+JNaHwD7AhOIwZHA28WNcrDoOpYmXXeRd+Vohvx5LO0loq/3dQdr5KMH/VGVP0VzK
+YgPjh+z7HT66oMUz1fOeWtIqzLj7Un6rfodfq50OouDwhkAGseupDHnY2MBrfi6v
+fexpttnBuOx5NSeuYYxkWK8cUfAFVFO5bFCb3MW1e2waaiceS1vq3dXiZx3l23Pr
+qOs7Ahdz5P4/GZGjIDKNrdLid5tfBI12hxFOSuXoF7G9Ak24a77A9qks40NL6TMi
+hK7IB8p3wuRzngwa0WY3QQ==
+=6Ym/
+-----END PGP PUBLIC KEY BLOCK-----
\ No newline at end of file
diff --git a/keys/hosts/staging.key b/keys/hosts/staging.key
new file mode 100644
index 0000000..1cec290
--- /dev/null
+++ b/keys/hosts/staging.key
@@ -0,0 +1,49 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn
+NhAAAAAwEAAQAAAgEAxWlZk+V7ePpwjNoWfmau1Mm4NukyEkq6VP952fqsWUguuZqnwalj
+UdZAqSaQ74cFIWkwtsdNC/3JEaD3BetAKmEet9qMENAIMrhvsUdByUea6Vs0bHDCDZNTTi
+0OFcPSGkcpH8eWLSi95j6PIizUKJukpBRtYT6sKAM81jSwSyjHyqw7VrgZ7Gxi65AAf9ni
+QcPcQ5qTKS1eX9pSQwPPUUGFfGEIXuEwS/QdFkknPQql/Uz+pt9M2Oowlr32C/h4vmIkdi
+vnafalweeVYmHMPIURvfZ+X0smUgdIcrbZyFe+htCNuzHBbnlrui82f5TBCTPDnhVYMjCR
+TFVxwgcS2By6pSb8ZOLVeNyZJeCDp+IAYBtqEu0pNcKM+e1DboPwBnBgBy/2AG5PlnBLrd
+kYsKE1BMkKUaz+ED52YrxJHk7NB+JX990h1urJzHXAg5IzulQqPQ07EqV/HjS4/YVvFDLl
+DLFN4y7VeC9kzKA56kRzu4nGwq/twiIv8gORFq8vwEXjj0xWPnrV9161VFHQP0iS/zlywf
+EA9o1tF21Xmhy4HYZbeVHg8Elg2B5+C12K/El2t2CgtjpiAFPMjSJzwhosxz5vCGVRuM48
+zzYzNwYocaWY4yFWoxXtOyDXfLDOkVxPmANEE5hA6BltkHJbUch3QD8+V1ZEcqW1eTjWS0
+0AAAdAO1rPtDtaz7QAAAAHc3NoLXJzYQAAAgEAxWlZk+V7ePpwjNoWfmau1Mm4NukyEkq6
+VP952fqsWUguuZqnwaljUdZAqSaQ74cFIWkwtsdNC/3JEaD3BetAKmEet9qMENAIMrhvsU
+dByUea6Vs0bHDCDZNTTi0OFcPSGkcpH8eWLSi95j6PIizUKJukpBRtYT6sKAM81jSwSyjH
+yqw7VrgZ7Gxi65AAf9niQcPcQ5qTKS1eX9pSQwPPUUGFfGEIXuEwS/QdFkknPQql/Uz+pt
+9M2Oowlr32C/h4vmIkdivnafalweeVYmHMPIURvfZ+X0smUgdIcrbZyFe+htCNuzHBbnlr
+ui82f5TBCTPDnhVYMjCRTFVxwgcS2By6pSb8ZOLVeNyZJeCDp+IAYBtqEu0pNcKM+e1Dbo
+PwBnBgBy/2AG5PlnBLrdkYsKE1BMkKUaz+ED52YrxJHk7NB+JX990h1urJzHXAg5IzulQq
+PQ07EqV/HjS4/YVvFDLlDLFN4y7VeC9kzKA56kRzu4nGwq/twiIv8gORFq8vwEXjj0xWPn
+rV9161VFHQP0iS/zlywfEA9o1tF21Xmhy4HYZbeVHg8Elg2B5+C12K/El2t2CgtjpiAFPM
+jSJzwhosxz5vCGVRuM48zzYzNwYocaWY4yFWoxXtOyDXfLDOkVxPmANEE5hA6BltkHJbUc
+h3QD8+V1ZEcqW1eTjWS00AAAADAQABAAACAFMv1CQK+U9e9UudYQotufGH+V0GQmfL3p4P
+s+jDhZnv3WSwA44Lk4M6TjAZRMzysBpGqdTzwgdSD8cidcWkPvs8xsWBzjENgM7iwopJNT
+Mcve4k1T/2+gbfdKTGPp+0T1ZscytlnuZzuyYJaaZkjph4EdZklzz5vHD2AE5hkIJzclF4
+515hIOdsOvj5ywQVLA87ehdwzR92c0TgCncb5WJfwmDJwM2+hewTt6ga9nJ2CMFnDw4Bne
+/wK75x2PttXnAXijbTxGX2Hh5KOLxm6rn79yB9/P2p/MFnOUPBwp72Pp6vxnHCAzlK6Dbi
+S0xSwk9e5Uk5xFsN9URd4xx4f5scwxyk8RQCh/sMqn3JIOwodNwVjv+AWc3YNFR+aP+qXR
+wggXSypKDbVIAp2+cGKCobktNBiM/fEPMHe20Ssn+SBclUSeAYMpjRrn8Kxwb2oSMASrsV
+1ykyY+/j+Xb3jC2V+/XTV+5WtKt4SW4RV45g/+C65H+zy+56BoyPqJKyI8d3FB0dp/ICwo
+zfrmo/X00XF77d3ZThLoapSnOVeaNIiFtG5Ia635gNUyr/81xNhOeX5NMBUHSqdxrtZfC2
+PeuBcspWOg2tp/6UPjBppwrT3VnM/K27lqmDx9jPE4tMY4kl55KdSJ4uBr7H5Lu6w2zNnZ
+zGYToWbhXNDHqm9PqPAAABAQCCBatZmvEyP+7+qBFkvU1t8nseupa/Lu6Va5qV9ZLvUI0Q
+8nMYMZ/lMMB6TROyy9OJY59srkCjyF7COqNH6A/eo2XBCVdkAEBpUta8gzbLTtzRaDY+tH
+64tzDJYTLPumfE1M2IfztVwVgJuwrz/t6eAtakXfjNRG8nKVlTI5UALRLIIqVK5ReDs5NU
+7FbO5MwYtrsVHmpiXqNA8d1pZkjXNmU+I67DblPTCWraNnEC6mcIgau9n+mGuQjrHzpUqn
+kbQF3GSJTwgJSlKhkNGLyH4qrFsK0yemCkxKtzi1fXy/iLKXUG2A1uovuugXwQZmV7nHRM
++oDKZz13CWk14kDtAAABAQD07kRtO22XTklTf3w/cC67aVj+Ltifl0bVwbsFgY9zu0F7yl
+odYYfxV/rDn639V80JoAaTZ3lSuBvOwgtGWr298rwkkkV4CLKu7+bTLdS2L9YScKmKL8N+
+FGoYgVCTZZxaUe49eUdLaUcjxYTPC5FWGFCztLG7uAvydIbTFKG6++j4poow6q2AwejC8f
+ZiO2r0srZM1ouYW5j+6YCbLCKKcgJdZvZFBhDXyHwQXF5rCtB8htg6BgsTu3Fx6oZR3PXc
+RoO5A2CmoZ3bUSAzUOH4g80yB6Fq0dvpFr1CtzzNCda5TLNS6ediLqlP62NEez+wduv+Rs
+Xd+EhFect0lmETAAABAQDOVU7PqTLZFTxUx++JVFmdrd5FqTHwOrnEYWo8Hzx8X4RomIBg
+kY4oIGLXsBfZINyWKOKjQqhfh+nRgsCR7OQ9IjeWh/0eRma6b9kjBQT4UKYvylBjchoVci
+6DrxXWhwbRTCV2Vxpn/+Bx2JexUJx5oQ8yZ7a/H/w9J5GjgT3OR6d/ogzHr3FqdeAnvUle
+PBlaCZUQxuI2ADmdWpzxwmCalAxrLQiUCdRtY6X8TWYi35DWvGgVU1nz5VWYRvI1/+pQdt
+Qe9lP4uFNOpc05G7xcloEe+wE4aIqL4fLGVOrOqtHOps1W62Owk8iU7OFXw6Aoc4yjNWcj
+SEsRv2HtGI4fAAAACnRsYXRlckB5dWk=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/keys/hosts/staging.key.pub b/keys/hosts/staging.key.pub
new file mode 100644
index 0000000..7704002
--- /dev/null
+++ b/keys/hosts/staging.key.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDFaVmT5Xt4+nCM2hZ+Zq7Uybg26TISSrpU/3nZ+qxZSC65mqfBqWNR1kCpJpDvhwUhaTC2x00L/ckRoPcF60AqYR632owQ0AgyuG+xR0HJR5rpWzRscMINk1NOLQ4Vw9IaRykfx5YtKL3mPo8iLNQom6SkFG1hPqwoAzzWNLBLKMfKrDtWuBnsbGLrkAB/2eJBw9xDmpMpLV5f2lJDA89RQYV8YQhe4TBL9B0WSSc9CqX9TP6m30zY6jCWvfYL+Hi+YiR2K+dp9qXB55ViYcw8hRG99n5fSyZSB0hyttnIV76G0I27McFueWu6LzZ/lMEJM8OeFVgyMJFMVXHCBxLYHLqlJvxk4tV43Jkl4IOn4gBgG2oS7Sk1woz57UNug/AGcGAHL/YAbk+WcEut2RiwoTUEyQpRrP4QPnZivEkeTs0H4lf33SHW6snMdcCDkjO6VCo9DTsSpX8eNLj9hW8UMuUMsU3jLtV4L2TMoDnqRHO7icbCr+3CIi/yA5EWry/AReOPTFY+etX3XrVUUdA/SJL/OXLB8QD2jW0XbVeaHLgdhlt5UeDwSWDYHn4LXYr8SXa3YKC2OmIAU8yNInPCGizHPm8IZVG4zjzPNjM3BihxpZjjIVajFe07INd8sM6RXE+YA0QTmEDoGW2QcltRyHdAPz5XVkRypbV5ONZLTQ== tlater@yui
diff --git a/keys/staging.yaml b/keys/staging.yaml
index 73f0f94..fb1d15d 100644
--- a/keys/staging.yaml
+++ b/keys/staging.yaml
@@ -1,5 +1,5 @@
 gitea:
-    metrics-token: ENC[AES256_GCM,data:J4QdfI1wKyM=,iv:8fqCbftyhj90eIVFxjEp9RXKC1y1IaLnV1r2MOdY15M=,tag:8W/juv1OZh4hJco02qXO6g==,type:str]
+    metrics-token: ENC[AES256_GCM,data:T1NYXRWbruA=,iv:usgHYHwWJFbaEdHLO6JX3z/42MVheY2wu0YrXmnz2ng=,tag:W+B7pKGOc/wX/0My0dWY5w==,type:str]
 grafana:
     adminPassword: ENC[AES256_GCM,data:dYfaxUpQpzA=,iv:j5wSem8C5+V4c5qRzXQJhsU7/FOtpvrnaEyFBmW6zJ4=,tag:oc8n3TkEbjF2gjuOobZuLA==,type:str]
     secretKey: ENC[AES256_GCM,data:Atruvh2MsNY=,iv:y2MaCUCEzGIydHp6G0DJHfk289S1is0twKm2oUYwDhM=,tag:nAWeg+YqaYqk6k22oBkAhQ==,type:str]
@@ -26,43 +26,43 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2023-10-07T02:17:50Z"
-    mac: ENC[AES256_GCM,data:vZDq33YIn0Nf1FQ2+ySezox6igiw6zNFCu3l3kaIsBKo1797pohmAxj2Lcc+OmlBjj98khaBIlbQuA5ULM+uPN5ILaz3NuXD5PZtsV+rL2PsLNMW9FBSmJ0m0YQrt0nZ0tpzifn12XghcSK2IXv+FnxlfrAJCxDvr5tRm90uUwU=,iv:ct8CzIWjaoJ1UjZcdFSr8lZ626vA0RvM883V6H5plWc=,tag:waJNtp/UbRDOfyzNElrung==,type:str]
+    lastmodified: "2023-12-29T15:14:54Z"
+    mac: ENC[AES256_GCM,data:yJUprLcfw4ypsrSlhot7vsavVqzaFlJoJeEC/DdTfKDoJ0L607r6aCfXtCSg+qrR5JA2bvEATwDJM5qgA2vbMhSOqmc3zT7yBPUKC4Sk24Me3IOOum2DhNID/l/PLtxUIk3Rzz49PJZECUsIKnT7k6KvZ5nWe5sEUupCBgdKjG4=,iv:Axpml84/6wgBxld94AB+Ybdo3r/7Bym6Lsj/49P7jWE=,tag:wXAx3AoopQS7i6rbo70AYg==,type:str]
     pgp:
-        - created_at: "2022-10-12T16:48:23Z"
+        - created_at: "2023-12-29T15:25:27Z"
           enc: |
             -----BEGIN PGP MESSAGE-----
 
-            hQEMA7x7stsXx45CAQf/QKXxlgFzUn5ZS02JDiOLds6wjsiTbwQeIy+den+qH9KF
-            CyfC/8WhxojyhliG0zUzQ7oHtYYkbknF2DyrR7J4+S3SyvMS6MDGTUUn5dIcGwBO
-            2/Q2bt4ayOJFNTPePA0IfuMYNUiMl5B/0GCFRV9DE+gG/dcsOzM5q1Uya/yJ1966
-            RndWwbnE4j5yP4Nj2o3OiZFhlNi6W6UffYB0hsTTPmmebIZltDRbmLSSpKcfNEYw
-            h3st3WaJ0BCuQC5i/kvYTfJyBCoYnvFrb3RmXm3h+MvW0JZwHzfbST3nJCBHh5XJ
-            fVquF17oDJzn5S7EdWMhUbWwHgZwz2J6sZMgGEQ6WdJeAf2IlCuRYGjQMcB1WhxH
-            GCgbzUGoOGrxT3euzz9R1J98d1HQqtpFgeg9JgWndUdhoF80+AU7Wpyy6qOg2n/4
-            wCcb4pcqG1OqFezauEu8+sFdE07vfLoWzxJIark8WA==
-            =pc2z
+            hQEMA7x7stsXx45CAQf/RWxP6z7xjV5TqiA6lFhtygjrH9x3y1DUWG9aUb/dO+xH
+            zDbGMYqGe9RPlgi5sWPstdKXvCgs+AKNj93qJYMwEtaasJOinYXCGeAQmzg90+pt
+            bS6SoBHhGIxAvvLKKPtYx0V50I2reYR+32ux9bcrnzwIsV0P7/SSp1Cl8H+sotB8
+            yf+0ULXcpC+SYECmZqzR9qQ3S+3I6/+QS+QgWj4NsyF+apxnE9oQDcBLdYP4aKgR
+            JHERA9HYfDTKoS137pFHxgINqHkFRY6lhoZdz1yDzOjiPxd8YVfPdKyf022Rg+cX
+            J/Q2P+OhNZEG3gapNATp6wH3niovA89KwZKSmbTZOdJeAZ6NV6TiUP+TgGg5+CmV
+            pSLaGel2NZRnFVNdDFi0dsOwhHv3FpKhIpALJh08/jsmAAslfE7vVlcEnaoUJPTS
+            3v86AACUC5D/gUxmFrrED1qoxbELCmZ17xTwjQzxwg==
+            =KzdF
             -----END PGP MESSAGE-----
           fp: 535B61015823443941C744DD12264F6BBDFABA89
-        - created_at: "2022-10-12T16:48:23Z"
+        - created_at: "2023-12-29T15:25:27Z"
           enc: |
             -----BEGIN PGP MESSAGE-----
 
-            hQIMA2HlP5TKoxTkARAAl+2Y+pd5oraYLgiiJ0CbMFef0zCpFwBwUCyzykMOICGa
-            TWCYs8K6hChjepe0p8+oZnp0wi8U1qrmgRtFljQfHoXq5EXDYKydkz8XHHDI7/W7
-            1BmETajv9Mx7j4BFNB3z0XvLJTPeNhygemuHhox5pA8CUt5FkYahpzYR9AlLiAwx
-            NtU+csrcGUqYllT5WYIKFVIwFk07IvgK/7vj3filO5G2GMiH7lsV6p7W/MYqCFTV
-            grE383/bGCT18XmHpe3Uu0NcotexiqKSXpnFNntWOgd/KynBn8Oa/DMr8ci/4QSF
-            rEV4+IGJSmfAzQYaIfzNRGyTQJKBFiXWQv53GWT9Y5EbdEYEBhyqlIaV5fp/61X+
-            8zhLz3b6QMkNkI6mNVVLK96g2p0dhVoq+R3Wlj/RIVDw/BzH+vJIArQhc8T2NEOX
-            lmLFTMoTRXPrw/UZKMoO+JSDwt2p3WI0sb/ThS+bd7eymxt5lFW1Ikc4Jgd/iHHu
-            JtUZ78i8jAV/nBJPaAYXoRxfpcAMFqJCnxTwCoF7vYP6hHeYW9PPqsClPxQ97TrO
-            /Ei01e9YSfdtIzKcwkOThffRr+7hxwEGQ3EZ+2ShOW9ASfLkIo4MgoLtDAoHCK5E
-            vc2JGWP+vlylTVnZ46Hp8BMRlSjdkS/qGU0lSTPC3q+PllCF2gkN6ZcdLv5L2DDS
-            UAFD70TIN2QAiYEZW6jxg2UtO9ULLT5NgrvfHD9aGAk7jIxeY+nH3S7KqFgmA21c
-            IkNZJSX/J85d13+kJADms3vI7uMOcSUiInaQHy9Cqjrr
-            =fnOr
+            hQIMA/3lh+ZzfS28ARAAm729dMouF7juUeHAb+aHMoyZVKsXapxnxebkjE/LSIbz
+            IEZwegTNrtxQJLclV4Km2gUaBTcE4vLJCpB7YxZvk7JV9OdVKi97o9PcXUXbz9ej
+            /WomnEvFyyxTZGTiHU+L4kNudl8UAKhTt3P4fR3PLpTily75Kn53tzLFJuCO8fAY
+            I/YwQAzayxhPcxk3FuPsD/ONiG7mW8n2ZwfwgOkKXwnrlJv7DreKJRYzu/EeuvX/
+            d4oz+k+xofniOeZmQjZllzR7/++MBg/e1U9VocN1EAWpWHP5taLiThfnVSGDhlQM
+            +4WT5ezH6EuUQlAyQNpDaCincBvCHInhrNlUPOpW51nHMb0y3n4x2hMtZA0JbYEu
+            mkWTYDe65cHjImHXQk9oO2/v4oIyq7ywHX7g2hqVbbiLHZqqTaGfV8lP30+r6/UQ
+            29iAdWac1hY5HDzwbqpY6b38i60j4bkiS83xqrGYBy037bCFk1oHJqwxp5P7vrzr
+            rTv5NBr95BlwF+s8xPEPZneaEu7N3UnhhSzDWp1jgsCxN9b/XHarchNt70xEt2VS
+            xpgs9GEXhsJcbrFNPYqTkFb8vjLFI+poGPTfadW17j4Pp5ftIBRNdKvDG0ni/AIp
+            K98R/nvaHEFuX31SkL8ZUIRqhJm3JVqilFxLAJrqGuSN3jA6wKrimUYpK+t+64jS
+            WAEN9jHYFQDTVHix3g15S5YTGh5ROyqxouDhvSDFTmGtbm5W/HYgnkZmh53TgVeJ
+            Rph/O9QptculzTN+nEqshBhbjhl/uDsLsjLYo/O1AyCwTUSd3OKn6uU=
+            =zThh
             -----END PGP MESSAGE-----
-          fp: 7762ec55a5727cabada621d961e53f94caa314e4
+          fp: 2f5caa73e7ceea4fcc8d2881fde587e6737d2dbc
     unencrypted_suffix: _unencrypted
-    version: 3.7.3
+    version: 3.8.1

From ebc45a9af1e8d7515887e66db5b129859b867b7e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 29 Dec 2023 16:11:46 +0100
Subject: [PATCH 115/212] treewide: Upgrade to NixOS 23.11

---
 configuration/services/nextcloud.nix |  9 ++--
 configuration/services/postgres.nix  |  8 +--
 flake.lock                           | 76 +++++++++++++++++-----------
 flake.nix                            |  2 +-
 pkgs/mkNextcloudApp.nix              |  1 +
 5 files changed, 54 insertions(+), 42 deletions(-)

diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 81f38a3..75993c3 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -11,7 +11,6 @@ in {
     inherit hostName;
 
     package = nextcloud;
-    enableBrokenCiphersForSSE = false;
     enable = true;
     maxUploadSize = "2G";
     https = true;
@@ -30,11 +29,9 @@ in {
       defaultPhoneRegion = "AT";
     };
 
-    phpOptions =
-      options.services.nextcloud.phpOptions.default
-      // {
-        "opcache.interned_strings_buffer" = "16";
-      };
+    phpOptions = {
+      "opcache.interned_strings_buffer" = "16";
+    };
 
     extraApps = {
       inherit (pkgs.local) bookmarks calendar contacts cookbook news notes;
diff --git a/configuration/services/postgres.nix b/configuration/services/postgres.nix
index 923007d..018dc6e 100644
--- a/configuration/services/postgres.nix
+++ b/configuration/services/postgres.nix
@@ -18,15 +18,11 @@
     ensureUsers = [
       {
         name = "grafana";
-        ensurePermissions = {
-          "DATABASE grafana" = "ALL PRIVILEGES";
-        };
+        ensureDBOwnership = true;
       }
       {
         name = "nextcloud";
-        ensurePermissions = {
-          "DATABASE nextcloud" = "ALL PRIVILEGES";
-        };
+        ensureDBOwnership = true;
       }
     ];
 
diff --git a/flake.lock b/flake.lock
index b64bc75..3a73266 100644
--- a/flake.lock
+++ b/flake.lock
@@ -41,11 +41,11 @@
         "utils": "utils"
       },
       "locked": {
-        "lastModified": 1694513707,
-        "narHash": "sha256-wE5kHco3+FQjc+MwTPwLVqYz4hM7uno2CgXDXUFMCpc=",
+        "lastModified": 1703087360,
+        "narHash": "sha256-0VUbWBW8VyiDRuimMuLsEO4elGuUw/nc2WDeuO1eN1M=",
         "owner": "serokell",
         "repo": "deploy-rs",
-        "rev": "31c32fb2959103a796e07bbe47e0a5e287c343a8",
+        "rev": "b709d63debafce9f5645a5ba550c9e0983b3d1f7",
         "type": "github"
       },
       "original": {
@@ -160,11 +160,11 @@
     "flake-compat": {
       "flake": false,
       "locked": {
-        "lastModified": 1668681692,
-        "narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=",
+        "lastModified": 1696426674,
+        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
         "owner": "edolstra",
         "repo": "flake-compat",
-        "rev": "009399224d5e398d03b22badca40a37ac85412a1",
+        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
         "type": "github"
       },
       "original": {
@@ -229,7 +229,7 @@
     },
     "flake-utils": {
       "inputs": {
-        "systems": "systems"
+        "systems": "systems_2"
       },
       "locked": {
         "lastModified": 1692799911,
@@ -267,11 +267,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1691701569,
-        "narHash": "sha256-7TK+sO+JC37OGTQDTiz9TriqbB5yTgoo7fyPyLtWvd8=",
+        "lastModified": 1701473318,
+        "narHash": "sha256-QdCJN8GeNl/V8wMjrvNkrWzNXnahgfjBfCSya4qQdrc=",
         "owner": "reckenrode",
         "repo": "nix-foundryvtt",
-        "rev": "3358ccef0ea3e06faabe8c54761fb8a0862b80d4",
+        "rev": "f624c0ceabe13dd876ecff871e0dc7f55f96e993",
         "type": "github"
       },
       "original": {
@@ -345,11 +345,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1671417167,
-        "narHash": "sha256-JkHam6WQOwZN1t2C2sbp1TqMv3TVRjzrdoejqfefwrM=",
+        "lastModified": 1702272962,
+        "narHash": "sha256-D+zHwkwPc6oYQ4G3A1HuadopqRwUY/JkMwHz1YF7j4Q=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "bb31220cca6d044baa6dc2715b07497a2a7c4bc7",
+        "rev": "e97b3e4186bcadf0ef1b6be22b8558eab1cdeb5d",
         "type": "github"
       },
       "original": {
@@ -361,11 +361,11 @@
     },
     "nixpkgs-stable": {
       "locked": {
-        "lastModified": 1693675694,
-        "narHash": "sha256-2pIOyQwGyy2FtFAUIb8YeKVmOCcPOTVphbAvmshudLE=",
+        "lastModified": 1703351344,
+        "narHash": "sha256-9FEelzftkE9UaJ5nqxidaJJPEhe9TPhbypLHmc2Mysc=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "5601118d39ca9105f8e7b39d4c221d3388c0419d",
+        "rev": "7790e078f8979a9fcd543f9a47427eeaba38f268",
         "type": "github"
       },
       "original": {
@@ -377,11 +377,11 @@
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1694767346,
-        "narHash": "sha256-5uH27SiVFUwsTsqC5rs3kS7pBoNhtoy9QfTP9BmknGk=",
+        "lastModified": 1703637592,
+        "narHash": "sha256-8MXjxU0RfFfzl57Zy3OfXCITS0qWDNLzlBAdwxGZwfY=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "ace5093e36ab1e95cb9463863491bee90d5a4183",
+        "rev": "cfc3698c31b1fb9cdcf10f36c9643460264d0ca8",
         "type": "github"
       },
       "original": {
@@ -408,16 +408,16 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1694937365,
-        "narHash": "sha256-iHZSGrb9gVpZRR4B2ishUN/1LRKWtSHZNO37C8z1SmA=",
+        "lastModified": 1703467016,
+        "narHash": "sha256-/5A/dNPhbQx/Oa2d+Get174eNI3LERQ7u6WTWOlR1eQ=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "5d017a8822e0907fb96f7700a319f9fe2434de02",
+        "rev": "d02d818f22c777aa4e854efc3242ec451e5d462a",
         "type": "github"
       },
       "original": {
         "owner": "nixos",
-        "ref": "nixos-23.05",
+        "ref": "nixos-23.11",
         "repo": "nixpkgs",
         "type": "github"
       }
@@ -556,11 +556,11 @@
         "nixpkgs-stable": "nixpkgs-stable"
       },
       "locked": {
-        "lastModified": 1694495315,
-        "narHash": "sha256-sZEYXs9T1NVHZSSbMqBEtEm2PGa7dEDcx0ttQkArORc=",
+        "lastModified": 1703387502,
+        "narHash": "sha256-JnWuQmyanPtF8c5yAEFXVWzaIlMxA3EAZCh8XNvnVqE=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "ea208e55f8742fdcc0986b256bdfa8986f5e4415",
+        "rev": "e523e89763ff45f0a6cf15bcb1092636b1da9ed3",
         "type": "github"
       },
       "original": {
@@ -584,6 +584,21 @@
         "type": "github"
       }
     },
+    "systems_2": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    },
     "tlaternet-webserver": {
       "inputs": {
         "dream2nix": "dream2nix",
@@ -607,12 +622,15 @@
       }
     },
     "utils": {
+      "inputs": {
+        "systems": "systems"
+      },
       "locked": {
-        "lastModified": 1667395993,
-        "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
+        "lastModified": 1701680307,
+        "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
+        "rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
         "type": "github"
       },
       "original": {
diff --git a/flake.nix b/flake.nix
index d8ff1a8..efe6433 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,7 +2,7 @@
   description = "tlater.net host configuration";
 
   inputs = {
-    nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
+    nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
     nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
     deploy-rs.url = "github:serokell/deploy-rs";
     sops-nix = {
diff --git a/pkgs/mkNextcloudApp.nix b/pkgs/mkNextcloudApp.nix
index 6430ac1..9bf6b26 100644
--- a/pkgs/mkNextcloudApp.nix
+++ b/pkgs/mkNextcloudApp.nix
@@ -5,4 +5,5 @@
 fetchNextcloudApp {
   url = source.src.url;
   sha256 = source.src.sha256;
+  license = "unlicense"; # Blatant lie
 }

From 54e0826860113a47245689b7135c3d3159b378e5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 29 Dec 2023 16:11:16 +0100
Subject: [PATCH 116/212] gitea: Migrate to forgejo

---
 configuration/services/gitea.nix              | 81 +++++++++----------
 .../services/metrics/victoriametrics.nix      |  6 +-
 configuration/sops.nix                        |  4 +-
 keys/production.yaml                          | 10 +--
 keys/staging.yaml                             |  8 +-
 5 files changed, 53 insertions(+), 56 deletions(-)

diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index 013842e..d77d6cc 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -6,12 +6,10 @@
 }: let
   domain = "gitea.${config.services.nginx.domain}";
 in {
-  services.gitea = {
+  services.forgejo = {
     enable = true;
     database.type = "postgres";
 
-    appName = "Gitea: Git with a cup of tea";
-
     settings = {
       server = {
         DOMAIN = domain;
@@ -29,18 +27,18 @@ in {
     };
   };
 
-  systemd.services.gitea.serviceConfig.ExecStartPre = let
+  systemd.services.forgejo.serviceConfig.ExecStartPre = let
     replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret";
-    secretPath = config.sops.secrets."gitea/metrics-token".path;
-    runConfig = "${config.services.gitea.customDir}/conf/app.ini";
+    secretPath = config.sops.secrets."forgejo/metrics-token".path;
+    runConfig = "${config.services.forgejo.customDir}/conf/app.ini";
   in [
     "+${replaceSecretBin} '#metricstoken#' '${secretPath}' '${runConfig}'"
   ];
 
   # Set up SSL
   services.nginx.virtualHosts."${domain}" = let
-    httpAddress = config.services.gitea.settings.server.HTTP_ADDR;
-    httpPort = config.services.gitea.settings.server.HTTP_PORT;
+    httpAddress = config.services.forgejo.settings.server.HTTP_ADDR;
+    httpPort = config.services.forgejo.settings.server.HTTP_PORT;
   in {
     forceSSL = true;
     enableACME = true;
@@ -62,40 +60,39 @@ in {
 
   # Block repeated failed login attempts
   #
-  # TODO(tlater): Update to the new regex, since apparently this one
-  # is deprecated (but the new one doesn't work on the current version
-  # of gitea yet): https://docs.gitea.io/en-us/fail2ban-setup/
-  environment.etc = {
-    "fail2ban/filter.d/gitea.conf".text = ''
-      [Definition]
-      failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>
-      journalmatch = _SYSTEMD_UNIT=gitea.service + _COMM=gitea + SYSLOG_IDENTIFIER=gitea
-    '';
-  };
+  # TODO(tlater): Update this - we switched to forgejo, who knows what
+  # the new matches are.
+  # environment.etc = {
+  #   "fail2ban/filter.d/gitea.conf".text = ''
+  #     [Definition]
+  #     failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>
+  #     journalmatch = _SYSTEMD_UNIT=forgejo.service + _COMM=forgejo + SYSLOG_IDENTIFIER=forgejo
+  #   '';
+  # };
 
-  services.fail2ban.jails = {
-    gitea = ''
-      enabled = true
-    '';
-  };
+  # services.fail2ban.jails = {
+  #   gitea = ''
+  #     enabled = true
+  #   '';
+  # };
 
-  services.backups.gitea = {
-    user = "gitea";
-    paths = [
-      "/var/lib/gitea/gitea-db.sql"
-      "/var/lib/gitea/repositories/"
-      "/var/lib/gitea/data/"
-      "/var/lib/gitea/custom/"
-      # Conf is backed up via nix
-    ];
-    preparation = {
-      packages = [config.services.postgresql.package];
-      text = "pg_dump ${config.services.gitea.database.name} --file=/var/lib/gitea/gitea-db.sql";
-    };
-    cleanup = {
-      packages = [pkgs.coreutils];
-      text = "rm /var/lib/gitea/gitea-db.sql";
-    };
-    pauseServices = ["gitea.service"];
-  };
+  # services.backups.forgejo = {
+  #   user = "forgejo";
+  #   paths = [
+  #     "/var/lib/forgejo/forgejo-db.sql"
+  #     "/var/lib/forgejo/repositories/"
+  #     "/var/lib/forgejo/data/"
+  #     "/var/lib/forgejo/custom/"
+  #     # Conf is backed up via nix
+  #   ];
+  #   preparation = {
+  #     packages = [config.services.postgresql.package];
+  #     text = "pg_dump ${config.services.forgejo.database.name} --file=/var/lib/forgejo/forgejo-db.sql";
+  #   };
+  #   cleanup = {
+  #     packages = [pkgs.coreutils];
+  #     text = "rm /var/lib/forgejo/forgejo-db.sql";
+  #   };
+  #   pauseServices = ["forgejo.service"];
+  # };
 }
diff --git a/configuration/services/metrics/victoriametrics.nix b/configuration/services/metrics/victoriametrics.nix
index 4cdc770..daf3f94 100644
--- a/configuration/services/metrics/victoriametrics.nix
+++ b/configuration/services/metrics/victoriametrics.nix
@@ -6,9 +6,9 @@
     ];
 
     scrapeConfigs = {
-      gitea = {
-        targets = ["127.0.0.1:${toString config.services.gitea.settings.server.HTTP_PORT}"];
-        extraSettings.authorization.credentials_file = config.sops.secrets."gitea/metrics-token".path;
+      forgejo = {
+        targets = ["127.0.0.1:${toString config.services.forgejo.settings.server.HTTP_PORT}"];
+        extraSettings.authorization.credentials_file = config.sops.secrets."forgejo/metrics-token".path;
       };
       coturn.targets = ["127.0.0.1:9641"];
     };
diff --git a/configuration/sops.nix b/configuration/sops.nix
index 03faf82..c7cb1f0 100644
--- a/configuration/sops.nix
+++ b/configuration/sops.nix
@@ -4,8 +4,8 @@
 
     secrets = {
       # Gitea
-      "gitea/metrics-token" = {
-        owner = "gitea";
+      "forgejo/metrics-token" = {
+        owner = "forgejo";
         group = "metrics";
         mode = "0440";
       };
diff --git a/keys/production.yaml b/keys/production.yaml
index efeea6a..da53b95 100644
--- a/keys/production.yaml
+++ b/keys/production.yaml
@@ -1,5 +1,5 @@
-gitea:
-    metrics-token: ENC[AES256_GCM,data:/7/zvVl2ZOBoekrJR32vl/QQcG5XqTmltgpHEMUpbXVeqwnq29idzE2Qyjau96ZHObmSI73/ZtW95uXF6LH9Qw==,iv:iWZECCZSh1CN7wMBqstXR5QWtriR7QLKVqhekGnpXl0=,tag:HEr9km8VYmruBzf0I/5HuA==,type:str]
+forgejo:
+    metrics-token: ENC[AES256_GCM,data:WVbD5JloJlHNjeEwe1uEd4Haj6L3ilj1Pnux6yrelUQP18ZPAh90aDO1OIZHaPJR7tTeyATr8BIzZL1zkNhCuA==,iv:eTYXN3hymIN3bTX1YxNGkAYE0KVDbdz2ds8UQAHlALE=,tag:A61loGdu0pfsiez96u2Qsg==,type:str]
 grafana:
     adminPassword: ENC[AES256_GCM,data:/qw//J7cOkIGa58bG4GgdzndvKof32AmQeWB00IX8WhA22PDCOc4VdUEoB3wVJJqI/ucoHFInYyhg2rFYoYBesBjAt0QS3+O+8WblIunUuYeqlBuYJJK1TLhy6ql6+aqvfiW/rJLm4LpgA7CboyDD2OYHcAbvGSD2GWwFcHTR/Y=,iv:KK6p8GKzc9SBDZZFkEwCdIjSxriPGNMDNcr97tfbwTI=,tag:gLRNSGdJWFD+V9K5TfJvXw==,type:str]
     secretKey: ENC[AES256_GCM,data:OUXWOE6I3a26SrFEOczWNIwyR3Rx62fbsRBBcfh0xyEbxOIPhexH6lIqlVG9Ltwra9+rAldNM4/0BydtxIDj7A==,iv:fiNO/or5yZnhpDPMANDnEC5dtXmbKBZsV+BPmvCN/HI=,tag:Q0M0OtLWdWAJgQmUlL//fg==,type:str]
@@ -26,8 +26,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2023-10-12T18:40:26Z"
-    mac: ENC[AES256_GCM,data:F+yQ20jCtLRKeQDFVKoqrYCgtwGkXxrK6aQO0MFZTIMJAnbTVPM2ZJGQ1RxXb+Zs4T+44EEc2xN4LjeANvgpE6MfOz2VTw+sEEjcYwUyB6RcXHia9XlFLa8lh7/Wx/9DxlSFjjSrxmDkNB6r+n5UF81cdRXF2E9ibdH346ST98A=,iv:xVxFN1IDKrLskaGqnWvOWx1zUII0jRSjQxEsaTf2GNw=,tag:lnp1AvgMOXXlg1vFjHEWUQ==,type:str]
+    lastmodified: "2023-12-28T00:07:08Z"
+    mac: ENC[AES256_GCM,data:P2bNJLjzn69Kg2bJHXmofER7J8wbEj9C4jq9ePWewXBOt45GEiqgnqIaISwZkyzQmm9cxZd95Lr780ICwoKDFdtSCCcC7CdYxYEfyyhnvU3W2qzEghvkypL8JbiEtPSlQ9xOlCk7p41A9eRrV+JziIVSv5UEUs4NubrG9Mkwv3k=,iv:Yq2gANTTgx6cFxkdustUZ1MPszxGSkao/bS1KHAkzJc=,tag:kqJibocgRQXkxTJze6O5MA==,type:str]
     pgp:
         - created_at: "2022-10-12T00:46:51Z"
           enc: |
@@ -65,4 +65,4 @@ sops:
             -----END PGP MESSAGE-----
           fp: 8a3737d48f1035fe6c3a0a8fd6a1976ca74c7f3b
     unencrypted_suffix: _unencrypted
-    version: 3.7.3
+    version: 3.8.1
diff --git a/keys/staging.yaml b/keys/staging.yaml
index fb1d15d..de7686b 100644
--- a/keys/staging.yaml
+++ b/keys/staging.yaml
@@ -1,5 +1,5 @@
-gitea:
-    metrics-token: ENC[AES256_GCM,data:T1NYXRWbruA=,iv:usgHYHwWJFbaEdHLO6JX3z/42MVheY2wu0YrXmnz2ng=,tag:W+B7pKGOc/wX/0My0dWY5w==,type:str]
+forgejo:
+    metrics-token: ENC[AES256_GCM,data:HEDV/GK/WtI=,iv:ihPEusEGVUNZjjjxz2ys6Nfag/og4n7Cqmd4rroT6Ww=,tag:Brcv7XW6HfzzgF3emtuT2A==,type:str]
 grafana:
     adminPassword: ENC[AES256_GCM,data:dYfaxUpQpzA=,iv:j5wSem8C5+V4c5qRzXQJhsU7/FOtpvrnaEyFBmW6zJ4=,tag:oc8n3TkEbjF2gjuOobZuLA==,type:str]
     secretKey: ENC[AES256_GCM,data:Atruvh2MsNY=,iv:y2MaCUCEzGIydHp6G0DJHfk289S1is0twKm2oUYwDhM=,tag:nAWeg+YqaYqk6k22oBkAhQ==,type:str]
@@ -26,8 +26,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2023-12-29T15:14:54Z"
-    mac: ENC[AES256_GCM,data:yJUprLcfw4ypsrSlhot7vsavVqzaFlJoJeEC/DdTfKDoJ0L607r6aCfXtCSg+qrR5JA2bvEATwDJM5qgA2vbMhSOqmc3zT7yBPUKC4Sk24Me3IOOum2DhNID/l/PLtxUIk3Rzz49PJZECUsIKnT7k6KvZ5nWe5sEUupCBgdKjG4=,iv:Axpml84/6wgBxld94AB+Ybdo3r/7Bym6Lsj/49P7jWE=,tag:wXAx3AoopQS7i6rbo70AYg==,type:str]
+    lastmodified: "2023-12-30T14:09:03Z"
+    mac: ENC[AES256_GCM,data:kuyzVV1Dhlb2LemqRzw2xPr9jtTWqSbFMv70LUEbRmsDpjwQsAIARgoaj32EXdDRTHYXBplTYieR7KvmxykL/8rkj0g4+IuRLY1TcbRS31Gi74FiXvV2apscHhQWXhHPHIHMbwZAfDSHdMrf8hPu28SC9QdbP3SXYNt28Imstrc=,iv:UALUiWGHlWEBmIVWeSyEa16ZdcDZvgtlpHETDV2CcRY=,tag:rxbd3ph+pPf11jup/CMEzw==,type:str]
     pgp:
         - created_at: "2023-12-29T15:25:27Z"
           enc: |

From ddda6f534b722493696bb6a946ca44ea8293a216 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 2 Mar 2024 02:27:24 +0100
Subject: [PATCH 117/212] hetzner: Add new server config

---
 .sops.yaml                                    |   2 +
 configuration/default.nix                     |   2 +-
 .../hardware-specific/hetzner/default.nix     |  47 +++
 .../hardware-specific/hetzner/disko.nix       |  82 ++++
 .../hetzner/hardware-configuration.nix        |  25 ++
 configuration/hardware-specific/vm.nix        |   1 +
 configuration/services/gitea.nix              |  38 +-
 flake.lock                                    | 364 ++++--------------
 flake.nix                                     |  42 +-
 keys/hosts/hetzner1.asc                       |  28 ++
 keys/production.yaml                          |  79 ++--
 11 files changed, 373 insertions(+), 337 deletions(-)
 create mode 100644 configuration/hardware-specific/hetzner/default.nix
 create mode 100644 configuration/hardware-specific/hetzner/disko.nix
 create mode 100644 configuration/hardware-specific/hetzner/hardware-configuration.nix
 create mode 100644 keys/hosts/hetzner1.asc

diff --git a/.sops.yaml b/.sops.yaml
index dc2021d..7444d2c 100644
--- a/.sops.yaml
+++ b/.sops.yaml
@@ -1,6 +1,7 @@
 keys:
   - &tlater 535B61015823443941C744DD12264F6BBDFABA89
   - &server_tlaternet 8a3737d48f1035fe6c3a0a8fd6a1976ca74c7f3b
+  - &server_hetzner1 0af7641adb8aa843136cf6d047f71da3e5ad79f9
   - &server_staging 2f5caa73e7ceea4fcc8d2881fde587e6737d2dbc
 
 creation_rules:
@@ -9,6 +10,7 @@ creation_rules:
       - pgp:
           - *tlater
           - *server_tlaternet
+          - *server_hetzner1
   - path_regex: keys/staging.yaml
     key_groups:
       - pgp:
diff --git a/configuration/default.nix b/configuration/default.nix
index 6f7cf41..34b1f42 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -7,6 +7,7 @@
   ...
 }: {
   imports = [
+    flake-inputs.disko.nixosModules.disko
     flake-inputs.sops-nix.nixosModules.sops
     flake-inputs.tlaternet-webserver.nixosModules.default
 
@@ -55,7 +56,6 @@
   boot.kernelParams = ["highres=off" "nohz=off"];
 
   networking = {
-    hostName = "tlaternet";
     usePredictableInterfaceNames = false;
     useDHCP = false;
 
diff --git a/configuration/hardware-specific/hetzner/default.nix b/configuration/hardware-specific/hetzner/default.nix
new file mode 100644
index 0000000..5ecf63a
--- /dev/null
+++ b/configuration/hardware-specific/hetzner/default.nix
@@ -0,0 +1,47 @@
+{
+  imports = [
+    ./hardware-configuration.nix
+    ./disko.nix
+  ];
+
+  # Intel's special encrypted memory<->CPU feature. Hetzner's BIOS
+  # disables it by default.
+  #
+  # TODO(tlater): See if would be useful for anything?
+  boot.kernelParams = ["nosgx"];
+
+  networking.hostName = "hetzner-1";
+  services.nginx.domain = "tlater.net";
+
+  systemd.network.networks."eth0" = {
+    matchConfig.MACAddress = "90:1b:0e:c1:8c:62";
+
+    addresses = [
+      # IPv4
+      {
+        addressConfig = {
+          Address = "116.202.158.55/32";
+          Peer = "116.202.158.1/32"; # Gateway
+        };
+      }
+      # IPv6
+      {
+        addressConfig.Address = "2a01:4f8:10b:3c85::2/64";
+      }
+    ];
+
+    networkConfig = {
+      Gateway = [
+        "116.202.158.1"
+        "fe80::1"
+      ];
+
+      DNS = [
+        "185.12.64.1"
+        "185.12.64.2"
+        "2a01:4ff:ff00::add:1"
+        "2a01:4ff:ff00::add:2"
+      ];
+    };
+  };
+}
diff --git a/configuration/hardware-specific/hetzner/disko.nix b/configuration/hardware-specific/hetzner/disko.nix
new file mode 100644
index 0000000..e404688
--- /dev/null
+++ b/configuration/hardware-specific/hetzner/disko.nix
@@ -0,0 +1,82 @@
+{
+  disko.devices.disk = let
+    bootPartition = {
+      size = "1M";
+      type = "EF02";
+    };
+
+    swapPartition = {
+      # 8G is apparently recommended for this much RAM, but we set up
+      # 4G on both disks for mirroring purposes.
+      #
+      # That'll still be 8G during normal operation, and it's probably
+      # not too bad to have slightly less swap if a disk dies.
+      size = "4G";
+      content = {
+        type = "swap";
+        randomEncryption = true;
+      };
+    };
+
+    mountOptions = ["compress=zstd" "noatime"];
+  in {
+    sda = {
+      type = "disk";
+      device = "/dev/sda";
+      content = {
+        type = "gpt";
+        partitions = {
+          boot = bootPartition;
+          swap = swapPartition;
+
+          disk1 = {
+            size = "100%";
+            # Empty partition to combine in RAID0 with the other disk
+          };
+        };
+      };
+    };
+
+    sdb = {
+      type = "disk";
+      device = "/dev/sdb";
+      content = {
+        type = "gpt";
+        partitions = {
+          boot = bootPartition;
+          swap = swapPartition;
+
+          disk2 = {
+            size = "100%";
+            content = {
+              type = "btrfs";
+              # Hack to get multi-device btrfs going
+              # See https://github.com/nix-community/disko/issues/99
+              extraArgs = ["-d" "raid1" "-m" "raid1" "--runtime-features" "quota" "/dev/sda3"];
+              subvolumes = {
+                "/volume" = {};
+                "/volume/root" = {
+                  inherit mountOptions;
+                  mountpoint = "/";
+                };
+                "/volume/home" = {
+                  inherit mountOptions;
+                  mountpoint = "/home";
+                };
+                "/volume/var" = {
+                  inherit mountOptions;
+                  mountpoint = "/var";
+                };
+                "/volume/nix-store" = {
+                  inherit mountOptions;
+                  mountpoint = "/nix";
+                };
+                "/snapshots" = {};
+              };
+            };
+          };
+        };
+      };
+    };
+  };
+}
diff --git a/configuration/hardware-specific/hetzner/hardware-configuration.nix b/configuration/hardware-specific/hetzner/hardware-configuration.nix
new file mode 100644
index 0000000..e7a99f9
--- /dev/null
+++ b/configuration/hardware-specific/hetzner/hardware-configuration.nix
@@ -0,0 +1,25 @@
+# Do not modify this file!  It was generated by ‘nixos-generate-config’
+# and may be overwritten by future invocations.  Please make changes
+# to /etc/nixos/configuration.nix instead.
+{ config, lib, pkgs, modulesPath, ... }:
+
+{
+  imports =
+    [ (modulesPath + "/installer/scan/not-detected.nix")
+    ];
+
+  boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "sd_mod" ];
+  boot.initrd.kernelModules = [ ];
+  boot.kernelModules = [ "kvm-intel" ];
+  boot.extraModulePackages = [ ];
+
+  # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
+  # (the default) this is the recommended approach. When using systemd-networkd it's
+  # still possible to use this option, but it's recommended to use it in conjunction
+  # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
+  networking.useDHCP = lib.mkDefault true;
+  # networking.interfaces.enp0s31f6.useDHCP = lib.mkDefault true;
+
+  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
+  hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
+}
diff --git a/configuration/hardware-specific/vm.nix b/configuration/hardware-specific/vm.nix
index 32423ab..79f4b35 100644
--- a/configuration/hardware-specific/vm.nix
+++ b/configuration/hardware-specific/vm.nix
@@ -4,6 +4,7 @@
   # Disable graphical tty so -curses works
   boot.kernelParams = ["nomodeset"];
 
+  networking.hostName = "testvm";
   # Sets the base domain for nginx to localhost so that we
   # can easily test locally with the VM.
   services.nginx.domain = lib.mkOverride 99 "localhost";
diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index d77d6cc..41b8583 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -76,23 +76,23 @@ in {
   #   '';
   # };
 
-  # services.backups.forgejo = {
-  #   user = "forgejo";
-  #   paths = [
-  #     "/var/lib/forgejo/forgejo-db.sql"
-  #     "/var/lib/forgejo/repositories/"
-  #     "/var/lib/forgejo/data/"
-  #     "/var/lib/forgejo/custom/"
-  #     # Conf is backed up via nix
-  #   ];
-  #   preparation = {
-  #     packages = [config.services.postgresql.package];
-  #     text = "pg_dump ${config.services.forgejo.database.name} --file=/var/lib/forgejo/forgejo-db.sql";
-  #   };
-  #   cleanup = {
-  #     packages = [pkgs.coreutils];
-  #     text = "rm /var/lib/forgejo/forgejo-db.sql";
-  #   };
-  #   pauseServices = ["forgejo.service"];
-  # };
+  services.backups.forgejo = {
+    user = "forgejo";
+    paths = [
+      "/var/lib/forgejo/forgejo-db.sql"
+      "/var/lib/forgejo/repositories/"
+      "/var/lib/forgejo/data/"
+      "/var/lib/forgejo/custom/"
+      # Conf is backed up via nix
+    ];
+    preparation = {
+      packages = [config.services.postgresql.package];
+      text = "pg_dump ${config.services.forgejo.database.name} --file=/var/lib/forgejo/forgejo-db.sql";
+    };
+    cleanup = {
+      packages = [pkgs.coreutils];
+      text = "rm /var/lib/forgejo/forgejo-db.sql";
+    };
+    pauseServices = ["forgejo.service"];
+  };
 }
diff --git a/flake.lock b/flake.lock
index 3a73266..8a9fadc 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1,39 +1,5 @@
 {
   "nodes": {
-    "all-cabal-json": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1665552503,
-        "narHash": "sha256-r14RmRSwzv5c+bWKUDaze6pXM7nOsiz1H8nvFHJvufc=",
-        "owner": "nix-community",
-        "repo": "all-cabal-json",
-        "rev": "d7c0434eebffb305071404edcf9d5cd99703878e",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nix-community",
-        "ref": "hackage",
-        "repo": "all-cabal-json",
-        "type": "github"
-      }
-    },
-    "crane": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1681175776,
-        "narHash": "sha256-7SsUy9114fryHAZ8p1L6G6YSu7jjz55FddEwa2U8XZc=",
-        "owner": "ipetkov",
-        "repo": "crane",
-        "rev": "445a3d222947632b5593112bb817850e8a9cf737",
-        "type": "github"
-      },
-      "original": {
-        "owner": "ipetkov",
-        "ref": "v0.12.1",
-        "repo": "crane",
-        "type": "github"
-      }
-    },
     "deploy-rs": {
       "inputs": {
         "flake-compat": "flake-compat",
@@ -54,47 +20,38 @@
         "type": "github"
       }
     },
-    "devshell": {
-      "flake": false,
+    "disko": {
+      "inputs": {
+        "nixpkgs": [
+          "nixpkgs"
+        ]
+      },
       "locked": {
-        "lastModified": 1663445644,
-        "narHash": "sha256-+xVlcK60x7VY1vRJbNUEAHi17ZuoQxAIH4S4iUFUGBA=",
-        "owner": "numtide",
-        "repo": "devshell",
-        "rev": "e3dc3e21594fe07bdb24bdf1c8657acaa4cb8f66",
+        "lastModified": 1709286488,
+        "narHash": "sha256-RDpTZ72zLu05djvXRzK76Ysqp9zSdh84ax/edEaJucs=",
+        "owner": "nix-community",
+        "repo": "disko",
+        "rev": "bde7dd352c07d43bd5b8245e6c39074a391fdd46",
         "type": "github"
       },
       "original": {
-        "owner": "numtide",
-        "repo": "devshell",
+        "owner": "nix-community",
+        "repo": "disko",
         "type": "github"
       }
     },
     "dream2nix": {
       "inputs": {
-        "all-cabal-json": "all-cabal-json",
-        "crane": "crane",
-        "devshell": "devshell",
-        "drv-parts": "drv-parts",
-        "flake-compat": "flake-compat_3",
-        "flake-parts": "flake-parts",
-        "flake-utils-pre-commit": "flake-utils-pre-commit",
-        "ghc-utils": "ghc-utils",
-        "gomod2nix": "gomod2nix",
-        "mach-nix": "mach-nix",
-        "nix-pypi-fetcher": "nix-pypi-fetcher",
         "nixpkgs": "nixpkgs_3",
-        "nixpkgsV1": "nixpkgsV1",
-        "poetry2nix": "poetry2nix",
-        "pre-commit-hooks": "pre-commit-hooks",
-        "pruned-racket-catalog": "pruned-racket-catalog"
+        "purescript-overlay": "purescript-overlay",
+        "pyproject-nix": "pyproject-nix"
       },
       "locked": {
-        "lastModified": 1686064783,
-        "narHash": "sha256-qyptOk4vDut2JkRMJ+815eJNqqd8gIfjpz3l4WCCtMY=",
+        "lastModified": 1702457430,
+        "narHash": "sha256-8NQiXtYCOiC7XFayy6GPGDudCBrPROry3mfWjpdVj5g=",
         "owner": "nix-community",
         "repo": "dream2nix",
-        "rev": "0c064fa9dd025069cc215b0a8b4eb5ea734aceb0",
+        "rev": "262198033e23e9ee832f0cc8133d38f07598f555",
         "type": "github"
       },
       "original": {
@@ -103,38 +60,6 @@
         "type": "github"
       }
     },
-    "drv-parts": {
-      "inputs": {
-        "flake-compat": [
-          "tlaternet-webserver",
-          "dream2nix",
-          "flake-compat"
-        ],
-        "flake-parts": [
-          "tlaternet-webserver",
-          "dream2nix",
-          "flake-parts"
-        ],
-        "nixpkgs": [
-          "tlaternet-webserver",
-          "dream2nix",
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1680698112,
-        "narHash": "sha256-FgnobN/DvCjEsc0UAZEAdPLkL4IZi2ZMnu2K2bUaElc=",
-        "owner": "davhau",
-        "repo": "drv-parts",
-        "rev": "e8c2ec1157dc1edb002989669a0dbd935f430201",
-        "type": "github"
-      },
-      "original": {
-        "owner": "davhau",
-        "repo": "drv-parts",
-        "type": "github"
-      }
-    },
     "fenix": {
       "inputs": {
         "nixpkgs": [
@@ -144,11 +69,11 @@
         "rust-analyzer-src": "rust-analyzer-src"
       },
       "locked": {
-        "lastModified": 1686637310,
-        "narHash": "sha256-sGfKyioVsxQppDM0eDO62wtFiz+bZOD0cBMMIEjqn4I=",
+        "lastModified": 1704003651,
+        "narHash": "sha256-bA3d4E1CX5G7TVbKwJOm9jZfVOGOPp6u5CKEUzNsE8E=",
         "owner": "nix-community",
         "repo": "fenix",
-        "rev": "6fbeedcd2fc1fba77152e13fd7492824d77a4060",
+        "rev": "c6d82e087ac96f24b90c5787a17e29a72566c2b4",
         "type": "github"
       },
       "original": {
@@ -189,44 +114,6 @@
         "type": "github"
       }
     },
-    "flake-compat_3": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1673956053,
-        "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
-        "owner": "edolstra",
-        "repo": "flake-compat",
-        "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
-        "type": "github"
-      },
-      "original": {
-        "owner": "edolstra",
-        "repo": "flake-compat",
-        "type": "github"
-      }
-    },
-    "flake-parts": {
-      "inputs": {
-        "nixpkgs-lib": [
-          "tlaternet-webserver",
-          "dream2nix",
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1675933616,
-        "narHash": "sha256-/rczJkJHtx16IFxMmAWu5nNYcSXNg1YYXTHoGjLrLUA=",
-        "owner": "hercules-ci",
-        "repo": "flake-parts",
-        "rev": "47478a4a003e745402acf63be7f9a092d51b83d7",
-        "type": "github"
-      },
-      "original": {
-        "owner": "hercules-ci",
-        "repo": "flake-parts",
-        "type": "github"
-      }
-    },
     "flake-utils": {
       "inputs": {
         "systems": "systems_2"
@@ -245,21 +132,6 @@
         "type": "github"
       }
     },
-    "flake-utils-pre-commit": {
-      "locked": {
-        "lastModified": 1644229661,
-        "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
-        "type": "github"
-      },
-      "original": {
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "type": "github"
-      }
-    },
     "foundryvtt": {
       "inputs": {
         "nixpkgs": [
@@ -267,11 +139,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1701473318,
-        "narHash": "sha256-QdCJN8GeNl/V8wMjrvNkrWzNXnahgfjBfCSya4qQdrc=",
+        "lastModified": 1709504473,
+        "narHash": "sha256-hXzXxaZaI9Pn5tO4otY2gJUvW/orDGDAMdstm3AY8RU=",
         "owner": "reckenrode",
         "repo": "nix-foundryvtt",
-        "rev": "f624c0ceabe13dd876ecff871e0dc7f55f96e993",
+        "rev": "5cf4e6d9ed7b662dbea7a61d785b67a878598986",
         "type": "github"
       },
       "original": {
@@ -280,69 +152,6 @@
         "type": "github"
       }
     },
-    "ghc-utils": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1662774800,
-        "narHash": "sha256-1Rd2eohGUw/s1tfvkepeYpg8kCEXiIot0RijapUjAkE=",
-        "ref": "refs/heads/master",
-        "rev": "bb3a2d3dc52ff0253fb9c2812bd7aa2da03e0fea",
-        "revCount": 1072,
-        "type": "git",
-        "url": "https://gitlab.haskell.org/bgamari/ghc-utils"
-      },
-      "original": {
-        "type": "git",
-        "url": "https://gitlab.haskell.org/bgamari/ghc-utils"
-      }
-    },
-    "gomod2nix": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1627572165,
-        "narHash": "sha256-MFpwnkvQpauj799b4QTBJQFEddbD02+Ln5k92QyHOSk=",
-        "owner": "tweag",
-        "repo": "gomod2nix",
-        "rev": "67f22dd738d092c6ba88e420350ada0ed4992ae8",
-        "type": "github"
-      },
-      "original": {
-        "owner": "tweag",
-        "repo": "gomod2nix",
-        "type": "github"
-      }
-    },
-    "mach-nix": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1634711045,
-        "narHash": "sha256-m5A2Ty88NChLyFhXucECj6+AuiMZPHXNbw+9Kcs7F6Y=",
-        "owner": "DavHau",
-        "repo": "mach-nix",
-        "rev": "4433f74a97b94b596fa6cd9b9c0402104aceef5d",
-        "type": "github"
-      },
-      "original": {
-        "id": "mach-nix",
-        "type": "indirect"
-      }
-    },
-    "nix-pypi-fetcher": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1669065297,
-        "narHash": "sha256-UStjXjNIuIm7SzMOWvuYWIHBkPUKQ8Id63BMJjnIDoA=",
-        "owner": "DavHau",
-        "repo": "nix-pypi-fetcher",
-        "rev": "a9885ac6a091576b5195d547ac743d45a2a615ac",
-        "type": "github"
-      },
-      "original": {
-        "owner": "DavHau",
-        "repo": "nix-pypi-fetcher",
-        "type": "github"
-      }
-    },
     "nixpkgs": {
       "locked": {
         "lastModified": 1702272962,
@@ -391,21 +200,6 @@
         "type": "github"
       }
     },
-    "nixpkgsV1": {
-      "locked": {
-        "lastModified": 1678500271,
-        "narHash": "sha256-tRBLElf6f02HJGG0ZR7znMNFv/Uf7b2fFInpTHiHaSE=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "5eb98948b66de29f899c7fe27ae112a47964baf8",
-        "type": "github"
-      },
-      "original": {
-        "id": "nixpkgs",
-        "ref": "nixos-22.11",
-        "type": "indirect"
-      }
-    },
     "nixpkgs_2": {
       "locked": {
         "lastModified": 1703467016,
@@ -424,17 +218,18 @@
     },
     "nixpkgs_3": {
       "locked": {
-        "lastModified": 1665580254,
-        "narHash": "sha256-hO61XPkp1Hphl4HGNzj1VvDH5URt7LI6LaY/385Eul4=",
+        "lastModified": 1702272962,
+        "narHash": "sha256-D+zHwkwPc6oYQ4G3A1HuadopqRwUY/JkMwHz1YF7j4Q=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "f634d427b0224a5f531ea5aa10c3960ba6ec5f0f",
+        "rev": "e97b3e4186bcadf0ef1b6be22b8558eab1cdeb5d",
         "type": "github"
       },
       "original": {
-        "id": "nixpkgs",
-        "ref": "nixos-unstable",
-        "type": "indirect"
+        "owner": "NixOS",
+        "ref": "nixpkgs-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
       }
     },
     "nvfetcher": {
@@ -459,70 +254,50 @@
         "type": "github"
       }
     },
-    "poetry2nix": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1666918719,
-        "narHash": "sha256-BkK42fjAku+2WgCOv2/1NrPa754eQPV7gPBmoKQBWlc=",
-        "owner": "nix-community",
-        "repo": "poetry2nix",
-        "rev": "289efb187123656a116b915206e66852f038720e",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nix-community",
-        "ref": "1.36.0",
-        "repo": "poetry2nix",
-        "type": "github"
-      }
-    },
-    "pre-commit-hooks": {
+    "purescript-overlay": {
       "inputs": {
-        "flake-utils": [
-          "tlaternet-webserver",
-          "dream2nix",
-          "flake-utils-pre-commit"
-        ],
         "nixpkgs": [
           "tlaternet-webserver",
           "dream2nix",
           "nixpkgs"
-        ]
+        ],
+        "slimlock": "slimlock"
       },
       "locked": {
-        "lastModified": 1646153636,
-        "narHash": "sha256-AlWHMzK+xJ1mG267FdT8dCq/HvLCA6jwmx2ZUy5O8tY=",
-        "owner": "cachix",
-        "repo": "pre-commit-hooks.nix",
-        "rev": "b6bc0b21e1617e2b07d8205e7fae7224036dfa4b",
+        "lastModified": 1696022621,
+        "narHash": "sha256-eMjFmsj2G1E0Q5XiibUNgFjTiSz0GxIeSSzzVdoN730=",
+        "owner": "thomashoneyman",
+        "repo": "purescript-overlay",
+        "rev": "047c7933abd6da8aa239904422e22d190ce55ead",
         "type": "github"
       },
       "original": {
-        "owner": "cachix",
-        "repo": "pre-commit-hooks.nix",
+        "owner": "thomashoneyman",
+        "repo": "purescript-overlay",
         "type": "github"
       }
     },
-    "pruned-racket-catalog": {
+    "pyproject-nix": {
       "flake": false,
       "locked": {
-        "lastModified": 1672537287,
-        "narHash": "sha256-SuOvXVcLfakw18oJB/PuRMyvGyGG1+CQD3R+TGHIv44=",
-        "owner": "nix-community",
-        "repo": "pruned-racket-catalog",
-        "rev": "c8b89557fb53b36efa2ee48a769c7364df0f6262",
+        "lastModified": 1702448246,
+        "narHash": "sha256-hFg5s/hoJFv7tDpiGvEvXP0UfFvFEDgTdyHIjDVHu1I=",
+        "owner": "davhau",
+        "repo": "pyproject.nix",
+        "rev": "5a06a2697b228c04dd2f35659b4b659ca74f7aeb",
         "type": "github"
       },
       "original": {
-        "owner": "nix-community",
-        "ref": "catalog",
-        "repo": "pruned-racket-catalog",
+        "owner": "davhau",
+        "ref": "dream2nix",
+        "repo": "pyproject.nix",
         "type": "github"
       }
     },
     "root": {
       "inputs": {
         "deploy-rs": "deploy-rs",
+        "disko": "disko",
         "foundryvtt": "foundryvtt",
         "nixpkgs": "nixpkgs_2",
         "nixpkgs-unstable": "nixpkgs-unstable",
@@ -534,11 +309,11 @@
     "rust-analyzer-src": {
       "flake": false,
       "locked": {
-        "lastModified": 1686586902,
-        "narHash": "sha256-+zfBFBmUxWutKbhdntI9uvF4D5Rh7BhcByM2l+ReyTw=",
+        "lastModified": 1703965384,
+        "narHash": "sha256-3iyouqkBvhh/E48TkBlt4JmmcIEyfQwY7pokKBx9WNg=",
         "owner": "rust-lang",
         "repo": "rust-analyzer",
-        "rev": "1f1fe81f0db301124b3026bd2940294526cdd852",
+        "rev": "e872f5085cf5b0e44558442365c1c033d486eff2",
         "type": "github"
       },
       "original": {
@@ -548,6 +323,29 @@
         "type": "github"
       }
     },
+    "slimlock": {
+      "inputs": {
+        "nixpkgs": [
+          "tlaternet-webserver",
+          "dream2nix",
+          "purescript-overlay",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1688610262,
+        "narHash": "sha256-Wg0ViDotFWGWqKIQzyYCgayeH8s4U1OZcTiWTQYdAp4=",
+        "owner": "thomashoneyman",
+        "repo": "slimlock",
+        "rev": "b5c6cdcaf636ebbebd0a1f32520929394493f1a6",
+        "type": "github"
+      },
+      "original": {
+        "owner": "thomashoneyman",
+        "repo": "slimlock",
+        "type": "github"
+      }
+    },
     "sops-nix": {
       "inputs": {
         "nixpkgs": [
@@ -608,11 +406,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1686688441,
-        "narHash": "sha256-rcqAQzExGu0uV9Din8yy+Nn8FQvG/Itm8hp66amDj6o=",
+        "lastModified": 1704840002,
+        "narHash": "sha256-ik2LeuRjcnRXwBLoRSOyGEMXscE+coO8G79IFhZhdJk=",
         "ref": "refs/heads/master",
-        "rev": "c573a6f81827594ceeffbfa058659e2fc20e4a1e",
-        "revCount": 66,
+        "rev": "d14f50c8dcc8ab30a5e5fa907b392ac0df6c7b52",
+        "revCount": 73,
         "type": "git",
         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git"
       },
diff --git a/flake.nix b/flake.nix
index efe6433..af41d53 100644
--- a/flake.nix
+++ b/flake.nix
@@ -4,6 +4,10 @@
   inputs = {
     nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
     nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
+    disko = {
+      url = "github:nix-community/disko";
+      inputs.nixpkgs.follows = "nixpkgs";
+    };
     deploy-rs.url = "github:serokell/deploy-rs";
     sops-nix = {
       url = "github:Mic92/sops-nix";
@@ -47,21 +51,45 @@
           ./configuration/hardware-specific/linode
         ];
       };
+
+      hetzner-1 = nixpkgs.lib.nixosSystem {
+        inherit system;
+        specialArgs.flake-inputs = inputs;
+
+        modules = [
+          ./configuration
+          ./configuration/hardware-specific/hetzner
+        ];
+      };
     };
 
     ############################
     # Deployment configuration #
     ############################
-    deploy.nodes.tlaternet = {
-      hostname = "tlater.net";
+    deploy.nodes = {
+      tlaternet = {
+        hostname = "tlater.net";
 
-      profiles.system = {
-        user = "root";
-        path = deploy-rs.lib.${system}.activate.nixos self.nixosConfigurations.tlaternet;
+        profiles.system = {
+          user = "root";
+          path = deploy-rs.lib.${system}.activate.nixos self.nixosConfigurations.tlaternet;
+        };
+
+        sshUser = "tlater";
+        sshOpts = ["-p" "2222" "-o" "ForwardAgent=yes"];
       };
 
-      sshUser = "tlater";
-      sshOpts = ["-p" "2222" "-o" "ForwardAgent=yes"];
+      hetzner-1 = {
+        hostname = "116.202.158.55";
+
+        profiles.system = {
+          user = "root";
+          path = deploy-rs.lib.${system}.activate.nixos self.nixosConfigurations.hetzner-1;
+        };
+
+        sshUser = "tlater";
+        sshOpts = ["-p" "2222" "-o" "ForwardAgent=yes"];
+      };
     };
 
     #########
diff --git a/keys/hosts/hetzner1.asc b/keys/hosts/hetzner1.asc
new file mode 100644
index 0000000..e58d723
--- /dev/null
+++ b/keys/hosts/hetzner1.asc
@@ -0,0 +1,28 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+xsFNBAAAAAABEADQWw0P407m704eEqPWA2SxNYdVIOAWPFPS1AJBOQycDMW3Mgv3
+v26H5Oan4t1ZD4yLYsJu6HcrGsIY3Xnhd/JGHVd8eazxl092rdAWUaLRPXusUKxY
+KbtBij1U4dkV5npcWyzBN3pzNbU8iItyYS9aOTO6N51QJ3sNIflp+tSf+0Yg26DM
+cXZsAQLERdCgttnbd8hoYE3ge02FDwKIY/pr7cVvdOnrsFcOugNTCvCsJQPVknUz
+sE/BOtFEBnV5Hw7S5ahO4EEvdQpW+VJLa6XRrH8vXB/LJIoPtw11AKA6Rpb/AvG9
+JOKxhSEODVLcdmg5y2dZDrSg5tSzWikCkhPgxcDdhYK+kYwOOCZCwijMmD+cm2J9
+aDPuQho0LBwnwbTsQuXrPNMSGMFP9F1LVbr4X64x0J2E/70ic96xI3F5E+KHpTFL
+kBOr66IFfd91gWLIbxYYtwyx19dPQ7LgZ0GWAMgfHnOdtMwO0Tduubhvq8m7to5B
+wD3VN2Tz/2OUa0gbJrnznaMrSOIj1nOU3FLBjT9/wh9DpXMbZw6D2fzqdt03Kpw9
+XjqJzXN1iRkcMpYkxic1Eq2yoAEtLr13cLv+9Dlkvi01kwN/MxwgnQGuc7/R4ZyA
+Z4aQtviPhT7geIOtY1jH9ZKosEVg2eXyI7YSxHvdXY+vCcwqzh8x+gRJowARAQAB
+zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT
+AQgAFgUCAAAAAAkQR/cdo+WtefkCGw8CGQEAAHNAEACZcvbykefvO1cYp3VEGyHI
+rjCdA+docXXpyZOe9OcNzB1HBjOLwe9cJgkPnTtDZMYhrN6vnb2td7xiX8LVvhgZ
+npSCWtdqXo/EbkN88CP4GraT/9aaB6Joa2RSlZz5jSv3kuq+Q1QXxQqly5/qYhpS
+Ibz3ZWcovI1tMcdvA/u74oQ+4m0Mgqbyg9G2vwAygsexdHQMY+L0SDXI1GMX8z0A
+zFmtIlYkgqMoJY8qeJniwkmrHoLyFLIjnjQERV0FtQJ3S3sL63JVDNiA4OmwxIlR
+M+6LcRDcVqPDEOJxgCKkd6Cg9vOGyCdMTsI42pMuQOflhntx6Ez9tkyQQtkH1dS6
+n9wqmBL47GaZE32GepzvJw3aix87UouuZr8NlzsIr937rp9s3kW4+WpzakimBNjs
+kRWNhMaty2az171g3rvnL8yDejibE1OCHMakq7RUtYWC7Z8pNm2eHtHfTnH9qAZe
+mRcTiiY308ZI046muN9BAg1/m7v/sD3uEI8YXz7kb3lTWb0iioyUZqo0bqNhADEG
+5WLka2RK5fPnsyEalZ8mumUdGCH5iXKmXjK85GUaRwHgJUjhTdnpuqiuwVS3fxvN
+KlPP59q/kbWXL6bnVokvzBuW5GRl8im7qw8ggrEuxmSFD1WQLkvswLum6mVvDFpS
+HX938nRTHMgZfPW/gvR2aA==
+=nrXn
+-----END PGP PUBLIC KEY BLOCK-----
\ No newline at end of file
diff --git a/keys/production.yaml b/keys/production.yaml
index da53b95..dfc0a92 100644
--- a/keys/production.yaml
+++ b/keys/production.yaml
@@ -29,40 +29,65 @@ sops:
     lastmodified: "2023-12-28T00:07:08Z"
     mac: ENC[AES256_GCM,data:P2bNJLjzn69Kg2bJHXmofER7J8wbEj9C4jq9ePWewXBOt45GEiqgnqIaISwZkyzQmm9cxZd95Lr780ICwoKDFdtSCCcC7CdYxYEfyyhnvU3W2qzEghvkypL8JbiEtPSlQ9xOlCk7p41A9eRrV+JziIVSv5UEUs4NubrG9Mkwv3k=,iv:Yq2gANTTgx6cFxkdustUZ1MPszxGSkao/bS1KHAkzJc=,tag:kqJibocgRQXkxTJze6O5MA==,type:str]
     pgp:
-        - created_at: "2022-10-12T00:46:51Z"
-          enc: |
+        - created_at: "2024-03-02T21:16:50Z"
+          enc: |-
             -----BEGIN PGP MESSAGE-----
 
-            hQEMA7x7stsXx45CAQf9Hivg5x2NEKp3icdAIXKoBVTp5jnqJ2S5xDpK4cbCUwRd
-            Z2VyNjxAXdTgKsviXseWbtsEbqo41oqjtpZwXK36gT/miKSPYyBSLb689L70RpWR
-            aC4QzOHbYr1Trr1whkTVaQG1vd2u9ZEyxsi13ItiYVylu7tgMqaDqzE4Y47RPZtz
-            FWFY4chO5Tq/DL0blP8oCTLFx4LSL82JbZswCfqrSHX44HGZ/OELHqNhYNF6hkCr
-            DgYYh7l7s08farE+PnTbWt808Kd3kP8fCRaLm9nt1X1c5QQElaWBjGIscK9fOsV4
-            iVFQfPBdwBi8aawCmwvXOcg6sX050Ow3NeYQBJVICtJeAeHyetxxEYip6CrADsiq
-            UG1Np+p6Pcbq/k6E1vT6bsRrhUWPYC4yuh6Edg5p/jxa4DAlsq/OgDI9pquE9aIt
-            F8cQMHfIkNP8/HiM/KwmdHoTJiy8YCwqP/UalSJdVw==
-            =lnlW
+            hQIMAzWu0p84AOApARAAi+GxJ9z+cMaMgENnDC0Kq6ZJZ/rkXnUIjVxpdXLVhnCc
+            E2S8NoXJI5jcqsYI08wVQm7OWzsNK6GuJET1i3YdHVDOiwYK+WNGeMA6JdIuJzXV
+            EDcuarLusygqIV1UcZCwTl362zuLi5kPs/fGsn7BJeI8Q7CtMEP1cmCk0LlHotjz
+            Pl53bUos1WUqSv0EQw9Cz1dhL6LGlUtoIJaPbB9OO/+chzQCFUJGbCO5KJ/+3fFq
+            2DhQZw1GvgNf9/66f39tgY+jeQq5OyuoFSpuzyjxCeK+eX6Jkxs4zOVlcJoztSVc
+            FEiPIO4YfcgDXToLJWSWA2uGJ+KCvqDXDWyPATQupytAItw05oFyfZOPuh45Wj46
+            6Dm9QYKZMsFj6xfgNl6VEK0KK34zi0EcBKm4wmfF8hw4o5T2U542iPzgKv53jbC2
+            F1dn7GI8ZkSGDPlw7UWSIRLmRYilZhbR+2RJX23nXoarP9oxigCpqhIGBGizdBEx
+            PpUYQjiPUuytk/B3DP+0q01lVvdqcxchA3s88iZwc5GSwBfEMVJ2MJOFkiwIkttO
+            9PkmtXAaFAt7jjRCzhH05/S7g9xt/1zid/lHCGKcfaZJqX6YIu9+mXeERsZ7OdMs
+            uur8T7r14DC4ffPOYQR6BIfNZ3vPUyEP2/fSncAtyDFKO2Cc6ry3JvxBCdPGErjS
+            XgFwk6xHtOsIU3ozokW3aupo5eSNBEPpfIK28P0ivouIZsU64sVJFjc7zPpZnaF+
+            bEnAXMK8FrHvYZz3v4+LSaYZyoKWYly0wCWrSOZTEphTJHFrW/KsJ2hmVTpjS58=
+            =qqF7
             -----END PGP MESSAGE-----
           fp: 535B61015823443941C744DD12264F6BBDFABA89
-        - created_at: "2022-10-12T00:46:51Z"
-          enc: |
+        - created_at: "2024-03-02T21:16:50Z"
+          enc: |-
             -----BEGIN PGP MESSAGE-----
 
-            hQIMA9ahl2ynTH87AQ/+ID/6Dcbat+YRvT8VpfKpZf2O6EFbI3dlPDkZ+f4yFW0R
-            uGKkLR69utM8FoEn1XUkPG3klDk5t/gQikS/d1lPZ6cPOsVzY4P2Te6LizP25vCE
-            cHkztZG/IuBCBfLp8xsEjF1OXEDnb7Klqd3aJuYrvJNm3SreNydRAGyM1E94+iQL
-            zLrHF0WbD+dVdVG+ZoHKouGHVVmcxTkfi8Ce63pHKxOiMgqJLnImC357mle4DlJV
-            1My0CPV9Y1ElY+W5s+a7sRgursR0AVOkuvWYT39VW+RmFpUZyRCgyW+L6ilCEcOV
-            VXJHf0IFylkqevh11BssIetHAtT8anqZ+wo3ON4gEHjcahufc1h8rOxEEsWe/qUC
-            XZzfwilOsY/vKJ+GTz5Cp8XAviozQL5o2O5H9PiHxQl019QHZgprJclGMlukCBkR
-            Uo3h1Rl2na8JqcolAlFGQ1/QxsOnJ/KAmOpUZ7fZqG2qnsXnFjXcuqo+0e58odaT
-            sZLIspvsEHBHKzsvUa6BT8bTc+GlsB3hFolBVdX4y9kTWuzxy0K6bKA9HMTf4FPW
-            w2hIlvYhlgEx9MVqKLbemN3ye2rC3GRUBXxVXmlXBmb7nXPZCOGqL6nrvtsQ1E4h
-            D9+sN+cvYh5lYPByjXYinT8TqFVpqX++qnpgHC+5c6WtDHlhRAyfIQK51wCyiZbS
-            UAG6iDEbCWwD7uHZjDmVycC2R/0HnO+o9xMBI6teKYziFhvn8m7R9gzr7zn/0x3t
-            dVMXtojhfbMPzYK0gT6xOn8SbYGH0MV7ddOm7+Kl3Z8Y
-            =zDer
+            hQIMA9ahl2ynTH87ARAApU/UkNVGbtqxwQ83Zl3f7Zp/PTIeLtcvmuOUjSnPYrYi
+            60H1ZPVJUhAv+gcTwRBZ+aN39mUI43qBgCjNu7Z7Bmevf+TXCvK1CwsxuxVbG1tl
+            sL8FtVH0p8KETq+v8aylTzaV339BmEgnLOBLCE9oP+PhLEERqIT1sz5CeaI71z4F
+            wETPCfJKEouCQpT0P6hSN1f/9h43PZDQQW5MLY2m1o8t+pFHfowADIlsAmZziXBf
+            t/IezzM7oo/QKITpLI8NND9nZfvG7leubG3L2TIL0xIgQeLBs4a+jfFSpt8DR0ii
+            YGf1RgrtpnlkA4B75KHTfEq1LMEn0wOJj89Z38x5MZEw3suUc8W+1PcKoKIgt4Dw
+            RN4K+CS/4Ud8pNLoO+zZ4moRlM9ltWpCJ9kSHNeMShxtsIEPxkhh3CqWU+Ta/4er
+            1W2bkII2ieS4mLlJM6qqLYAb8VJpaKi3BQmB66KtDS4n4HEXvOO+nurmz9luKZZt
+            1e3t8ABBowOu+LOVxUbx9DKFObBJ1CDDPQHxRDmGxeSz3ZccHlXsC83QSHCtcm8G
+            uFtUZLOCaR0iB7DbEUX43p40xFZ5ieqY9XDC3uGJfzoEZRfaX05I3MX267EZBKSp
+            H6kyYPnTBqI0UhIsDtd6AWd9huqOZ/TrWubTeDf07s6VDusMYrtE+WaVczaYUkPS
+            WAHYUCmSFUN5z3Emds26kMUQvWTKMvx8TgaEf9LwOfjo4LXhvNKjU5yi+hqZqlO8
+            AOvcgnksjHUhonEl7GLaOvPPiyoB6F6ZuOFlzOeL1OB3QxJiEoRFbF8=
+            =574h
             -----END PGP MESSAGE-----
           fp: 8a3737d48f1035fe6c3a0a8fd6a1976ca74c7f3b
+        - created_at: "2024-03-02T21:16:50Z"
+          enc: |-
+            -----BEGIN PGP MESSAGE-----
+
+            hQIMA0f3HaPlrXn5AQ/8Cvb9YhG/wYRhu+B3iSTCOq1xiPbCOPs9BcCg85G2yI+5
+            LA8G18XVDpaxlT4lyOE3p4XEbJkP+ceLhNbldiQns9HCDQXanRonZndLjwSdEuRj
+            /A/ql2Q27Xhad34Bu0n+hoNfQ2qKjjx6q5lbbKLIIGOvEBF35oImnWF+Vc2cYpzp
+            J0PT/gkKkGnBCihiUrmpISU+7grFMFT59UnWSthCpACG8ocjzF0PBdzPOj2QSDiv
+            eDiPEdd72KcGXVfRodrdAbApFXJx2goaxYobAFCyC7G3UHJTliCOEG/5PNSb8lSl
+            Xv8NJnYI7bs8bRMFTvpEIsogrVeXy0yDl+qogQWPKYwpStn6yqOMIvs2C476nY/f
+            llRLfjJLTEmPuq+JYhWfZ4o0tOZNECmq4DiAg30ePqThZNXJLNyk9sfkjuDz+zbh
+            rYnJ1Xb1UM7ZKyjGcxSU9eAba0MBJpVZa/ZDrb4GjysPq+rsEb8LO6WPPbYfLbr/
+            kfiK7e4Rv4AgUdd7NjRwBHJSjIFCul8I2hF4v/vp+da11CktPXC0sJNsYXWBR1I+
+            FeKxc+WkLTfuS6evb8Y+UuyQkTDI3mb13QfXaX1V8I63LivdCE7zsTOlnOWPT1k7
+            cqhQ2VpNxBtt7gNG7MAYHn9KAwGbyQ/Ma6Qx//ftjmf47b8qnZuJe8HEg0Nh5uDS
+            WAGdbEL/ZXTT4ZxNm/QHVctZVzCAqDUMIkMK4vCCR+Bs8FvLFUo6YoVEnajqTSj8
+            pkEyS0RuM68KTpivAjDhqlY4vJsMmiRBjx/q5rSwi29vOuhK9ttSj38=
+            =KQd3
+            -----END PGP MESSAGE-----
+          fp: 0af7641adb8aa843136cf6d047f71da3e5ad79f9
     unencrypted_suffix: _unencrypted
     version: 3.8.1

From 1c6e7ec1060953489396269e93f06235fc27dba6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 3 Mar 2024 01:06:52 +0100
Subject: [PATCH 118/212] acme: Don't attempt to get certs if the domain is
 wrong

---
 configuration/default.nix                     |  1 -
 .../hardware-specific/linode/default.nix      |  2 ++
 configuration/hardware-specific/vm.nix        |  2 +-
 modules/default.nix                           | 21 ++++++++++++++++---
 4 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index 34b1f42..bea7539 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -137,7 +137,6 @@
     recommendedGzipSettings = true;
     recommendedProxySettings = true;
     clientMaxBodySize = "10G";
-    domain = "tlater.net";
 
     statusPage = true; # For metrics, should be accessible only from localhost
 
diff --git a/configuration/hardware-specific/linode/default.nix b/configuration/hardware-specific/linode/default.nix
index b05fade..8194ec4 100644
--- a/configuration/hardware-specific/linode/default.nix
+++ b/configuration/hardware-specific/linode/default.nix
@@ -6,6 +6,8 @@
   # Required for the lish console
   boot.kernelParams = ["console=ttyS0,19200n8"];
 
+  services.nginx.domain = "tlater.net";
+
   boot.loader = {
     # Timeout to allow lish to connect
     timeout = 10;
diff --git a/configuration/hardware-specific/vm.nix b/configuration/hardware-specific/vm.nix
index 79f4b35..f17e7ee 100644
--- a/configuration/hardware-specific/vm.nix
+++ b/configuration/hardware-specific/vm.nix
@@ -7,7 +7,7 @@
   networking.hostName = "testvm";
   # Sets the base domain for nginx to localhost so that we
   # can easily test locally with the VM.
-  services.nginx.domain = lib.mkOverride 99 "localhost";
+  services.nginx.domain = "localhost";
 
   # Use the staging secrets
   sops.defaultSopsFile = lib.mkOverride 99 ../../keys/staging.yaml;
diff --git a/modules/default.nix b/modules/default.nix
index 55e356c..de1c7c2 100644
--- a/modules/default.nix
+++ b/modules/default.nix
@@ -1,8 +1,23 @@
-{lib, ...}: let
-  inherit (lib) mkOption types;
-in {
+{
+  pkgs,
+  config,
+  lib,
+  ...
+}: {
   options.services.nginx.domain = lib.mkOption {
     type = lib.types.str;
     description = "The base domain name to append to virtual domain names";
   };
+
+  config = {
+    # Don't attempt to run acme if the domain name is not tlater.net
+    systemd.services = let
+      confirm = ''[[ "tlater.net" = ${config.services.nginx.domain} ]]'';
+    in
+      lib.mapAttrs' (cert: _:
+        lib.nameValuePair "acme-${cert}" {
+          serviceConfig.ExecCondition = ''${pkgs.runtimeShell} -c '${confirm}' '';
+        })
+      config.security.acme.certs;
+  };
 }

From ae18832cb09ae44085422be61e4bf14e1ef3816b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 11 Mar 2024 00:32:25 +0100
Subject: [PATCH 119/212] linode: Remove old server

---
 README.md                                     |  2 +-
 .../hardware-specific/linode/default.nix      | 62 -------------------
 .../linode/hardware-configuration.nix         | 39 ------------
 flake.nix                                     | 22 -------
 4 files changed, 1 insertion(+), 124 deletions(-)
 delete mode 100644 configuration/hardware-specific/linode/default.nix
 delete mode 100644 configuration/hardware-specific/linode/hardware-configuration.nix

diff --git a/README.md b/README.md
index 3962a65..8104f1c 100644
--- a/README.md
+++ b/README.md
@@ -34,5 +34,5 @@ Deployment is handled using
 [deploy-rs](https://github.com/serokell/deploy-rs):
 
 ```
-deploy .#tlaternet
+deploy .#
 ```
diff --git a/configuration/hardware-specific/linode/default.nix b/configuration/hardware-specific/linode/default.nix
deleted file mode 100644
index 8194ec4..0000000
--- a/configuration/hardware-specific/linode/default.nix
+++ /dev/null
@@ -1,62 +0,0 @@
-{
-  imports = [
-    ./hardware-configuration.nix
-  ];
-
-  # Required for the lish console
-  boot.kernelParams = ["console=ttyS0,19200n8"];
-
-  services.nginx.domain = "tlater.net";
-
-  boot.loader = {
-    # Timeout to allow lish to connect
-    timeout = 10;
-
-    grub = {
-      device = "nodev";
-      extraConfig = ''
-        serial --speed=19200 --unit=0 --word=8 --parity=no --stop=1;
-        terminal_input serial;
-        terminal_output serial;
-      '';
-    };
-  };
-
-  systemd.network.networks."10-eth0" = {
-    matchConfig.Name = "eth0";
-
-    networkConfig = {
-      DHCP = "no";
-
-      Address = "178.79.137.55/24";
-      Gateway = "178.79.137.1";
-
-      Domains = "ip.linodeusercontent.com";
-      DNS = [
-        "178.79.182.5"
-        "176.58.107.5"
-        "176.58.116.5"
-        "176.58.121.5"
-        "151.236.220.5"
-        "212.71.252.5"
-        "212.71.253.5"
-        "109.74.192.20"
-        "109.74.193.20"
-        "109.74.194.20"
-        "2a01:7e00::9"
-        "2a01:7e00::3"
-        "2a01:7e00::c"
-        "2a01:7e00::5"
-        "2a01:7e00::6"
-        "2a01:7e00::8"
-        "2a01:7e00::b"
-        "2a01:7e00::4"
-        "2a01:7e00::7"
-        "2a01:7e00::2"
-      ];
-
-      IPv6PrivacyExtensions = "no";
-      IPv6AcceptRA = "yes";
-    };
-  };
-}
diff --git a/configuration/hardware-specific/linode/hardware-configuration.nix b/configuration/hardware-specific/linode/hardware-configuration.nix
deleted file mode 100644
index c1776d5..0000000
--- a/configuration/hardware-specific/linode/hardware-configuration.nix
+++ /dev/null
@@ -1,39 +0,0 @@
-# Do not modify this file!  It was generated by ‘nixos-generate-config’
-# and may be overwritten by future invocations.  Please make changes
-# to /etc/nixos/configuration.nix instead.
-{ config, lib, pkgs, modulesPath, ... }:
-
-{
-  imports =
-    [ (modulesPath + "/profiles/qemu-guest.nix")
-    ];
-
-  boot.initrd.availableKernelModules = [ "virtio_pci" "virtio_scsi" "ahci" "sd_mod" ];
-  boot.initrd.kernelModules = [ ];
-  boot.kernelModules = [ ];
-  boot.extraModulePackages = [ ];
-
-  fileSystems."/" =
-    { device = "/dev/disk/by-uuid/e541bdc3-79d6-459f-9169-92b13b0a8959";
-      fsType = "ext4";
-    };
-
-  fileSystems."/var" =
-    { device = "/dev/disk/by-uuid/79f8fbbd-476d-4e1a-9675-a8474d98f42f";
-      fsType = "ext4";
-    };
-
-  swapDevices =
-    [ { device = "/dev/disk/by-uuid/45c8ad29-3861-4e68-a566-47e6d9269dca"; }
-    ];
-
-  # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
-  # (the default) this is the recommended approach. When using systemd-networkd it's
-  # still possible to use this option, but it's recommended to use it in conjunction
-  # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
-  networking.useDHCP = lib.mkDefault true;
-  # networking.interfaces.eth0.useDHCP = lib.mkDefault true;
-
-  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
-  hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
-}
diff --git a/flake.nix b/flake.nix
index af41d53..21731e6 100644
--- a/flake.nix
+++ b/flake.nix
@@ -42,16 +42,6 @@
     ##################
     nixosConfigurations = {
       # The actual system definition
-      tlaternet = nixpkgs.lib.nixosSystem {
-        inherit system;
-        specialArgs.flake-inputs = inputs;
-
-        modules = [
-          ./configuration
-          ./configuration/hardware-specific/linode
-        ];
-      };
-
       hetzner-1 = nixpkgs.lib.nixosSystem {
         inherit system;
         specialArgs.flake-inputs = inputs;
@@ -67,18 +57,6 @@
     # Deployment configuration #
     ############################
     deploy.nodes = {
-      tlaternet = {
-        hostname = "tlater.net";
-
-        profiles.system = {
-          user = "root";
-          path = deploy-rs.lib.${system}.activate.nixos self.nixosConfigurations.tlaternet;
-        };
-
-        sshUser = "tlater";
-        sshOpts = ["-p" "2222" "-o" "ForwardAgent=yes"];
-      };
-
       hetzner-1 = {
         hostname = "116.202.158.55";
 

From 1b66bf491096c910f988bf91b0a5152e3a60ac68 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 11 Mar 2024 03:48:57 +0100
Subject: [PATCH 120/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'deploy-rs':
    'github:serokell/deploy-rs/b709d63debafce9f5645a5ba550c9e0983b3d1f7' (2023-12-20)
  → 'github:serokell/deploy-rs/0a0187794ac7f7a1e62cda3dabf8dc041f868790' (2024-02-16)
• Updated input 'disko':
    'github:nix-community/disko/bde7dd352c07d43bd5b8245e6c39074a391fdd46' (2024-03-01)
  → 'github:nix-community/disko/d389901567d9ceda5a1a833fbf8e8e254e18eb0a' (2024-03-11)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/d02d818f22c777aa4e854efc3242ec451e5d462a' (2023-12-25)
  → 'github:nixos/nixpkgs/b94a96839afcc56de3551aa7472b8d9a3e77e05d' (2024-03-09)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/cfc3698c31b1fb9cdcf10f36c9643460264d0ca8' (2023-12-27)
  → 'github:nixos/nixpkgs/3030f185ba6a4bf4f18b87f345f104e6a6961f34' (2024-03-09)
• Updated input 'nvfetcher':
    'github:berberman/nvfetcher/2bcf73dea96497ac9c36ed320b457caa705f9485' (2023-09-01)
  → 'github:berberman/nvfetcher/367e2eaa92d8f5133c2c5ac03a80c0cf25f301b8' (2024-02-25)
• Updated input 'nvfetcher/flake-compat':
    'github:edolstra/flake-compat/35bb57c0c8d8b62bbfd284272c928ceb64ddbde9' (2023-01-17)
  → 'github:edolstra/flake-compat/0f9255e01c2351cc7d116c072cb317785dd33b33' (2023-10-04)
• Updated input 'nvfetcher/flake-utils':
    'github:numtide/flake-utils/f9e7cf818399d17d347f847525c5a5a8032e4e44' (2023-08-23)
  → 'github:numtide/flake-utils/1ef2e671c3b0c19053962c07dbda38332dcebf26' (2024-01-15)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/e523e89763ff45f0a6cf15bcb1092636b1da9ed3' (2023-12-24)
  → 'github:Mic92/sops-nix/f8d5c8baa83fe620a28c0db633be9db3e34474b4' (2024-03-10)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/7790e078f8979a9fcd543f9a47427eeaba38f268' (2023-12-23)
  → 'github:NixOS/nixpkgs/b17375d3bb7c79ffc52f3538028b2ec06eb79ef8' (2024-03-10)
---
 flake.lock | 56 +++++++++++++++++++++++++++---------------------------
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/flake.lock b/flake.lock
index 8a9fadc..f8fe220 100644
--- a/flake.lock
+++ b/flake.lock
@@ -7,11 +7,11 @@
         "utils": "utils"
       },
       "locked": {
-        "lastModified": 1703087360,
-        "narHash": "sha256-0VUbWBW8VyiDRuimMuLsEO4elGuUw/nc2WDeuO1eN1M=",
+        "lastModified": 1708091384,
+        "narHash": "sha256-dTGGw2y8wvfjr+J9CjQbfdulOq72hUG17HXVNxpH1yE=",
         "owner": "serokell",
         "repo": "deploy-rs",
-        "rev": "b709d63debafce9f5645a5ba550c9e0983b3d1f7",
+        "rev": "0a0187794ac7f7a1e62cda3dabf8dc041f868790",
         "type": "github"
       },
       "original": {
@@ -27,11 +27,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1709286488,
-        "narHash": "sha256-RDpTZ72zLu05djvXRzK76Ysqp9zSdh84ax/edEaJucs=",
+        "lastModified": 1710119954,
+        "narHash": "sha256-e7AMYtBQgRzeRtn//k1dXu22xeiav+G0cQjm3gEky7o=",
         "owner": "nix-community",
         "repo": "disko",
-        "rev": "bde7dd352c07d43bd5b8245e6c39074a391fdd46",
+        "rev": "d389901567d9ceda5a1a833fbf8e8e254e18eb0a",
         "type": "github"
       },
       "original": {
@@ -101,11 +101,11 @@
     "flake-compat_2": {
       "flake": false,
       "locked": {
-        "lastModified": 1673956053,
-        "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
+        "lastModified": 1696426674,
+        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
         "owner": "edolstra",
         "repo": "flake-compat",
-        "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
+        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
         "type": "github"
       },
       "original": {
@@ -119,11 +119,11 @@
         "systems": "systems_2"
       },
       "locked": {
-        "lastModified": 1692799911,
-        "narHash": "sha256-3eihraek4qL744EvQXsK1Ha6C3CR7nnT8X2qWap4RNk=",
+        "lastModified": 1705309234,
+        "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "f9e7cf818399d17d347f847525c5a5a8032e4e44",
+        "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
         "type": "github"
       },
       "original": {
@@ -170,27 +170,27 @@
     },
     "nixpkgs-stable": {
       "locked": {
-        "lastModified": 1703351344,
-        "narHash": "sha256-9FEelzftkE9UaJ5nqxidaJJPEhe9TPhbypLHmc2Mysc=",
+        "lastModified": 1710033658,
+        "narHash": "sha256-yiZiVKP5Ya813iYLho2+CcFuuHpaqKc/CoxOlANKcqM=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "7790e078f8979a9fcd543f9a47427eeaba38f268",
+        "rev": "b17375d3bb7c79ffc52f3538028b2ec06eb79ef8",
         "type": "github"
       },
       "original": {
         "owner": "NixOS",
-        "ref": "release-23.05",
+        "ref": "release-23.11",
         "repo": "nixpkgs",
         "type": "github"
       }
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1703637592,
-        "narHash": "sha256-8MXjxU0RfFfzl57Zy3OfXCITS0qWDNLzlBAdwxGZwfY=",
+        "lastModified": 1709961763,
+        "narHash": "sha256-6H95HGJHhEZtyYA3rIQpvamMKAGoa8Yh2rFV29QnuGw=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "cfc3698c31b1fb9cdcf10f36c9643460264d0ca8",
+        "rev": "3030f185ba6a4bf4f18b87f345f104e6a6961f34",
         "type": "github"
       },
       "original": {
@@ -202,11 +202,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1703467016,
-        "narHash": "sha256-/5A/dNPhbQx/Oa2d+Get174eNI3LERQ7u6WTWOlR1eQ=",
+        "lastModified": 1710021367,
+        "narHash": "sha256-FuMVdWqXMT38u1lcySYyv93A7B8wU0EGzUr4t4jQu8g=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "d02d818f22c777aa4e854efc3242ec451e5d462a",
+        "rev": "b94a96839afcc56de3551aa7472b8d9a3e77e05d",
         "type": "github"
       },
       "original": {
@@ -241,11 +241,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1693539235,
-        "narHash": "sha256-ACmCq1+RnVq+EB7yeN6fThUR3cCJZb6lKEfv937WG84=",
+        "lastModified": 1708838575,
+        "narHash": "sha256-brhWjqJG+Yp0KGkF1LE7h0E86Z7OhDQJLo9qhWAmoYw=",
         "owner": "berberman",
         "repo": "nvfetcher",
-        "rev": "2bcf73dea96497ac9c36ed320b457caa705f9485",
+        "rev": "367e2eaa92d8f5133c2c5ac03a80c0cf25f301b8",
         "type": "github"
       },
       "original": {
@@ -354,11 +354,11 @@
         "nixpkgs-stable": "nixpkgs-stable"
       },
       "locked": {
-        "lastModified": 1703387502,
-        "narHash": "sha256-JnWuQmyanPtF8c5yAEFXVWzaIlMxA3EAZCh8XNvnVqE=",
+        "lastModified": 1710039806,
+        "narHash": "sha256-vC2fo/phnetp6ub/nRv6mgAi5LbhJ6ujGQWrRD2VgNs=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "e523e89763ff45f0a6cf15bcb1092636b1da9ed3",
+        "rev": "f8d5c8baa83fe620a28c0db633be9db3e34474b4",
         "type": "github"
       },
       "original": {

From c44c9fd8e8a3d63463c9ae2dd2c858525a37c451 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 11 Mar 2024 04:50:40 +0100
Subject: [PATCH 121/212] nextcloud: Update apps

---
 pkgs/_sources_nextcloud/generated.json | 36 +++++++++++++-------------
 pkgs/_sources_nextcloud/generated.nix  | 36 +++++++++++++-------------
 pkgs/nextcloud-apps.toml               |  5 ++--
 3 files changed, 38 insertions(+), 39 deletions(-)

diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index 1e731e8..55dc2d0 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -7,11 +7,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-7baI+vGBg48vZKZY0ikme+4PQl+PLUlC6JE0Air2s5E=",
+            "sha256": "sha256-JXNQNnWXoii71QhtKktuEBEIqzmONVetULBhpSjM9xo=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/bookmarks/releases/download/v13.1.1/bookmarks-13.1.1.tar.gz"
+            "url": "https://github.com/nextcloud/bookmarks/releases/download/v13.1.3/bookmarks-13.1.3.tar.gz"
         },
-        "version": "13.1.1"
+        "version": "13.1.3"
     },
     "calendar": {
         "cargoLocks": null,
@@ -21,11 +21,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-8KwFmnFFlyYzKy2acCCjmpRj2W5pOrbQaPRPm16ZZ7g=",
+            "sha256": "sha256-jf6SIsgWTkQIVIYbfNiTA+KRbUM6g7NHFIOVygBwWmU=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.5.0/calendar-v4.5.0.tar.gz"
+            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.6.6/calendar-v4.6.6.tar.gz"
         },
-        "version": "v4.5.0"
+        "version": "v4.6.6"
     },
     "contacts": {
         "cargoLocks": null,
@@ -35,11 +35,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-dNim0PqUlEGB6J/OTsOjyUZ2JhOBhXC60HhjTstmF4s=",
+            "sha256": "sha256-HCEjiAqn6sTNXKW6O5X6Ta9Ll4ehvzmGZUj1c0ue2Xc=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/contacts/releases/download/v5.4.0/contacts-v5.4.0.tar.gz"
+            "url": "https://github.com/nextcloud-releases/contacts/releases/download/v5.5.3/contacts-v5.5.3.tar.gz"
         },
-        "version": "v5.4.0"
+        "version": "v5.5.3"
     },
     "cookbook": {
         "cargoLocks": null,
@@ -49,11 +49,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-XgBwUr26qW6wvqhrnhhhhcN4wkI+eXDHnNSm1HDbP6M=",
+            "sha256": "sha256-19LN1nYJJ0RMWj6DrYPvHzocTyhMfYdpdhBFch3fpHE=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/cookbook/releases/download/v0.10.2/Cookbook-0.10.2.tar.gz"
+            "url": "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.11.0/Cookbook-0.11.0.tar.gz"
         },
-        "version": "0.10.2"
+        "version": "0.11.0"
     },
     "news": {
         "cargoLocks": null,
@@ -63,11 +63,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-WrLikMN8jxu+vav9Xn8J1wUoGN5wQeQGr5pbVT6GLck=",
+            "sha256": "sha256-cfJkKRNSz15L4E3w1tnEb+t4MrVwVzb8lb6vCOA4cK4=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/news/releases/download/23.0.0/news.tar.gz"
+            "url": "https://github.com/nextcloud/news/releases/download/24.0.0/news.tar.gz"
         },
-        "version": "23.0.0"
+        "version": "24.0.0"
     },
     "notes": {
         "cargoLocks": null,
@@ -77,10 +77,10 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-7GkTGyGTvtDbZsq/zOdbBE7xh6DZO183W6I5XX1ekbw=",
+            "sha256": "sha256-rnDeo6BRqIAPdw8CcnpO1ifQrx8Bnj5WdgcU/L8aCQk=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/notes/releases/download/v4.8.1/notes.tar.gz"
+            "url": "https://github.com/nextcloud/notes/releases/download/v4.9.2/notes.tar.gz"
         },
-        "version": "v4.8.1"
+        "version": "v4.9.2"
     }
 }
\ No newline at end of file
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index ecdbdf3..69fe7cc 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -3,50 +3,50 @@
 {
   bookmarks = {
     pname = "bookmarks";
-    version = "13.1.1";
+    version = "13.1.3";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/bookmarks/releases/download/v13.1.1/bookmarks-13.1.1.tar.gz";
-      sha256 = "sha256-7baI+vGBg48vZKZY0ikme+4PQl+PLUlC6JE0Air2s5E=";
+      url = "https://github.com/nextcloud/bookmarks/releases/download/v13.1.3/bookmarks-13.1.3.tar.gz";
+      sha256 = "sha256-JXNQNnWXoii71QhtKktuEBEIqzmONVetULBhpSjM9xo=";
     };
   };
   calendar = {
     pname = "calendar";
-    version = "v4.5.0";
+    version = "v4.6.6";
     src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.5.0/calendar-v4.5.0.tar.gz";
-      sha256 = "sha256-8KwFmnFFlyYzKy2acCCjmpRj2W5pOrbQaPRPm16ZZ7g=";
+      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.6.6/calendar-v4.6.6.tar.gz";
+      sha256 = "sha256-jf6SIsgWTkQIVIYbfNiTA+KRbUM6g7NHFIOVygBwWmU=";
     };
   };
   contacts = {
     pname = "contacts";
-    version = "v5.4.0";
+    version = "v5.5.3";
     src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/contacts/releases/download/v5.4.0/contacts-v5.4.0.tar.gz";
-      sha256 = "sha256-dNim0PqUlEGB6J/OTsOjyUZ2JhOBhXC60HhjTstmF4s=";
+      url = "https://github.com/nextcloud-releases/contacts/releases/download/v5.5.3/contacts-v5.5.3.tar.gz";
+      sha256 = "sha256-HCEjiAqn6sTNXKW6O5X6Ta9Ll4ehvzmGZUj1c0ue2Xc=";
     };
   };
   cookbook = {
     pname = "cookbook";
-    version = "0.10.2";
+    version = "0.11.0";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/cookbook/releases/download/v0.10.2/Cookbook-0.10.2.tar.gz";
-      sha256 = "sha256-XgBwUr26qW6wvqhrnhhhhcN4wkI+eXDHnNSm1HDbP6M=";
+      url = "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.11.0/Cookbook-0.11.0.tar.gz";
+      sha256 = "sha256-19LN1nYJJ0RMWj6DrYPvHzocTyhMfYdpdhBFch3fpHE=";
     };
   };
   news = {
     pname = "news";
-    version = "23.0.0";
+    version = "24.0.0";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/news/releases/download/23.0.0/news.tar.gz";
-      sha256 = "sha256-WrLikMN8jxu+vav9Xn8J1wUoGN5wQeQGr5pbVT6GLck=";
+      url = "https://github.com/nextcloud/news/releases/download/24.0.0/news.tar.gz";
+      sha256 = "sha256-cfJkKRNSz15L4E3w1tnEb+t4MrVwVzb8lb6vCOA4cK4=";
     };
   };
   notes = {
     pname = "notes";
-    version = "v4.8.1";
+    version = "v4.9.2";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/notes/releases/download/v4.8.1/notes.tar.gz";
-      sha256 = "sha256-7GkTGyGTvtDbZsq/zOdbBE7xh6DZO183W6I5XX1ekbw=";
+      url = "https://github.com/nextcloud/notes/releases/download/v4.9.2/notes.tar.gz";
+      sha256 = "sha256-rnDeo6BRqIAPdw8CcnpO1ifQrx8Bnj5WdgcU/L8aCQk=";
     };
   };
 }
diff --git a/pkgs/nextcloud-apps.toml b/pkgs/nextcloud-apps.toml
index 69bccdc..a515930 100644
--- a/pkgs/nextcloud-apps.toml
+++ b/pkgs/nextcloud-apps.toml
@@ -12,10 +12,9 @@ src.github = "nextcloud-releases/contacts"
 fetch.tarball = "https://github.com/nextcloud-releases/contacts/releases/download/$ver/contacts-$ver.tar.gz"
 
 [cookbook]
-src.github_tag = "nextcloud/cookbook"
+src.github = "christianlupus-nextcloud/cookbook-releases"
 src.prefix = "v"
-src.exclude_regex = 'v\d+\.\d+\.\d+-rc\d+'
-fetch.tarball = "https://github.com/nextcloud/cookbook/releases/download/v$ver/Cookbook-$ver.tar.gz"
+fetch.tarball = "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v$ver/Cookbook-$ver.tar.gz"
 
 [news]
 src.github = "nextcloud/news"

From aaa9a164f7a9fa287fd71522a51bc4927d42edfb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 11 Mar 2024 04:50:48 +0100
Subject: [PATCH 122/212] flake: Fix vm run command path

---
 flake.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flake.nix b/flake.nix
index 21731e6..f8255f6 100644
--- a/flake.nix
+++ b/flake.nix
@@ -109,7 +109,7 @@
         writeShellScript "run-vm" ''
           export QEMU_OPTS="-m 3941 -smp 2 -display curses"
           export QEMU_NET_OPTS="${qemuNetOpts}"
-          "${vm.config.system.build.vm}/bin/run-tlaternet-vm"
+          "${vm.config.system.build.vm}/bin/run-testvm-vm"
         '';
 
       update-pkgs = let

From aec7c5c7d872ece1345584b2e6dadfe637083e2e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 11 Mar 2024 04:50:59 +0100
Subject: [PATCH 123/212] vm: Change domain

---
 configuration/hardware-specific/vm.nix | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/configuration/hardware-specific/vm.nix b/configuration/hardware-specific/vm.nix
index f17e7ee..b2e8826 100644
--- a/configuration/hardware-specific/vm.nix
+++ b/configuration/hardware-specific/vm.nix
@@ -5,9 +5,9 @@
   boot.kernelParams = ["nomodeset"];
 
   networking.hostName = "testvm";
-  # Sets the base domain for nginx to localhost so that we
-  # can easily test locally with the VM.
-  services.nginx.domain = "localhost";
+  # Sets the base domain for nginx to a local domain so that we can
+  # easily test locally with the VM.
+  services.nginx.domain = "dev.local";
 
   # Use the staging secrets
   sops.defaultSopsFile = lib.mkOverride 99 ../../keys/staging.yaml;

From 7affed34f1b01f9c7b0783c13330d77309fffddf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 11 Mar 2024 04:51:25 +0100
Subject: [PATCH 124/212] nextcloud: Remove unused variable

---
 configuration/services/nextcloud.nix | 1 -
 1 file changed, 1 deletion(-)

diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 75993c3..3ba967a 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -1,7 +1,6 @@
 {
   pkgs,
   config,
-  options,
   ...
 }: let
   nextcloud = pkgs.nextcloud27;

From 980122563e6a0f933c6c51ac6925d0708210ca76 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 11 Mar 2024 05:04:17 +0100
Subject: [PATCH 125/212] nextcloud: Downgrade cookbook

---
 pkgs/_sources_nextcloud/generated.json | 6 +++---
 pkgs/_sources_nextcloud/generated.nix  | 6 +++---
 pkgs/nextcloud-apps.toml               | 3 ++-
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index 55dc2d0..6f96b13 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -49,11 +49,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-19LN1nYJJ0RMWj6DrYPvHzocTyhMfYdpdhBFch3fpHE=",
+            "sha256": "sha256-TE/w8SgyIPaGl5wZUAsG234nxoPj25QoRPF3zjbMoRk=",
             "type": "tarball",
-            "url": "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.11.0/Cookbook-0.11.0.tar.gz"
+            "url": "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.10.5/Cookbook-0.10.5.tar.gz"
         },
-        "version": "0.11.0"
+        "version": "0.10.5"
     },
     "news": {
         "cargoLocks": null,
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index 69fe7cc..e69b20a 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -27,10 +27,10 @@
   };
   cookbook = {
     pname = "cookbook";
-    version = "0.11.0";
+    version = "0.10.5";
     src = fetchTarball {
-      url = "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.11.0/Cookbook-0.11.0.tar.gz";
-      sha256 = "sha256-19LN1nYJJ0RMWj6DrYPvHzocTyhMfYdpdhBFch3fpHE=";
+      url = "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.10.5/Cookbook-0.10.5.tar.gz";
+      sha256 = "sha256-TE/w8SgyIPaGl5wZUAsG234nxoPj25QoRPF3zjbMoRk=";
     };
   };
   news = {
diff --git a/pkgs/nextcloud-apps.toml b/pkgs/nextcloud-apps.toml
index a515930..25ac8d9 100644
--- a/pkgs/nextcloud-apps.toml
+++ b/pkgs/nextcloud-apps.toml
@@ -12,7 +12,8 @@ src.github = "nextcloud-releases/contacts"
 fetch.tarball = "https://github.com/nextcloud-releases/contacts/releases/download/$ver/contacts-$ver.tar.gz"
 
 [cookbook]
-src.github = "christianlupus-nextcloud/cookbook-releases"
+# src.github = "christianlupus-nextcloud/cookbook-releases"
+src.manual = "v0.10.5"
 src.prefix = "v"
 fetch.tarball = "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v$ver/Cookbook-$ver.tar.gz"
 

From 07f819cc58c28f2bbdff7ea09e4dd32bb1bb9610 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 11 Mar 2024 21:56:41 +0100
Subject: [PATCH 126/212] coturn: Fix outdated IP address

---
 configuration/services/conduit.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
index 6c84705..f50613b 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit.nix
@@ -125,7 +125,7 @@ in {
     static-auth-secret-file = config.sops.secrets."turn/secret".path;
     realm = turn-realm;
     relay-ips = [
-      "178.79.137.55"
+      "116.202.158.55"
     ];
 
     # SSL config

From f8789ee4d091cda79e017623179d3ce2f152ef7a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 12 Mar 2024 05:35:18 +0100
Subject: [PATCH 127/212] foundryvtt: Mark as running behind a reverse proxy

---
 configuration/services/foundryvtt.nix | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configuration/services/foundryvtt.nix b/configuration/services/foundryvtt.nix
index d573480..a55bf24 100644
--- a/configuration/services/foundryvtt.nix
+++ b/configuration/services/foundryvtt.nix
@@ -12,6 +12,8 @@ in {
     enable = true;
     hostName = domain;
     minifyStaticFiles = true;
+    proxySSL = true;
+    proxyPort = 443;
   };
 
   # Want to start it manually when I need it, not have it constantly

From 329a6c4cf1fa9287e5d8339107ed429edbd10dd4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 12 Mar 2024 05:40:49 +0100
Subject: [PATCH 128/212] foundryvtt: Enable backups

---
 configuration/services/foundryvtt.nix | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/configuration/services/foundryvtt.nix b/configuration/services/foundryvtt.nix
index a55bf24..069f336 100644
--- a/configuration/services/foundryvtt.nix
+++ b/configuration/services/foundryvtt.nix
@@ -35,4 +35,12 @@ in {
       proxyPass = "http://localhost:${toString port}";
     };
   };
+
+  services.backups.foundryvtt = {
+    user = "foundryvtt";
+    paths = [
+      config.services.foundryvtt.dataDir
+    ];
+    pauseServices = ["foundryvtt.service"];
+  };
 }

From fa73574dba2704d912f98d554b0388a67a4c38a5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 12 Mar 2024 05:44:47 +0100
Subject: [PATCH 129/212] nginx: Factor nginx configuration into a separate
 module

---
 configuration/default.nix | 74 ++++++++-------------------------------
 configuration/nginx.nix   | 53 ++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+), 60 deletions(-)
 create mode 100644 configuration/nginx.nix

diff --git a/configuration/default.nix b/configuration/default.nix
index bea7539..ef1c804 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -26,6 +26,7 @@
     ./services/wireguard.nix
     ./services/starbound.nix
     ./services/postgres.nix
+    ./nginx.nix
     ./sops.nix
   ];
 
@@ -108,17 +109,21 @@
     openssh.authorizedKeys.keyFiles = [../keys/tlater.pub];
   };
 
-  services.openssh = {
-    enable = true;
-    allowSFTP = false;
-    ports = [2222];
-    startWhenNeeded = true;
+  services = {
+    openssh = {
+      enable = true;
+      allowSFTP = false;
+      ports = [2222];
+      startWhenNeeded = true;
 
-    settings = {
-      GatewayPorts = "yes";
-      PermitRootLogin = "no";
-      PasswordAuthentication = false;
+      settings = {
+        GatewayPorts = "yes";
+        PermitRootLogin = "no";
+        PasswordAuthentication = false;
+      };
     };
+
+    logrotate.enable = true;
   };
 
   security = {
@@ -130,57 +135,6 @@
     };
   };
 
-  services.nginx = {
-    enable = true;
-    recommendedTlsSettings = true;
-    recommendedOptimisation = true;
-    recommendedGzipSettings = true;
-    recommendedProxySettings = true;
-    clientMaxBodySize = "10G";
-
-    statusPage = true; # For metrics, should be accessible only from localhost
-
-    commonHttpConfig = ''
-      log_format upstream_time '$remote_addr - $remote_user [$time_local] '
-                         '"$request" $status $body_bytes_sent '
-                         '"$http_referer" "$http_user_agent" '
-                         'rt=$request_time uct="$upstream_connect_time" '
-                         'uht="$upstream_header_time" urt="$upstream_response_time"';
-    '';
-  };
-
-  services.logrotate = {
-    enable = true;
-
-    settings =
-      {
-        # Override the default, just keep fewer logs
-        nginx.rotate = 6;
-      }
-      // lib.mapAttrs' (virtualHost: _:
-        lib.nameValuePair "/var/log/nginx/${virtualHost}/access.log" {
-          frequency = "daily";
-          rotate = 2;
-          compress = true;
-          delaycompress = true;
-          su = "${config.services.nginx.user} ${config.services.nginx.group}";
-          postrotate = "[ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`";
-        })
-      config.services.nginx.virtualHosts;
-  };
-  systemd.tmpfiles.rules =
-    lib.mapAttrsToList (
-      virtualHost: _:
-      #
-      "d /var/log/nginx/${virtualHost} 0750 ${config.services.nginx.user} ${config.services.nginx.group}"
-    )
-    config.services.nginx.virtualHosts;
-
-  security.acme = {
-    defaults.email = "tm@tlater.net";
-    acceptTerms = true;
-  };
-
   # Remove some unneeded packages
   environment.defaultPackages = [];
 
diff --git a/configuration/nginx.nix b/configuration/nginx.nix
new file mode 100644
index 0000000..5315ae6
--- /dev/null
+++ b/configuration/nginx.nix
@@ -0,0 +1,53 @@
+{
+  config,
+  lib,
+  ...
+}: {
+  services.nginx = {
+    enable = true;
+    recommendedTlsSettings = true;
+    recommendedOptimisation = true;
+    recommendedGzipSettings = true;
+    recommendedProxySettings = true;
+    clientMaxBodySize = "10G";
+
+    statusPage = true; # For metrics, should be accessible only from localhost
+
+    commonHttpConfig = ''
+      log_format upstream_time '$remote_addr - $remote_user [$time_local] '
+                         '"$request" $status $body_bytes_sent '
+                         '"$http_referer" "$http_user_agent" '
+                         'rt=$request_time uct="$upstream_connect_time" '
+                         'uht="$upstream_header_time" urt="$upstream_response_time"';
+    '';
+  };
+
+  services.logrotate.settings =
+    {
+      # Override the default, just keep fewer logs
+      nginx.rotate = 6;
+    }
+    // lib.mapAttrs' (virtualHost: _:
+      lib.nameValuePair "/var/log/nginx/${virtualHost}/access.log" {
+        frequency = "daily";
+        rotate = 2;
+        compress = true;
+        delaycompress = true;
+        su = "${config.services.nginx.user} ${config.services.nginx.group}";
+        postrotate = "[ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`";
+      })
+    config.services.nginx.virtualHosts;
+
+  systemd.tmpfiles.rules =
+    lib.mapAttrsToList (
+      virtualHost: _:
+      #
+      "d /var/log/nginx/${virtualHost} 0750 ${config.services.nginx.user} ${config.services.nginx.group}"
+    )
+    config.services.nginx.virtualHosts;
+
+  security.acme = {
+    defaults.email = "tm@tlater.net";
+    acceptTerms = true;
+  };
+}

From cf02da0d00378ccbf8b836206956ecb069a310cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 12 Mar 2024 05:58:36 +0100
Subject: [PATCH 130/212] acme: Back up SSL certificates

---
 configuration/nginx.nix | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/configuration/nginx.nix b/configuration/nginx.nix
index 5315ae6..14ba9d9 100644
--- a/configuration/nginx.nix
+++ b/configuration/nginx.nix
@@ -50,4 +50,11 @@
     defaults.email = "tm@tlater.net";
     acceptTerms = true;
   };
+
+  services.backups.acme = {
+    user = "acme";
+    paths =
+      lib.mapAttrsToList (virtualHost: _: "/var/lib/acme/${virtualHost}")
+      config.services.nginx.virtualHosts;
+  };
 }

From f43f8742d9eb93ad24101c73d334bf687b232ef0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 18 Mar 2024 05:05:34 +0100
Subject: [PATCH 131/212] sops: Fix encryption

---
 flake.lock           |  6 +--
 keys/production.yaml | 89 +++++++++++++++++++++-----------------------
 2 files changed, 45 insertions(+), 50 deletions(-)

diff --git a/flake.lock b/flake.lock
index f8fe220..475ddf8 100644
--- a/flake.lock
+++ b/flake.lock
@@ -354,11 +354,11 @@
         "nixpkgs-stable": "nixpkgs-stable"
       },
       "locked": {
-        "lastModified": 1710039806,
-        "narHash": "sha256-vC2fo/phnetp6ub/nRv6mgAi5LbhJ6ujGQWrRD2VgNs=",
+        "lastModified": 1710433464,
+        "narHash": "sha256-IXlPoWgIRovZ32mYvqqdBgOQln71LouE/HBhbKc1wcw=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "f8d5c8baa83fe620a28c0db633be9db3e34474b4",
+        "rev": "6c32d3b9c7593f4b466ec5404e59fc09a803a090",
         "type": "github"
       },
       "original": {
diff --git a/keys/production.yaml b/keys/production.yaml
index dfc0a92..80172e2 100644
--- a/keys/production.yaml
+++ b/keys/production.yaml
@@ -26,67 +26,62 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2023-12-28T00:07:08Z"
-    mac: ENC[AES256_GCM,data:P2bNJLjzn69Kg2bJHXmofER7J8wbEj9C4jq9ePWewXBOt45GEiqgnqIaISwZkyzQmm9cxZd95Lr780ICwoKDFdtSCCcC7CdYxYEfyyhnvU3W2qzEghvkypL8JbiEtPSlQ9xOlCk7p41A9eRrV+JziIVSv5UEUs4NubrG9Mkwv3k=,iv:Yq2gANTTgx6cFxkdustUZ1MPszxGSkao/bS1KHAkzJc=,tag:kqJibocgRQXkxTJze6O5MA==,type:str]
+    lastmodified: "2024-03-18T04:04:56Z"
+    mac: ENC[AES256_GCM,data:qIbgeaaFQXYacURO9EVfvtvvlUP0j7FMJuh9CIRbzQCyoSedibt1yhGIMQk2ERUliPb8OEuG4QPZ8rled/DmP1BHrUNTYFnRcagtPOnIE+0b9TuAVrj+vTWVl4MvQKMt9i/DQJsWAZVuaP8isDuZ77mVnlj1V8F+1MvXtL0+ZVM=,iv:0mKgiXjWrmNmuXLEsPYBMWSZvD9qrHDHEkSPAm9GCY4=,tag:ZM32r6kbsi4ERGFERzTRpA==,type:str]
     pgp:
-        - created_at: "2024-03-02T21:16:50Z"
+        - created_at: "2024-03-18T04:02:00Z"
           enc: |-
             -----BEGIN PGP MESSAGE-----
 
-            hQIMAzWu0p84AOApARAAi+GxJ9z+cMaMgENnDC0Kq6ZJZ/rkXnUIjVxpdXLVhnCc
-            E2S8NoXJI5jcqsYI08wVQm7OWzsNK6GuJET1i3YdHVDOiwYK+WNGeMA6JdIuJzXV
-            EDcuarLusygqIV1UcZCwTl362zuLi5kPs/fGsn7BJeI8Q7CtMEP1cmCk0LlHotjz
-            Pl53bUos1WUqSv0EQw9Cz1dhL6LGlUtoIJaPbB9OO/+chzQCFUJGbCO5KJ/+3fFq
-            2DhQZw1GvgNf9/66f39tgY+jeQq5OyuoFSpuzyjxCeK+eX6Jkxs4zOVlcJoztSVc
-            FEiPIO4YfcgDXToLJWSWA2uGJ+KCvqDXDWyPATQupytAItw05oFyfZOPuh45Wj46
-            6Dm9QYKZMsFj6xfgNl6VEK0KK34zi0EcBKm4wmfF8hw4o5T2U542iPzgKv53jbC2
-            F1dn7GI8ZkSGDPlw7UWSIRLmRYilZhbR+2RJX23nXoarP9oxigCpqhIGBGizdBEx
-            PpUYQjiPUuytk/B3DP+0q01lVvdqcxchA3s88iZwc5GSwBfEMVJ2MJOFkiwIkttO
-            9PkmtXAaFAt7jjRCzhH05/S7g9xt/1zid/lHCGKcfaZJqX6YIu9+mXeERsZ7OdMs
-            uur8T7r14DC4ffPOYQR6BIfNZ3vPUyEP2/fSncAtyDFKO2Cc6ry3JvxBCdPGErjS
-            XgFwk6xHtOsIU3ozokW3aupo5eSNBEPpfIK28P0ivouIZsU64sVJFjc7zPpZnaF+
-            bEnAXMK8FrHvYZz3v4+LSaYZyoKWYly0wCWrSOZTEphTJHFrW/KsJ2hmVTpjS58=
-            =qqF7
+            hQEMA7x7stsXx45CAQf7BjF+HR3WKdMyAV6R1M0+lqDz6hBHKyGH7YBB/QZBqRbK
+            3hdABIwWUsqpHjleEOp/Gj0VhZqwagqHxK4Fp5G0r3QBupbAO8u/+DNI8wll0Nva
+            dlOh0Jqp4E17TkERMQL02rrQ1ZmpOYmPkCd2//xkmWAQ1LatHWeRVSRxQBuMtPQi
+            btrefcQNjQCvS9/60dp8oTu8nxlFA4iHCBQKNIKVGqQH7jkdIfMPdUILjCkCiyCc
+            h+OxlHZZnpU6U9A+hjMBinvCzebSkZh48VX/T33Kr+4b0CBr1gR9MSXKG9f2MPQP
+            PMl6rPvqSqG6ddN9QDI+0HEHYaRvxPIV8uDS36tVxNJeAQHB5/6Lt7hJdYWgwf5E
+            TLgbZ0IxB17++6K++GlaG8WHO65l1jzmkPlN+ZGcwnhibDxnZjP6kqGqDFcZP4ge
+            cnV0KnhYcC59IooQYrWKzAJex9rnwPo7MGKV6XwZOQ==
+            =Hy9T
             -----END PGP MESSAGE-----
           fp: 535B61015823443941C744DD12264F6BBDFABA89
-        - created_at: "2024-03-02T21:16:50Z"
+        - created_at: "2024-03-18T04:02:00Z"
           enc: |-
             -----BEGIN PGP MESSAGE-----
 
-            hQIMA9ahl2ynTH87ARAApU/UkNVGbtqxwQ83Zl3f7Zp/PTIeLtcvmuOUjSnPYrYi
-            60H1ZPVJUhAv+gcTwRBZ+aN39mUI43qBgCjNu7Z7Bmevf+TXCvK1CwsxuxVbG1tl
-            sL8FtVH0p8KETq+v8aylTzaV339BmEgnLOBLCE9oP+PhLEERqIT1sz5CeaI71z4F
-            wETPCfJKEouCQpT0P6hSN1f/9h43PZDQQW5MLY2m1o8t+pFHfowADIlsAmZziXBf
-            t/IezzM7oo/QKITpLI8NND9nZfvG7leubG3L2TIL0xIgQeLBs4a+jfFSpt8DR0ii
-            YGf1RgrtpnlkA4B75KHTfEq1LMEn0wOJj89Z38x5MZEw3suUc8W+1PcKoKIgt4Dw
-            RN4K+CS/4Ud8pNLoO+zZ4moRlM9ltWpCJ9kSHNeMShxtsIEPxkhh3CqWU+Ta/4er
-            1W2bkII2ieS4mLlJM6qqLYAb8VJpaKi3BQmB66KtDS4n4HEXvOO+nurmz9luKZZt
-            1e3t8ABBowOu+LOVxUbx9DKFObBJ1CDDPQHxRDmGxeSz3ZccHlXsC83QSHCtcm8G
-            uFtUZLOCaR0iB7DbEUX43p40xFZ5ieqY9XDC3uGJfzoEZRfaX05I3MX267EZBKSp
-            H6kyYPnTBqI0UhIsDtd6AWd9huqOZ/TrWubTeDf07s6VDusMYrtE+WaVczaYUkPS
-            WAHYUCmSFUN5z3Emds26kMUQvWTKMvx8TgaEf9LwOfjo4LXhvNKjU5yi+hqZqlO8
-            AOvcgnksjHUhonEl7GLaOvPPiyoB6F6ZuOFlzOeL1OB3QxJiEoRFbF8=
-            =574h
+            hQIMA9ahl2ynTH87AQ/+LNXxC3acjs2+c38gHZRW6Am4XFx1t/4tfxIgaaK/Boq8
+            PGU5CFNOMDGv8u/cwyDbfNM7GuL5g7vrLmBXzSV5ErZqc6bJ0+ZCNPTRIxP1Vxph
+            tWiDIyTwuqUzxWpOlSzii2Sqhlp8CyiWzBe95eIr96XzDCCtfzyCZ0BYyKgpHHxB
+            BltH0/+0JZFiR19zvf6M99AHwM8OddRQkXav+mRIJQpA87ovVZcAv5skYGJgNCqN
+            55fbskuYmqEnloQCZVJ2+2ZXK5Qn/uq4fLJCiIdZm4YsctJnV5spzZIL+dcOty65
+            Plk77BWzLaU5UOKCBAJWrK8oZSTGOrp4VZqb62DuqMRejG0JXmneIVk7p79yn5eA
+            ANVMGRF4b8RP9YUhzE8HACFzQebKpUU8XKv9+qsmO9Le5jUhU3UQeCSSzT/T5Dr8
+            kLDNtmW+mliQnxFlKcVWq2JIG+HaQD1KLOAl0JBNCOSLif2ofaHahuZ15agbYeis
+            hyrBY92EhzqYXHk/Kzv4ff4r+WUs9NN7R4Gg+wfWvMcTtVfbi4Ht+pjjTtCZwK1C
+            M8JebQn0NZSpVi3e7Xaz1fQ5Tqrg8PHZtkYGoIHLRPJQwLn9PHYtGzC3rFAk+Fqq
+            5WWHELxfcsZ6DakAGSXPK/80QhEZkpGmKizTwrEde+7fpEPxjdzUqlmH3rv7mFzS
+            WAGSiBIMjLR6ofb65vpghbwh6gXkpCtgUyINRhx/D+Kj5Z4lGD1u1I05DT1xD6VJ
+            FAbnH7oZ3PJecoAXgRT05FndFA1xfPMCkugmec8ML/sEZt+c3kbrXaA=
+            =MqS3
             -----END PGP MESSAGE-----
           fp: 8a3737d48f1035fe6c3a0a8fd6a1976ca74c7f3b
-        - created_at: "2024-03-02T21:16:50Z"
+        - created_at: "2024-03-18T04:02:00Z"
           enc: |-
             -----BEGIN PGP MESSAGE-----
 
-            hQIMA0f3HaPlrXn5AQ/8Cvb9YhG/wYRhu+B3iSTCOq1xiPbCOPs9BcCg85G2yI+5
-            LA8G18XVDpaxlT4lyOE3p4XEbJkP+ceLhNbldiQns9HCDQXanRonZndLjwSdEuRj
-            /A/ql2Q27Xhad34Bu0n+hoNfQ2qKjjx6q5lbbKLIIGOvEBF35oImnWF+Vc2cYpzp
-            J0PT/gkKkGnBCihiUrmpISU+7grFMFT59UnWSthCpACG8ocjzF0PBdzPOj2QSDiv
-            eDiPEdd72KcGXVfRodrdAbApFXJx2goaxYobAFCyC7G3UHJTliCOEG/5PNSb8lSl
-            Xv8NJnYI7bs8bRMFTvpEIsogrVeXy0yDl+qogQWPKYwpStn6yqOMIvs2C476nY/f
-            llRLfjJLTEmPuq+JYhWfZ4o0tOZNECmq4DiAg30ePqThZNXJLNyk9sfkjuDz+zbh
-            rYnJ1Xb1UM7ZKyjGcxSU9eAba0MBJpVZa/ZDrb4GjysPq+rsEb8LO6WPPbYfLbr/
-            kfiK7e4Rv4AgUdd7NjRwBHJSjIFCul8I2hF4v/vp+da11CktPXC0sJNsYXWBR1I+
-            FeKxc+WkLTfuS6evb8Y+UuyQkTDI3mb13QfXaX1V8I63LivdCE7zsTOlnOWPT1k7
-            cqhQ2VpNxBtt7gNG7MAYHn9KAwGbyQ/Ma6Qx//ftjmf47b8qnZuJe8HEg0Nh5uDS
-            WAGdbEL/ZXTT4ZxNm/QHVctZVzCAqDUMIkMK4vCCR+Bs8FvLFUo6YoVEnajqTSj8
-            pkEyS0RuM68KTpivAjDhqlY4vJsMmiRBjx/q5rSwi29vOuhK9ttSj38=
-            =KQd3
+            hQIMA0f3HaPlrXn5AQ/+N5NK5UJdtw5e7O9T4hfIhtMXci/og1cJiI64daSyNeDH
+            jq+CPJ8e73yiTPwu6wHHqfuEhlEuI6sJY0ZJVFU+h4SIBtG21veGEz7GzlYgBCJm
+            xvJHXjtM8AprqnFVO7Fj9QA/ik5QBP6ZpkOY7j8/qf1G7alOIne/MYRALXDvvIMH
+            HTWE+Y2N57yZK55Pokmdw10hawbrn/N1nt2Y7sa1+5TlRNtuA/+zLkXtEjRr5U3N
+            DId+hqCKgXDqKLBMkh4mZUTGOGsk8eeKAWwyPp9+8A5/0rfy+xOJYEjjHICXQMSE
+            zfe6qvj/fRJKGzT5lEzD+ZKHlR0zHEwGRfHqrVUTdPcPdKj3DZILjsoe5ba4VlAp
+            sS0CAYTg3YuWMT4iHuOQlY5IoQxHHrn7k8ox5iZULFecg58f6r6iJL3AepDYWAey
+            gtQXYBeaeCm5Ddwmd6TBVz8Q4bCVYIrHbVeAhSDkxfrWLc5UORggvLEWiXilGDJi
+            DzAv0MVHE2Wa3eOJLq05K2/LBqRBD1XYM3dcS6JSdFxWWMzvLdUOB4dAuPt9gpl9
+            liaA13Blw/ev+U4ADxptrl+QuYRbWz3z6rniYpluSrTbVCKFRoHXSGFPy5u8/N6O
+            QyjfoovIBxXKnbUq2kMoFa/qFpc1pDUn0sjQNsUBdtorAu3Up4icyoih7qwx2J3S
+            WAGB1jHWMfcsBJqPwjRYkqBf6MuwHAZWdd+zvj/fKfft9jtxLcCGOIM6QdfiWbl0
+            Wq4gHdH7OhSy+ZgRnaBRt/GAkzkHvfG68HfulviHZ1h2mrQN1y3mxpg=
+            =RCYB
             -----END PGP MESSAGE-----
           fp: 0af7641adb8aa843136cf6d047f71da3e5ad79f9
     unencrypted_suffix: _unencrypted

From c161eeb056a6c91d226b5be7adef617625eb4f95 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 18 Mar 2024 05:05:54 +0100
Subject: [PATCH 132/212] backups: Switch to hetzner storage box

---
 configuration/services/backups.nix | 76 +++++++++++++++++++-----------
 configuration/sops.nix             | 10 ++++
 keys/production.yaml               |  6 ++-
 3 files changed, 63 insertions(+), 29 deletions(-)

diff --git a/configuration/services/backups.nix b/configuration/services/backups.nix
index 3635a83..98aa473 100644
--- a/configuration/services/backups.nix
+++ b/configuration/services/backups.nix
@@ -24,6 +24,24 @@
       inherit name text;
       runtimeInputs = packages;
     });
+
+  # *NOT* a TOML file, for some reason quotes are interpreted
+  # *literally
+  rcloneConfig = pkgs.writeText "rclone.conf" ''
+    [storagebox]
+    type = sftp
+    user = u395933
+    host = u395933.your-storagebox.de
+    port = 23
+    key_file = ${config.sops.secrets."restic/storagebox-ssh-key".path}
+    shell_type = unix
+  '';
+
+  resticEnv = {
+    RESTIC_PASSWORD_FILE = config.sops.secrets."restic/storagebox-backups".path;
+    RESTIC_REPOSITORY = "rclone:storagebox:backups";
+    RCLONE_CONFIG = rcloneConfig;
+  };
 in {
   options = {
     services.backups = lib.mkOption {
@@ -120,13 +138,11 @@ in {
           # Doesn't hurt to finish the ongoing prune
           restartIfChanged = false;
 
-          environment = {
-            RESTIC_PASSWORD_FILE = config.sops.secrets."restic/local-backups".path;
-            RESTIC_REPOSITORY = "/var/lib/backups/";
-            RESTIC_CACHE_DIR = "%C/restic-prune";
-          };
+          environment = resticEnv;
 
           path = with pkgs; [
+            openssh
+            rclone
             restic
           ];
 
@@ -145,11 +161,6 @@ in {
 
             CacheDirectory = "restic-prune";
             CacheDirectoryMode = "0700";
-            ReadWritePaths = "/var/lib/backups/";
-
-            # Ensure we don't leave behind any files with the
-            # temporary UID of this service.
-            ExecStopPost = "+${pkgs.coreutils}/bin/chown -R root:backup /var/lib/backups/";
           };
         };
       }
@@ -158,17 +169,24 @@ in {
           # Don't want to restart mid-backup
           restartIfChanged = false;
 
-          environment = {
-            RESTIC_CACHE_DIR = "%C/backup-${name}";
-            RESTIC_PASSWORD_FILE = config.sops.secrets."restic/local-backups".path;
-            # TODO(tlater): If I ever add more than one repo, service
-            # shutdown/restarting will potentially break if multiple
-            # backups for the same service overlap. A more clever
-            # sentinel file with reference counts would probably solve
-            # this.
-            RESTIC_REPOSITORY = "/var/lib/backups/";
-          };
+          environment =
+            resticEnv
+            // {
+              RESTIC_CACHE_DIR = "%C/backup-${name}";
+            };
 
+          path = with pkgs; [
+            coreutils
+            openssh
+            rclone
+            restic
+          ];
+
+          # TODO(tlater): If I ever add more than one repo, service
+          # shutdown/restarting will potentially break if multiple
+          # backups for the same service overlap. A more clever
+          # sentinel file with reference counts would probably solve
+          # this.
           serviceConfig = {
             User = backup.user;
             Group = "backup";
@@ -183,8 +201,8 @@ in {
 
             ExecStartPre =
               map (service: "+${mkShutdownScript service}") backup.pauseServices
-              ++ singleton (writeScript "backup-${name}-repo-init" [pkgs.restic pkgs.coreutils] ''
-                restic snapshots || (restic init && chmod -R g+rwx "$RESTIC_REPOSITORY"/*)
+              ++ singleton (writeScript "backup-${name}-repo-init" [] ''
+                restic snapshots || restic init
               '')
               ++ optional (backup.preparation.text != null)
               (writeScript "backup-${name}-prepare" backup.preparation.packages backup.preparation.text);
@@ -220,10 +238,14 @@ in {
         })
       config.services.backups;
 
-    users.groups.backup = {};
-
-    systemd.tmpfiles.rules = [
-      "d /var/lib/backups/ 0770 root backup"
-    ];
+    users = {
+      # This user is only used to own the ssh key, because apparently
+      # the ssh client checks file permissions and is stuck in 1980.
+      users.backup = {
+        group = "backup";
+        isSystemUser = true;
+      };
+      groups.backup = {};
+    };
   };
 }
diff --git a/configuration/sops.nix b/configuration/sops.nix
index c7cb1f0..dc9fcb5 100644
--- a/configuration/sops.nix
+++ b/configuration/sops.nix
@@ -36,6 +36,16 @@
         group = "backup";
         mode = "0440";
       };
+      "restic/storagebox-backups" = {
+        owner = "root";
+        group = "backup";
+        mode = "0440";
+      };
+      "restic/storagebox-ssh-key" = {
+        owner = "backup";
+        group = "backup";
+        mode = "0040";
+      };
 
       # Steam
       "steam/tlater" = {};
diff --git a/keys/production.yaml b/keys/production.yaml
index 80172e2..aa25072 100644
--- a/keys/production.yaml
+++ b/keys/production.yaml
@@ -14,6 +14,8 @@ wireguard:
     server-key: ENC[AES256_GCM,data:mXb7ZznJHf5CgV8rI4uzPBATMRbmd7LimgtCkQM9kAjbIaGwUBqJZBN3fXs=,iv:3Po1Orinzov9rnEm9cLzgJY1PeD+5Jl9115MriABHh8=,tag:E/2CjDO1JCvJzxCnqKcNyw==,type:str]
 restic:
     local-backups: ENC[AES256_GCM,data:NLNVlR9G9bLSZOkMoPvkbBbAZlKkmiUbdWHOFDnaefuy9wNLH53ctOIyS0rSsQLaJCSBTpgPSWIIXUSuzoK/eA==,iv:DzuujmyJJP4GiE5z7KOOGUEzUgOwmtf/7UYhwkyLe9g=,tag:cElFhpVC7S6HYlB6UyN7PQ==,type:str]
+    storagebox-backups: ENC[AES256_GCM,data:UyT8jCkKlfYJXjWLI9MbYfeVhY5d89N3aj1Olj54/aBOP3gwcrx6gU56Pwa1xKZ3lR13AVs/b4wF9sbvP7Kqqg==,iv:0HM+DgH4iCiWpjRvAYCFQGEy4xIBQwAM+PkkzOsizw0=,tag:jbrqo1In2O4jVM5e7fjOzg==,type:str]
+    storagebox-ssh-key: ENC[AES256_GCM,data:7aYlKX7I8Bsur3nm4nV9eSW3lmIxBCeCUMbPX3qgcotPbyPYaUqD3MOCnFRepajYkFXAgMX4jknqLfoO9xYc4bavDFjOY8Ww/KmLay7ces6tDnkK6tTRxcNRPUBqEzaFiPNsZc2UwHnmHOF0rKvQusvhCOplYao3xxz5McTHC7IEriUApSNudWCg3qGbyAmxkGEw7tRfh6IiUXEOFeaXDZd78dWZlWIIeospmA1hcVhkLGrjMmoikt/YANHUpWPbd+B9E6x+s2eIzFdvztRjarBluWPZuX981b+hcOm1/+HY/tJ/jzgyVbX1rjmdgZ9jZqdKO/vkOkijHWXlwpQ0QJ2s8p5MURPGRsC7W5jfmGbVKrubxfQC2mSJRJgBaj1wX3yI4GbfCXNdbpseAMy7t8OmN/iMN57lGnD3uX8CWWD327PIWp3SgwMDIZtJRlMBu3vMUrBdNnrrlYoLgf821tX7JWW6L5g1EK/bcBZqZZ/6rE+Q9fLiJHTsj2lyTzQZRLKsn0YePlcIMOWHO2CG/aWrfycdSKKjaKGG,iv:OVnEIMFB4h/EQ8zV3XOpVXLDrV5t4roNYDFQz99m4sQ=,tag:mKWF12uD1TLla/MoJs2zNg==,type:str]
 turn:
     env: ENC[AES256_GCM,data:kt5nhVo9pb/ZbPUEcqSYXxN9YMgQKnFb5VRfFFS/qoIaJ73uD2fuJKqcxAyVRrdLqnSAWSQBgTgunBzdP7xqLAK2qt8DYAQWHkIe9uxFbSXZpdmw,iv:9lq6SFwTFN4GGm6gPiJpUMasMdnHVF6XLGYrsyG3kjU=,tag:428Qf9DOiiHt/Wjb188b8g==,type:str]
     secret: ENC[AES256_GCM,data:si7ee6Xfhdgdyzbp6aQpF7pz3TmTBb7iQ82lRPVXNDg9JfHI+lbmgAsSnRLX5qMCA6P9R045sSMosqidL8QwRg==,iv:SrhpZKK8D45yxCEfDb9P3TwtA14+qEI+wcRqcN/a6pw=,tag:PiwV+mOL9xHJgJft6sc61g==,type:str]
@@ -26,8 +28,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2024-03-18T04:04:56Z"
-    mac: ENC[AES256_GCM,data:qIbgeaaFQXYacURO9EVfvtvvlUP0j7FMJuh9CIRbzQCyoSedibt1yhGIMQk2ERUliPb8OEuG4QPZ8rled/DmP1BHrUNTYFnRcagtPOnIE+0b9TuAVrj+vTWVl4MvQKMt9i/DQJsWAZVuaP8isDuZ77mVnlj1V8F+1MvXtL0+ZVM=,iv:0mKgiXjWrmNmuXLEsPYBMWSZvD9qrHDHEkSPAm9GCY4=,tag:ZM32r6kbsi4ERGFERzTRpA==,type:str]
+    lastmodified: "2024-03-18T04:05:08Z"
+    mac: ENC[AES256_GCM,data:/v/XRBizRUn8UR1HOIaKrY11/5I8RmsctmxXg0wcCXO983YgcGYTEqfXOSRJzkh/MOjB0c8jpdfE7tyqYgB2iYjm+HmRFVsGNB484e+3ukAMsxz4CTz26RWC/LEemQeBOa5RB3rrPXXo1LrJCBN9Y+T/PVgO2xshUSxyhRFQmMA=,iv:km1m8k/vrCVT8ugvqAZNORLu0NSW66B58btH5k4e//Y=,tag:RZXviobM03IQXN1FwDUlVA==,type:str]
     pgp:
         - created_at: "2024-03-18T04:02:00Z"
           enc: |-

From e7d68790633656d2b3ad0ec829cc2407aa5e9e43 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 25 Mar 2024 01:10:31 +0100
Subject: [PATCH 133/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/d389901567d9ceda5a1a833fbf8e8e254e18eb0a' (2024-03-11)
  → 'github:nix-community/disko/5d2d3e421ade554b19b4dbb0d11a04023378a330' (2024-03-24)
• Updated input 'foundryvtt':
    'github:reckenrode/nix-foundryvtt/5cf4e6d9ed7b662dbea7a61d785b67a878598986' (2024-03-03)
  → 'github:reckenrode/nix-foundryvtt/0e61d84370fd051d873216553d09e596b7ad3a34' (2024-03-17)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/b94a96839afcc56de3551aa7472b8d9a3e77e05d' (2024-03-09)
  → 'github:nixos/nixpkgs/56528ee42526794d413d6f244648aaee4a7b56c0' (2024-03-22)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/3030f185ba6a4bf4f18b87f345f104e6a6961f34' (2024-03-09)
  → 'github:nixos/nixpkgs/44d0940ea560dee511026a53f0e2e2cde489b4d4' (2024-03-23)
• Updated input 'nvfetcher':
    'github:berberman/nvfetcher/367e2eaa92d8f5133c2c5ac03a80c0cf25f301b8' (2024-02-25)
  → 'github:berberman/nvfetcher/c774baef4285ce5c72784f58dc565d48f41fd22d' (2024-03-24)
• Updated input 'nvfetcher/flake-utils':
    'github:numtide/flake-utils/1ef2e671c3b0c19053962c07dbda38332dcebf26' (2024-01-15)
  → 'github:numtide/flake-utils/b1d9ab70662946ef0850d488da1c9019f3a9752a' (2024-03-11)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/6c32d3b9c7593f4b466ec5404e59fc09a803a090' (2024-03-14)
  → 'github:Mic92/sops-nix/405987a66cce9a4a82f321f11b205982a7127c88' (2024-03-24)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/b17375d3bb7c79ffc52f3538028b2ec06eb79ef8' (2024-03-10)
  → 'github:NixOS/nixpkgs/ac6bdf6181666ebb4f90dd20f31e2fa66ede6b68' (2024-03-23)
---
 flake.lock | 48 ++++++++++++++++++++++++------------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/flake.lock b/flake.lock
index 475ddf8..f3cd588 100644
--- a/flake.lock
+++ b/flake.lock
@@ -27,11 +27,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1710119954,
-        "narHash": "sha256-e7AMYtBQgRzeRtn//k1dXu22xeiav+G0cQjm3gEky7o=",
+        "lastModified": 1711261295,
+        "narHash": "sha256-5DUNQl9BSmLxgGLbF05G7hi/UTk9DyZq8AuEszhQA7Q=",
         "owner": "nix-community",
         "repo": "disko",
-        "rev": "d389901567d9ceda5a1a833fbf8e8e254e18eb0a",
+        "rev": "5d2d3e421ade554b19b4dbb0d11a04023378a330",
         "type": "github"
       },
       "original": {
@@ -119,11 +119,11 @@
         "systems": "systems_2"
       },
       "locked": {
-        "lastModified": 1705309234,
-        "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
+        "lastModified": 1710146030,
+        "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
+        "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
         "type": "github"
       },
       "original": {
@@ -139,11 +139,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1709504473,
-        "narHash": "sha256-hXzXxaZaI9Pn5tO4otY2gJUvW/orDGDAMdstm3AY8RU=",
+        "lastModified": 1710638592,
+        "narHash": "sha256-R6477tybK4LBP8MKlmMyvndTcZR1Ofi/XA9nDEVcViY=",
         "owner": "reckenrode",
         "repo": "nix-foundryvtt",
-        "rev": "5cf4e6d9ed7b662dbea7a61d785b67a878598986",
+        "rev": "0e61d84370fd051d873216553d09e596b7ad3a34",
         "type": "github"
       },
       "original": {
@@ -170,11 +170,11 @@
     },
     "nixpkgs-stable": {
       "locked": {
-        "lastModified": 1710033658,
-        "narHash": "sha256-yiZiVKP5Ya813iYLho2+CcFuuHpaqKc/CoxOlANKcqM=",
+        "lastModified": 1711233294,
+        "narHash": "sha256-eEu5y4J145BYDw9o/YEmeJyqh8blgnZwuz9k234zuWc=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "b17375d3bb7c79ffc52f3538028b2ec06eb79ef8",
+        "rev": "ac6bdf6181666ebb4f90dd20f31e2fa66ede6b68",
         "type": "github"
       },
       "original": {
@@ -186,11 +186,11 @@
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1709961763,
-        "narHash": "sha256-6H95HGJHhEZtyYA3rIQpvamMKAGoa8Yh2rFV29QnuGw=",
+        "lastModified": 1711163522,
+        "narHash": "sha256-YN/Ciidm+A0fmJPWlHBGvVkcarYWSC+s3NTPk/P+q3c=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "3030f185ba6a4bf4f18b87f345f104e6a6961f34",
+        "rev": "44d0940ea560dee511026a53f0e2e2cde489b4d4",
         "type": "github"
       },
       "original": {
@@ -202,11 +202,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1710021367,
-        "narHash": "sha256-FuMVdWqXMT38u1lcySYyv93A7B8wU0EGzUr4t4jQu8g=",
+        "lastModified": 1711124224,
+        "narHash": "sha256-l0zlN/3CiodvWDtfBOVxeTwYSRz93muVbXWSpaMjXxM=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "b94a96839afcc56de3551aa7472b8d9a3e77e05d",
+        "rev": "56528ee42526794d413d6f244648aaee4a7b56c0",
         "type": "github"
       },
       "original": {
@@ -241,11 +241,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1708838575,
-        "narHash": "sha256-brhWjqJG+Yp0KGkF1LE7h0E86Z7OhDQJLo9qhWAmoYw=",
+        "lastModified": 1711260237,
+        "narHash": "sha256-0/7gn8gDuhNukcnKI5tdFYXYGc19x8CgHeF1x72k9Zw=",
         "owner": "berberman",
         "repo": "nvfetcher",
-        "rev": "367e2eaa92d8f5133c2c5ac03a80c0cf25f301b8",
+        "rev": "c774baef4285ce5c72784f58dc565d48f41fd22d",
         "type": "github"
       },
       "original": {
@@ -354,11 +354,11 @@
         "nixpkgs-stable": "nixpkgs-stable"
       },
       "locked": {
-        "lastModified": 1710433464,
-        "narHash": "sha256-IXlPoWgIRovZ32mYvqqdBgOQln71LouE/HBhbKc1wcw=",
+        "lastModified": 1711249319,
+        "narHash": "sha256-N+Pp3/8H+rd7cO71VNV/ovV/Kwt+XNeUHNhsmyTabdM=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "6c32d3b9c7593f4b466ec5404e59fc09a803a090",
+        "rev": "405987a66cce9a4a82f321f11b205982a7127c88",
         "type": "github"
       },
       "original": {

From d28979c61fd1798de473dcfb36efd3dedee4b520 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 25 Mar 2024 01:14:27 +0100
Subject: [PATCH 134/212] nvfetcher: Update package inputs

---
 pkgs/_sources_nextcloud/generated.json | 6 +++---
 pkgs/_sources_nextcloud/generated.nix  | 6 +++---
 pkgs/_sources_pkgs/generated.json      | 6 +++---
 pkgs/_sources_pkgs/generated.nix       | 6 +++---
 pkgs/nvfetcher.toml                    | 2 +-
 pkgs/prometheus/fail2ban-exporter.nix  | 2 +-
 6 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index 6f96b13..499f108 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -21,11 +21,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-jf6SIsgWTkQIVIYbfNiTA+KRbUM6g7NHFIOVygBwWmU=",
+            "sha256": "sha256-hZfjWAMi/0qs5xMMgOlcoSXG6kcZ2aeDaez+NqSZFKI=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.6.6/calendar-v4.6.6.tar.gz"
+            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.6.7/calendar-v4.6.7.tar.gz"
         },
-        "version": "v4.6.6"
+        "version": "v4.6.7"
     },
     "contacts": {
         "cargoLocks": null,
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index e69b20a..51e76fd 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -11,10 +11,10 @@
   };
   calendar = {
     pname = "calendar";
-    version = "v4.6.6";
+    version = "v4.6.7";
     src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.6.6/calendar-v4.6.6.tar.gz";
-      sha256 = "sha256-jf6SIsgWTkQIVIYbfNiTA+KRbUM6g7NHFIOVygBwWmU=";
+      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.6.7/calendar-v4.6.7.tar.gz";
+      sha256 = "sha256-hZfjWAMi/0qs5xMMgOlcoSXG6kcZ2aeDaez+NqSZFKI=";
     };
   };
   contacts = {
diff --git a/pkgs/_sources_pkgs/generated.json b/pkgs/_sources_pkgs/generated.json
index b3faf9a..fc6c343 100644
--- a/pkgs/_sources_pkgs/generated.json
+++ b/pkgs/_sources_pkgs/generated.json
@@ -11,11 +11,11 @@
             "fetchSubmodules": false,
             "leaveDotGit": false,
             "name": null,
-            "rev": "v0.10.0",
-            "sha256": "sha256-8nIW1XaHCBqQCoLkV1ZYE3NTbVZ6c+UOqYD08XQiv+4=",
+            "rev": "v0.10.1",
+            "sha256": "sha256-zGEhDy3uXIbvx4agSA8Mx7bRtiZZtoDZGbNbHc9L+yI=",
             "type": "git",
             "url": "https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter"
         },
-        "version": "v0.10.0"
+        "version": "v0.10.1"
     }
 }
\ No newline at end of file
diff --git a/pkgs/_sources_pkgs/generated.nix b/pkgs/_sources_pkgs/generated.nix
index bb015b4..39dc6d0 100644
--- a/pkgs/_sources_pkgs/generated.nix
+++ b/pkgs/_sources_pkgs/generated.nix
@@ -3,14 +3,14 @@
 {
   prometheus-fail2ban-exporter = {
     pname = "prometheus-fail2ban-exporter";
-    version = "v0.10.0";
+    version = "v0.10.1";
     src = fetchgit {
       url = "https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter";
-      rev = "v0.10.0";
+      rev = "v0.10.1";
       fetchSubmodules = false;
       deepClone = false;
       leaveDotGit = false;
-      sha256 = "sha256-8nIW1XaHCBqQCoLkV1ZYE3NTbVZ6c+UOqYD08XQiv+4=";
+      sha256 = "sha256-zGEhDy3uXIbvx4agSA8Mx7bRtiZZtoDZGbNbHc9L+yI=";
     };
   };
 }
diff --git a/pkgs/nvfetcher.toml b/pkgs/nvfetcher.toml
index 8c53200..d0dfbe5 100644
--- a/pkgs/nvfetcher.toml
+++ b/pkgs/nvfetcher.toml
@@ -1,3 +1,3 @@
 [prometheus-fail2ban-exporter]
-src.manual = "v0.10.0" # No gitlab support in nvfetcher
+src.manual = "v0.10.1" # No gitlab support in nvfetcher
 fetch.git = "https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter"
diff --git a/pkgs/prometheus/fail2ban-exporter.nix b/pkgs/prometheus/fail2ban-exporter.nix
index 50b4973..b2c6a25 100644
--- a/pkgs/prometheus/fail2ban-exporter.nix
+++ b/pkgs/prometheus/fail2ban-exporter.nix
@@ -4,5 +4,5 @@
 }:
 buildGoModule {
   inherit (sources.prometheus-fail2ban-exporter) pname src version;
-  vendorHash = "sha256-qU6opwhhvzbQOhfGVyiVgKhfCSB0Z4eSRAJnv6ht2I0=";
+  vendorHash = "sha256-5o8p5p0U/c0WAIV5dACnWA3ThzSh2tt5LIFMb59i9GY=";
 }

From 14785afa1429a8c5b0f2a00f273a73cd06c1ec5f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 27 Mar 2024 01:17:26 +0100
Subject: [PATCH 135/212] vm: Set up proper bridge networking

---
 .gitignore                             |  2 +-
 README.md                              |  7 --
 configuration/default.nix              |  1 -
 configuration/hardware-specific/vm.nix | 21 ++++--
 flake.nix                              | 93 +++++++++++---------------
 keys/staging.yaml                      |  6 +-
 lib/default.nix                        | 10 ---
 7 files changed, 61 insertions(+), 79 deletions(-)
 delete mode 100644 lib/default.nix

diff --git a/.gitignore b/.gitignore
index 21e279e..dbee5b9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
 /result
-/tlaternet.qcow2
+*.qcow2
diff --git a/README.md b/README.md
index 8104f1c..f3013ed 100644
--- a/README.md
+++ b/README.md
@@ -21,13 +21,6 @@ running the following in the repository root:
 qemu-img create -f qcow2 ./tlaternet.qcow2 20G
 ```
 
-### New services
-
-Whenever a new service is added, add an appropriate port binding to
-`qemuNetOpts` in the default app.
-
-There is no way to test this without binding to the host port, sadly.
-
 ## Deploying
 
 Deployment is handled using
diff --git a/configuration/default.nix b/configuration/default.nix
index ef1c804..d202fe5 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -11,7 +11,6 @@
     flake-inputs.sops-nix.nixosModules.sops
     flake-inputs.tlaternet-webserver.nixosModules.default
 
-    "${modulesPath}/profiles/headless.nix"
     "${modulesPath}/profiles/minimal.nix"
     (import ../modules)
 
diff --git a/configuration/hardware-specific/vm.nix b/configuration/hardware-specific/vm.nix
index b2e8826..7f1fcf1 100644
--- a/configuration/hardware-specific/vm.nix
+++ b/configuration/hardware-specific/vm.nix
@@ -14,7 +14,9 @@
 
   systemd.network.networks."10-eth0" = {
     matchConfig.Name = "eth0";
-    networkConfig.DHCP = "yes";
+    networkConfig = {
+      Address = "192.168.9.2/24";
+    };
   };
 
   # Both so we have a predictable key for the staging env, as well as
@@ -33,7 +35,18 @@
     }
   ];
 
-  # # Set up VM settings to match real VPS
-  # virtualisation.memorySize = 3941;
-  # virtualisation.cores = 2;
+  virtualisation.vmVariant = {
+    virtualisation = {
+      memorySize = 3941;
+      cores = 2;
+      graphics = false;
+    };
+
+    virtualisation.qemu = {
+      networkingOptions = lib.mkForce [
+        "-device virtio-net,netdev=n1"
+        "-netdev bridge,id=n1,br=br0,helper=$(which qemu-bridge-helper)"
+      ];
+    };
+  };
 }
diff --git a/flake.nix b/flake.nix
index f8255f6..6f6b386 100644
--- a/flake.nix
+++ b/flake.nix
@@ -36,6 +36,7 @@
     ...
   } @ inputs: let
     system = "x86_64-linux";
+    pkgs = nixpkgs.legacyPackages.${system};
   in {
     ##################
     # Configurations #
@@ -75,69 +76,53 @@
     #########
     checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
 
-    ####################
-    # Helper functions #
-    ####################
-    lib = import ./lib {inherit (nixpkgs) lib;};
-
     ###################
     # Utility scripts #
     ###################
-    packages.${system} = let
-      inherit (nixpkgs.legacyPackages.${system}) writeShellScript writeShellScriptBin;
-      vm = nixpkgs.lib.nixosSystem {
-        inherit system;
-        specialArgs.flake-inputs = inputs;
-
-        modules = [
-          ./configuration
-          ./configuration/hardware-specific/vm.nix
-        ];
-      };
-    in {
-      default = vm.config.system.build.vm;
-
-      run-vm = let
-        qemuNetOpts = self.lib.makeQemuNetOpts {
-          "2222" = "2222";
-          "3080" = "80";
-          "3443" = "443";
-          "8448" = "8448"; # Matrix
-          "21025" = "21025"; # Starbound
-        };
-      in
-        writeShellScript "run-vm" ''
-          export QEMU_OPTS="-m 3941 -smp 2 -display curses"
-          export QEMU_NET_OPTS="${qemuNetOpts}"
-          "${vm.config.system.build.vm}/bin/run-testvm-vm"
-        '';
-
-      update-pkgs = let
-        nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher";
-      in
-        writeShellScriptBin "update-pkgs" ''
-          cd "$(git rev-parse --show-toplevel)/pkgs"
-          ${nvfetcher-bin} -o _sources_pkgs -c nvfetcher.toml
-        '';
-
-      update-nextcloud-apps = let
-        nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher";
-      in
-        writeShellScript "update-nextcloud-apps" ''
-          cd "$(git rev-parse --show-toplevel)/pkgs"
-          ${nvfetcher-bin} -o _sources_nextcloud -c nextcloud-apps.toml
-        '';
-    };
-
     apps.${system} = {
-      default = {
+      default = self.apps.${system}.run-vm;
+
+      run-vm = {
         type = "app";
-        program = builtins.toString self.packages.${system}.run-vm;
+        program = let
+          vm = nixpkgs.lib.nixosSystem {
+            inherit system;
+            specialArgs.flake-inputs = inputs;
+
+            modules = [
+              ./configuration
+              ./configuration/hardware-specific/vm.nix
+            ];
+          };
+        in
+          (pkgs.writeShellScript "" ''
+            ${vm.config.system.build.vm.outPath}/bin/run-testvm-vm
+          '')
+          .outPath;
+      };
+
+      update-pkgs = {
+        type = "app";
+        program = let
+          nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher";
+        in
+          (pkgs.writeShellScript "update-pkgs" ''
+            cd "$(git rev-parse --show-toplevel)/pkgs"
+            ${nvfetcher-bin} -o _sources_pkgs -c nvfetcher.toml
+          '')
+          .outPath;
       };
 
       update-nextcloud-apps = {
         type = "app";
-        program = builtins.toString self.packages.${system}.update-nextcloud-apps;
+        program = let
+          nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher";
+        in
+          (pkgs.writeShellScript "update-nextcloud-apps" ''
+            cd "$(git rev-parse --show-toplevel)/pkgs"
+            ${nvfetcher-bin} -o _sources_nextcloud -c nextcloud-apps.toml
+          '')
+          .outPath;
       };
     };
 
diff --git a/keys/staging.yaml b/keys/staging.yaml
index de7686b..9e495ba 100644
--- a/keys/staging.yaml
+++ b/keys/staging.yaml
@@ -14,6 +14,8 @@ wireguard:
     server-key: ENC[AES256_GCM,data:FvY897XdKoa/mckE8JQLCkklsnYD6Wz1wpsu5t3uhEnW3iarnDQxF9msuYU=,iv:jqGXfekM+Vs+J9b5nlZ5Skd1ZKHajoUo2Dc4tMYPm1w=,tag:EehikjI/FCU8wqtpvJRamQ==,type:str]
 restic:
     local-backups: ENC[AES256_GCM,data:3QjEv03t7wE=,iv:y/6Lv4eUbZZfGPwUONykz8VNL62cAJuWaJy9yk3aAmk=,tag:wMlGsepuG9JjwtUKGWSibw==,type:str]
+    storagebox-backups: ENC[AES256_GCM,data:NEHk57B3YtI=,iv:0/qnqMVK0662sgfDQoLxcW7L09SKF8E5liCnjaQ2+2k=,tag:RU0BPwGgvI9bgOPr8VItmA==,type:str]
+    storagebox-ssh-key: ENC[AES256_GCM,data:65+kbJPO90y+rRh3Q5cqLDtQa3VFfbaDPPo1nJLqxgAB7Wm3J7K4qUYAKPcYnkWV4/xFz63R2uCNaq5xv+vuZA==,iv:O7AeE/ujp5p1P7nff7PpghQfN2tQUYBSWL+EHRbE5yA=,tag:Pu/+bEAQuqwmD1Rc//t0cA==,type:str]
 turn:
     env: ENC[AES256_GCM,data:xjIz/AY109lyiL5N01p5T3HcYco/rM5CJSRTtg==,iv:16bW6OpyOK/QL0QPGQp/Baa9xyT8E3ZsYkwqmjuofk0=,tag:J5re3uKxIykw3YunvQWBgg==,type:str]
     secret: ENC[AES256_GCM,data:eQ7dAocoZtg=,iv:fgzjTPv30WqTKlLy+yMn5MsKQgjhPnwlGFFwYEg3gWs=,tag:1ze33U1NBkgMX/9SiaBNQg==,type:str]
@@ -26,8 +28,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2023-12-30T14:09:03Z"
-    mac: ENC[AES256_GCM,data:kuyzVV1Dhlb2LemqRzw2xPr9jtTWqSbFMv70LUEbRmsDpjwQsAIARgoaj32EXdDRTHYXBplTYieR7KvmxykL/8rkj0g4+IuRLY1TcbRS31Gi74FiXvV2apscHhQWXhHPHIHMbwZAfDSHdMrf8hPu28SC9QdbP3SXYNt28Imstrc=,iv:UALUiWGHlWEBmIVWeSyEa16ZdcDZvgtlpHETDV2CcRY=,tag:rxbd3ph+pPf11jup/CMEzw==,type:str]
+    lastmodified: "2024-03-18T23:13:42Z"
+    mac: ENC[AES256_GCM,data:/6GnUxOkftB07feEwQbeXoueLQUkRXL4pee973bAYbjse8gbmU3IvI8CVoj1PuY5JeC7pOFCMjZAxqbMh90oUbVSHssVDLIuL4/ZhxF3on+sKmC5wa/M8lU+Ld2upL+//bz2p4EsDKy1Fedwm22b3mOkjSAUcKp+uh8ORrRmWZ0=,iv:waVUyPo1VPfTldzbs0DH3mGukAWvy2Ut9w5bw7/bdFA=,tag:Wm4KUZwKI4VylJ1i2QoptA==,type:str]
     pgp:
         - created_at: "2023-12-29T15:25:27Z"
           enc: |
diff --git a/lib/default.nix b/lib/default.nix
deleted file mode 100644
index 20d874d..0000000
--- a/lib/default.nix
+++ /dev/null
@@ -1,10 +0,0 @@
-{lib}: let
-  inherit (lib.attrsets) mapAttrsToList;
-  inherit (lib.strings) concatStringsSep;
-in {
-  makeQemuNetOpts = portMapping:
-    concatStringsSep ","
-    (mapAttrsToList
-      (host: vm: "hostfwd=::${host}-:${vm}")
-      portMapping);
-}

From 119db5e1d3d9dc38bcd40e7fd1de38c1b30285c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 8 Apr 2024 20:02:53 +0200
Subject: [PATCH 136/212] sonnenshift: Init

---
 configuration/default.nix                  |   1 +
 configuration/services/battery-manager.nix |  17 +++
 configuration/sops.nix                     |  10 ++
 flake.lock                                 | 139 +++++++++++++++++++++
 flake.nix                                  |   5 +
 keys/production.yaml                       |   7 +-
 keys/staging.yaml                          |   7 +-
 7 files changed, 182 insertions(+), 4 deletions(-)
 create mode 100644 configuration/services/battery-manager.nix

diff --git a/configuration/default.nix b/configuration/default.nix
index d202fe5..b4601b1 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -15,6 +15,7 @@
     (import ../modules)
 
     ./services/backups.nix
+    ./services/battery-manager.nix
     ./services/conduit.nix
     ./services/fail2ban.nix
     ./services/foundryvtt.nix
diff --git a/configuration/services/battery-manager.nix b/configuration/services/battery-manager.nix
new file mode 100644
index 0000000..7f27931
--- /dev/null
+++ b/configuration/services/battery-manager.nix
@@ -0,0 +1,17 @@
+{
+  config,
+  flake-inputs,
+  ...
+}: {
+  imports = [
+    flake-inputs.sonnenshift.nixosModules.default
+  ];
+
+  services.batteryManager = {
+    enable = true;
+    battery = "3ca39300-c523-4315-b9a3-d030f85a9373";
+
+    emailFile = "${config.sops.secrets."battery-manager/email".path}";
+    passwordFile = "${config.sops.secrets."battery-manager/password".path}";
+  };
+}
diff --git a/configuration/sops.nix b/configuration/sops.nix
index dc9fcb5..53044fc 100644
--- a/configuration/sops.nix
+++ b/configuration/sops.nix
@@ -3,6 +3,16 @@
     defaultSopsFile = ../keys/production.yaml;
 
     secrets = {
+      "battery-manager/email" = {
+        owner = "battery-manager";
+        group = "battery-manager";
+      };
+
+      "battery-manager/password" = {
+        owner = "battery-manager";
+        group = "battery-manager";
+      };
+
       # Gitea
       "forgejo/metrics-token" = {
         owner = "forgejo";
diff --git a/flake.lock b/flake.lock
index f3cd588..ea6e19f 100644
--- a/flake.lock
+++ b/flake.lock
@@ -132,6 +132,24 @@
         "type": "github"
       }
     },
+    "flake-utils_2": {
+      "inputs": {
+        "systems": "systems_3"
+      },
+      "locked": {
+        "lastModified": 1705309234,
+        "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
     "foundryvtt": {
       "inputs": {
         "nixpkgs": [
@@ -152,6 +170,28 @@
         "type": "github"
       }
     },
+    "nix-github-actions": {
+      "inputs": {
+        "nixpkgs": [
+          "sonnenshift",
+          "poetry2nixi",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1703863825,
+        "narHash": "sha256-rXwqjtwiGKJheXB43ybM8NwWB8rO2dSRrEqes0S7F5Y=",
+        "owner": "nix-community",
+        "repo": "nix-github-actions",
+        "rev": "5163432afc817cf8bd1f031418d1869e4c9d5547",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "repo": "nix-github-actions",
+        "type": "github"
+      }
+    },
     "nixpkgs": {
       "locked": {
         "lastModified": 1702272962,
@@ -254,6 +294,31 @@
         "type": "github"
       }
     },
+    "poetry2nixi": {
+      "inputs": {
+        "flake-utils": "flake-utils_2",
+        "nix-github-actions": "nix-github-actions",
+        "nixpkgs": [
+          "sonnenshift",
+          "nixpkgs"
+        ],
+        "systems": "systems_4",
+        "treefmt-nix": "treefmt-nix"
+      },
+      "locked": {
+        "lastModified": 1708589824,
+        "narHash": "sha256-2GOiFTkvs5MtVF65sC78KNVxQSmsxtk0WmV1wJ9V2ck=",
+        "owner": "nix-community",
+        "repo": "poetry2nix",
+        "rev": "3c92540611f42d3fb2d0d084a6c694cd6544b609",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "repo": "poetry2nix",
+        "type": "github"
+      }
+    },
     "purescript-overlay": {
       "inputs": {
         "nixpkgs": [
@@ -302,6 +367,7 @@
         "nixpkgs": "nixpkgs_2",
         "nixpkgs-unstable": "nixpkgs-unstable",
         "nvfetcher": "nvfetcher",
+        "sonnenshift": "sonnenshift",
         "sops-nix": "sops-nix",
         "tlaternet-webserver": "tlaternet-webserver"
       }
@@ -346,6 +412,28 @@
         "type": "github"
       }
     },
+    "sonnenshift": {
+      "inputs": {
+        "nixpkgs": [
+          "nixpkgs"
+        ],
+        "poetry2nixi": "poetry2nixi"
+      },
+      "locked": {
+        "lastModified": 1712437610,
+        "narHash": "sha256-U0xIqSupo6yBVWQcHIcLPDKg5ShQIkV/0Ay+Xg3GIlk=",
+        "ref": "tlater/implement-nix-module",
+        "rev": "43c4f591328f194ca989b86cea49773104f75549",
+        "revCount": 7,
+        "type": "git",
+        "url": "ssh://git@github.com/sonnenshift/battery-manager"
+      },
+      "original": {
+        "ref": "tlater/implement-nix-module",
+        "type": "git",
+        "url": "ssh://git@github.com/sonnenshift/battery-manager"
+      }
+    },
     "sops-nix": {
       "inputs": {
         "nixpkgs": [
@@ -397,6 +485,35 @@
         "type": "github"
       }
     },
+    "systems_3": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    },
+    "systems_4": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "id": "systems",
+        "type": "indirect"
+      }
+    },
     "tlaternet-webserver": {
       "inputs": {
         "dream2nix": "dream2nix",
@@ -419,6 +536,28 @@
         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git"
       }
     },
+    "treefmt-nix": {
+      "inputs": {
+        "nixpkgs": [
+          "sonnenshift",
+          "poetry2nixi",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1708335038,
+        "narHash": "sha256-ETLZNFBVCabo7lJrpjD6cAbnE11eDOjaQnznmg/6hAE=",
+        "owner": "numtide",
+        "repo": "treefmt-nix",
+        "rev": "e504621290a1fd896631ddbc5e9c16f4366c9f65",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "treefmt-nix",
+        "type": "github"
+      }
+    },
     "utils": {
       "inputs": {
         "systems": "systems"
diff --git a/flake.nix b/flake.nix
index 6f6b386..f9941ba 100644
--- a/flake.nix
+++ b/flake.nix
@@ -25,6 +25,11 @@
       url = "github:reckenrode/nix-foundryvtt";
       inputs.nixpkgs.follows = "nixpkgs";
     };
+
+    sonnenshift = {
+      url = "git+ssh://git@github.com/sonnenshift/battery-manager?ref=tlater/implement-nix-module";
+      inputs.nixpkgs.follows = "nixpkgs";
+    };
   };
 
   outputs = {
diff --git a/keys/production.yaml b/keys/production.yaml
index aa25072..7ed57b3 100644
--- a/keys/production.yaml
+++ b/keys/production.yaml
@@ -1,3 +1,6 @@
+battery-manager:
+    email: ENC[AES256_GCM,data:rYLUACXR/n+bLBmZ,iv:sUBEkh2+7qGjHZ5R23e/hoCiyTA7GTL4bJvXmxjZ5Sw=,tag:fdPMllaQQfRgX0WZKIre4g==,type:str]
+    password: ENC[AES256_GCM,data:7cokZa6Q6ahSeiFPz+cV,iv:vz405P0IcG9FsAQXlY7mi78GuushQUKJm2irG6buGzc=,tag:JLHG2jTkJDGbinAq9dXRsQ==,type:str]
 forgejo:
     metrics-token: ENC[AES256_GCM,data:WVbD5JloJlHNjeEwe1uEd4Haj6L3ilj1Pnux6yrelUQP18ZPAh90aDO1OIZHaPJR7tTeyATr8BIzZL1zkNhCuA==,iv:eTYXN3hymIN3bTX1YxNGkAYE0KVDbdz2ds8UQAHlALE=,tag:A61loGdu0pfsiez96u2Qsg==,type:str]
 grafana:
@@ -28,8 +31,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2024-03-18T04:05:08Z"
-    mac: ENC[AES256_GCM,data:/v/XRBizRUn8UR1HOIaKrY11/5I8RmsctmxXg0wcCXO983YgcGYTEqfXOSRJzkh/MOjB0c8jpdfE7tyqYgB2iYjm+HmRFVsGNB484e+3ukAMsxz4CTz26RWC/LEemQeBOa5RB3rrPXXo1LrJCBN9Y+T/PVgO2xshUSxyhRFQmMA=,iv:km1m8k/vrCVT8ugvqAZNORLu0NSW66B58btH5k4e//Y=,tag:RZXviobM03IQXN1FwDUlVA==,type:str]
+    lastmodified: "2024-04-06T15:32:49Z"
+    mac: ENC[AES256_GCM,data:ShqLJf9b20LdmjK6MMPtI3KicE+fPc0ejzVGEIdgbNs7ueDwdt7jqgpDrpiyf+vW86tr3I1E1VTlh127XlSH/RZDRRHehpX0tnBiF0zMscmt1vdinY4cPhTwhLJ1fdpVpY8ihdOqv0UFyC39HP78aWESX5S/dJZQ6vS7K5VGKTY=,iv:TYE9f9iyrUQxmMeKXApEYsSPcMWK8vndyBm7HtJyJPo=,tag:vSlobwA1R0Go7BYgNVpMkw==,type:str]
     pgp:
         - created_at: "2024-03-18T04:02:00Z"
           enc: |-
diff --git a/keys/staging.yaml b/keys/staging.yaml
index 9e495ba..029e6ac 100644
--- a/keys/staging.yaml
+++ b/keys/staging.yaml
@@ -1,3 +1,6 @@
+battery-manager:
+    email: ENC[AES256_GCM,data:LM/EGzWHfVQ=,iv:jFaoUQuUfuGoOyj/GFpdI8TerH/c8D9fjvio+IEt2Tc=,tag:IWLiN011JEnHRLIXWQgfmA==,type:str]
+    password: ENC[AES256_GCM,data:SUxjqS7SJHM=,iv:LvdKk88S+nSImh6/ZezbFGLCUBu1Lpdu+neF2xyHdBg=,tag:rcMyZuW4FVNbcbz00wQKBg==,type:str]
 forgejo:
     metrics-token: ENC[AES256_GCM,data:HEDV/GK/WtI=,iv:ihPEusEGVUNZjjjxz2ys6Nfag/og4n7Cqmd4rroT6Ww=,tag:Brcv7XW6HfzzgF3emtuT2A==,type:str]
 grafana:
@@ -28,8 +31,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2024-03-18T23:13:42Z"
-    mac: ENC[AES256_GCM,data:/6GnUxOkftB07feEwQbeXoueLQUkRXL4pee973bAYbjse8gbmU3IvI8CVoj1PuY5JeC7pOFCMjZAxqbMh90oUbVSHssVDLIuL4/ZhxF3on+sKmC5wa/M8lU+Ld2upL+//bz2p4EsDKy1Fedwm22b3mOkjSAUcKp+uh8ORrRmWZ0=,iv:waVUyPo1VPfTldzbs0DH3mGukAWvy2Ut9w5bw7/bdFA=,tag:Wm4KUZwKI4VylJ1i2QoptA==,type:str]
+    lastmodified: "2024-04-06T15:33:40Z"
+    mac: ENC[AES256_GCM,data:qB9uDDM5K6+BmeAKyTJ0Sel6Um0Fc9IhdV3wAn13WxpwDtxmMsdqnwaewI/KepsRG3k76x9vkYL+oKkUysqq1r1FkocUDg4DnKnf1KtKo2Zm9MPcVRG833m6oDoTeGnmgrAMTDKy1tUdGkXW40IfbMakbSjSIfLbrymtoHeVbaE=,iv:8P8M4Ueo3Idlgo+Yqj6JUtFfWX949fz6HfRHEOy1/Vg=,tag:ou+IGZSQSfX6gNoxbpAipg==,type:str]
     pgp:
         - created_at: "2023-12-29T15:25:27Z"
           enc: |

From a243613e6a4c6ac410ecbdacb84a2cf67dfba479 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 8 Apr 2024 20:14:41 +0200
Subject: [PATCH 137/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'deploy-rs':
    'github:serokell/deploy-rs/0a0187794ac7f7a1e62cda3dabf8dc041f868790' (2024-02-16)
  → 'github:serokell/deploy-rs/88b3059b020da69cbe16526b8d639bd5e0b51c8b' (2024-04-01)
• Updated input 'disko':
    'github:nix-community/disko/5d2d3e421ade554b19b4dbb0d11a04023378a330' (2024-03-24)
  → 'github:nix-community/disko/0a17298c0d96190ef3be729d594ba202b9c53beb' (2024-04-05)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/56528ee42526794d413d6f244648aaee4a7b56c0' (2024-03-22)
  → 'github:nixos/nixpkgs/e38d7cb66ea4f7a0eb6681920615dfcc30fc2920' (2024-04-06)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/44d0940ea560dee511026a53f0e2e2cde489b4d4' (2024-03-23)
  → 'github:nixos/nixpkgs/ff0dbd94265ac470dda06a657d5fe49de93b4599' (2024-04-06)
• Updated input 'nvfetcher':
    'github:berberman/nvfetcher/c774baef4285ce5c72784f58dc565d48f41fd22d' (2024-03-24)
  → 'github:berberman/nvfetcher/1463db224a54cbc9499860ef5a51a9b6bf7c3180' (2024-04-08)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/405987a66cce9a4a82f321f11b205982a7127c88' (2024-03-24)
  → 'github:Mic92/sops-nix/39191e8e6265b106c9a2ba0cfd3a4dafe98a31c6' (2024-04-07)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/ac6bdf6181666ebb4f90dd20f31e2fa66ede6b68' (2024-03-23)
  → 'github:NixOS/nixpkgs/e38d7cb66ea4f7a0eb6681920615dfcc30fc2920' (2024-04-06)
---
 flake.lock | 42 +++++++++++++++++++++---------------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/flake.lock b/flake.lock
index ea6e19f..be3a0e2 100644
--- a/flake.lock
+++ b/flake.lock
@@ -7,11 +7,11 @@
         "utils": "utils"
       },
       "locked": {
-        "lastModified": 1708091384,
-        "narHash": "sha256-dTGGw2y8wvfjr+J9CjQbfdulOq72hUG17HXVNxpH1yE=",
+        "lastModified": 1711973905,
+        "narHash": "sha256-UFKME/N1pbUtn+2Aqnk+agUt8CekbpuqwzljivfIme8=",
         "owner": "serokell",
         "repo": "deploy-rs",
-        "rev": "0a0187794ac7f7a1e62cda3dabf8dc041f868790",
+        "rev": "88b3059b020da69cbe16526b8d639bd5e0b51c8b",
         "type": "github"
       },
       "original": {
@@ -27,11 +27,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1711261295,
-        "narHash": "sha256-5DUNQl9BSmLxgGLbF05G7hi/UTk9DyZq8AuEszhQA7Q=",
+        "lastModified": 1712356478,
+        "narHash": "sha256-kTcEtrQIRnexu5lAbLsmUcfR2CrmsACF1s3ZFw1NEVA=",
         "owner": "nix-community",
         "repo": "disko",
-        "rev": "5d2d3e421ade554b19b4dbb0d11a04023378a330",
+        "rev": "0a17298c0d96190ef3be729d594ba202b9c53beb",
         "type": "github"
       },
       "original": {
@@ -210,11 +210,11 @@
     },
     "nixpkgs-stable": {
       "locked": {
-        "lastModified": 1711233294,
-        "narHash": "sha256-eEu5y4J145BYDw9o/YEmeJyqh8blgnZwuz9k234zuWc=",
+        "lastModified": 1712437997,
+        "narHash": "sha256-g0whLLwRvgO2FsyhY8fNk+TWenS3jg5UdlWL4uqgFeo=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "ac6bdf6181666ebb4f90dd20f31e2fa66ede6b68",
+        "rev": "e38d7cb66ea4f7a0eb6681920615dfcc30fc2920",
         "type": "github"
       },
       "original": {
@@ -226,11 +226,11 @@
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1711163522,
-        "narHash": "sha256-YN/Ciidm+A0fmJPWlHBGvVkcarYWSC+s3NTPk/P+q3c=",
+        "lastModified": 1712439257,
+        "narHash": "sha256-aSpiNepFOMk9932HOax0XwNxbA38GOUVOiXfUVPOrck=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "44d0940ea560dee511026a53f0e2e2cde489b4d4",
+        "rev": "ff0dbd94265ac470dda06a657d5fe49de93b4599",
         "type": "github"
       },
       "original": {
@@ -242,11 +242,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1711124224,
-        "narHash": "sha256-l0zlN/3CiodvWDtfBOVxeTwYSRz93muVbXWSpaMjXxM=",
+        "lastModified": 1712437997,
+        "narHash": "sha256-g0whLLwRvgO2FsyhY8fNk+TWenS3jg5UdlWL4uqgFeo=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "56528ee42526794d413d6f244648aaee4a7b56c0",
+        "rev": "e38d7cb66ea4f7a0eb6681920615dfcc30fc2920",
         "type": "github"
       },
       "original": {
@@ -281,11 +281,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1711260237,
-        "narHash": "sha256-0/7gn8gDuhNukcnKI5tdFYXYGc19x8CgHeF1x72k9Zw=",
+        "lastModified": 1712538578,
+        "narHash": "sha256-+fFOtg2fQK6kafSucYDpMG8ENXgo52+YSQtCoXv/+Ik=",
         "owner": "berberman",
         "repo": "nvfetcher",
-        "rev": "c774baef4285ce5c72784f58dc565d48f41fd22d",
+        "rev": "1463db224a54cbc9499860ef5a51a9b6bf7c3180",
         "type": "github"
       },
       "original": {
@@ -442,11 +442,11 @@
         "nixpkgs-stable": "nixpkgs-stable"
       },
       "locked": {
-        "lastModified": 1711249319,
-        "narHash": "sha256-N+Pp3/8H+rd7cO71VNV/ovV/Kwt+XNeUHNhsmyTabdM=",
+        "lastModified": 1712458908,
+        "narHash": "sha256-DMgBS+jNHDg8z3g9GkwqL8xTKXCRQ/0FGsAyrniVonc=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "405987a66cce9a4a82f321f11b205982a7127c88",
+        "rev": "39191e8e6265b106c9a2ba0cfd3a4dafe98a31c6",
         "type": "github"
       },
       "original": {

From a6091b4133e4ff820d0d565b54dca567f4b0697a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 8 Apr 2024 20:44:09 +0200
Subject: [PATCH 138/212] pkgs: Update nextcloud extensions

---
 pkgs/_sources_nextcloud/generated.json | 6 +++---
 pkgs/_sources_nextcloud/generated.nix  | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index 499f108..c45e204 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -77,10 +77,10 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-rnDeo6BRqIAPdw8CcnpO1ifQrx8Bnj5WdgcU/L8aCQk=",
+            "sha256": "sha256-h6RWWIQzpwObDmcGnZPwVwIJZFUXgggeCKBNwI/wDIo=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/notes/releases/download/v4.9.2/notes.tar.gz"
+            "url": "https://github.com/nextcloud/notes/releases/download/v4.9.4/notes.tar.gz"
         },
-        "version": "v4.9.2"
+        "version": "v4.9.4"
     }
 }
\ No newline at end of file
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index 51e76fd..1d0f3a0 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -43,10 +43,10 @@
   };
   notes = {
     pname = "notes";
-    version = "v4.9.2";
+    version = "v4.9.4";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/notes/releases/download/v4.9.2/notes.tar.gz";
-      sha256 = "sha256-rnDeo6BRqIAPdw8CcnpO1ifQrx8Bnj5WdgcU/L8aCQk=";
+      url = "https://github.com/nextcloud/notes/releases/download/v4.9.4/notes.tar.gz";
+      sha256 = "sha256-h6RWWIQzpwObDmcGnZPwVwIJZFUXgggeCKBNwI/wDIo=";
     };
   };
 }

From 7bb27d9bee25aa027879dfb17f186ead91890f65 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 8 Apr 2024 20:49:44 +0200
Subject: [PATCH 139/212] conduit: Switch to stable package since that has
 updated

---
 configuration/services/conduit.nix | 2 --
 1 file changed, 2 deletions(-)

diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
index f50613b..cae2510 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit.nix
@@ -2,7 +2,6 @@
   pkgs,
   config,
   lib,
-  flake-inputs,
   ...
 }: let
   inherit (lib.strings) concatMapStringsSep;
@@ -13,7 +12,6 @@
 in {
   services.matrix-conduit = {
     enable = true;
-    package = flake-inputs.nixpkgs-unstable.legacyPackages.${pkgs.system}.matrix-conduit;
     settings.global = {
       address = "127.0.0.1";
       server_name = domain;

From 0d43b5177d3046fd818204dbc8fffcd2f02d3649 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 13 Apr 2024 04:34:53 +0200
Subject: [PATCH 140/212] treewide: Refactor nginx config

---
 configuration/services/conduit.nix         |  2 +-
 configuration/services/foundryvtt.nix      |  5 +-
 configuration/services/gitea.nix           |  5 +-
 configuration/services/metrics/grafana.nix |  5 +-
 configuration/services/nextcloud.nix       |  4 +-
 configuration/services/webserver.nix       |  5 +-
 modules/default.nix                        | 24 ++-------
 modules/nginxExtensions.nix                | 59 ++++++++++++++++++++++
 8 files changed, 68 insertions(+), 41 deletions(-)
 create mode 100644 modules/nginxExtensions.nix

diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
index cae2510..3fcadeb 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit.nix
@@ -212,9 +212,9 @@ in {
     ];
 
     forceSSL = true;
+    enableHSTS = true;
     extraConfig = ''
       merge_slashes off;
-      access_log /var/log/nginx/${domain}/access.log upstream_time;
     '';
 
     locations = {
diff --git a/configuration/services/foundryvtt.nix b/configuration/services/foundryvtt.nix
index 069f336..51b0212 100644
--- a/configuration/services/foundryvtt.nix
+++ b/configuration/services/foundryvtt.nix
@@ -25,10 +25,7 @@ in {
   in {
     forceSSL = true;
     enableACME = true;
-    extraConfig = ''
-      add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
-      access_log /var/log/nginx/${domain}/access.log upstream_time;
-    '';
+    enableHSTS = true;
 
     locations."/" = {
       proxyWebsockets = true;
diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index 41b8583..ffd21dc 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -42,10 +42,7 @@ in {
   in {
     forceSSL = true;
     enableACME = true;
-    extraConfig = ''
-      add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
-      access_log /var/log/nginx/${domain}/access.log upstream_time;
-    '';
+    enableHSTS = true;
 
     locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}";
     locations."/metrics" = {
diff --git a/configuration/services/metrics/grafana.nix b/configuration/services/metrics/grafana.nix
index 8538dc7..75b9777 100644
--- a/configuration/services/metrics/grafana.nix
+++ b/configuration/services/metrics/grafana.nix
@@ -39,10 +39,7 @@ in {
   services.nginx.virtualHosts."${domain}" = {
     forceSSL = true;
     enableACME = true;
-    extraConfig = ''
-      add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
-      access_log /var/log/nginx/${domain}/access.log upstream_time;
-    '';
+    enableHSTS = true;
     locations."/".proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}";
   };
 }
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 3ba967a..73e075e 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -46,9 +46,7 @@ in {
   services.nginx.virtualHosts."${hostName}" = {
     forceSSL = true;
     enableACME = true;
-    extraConfig = ''
-      access_log /var/log/nginx/${hostName}/access.log upstream_time;
-    '';
+    # The upstream module already adds HSTS
   };
 
   # Block repeated failed login attempts
diff --git a/configuration/services/webserver.nix b/configuration/services/webserver.nix
index 085b1f7..defcae1 100644
--- a/configuration/services/webserver.nix
+++ b/configuration/services/webserver.nix
@@ -17,10 +17,7 @@ in {
 
     forceSSL = true;
     enableACME = true;
-    extraConfig = ''
-      add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
-      access_log /var/log/nginx/${domain}/access.log upstream_time;
-    '';
+    enableHSTS = true;
 
     locations."/".proxyPass = "http://${addr}:${toString port}";
   };
diff --git a/modules/default.nix b/modules/default.nix
index de1c7c2..9341a5a 100644
--- a/modules/default.nix
+++ b/modules/default.nix
@@ -1,23 +1,5 @@
 {
-  pkgs,
-  config,
-  lib,
-  ...
-}: {
-  options.services.nginx.domain = lib.mkOption {
-    type = lib.types.str;
-    description = "The base domain name to append to virtual domain names";
-  };
-
-  config = {
-    # Don't attempt to run acme if the domain name is not tlater.net
-    systemd.services = let
-      confirm = ''[[ "tlater.net" = ${config.services.nginx.domain} ]]'';
-    in
-      lib.mapAttrs' (cert: _:
-        lib.nameValuePair "acme-${cert}" {
-          serviceConfig.ExecCondition = ''${pkgs.runtimeShell} -c '${confirm}' '';
-        })
-      config.security.acme.certs;
-  };
+  imports = [
+    ./nginxExtensions.nix
+  ];
 }
diff --git a/modules/nginxExtensions.nix b/modules/nginxExtensions.nix
new file mode 100644
index 0000000..9fe489a
--- /dev/null
+++ b/modules/nginxExtensions.nix
@@ -0,0 +1,59 @@
+{
+  config,
+  pkgs,
+  lib,
+  ...
+}: {
+  options = {
+    services.nginx.domain = lib.mkOption {
+      type = lib.types.str;
+      description = "The base domain name to append to virtual domain names";
+    };
+
+    services.nginx.virtualHosts = let
+      extraVirtualHostOptions = {
+        name,
+        config,
+        ...
+      }: {
+        options = {
+          enableHSTS = lib.mkEnableOption "Enable HSTS";
+
+          addAccessLog = lib.mkOption {
+            type = lib.types.bool;
+            default = true;
+            description = ''
+              Add special logging to `/var/log/nginx/''${serverName}`
+            '';
+          };
+        };
+
+        config = {
+          extraConfig = lib.concatStringsSep "\n" [
+            (lib.optionalString config.enableHSTS ''
+              add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
+            '')
+            (lib.optionalString config.addAccessLog ''
+              access_log /var/log/nginx/${name}/access.log upstream_time;
+            '')
+          ];
+        };
+      };
+    in
+      lib.mkOption {
+        type = lib.types.attrsOf (lib.types.submodule extraVirtualHostOptions);
+      };
+  };
+
+  config = {
+    # Don't attempt to run acme if the domain name is not tlater.net
+    systemd.services = let
+      confirm = ''[[ "tlater.net" = ${config.services.nginx.domain} ]]'';
+    in
+      lib.mapAttrs' (cert: _:
+        lib.nameValuePair "acme-${cert}" {
+          serviceConfig.ExecCondition = ''${pkgs.runtimeShell} -c '${confirm}' '';
+        })
+      config.security.acme.certs;
+  };
+}

From 8f178f776e2dae3483097c49d795e485e5e7070d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 15 Apr 2024 02:58:09 +0200
Subject: [PATCH 141/212] afvalcalendar: Host enschede afvalcalendar

---
 configuration/default.nix                |    1 +
 configuration/services/afvalcalendar.nix |   67 +
 pkgs/afvalcalendar/Cargo.lock            | 1430 ++++++++++++++++++++++
 pkgs/afvalcalendar/Cargo.toml            |   16 +
 pkgs/afvalcalendar/default.nix           |   20 +
 pkgs/afvalcalendar/src/calendar.rs       |   43 +
 pkgs/afvalcalendar/src/main.rs           |   10 +
 pkgs/afvalcalendar/src/trash.rs          |   59 +
 pkgs/afvalcalendar/test.rest             |    4 +
 pkgs/default.nix                         |    1 +
 10 files changed, 1651 insertions(+)
 create mode 100644 configuration/services/afvalcalendar.nix
 create mode 100644 pkgs/afvalcalendar/Cargo.lock
 create mode 100644 pkgs/afvalcalendar/Cargo.toml
 create mode 100644 pkgs/afvalcalendar/default.nix
 create mode 100644 pkgs/afvalcalendar/src/calendar.rs
 create mode 100644 pkgs/afvalcalendar/src/main.rs
 create mode 100644 pkgs/afvalcalendar/src/trash.rs
 create mode 100644 pkgs/afvalcalendar/test.rest

diff --git a/configuration/default.nix b/configuration/default.nix
index b4601b1..6f93440 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -14,6 +14,7 @@
     "${modulesPath}/profiles/minimal.nix"
     (import ../modules)
 
+    ./services/afvalcalendar.nix
     ./services/backups.nix
     ./services/battery-manager.nix
     ./services/conduit.nix
diff --git a/configuration/services/afvalcalendar.nix b/configuration/services/afvalcalendar.nix
new file mode 100644
index 0000000..0219e88
--- /dev/null
+++ b/configuration/services/afvalcalendar.nix
@@ -0,0 +1,67 @@
+{
+  pkgs,
+  config,
+  ...
+}: {
+  systemd.services.afvalcalendar = {
+    description = "Enschede afvalcalendar -> ical converter";
+    wantedBy = ["multi-user.target"];
+    after = ["network.target"];
+
+    script = ''
+      ${pkgs.local.afvalcalendar}/bin/afvalcalendar > /srv/afvalcalendar/afvalcalendar.ical
+    '';
+
+    startAt = "daily";
+
+    serviceConfig = {
+      DynamicUser = true;
+      ProtectHome = true; # Override the default (read-only)
+      PrivateDevices = true;
+      PrivateIPC = true;
+      PrivateUsers = true;
+      ProtectHostname = true;
+      ProtectClock = true;
+      ProtectKernelTunables = true;
+      ProtectKernelModules = true;
+      ProtectKernelLogs = true;
+      ProtectControlGroups = true;
+      RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"];
+      RestrictNamespaces = true;
+      LockPersonality = true;
+      MemoryDenyWriteExecute = true;
+      RestrictRealtime = true;
+      RestrictSUIDSGID = true;
+      SystemCallArchitectures = "native";
+      SystemCallFilter = ["@system-service" "~@privileged @resources @setuid @keyring"];
+
+      Umask = 0002;
+      SupplementaryGroups = "afvalcalendar-hosting";
+
+      ReadWritePaths = "/srv/afvalcalendar";
+    };
+  };
+
+  services.nginx.virtualHosts."afvalcalendar.${config.services.nginx.domain}" = {
+    forceSSL = true;
+    enableACME = true;
+    enableHSTS = true;
+
+    root = "/srv/afvalcalendar";
+  };
+
+  users.groups.afvalcalendar-hosting = {};
+  systemd.tmpfiles.settings."10-afvalcalendar" = {
+    "/srv/afvalcalendar".d = {
+      user = "nginx";
+      group = "afvalcalendar-hosting";
+      mode = "0775";
+    };
+
+    "/srv/afvalcalendar/afvalcalendar.ical".f = {
+      user = "nginx";
+      group = "afvalcalendar-hosting";
+      mode = "0775";
+    };
+  };
+}
diff --git a/pkgs/afvalcalendar/Cargo.lock b/pkgs/afvalcalendar/Cargo.lock
new file mode 100644
index 0000000..24cace4
--- /dev/null
+++ b/pkgs/afvalcalendar/Cargo.lock
@@ -0,0 +1,1430 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "addr2line"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "afvalcalendar"
+version = "0.1.0"
+dependencies = [
+ "chrono",
+ "hostname",
+ "icalendar",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "serde_repr",
+ "tokio",
+]
+
+[[package]]
+name = "android-tzdata"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
+
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "backtrace"
+version = "0.3.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
+dependencies = [
+ "addr2line",
+ "cc",
+ "cfg-if",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+]
+
+[[package]]
+name = "base64"
+version = "0.21.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bitflags"
+version = "2.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
+
+[[package]]
+name = "bumpalo"
+version = "3.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d32a994c2b3ca201d9b263612a374263f05e7adde37c4707f693dcd375076d1f"
+
+[[package]]
+name = "bytes"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
+
+[[package]]
+name = "cc"
+version = "1.0.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "chrono"
+version = "0.4.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b"
+dependencies = [
+ "android-tzdata",
+ "iana-time-zone",
+ "js-sys",
+ "num-traits",
+ "serde",
+ "wasm-bindgen",
+ "windows-targets 0.52.0",
+]
+
+[[package]]
+name = "cookie"
+version = "0.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24"
+dependencies = [
+ "percent-encoding",
+ "time",
+ "version_check",
+]
+
+[[package]]
+name = "cookie_store"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "387461abbc748185c3a6e1673d826918b450b87ff22639429c694619a83b6cf6"
+dependencies = [
+ "cookie",
+ "idna 0.3.0",
+ "log",
+ "publicsuffix",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "time",
+ "url",
+]
+
+[[package]]
+name = "core-foundation"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
+
+[[package]]
+name = "deranged"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
+dependencies = [
+ "powerfmt",
+]
+
+[[package]]
+name = "encoding_rs"
+version = "0.8.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "equivalent"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+
+[[package]]
+name = "errno"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
+dependencies = [
+ "libc",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+dependencies = [
+ "foreign-types-shared",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
+dependencies = [
+ "futures-core",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
+
+[[package]]
+name = "futures-sink"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
+
+[[package]]
+name = "futures-task"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
+
+[[package]]
+name = "futures-util"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "pin-project-lite",
+ "pin-utils",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "libc",
+ "wasi",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "gimli"
+version = "0.28.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
+
+[[package]]
+name = "h2"
+version = "0.3.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9"
+dependencies = [
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http",
+ "indexmap",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
+
+[[package]]
+name = "hermit-abi"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd"
+
+[[package]]
+name = "hostname"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
+dependencies = [
+ "libc",
+ "match_cfg",
+ "winapi",
+]
+
+[[package]]
+name = "http"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
+dependencies = [
+ "bytes",
+ "http",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "httparse"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
+
+[[package]]
+name = "httpdate"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
+
+[[package]]
+name = "hyper"
+version = "0.14.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "socket2",
+ "tokio",
+ "tower-service",
+ "tracing",
+ "want",
+]
+
+[[package]]
+name = "hyper-tls"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
+dependencies = [
+ "bytes",
+ "hyper",
+ "native-tls",
+ "tokio",
+ "tokio-native-tls",
+]
+
+[[package]]
+name = "iana-time-zone"
+version = "0.1.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "windows-core",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "icalendar"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa4ffbcf3325ae94554c5259ce0b8907d37133c066cb3d424a2fa96aa1f10088"
+dependencies = [
+ "chrono",
+ "iso8601",
+ "nom",
+ "uuid",
+]
+
+[[package]]
+name = "idna"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "idna"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "indexmap"
+version = "2.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177"
+dependencies = [
+ "equivalent",
+ "hashbrown",
+]
+
+[[package]]
+name = "ipnet"
+version = "2.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
+
+[[package]]
+name = "iso8601"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "924e5d73ea28f59011fec52a0d12185d496a9b075d360657aed2a5707f701153"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
+
+[[package]]
+name = "js-sys"
+version = "0.3.68"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.153"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
+
+[[package]]
+name = "log"
+version = "0.4.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
+
+[[package]]
+name = "match_cfg"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
+
+[[package]]
+name = "memchr"
+version = "2.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
+
+[[package]]
+name = "mime"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
+dependencies = [
+ "adler",
+]
+
+[[package]]
+name = "mio"
+version = "0.8.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
+dependencies = [
+ "libc",
+ "wasi",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "native-tls"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
+dependencies = [
+ "lazy_static",
+ "libc",
+ "log",
+ "openssl",
+ "openssl-probe",
+ "openssl-sys",
+ "schannel",
+ "security-framework",
+ "security-framework-sys",
+ "tempfile",
+]
+
+[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
+name = "num-conv"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+
+[[package]]
+name = "num-traits"
+version = "0.2.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "object"
+version = "0.32.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+
+[[package]]
+name = "openssl"
+version = "0.10.64"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
+dependencies = [
+ "bitflags 2.4.2",
+ "cfg-if",
+ "foreign-types",
+ "libc",
+ "once_cell",
+ "openssl-macros",
+ "openssl-sys",
+]
+
+[[package]]
+name = "openssl-macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
+
+[[package]]
+name = "openssl-sys"
+version = "0.9.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae94056a791d0e1217d18b6cbdccb02c61e3054fc69893607f4067e3bb0b1fd1"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "percent-encoding"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
+
+[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "psl-types"
+version = "2.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac"
+
+[[package]]
+name = "publicsuffix"
+version = "2.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457"
+dependencies = [
+ "idna 0.3.0",
+ "psl-types",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "reqwest"
+version = "0.11.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251"
+dependencies = [
+ "base64",
+ "bytes",
+ "cookie",
+ "cookie_store",
+ "encoding_rs",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-tls",
+ "ipnet",
+ "js-sys",
+ "log",
+ "mime",
+ "native-tls",
+ "once_cell",
+ "percent-encoding",
+ "pin-project-lite",
+ "rustls-pemfile",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "sync_wrapper",
+ "system-configuration",
+ "tokio",
+ "tokio-native-tls",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+ "winreg",
+]
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
+
+[[package]]
+name = "rustix"
+version = "0.38.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
+dependencies = [
+ "bitflags 2.4.2",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
+dependencies = [
+ "base64",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
+
+[[package]]
+name = "schannel"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
+dependencies = [
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "security-framework"
+version = "2.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
+dependencies = [
+ "bitflags 1.3.2",
+ "core-foundation",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "2.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.196"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.196"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.114"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_repr"
+version = "0.1.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_urlencoded"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "socket2"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
+dependencies = [
+ "libc",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.49"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "sync_wrapper"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
+
+[[package]]
+name = "system-configuration"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
+dependencies = [
+ "bitflags 1.3.2",
+ "core-foundation",
+ "system-configuration-sys",
+]
+
+[[package]]
+name = "system-configuration-sys"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "rustix",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "time"
+version = "0.3.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749"
+dependencies = [
+ "deranged",
+ "itoa",
+ "num-conv",
+ "powerfmt",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
+
+[[package]]
+name = "time-macros"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774"
+dependencies = [
+ "num-conv",
+ "time-core",
+]
+
+[[package]]
+name = "tinyvec"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
+[[package]]
+name = "tokio"
+version = "1.36.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931"
+dependencies = [
+ "backtrace",
+ "bytes",
+ "libc",
+ "mio",
+ "num_cpus",
+ "pin-project-lite",
+ "socket2",
+ "tokio-macros",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tokio-native-tls"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
+dependencies = [
+ "native-tls",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "pin-project-lite",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "tower-service"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
+
+[[package]]
+name = "tracing"
+version = "0.1.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
+dependencies = [
+ "pin-project-lite",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "try-lock"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "url"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
+dependencies = [
+ "form_urlencoded",
+ "idna 0.5.0",
+ "percent-encoding",
+]
+
+[[package]]
+name = "uuid"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
+dependencies = [
+ "getrandom",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "want"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
+dependencies = [
+ "try-lock",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.91"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.91"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.91"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.91"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.91"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838"
+
+[[package]]
+name = "web-sys"
+version = "0.3.68"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-core"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
+dependencies = [
+ "windows-targets 0.52.0",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets 0.48.5",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets 0.52.0",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.5",
+ "windows_aarch64_msvc 0.48.5",
+ "windows_i686_gnu 0.48.5",
+ "windows_i686_msvc 0.48.5",
+ "windows_x86_64_gnu 0.48.5",
+ "windows_x86_64_gnullvm 0.48.5",
+ "windows_x86_64_msvc 0.48.5",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.0",
+ "windows_aarch64_msvc 0.52.0",
+ "windows_i686_gnu 0.52.0",
+ "windows_i686_msvc 0.52.0",
+ "windows_x86_64_gnu 0.52.0",
+ "windows_x86_64_gnullvm 0.52.0",
+ "windows_x86_64_msvc 0.52.0",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
+
+[[package]]
+name = "winreg"
+version = "0.50.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
+dependencies = [
+ "cfg-if",
+ "windows-sys 0.48.0",
+]
diff --git a/pkgs/afvalcalendar/Cargo.toml b/pkgs/afvalcalendar/Cargo.toml
new file mode 100644
index 0000000..f37dff1
--- /dev/null
+++ b/pkgs/afvalcalendar/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "afvalcalendar"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+icalendar = "0.16.0"
+serde = { version = "1.0.195", features = ["derive"] }
+tokio = { version = "1.35.1", features = ["macros", "rt-multi-thread"] }
+reqwest = { version = "0.11", features = ["cookies", "json"] }
+chrono = { version = "0.4.34", features = ["serde"] }
+serde_json = "1.0.114"
+serde_repr = "0.1.18"
+hostname = "0.3.1"
diff --git a/pkgs/afvalcalendar/default.nix b/pkgs/afvalcalendar/default.nix
new file mode 100644
index 0000000..12e2af5
--- /dev/null
+++ b/pkgs/afvalcalendar/default.nix
@@ -0,0 +1,20 @@
+{
+  pkgs,
+  rustPlatform,
+  ...
+}:
+rustPlatform.buildRustPackage {
+  pname = "afvalcalendar";
+  version = "0.1.0";
+  src = ./.;
+
+  nativeBuildInputs = with pkgs; [
+    pkg-config
+  ];
+
+  buildInputs = with pkgs; [
+    openssl
+  ];
+
+  cargoHash = "sha256-JXx6aUKdKbUTBCwlBw5i1hZy8ofCfSrhLCwFzqdA8cI=";
+}
diff --git a/pkgs/afvalcalendar/src/calendar.rs b/pkgs/afvalcalendar/src/calendar.rs
new file mode 100644
index 0000000..2c76d7f
--- /dev/null
+++ b/pkgs/afvalcalendar/src/calendar.rs
@@ -0,0 +1,43 @@
+use chrono::{Duration, NaiveDate};
+use icalendar::{Alarm, Calendar, Component, Event, EventLike, Property};
+
+use crate::trash::TrashType;
+
+pub(crate) fn calendar_from_pickup_dates(dates: Vec<(TrashType, NaiveDate)>) -> Calendar {
+    let mut ical = Calendar::new();
+    ical.name("Twente Milieu Afvalkalender");
+
+    let events = dates.iter().map(|date| {
+        let description = match date.0 {
+            TrashType::Grey => "Restafval wordt opgehaald",
+            TrashType::Green => "GFT wordt opgehaald",
+            TrashType::Paper => "Papier wordt opgehaald",
+            TrashType::Packages => "Verpakkingen worden opgehaald",
+        };
+
+        let color = Property::new(
+            "COLOR",
+            match date.0 {
+                TrashType::Grey => "darkgray",
+                TrashType::Green => "darkgreen",
+                TrashType::Paper => "royalblue",
+                TrashType::Packages => "darkorange",
+            },
+        );
+
+        let reminder = Alarm::display(description, -Duration::hours(5));
+
+        Event::new()
+            .all_day(date.1)
+            .summary(description)
+            .append_property(color)
+            .alarm(reminder)
+            .done()
+    });
+
+    for event in events {
+        ical.push(event);
+    }
+
+    ical.done()
+}
diff --git a/pkgs/afvalcalendar/src/main.rs b/pkgs/afvalcalendar/src/main.rs
new file mode 100644
index 0000000..b6a5fb0
--- /dev/null
+++ b/pkgs/afvalcalendar/src/main.rs
@@ -0,0 +1,10 @@
+mod calendar;
+mod trash;
+
+#[tokio::main]
+async fn main() {
+    let dates = trash::get_pickup_dates().await.unwrap();
+    let calendar = calendar::calendar_from_pickup_dates(dates);
+
+    calendar.print().unwrap();
+}
diff --git a/pkgs/afvalcalendar/src/trash.rs b/pkgs/afvalcalendar/src/trash.rs
new file mode 100644
index 0000000..89a84d0
--- /dev/null
+++ b/pkgs/afvalcalendar/src/trash.rs
@@ -0,0 +1,59 @@
+use chrono::{Months, NaiveDate, NaiveDateTime, Utc};
+use serde::Deserialize;
+use serde_repr::Deserialize_repr;
+
+#[derive(Deserialize, Debug)]
+#[serde(rename_all = "camelCase")]
+struct CalendarAPIDatum {
+    pickup_dates: Vec<NaiveDateTime>,
+    pickup_type: TrashType,
+}
+
+#[derive(Deserialize, Debug)]
+#[serde(rename_all = "camelCase")]
+struct CalendarAPIResponse {
+    data_list: Vec<CalendarAPIDatum>,
+}
+
+#[derive(Copy, Clone, Deserialize_repr, Debug)]
+#[repr(u8)]
+pub(crate) enum TrashType {
+    Grey = 0,
+    Green = 1,
+    Paper = 2,
+    Packages = 10,
+}
+
+pub(crate) async fn get_pickup_dates() -> Result<Vec<(TrashType, NaiveDate)>, reqwest::Error> {
+    let today = Utc::now().date_naive();
+    let next_month = (today + Months::new(1)).to_string();
+    let today = today.to_string();
+
+    let client = reqwest::Client::new();
+
+    let params = [
+        ("companyCode", "8d97bb56-5afd-4cbc-a651-b4f7314264b4"),
+        ("uniqueAddressID", "1300002485"),
+        ("startDate", &today),
+        ("endDate", &next_month),
+    ];
+
+    let calendar = client
+        .post("https://twentemilieuapi.ximmio.com/api/GetCalendar")
+        .form(&params)
+        .send()
+        .await?
+        .json::<CalendarAPIResponse>()
+        .await?;
+
+    Ok(calendar
+        .data_list
+        .iter()
+        .flat_map(|datum| {
+            datum
+                .pickup_dates
+                .iter()
+                .map(|date| (datum.pickup_type, NaiveDate::from(*date)))
+        })
+        .collect::<Vec<(TrashType, NaiveDate)>>())
+}
diff --git a/pkgs/afvalcalendar/test.rest b/pkgs/afvalcalendar/test.rest
new file mode 100644
index 0000000..d2d409e
--- /dev/null
+++ b/pkgs/afvalcalendar/test.rest
@@ -0,0 +1,4 @@
+POST https://twentemilieuapi.ximmio.com/api/GetCalendar
+Content-Type: application/x-www-form-urlencoded
+
+companyCode=8d97bb56-5afd-4cbc-a651-b4f7314264b4&uniqueAddressID=1300002485&startDate=2024-02-01&endDate=2024-02-29
diff --git a/pkgs/default.nix b/pkgs/default.nix
index 3130ae0..3162787 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -10,6 +10,7 @@ in
     prometheus-fail2ban-exporter = callPackage ./prometheus/fail2ban-exporter.nix {
       sources = pkgs.callPackage ./_sources_pkgs/generated.nix {};
     };
+    afvalcalendar = callPackage ./afvalcalendar {};
   }
   // (
     # Add nextcloud apps

From e16f3be3264bb87b9f8de701d6a991dc2f3c4efb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 16 Apr 2024 01:08:13 +0200
Subject: [PATCH 142/212] acme: Switch to a wildcard certificate

---
 configuration/nginx.nix                    | 7 +++++++
 configuration/services/afvalcalendar.nix   | 2 +-
 configuration/services/conduit.nix         | 2 +-
 configuration/services/foundryvtt.nix      | 2 +-
 configuration/services/gitea.nix           | 2 +-
 configuration/services/metrics/grafana.nix | 2 +-
 configuration/services/nextcloud.nix       | 2 +-
 configuration/services/webserver.nix       | 2 +-
 configuration/sops.nix                     | 4 ++++
 keys/production.yaml                       | 5 +++--
 keys/staging.yaml                          | 5 +++--
 11 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/configuration/nginx.nix b/configuration/nginx.nix
index 14ba9d9..82baab0 100644
--- a/configuration/nginx.nix
+++ b/configuration/nginx.nix
@@ -49,6 +49,13 @@
   security.acme = {
     defaults.email = "tm@tlater.net";
     acceptTerms = true;
+
+    certs."tlater.net" = {
+      extraDomainNames = ["*.tlater.net"];
+      dnsProvider = "hetzner";
+      group = "nginx";
+      credentialFiles."HETZNER_API_KEY_FILE" = config.sops.secrets."hetzner-api".path;
+    };
   };
 
   services.backups.acme = {
diff --git a/configuration/services/afvalcalendar.nix b/configuration/services/afvalcalendar.nix
index 0219e88..e27ba62 100644
--- a/configuration/services/afvalcalendar.nix
+++ b/configuration/services/afvalcalendar.nix
@@ -44,7 +44,7 @@
 
   services.nginx.virtualHosts."afvalcalendar.${config.services.nginx.domain}" = {
     forceSSL = true;
-    enableACME = true;
+    useACMEHost = "tlater.net";
     enableHSTS = true;
 
     root = "/srv/afvalcalendar";
diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
index 3fcadeb..2462d9b 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit.nix
@@ -178,7 +178,7 @@ in {
   };
 
   services.nginx.virtualHosts."${domain}" = {
-    enableACME = true;
+    useACMEHost = "tlater.net";
 
     listen = [
       {
diff --git a/configuration/services/foundryvtt.nix b/configuration/services/foundryvtt.nix
index 51b0212..ac206fc 100644
--- a/configuration/services/foundryvtt.nix
+++ b/configuration/services/foundryvtt.nix
@@ -24,7 +24,7 @@ in {
     inherit (config.services.foundryvtt) port;
   in {
     forceSSL = true;
-    enableACME = true;
+    useACMEHost = "tlater.net";
     enableHSTS = true;
 
     locations."/" = {
diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index ffd21dc..26fe2f8 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -41,7 +41,7 @@ in {
     httpPort = config.services.forgejo.settings.server.HTTP_PORT;
   in {
     forceSSL = true;
-    enableACME = true;
+    useACMEHost = "tlater.net";
     enableHSTS = true;
 
     locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}";
diff --git a/configuration/services/metrics/grafana.nix b/configuration/services/metrics/grafana.nix
index 75b9777..eb5106e 100644
--- a/configuration/services/metrics/grafana.nix
+++ b/configuration/services/metrics/grafana.nix
@@ -38,7 +38,7 @@ in {
 
   services.nginx.virtualHosts."${domain}" = {
     forceSSL = true;
-    enableACME = true;
+    useACMEHost = "tlater.net";
     enableHSTS = true;
     locations."/".proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}";
   };
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 73e075e..bd36041 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -45,7 +45,7 @@ in {
   # Set up SSL
   services.nginx.virtualHosts."${hostName}" = {
     forceSSL = true;
-    enableACME = true;
+    useACMEHost = "tlater.net";
     # The upstream module already adds HSTS
   };
 
diff --git a/configuration/services/webserver.nix b/configuration/services/webserver.nix
index defcae1..387df57 100644
--- a/configuration/services/webserver.nix
+++ b/configuration/services/webserver.nix
@@ -16,7 +16,7 @@ in {
     serverAliases = ["www.${domain}"];
 
     forceSSL = true;
-    enableACME = true;
+    useACMEHost = "tlater.net";
     enableHSTS = true;
 
     locations."/".proxyPass = "http://${addr}:${toString port}";
diff --git a/configuration/sops.nix b/configuration/sops.nix
index 53044fc..0746133 100644
--- a/configuration/sops.nix
+++ b/configuration/sops.nix
@@ -34,6 +34,10 @@
       "heisenbridge/as-token" = {};
       "heisenbridge/hs-token" = {};
 
+      "hetzner-api" = {
+        owner = "acme";
+      };
+
       # Nextcloud
       "nextcloud/tlater" = {
         owner = "nextcloud";
diff --git a/keys/production.yaml b/keys/production.yaml
index 7ed57b3..da90860 100644
--- a/keys/production.yaml
+++ b/keys/production.yaml
@@ -1,3 +1,4 @@
+hetzner-api: ENC[AES256_GCM,data:OsUfo86AzcBe/OELkfB5brEfsZ4gkbeehxwIVUBwQgE=,iv:Bt/cjlZ6oZEVUOQjWMDL7/mfL3HWLFAw1tEGeLMgeKg=,tag:TMU2XiHlMgP4aes10mIQYQ==,type:str]
 battery-manager:
     email: ENC[AES256_GCM,data:rYLUACXR/n+bLBmZ,iv:sUBEkh2+7qGjHZ5R23e/hoCiyTA7GTL4bJvXmxjZ5Sw=,tag:fdPMllaQQfRgX0WZKIre4g==,type:str]
     password: ENC[AES256_GCM,data:7cokZa6Q6ahSeiFPz+cV,iv:vz405P0IcG9FsAQXlY7mi78GuushQUKJm2irG6buGzc=,tag:JLHG2jTkJDGbinAq9dXRsQ==,type:str]
@@ -31,8 +32,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2024-04-06T15:32:49Z"
-    mac: ENC[AES256_GCM,data:ShqLJf9b20LdmjK6MMPtI3KicE+fPc0ejzVGEIdgbNs7ueDwdt7jqgpDrpiyf+vW86tr3I1E1VTlh127XlSH/RZDRRHehpX0tnBiF0zMscmt1vdinY4cPhTwhLJ1fdpVpY8ihdOqv0UFyC39HP78aWESX5S/dJZQ6vS7K5VGKTY=,iv:TYE9f9iyrUQxmMeKXApEYsSPcMWK8vndyBm7HtJyJPo=,tag:vSlobwA1R0Go7BYgNVpMkw==,type:str]
+    lastmodified: "2024-04-15T23:13:18Z"
+    mac: ENC[AES256_GCM,data:3/v+WgSWJ+VcBSBe1Wkis3z+tMmSjbKzLFqBB8xugc6DvgQG8J+1HRrPucLnpNNtEdmpyoTa72U6fPm6JnyUsuj5pLEghLprOJkqQNdRI06fllhw+9d3e3twx6D4oIIsVH6/io4ElXrGsGQTsfNbYhgn+987wa3WP5N25fBac3U=,iv:FL3tzPutOMN6IPkQfXIu/JOZT+OzUSqpMSQrUeXZQHE=,tag:jL1BTsYTA9XjrsjFszxZhA==,type:str]
     pgp:
         - created_at: "2024-03-18T04:02:00Z"
           enc: |-
diff --git a/keys/staging.yaml b/keys/staging.yaml
index 029e6ac..17e7875 100644
--- a/keys/staging.yaml
+++ b/keys/staging.yaml
@@ -1,3 +1,4 @@
+hetzner-api: ENC[AES256_GCM,data:1Zjp003j60g=,iv:+vDcyiqYm4A9CMIrW4oGZKdZiczatBcvfL4qYYhKwCg=,tag:Xeu8JuRm+b+5RO+wFR2M8w==,type:str]
 battery-manager:
     email: ENC[AES256_GCM,data:LM/EGzWHfVQ=,iv:jFaoUQuUfuGoOyj/GFpdI8TerH/c8D9fjvio+IEt2Tc=,tag:IWLiN011JEnHRLIXWQgfmA==,type:str]
     password: ENC[AES256_GCM,data:SUxjqS7SJHM=,iv:LvdKk88S+nSImh6/ZezbFGLCUBu1Lpdu+neF2xyHdBg=,tag:rcMyZuW4FVNbcbz00wQKBg==,type:str]
@@ -31,8 +32,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2024-04-06T15:33:40Z"
-    mac: ENC[AES256_GCM,data:qB9uDDM5K6+BmeAKyTJ0Sel6Um0Fc9IhdV3wAn13WxpwDtxmMsdqnwaewI/KepsRG3k76x9vkYL+oKkUysqq1r1FkocUDg4DnKnf1KtKo2Zm9MPcVRG833m6oDoTeGnmgrAMTDKy1tUdGkXW40IfbMakbSjSIfLbrymtoHeVbaE=,iv:8P8M4Ueo3Idlgo+Yqj6JUtFfWX949fz6HfRHEOy1/Vg=,tag:ou+IGZSQSfX6gNoxbpAipg==,type:str]
+    lastmodified: "2024-04-15T23:13:27Z"
+    mac: ENC[AES256_GCM,data:JhEVrKF2Jsqpdztcr3g5lMrgEFeLXfBRQTwQJ6PmLSNyDORcTU09TJPNWTPDnR5okDrvIU/wlzi5DZ8A0ebNhrKf6l0tNFBT9LSvQFHU5SBxqY/m8uEJKSrEC4IL5lugOOISDka2KSvYXVCXrumMHE5FnmOS/CgOZaZk6LUjPYA=,iv:ygygnSedcTo2Vsc56s2qrz1qkWchvSgvoiMTebRxQQ8=,tag:vf6z8rxsXmqzwpDy9Avifw==,type:str]
     pgp:
         - created_at: "2023-12-29T15:25:27Z"
           enc: |

From 5ddd9914e4b650114d6993d89dd4477e02ba94d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 29 Apr 2024 09:20:14 +0200
Subject: [PATCH 143/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/0a17298c0d96190ef3be729d594ba202b9c53beb' (2024-04-05)
  → 'github:nix-community/disko/285e26465a0bae510897ca04da26ce6307c652b4' (2024-04-26)
• Updated input 'foundryvtt':
    'github:reckenrode/nix-foundryvtt/0e61d84370fd051d873216553d09e596b7ad3a34' (2024-03-17)
  → 'github:reckenrode/nix-foundryvtt/6025615b431170558c3c13f16b549fc0126425e1' (2024-04-09)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/e38d7cb66ea4f7a0eb6681920615dfcc30fc2920' (2024-04-06)
  → 'github:nixos/nixpkgs/12430e43bd9b81a6b4e79e64f87c624ade701eaf' (2024-04-28)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/ff0dbd94265ac470dda06a657d5fe49de93b4599' (2024-04-06)
  → 'github:nixos/nixpkgs/58a1abdbae3217ca6b702f03d3b35125d88a2994' (2024-04-27)
• Updated input 'nvfetcher':
    'github:berberman/nvfetcher/1463db224a54cbc9499860ef5a51a9b6bf7c3180' (2024-04-08)
  → 'github:berberman/nvfetcher/2a824322dc6a755ffda83a13b948d42304521e4d' (2024-04-17)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/39191e8e6265b106c9a2ba0cfd3a4dafe98a31c6' (2024-04-07)
  → 'github:Mic92/sops-nix/f1b0adc27265274e3b0c9b872a8f476a098679bd' (2024-04-23)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/e38d7cb66ea4f7a0eb6681920615dfcc30fc2920' (2024-04-06)
  → 'github:NixOS/nixpkgs/74574c38577914733b4f7a775dd77d24245081dd' (2024-04-20)
---
 flake.lock | 42 +++++++++++++++++++++---------------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/flake.lock b/flake.lock
index be3a0e2..dce5748 100644
--- a/flake.lock
+++ b/flake.lock
@@ -27,11 +27,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1712356478,
-        "narHash": "sha256-kTcEtrQIRnexu5lAbLsmUcfR2CrmsACF1s3ZFw1NEVA=",
+        "lastModified": 1714103775,
+        "narHash": "sha256-kcBiIrmqzt3bNTr2GMBfAyA+on8BEKO1iKzzDFQZkjI=",
         "owner": "nix-community",
         "repo": "disko",
-        "rev": "0a17298c0d96190ef3be729d594ba202b9c53beb",
+        "rev": "285e26465a0bae510897ca04da26ce6307c652b4",
         "type": "github"
       },
       "original": {
@@ -157,11 +157,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1710638592,
-        "narHash": "sha256-R6477tybK4LBP8MKlmMyvndTcZR1Ofi/XA9nDEVcViY=",
+        "lastModified": 1712623723,
+        "narHash": "sha256-jPD5+M+QPyMRk52zfFMIeHdv7yXYJ/yNGqwS0PhYF+E=",
         "owner": "reckenrode",
         "repo": "nix-foundryvtt",
-        "rev": "0e61d84370fd051d873216553d09e596b7ad3a34",
+        "rev": "6025615b431170558c3c13f16b549fc0126425e1",
         "type": "github"
       },
       "original": {
@@ -210,11 +210,11 @@
     },
     "nixpkgs-stable": {
       "locked": {
-        "lastModified": 1712437997,
-        "narHash": "sha256-g0whLLwRvgO2FsyhY8fNk+TWenS3jg5UdlWL4uqgFeo=",
+        "lastModified": 1713638189,
+        "narHash": "sha256-q7APLfB6FmmSMI1Su5ihW9IwntBsk2hWNXh8XtSdSIk=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "e38d7cb66ea4f7a0eb6681920615dfcc30fc2920",
+        "rev": "74574c38577914733b4f7a775dd77d24245081dd",
         "type": "github"
       },
       "original": {
@@ -226,11 +226,11 @@
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1712439257,
-        "narHash": "sha256-aSpiNepFOMk9932HOax0XwNxbA38GOUVOiXfUVPOrck=",
+        "lastModified": 1714253743,
+        "narHash": "sha256-mdTQw2XlariysyScCv2tTE45QSU9v/ezLcHJ22f0Nxc=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "ff0dbd94265ac470dda06a657d5fe49de93b4599",
+        "rev": "58a1abdbae3217ca6b702f03d3b35125d88a2994",
         "type": "github"
       },
       "original": {
@@ -242,11 +242,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1712437997,
-        "narHash": "sha256-g0whLLwRvgO2FsyhY8fNk+TWenS3jg5UdlWL4uqgFeo=",
+        "lastModified": 1714272655,
+        "narHash": "sha256-3/ghIWCve93ngkx5eNPdHIKJP/pMzSr5Wc4rNKE1wOc=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "e38d7cb66ea4f7a0eb6681920615dfcc30fc2920",
+        "rev": "12430e43bd9b81a6b4e79e64f87c624ade701eaf",
         "type": "github"
       },
       "original": {
@@ -281,11 +281,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1712538578,
-        "narHash": "sha256-+fFOtg2fQK6kafSucYDpMG8ENXgo52+YSQtCoXv/+Ik=",
+        "lastModified": 1713333471,
+        "narHash": "sha256-sIVQKOXzruxtTYiBRHZa8UQH+CSIa9K5MZlY6vavYfA=",
         "owner": "berberman",
         "repo": "nvfetcher",
-        "rev": "1463db224a54cbc9499860ef5a51a9b6bf7c3180",
+        "rev": "2a824322dc6a755ffda83a13b948d42304521e4d",
         "type": "github"
       },
       "original": {
@@ -442,11 +442,11 @@
         "nixpkgs-stable": "nixpkgs-stable"
       },
       "locked": {
-        "lastModified": 1712458908,
-        "narHash": "sha256-DMgBS+jNHDg8z3g9GkwqL8xTKXCRQ/0FGsAyrniVonc=",
+        "lastModified": 1713892811,
+        "narHash": "sha256-uIGmA2xq41vVFETCF1WW4fFWFT2tqBln+aXnWrvjGRE=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "39191e8e6265b106c9a2ba0cfd3a4dafe98a31c6",
+        "rev": "f1b0adc27265274e3b0c9b872a8f476a098679bd",
         "type": "github"
       },
       "original": {

From d8f1b9941e809dec932d2eb089f64a2563004ae6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 29 Apr 2024 09:46:11 +0200
Subject: [PATCH 144/212] nextcloud: Update apps

---
 pkgs/_sources_nextcloud/generated.json |  6 +++---
 pkgs/_sources_nextcloud/generated.nix  |  6 +++---
 pkgs/nextcloud-apps.toml               | 15 ++++++++++-----
 3 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index c45e204..ce9ac04 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -77,10 +77,10 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-h6RWWIQzpwObDmcGnZPwVwIJZFUXgggeCKBNwI/wDIo=",
+            "sha256": "sha256-ydpxatwuZUz7XIgK8FMklZlxNQklpsP8Uqpxvt3iK0k=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/notes/releases/download/v4.9.4/notes.tar.gz"
+            "url": "https://github.com/nextcloud/notes/releases/download/v4.10.0/notes.tar.gz"
         },
-        "version": "v4.9.4"
+        "version": "v4.10.0"
     }
 }
\ No newline at end of file
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index 1d0f3a0..c77aa9c 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -43,10 +43,10 @@
   };
   notes = {
     pname = "notes";
-    version = "v4.9.4";
+    version = "v4.10.0";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/notes/releases/download/v4.9.4/notes.tar.gz";
-      sha256 = "sha256-h6RWWIQzpwObDmcGnZPwVwIJZFUXgggeCKBNwI/wDIo=";
+      url = "https://github.com/nextcloud/notes/releases/download/v4.10.0/notes.tar.gz";
+      sha256 = "sha256-ydpxatwuZUz7XIgK8FMklZlxNQklpsP8Uqpxvt3iK0k=";
     };
   };
 }
diff --git a/pkgs/nextcloud-apps.toml b/pkgs/nextcloud-apps.toml
index 25ac8d9..36566db 100644
--- a/pkgs/nextcloud-apps.toml
+++ b/pkgs/nextcloud-apps.toml
@@ -1,24 +1,29 @@
 [bookmarks]
-src.github = "nextcloud/bookmarks"
+# src.github = "nextcloud/bookmarks"
 src.prefix = "v"
+src.manual = "v13.1.3"
 fetch.tarball = "https://github.com/nextcloud/bookmarks/releases/download/v$ver/bookmarks-$ver.tar.gz"
 
 [calendar]
-src.github = "nextcloud-releases/calendar"
+# src.github = "nextcloud-releases/calendar"
+src.manual = "v4.6.7"
 fetch.tarball = "https://github.com/nextcloud-releases/calendar/releases/download/$ver/calendar-$ver.tar.gz"
 
 [contacts]
-src.github = "nextcloud-releases/contacts"
+# src.github = "nextcloud-releases/contacts"
+src.manual = "v5.5.3"
 fetch.tarball = "https://github.com/nextcloud-releases/contacts/releases/download/$ver/contacts-$ver.tar.gz"
 
 [cookbook]
 # src.github = "christianlupus-nextcloud/cookbook-releases"
-src.manual = "v0.10.5"
 src.prefix = "v"
+src.manual = "0.10.5"
 fetch.tarball = "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v$ver/Cookbook-$ver.tar.gz"
 
 [news]
-src.github = "nextcloud/news"
+# src.github = "nextcloud/news"
+# Update to 25 when angular rewrite is done/the alpha when I need to switch to nextcloud 28+
+src.manual = "24.0.0"
 fetch.tarball = "https://github.com/nextcloud/news/releases/download/$ver/news.tar.gz"
 
 [notes]

From 0312fbad3a1b88e2c9925a5f3d33f02d0750283e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 30 Apr 2024 06:09:04 +0200
Subject: [PATCH 145/212] afvalcalendar: Add proper error handling

---
 flake.nix                      | 10 +++++++++-
 pkgs/afvalcalendar/src/main.rs | 13 +++++++++----
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/flake.nix b/flake.nix
index f9941ba..ae22b2e 100644
--- a/flake.nix
+++ b/flake.nix
@@ -140,9 +140,17 @@
         sops-nix.packages.${system}.sops-import-keys-hook
       ];
 
-      packages = [
+      packages = with pkgs; [
         sops-nix.packages.${system}.sops-init-gpg-key
         deploy-rs.packages.${system}.default
+
+        cargo
+        clippy
+        rustc
+        rustfmt
+        rust-analyzer
+        pkg-config
+        openssl
       ];
     };
   };
diff --git a/pkgs/afvalcalendar/src/main.rs b/pkgs/afvalcalendar/src/main.rs
index b6a5fb0..e8023f7 100644
--- a/pkgs/afvalcalendar/src/main.rs
+++ b/pkgs/afvalcalendar/src/main.rs
@@ -3,8 +3,13 @@ mod trash;
 
 #[tokio::main]
 async fn main() {
-    let dates = trash::get_pickup_dates().await.unwrap();
-    let calendar = calendar::calendar_from_pickup_dates(dates);
-
-    calendar.print().unwrap();
+    match trash::get_pickup_dates().await {
+        Ok(dates) => {
+            let calendar = calendar::calendar_from_pickup_dates(dates);
+            calendar.print().unwrap();
+        }
+        Err(error) => {
+            eprintln!("{}", error);
+        }
+    }
 }

From 501c3466bc0d44fa49c07284765463f28ff5b4f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 14 Jun 2024 00:49:12 +0200
Subject: [PATCH 146/212] Update to NixOS 24.05

---
 configuration/default.nix            |  5 ++++-
 configuration/services/nextcloud.nix | 12 +++++++-----
 flake.lock                           |  8 ++++----
 flake.nix                            |  2 +-
 4 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index 6f93440..3b580eb 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -131,7 +131,10 @@
     sudo.execWheelOnly = true;
 
     pam = {
-      enableSSHAgentAuth = true;
+      sshAgentAuth = {
+        enable = true;
+        authorizedKeysFiles = ["/etc/ssh/authorized_keys.d/%u"];
+      };
       services.sudo.sshAgentAuth = true;
     };
   };
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index bd36041..2c7fe4f 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -3,6 +3,9 @@
   config,
   ...
 }: let
+  # Update pending on rewrite of nextcloud news, though there is an
+  # alpha to switch to if it becomes necessary:
+  # https://github.com/nextcloud/news/issues/2610
   nextcloud = pkgs.nextcloud27;
   hostName = "nextcloud.${config.services.nginx.domain}";
 in {
@@ -17,15 +20,16 @@ in {
     configureRedis = true;
 
     config = {
-      overwriteProtocol = "https";
-
       dbtype = "pgsql";
       dbhost = "/run/postgresql";
 
       adminuser = "tlater";
       adminpassFile = config.sops.secrets."nextcloud/tlater".path;
+    };
 
-      defaultPhoneRegion = "AT";
+    settings = {
+      default_phone_region = "AT";
+      overwriteprotocol = "https";
     };
 
     phpOptions = {
@@ -37,8 +41,6 @@ in {
     };
   };
 
-  services.redis.vmOverCommit = true;
-
   # Ensure that this service doesn't start before postgres is ready
   systemd.services.nextcloud-setup.after = ["postgresql.service"];
 
diff --git a/flake.lock b/flake.lock
index dce5748..3f8dcb9 100644
--- a/flake.lock
+++ b/flake.lock
@@ -242,16 +242,16 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1714272655,
-        "narHash": "sha256-3/ghIWCve93ngkx5eNPdHIKJP/pMzSr5Wc4rNKE1wOc=",
+        "lastModified": 1718208800,
+        "narHash": "sha256-US1tAChvPxT52RV8GksWZS415tTS7PV42KTc2PNDBmc=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "12430e43bd9b81a6b4e79e64f87c624ade701eaf",
+        "rev": "cc54fb41d13736e92229c21627ea4f22199fee6b",
         "type": "github"
       },
       "original": {
         "owner": "nixos",
-        "ref": "nixos-23.11",
+        "ref": "nixos-24.05",
         "repo": "nixpkgs",
         "type": "github"
       }
diff --git a/flake.nix b/flake.nix
index ae22b2e..09a74ac 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,7 +2,7 @@
   description = "tlater.net host configuration";
 
   inputs = {
-    nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
+    nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
     nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
     disko = {
       url = "github:nix-community/disko";

From fd138d45e6a2cad89fead6e9f246ba282070d6b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 28 Jun 2024 20:12:55 +0200
Subject: [PATCH 147/212] treewide: Start using nixpkgs-fmt formatting

---
 configuration/default.nix                     |  29 +-
 .../hardware-specific/hetzner/default.nix     |   2 +-
 .../hardware-specific/hetzner/disko.nix       | 132 +++++-----
 configuration/hardware-specific/vm.nix        |   4 +-
 configuration/nginx.nix                       |  45 ++--
 configuration/services/afvalcalendar.nix      |  17 +-
 configuration/services/backups.nix            | 152 +++++------
 configuration/services/battery-manager.nix    |   7 +-
 configuration/services/conduit.nix            | 199 +++++++-------
 configuration/services/fail2ban.nix           |   6 +-
 configuration/services/foundryvtt.nix         |  43 +--
 configuration/services/gitea.nix              |  71 ++---
 configuration/services/metrics/exporters.nix  | 100 +++----
 configuration/services/metrics/grafana.nix    |   6 +-
 configuration/services/metrics/options.nix    | 249 +++++++++---------
 .../services/metrics/victoriametrics.nix      |   6 +-
 configuration/services/nextcloud.nix          |  15 +-
 configuration/services/postgres.nix           |   2 +-
 configuration/services/starbound.nix          |  19 +-
 configuration/services/webserver.nix          |  26 +-
 configuration/services/wireguard.nix          |   6 +-
 configuration/sops.nix                        |   8 +-
 flake.nix                                     | 240 ++++++++---------
 modules/nginxExtensions.nix                   |  84 +++---
 pkgs/afvalcalendar/default.nix                |   7 +-
 pkgs/default.nix                              |  37 +--
 pkgs/mkNextcloudApp.nix                       |   6 +-
 pkgs/prometheus/fail2ban-exporter.nix         |   6 +-
 pkgs/starbound/default.nix                    |  55 ++--
 29 files changed, 812 insertions(+), 767 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index 3b580eb..b933d19 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -1,10 +1,9 @@
-{
-  config,
-  pkgs,
-  lib,
-  modulesPath,
-  flake-inputs,
-  ...
+{ config
+, pkgs
+, lib
+, modulesPath
+, flake-inputs
+, ...
 }: {
   imports = [
     flake-inputs.disko.nixosModules.disko
@@ -47,15 +46,15 @@
     '';
 
     # Enable remote builds from tlater
-    settings.trusted-users = ["@wheel"];
+    settings.trusted-users = [ "@wheel" ];
   };
 
   nixpkgs.config.allowUnfreePredicate = pkg:
-    builtins.elem (lib.getName pkg) ["steam-original" "steam-runtime" "steam-run" "steamcmd"];
+    builtins.elem (lib.getName pkg) [ "steam-original" "steam-runtime" "steam-run" "steamcmd" ];
 
   # Optimization for minecraft servers, see:
   # https://bugs.mojang.com/browse/MC-183518
-  boot.kernelParams = ["highres=off" "nohz=off"];
+  boot.kernelParams = [ "highres=off" "nohz=off" ];
 
   networking = {
     usePredictableInterfaceNames = false;
@@ -106,15 +105,15 @@
 
   users.users.tlater = {
     isNormalUser = true;
-    extraGroups = ["wheel"];
-    openssh.authorizedKeys.keyFiles = [../keys/tlater.pub];
+    extraGroups = [ "wheel" ];
+    openssh.authorizedKeys.keyFiles = [ ../keys/tlater.pub ];
   };
 
   services = {
     openssh = {
       enable = true;
       allowSFTP = false;
-      ports = [2222];
+      ports = [ 2222 ];
       startWhenNeeded = true;
 
       settings = {
@@ -133,14 +132,14 @@
     pam = {
       sshAgentAuth = {
         enable = true;
-        authorizedKeysFiles = ["/etc/ssh/authorized_keys.d/%u"];
+        authorizedKeysFiles = [ "/etc/ssh/authorized_keys.d/%u" ];
       };
       services.sudo.sshAgentAuth = true;
     };
   };
 
   # Remove some unneeded packages
-  environment.defaultPackages = [];
+  environment.defaultPackages = [ ];
 
   system.stateVersion = "20.09";
 }
diff --git a/configuration/hardware-specific/hetzner/default.nix b/configuration/hardware-specific/hetzner/default.nix
index 5ecf63a..3106f19 100644
--- a/configuration/hardware-specific/hetzner/default.nix
+++ b/configuration/hardware-specific/hetzner/default.nix
@@ -8,7 +8,7 @@
   # disables it by default.
   #
   # TODO(tlater): See if would be useful for anything?
-  boot.kernelParams = ["nosgx"];
+  boot.kernelParams = [ "nosgx" ];
 
   networking.hostName = "hetzner-1";
   services.nginx.domain = "tlater.net";
diff --git a/configuration/hardware-specific/hetzner/disko.nix b/configuration/hardware-specific/hetzner/disko.nix
index e404688..a2ea764 100644
--- a/configuration/hardware-specific/hetzner/disko.nix
+++ b/configuration/hardware-specific/hetzner/disko.nix
@@ -1,82 +1,84 @@
 {
-  disko.devices.disk = let
-    bootPartition = {
-      size = "1M";
-      type = "EF02";
-    };
-
-    swapPartition = {
-      # 8G is apparently recommended for this much RAM, but we set up
-      # 4G on both disks for mirroring purposes.
-      #
-      # That'll still be 8G during normal operation, and it's probably
-      # not too bad to have slightly less swap if a disk dies.
-      size = "4G";
-      content = {
-        type = "swap";
-        randomEncryption = true;
+  disko.devices.disk =
+    let
+      bootPartition = {
+        size = "1M";
+        type = "EF02";
       };
-    };
 
-    mountOptions = ["compress=zstd" "noatime"];
-  in {
-    sda = {
-      type = "disk";
-      device = "/dev/sda";
-      content = {
-        type = "gpt";
-        partitions = {
-          boot = bootPartition;
-          swap = swapPartition;
+      swapPartition = {
+        # 8G is apparently recommended for this much RAM, but we set up
+        # 4G on both disks for mirroring purposes.
+        #
+        # That'll still be 8G during normal operation, and it's probably
+        # not too bad to have slightly less swap if a disk dies.
+        size = "4G";
+        content = {
+          type = "swap";
+          randomEncryption = true;
+        };
+      };
 
-          disk1 = {
-            size = "100%";
-            # Empty partition to combine in RAID0 with the other disk
+      mountOptions = [ "compress=zstd" "noatime" ];
+    in
+    {
+      sda = {
+        type = "disk";
+        device = "/dev/sda";
+        content = {
+          type = "gpt";
+          partitions = {
+            boot = bootPartition;
+            swap = swapPartition;
+
+            disk1 = {
+              size = "100%";
+              # Empty partition to combine in RAID0 with the other disk
+            };
           };
         };
       };
-    };
 
-    sdb = {
-      type = "disk";
-      device = "/dev/sdb";
-      content = {
-        type = "gpt";
-        partitions = {
-          boot = bootPartition;
-          swap = swapPartition;
+      sdb = {
+        type = "disk";
+        device = "/dev/sdb";
+        content = {
+          type = "gpt";
+          partitions = {
+            boot = bootPartition;
+            swap = swapPartition;
 
-          disk2 = {
-            size = "100%";
-            content = {
-              type = "btrfs";
-              # Hack to get multi-device btrfs going
-              # See https://github.com/nix-community/disko/issues/99
-              extraArgs = ["-d" "raid1" "-m" "raid1" "--runtime-features" "quota" "/dev/sda3"];
-              subvolumes = {
-                "/volume" = {};
-                "/volume/root" = {
-                  inherit mountOptions;
-                  mountpoint = "/";
+            disk2 = {
+              size = "100%";
+              content = {
+                type = "btrfs";
+                # Hack to get multi-device btrfs going
+                # See https://github.com/nix-community/disko/issues/99
+                extraArgs = [ "-d" "raid1" "-m" "raid1" "--runtime-features" "quota" "/dev/sda3" ];
+                subvolumes = {
+                  "/volume" = { };
+                  "/volume/root" = {
+                    inherit mountOptions;
+                    mountpoint = "/";
+                  };
+                  "/volume/home" = {
+                    inherit mountOptions;
+                    mountpoint = "/home";
+                  };
+                  "/volume/var" = {
+                    inherit mountOptions;
+                    mountpoint = "/var";
+                  };
+                  "/volume/nix-store" = {
+                    inherit mountOptions;
+                    mountpoint = "/nix";
+                  };
+                  "/snapshots" = { };
                 };
-                "/volume/home" = {
-                  inherit mountOptions;
-                  mountpoint = "/home";
-                };
-                "/volume/var" = {
-                  inherit mountOptions;
-                  mountpoint = "/var";
-                };
-                "/volume/nix-store" = {
-                  inherit mountOptions;
-                  mountpoint = "/nix";
-                };
-                "/snapshots" = {};
               };
             };
           };
         };
       };
     };
-  };
 }
diff --git a/configuration/hardware-specific/vm.nix b/configuration/hardware-specific/vm.nix
index 7f1fcf1..86fcaed 100644
--- a/configuration/hardware-specific/vm.nix
+++ b/configuration/hardware-specific/vm.nix
@@ -1,8 +1,8 @@
-{lib, ...}: {
+{ lib, ... }: {
   users.users.tlater.password = "insecure";
 
   # Disable graphical tty so -curses works
-  boot.kernelParams = ["nomodeset"];
+  boot.kernelParams = [ "nomodeset" ];
 
   networking.hostName = "testvm";
   # Sets the base domain for nginx to a local domain so that we can
diff --git a/configuration/nginx.nix b/configuration/nginx.nix
index 82baab0..d696bba 100644
--- a/configuration/nginx.nix
+++ b/configuration/nginx.nix
@@ -1,7 +1,6 @@
-{
-  config,
-  lib,
-  ...
+{ config
+, lib
+, ...
 }: {
   services.nginx = {
     enable = true;
@@ -27,31 +26,33 @@
       # Override the default, just keep fewer logs
       nginx.rotate = 6;
     }
-    // lib.mapAttrs' (virtualHost: _:
-      lib.nameValuePair "/var/log/nginx/${virtualHost}/access.log" {
-        frequency = "daily";
-        rotate = 2;
-        compress = true;
-        delaycompress = true;
-        su = "${config.services.nginx.user} ${config.services.nginx.group}";
-        postrotate = "[ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`";
-      })
-    config.services.nginx.virtualHosts;
+    // lib.mapAttrs'
+      (virtualHost: _:
+        lib.nameValuePair "/var/log/nginx/${virtualHost}/access.log" {
+          frequency = "daily";
+          rotate = 2;
+          compress = true;
+          delaycompress = true;
+          su = "${config.services.nginx.user} ${config.services.nginx.group}";
+          postrotate = "[ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`";
+        })
+      config.services.nginx.virtualHosts;
 
   systemd.tmpfiles.rules =
-    lib.mapAttrsToList (
-      virtualHost: _:
-      #
-      "d /var/log/nginx/${virtualHost} 0750 ${config.services.nginx.user} ${config.services.nginx.group}"
-    )
-    config.services.nginx.virtualHosts;
+    lib.mapAttrsToList
+      (
+        virtualHost: _:
+          #
+          "d /var/log/nginx/${virtualHost} 0750 ${config.services.nginx.user} ${config.services.nginx.group}"
+      )
+      config.services.nginx.virtualHosts;
 
   security.acme = {
     defaults.email = "tm@tlater.net";
     acceptTerms = true;
 
     certs."tlater.net" = {
-      extraDomainNames = ["*.tlater.net"];
+      extraDomainNames = [ "*.tlater.net" ];
       dnsProvider = "hetzner";
       group = "nginx";
       credentialFiles."HETZNER_API_KEY_FILE" = config.sops.secrets."hetzner-api".path;
@@ -62,6 +63,6 @@
     user = "acme";
     paths =
       lib.mapAttrsToList (virtualHost: _: "/var/lib/acme/${virtualHost}")
-      config.services.nginx.virtualHosts;
+        config.services.nginx.virtualHosts;
   };
 }
diff --git a/configuration/services/afvalcalendar.nix b/configuration/services/afvalcalendar.nix
index e27ba62..28e3a75 100644
--- a/configuration/services/afvalcalendar.nix
+++ b/configuration/services/afvalcalendar.nix
@@ -1,12 +1,11 @@
-{
-  pkgs,
-  config,
-  ...
+{ pkgs
+, config
+, ...
 }: {
   systemd.services.afvalcalendar = {
     description = "Enschede afvalcalendar -> ical converter";
-    wantedBy = ["multi-user.target"];
-    after = ["network.target"];
+    wantedBy = [ "multi-user.target" ];
+    after = [ "network.target" ];
 
     script = ''
       ${pkgs.local.afvalcalendar}/bin/afvalcalendar > /srv/afvalcalendar/afvalcalendar.ical
@@ -26,14 +25,14 @@
       ProtectKernelModules = true;
       ProtectKernelLogs = true;
       ProtectControlGroups = true;
-      RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"];
+      RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
       RestrictNamespaces = true;
       LockPersonality = true;
       MemoryDenyWriteExecute = true;
       RestrictRealtime = true;
       RestrictSUIDSGID = true;
       SystemCallArchitectures = "native";
-      SystemCallFilter = ["@system-service" "~@privileged @resources @setuid @keyring"];
+      SystemCallFilter = [ "@system-service" "~@privileged @resources @setuid @keyring" ];
 
       Umask = 0002;
       SupplementaryGroups = "afvalcalendar-hosting";
@@ -50,7 +49,7 @@
     root = "/srv/afvalcalendar";
   };
 
-  users.groups.afvalcalendar-hosting = {};
+  users.groups.afvalcalendar-hosting = { };
   systemd.tmpfiles.settings."10-afvalcalendar" = {
     "/srv/afvalcalendar".d = {
       user = "nginx";
diff --git a/configuration/services/backups.nix b/configuration/services/backups.nix
index 98aa473..7c77399 100644
--- a/configuration/services/backups.nix
+++ b/configuration/services/backups.nix
@@ -1,9 +1,9 @@
-{
-  config,
-  pkgs,
-  lib,
-  ...
-}: let
+{ config
+, pkgs
+, lib
+, ...
+}:
+let
   inherit (lib) types optional singleton;
   mkShutdownScript = service:
     pkgs.writeShellScript "backup-${service}-shutdown" ''
@@ -42,17 +42,17 @@
     RESTIC_REPOSITORY = "rclone:storagebox:backups";
     RCLONE_CONFIG = rcloneConfig;
   };
-in {
+in
+{
   options = {
     services.backups = lib.mkOption {
       description = lib.mdDoc ''
         Configure restic backups with a specific tag.
       '';
-      type = types.attrsOf (types.submodule ({
-        config,
-        name,
-        ...
-      }: {
+      type = types.attrsOf (types.submodule ({ config
+                                             , name
+                                             , ...
+                                             }: {
         options = {
           user = lib.mkOption {
             type = types.str;
@@ -76,7 +76,7 @@ in {
           preparation = {
             packages = lib.mkOption {
               type = types.listOf types.package;
-              default = [];
+              default = [ ];
               description = ''
                 The list of packages to make available in the
                 preparation script.
@@ -97,7 +97,7 @@ in {
           cleanup = {
             packages = lib.mkOption {
               type = types.listOf types.package;
-              default = [];
+              default = [ ];
               description = ''
                 The list of packages to make available in the
                 cleanup script.
@@ -116,7 +116,7 @@ in {
           };
           pauseServices = lib.mkOption {
             type = types.listOf types.str;
-            default = [];
+            default = [ ];
             description = ''
               The systemd services that need to be shut down before
               the backup can run. Services will be restarted after the
@@ -131,7 +131,7 @@ in {
     };
   };
 
-  config = lib.mkIf (config.services.backups != {}) {
+  config = lib.mkIf (config.services.backups != { }) {
     systemd.services =
       {
         restic-prune = {
@@ -164,79 +164,81 @@ in {
           };
         };
       }
-      // lib.mapAttrs' (name: backup:
-        lib.nameValuePair "backup-${name}" {
-          # Don't want to restart mid-backup
-          restartIfChanged = false;
+      // lib.mapAttrs'
+        (name: backup:
+          lib.nameValuePair "backup-${name}" {
+            # Don't want to restart mid-backup
+            restartIfChanged = false;
 
-          environment =
-            resticEnv
-            // {
-              RESTIC_CACHE_DIR = "%C/backup-${name}";
-            };
+            environment =
+              resticEnv
+              // {
+                RESTIC_CACHE_DIR = "%C/backup-${name}";
+              };
 
-          path = with pkgs; [
-            coreutils
-            openssh
-            rclone
-            restic
-          ];
-
-          # TODO(tlater): If I ever add more than one repo, service
-          # shutdown/restarting will potentially break if multiple
-          # backups for the same service overlap. A more clever
-          # sentinel file with reference counts would probably solve
-          # this.
-          serviceConfig = {
-            User = backup.user;
-            Group = "backup";
-            RuntimeDirectory = "backup-${name}";
-            CacheDirectory = "backup-${name}";
-            CacheDirectoryMode = "0700";
-            PrivateTmp = true;
-
-            ExecStart = [
-              (lib.concatStringsSep " " (["${pkgs.restic}/bin/restic" "backup" "--tag" name] ++ backup.paths))
+            path = with pkgs; [
+              coreutils
+              openssh
+              rclone
+              restic
             ];
 
-            ExecStartPre =
-              map (service: "+${mkShutdownScript service}") backup.pauseServices
-              ++ singleton (writeScript "backup-${name}-repo-init" [] ''
-                restic snapshots || restic init
-              '')
-              ++ optional (backup.preparation.text != null)
-              (writeScript "backup-${name}-prepare" backup.preparation.packages backup.preparation.text);
+            # TODO(tlater): If I ever add more than one repo, service
+            # shutdown/restarting will potentially break if multiple
+            # backups for the same service overlap. A more clever
+            # sentinel file with reference counts would probably solve
+            # this.
+            serviceConfig = {
+              User = backup.user;
+              Group = "backup";
+              RuntimeDirectory = "backup-${name}";
+              CacheDirectory = "backup-${name}";
+              CacheDirectoryMode = "0700";
+              PrivateTmp = true;
 
-            # TODO(tlater): Add repo pruning/checking
-            ExecStopPost =
-              map (service: "+${mkRestartScript service}") backup.pauseServices
-              ++ optional (backup.cleanup.text != null)
-              (writeScript "backup-${name}-cleanup" backup.cleanup.packages backup.cleanup.text);
-          };
-        })
-      config.services.backups;
+              ExecStart = [
+                (lib.concatStringsSep " " ([ "${pkgs.restic}/bin/restic" "backup" "--tag" name ] ++ backup.paths))
+              ];
+
+              ExecStartPre =
+                map (service: "+${mkShutdownScript service}") backup.pauseServices
+                ++ singleton (writeScript "backup-${name}-repo-init" [ ] ''
+                  restic snapshots || restic init
+                '')
+                ++ optional (backup.preparation.text != null)
+                  (writeScript "backup-${name}-prepare" backup.preparation.packages backup.preparation.text);
+
+              # TODO(tlater): Add repo pruning/checking
+              ExecStopPost =
+                map (service: "+${mkRestartScript service}") backup.pauseServices
+                ++ optional (backup.cleanup.text != null)
+                  (writeScript "backup-${name}-cleanup" backup.cleanup.packages backup.cleanup.text);
+            };
+          })
+        config.services.backups;
 
     systemd.timers =
       {
         restic-prune = {
-          wantedBy = ["timers.target"];
+          wantedBy = [ "timers.target" ];
           timerConfig.OnCalendar = "Thursday 03:00:00 UTC";
           # Don't make this persistent, in case the server was offline
           # for a while. This job cannot run at the same time as any
           # of the backup jobs.
         };
       }
-      // lib.mapAttrs' (name: backup:
-        lib.nameValuePair "backup-${name}" {
-          wantedBy = ["timers.target"];
-          timerConfig = {
-            OnCalendar = "Wednesday 02:30:00 UTC";
-            RandomizedDelaySec = "1h";
-            FixedRandomDelay = true;
-            Persistent = true;
-          };
-        })
-      config.services.backups;
+      // lib.mapAttrs'
+        (name: backup:
+          lib.nameValuePair "backup-${name}" {
+            wantedBy = [ "timers.target" ];
+            timerConfig = {
+              OnCalendar = "Wednesday 02:30:00 UTC";
+              RandomizedDelaySec = "1h";
+              FixedRandomDelay = true;
+              Persistent = true;
+            };
+          })
+        config.services.backups;
 
     users = {
       # This user is only used to own the ssh key, because apparently
@@ -245,7 +247,7 @@ in {
         group = "backup";
         isSystemUser = true;
       };
-      groups.backup = {};
+      groups.backup = { };
     };
   };
 }
diff --git a/configuration/services/battery-manager.nix b/configuration/services/battery-manager.nix
index 7f27931..7783a3b 100644
--- a/configuration/services/battery-manager.nix
+++ b/configuration/services/battery-manager.nix
@@ -1,7 +1,6 @@
-{
-  config,
-  flake-inputs,
-  ...
+{ config
+, flake-inputs
+, ...
 }: {
   imports = [
     flake-inputs.sonnenshift.nixosModules.default
diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
index 2462d9b..950165c 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit.nix
@@ -1,15 +1,16 @@
-{
-  pkgs,
-  config,
-  lib,
-  ...
-}: let
+{ pkgs
+, config
+, lib
+, ...
+}:
+let
   inherit (lib.strings) concatMapStringsSep;
 
   cfg = config.services.matrix-conduit;
   domain = "matrix.${config.services.nginx.domain}";
   turn-realm = "turn.${config.services.nginx.domain}";
-in {
+in
+{
   services.matrix-conduit = {
     enable = true;
     settings.global = {
@@ -17,99 +18,103 @@ in {
       server_name = domain;
       database_backend = "rocksdb";
 
-      turn_uris = let
-        address = "${config.services.coturn.realm}:${toString config.services.coturn.listening-port}";
-        tls-address = "${config.services.coturn.realm}:${toString config.services.coturn.tls-listening-port}";
-      in [
-        "turn:${address}?transport=udp"
-        "turn:${address}?transport=tcp"
-        "turns:${tls-address}?transport=udp"
-        "turns:${tls-address}?transport=tcp"
-      ];
-    };
-  };
-
-  systemd.services.heisenbridge = let
-    replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret";
-    registrationFile = builtins.toFile "heisenbridge-registration.yaml" (builtins.toJSON {
-      id = "heisenbridge";
-      url = "http://127.0.0.1:9898";
-      as_token = "@AS_TOKEN@";
-      hs_token = "@HS_TOKEN@";
-      rate_limited = false;
-      sender_localpart = "heisenbridge";
-      namespaces = {
-        users = [
-          {
-            regex = "@irc_.*";
-            exclusive = true;
-          }
-          {
-            regex = "@heisenbridge:.*";
-            exclusive = true;
-          }
+      turn_uris =
+        let
+          address = "${config.services.coturn.realm}:${toString config.services.coturn.listening-port}";
+          tls-address = "${config.services.coturn.realm}:${toString config.services.coturn.tls-listening-port}";
+        in
+        [
+          "turn:${address}?transport=udp"
+          "turn:${address}?transport=tcp"
+          "turns:${tls-address}?transport=udp"
+          "turns:${tls-address}?transport=tcp"
         ];
-        aliases = [];
-        rooms = [];
-      };
-    });
-
-    # TODO(tlater): Starting with systemd 253 it will become possible
-    # to do the credential setup as part of ExecStartPre/preStart
-    # instead.
-    #
-    # This will also make it possible to actually set caps on the
-    # heisenbridge process using systemd, so that we can run the
-    # identd process.
-    execScript = pkgs.writeShellScript "heisenbridge" ''
-      cp ${registrationFile} "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml"
-      chmod 600 $RUNTIME_DIRECTORY/heisenbridge-registration.yaml
-      ${replaceSecretBin} '@AS_TOKEN@' "$CREDENTIALS_DIRECTORY/heisenbridge_as-token" "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml"
-      ${replaceSecretBin} '@HS_TOKEN@' "$CREDENTIALS_DIRECTORY/heisenbridge_hs-token" "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml"
-      chmod 400 $RUNTIME_DIRECTORY/heisenbridge-registration.yaml
-
-      ${pkgs.heisenbridge}/bin/heisenbridge \
-          --config $RUNTIME_DIRECTORY/heisenbridge-registration.yaml \
-          --owner @tlater:matrix.tlater.net \
-          'http://localhost:${toString cfg.settings.global.port}'
-    '';
-  in {
-    description = "Matrix<->IRC bridge";
-    wantedBy = ["multi-user.target"];
-    after = ["conduit.service"];
-
-    serviceConfig = {
-      Type = "simple";
-
-      LoadCredential = "heisenbridge:/run/secrets/heisenbridge";
-
-      ExecStart = execScript;
-
-      DynamicUser = true;
-      RuntimeDirectory = "heisenbridge";
-      RuntimeDirectoryMode = "0700";
-
-      RestrictNamespaces = true;
-      PrivateUsers = true;
-      ProtectHostname = true;
-      ProtectClock = true;
-      ProtectKernelTunables = true;
-      ProtectKernelModules = true;
-      ProtectKernelLogs = true;
-      ProtectControlGroups = true;
-      RestrictAddressFamilies = ["AF_INET AF_INET6"];
-      LockPersonality = true;
-      RestrictRealtime = true;
-      ProtectProc = "invisible";
-      ProcSubset = "pid";
-      UMask = 0077;
-
-      # For the identd port
-      # CapabilityBoundingSet = ["CAP_NET_BIND_SERVICE"];
-      # AmbientCapabilities = ["CAP_NET_BIND_SERVICE"];
     };
   };
 
+  systemd.services.heisenbridge =
+    let
+      replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret";
+      registrationFile = builtins.toFile "heisenbridge-registration.yaml" (builtins.toJSON {
+        id = "heisenbridge";
+        url = "http://127.0.0.1:9898";
+        as_token = "@AS_TOKEN@";
+        hs_token = "@HS_TOKEN@";
+        rate_limited = false;
+        sender_localpart = "heisenbridge";
+        namespaces = {
+          users = [
+            {
+              regex = "@irc_.*";
+              exclusive = true;
+            }
+            {
+              regex = "@heisenbridge:.*";
+              exclusive = true;
+            }
+          ];
+          aliases = [ ];
+          rooms = [ ];
+        };
+      });
+
+      # TODO(tlater): Starting with systemd 253 it will become possible
+      # to do the credential setup as part of ExecStartPre/preStart
+      # instead.
+      #
+      # This will also make it possible to actually set caps on the
+      # heisenbridge process using systemd, so that we can run the
+      # identd process.
+      execScript = pkgs.writeShellScript "heisenbridge" ''
+        cp ${registrationFile} "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml"
+        chmod 600 $RUNTIME_DIRECTORY/heisenbridge-registration.yaml
+        ${replaceSecretBin} '@AS_TOKEN@' "$CREDENTIALS_DIRECTORY/heisenbridge_as-token" "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml"
+        ${replaceSecretBin} '@HS_TOKEN@' "$CREDENTIALS_DIRECTORY/heisenbridge_hs-token" "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml"
+        chmod 400 $RUNTIME_DIRECTORY/heisenbridge-registration.yaml
+
+        ${pkgs.heisenbridge}/bin/heisenbridge \
+            --config $RUNTIME_DIRECTORY/heisenbridge-registration.yaml \
+            --owner @tlater:matrix.tlater.net \
+            'http://localhost:${toString cfg.settings.global.port}'
+      '';
+    in
+    {
+      description = "Matrix<->IRC bridge";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "conduit.service" ];
+
+      serviceConfig = {
+        Type = "simple";
+
+        LoadCredential = "heisenbridge:/run/secrets/heisenbridge";
+
+        ExecStart = execScript;
+
+        DynamicUser = true;
+        RuntimeDirectory = "heisenbridge";
+        RuntimeDirectoryMode = "0700";
+
+        RestrictNamespaces = true;
+        PrivateUsers = true;
+        ProtectHostname = true;
+        ProtectClock = true;
+        ProtectKernelTunables = true;
+        ProtectKernelModules = true;
+        ProtectKernelLogs = true;
+        ProtectControlGroups = true;
+        RestrictAddressFamilies = [ "AF_INET AF_INET6" ];
+        LockPersonality = true;
+        RestrictRealtime = true;
+        ProtectProc = "invisible";
+        ProcSubset = "pid";
+        UMask = 0077;
+
+        # For the identd port
+        # CapabilityBoundingSet = ["CAP_NET_BIND_SERVICE"];
+        # AmbientCapabilities = ["CAP_NET_BIND_SERVICE"];
+      };
+    };
+
   # Pass in the TURN secret via EnvironmentFile, not supported by
   # upstream module currently.
   #
@@ -249,6 +254,6 @@ in {
     ];
     # Other services store their data in conduit, so no other services
     # need to be shut down currently.
-    pauseServices = ["conduit.service"];
+    pauseServices = [ "conduit.service" ];
   };
 }
diff --git a/configuration/services/fail2ban.nix b/configuration/services/fail2ban.nix
index ace3219..1811046 100644
--- a/configuration/services/fail2ban.nix
+++ b/configuration/services/fail2ban.nix
@@ -1,7 +1,7 @@
-{pkgs, ...}: {
+{ pkgs, ... }: {
   services.fail2ban = {
     enable = true;
-    extraPackages = [pkgs.ipset];
+    extraPackages = [ pkgs.ipset ];
     banaction = "iptables-ipset-proto6-allports";
     bantime-increment.enable = true;
 
@@ -21,7 +21,7 @@
   };
 
   # Allow metrics services to connect to the socket as well
-  users.groups.fail2ban = {};
+  users.groups.fail2ban = { };
   systemd.services.fail2ban.serviceConfig = {
     ExecStartPost =
       "+"
diff --git a/configuration/services/foundryvtt.nix b/configuration/services/foundryvtt.nix
index ac206fc..e69d2dd 100644
--- a/configuration/services/foundryvtt.nix
+++ b/configuration/services/foundryvtt.nix
@@ -1,12 +1,13 @@
-{
-  lib,
-  config,
-  flake-inputs,
-  ...
-}: let
+{ lib
+, config
+, flake-inputs
+, ...
+}:
+let
   domain = "foundryvtt.${config.services.nginx.domain}";
-in {
-  imports = [flake-inputs.foundryvtt.nixosModules.foundryvtt];
+in
+{
+  imports = [ flake-inputs.foundryvtt.nixosModules.foundryvtt ];
 
   services.foundryvtt = {
     enable = true;
@@ -18,26 +19,28 @@ in {
 
   # Want to start it manually when I need it, not have it constantly
   # running
-  systemd.services.foundryvtt.wantedBy = lib.mkForce [];
+  systemd.services.foundryvtt.wantedBy = lib.mkForce [ ];
 
-  services.nginx.virtualHosts."${domain}" = let
-    inherit (config.services.foundryvtt) port;
-  in {
-    forceSSL = true;
-    useACMEHost = "tlater.net";
-    enableHSTS = true;
+  services.nginx.virtualHosts."${domain}" =
+    let
+      inherit (config.services.foundryvtt) port;
+    in
+    {
+      forceSSL = true;
+      useACMEHost = "tlater.net";
+      enableHSTS = true;
 
-    locations."/" = {
-      proxyWebsockets = true;
-      proxyPass = "http://localhost:${toString port}";
+      locations."/" = {
+        proxyWebsockets = true;
+        proxyPass = "http://localhost:${toString port}";
+      };
     };
-  };
 
   services.backups.foundryvtt = {
     user = "foundryvtt";
     paths = [
       config.services.foundryvtt.dataDir
     ];
-    pauseServices = ["foundryvtt.service"];
+    pauseServices = [ "foundryvtt.service" ];
   };
 }
diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index 26fe2f8..4ef6238 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -1,11 +1,12 @@
-{
-  pkgs,
-  config,
-  lib,
-  ...
-}: let
+{ pkgs
+, config
+, lib
+, ...
+}:
+let
   domain = "gitea.${config.services.nginx.domain}";
-in {
+in
+{
   services.forgejo = {
     enable = true;
     database.type = "postgres";
@@ -27,33 +28,37 @@ in {
     };
   };
 
-  systemd.services.forgejo.serviceConfig.ExecStartPre = let
-    replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret";
-    secretPath = config.sops.secrets."forgejo/metrics-token".path;
-    runConfig = "${config.services.forgejo.customDir}/conf/app.ini";
-  in [
-    "+${replaceSecretBin} '#metricstoken#' '${secretPath}' '${runConfig}'"
-  ];
+  systemd.services.forgejo.serviceConfig.ExecStartPre =
+    let
+      replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret";
+      secretPath = config.sops.secrets."forgejo/metrics-token".path;
+      runConfig = "${config.services.forgejo.customDir}/conf/app.ini";
+    in
+    [
+      "+${replaceSecretBin} '#metricstoken#' '${secretPath}' '${runConfig}'"
+    ];
 
   # Set up SSL
-  services.nginx.virtualHosts."${domain}" = let
-    httpAddress = config.services.forgejo.settings.server.HTTP_ADDR;
-    httpPort = config.services.forgejo.settings.server.HTTP_PORT;
-  in {
-    forceSSL = true;
-    useACMEHost = "tlater.net";
-    enableHSTS = true;
+  services.nginx.virtualHosts."${domain}" =
+    let
+      httpAddress = config.services.forgejo.settings.server.HTTP_ADDR;
+      httpPort = config.services.forgejo.settings.server.HTTP_PORT;
+    in
+    {
+      forceSSL = true;
+      useACMEHost = "tlater.net";
+      enableHSTS = true;
 
-    locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}";
-    locations."/metrics" = {
-      extraConfig = ''
-        access_log off;
-        allow 127.0.0.1;
-        ${lib.optionalString config.networking.enableIPv6 "allow ::1;"}
-        deny all;
-      '';
+      locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}";
+      locations."/metrics" = {
+        extraConfig = ''
+          access_log off;
+          allow 127.0.0.1;
+          ${lib.optionalString config.networking.enableIPv6 "allow ::1;"}
+          deny all;
+        '';
+      };
     };
-  };
 
   # Block repeated failed login attempts
   #
@@ -83,13 +88,13 @@ in {
       # Conf is backed up via nix
     ];
     preparation = {
-      packages = [config.services.postgresql.package];
+      packages = [ config.services.postgresql.package ];
       text = "pg_dump ${config.services.forgejo.database.name} --file=/var/lib/forgejo/forgejo-db.sql";
     };
     cleanup = {
-      packages = [pkgs.coreutils];
+      packages = [ pkgs.coreutils ];
       text = "rm /var/lib/forgejo/forgejo-db.sql";
     };
-    pauseServices = ["forgejo.service"];
+    pauseServices = [ "forgejo.service" ];
   };
 }
diff --git a/configuration/services/metrics/exporters.nix b/configuration/services/metrics/exporters.nix
index f3054db..e17be8e 100644
--- a/configuration/services/metrics/exporters.nix
+++ b/configuration/services/metrics/exporters.nix
@@ -1,25 +1,28 @@
+{ config
+, pkgs
+, lib
+, ...
+}:
+let
+  yaml = pkgs.formats.yaml { };
+in
 {
-  config,
-  pkgs,
-  lib,
-  ...
-}: let
-  yaml = pkgs.formats.yaml {};
-in {
   services.prometheus = {
     exporters = {
       # Periodically check domain registration status
       domain = {
         enable = true;
         listenAddress = "127.0.0.1";
-        extraFlags = let
-          conf.domains = [
-            "tlater.net"
-            "tlater.com"
+        extraFlags =
+          let
+            conf.domains = [
+              "tlater.net"
+              "tlater.com"
+            ];
+          in
+          [
+            "--config=${yaml.generate "domains.yml" conf}"
           ];
-        in [
-          "--config=${yaml.generate "domains.yml" conf}"
-        ];
       };
 
       # System statistics
@@ -49,47 +52,50 @@ in {
         group = "nginx";
 
         settings.namespaces =
-          lib.mapAttrsToList (name: virtualHost: {
-            inherit name;
-            metrics_override.prefix = "nginxlog";
-            namespace_label = "vhost";
+          lib.mapAttrsToList
+            (name: virtualHost: {
+              inherit name;
+              metrics_override.prefix = "nginxlog";
+              namespace_label = "vhost";
 
-            format = lib.concatStringsSep " " [
-              "$remote_addr - $remote_user [$time_local]"
-              ''"$request" $status $body_bytes_sent''
-              ''"$http_referer" "$http_user_agent"''
-              ''rt=$request_time uct="$upstream_connect_time"''
-              ''uht="$upstream_header_time" urt="$upstream_response_time"''
-            ];
+              format = lib.concatStringsSep " " [
+                "$remote_addr - $remote_user [$time_local]"
+                ''"$request" $status $body_bytes_sent''
+                ''"$http_referer" "$http_user_agent"''
+                ''rt=$request_time uct="$upstream_connect_time"''
+                ''uht="$upstream_header_time" urt="$upstream_response_time"''
+              ];
 
-            source.files = [
-              "/var/log/nginx/${name}/access.log"
-            ];
-          })
-          config.services.nginx.virtualHosts;
+              source.files = [
+                "/var/log/nginx/${name}/access.log"
+              ];
+            })
+            config.services.nginx.virtualHosts;
       };
     };
 
     extraExporters = {
-      fail2ban = let
-        cfg = config.services.prometheus.extraExporters.fail2ban;
-      in {
-        port = 9191;
-        serviceOpts = {
-          after = ["fail2ban.service"];
-          requires = ["fail2ban.service"];
-          serviceConfig = {
-            Group = "fail2ban";
-            RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"];
-            ExecStart = lib.concatStringsSep " " [
-              "${pkgs.local.prometheus-fail2ban-exporter}/bin/fail2ban-prometheus-exporter"
-              "--collector.f2b.socket=/var/run/fail2ban/fail2ban.sock"
-              "--web.listen-address='${cfg.listenAddress}:${toString cfg.port}'"
-              "--collector.f2b.exit-on-socket-connection-error=true"
-            ];
+      fail2ban =
+        let
+          cfg = config.services.prometheus.extraExporters.fail2ban;
+        in
+        {
+          port = 9191;
+          serviceOpts = {
+            after = [ "fail2ban.service" ];
+            requires = [ "fail2ban.service" ];
+            serviceConfig = {
+              Group = "fail2ban";
+              RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
+              ExecStart = lib.concatStringsSep " " [
+                "${pkgs.local.prometheus-fail2ban-exporter}/bin/fail2ban-prometheus-exporter"
+                "--collector.f2b.socket=/var/run/fail2ban/fail2ban.sock"
+                "--web.listen-address='${cfg.listenAddress}:${toString cfg.port}'"
+                "--collector.f2b.exit-on-socket-connection-error=true"
+              ];
+            };
           };
         };
-      };
     };
 
     # TODO(tlater):
diff --git a/configuration/services/metrics/grafana.nix b/configuration/services/metrics/grafana.nix
index eb5106e..d13fe7b 100644
--- a/configuration/services/metrics/grafana.nix
+++ b/configuration/services/metrics/grafana.nix
@@ -1,6 +1,8 @@
-{config, ...}: let
+{ config, ... }:
+let
   domain = "metrics.${config.services.nginx.domain}";
-in {
+in
+{
   services.grafana = {
     enable = true;
     settings = {
diff --git a/configuration/services/metrics/options.nix b/configuration/services/metrics/options.nix
index 81f0865..552aec8 100644
--- a/configuration/services/metrics/options.nix
+++ b/configuration/services/metrics/options.nix
@@ -1,12 +1,13 @@
-{
-  pkgs,
-  config,
-  lib,
-  ...
-}: let
+{ pkgs
+, config
+, lib
+, ...
+}:
+let
   inherit (lib) types mkOption mkDefault;
-  yaml = pkgs.formats.yaml {};
-in {
+  yaml = pkgs.formats.yaml { };
+in
+{
   options = {
     services.prometheus = {
       extraExporters = mkOption {
@@ -31,11 +32,10 @@ in {
     };
 
     services.victoriametrics.scrapeConfigs = mkOption {
-      type = types.attrsOf (types.submodule ({
-        name,
-        self,
-        ...
-      }: {
+      type = types.attrsOf (types.submodule ({ name
+                                             , self
+                                             , ...
+                                             }: {
         options = {
           job_name = mkOption {
             type = types.str;
@@ -47,7 +47,7 @@ in {
             description = ''
               Other settings to set for this scrape config.
             '';
-            default = {};
+            default = { };
           };
 
           targets = mkOption {
@@ -57,11 +57,11 @@ in {
 
               Shortcut for `static_configs = lib.singleton {targets = [<targets>];}`
             '';
-            default = [];
+            default = [ ];
           };
 
           static_configs = mkOption {
-            default = [];
+            default = [ ];
             type = types.listOf (types.submodule {
               options = {
                 targets = mkOption {
@@ -77,7 +77,7 @@ in {
                   description = lib.mdDoc ''
                     Labels to apply to all targets defined for this static config.
                   '';
-                  default = {};
+                  default = { };
                 };
               };
             });
@@ -89,116 +89,125 @@ in {
 
   config = {
     systemd.services = lib.mkMerge [
-      (lib.mapAttrs' (name: exporter:
-        lib.nameValuePair "prometheus-${name}-exporter" (lib.mkMerge [
-          {
-            # Shamelessly copied from upstream because the upstream
-            # module is an intractable mess
-            wantedBy = ["multi-user.target"];
-            after = ["network.target"];
-            serviceConfig.Restart = mkDefault "always";
-            serviceConfig.PrivateTmp = mkDefault true;
-            serviceConfig.WorkingDirectory = mkDefault /tmp;
-            serviceConfig.DynamicUser = mkDefault true;
-            # Hardening
-            serviceConfig.CapabilityBoundingSet = mkDefault [""];
-            serviceConfig.DeviceAllow = [""];
-            serviceConfig.LockPersonality = true;
-            serviceConfig.MemoryDenyWriteExecute = true;
-            serviceConfig.NoNewPrivileges = true;
-            serviceConfig.PrivateDevices = mkDefault true;
-            serviceConfig.ProtectClock = mkDefault true;
-            serviceConfig.ProtectControlGroups = true;
-            serviceConfig.ProtectHome = true;
-            serviceConfig.ProtectHostname = true;
-            serviceConfig.ProtectKernelLogs = true;
-            serviceConfig.ProtectKernelModules = true;
-            serviceConfig.ProtectKernelTunables = true;
-            serviceConfig.ProtectSystem = mkDefault "strict";
-            serviceConfig.RemoveIPC = true;
-            serviceConfig.RestrictAddressFamilies = ["AF_INET" "AF_INET6"];
-            serviceConfig.RestrictNamespaces = true;
-            serviceConfig.RestrictRealtime = true;
-            serviceConfig.RestrictSUIDSGID = true;
-            serviceConfig.SystemCallArchitectures = "native";
-            serviceConfig.UMask = "0077";
-          }
-          exporter.serviceOpts
-        ]))
-      config.services.prometheus.extraExporters)
+      (lib.mapAttrs'
+        (name: exporter:
+          lib.nameValuePair "prometheus-${name}-exporter" (lib.mkMerge [
+            {
+              # Shamelessly copied from upstream because the upstream
+              # module is an intractable mess
+              wantedBy = [ "multi-user.target" ];
+              after = [ "network.target" ];
+              serviceConfig.Restart = mkDefault "always";
+              serviceConfig.PrivateTmp = mkDefault true;
+              serviceConfig.WorkingDirectory = mkDefault /tmp;
+              serviceConfig.DynamicUser = mkDefault true;
+              # Hardening
+              serviceConfig.CapabilityBoundingSet = mkDefault [ "" ];
+              serviceConfig.DeviceAllow = [ "" ];
+              serviceConfig.LockPersonality = true;
+              serviceConfig.MemoryDenyWriteExecute = true;
+              serviceConfig.NoNewPrivileges = true;
+              serviceConfig.PrivateDevices = mkDefault true;
+              serviceConfig.ProtectClock = mkDefault true;
+              serviceConfig.ProtectControlGroups = true;
+              serviceConfig.ProtectHome = true;
+              serviceConfig.ProtectHostname = true;
+              serviceConfig.ProtectKernelLogs = true;
+              serviceConfig.ProtectKernelModules = true;
+              serviceConfig.ProtectKernelTunables = true;
+              serviceConfig.ProtectSystem = mkDefault "strict";
+              serviceConfig.RemoveIPC = true;
+              serviceConfig.RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
+              serviceConfig.RestrictNamespaces = true;
+              serviceConfig.RestrictRealtime = true;
+              serviceConfig.RestrictSUIDSGID = true;
+              serviceConfig.SystemCallArchitectures = "native";
+              serviceConfig.UMask = "0077";
+            }
+            exporter.serviceOpts
+          ]))
+        config.services.prometheus.extraExporters)
 
       {
-        vmagent-scrape-exporters = let
-          listenAddress = config.services.victoriametrics.listenAddress;
-          vmAddr = (lib.optionalString (lib.hasPrefix ":" listenAddress) "127.0.0.1") + listenAddress;
-          promscrape = yaml.generate "prometheus.yml" {
-            scrape_configs = lib.mapAttrsToList (_: scrape:
-              lib.recursiveUpdate {
-                inherit (scrape) job_name;
-                static_configs =
-                  scrape.static_configs
-                  ++ lib.optional (scrape.targets != []) {targets = scrape.targets;};
-              }
-              scrape.extraSettings)
-            config.services.victoriametrics.scrapeConfigs;
-          };
-        in {
-          enable = true;
-          path = [pkgs.victoriametrics];
-          wantedBy = ["multi-user.target"];
-          after = ["network.target" "victoriametrics.service"];
-          serviceConfig = {
-            ExecStart = [
-              (lib.concatStringsSep " " [
-                "${pkgs.victoriametrics}/bin/vmagent"
-                "-promscrape.config=${promscrape}"
-                "-remoteWrite.url=http://${vmAddr}/api/v1/write"
-                "-remoteWrite.tmpDataPath=%t/vmagent"
-              ])
-            ];
-            SupplementaryGroups = "metrics";
+        vmagent-scrape-exporters =
+          let
+            listenAddress = config.services.victoriametrics.listenAddress;
+            vmAddr = (lib.optionalString (lib.hasPrefix ":" listenAddress) "127.0.0.1") + listenAddress;
+            promscrape = yaml.generate "prometheus.yml" {
+              scrape_configs = lib.mapAttrsToList
+                (_: scrape:
+                  lib.recursiveUpdate
+                    {
+                      inherit (scrape) job_name;
+                      static_configs =
+                        scrape.static_configs
+                        ++ lib.optional (scrape.targets != [ ]) { targets = scrape.targets; };
+                    }
+                    scrape.extraSettings)
+                config.services.victoriametrics.scrapeConfigs;
+            };
+          in
+          {
+            enable = true;
+            path = [ pkgs.victoriametrics ];
+            wantedBy = [ "multi-user.target" ];
+            after = [ "network.target" "victoriametrics.service" ];
+            serviceConfig = {
+              ExecStart = [
+                (lib.concatStringsSep " " [
+                  "${pkgs.victoriametrics}/bin/vmagent"
+                  "-promscrape.config=${promscrape}"
+                  "-remoteWrite.url=http://${vmAddr}/api/v1/write"
+                  "-remoteWrite.tmpDataPath=%t/vmagent"
+                ])
+              ];
+              SupplementaryGroups = "metrics";
 
-            DynamicUser = true;
-            RuntimeDirectory = "vmagent";
-            CapabilityBoundingSet = [""];
-            DeviceAllow = [""];
-            LockPersonality = true;
-            MemoryDenyWriteExecute = true;
-            NoNewPrivileges = true;
-            PrivateDevices = true;
-            ProtectClock = true;
-            ProtectControlGroups = true;
-            ProtectHome = true;
-            ProtectHostname = true;
-            ProtectKernelLogs = true;
-            ProtectKernelModules = true;
-            ProtectKernelTunables = true;
-            ProtectSystem = "strict";
-            RemoveIPC = true;
-            RestrictAddressFamilies = ["AF_INET" "AF_INET6"];
-            RestrictNamespaces = true;
-            RestrictRealtime = true;
-            RestrictSUIDSGID = true;
-            SystemCallArchitectures = "native";
-            UMask = "0077";
+              DynamicUser = true;
+              RuntimeDirectory = "vmagent";
+              CapabilityBoundingSet = [ "" ];
+              DeviceAllow = [ "" ];
+              LockPersonality = true;
+              MemoryDenyWriteExecute = true;
+              NoNewPrivileges = true;
+              PrivateDevices = true;
+              ProtectClock = true;
+              ProtectControlGroups = true;
+              ProtectHome = true;
+              ProtectHostname = true;
+              ProtectKernelLogs = true;
+              ProtectKernelModules = true;
+              ProtectKernelTunables = true;
+              ProtectSystem = "strict";
+              RemoveIPC = true;
+              RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
+              RestrictNamespaces = true;
+              RestrictRealtime = true;
+              RestrictSUIDSGID = true;
+              SystemCallArchitectures = "native";
+              UMask = "0077";
+            };
           };
-        };
       }
     ];
 
-    users.groups.metrics = {};
+    users.groups.metrics = { };
 
-    services.victoriametrics.scrapeConfigs = let
-      allExporters =
-        lib.mapAttrs (name: exporter: {
-          inherit (exporter) listenAddress port;
-        }) ((lib.filterAttrs (_: exporter: builtins.isAttrs exporter && exporter.enable)
-          config.services.prometheus.exporters)
-        // config.services.prometheus.extraExporters);
-    in
-      lib.mapAttrs (_: exporter: {
-        targets = ["${exporter.listenAddress}:${toString exporter.port}"];
-      })
-      allExporters;
+    services.victoriametrics.scrapeConfigs =
+      let
+        allExporters =
+          lib.mapAttrs
+            (name: exporter: {
+              inherit (exporter) listenAddress port;
+            })
+            ((lib.filterAttrs (_: exporter: builtins.isAttrs exporter && exporter.enable)
+              config.services.prometheus.exporters)
+            // config.services.prometheus.extraExporters);
+      in
+      lib.mapAttrs
+        (_: exporter: {
+          targets = [ "${exporter.listenAddress}:${toString exporter.port}" ];
+        })
+        allExporters;
   };
 }
diff --git a/configuration/services/metrics/victoriametrics.nix b/configuration/services/metrics/victoriametrics.nix
index daf3f94..695b89e 100644
--- a/configuration/services/metrics/victoriametrics.nix
+++ b/configuration/services/metrics/victoriametrics.nix
@@ -1,4 +1,4 @@
-{config, ...}: {
+{ config, ... }: {
   config.services.victoriametrics = {
     enable = true;
     extraOptions = [
@@ -7,10 +7,10 @@
 
     scrapeConfigs = {
       forgejo = {
-        targets = ["127.0.0.1:${toString config.services.forgejo.settings.server.HTTP_PORT}"];
+        targets = [ "127.0.0.1:${toString config.services.forgejo.settings.server.HTTP_PORT}" ];
         extraSettings.authorization.credentials_file = config.sops.secrets."forgejo/metrics-token".path;
       };
-      coturn.targets = ["127.0.0.1:9641"];
+      coturn.targets = [ "127.0.0.1:9641" ];
     };
   };
 }
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 2c7fe4f..7c4fcf4 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -1,14 +1,15 @@
-{
-  pkgs,
-  config,
-  ...
-}: let
+{ pkgs
+, config
+, ...
+}:
+let
   # Update pending on rewrite of nextcloud news, though there is an
   # alpha to switch to if it becomes necessary:
   # https://github.com/nextcloud/news/issues/2610
   nextcloud = pkgs.nextcloud27;
   hostName = "nextcloud.${config.services.nginx.domain}";
-in {
+in
+{
   services.nextcloud = {
     inherit hostName;
 
@@ -42,7 +43,7 @@ in {
   };
 
   # Ensure that this service doesn't start before postgres is ready
-  systemd.services.nextcloud-setup.after = ["postgresql.service"];
+  systemd.services.nextcloud-setup.after = [ "postgresql.service" ];
 
   # Set up SSL
   services.nginx.virtualHosts."${hostName}" = {
diff --git a/configuration/services/postgres.nix b/configuration/services/postgres.nix
index 018dc6e..62dfb01 100644
--- a/configuration/services/postgres.nix
+++ b/configuration/services/postgres.nix
@@ -1,4 +1,4 @@
-{pkgs, ...}: {
+{ pkgs, ... }: {
   services.postgresql = {
     package = pkgs.postgresql_14;
     enable = true;
diff --git a/configuration/services/starbound.nix b/configuration/services/starbound.nix
index 6da890e..3b54ee9 100644
--- a/configuration/services/starbound.nix
+++ b/configuration/services/starbound.nix
@@ -1,16 +1,17 @@
-{
-  pkgs,
-  lib,
-  ...
-}: let
+{ pkgs
+, lib
+, ...
+}:
+let
   inherit (lib) concatStringsSep;
-in {
+in
+{
   # Sadly, steam-run requires some X libs
   environment.noXlibs = false;
 
   systemd.services.starbound = {
     description = "Starbound";
-    after = ["network.target"];
+    after = [ "network.target" ];
 
     serviceConfig = {
       ExecStart = "${pkgs.local.starbound}/bin/launch-starbound ${./configs/starbound.json}";
@@ -67,7 +68,7 @@ in {
       # Game servers shouldn't use cgroups themselves either
       ProtectControlGroups = true;
       # Most game servers will never need other socket types
-      RestrictAddressFamilies = ["AF_UNIX AF_INET AF_INET6"];
+      RestrictAddressFamilies = [ "AF_UNIX AF_INET AF_INET6" ];
       # Also a no-brainer, no game server should ever need this
       LockPersonality = true;
       # Some game servers will probably try to set this, but they
@@ -116,6 +117,6 @@ in {
     paths = [
       "/var/lib/private/starbound/storage/universe/"
     ];
-    pauseServices = ["starbound.service"];
+    pauseServices = [ "starbound.service" ];
   };
 }
diff --git a/configuration/services/webserver.nix b/configuration/services/webserver.nix
index 387df57..e6b49b3 100644
--- a/configuration/services/webserver.nix
+++ b/configuration/services/webserver.nix
@@ -1,6 +1,8 @@
-{config, ...}: let
+{ config, ... }:
+let
   domain = config.services.nginx.domain;
-in {
+in
+{
   services.tlaternet-webserver = {
     enable = true;
     listen = {
@@ -10,15 +12,17 @@ in {
   };
 
   # Set up SSL
-  services.nginx.virtualHosts."${domain}" = let
-    inherit (config.services.tlaternet-webserver.listen) addr port;
-  in {
-    serverAliases = ["www.${domain}"];
+  services.nginx.virtualHosts."${domain}" =
+    let
+      inherit (config.services.tlaternet-webserver.listen) addr port;
+    in
+    {
+      serverAliases = [ "www.${domain}" ];
 
-    forceSSL = true;
-    useACMEHost = "tlater.net";
-    enableHSTS = true;
+      forceSSL = true;
+      useACMEHost = "tlater.net";
+      enableHSTS = true;
 
-    locations."/".proxyPass = "http://${addr}:${toString port}";
-  };
+      locations."/".proxyPass = "http://${addr}:${toString port}";
+    };
 }
diff --git a/configuration/services/wireguard.nix b/configuration/services/wireguard.nix
index 1ae6aac..057a2e9 100644
--- a/configuration/services/wireguard.nix
+++ b/configuration/services/wireguard.nix
@@ -1,4 +1,4 @@
-{config, ...}: {
+{ config, ... }: {
   # iptables needs to permit forwarding from wg0 to wg0
   networking.firewall.extraCommands = ''
     iptables -A FORWARD -i wg0 -o wg0 -j ACCEPT
@@ -26,7 +26,7 @@
           {
             # yui
             wireguardPeerConfig = {
-              AllowedIPs = ["10.45.249.2/32"];
+              AllowedIPs = [ "10.45.249.2/32" ];
               PublicKey = "5mlnqEVJWks5OqgeFA2bLIrvST9TlCE81Btl+j4myz0=";
             };
           }
@@ -34,7 +34,7 @@
           {
             # yuanyuan
             wireguardPeerConfig = {
-              AllowedIPs = ["10.45.249.10/32"];
+              AllowedIPs = [ "10.45.249.10/32" ];
               PublicKey = "0UsFE2atz/O5P3OKQ8UHyyyGQNJbp1MeIWUJLuoerwE=";
             };
           }
diff --git a/configuration/sops.nix b/configuration/sops.nix
index 0746133..bc21834 100644
--- a/configuration/sops.nix
+++ b/configuration/sops.nix
@@ -31,8 +31,8 @@
       };
 
       # Heisenbridge
-      "heisenbridge/as-token" = {};
-      "heisenbridge/hs-token" = {};
+      "heisenbridge/as-token" = { };
+      "heisenbridge/hs-token" = { };
 
       "hetzner-api" = {
         owner = "acme";
@@ -62,10 +62,10 @@
       };
 
       # Steam
-      "steam/tlater" = {};
+      "steam/tlater" = { };
 
       # Turn
-      "turn/env" = {};
+      "turn/env" = { };
       "turn/secret" = {
         owner = "turnserver";
       };
diff --git a/flake.nix b/flake.nix
index 09a74ac..afdc668 100644
--- a/flake.nix
+++ b/flake.nix
@@ -32,126 +32,130 @@
     };
   };
 
-  outputs = {
-    self,
-    nixpkgs,
-    sops-nix,
-    nvfetcher,
-    deploy-rs,
-    ...
-  } @ inputs: let
-    system = "x86_64-linux";
-    pkgs = nixpkgs.legacyPackages.${system};
-  in {
-    ##################
-    # Configurations #
-    ##################
-    nixosConfigurations = {
-      # The actual system definition
-      hetzner-1 = nixpkgs.lib.nixosSystem {
-        inherit system;
-        specialArgs.flake-inputs = inputs;
+  outputs =
+    { self
+    , nixpkgs
+    , sops-nix
+    , nvfetcher
+    , deploy-rs
+    , ...
+    } @ inputs:
+    let
+      system = "x86_64-linux";
+      pkgs = nixpkgs.legacyPackages.${system};
+    in
+    {
+      ##################
+      # Configurations #
+      ##################
+      nixosConfigurations = {
+        # The actual system definition
+        hetzner-1 = nixpkgs.lib.nixosSystem {
+          inherit system;
+          specialArgs.flake-inputs = inputs;
 
-        modules = [
-          ./configuration
-          ./configuration/hardware-specific/hetzner
+          modules = [
+            ./configuration
+            ./configuration/hardware-specific/hetzner
+          ];
+        };
+      };
+
+      ############################
+      # Deployment configuration #
+      ############################
+      deploy.nodes = {
+        hetzner-1 = {
+          hostname = "116.202.158.55";
+
+          profiles.system = {
+            user = "root";
+            path = deploy-rs.lib.${system}.activate.nixos self.nixosConfigurations.hetzner-1;
+          };
+
+          sshUser = "tlater";
+          sshOpts = [ "-p" "2222" "-o" "ForwardAgent=yes" ];
+        };
+      };
+
+      #########
+      # Tests #
+      #########
+      checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
+
+      ###################
+      # Utility scripts #
+      ###################
+      apps.${system} = {
+        default = self.apps.${system}.run-vm;
+
+        run-vm = {
+          type = "app";
+          program =
+            let
+              vm = nixpkgs.lib.nixosSystem {
+                inherit system;
+                specialArgs.flake-inputs = inputs;
+
+                modules = [
+                  ./configuration
+                  ./configuration/hardware-specific/vm.nix
+                ];
+              };
+            in
+            (pkgs.writeShellScript "" ''
+              ${vm.config.system.build.vm.outPath}/bin/run-testvm-vm
+            '').outPath;
+        };
+
+        update-pkgs = {
+          type = "app";
+          program =
+            let
+              nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher";
+            in
+            (pkgs.writeShellScript "update-pkgs" ''
+              cd "$(git rev-parse --show-toplevel)/pkgs"
+              ${nvfetcher-bin} -o _sources_pkgs -c nvfetcher.toml
+            '').outPath;
+        };
+
+        update-nextcloud-apps = {
+          type = "app";
+          program =
+            let
+              nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher";
+            in
+            (pkgs.writeShellScript "update-nextcloud-apps" ''
+              cd "$(git rev-parse --show-toplevel)/pkgs"
+              ${nvfetcher-bin} -o _sources_nextcloud -c nextcloud-apps.toml
+            '').outPath;
+        };
+      };
+
+      ###########################
+      # Development environment #
+      ###########################
+      devShells.${system}.default = nixpkgs.legacyPackages.${system}.mkShell {
+        sopsPGPKeyDirs = [ "./keys/hosts/" "./keys/users/" ];
+        nativeBuildInputs = [
+          sops-nix.packages.${system}.sops-import-keys-hook
+        ];
+
+        packages = with pkgs; [
+          sops-nix.packages.${system}.sops-init-gpg-key
+          deploy-rs.packages.${system}.default
+
+          nixpkgs-fmt
+
+          cargo
+          clippy
+          rustc
+          rustfmt
+          rust-analyzer
+          pkg-config
+          openssl
         ];
       };
     };
-
-    ############################
-    # Deployment configuration #
-    ############################
-    deploy.nodes = {
-      hetzner-1 = {
-        hostname = "116.202.158.55";
-
-        profiles.system = {
-          user = "root";
-          path = deploy-rs.lib.${system}.activate.nixos self.nixosConfigurations.hetzner-1;
-        };
-
-        sshUser = "tlater";
-        sshOpts = ["-p" "2222" "-o" "ForwardAgent=yes"];
-      };
-    };
-
-    #########
-    # Tests #
-    #########
-    checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
-
-    ###################
-    # Utility scripts #
-    ###################
-    apps.${system} = {
-      default = self.apps.${system}.run-vm;
-
-      run-vm = {
-        type = "app";
-        program = let
-          vm = nixpkgs.lib.nixosSystem {
-            inherit system;
-            specialArgs.flake-inputs = inputs;
-
-            modules = [
-              ./configuration
-              ./configuration/hardware-specific/vm.nix
-            ];
-          };
-        in
-          (pkgs.writeShellScript "" ''
-            ${vm.config.system.build.vm.outPath}/bin/run-testvm-vm
-          '')
-          .outPath;
-      };
-
-      update-pkgs = {
-        type = "app";
-        program = let
-          nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher";
-        in
-          (pkgs.writeShellScript "update-pkgs" ''
-            cd "$(git rev-parse --show-toplevel)/pkgs"
-            ${nvfetcher-bin} -o _sources_pkgs -c nvfetcher.toml
-          '')
-          .outPath;
-      };
-
-      update-nextcloud-apps = {
-        type = "app";
-        program = let
-          nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher";
-        in
-          (pkgs.writeShellScript "update-nextcloud-apps" ''
-            cd "$(git rev-parse --show-toplevel)/pkgs"
-            ${nvfetcher-bin} -o _sources_nextcloud -c nextcloud-apps.toml
-          '')
-          .outPath;
-      };
-    };
-
-    ###########################
-    # Development environment #
-    ###########################
-    devShells.${system}.default = nixpkgs.legacyPackages.${system}.mkShell {
-      sopsPGPKeyDirs = ["./keys/hosts/" "./keys/users/"];
-      nativeBuildInputs = [
-        sops-nix.packages.${system}.sops-import-keys-hook
-      ];
-
-      packages = with pkgs; [
-        sops-nix.packages.${system}.sops-init-gpg-key
-        deploy-rs.packages.${system}.default
-
-        cargo
-        clippy
-        rustc
-        rustfmt
-        rust-analyzer
-        pkg-config
-        openssl
-      ];
-    };
-  };
 }
diff --git a/modules/nginxExtensions.nix b/modules/nginxExtensions.nix
index 9fe489a..3603756 100644
--- a/modules/nginxExtensions.nix
+++ b/modules/nginxExtensions.nix
@@ -1,8 +1,7 @@
-{
-  config,
-  pkgs,
-  lib,
-  ...
+{ config
+, pkgs
+, lib
+, ...
 }: {
   options = {
     services.nginx.domain = lib.mkOption {
@@ -10,36 +9,37 @@
       description = "The base domain name to append to virtual domain names";
     };
 
-    services.nginx.virtualHosts = let
-      extraVirtualHostOptions = {
-        name,
-        config,
-        ...
-      }: {
-        options = {
-          enableHSTS = lib.mkEnableOption "Enable HSTS";
+    services.nginx.virtualHosts =
+      let
+        extraVirtualHostOptions =
+          { name
+          , config
+          , ...
+          }: {
+            options = {
+              enableHSTS = lib.mkEnableOption "Enable HSTS";
 
-          addAccessLog = lib.mkOption {
-            type = lib.types.bool;
-            default = true;
-            description = ''
-              Add special logging to `/var/log/nginx/''${serverName}`
-            '';
+              addAccessLog = lib.mkOption {
+                type = lib.types.bool;
+                default = true;
+                description = ''
+                  Add special logging to `/var/log/nginx/''${serverName}`
+                '';
+              };
+            };
+
+            config = {
+              extraConfig = lib.concatStringsSep "\n" [
+                (lib.optionalString config.enableHSTS ''
+                  add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
+                '')
+                (lib.optionalString config.addAccessLog ''
+                  access_log /var/log/nginx/${name}/access.log upstream_time;
+                '')
+              ];
+            };
           };
-        };
-
-        config = {
-          extraConfig = lib.concatStringsSep "\n" [
-            (lib.optionalString config.enableHSTS ''
-              add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
-            '')
-            (lib.optionalString config.addAccessLog ''
-              access_log /var/log/nginx/${name}/access.log upstream_time;
-            '')
-          ];
-        };
-      };
-    in
+      in
       lib.mkOption {
         type = lib.types.attrsOf (lib.types.submodule extraVirtualHostOptions);
       };
@@ -47,13 +47,15 @@
 
   config = {
     # Don't attempt to run acme if the domain name is not tlater.net
-    systemd.services = let
-      confirm = ''[[ "tlater.net" = ${config.services.nginx.domain} ]]'';
-    in
-      lib.mapAttrs' (cert: _:
-        lib.nameValuePair "acme-${cert}" {
-          serviceConfig.ExecCondition = ''${pkgs.runtimeShell} -c '${confirm}' '';
-        })
-      config.security.acme.certs;
+    systemd.services =
+      let
+        confirm = ''[[ "tlater.net" = ${config.services.nginx.domain} ]]'';
+      in
+      lib.mapAttrs'
+        (cert: _:
+          lib.nameValuePair "acme-${cert}" {
+            serviceConfig.ExecCondition = ''${pkgs.runtimeShell} -c '${confirm}' '';
+          })
+        config.security.acme.certs;
   };
 }
diff --git a/pkgs/afvalcalendar/default.nix b/pkgs/afvalcalendar/default.nix
index 12e2af5..12b868c 100644
--- a/pkgs/afvalcalendar/default.nix
+++ b/pkgs/afvalcalendar/default.nix
@@ -1,7 +1,6 @@
-{
-  pkgs,
-  rustPlatform,
-  ...
+{ pkgs
+, rustPlatform
+, ...
 }:
 rustPlatform.buildRustPackage {
   pname = "afvalcalendar";
diff --git a/pkgs/default.nix b/pkgs/default.nix
index 3162787..132d0f5 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -1,22 +1,23 @@
-{
-  pkgs,
-  lib,
-}: let
+{ pkgs
+, lib
+,
+}:
+let
   inherit (builtins) fromJSON mapAttrs readFile;
   inherit (pkgs) callPackage;
 in
-  {
-    starbound = callPackage ./starbound {};
-    prometheus-fail2ban-exporter = callPackage ./prometheus/fail2ban-exporter.nix {
-      sources = pkgs.callPackage ./_sources_pkgs/generated.nix {};
-    };
-    afvalcalendar = callPackage ./afvalcalendar {};
-  }
+{
+  starbound = callPackage ./starbound { };
+  prometheus-fail2ban-exporter = callPackage ./prometheus/fail2ban-exporter.nix {
+    sources = pkgs.callPackage ./_sources_pkgs/generated.nix { };
+  };
+  afvalcalendar = callPackage ./afvalcalendar { };
+}
   // (
-    # Add nextcloud apps
-    let
-      mkNextcloudApp = pkgs.callPackage ./mkNextcloudApp.nix {};
-      sources = fromJSON (readFile ./_sources_nextcloud/generated.json);
-    in
-      mapAttrs (_: source: mkNextcloudApp source) sources
-  )
+  # Add nextcloud apps
+  let
+    mkNextcloudApp = pkgs.callPackage ./mkNextcloudApp.nix { };
+    sources = fromJSON (readFile ./_sources_nextcloud/generated.json);
+  in
+  mapAttrs (_: source: mkNextcloudApp source) sources
+)
diff --git a/pkgs/mkNextcloudApp.nix b/pkgs/mkNextcloudApp.nix
index 9bf6b26..7453f44 100644
--- a/pkgs/mkNextcloudApp.nix
+++ b/pkgs/mkNextcloudApp.nix
@@ -1,6 +1,6 @@
-{
-  fetchNextcloudApp,
-  lib,
+{ fetchNextcloudApp
+, lib
+,
 }: source:
 fetchNextcloudApp {
   url = source.src.url;
diff --git a/pkgs/prometheus/fail2ban-exporter.nix b/pkgs/prometheus/fail2ban-exporter.nix
index b2c6a25..b74e35d 100644
--- a/pkgs/prometheus/fail2ban-exporter.nix
+++ b/pkgs/prometheus/fail2ban-exporter.nix
@@ -1,6 +1,6 @@
-{
-  buildGoModule,
-  sources,
+{ buildGoModule
+, sources
+,
 }:
 buildGoModule {
   inherit (sources.prometheus-fail2ban-exporter) pname src version;
diff --git a/pkgs/starbound/default.nix b/pkgs/starbound/default.nix
index 304f0f3..a8689f3 100644
--- a/pkgs/starbound/default.nix
+++ b/pkgs/starbound/default.nix
@@ -1,34 +1,35 @@
-{
-  stdenv,
-  lib,
-  makeWrapper,
-  patchelf,
-  steamPackages,
-  replace-secret,
-}: let
+{ stdenv
+, lib
+, makeWrapper
+, patchelf
+, steamPackages
+, replace-secret
+,
+}:
+let
   # Use the directory in which starbound is installed so steamcmd
   # doesn't have to be reinstalled constantly (we're using DynamicUser
   # with StateDirectory to persist this).
   steamcmd = steamPackages.steamcmd.override {
     steamRoot = "/var/lib/starbound/.steamcmd";
   };
-  wrapperPath = lib.makeBinPath [patchelf steamcmd replace-secret];
+  wrapperPath = lib.makeBinPath [ patchelf steamcmd replace-secret ];
 in
-  stdenv.mkDerivation {
-    name = "starbound-update-script";
-    nativeBuildInputs = [makeWrapper];
-    dontUnpack = true;
-    patchPhase = ''
-      interpreter="$(cat $NIX_CC/nix-support/dynamic-linker)"
-      substitute ${./launch-starbound.sh} launch-starbound --subst-var interpreter
-    '';
-    installPhase = ''
-      mkdir -p $out/bin
-      cp launch-starbound $out/bin/launch-starbound
-      chmod +x $out/bin/launch-starbound
-    '';
-    postFixup = ''
-      wrapProgram $out/bin/launch-starbound \
-          --prefix PATH : "${wrapperPath}"
-    '';
-  }
+stdenv.mkDerivation {
+  name = "starbound-update-script";
+  nativeBuildInputs = [ makeWrapper ];
+  dontUnpack = true;
+  patchPhase = ''
+    interpreter="$(cat $NIX_CC/nix-support/dynamic-linker)"
+    substitute ${./launch-starbound.sh} launch-starbound --subst-var interpreter
+  '';
+  installPhase = ''
+    mkdir -p $out/bin
+    cp launch-starbound $out/bin/launch-starbound
+    chmod +x $out/bin/launch-starbound
+  '';
+  postFixup = ''
+    wrapProgram $out/bin/launch-starbound \
+        --prefix PATH : "${wrapperPath}"
+  '';
+}

From 038a7974274e3e0a169516968cb935d4231e85e5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 28 Jun 2024 20:15:11 +0200
Subject: [PATCH 148/212] git: Blame-ignore nixpkgs-fmt commit

---
 .git-blame-ignore-revs | 8 ++++++++
 1 file changed, 8 insertions(+)
 create mode 100644 .git-blame-ignore-revs

diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644
index 0000000..cee878d
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,8 @@
+# Run this command to always ignore formatting commits in `git blame`
+# git config blame.ignoreRevsFile .git-blame-ignore-revs
+
+# Switch to nixpkgs-fmt formatting
+fd138d45e6a2cad89fead6e9f246ba282070d6b7
+
+# Switch to alejandra formatting
+046a88905ddfa7f9edc3291c310dbb985dee34f9

From 9654d599e90e46cd42fe02b852235cb44c380c79 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 28 Jun 2024 20:28:15 +0200
Subject: [PATCH 149/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'deploy-rs':
    'github:serokell/deploy-rs/88b3059b020da69cbe16526b8d639bd5e0b51c8b' (2024-04-01)
  → 'github:serokell/deploy-rs/3867348fa92bc892eba5d9ddb2d7a97b9e127a8a' (2024-06-12)
• Updated input 'disko':
    'github:nix-community/disko/285e26465a0bae510897ca04da26ce6307c652b4' (2024-04-26)
  → 'github:nix-community/disko/115311bc395f24c1b553338fec4b3aa28cbf5ae2' (2024-06-28)
• Updated input 'foundryvtt':
    'github:reckenrode/nix-foundryvtt/6025615b431170558c3c13f16b549fc0126425e1' (2024-04-09)
  → 'github:reckenrode/nix-foundryvtt/1176cc325e5e1d46c7a018663a8e02e699e838ec' (2024-06-28)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/cc54fb41d13736e92229c21627ea4f22199fee6b' (2024-06-12)
  → 'github:nixos/nixpkgs/89c49874fb15f4124bf71ca5f42a04f2ee5825fd' (2024-06-26)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/58a1abdbae3217ca6b702f03d3b35125d88a2994' (2024-04-27)
  → 'github:nixos/nixpkgs/2893f56de08021cffd9b6b6dfc70fd9ccd51eb60' (2024-06-24)
• Updated input 'nvfetcher':
    'github:berberman/nvfetcher/2a824322dc6a755ffda83a13b948d42304521e4d' (2024-04-17)
  → 'github:berberman/nvfetcher/fa7609950023462c6f91c425de7610c0bb6b86ba' (2024-06-13)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/f1b0adc27265274e3b0c9b872a8f476a098679bd' (2024-04-23)
  → 'github:Mic92/sops-nix/c2ea1186c0cbfa4d06d406ae50f3e4b085ddc9b3' (2024-06-24)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/74574c38577914733b4f7a775dd77d24245081dd' (2024-04-20)
  → 'github:NixOS/nixpkgs/5e8e3b89adbd0be63192f6e645e0a54080004924' (2024-06-22)
---
 flake.lock | 84 +++++++++++++++++++++++++++---------------------------
 flake.nix  |  4 +--
 2 files changed, 44 insertions(+), 44 deletions(-)

diff --git a/flake.lock b/flake.lock
index 3f8dcb9..dab6ebf 100644
--- a/flake.lock
+++ b/flake.lock
@@ -7,11 +7,11 @@
         "utils": "utils"
       },
       "locked": {
-        "lastModified": 1711973905,
-        "narHash": "sha256-UFKME/N1pbUtn+2Aqnk+agUt8CekbpuqwzljivfIme8=",
+        "lastModified": 1718194053,
+        "narHash": "sha256-FaGrf7qwZ99ehPJCAwgvNY5sLCqQ3GDiE/6uLhxxwSY=",
         "owner": "serokell",
         "repo": "deploy-rs",
-        "rev": "88b3059b020da69cbe16526b8d639bd5e0b51c8b",
+        "rev": "3867348fa92bc892eba5d9ddb2d7a97b9e127a8a",
         "type": "github"
       },
       "original": {
@@ -27,11 +27,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1714103775,
-        "narHash": "sha256-kcBiIrmqzt3bNTr2GMBfAyA+on8BEKO1iKzzDFQZkjI=",
+        "lastModified": 1719733833,
+        "narHash": "sha256-6h2EqZU9bL9rHlXE+2LCBgnDImejzbS+4dYsNDDFlkY=",
         "owner": "nix-community",
         "repo": "disko",
-        "rev": "285e26465a0bae510897ca04da26ce6307c652b4",
+        "rev": "d185770ea261fb5cf81aa5ad1791b93a7834d12c",
         "type": "github"
       },
       "original": {
@@ -47,11 +47,11 @@
         "pyproject-nix": "pyproject-nix"
       },
       "locked": {
-        "lastModified": 1702457430,
-        "narHash": "sha256-8NQiXtYCOiC7XFayy6GPGDudCBrPROry3mfWjpdVj5g=",
+        "lastModified": 1719685993,
+        "narHash": "sha256-04gy1icwnGO3ZXF6r96yBm/C0PNPzeLxA/8xzzq0dBI=",
         "owner": "nix-community",
         "repo": "dream2nix",
-        "rev": "262198033e23e9ee832f0cc8133d38f07598f555",
+        "rev": "1b5e01219a32324c8f6889fe1f4db933ec7932f6",
         "type": "github"
       },
       "original": {
@@ -69,11 +69,11 @@
         "rust-analyzer-src": "rust-analyzer-src"
       },
       "locked": {
-        "lastModified": 1704003651,
-        "narHash": "sha256-bA3d4E1CX5G7TVbKwJOm9jZfVOGOPp6u5CKEUzNsE8E=",
+        "lastModified": 1719815435,
+        "narHash": "sha256-K2xFp142onP35jcx7li10xUxNVEVRWjAdY8DSuR7Naw=",
         "owner": "nix-community",
         "repo": "fenix",
-        "rev": "c6d82e087ac96f24b90c5787a17e29a72566c2b4",
+        "rev": "ebfe2c639111d7e82972a12711206afaeeda2450",
         "type": "github"
       },
       "original": {
@@ -157,11 +157,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1712623723,
-        "narHash": "sha256-jPD5+M+QPyMRk52zfFMIeHdv7yXYJ/yNGqwS0PhYF+E=",
+        "lastModified": 1719541573,
+        "narHash": "sha256-9j8Rtv5UWsD4A3jAh8MpopNGmftSAoI8htssmXLu8jU=",
         "owner": "reckenrode",
         "repo": "nix-foundryvtt",
-        "rev": "6025615b431170558c3c13f16b549fc0126425e1",
+        "rev": "1176cc325e5e1d46c7a018663a8e02e699e838ec",
         "type": "github"
       },
       "original": {
@@ -210,11 +210,11 @@
     },
     "nixpkgs-stable": {
       "locked": {
-        "lastModified": 1713638189,
-        "narHash": "sha256-q7APLfB6FmmSMI1Su5ihW9IwntBsk2hWNXh8XtSdSIk=",
+        "lastModified": 1719663039,
+        "narHash": "sha256-tXlrgAQygNIy49LDVFuPXlWD2zTQV9/F8pfoqwwPJyo=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "74574c38577914733b4f7a775dd77d24245081dd",
+        "rev": "4a1e673523344f6ccc84b37f4413ad74ea19a119",
         "type": "github"
       },
       "original": {
@@ -226,43 +226,43 @@
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1714253743,
-        "narHash": "sha256-mdTQw2XlariysyScCv2tTE45QSU9v/ezLcHJ22f0Nxc=",
+        "lastModified": 1719824438,
+        "narHash": "sha256-pY0wosAgcr9W4vmGML0T3BVhQiGuKoozCbs2t+Je1zc=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "58a1abdbae3217ca6b702f03d3b35125d88a2994",
+        "rev": "7f993cdf26ccef564eabf31fdb40d140821e12bc",
         "type": "github"
       },
       "original": {
         "owner": "nixos",
-        "ref": "nixos-unstable",
+        "ref": "nixos-unstable-small",
         "repo": "nixpkgs",
         "type": "github"
       }
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1718208800,
-        "narHash": "sha256-US1tAChvPxT52RV8GksWZS415tTS7PV42KTc2PNDBmc=",
+        "lastModified": 1719825363,
+        "narHash": "sha256-2ASBatUTQWNIiTeBZRuxROu27MyOavVnzeCv7h40QNw=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "cc54fb41d13736e92229c21627ea4f22199fee6b",
+        "rev": "10c832d0548e9e3a6df7eb51e68c2783212a303e",
         "type": "github"
       },
       "original": {
         "owner": "nixos",
-        "ref": "nixos-24.05",
+        "ref": "nixos-24.05-small",
         "repo": "nixpkgs",
         "type": "github"
       }
     },
     "nixpkgs_3": {
       "locked": {
-        "lastModified": 1702272962,
-        "narHash": "sha256-D+zHwkwPc6oYQ4G3A1HuadopqRwUY/JkMwHz1YF7j4Q=",
+        "lastModified": 1719468428,
+        "narHash": "sha256-vN5xJAZ4UGREEglh3lfbbkIj+MPEYMuqewMn4atZFaQ=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "e97b3e4186bcadf0ef1b6be22b8558eab1cdeb5d",
+        "rev": "1e3deb3d8a86a870d925760db1a5adecc64d329d",
         "type": "github"
       },
       "original": {
@@ -281,11 +281,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1713333471,
-        "narHash": "sha256-sIVQKOXzruxtTYiBRHZa8UQH+CSIa9K5MZlY6vavYfA=",
+        "lastModified": 1718252448,
+        "narHash": "sha256-xZZBdKqe1ByITzvx65pVgGQ5jeb73MybjgrcfI84lEo=",
         "owner": "berberman",
         "repo": "nvfetcher",
-        "rev": "2a824322dc6a755ffda83a13b948d42304521e4d",
+        "rev": "fa7609950023462c6f91c425de7610c0bb6b86ba",
         "type": "github"
       },
       "original": {
@@ -375,11 +375,11 @@
     "rust-analyzer-src": {
       "flake": false,
       "locked": {
-        "lastModified": 1703965384,
-        "narHash": "sha256-3iyouqkBvhh/E48TkBlt4JmmcIEyfQwY7pokKBx9WNg=",
+        "lastModified": 1719760370,
+        "narHash": "sha256-fsxAuW6RxKZYjAP3biUC6C4vaYFhDfWv8lp1Tmx3ZCY=",
         "owner": "rust-lang",
         "repo": "rust-analyzer",
-        "rev": "e872f5085cf5b0e44558442365c1c033d486eff2",
+        "rev": "ea7fdada6a0940b239ddbde2048a4d7dac1efe1e",
         "type": "github"
       },
       "original": {
@@ -442,11 +442,11 @@
         "nixpkgs-stable": "nixpkgs-stable"
       },
       "locked": {
-        "lastModified": 1713892811,
-        "narHash": "sha256-uIGmA2xq41vVFETCF1WW4fFWFT2tqBln+aXnWrvjGRE=",
+        "lastModified": 1719716556,
+        "narHash": "sha256-KA9gy2Wkv76s4A8eLnOcdKVTygewbw3xsB8+awNMyqs=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "f1b0adc27265274e3b0c9b872a8f476a098679bd",
+        "rev": "b5974d4331fb6c893e808977a2e1a6d34b3162d6",
         "type": "github"
       },
       "original": {
@@ -523,11 +523,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1704840002,
-        "narHash": "sha256-ik2LeuRjcnRXwBLoRSOyGEMXscE+coO8G79IFhZhdJk=",
+        "lastModified": 1719851829,
+        "narHash": "sha256-M5miiIbiwP4uArTyeIr/RKA857rP14AEJUe11AZsKAc=",
         "ref": "refs/heads/master",
-        "rev": "d14f50c8dcc8ab30a5e5fa907b392ac0df6c7b52",
-        "revCount": 73,
+        "rev": "4a099f27a27f4107ceb14969e2158eaabebcf1d4",
+        "revCount": 74,
         "type": "git",
         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git"
       },
diff --git a/flake.nix b/flake.nix
index afdc668..e3ff531 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,8 +2,8 @@
   description = "tlater.net host configuration";
 
   inputs = {
-    nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
-    nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
+    nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05-small";
+    nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable-small";
     disko = {
       url = "github:nix-community/disko";
       inputs.nixpkgs.follows = "nixpkgs";

From 21cb4eab9cbaeee6dab27ee9dc0c03b42269839c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 1 Jul 2024 18:34:23 +0200
Subject: [PATCH 150/212] foundryvtt: Set foundry version explicitly

---
 configuration/services/foundryvtt.nix | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configuration/services/foundryvtt.nix b/configuration/services/foundryvtt.nix
index e69d2dd..3383ab3 100644
--- a/configuration/services/foundryvtt.nix
+++ b/configuration/services/foundryvtt.nix
@@ -1,6 +1,7 @@
 { lib
 , config
 , flake-inputs
+, pkgs
 , ...
 }:
 let
@@ -15,6 +16,7 @@ in
     minifyStaticFiles = true;
     proxySSL = true;
     proxyPort = 443;
+    package = flake-inputs.foundryvtt.packages.${pkgs.system}.foundryvtt_11;
   };
 
   # Want to start it manually when I need it, not have it constantly

From 32f4cabfa35bad8da8ef2a06e1f08dece6a9a6e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 1 Jul 2024 18:35:53 +0200
Subject: [PATCH 151/212] nextcloud: Update to 28 since 27 is EOL

We were waiting for nextcloud news to update, but we can't wait any
longer.
---
 configuration/services/nextcloud.nix   |  2 +-
 pkgs/_sources_nextcloud/generated.json | 24 ++++++++++++------------
 pkgs/_sources_nextcloud/generated.nix  | 24 ++++++++++++------------
 pkgs/nextcloud-apps.toml               | 13 +++++--------
 4 files changed, 30 insertions(+), 33 deletions(-)

diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 7c4fcf4..0d22e6c 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -6,7 +6,7 @@ let
   # Update pending on rewrite of nextcloud news, though there is an
   # alpha to switch to if it becomes necessary:
   # https://github.com/nextcloud/news/issues/2610
-  nextcloud = pkgs.nextcloud27;
+  nextcloud = pkgs.nextcloud28;
   hostName = "nextcloud.${config.services.nginx.domain}";
 in
 {
diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index ce9ac04..c216c8d 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -7,11 +7,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-JXNQNnWXoii71QhtKktuEBEIqzmONVetULBhpSjM9xo=",
+            "sha256": "sha256-wUeXcbxNCRA2brzdCHKwl0zbhmDucKv1ZCkF3KlQ8O4=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/bookmarks/releases/download/v13.1.3/bookmarks-13.1.3.tar.gz"
+            "url": "https://github.com/nextcloud/bookmarks/releases/download/v14.2.2/bookmarks-14.2.2.tar.gz"
         },
-        "version": "13.1.3"
+        "version": "14.2.2"
     },
     "calendar": {
         "cargoLocks": null,
@@ -21,11 +21,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-hZfjWAMi/0qs5xMMgOlcoSXG6kcZ2aeDaez+NqSZFKI=",
+            "sha256": "sha256-cuAqJz1cZ+VfxttAKjWIe11DFwWGLdSSvcNJKQKidgk=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.6.7/calendar-v4.6.7.tar.gz"
+            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.7.8/calendar-v4.7.8.tar.gz"
         },
-        "version": "v4.6.7"
+        "version": "v4.7.8"
     },
     "contacts": {
         "cargoLocks": null,
@@ -49,11 +49,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-TE/w8SgyIPaGl5wZUAsG234nxoPj25QoRPF3zjbMoRk=",
+            "sha256": "sha256-a8ekMnEzudHGiqHF53jPtgsVTOTc2QLuPg6YtTw5h68=",
             "type": "tarball",
-            "url": "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.10.5/Cookbook-0.10.5.tar.gz"
+            "url": "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.11.1/Cookbook-0.11.1.tar.gz"
         },
-        "version": "0.10.5"
+        "version": "0.11.1"
     },
     "news": {
         "cargoLocks": null,
@@ -63,11 +63,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-cfJkKRNSz15L4E3w1tnEb+t4MrVwVzb8lb6vCOA4cK4=",
+            "sha256": "sha256-XNGjf7SWgJYFdVNOh3ED0jxSG0GJwWImVQq4cJT1Lo4=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/news/releases/download/24.0.0/news.tar.gz"
+            "url": "https://github.com/nextcloud/news/releases/download/25.0.0-alpha7/news.tar.gz"
         },
-        "version": "24.0.0"
+        "version": "25.0.0-alpha7"
     },
     "notes": {
         "cargoLocks": null,
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index c77aa9c..3075206 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -3,18 +3,18 @@
 {
   bookmarks = {
     pname = "bookmarks";
-    version = "13.1.3";
+    version = "14.2.2";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/bookmarks/releases/download/v13.1.3/bookmarks-13.1.3.tar.gz";
-      sha256 = "sha256-JXNQNnWXoii71QhtKktuEBEIqzmONVetULBhpSjM9xo=";
+      url = "https://github.com/nextcloud/bookmarks/releases/download/v14.2.2/bookmarks-14.2.2.tar.gz";
+      sha256 = "sha256-wUeXcbxNCRA2brzdCHKwl0zbhmDucKv1ZCkF3KlQ8O4=";
     };
   };
   calendar = {
     pname = "calendar";
-    version = "v4.6.7";
+    version = "v4.7.8";
     src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.6.7/calendar-v4.6.7.tar.gz";
-      sha256 = "sha256-hZfjWAMi/0qs5xMMgOlcoSXG6kcZ2aeDaez+NqSZFKI=";
+      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.7.8/calendar-v4.7.8.tar.gz";
+      sha256 = "sha256-cuAqJz1cZ+VfxttAKjWIe11DFwWGLdSSvcNJKQKidgk=";
     };
   };
   contacts = {
@@ -27,18 +27,18 @@
   };
   cookbook = {
     pname = "cookbook";
-    version = "0.10.5";
+    version = "0.11.1";
     src = fetchTarball {
-      url = "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.10.5/Cookbook-0.10.5.tar.gz";
-      sha256 = "sha256-TE/w8SgyIPaGl5wZUAsG234nxoPj25QoRPF3zjbMoRk=";
+      url = "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.11.1/Cookbook-0.11.1.tar.gz";
+      sha256 = "sha256-a8ekMnEzudHGiqHF53jPtgsVTOTc2QLuPg6YtTw5h68=";
     };
   };
   news = {
     pname = "news";
-    version = "24.0.0";
+    version = "25.0.0-alpha7";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/news/releases/download/24.0.0/news.tar.gz";
-      sha256 = "sha256-cfJkKRNSz15L4E3w1tnEb+t4MrVwVzb8lb6vCOA4cK4=";
+      url = "https://github.com/nextcloud/news/releases/download/25.0.0-alpha7/news.tar.gz";
+      sha256 = "sha256-XNGjf7SWgJYFdVNOh3ED0jxSG0GJwWImVQq4cJT1Lo4=";
     };
   };
   notes = {
diff --git a/pkgs/nextcloud-apps.toml b/pkgs/nextcloud-apps.toml
index 36566db..9023dd3 100644
--- a/pkgs/nextcloud-apps.toml
+++ b/pkgs/nextcloud-apps.toml
@@ -1,12 +1,10 @@
 [bookmarks]
-# src.github = "nextcloud/bookmarks"
+src.github = "nextcloud/bookmarks"
 src.prefix = "v"
-src.manual = "v13.1.3"
 fetch.tarball = "https://github.com/nextcloud/bookmarks/releases/download/v$ver/bookmarks-$ver.tar.gz"
 
 [calendar]
-# src.github = "nextcloud-releases/calendar"
-src.manual = "v4.6.7"
+src.github = "nextcloud-releases/calendar"
 fetch.tarball = "https://github.com/nextcloud-releases/calendar/releases/download/$ver/calendar-$ver.tar.gz"
 
 [contacts]
@@ -15,15 +13,14 @@ src.manual = "v5.5.3"
 fetch.tarball = "https://github.com/nextcloud-releases/contacts/releases/download/$ver/contacts-$ver.tar.gz"
 
 [cookbook]
-# src.github = "christianlupus-nextcloud/cookbook-releases"
+src.github = "christianlupus-nextcloud/cookbook-releases"
 src.prefix = "v"
-src.manual = "0.10.5"
 fetch.tarball = "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v$ver/Cookbook-$ver.tar.gz"
 
 [news]
+# Update manually until angular rewrite is done
 # src.github = "nextcloud/news"
-# Update to 25 when angular rewrite is done/the alpha when I need to switch to nextcloud 28+
-src.manual = "24.0.0"
+src.manual = "25.0.0-alpha7"
 fetch.tarball = "https://github.com/nextcloud/news/releases/download/$ver/news.tar.gz"
 
 [notes]

From 222829d82a7ffe2887ceaaefa13ed3a2e4b8963a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 1 Jul 2024 18:39:42 +0200
Subject: [PATCH 152/212] starbound: Don't build service for now

This includes the really huge steam-run closure, which is just a PITA
to keep up with if we're never using it.
---
 configuration/default.nix | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index b933d19..792a4c9 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -24,7 +24,7 @@
     ./services/nextcloud.nix
     ./services/webserver.nix
     ./services/wireguard.nix
-    ./services/starbound.nix
+    # ./services/starbound.nix -- Not currently used
     ./services/postgres.nix
     ./nginx.nix
     ./sops.nix
@@ -49,9 +49,6 @@
     settings.trusted-users = [ "@wheel" ];
   };
 
-  nixpkgs.config.allowUnfreePredicate = pkg:
-    builtins.elem (lib.getName pkg) [ "steam-original" "steam-runtime" "steam-run" "steamcmd" ];
-
   # Optimization for minecraft servers, see:
   # https://bugs.mojang.com/browse/MC-183518
   boot.kernelParams = [ "highres=off" "nohz=off" ];

From d568436d83126c7e92a1402e1551aa7235412481 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 1 Jul 2024 19:18:34 +0200
Subject: [PATCH 153/212] conduit: Use new upstream delegation support

---
 configuration/services/conduit.nix | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
index 950165c..8734785 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit.nix
@@ -18,6 +18,13 @@ in
       server_name = domain;
       database_backend = "rocksdb";
 
+      # Set up delegation: https://docs.conduit.rs/delegation.html#automatic-recommended
+      # This is primarily to make sliding sync work
+      well_known = {
+        client = "https://${domain}";
+        server = "${domain}:443";
+      };
+
       turn_uris =
         let
           address = "${config.services.coturn.realm}:${toString config.services.coturn.listening-port}";
@@ -230,19 +237,8 @@ in
           proxy_buffering off;
         '';
       };
-
-      # Add Element X support
-      # TODO(tlater): Remove when no longer required: https://github.com/vector-im/element-x-android/issues/1085
-      "=/.well-known/matrix/client" = {
-        alias = pkgs.writeText "well-known-matrix-client" (builtins.toJSON {
-          "m.homeserver".base_url = "https://${domain}";
-          "org.matrix.msc3575.proxy".url = "https://${domain}";
-        });
-
-        extraConfig = ''
-          default_type application/json;
-          add_header Access-Control-Allow-Origin "*";
-        '';
+      "/.well-known/matrix" = {
+        proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}";
       };
     };
   };

From 21b9112f76675cc23201433186d7ca25cb38ebf6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 1 Jul 2024 19:18:59 +0200
Subject: [PATCH 154/212] fail2ban-exporter: Bump generated source json/nix

---
 pkgs/_sources_pkgs/generated.json | 1 +
 pkgs/_sources_pkgs/generated.nix  | 1 +
 2 files changed, 2 insertions(+)

diff --git a/pkgs/_sources_pkgs/generated.json b/pkgs/_sources_pkgs/generated.json
index fc6c343..cec5a92 100644
--- a/pkgs/_sources_pkgs/generated.json
+++ b/pkgs/_sources_pkgs/generated.json
@@ -13,6 +13,7 @@
             "name": null,
             "rev": "v0.10.1",
             "sha256": "sha256-zGEhDy3uXIbvx4agSA8Mx7bRtiZZtoDZGbNbHc9L+yI=",
+            "sparseCheckout": [],
             "type": "git",
             "url": "https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter"
         },
diff --git a/pkgs/_sources_pkgs/generated.nix b/pkgs/_sources_pkgs/generated.nix
index 39dc6d0..95fd75e 100644
--- a/pkgs/_sources_pkgs/generated.nix
+++ b/pkgs/_sources_pkgs/generated.nix
@@ -10,6 +10,7 @@
       fetchSubmodules = false;
       deepClone = false;
       leaveDotGit = false;
+      sparseCheckout = [ ];
       sha256 = "sha256-zGEhDy3uXIbvx4agSA8Mx7bRtiZZtoDZGbNbHc9L+yI=";
     };
   };

From 306b69f6b543e785f929919a83c8169e281f25c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 3 Jul 2024 01:28:23 +0200
Subject: [PATCH 155/212] nextcloud: Use the system postgres version

---
 configuration/services/nextcloud.nix | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 0d22e6c..30adf6e 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -1,5 +1,6 @@
 { pkgs
 , config
+, lib
 , ...
 }:
 let
@@ -14,6 +15,19 @@ in
     inherit hostName;
 
     package = nextcloud;
+    phpPackage = lib.mkForce
+      (pkgs.php.override {
+        packageOverrides = final: prev: {
+          extensions = prev.extensions // {
+            pgsql = prev.extensions.pgsql.overrideAttrs (old: {
+              configureFlags = [ "--with-pgsql=${config.services.postgresql.package}" ];
+            });
+            pdo_pgsql = prev.extensions.pdo_pgsql.overrideAttrs (old: {
+              configureFlags = [ "--with-pdo-pgsql=${config.services.postgresql.package}" ];
+            });
+          };
+        };
+      });
     enable = true;
     maxUploadSize = "2G";
     https = true;

From d426e783cda4725e6b3e1bba2d726215676a502f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 3 Jul 2024 02:56:23 +0200
Subject: [PATCH 156/212] grafana: Properly proxy websocket connections

Fixes #115
---
 configuration/services/metrics/grafana.nix | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/configuration/services/metrics/grafana.nix b/configuration/services/metrics/grafana.nix
index d13fe7b..5c779f2 100644
--- a/configuration/services/metrics/grafana.nix
+++ b/configuration/services/metrics/grafana.nix
@@ -42,6 +42,12 @@ in
     forceSSL = true;
     useACMEHost = "tlater.net";
     enableHSTS = true;
-    locations."/".proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}";
+    locations = {
+      "/".proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}";
+      "/api/live" = {
+        proxyWebsockets = true;
+        proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}";
+      };
+    };
   };
 }

From 0047b585a38526f237615afa6e776d80c10d51c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 5 Aug 2024 19:38:04 +0200
Subject: [PATCH 157/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/d185770ea261fb5cf81aa5ad1791b93a7834d12c' (2024-06-30)
  → 'github:nix-community/disko/0257e44f4ad472b54f19a6dd1615aee7fa48ed49' (2024-08-05)
• Updated input 'foundryvtt':
    'github:reckenrode/nix-foundryvtt/1176cc325e5e1d46c7a018663a8e02e699e838ec' (2024-06-28)
  → 'github:reckenrode/nix-foundryvtt/699a175398410688214615a9d977354e9ef98d2d' (2024-08-03)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/10c832d0548e9e3a6df7eb51e68c2783212a303e' (2024-07-01)
  → 'github:nixos/nixpkgs/0ab9c4c1e0cab782fcde00ec2b32436abfd2a6d4' (2024-08-05)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/7f993cdf26ccef564eabf31fdb40d140821e12bc' (2024-07-01)
  → 'github:nixos/nixpkgs/41d21a82c38e226e234e16f4ff213b3fcf85e6e9' (2024-08-05)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/b5974d4331fb6c893e808977a2e1a6d34b3162d6' (2024-06-30)
  → 'github:Mic92/sops-nix/eb34eb588132d653e4c4925d862f1e5a227cc2ab' (2024-07-27)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/4a1e673523344f6ccc84b37f4413ad74ea19a119' (2024-06-29)
  → 'github:NixOS/nixpkgs/556533a23879fc7e5f98dd2e0b31a6911a213171' (2024-07-21)
---
 flake.lock | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/flake.lock b/flake.lock
index dab6ebf..c541444 100644
--- a/flake.lock
+++ b/flake.lock
@@ -27,11 +27,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1719733833,
-        "narHash": "sha256-6h2EqZU9bL9rHlXE+2LCBgnDImejzbS+4dYsNDDFlkY=",
+        "lastModified": 1722821805,
+        "narHash": "sha256-FGrUPUD+LMDwJsYyNSxNIzFMldtCm8wXiQuyL2PHSrM=",
         "owner": "nix-community",
         "repo": "disko",
-        "rev": "d185770ea261fb5cf81aa5ad1791b93a7834d12c",
+        "rev": "0257e44f4ad472b54f19a6dd1615aee7fa48ed49",
         "type": "github"
       },
       "original": {
@@ -157,11 +157,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1719541573,
-        "narHash": "sha256-9j8Rtv5UWsD4A3jAh8MpopNGmftSAoI8htssmXLu8jU=",
+        "lastModified": 1722661736,
+        "narHash": "sha256-0lujsK40JV/2PlqCjhZMGpHKL4vDKzJcnkFJYnG1WZA=",
         "owner": "reckenrode",
         "repo": "nix-foundryvtt",
-        "rev": "1176cc325e5e1d46c7a018663a8e02e699e838ec",
+        "rev": "699a175398410688214615a9d977354e9ef98d2d",
         "type": "github"
       },
       "original": {
@@ -210,27 +210,27 @@
     },
     "nixpkgs-stable": {
       "locked": {
-        "lastModified": 1719663039,
-        "narHash": "sha256-tXlrgAQygNIy49LDVFuPXlWD2zTQV9/F8pfoqwwPJyo=",
+        "lastModified": 1721524707,
+        "narHash": "sha256-5NctRsoE54N86nWd0psae70YSLfrOek3Kv1e8KoXe/0=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "4a1e673523344f6ccc84b37f4413ad74ea19a119",
+        "rev": "556533a23879fc7e5f98dd2e0b31a6911a213171",
         "type": "github"
       },
       "original": {
         "owner": "NixOS",
-        "ref": "release-23.11",
+        "ref": "release-24.05",
         "repo": "nixpkgs",
         "type": "github"
       }
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1719824438,
-        "narHash": "sha256-pY0wosAgcr9W4vmGML0T3BVhQiGuKoozCbs2t+Je1zc=",
+        "lastModified": 1722849152,
+        "narHash": "sha256-Es/syckEivSAJWxVF6vRYAFMAgXhJpIPdxMwN70NYxo=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "7f993cdf26ccef564eabf31fdb40d140821e12bc",
+        "rev": "41d21a82c38e226e234e16f4ff213b3fcf85e6e9",
         "type": "github"
       },
       "original": {
@@ -242,11 +242,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1719825363,
-        "narHash": "sha256-2ASBatUTQWNIiTeBZRuxROu27MyOavVnzeCv7h40QNw=",
+        "lastModified": 1722821716,
+        "narHash": "sha256-VZMyGaYBuuQ+PCF4iRNeqJ/lbowOMQnnVF2Vg0tR3Dk=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "10c832d0548e9e3a6df7eb51e68c2783212a303e",
+        "rev": "0ab9c4c1e0cab782fcde00ec2b32436abfd2a6d4",
         "type": "github"
       },
       "original": {
@@ -442,11 +442,11 @@
         "nixpkgs-stable": "nixpkgs-stable"
       },
       "locked": {
-        "lastModified": 1719716556,
-        "narHash": "sha256-KA9gy2Wkv76s4A8eLnOcdKVTygewbw3xsB8+awNMyqs=",
+        "lastModified": 1722114803,
+        "narHash": "sha256-s6YhI8UHwQvO4cIFLwl1wZ1eS5Cuuw7ld2VzUchdFP0=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "b5974d4331fb6c893e808977a2e1a6d34b3162d6",
+        "rev": "eb34eb588132d653e4c4925d862f1e5a227cc2ab",
         "type": "github"
       },
       "original": {

From e1bd183cdda6a61930cffa4061e688a5a5bfc981 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 5 Aug 2024 19:42:55 +0200
Subject: [PATCH 158/212] pkgs: Update sources

---
 pkgs/_sources_nextcloud/generated.json | 24 ++++++++++++------------
 pkgs/_sources_nextcloud/generated.nix  | 24 ++++++++++++------------
 pkgs/nextcloud-apps.toml               |  6 +++---
 3 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index c216c8d..73a69ea 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -7,11 +7,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-wUeXcbxNCRA2brzdCHKwl0zbhmDucKv1ZCkF3KlQ8O4=",
+            "sha256": "sha256-32xlI+cQNlJT255F3lmx04FkeZdzd93YzSA3wPcETlQ=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/bookmarks/releases/download/v14.2.2/bookmarks-14.2.2.tar.gz"
+            "url": "https://github.com/nextcloud/bookmarks/releases/download/v14.2.3/bookmarks-14.2.3.tar.gz"
         },
-        "version": "14.2.2"
+        "version": "14.2.3"
     },
     "calendar": {
         "cargoLocks": null,
@@ -21,11 +21,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-cuAqJz1cZ+VfxttAKjWIe11DFwWGLdSSvcNJKQKidgk=",
+            "sha256": "sha256-k73g1SpepMz0kBWX67dLahE/vE1AgTzTV+Sq6UBNPuU=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.7.8/calendar-v4.7.8.tar.gz"
+            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.7.14/calendar-v4.7.14.tar.gz"
         },
-        "version": "v4.7.8"
+        "version": "v4.7.14"
     },
     "contacts": {
         "cargoLocks": null,
@@ -63,11 +63,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-XNGjf7SWgJYFdVNOh3ED0jxSG0GJwWImVQq4cJT1Lo4=",
+            "sha256": "sha256-AhTZGQCLeNgsRBF5w3+Lf9JtNN4D1QncB5t+odU+XUc=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/news/releases/download/25.0.0-alpha7/news.tar.gz"
+            "url": "https://github.com/nextcloud/news/releases/download/25.0.0-alpha8/news.tar.gz"
         },
-        "version": "25.0.0-alpha7"
+        "version": "25.0.0-alpha8"
     },
     "notes": {
         "cargoLocks": null,
@@ -77,10 +77,10 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-ydpxatwuZUz7XIgK8FMklZlxNQklpsP8Uqpxvt3iK0k=",
+            "sha256": "sha256-A3QNWGWeC2OcZngMrh9NpYbU5qp5x9xiDcRfB9cRXBo=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/notes/releases/download/v4.10.0/notes.tar.gz"
+            "url": "https://github.com/nextcloud-releases/notes/releases/download/v4.10.1/notes-v4.10.1.tar.gz"
         },
-        "version": "v4.10.0"
+        "version": "v4.10.1"
     }
 }
\ No newline at end of file
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index 3075206..918c8d2 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -3,18 +3,18 @@
 {
   bookmarks = {
     pname = "bookmarks";
-    version = "14.2.2";
+    version = "14.2.3";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/bookmarks/releases/download/v14.2.2/bookmarks-14.2.2.tar.gz";
-      sha256 = "sha256-wUeXcbxNCRA2brzdCHKwl0zbhmDucKv1ZCkF3KlQ8O4=";
+      url = "https://github.com/nextcloud/bookmarks/releases/download/v14.2.3/bookmarks-14.2.3.tar.gz";
+      sha256 = "sha256-32xlI+cQNlJT255F3lmx04FkeZdzd93YzSA3wPcETlQ=";
     };
   };
   calendar = {
     pname = "calendar";
-    version = "v4.7.8";
+    version = "v4.7.14";
     src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.7.8/calendar-v4.7.8.tar.gz";
-      sha256 = "sha256-cuAqJz1cZ+VfxttAKjWIe11DFwWGLdSSvcNJKQKidgk=";
+      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.7.14/calendar-v4.7.14.tar.gz";
+      sha256 = "sha256-k73g1SpepMz0kBWX67dLahE/vE1AgTzTV+Sq6UBNPuU=";
     };
   };
   contacts = {
@@ -35,18 +35,18 @@
   };
   news = {
     pname = "news";
-    version = "25.0.0-alpha7";
+    version = "25.0.0-alpha8";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/news/releases/download/25.0.0-alpha7/news.tar.gz";
-      sha256 = "sha256-XNGjf7SWgJYFdVNOh3ED0jxSG0GJwWImVQq4cJT1Lo4=";
+      url = "https://github.com/nextcloud/news/releases/download/25.0.0-alpha8/news.tar.gz";
+      sha256 = "sha256-AhTZGQCLeNgsRBF5w3+Lf9JtNN4D1QncB5t+odU+XUc=";
     };
   };
   notes = {
     pname = "notes";
-    version = "v4.10.0";
+    version = "v4.10.1";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/notes/releases/download/v4.10.0/notes.tar.gz";
-      sha256 = "sha256-ydpxatwuZUz7XIgK8FMklZlxNQklpsP8Uqpxvt3iK0k=";
+      url = "https://github.com/nextcloud-releases/notes/releases/download/v4.10.1/notes-v4.10.1.tar.gz";
+      sha256 = "sha256-A3QNWGWeC2OcZngMrh9NpYbU5qp5x9xiDcRfB9cRXBo=";
     };
   };
 }
diff --git a/pkgs/nextcloud-apps.toml b/pkgs/nextcloud-apps.toml
index 9023dd3..89dccb4 100644
--- a/pkgs/nextcloud-apps.toml
+++ b/pkgs/nextcloud-apps.toml
@@ -20,9 +20,9 @@ fetch.tarball = "https://github.com/christianlupus-nextcloud/cookbook-releases/r
 [news]
 # Update manually until angular rewrite is done
 # src.github = "nextcloud/news"
-src.manual = "25.0.0-alpha7"
+src.manual = "25.0.0-alpha8"
 fetch.tarball = "https://github.com/nextcloud/news/releases/download/$ver/news.tar.gz"
 
 [notes]
-src.github = "nextcloud/notes"
-fetch.tarball = "https://github.com/nextcloud/notes/releases/download/$ver/notes.tar.gz"
+src.github = "nextcloud-releases/notes"
+fetch.tarball = "https://github.com/nextcloud-releases/notes/releases/download/$ver/notes-$ver.tar.gz"

From 521190297bc2fa7380383df26ba559053ab246d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 18 Aug 2024 17:24:45 +0200
Subject: [PATCH 159/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/0257e44f4ad472b54f19a6dd1615aee7fa48ed49' (2024-08-05)
  → 'github:nix-community/disko/276a0d055a720691912c6a34abb724e395c8e38a' (2024-08-15)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/0ab9c4c1e0cab782fcde00ec2b32436abfd2a6d4' (2024-08-05)
  → 'github:nixos/nixpkgs/1cbd3d585263dc620c483e138d352a39b9f0e3ec' (2024-08-17)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/41d21a82c38e226e234e16f4ff213b3fcf85e6e9' (2024-08-05)
  → 'github:nixos/nixpkgs/abcef4da4ebb72240bddc370a27263627e64877f' (2024-08-18)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/eb34eb588132d653e4c4925d862f1e5a227cc2ab' (2024-07-27)
  → 'github:Mic92/sops-nix/be0eec2d27563590194a9206f551a6f73d52fa34' (2024-08-12)
---
 flake.lock | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/flake.lock b/flake.lock
index c541444..78327bf 100644
--- a/flake.lock
+++ b/flake.lock
@@ -27,11 +27,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1722821805,
-        "narHash": "sha256-FGrUPUD+LMDwJsYyNSxNIzFMldtCm8wXiQuyL2PHSrM=",
+        "lastModified": 1723685519,
+        "narHash": "sha256-GkXQIoZmW2zCPp1YFtAYGg/xHNyFH/Mgm79lcs81rq0=",
         "owner": "nix-community",
         "repo": "disko",
-        "rev": "0257e44f4ad472b54f19a6dd1615aee7fa48ed49",
+        "rev": "276a0d055a720691912c6a34abb724e395c8e38a",
         "type": "github"
       },
       "original": {
@@ -226,11 +226,11 @@
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1722849152,
-        "narHash": "sha256-Es/syckEivSAJWxVF6vRYAFMAgXhJpIPdxMwN70NYxo=",
+        "lastModified": 1723957280,
+        "narHash": "sha256-J08Yqf2IJ73y7myI69qEKsQ048ibweG6FeJeCxbIdB4=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "41d21a82c38e226e234e16f4ff213b3fcf85e6e9",
+        "rev": "abcef4da4ebb72240bddc370a27263627e64877f",
         "type": "github"
       },
       "original": {
@@ -242,11 +242,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1722821716,
-        "narHash": "sha256-VZMyGaYBuuQ+PCF4iRNeqJ/lbowOMQnnVF2Vg0tR3Dk=",
+        "lastModified": 1723920526,
+        "narHash": "sha256-USs6A60raDKZ/8BEpqja1XjZIsRzADX+NtWKH6wIxIw=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "0ab9c4c1e0cab782fcde00ec2b32436abfd2a6d4",
+        "rev": "1cbd3d585263dc620c483e138d352a39b9f0e3ec",
         "type": "github"
       },
       "original": {
@@ -442,11 +442,11 @@
         "nixpkgs-stable": "nixpkgs-stable"
       },
       "locked": {
-        "lastModified": 1722114803,
-        "narHash": "sha256-s6YhI8UHwQvO4cIFLwl1wZ1eS5Cuuw7ld2VzUchdFP0=",
+        "lastModified": 1723501126,
+        "narHash": "sha256-N9IcHgj/p1+2Pvk8P4Zc1bfrMwld5PcosVA0nL6IGdE=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "eb34eb588132d653e4c4925d862f1e5a227cc2ab",
+        "rev": "be0eec2d27563590194a9206f551a6f73d52fa34",
         "type": "github"
       },
       "original": {

From 0ad265f6aa269c953c76cbc998550a864ec72653 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 18 Aug 2024 18:51:16 +0200
Subject: [PATCH 160/212] pkgs/sources: Update package sources

---
 pkgs/_sources_nextcloud/generated.json | 12 ++++++------
 pkgs/_sources_nextcloud/generated.nix  | 12 ++++++------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index 73a69ea..4071726 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -7,11 +7,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-32xlI+cQNlJT255F3lmx04FkeZdzd93YzSA3wPcETlQ=",
+            "sha256": "sha256-V4zZsAwPn8QiCXEDqOgNFHaXqMOcHMpMbJ1Oz3Db0pc=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/bookmarks/releases/download/v14.2.3/bookmarks-14.2.3.tar.gz"
+            "url": "https://github.com/nextcloud/bookmarks/releases/download/v14.2.4/bookmarks-14.2.4.tar.gz"
         },
-        "version": "14.2.3"
+        "version": "14.2.4"
     },
     "calendar": {
         "cargoLocks": null,
@@ -21,11 +21,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-k73g1SpepMz0kBWX67dLahE/vE1AgTzTV+Sq6UBNPuU=",
+            "sha256": "sha256-sipXeyOL4OhENz7V2beFeSYBAoFZdCWtqftIy0lsqEY=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.7.14/calendar-v4.7.14.tar.gz"
+            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.7.15/calendar-v4.7.15.tar.gz"
         },
-        "version": "v4.7.14"
+        "version": "v4.7.15"
     },
     "contacts": {
         "cargoLocks": null,
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index 918c8d2..53e26d1 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -3,18 +3,18 @@
 {
   bookmarks = {
     pname = "bookmarks";
-    version = "14.2.3";
+    version = "14.2.4";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/bookmarks/releases/download/v14.2.3/bookmarks-14.2.3.tar.gz";
-      sha256 = "sha256-32xlI+cQNlJT255F3lmx04FkeZdzd93YzSA3wPcETlQ=";
+      url = "https://github.com/nextcloud/bookmarks/releases/download/v14.2.4/bookmarks-14.2.4.tar.gz";
+      sha256 = "sha256-V4zZsAwPn8QiCXEDqOgNFHaXqMOcHMpMbJ1Oz3Db0pc=";
     };
   };
   calendar = {
     pname = "calendar";
-    version = "v4.7.14";
+    version = "v4.7.15";
     src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.7.14/calendar-v4.7.14.tar.gz";
-      sha256 = "sha256-k73g1SpepMz0kBWX67dLahE/vE1AgTzTV+Sq6UBNPuU=";
+      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.7.15/calendar-v4.7.15.tar.gz";
+      sha256 = "sha256-sipXeyOL4OhENz7V2beFeSYBAoFZdCWtqftIy0lsqEY=";
     };
   };
   contacts = {

From 3a591863b01d275a472ae6706bb58ed4794b305e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 18 Aug 2024 17:36:45 +0200
Subject: [PATCH 161/212] flake.nix: Add default package to allow easily
 creating gc root

---
 flake.nix | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/flake.nix b/flake.nix
index e3ff531..56f3972 100644
--- a/flake.nix
+++ b/flake.nix
@@ -43,6 +43,16 @@
     let
       system = "x86_64-linux";
       pkgs = nixpkgs.legacyPackages.${system};
+
+      vm = nixpkgs.lib.nixosSystem {
+        inherit system;
+        specialArgs.flake-inputs = inputs;
+
+        modules = [
+          ./configuration
+          ./configuration/hardware-specific/vm.nix
+        ];
+      };
     in
     {
       ##################
@@ -83,6 +93,12 @@
       #########
       checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
 
+      ###########################
+      # Garbage collection root #
+      ###########################
+
+      packages.${system}.default = vm.config.system.build.vm;
+
       ###################
       # Utility scripts #
       ###################
@@ -93,15 +109,6 @@
           type = "app";
           program =
             let
-              vm = nixpkgs.lib.nixosSystem {
-                inherit system;
-                specialArgs.flake-inputs = inputs;
-
-                modules = [
-                  ./configuration
-                  ./configuration/hardware-specific/vm.nix
-                ];
-              };
             in
             (pkgs.writeShellScript "" ''
               ${vm.config.system.build.vm.outPath}/bin/run-testvm-vm

From 04f7a7ef1d38906163afc9cddfa8ce2b0ebf3b45 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 18 Aug 2024 20:41:20 +0200
Subject: [PATCH 162/212] treewide: Use nixfmt for formatting

---
 configuration/default.nix                     |  21 +-
 .../hardware-specific/hetzner/default.nix     |   4 +-
 .../hardware-specific/hetzner/disko.nix       |  15 +-
 configuration/hardware-specific/vm.nix        |   3 +-
 configuration/nginx.nix                       |  47 ++-
 configuration/services/afvalcalendar.nix      |  19 +-
 configuration/services/backups.nix            | 308 +++++++++---------
 configuration/services/battery-manager.nix    |  10 +-
 configuration/services/conduit.nix            |  65 ++--
 configuration/services/fail2ban.nix           |   3 +-
 configuration/services/foundryvtt.nix         |  15 +-
 configuration/services/gitea.nix              |  13 +-
 configuration/services/metrics/exporters.nix  |  50 ++-
 configuration/services/metrics/options.nix    | 218 +++++++------
 .../services/metrics/victoriametrics.nix      |   7 +-
 configuration/services/nextcloud.nix          |  25 +-
 configuration/services/postgres.nix           |   3 +-
 configuration/services/starbound.nix          |   9 +-
 configuration/services/wireguard.nix          |   3 +-
 flake.nix                                     |  29 +-
 modules/default.nix                           |   6 +-
 modules/nginxExtensions.nix                   |  34 +-
 pkgs/afvalcalendar/default.nix                |  13 +-
 pkgs/default.nix                              |   7 +-
 pkgs/mkNextcloudApp.nix                       |   6 +-
 pkgs/prometheus/fail2ban-exporter.nix         |   5 +-
 pkgs/starbound/default.nix                    |  24 +-
 27 files changed, 496 insertions(+), 466 deletions(-)

diff --git a/configuration/default.nix b/configuration/default.nix
index 792a4c9..333488b 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -1,10 +1,12 @@
-{ config
-, pkgs
-, lib
-, modulesPath
-, flake-inputs
-, ...
-}: {
+{
+  config,
+  pkgs,
+  lib,
+  modulesPath,
+  flake-inputs,
+  ...
+}:
+{
   imports = [
     flake-inputs.disko.nixosModules.disko
     flake-inputs.sops-nix.nixosModules.sops
@@ -51,7 +53,10 @@
 
   # Optimization for minecraft servers, see:
   # https://bugs.mojang.com/browse/MC-183518
-  boot.kernelParams = [ "highres=off" "nohz=off" ];
+  boot.kernelParams = [
+    "highres=off"
+    "nohz=off"
+  ];
 
   networking = {
     usePredictableInterfaceNames = false;
diff --git a/configuration/hardware-specific/hetzner/default.nix b/configuration/hardware-specific/hetzner/default.nix
index 3106f19..6795377 100644
--- a/configuration/hardware-specific/hetzner/default.nix
+++ b/configuration/hardware-specific/hetzner/default.nix
@@ -25,9 +25,7 @@
         };
       }
       # IPv6
-      {
-        addressConfig.Address = "2a01:4f8:10b:3c85::2/64";
-      }
+      { addressConfig.Address = "2a01:4f8:10b:3c85::2/64"; }
     ];
 
     networkConfig = {
diff --git a/configuration/hardware-specific/hetzner/disko.nix b/configuration/hardware-specific/hetzner/disko.nix
index a2ea764..cc15471 100644
--- a/configuration/hardware-specific/hetzner/disko.nix
+++ b/configuration/hardware-specific/hetzner/disko.nix
@@ -19,7 +19,10 @@
         };
       };
 
-      mountOptions = [ "compress=zstd" "noatime" ];
+      mountOptions = [
+        "compress=zstd"
+        "noatime"
+      ];
     in
     {
       sda = {
@@ -54,7 +57,15 @@
                 type = "btrfs";
                 # Hack to get multi-device btrfs going
                 # See https://github.com/nix-community/disko/issues/99
-                extraArgs = [ "-d" "raid1" "-m" "raid1" "--runtime-features" "quota" "/dev/sda3" ];
+                extraArgs = [
+                  "-d"
+                  "raid1"
+                  "-m"
+                  "raid1"
+                  "--runtime-features"
+                  "quota"
+                  "/dev/sda3"
+                ];
                 subvolumes = {
                   "/volume" = { };
                   "/volume/root" = {
diff --git a/configuration/hardware-specific/vm.nix b/configuration/hardware-specific/vm.nix
index 86fcaed..1783956 100644
--- a/configuration/hardware-specific/vm.nix
+++ b/configuration/hardware-specific/vm.nix
@@ -1,4 +1,5 @@
-{ lib, ... }: {
+{ lib, ... }:
+{
   users.users.tlater.password = "insecure";
 
   # Disable graphical tty so -curses works
diff --git a/configuration/nginx.nix b/configuration/nginx.nix
index d696bba..b38118b 100644
--- a/configuration/nginx.nix
+++ b/configuration/nginx.nix
@@ -1,7 +1,5 @@
-{ config
-, lib
-, ...
-}: {
+{ config, lib, ... }:
+{
   services.nginx = {
     enable = true;
     recommendedTlsSettings = true;
@@ -26,26 +24,23 @@
       # Override the default, just keep fewer logs
       nginx.rotate = 6;
     }
-    // lib.mapAttrs'
-      (virtualHost: _:
-        lib.nameValuePair "/var/log/nginx/${virtualHost}/access.log" {
-          frequency = "daily";
-          rotate = 2;
-          compress = true;
-          delaycompress = true;
-          su = "${config.services.nginx.user} ${config.services.nginx.group}";
-          postrotate = "[ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`";
-        })
-      config.services.nginx.virtualHosts;
+    // lib.mapAttrs' (
+      virtualHost: _:
+      lib.nameValuePair "/var/log/nginx/${virtualHost}/access.log" {
+        frequency = "daily";
+        rotate = 2;
+        compress = true;
+        delaycompress = true;
+        su = "${config.services.nginx.user} ${config.services.nginx.group}";
+        postrotate = "[ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`";
+      }
+    ) config.services.nginx.virtualHosts;
 
-  systemd.tmpfiles.rules =
-    lib.mapAttrsToList
-      (
-        virtualHost: _:
-          #
-          "d /var/log/nginx/${virtualHost} 0750 ${config.services.nginx.user} ${config.services.nginx.group}"
-      )
-      config.services.nginx.virtualHosts;
+  systemd.tmpfiles.rules = lib.mapAttrsToList (
+    virtualHost: _:
+    #
+    "d /var/log/nginx/${virtualHost} 0750 ${config.services.nginx.user} ${config.services.nginx.group}"
+  ) config.services.nginx.virtualHosts;
 
   security.acme = {
     defaults.email = "tm@tlater.net";
@@ -61,8 +56,8 @@
 
   services.backups.acme = {
     user = "acme";
-    paths =
-      lib.mapAttrsToList (virtualHost: _: "/var/lib/acme/${virtualHost}")
-        config.services.nginx.virtualHosts;
+    paths = lib.mapAttrsToList (
+      virtualHost: _: "/var/lib/acme/${virtualHost}"
+    ) config.services.nginx.virtualHosts;
   };
 }
diff --git a/configuration/services/afvalcalendar.nix b/configuration/services/afvalcalendar.nix
index 28e3a75..ec7d9f7 100644
--- a/configuration/services/afvalcalendar.nix
+++ b/configuration/services/afvalcalendar.nix
@@ -1,7 +1,5 @@
-{ pkgs
-, config
-, ...
-}: {
+{ pkgs, config, ... }:
+{
   systemd.services.afvalcalendar = {
     description = "Enschede afvalcalendar -> ical converter";
     wantedBy = [ "multi-user.target" ];
@@ -25,16 +23,23 @@
       ProtectKernelModules = true;
       ProtectKernelLogs = true;
       ProtectControlGroups = true;
-      RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
+      RestrictAddressFamilies = [
+        "AF_UNIX"
+        "AF_INET"
+        "AF_INET6"
+      ];
       RestrictNamespaces = true;
       LockPersonality = true;
       MemoryDenyWriteExecute = true;
       RestrictRealtime = true;
       RestrictSUIDSGID = true;
       SystemCallArchitectures = "native";
-      SystemCallFilter = [ "@system-service" "~@privileged @resources @setuid @keyring" ];
+      SystemCallFilter = [
+        "@system-service"
+        "~@privileged @resources @setuid @keyring"
+      ];
 
-      Umask = 0002;
+      Umask = 2;
       SupplementaryGroups = "afvalcalendar-hosting";
 
       ReadWritePaths = "/srv/afvalcalendar";
diff --git a/configuration/services/backups.nix b/configuration/services/backups.nix
index 7c77399..81e3554 100644
--- a/configuration/services/backups.nix
+++ b/configuration/services/backups.nix
@@ -1,29 +1,35 @@
-{ config
-, pkgs
-, lib
-, ...
+{
+  config,
+  pkgs,
+  lib,
+  ...
 }:
 let
   inherit (lib) types optional singleton;
-  mkShutdownScript = service:
+  mkShutdownScript =
+    service:
     pkgs.writeShellScript "backup-${service}-shutdown" ''
       if systemctl is-active --quiet '${service}'; then
         touch '/tmp/${service}-was-active'
         systemctl stop '${service}'
       fi
     '';
-  mkRestartScript = service:
+  mkRestartScript =
+    service:
     pkgs.writeShellScript "backup-${service}-restart" ''
       if [ -f '/tmp/${service}-was-active' ]; then
         rm '/tmp/${service}-was-active'
         systemctl start '${service}'
       fi
     '';
-  writeScript = name: packages: text:
-    lib.getExe (pkgs.writeShellApplication {
-      inherit name text;
-      runtimeInputs = packages;
-    });
+  writeScript =
+    name: packages: text:
+    lib.getExe (
+      pkgs.writeShellApplication {
+        inherit name text;
+        runtimeInputs = packages;
+      }
+    );
 
   # *NOT* a TOML file, for some reason quotes are interpreted
   # *literally
@@ -49,85 +55,87 @@ in
       description = lib.mdDoc ''
         Configure restic backups with a specific tag.
       '';
-      type = types.attrsOf (types.submodule ({ config
-                                             , name
-                                             , ...
-                                             }: {
-        options = {
-          user = lib.mkOption {
-            type = types.str;
-            description = ''
-              The user as which to run the backup.
-            '';
-          };
-          paths = lib.mkOption {
-            type = types.listOf types.str;
-            description = ''
-              The paths to back up.
-            '';
-          };
-          tag = lib.mkOption {
-            type = types.str;
-            description = ''
-              The restic tag to mark the backup with.
-            '';
-            default = name;
-          };
-          preparation = {
-            packages = lib.mkOption {
-              type = types.listOf types.package;
-              default = [ ];
-              description = ''
-                The list of packages to make available in the
-                preparation script.
-              '';
-            };
-            text = lib.mkOption {
-              type = types.nullOr types.str;
-              default = null;
-              description = ''
-                The preparation script to run before the backup.
+      type = types.attrsOf (
+        types.submodule (
+          { config, name, ... }:
+          {
+            options = {
+              user = lib.mkOption {
+                type = types.str;
+                description = ''
+                  The user as which to run the backup.
+                '';
+              };
+              paths = lib.mkOption {
+                type = types.listOf types.str;
+                description = ''
+                  The paths to back up.
+                '';
+              };
+              tag = lib.mkOption {
+                type = types.str;
+                description = ''
+                  The restic tag to mark the backup with.
+                '';
+                default = name;
+              };
+              preparation = {
+                packages = lib.mkOption {
+                  type = types.listOf types.package;
+                  default = [ ];
+                  description = ''
+                    The list of packages to make available in the
+                    preparation script.
+                  '';
+                };
+                text = lib.mkOption {
+                  type = types.nullOr types.str;
+                  default = null;
+                  description = ''
+                    The preparation script to run before the backup.
 
-                This should include things like database dumps and
-                enabling maintenance modes. If a service needs to be
-                shut down for backups, use `pauseServices` instead.
-              '';
-            };
-          };
-          cleanup = {
-            packages = lib.mkOption {
-              type = types.listOf types.package;
-              default = [ ];
-              description = ''
-                The list of packages to make available in the
-                cleanup script.
-              '';
-            };
-            text = lib.mkOption {
-              type = types.nullOr types.str;
-              default = null;
-              description = ''
-                The cleanup script to run after the backup.
+                    This should include things like database dumps and
+                    enabling maintenance modes. If a service needs to be
+                    shut down for backups, use `pauseServices` instead.
+                  '';
+                };
+              };
+              cleanup = {
+                packages = lib.mkOption {
+                  type = types.listOf types.package;
+                  default = [ ];
+                  description = ''
+                    The list of packages to make available in the
+                    cleanup script.
+                  '';
+                };
+                text = lib.mkOption {
+                  type = types.nullOr types.str;
+                  default = null;
+                  description = ''
+                    The cleanup script to run after the backup.
 
-                This should do things like cleaning up database dumps
-                and disabling maintenance modes.
-              '';
-            };
-          };
-          pauseServices = lib.mkOption {
-            type = types.listOf types.str;
-            default = [ ];
-            description = ''
-              The systemd services that need to be shut down before
-              the backup can run. Services will be restarted after the
-              backup is complete.
+                    This should do things like cleaning up database dumps
+                    and disabling maintenance modes.
+                  '';
+                };
+              };
+              pauseServices = lib.mkOption {
+                type = types.listOf types.str;
+                default = [ ];
+                description = ''
+                  The systemd services that need to be shut down before
+                  the backup can run. Services will be restarted after the
+                  backup is complete.
 
-              This is intended to be used for services that do not
-              support hot backups.
-            '';
-          };
-        };
-      }));
+                  This is intended to be used for services that do not
+                  support hot backups.
+                '';
+              };
+            };
+          }
+        )
+      );
     };
   };
 
@@ -164,58 +172,68 @@ in
           };
         };
       }
-      // lib.mapAttrs'
-        (name: backup:
-          lib.nameValuePair "backup-${name}" {
-            # Don't want to restart mid-backup
-            restartIfChanged = false;
+      // lib.mapAttrs' (
+        name: backup:
+        lib.nameValuePair "backup-${name}" {
+          # Don't want to restart mid-backup
+          restartIfChanged = false;
 
-            environment =
-              resticEnv
-              // {
-                RESTIC_CACHE_DIR = "%C/backup-${name}";
-              };
+          environment = resticEnv // {
+            RESTIC_CACHE_DIR = "%C/backup-${name}";
+          };
 
-            path = with pkgs; [
-              coreutils
-              openssh
-              rclone
-              restic
+          path = with pkgs; [
+            coreutils
+            openssh
+            rclone
+            restic
+          ];
+
+          # TODO(tlater): If I ever add more than one repo, service
+          # shutdown/restarting will potentially break if multiple
+          # backups for the same service overlap. A more clever
+          # sentinel file with reference counts would probably solve
+          # this.
+          serviceConfig = {
+            User = backup.user;
+            Group = "backup";
+            RuntimeDirectory = "backup-${name}";
+            CacheDirectory = "backup-${name}";
+            CacheDirectoryMode = "0700";
+            PrivateTmp = true;
+
+            ExecStart = [
+              (lib.concatStringsSep " " (
+                [
+                  "${pkgs.restic}/bin/restic"
+                  "backup"
+                  "--tag"
+                  name
+                ]
+                ++ backup.paths
+              ))
             ];
 
-            # TODO(tlater): If I ever add more than one repo, service
-            # shutdown/restarting will potentially break if multiple
-            # backups for the same service overlap. A more clever
-            # sentinel file with reference counts would probably solve
-            # this.
-            serviceConfig = {
-              User = backup.user;
-              Group = "backup";
-              RuntimeDirectory = "backup-${name}";
-              CacheDirectory = "backup-${name}";
-              CacheDirectoryMode = "0700";
-              PrivateTmp = true;
-
-              ExecStart = [
-                (lib.concatStringsSep " " ([ "${pkgs.restic}/bin/restic" "backup" "--tag" name ] ++ backup.paths))
-              ];
-
-              ExecStartPre =
-                map (service: "+${mkShutdownScript service}") backup.pauseServices
-                ++ singleton (writeScript "backup-${name}-repo-init" [ ] ''
+            ExecStartPre =
+              map (service: "+${mkShutdownScript service}") backup.pauseServices
+              ++ singleton (
+                writeScript "backup-${name}-repo-init" [ ] ''
                   restic snapshots || restic init
-                '')
-                ++ optional (backup.preparation.text != null)
-                  (writeScript "backup-${name}-prepare" backup.preparation.packages backup.preparation.text);
+                ''
+              )
+              ++ optional (backup.preparation.text != null) (
+                writeScript "backup-${name}-prepare" backup.preparation.packages backup.preparation.text
+              );
 
-              # TODO(tlater): Add repo pruning/checking
-              ExecStopPost =
-                map (service: "+${mkRestartScript service}") backup.pauseServices
-                ++ optional (backup.cleanup.text != null)
-                  (writeScript "backup-${name}-cleanup" backup.cleanup.packages backup.cleanup.text);
-            };
-          })
-        config.services.backups;
+            # TODO(tlater): Add repo pruning/checking
+            ExecStopPost =
+              map (service: "+${mkRestartScript service}") backup.pauseServices
+              ++ optional (backup.cleanup.text != null) (
+                writeScript "backup-${name}-cleanup" backup.cleanup.packages backup.cleanup.text
+              );
+          };
+        }
+      ) config.services.backups;
 
     systemd.timers =
       {
@@ -227,18 +245,18 @@ in
           # of the backup jobs.
         };
       }
-      // lib.mapAttrs'
-        (name: backup:
-          lib.nameValuePair "backup-${name}" {
-            wantedBy = [ "timers.target" ];
-            timerConfig = {
-              OnCalendar = "Wednesday 02:30:00 UTC";
-              RandomizedDelaySec = "1h";
-              FixedRandomDelay = true;
-              Persistent = true;
-            };
-          })
-        config.services.backups;
+      // lib.mapAttrs' (
+        name: backup:
+        lib.nameValuePair "backup-${name}" {
+          wantedBy = [ "timers.target" ];
+          timerConfig = {
+            OnCalendar = "Wednesday 02:30:00 UTC";
+            RandomizedDelaySec = "1h";
+            FixedRandomDelay = true;
+            Persistent = true;
+          };
+        }
+      ) config.services.backups;
 
     users = {
       # This user is only used to own the ssh key, because apparently
diff --git a/configuration/services/battery-manager.nix b/configuration/services/battery-manager.nix
index 7783a3b..a16cca1 100644
--- a/configuration/services/battery-manager.nix
+++ b/configuration/services/battery-manager.nix
@@ -1,10 +1,6 @@
-{ config
-, flake-inputs
-, ...
-}: {
-  imports = [
-    flake-inputs.sonnenshift.nixosModules.default
-  ];
+{ config, flake-inputs, ... }:
+{
+  imports = [ flake-inputs.sonnenshift.nixosModules.default ];
 
   services.batteryManager = {
     enable = true;
diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix
index 8734785..4e53241 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit.nix
@@ -1,7 +1,8 @@
-{ pkgs
-, config
-, lib
-, ...
+{
+  pkgs,
+  config,
+  lib,
+  ...
 }:
 let
   inherit (lib.strings) concatMapStringsSep;
@@ -42,28 +43,30 @@ in
   systemd.services.heisenbridge =
     let
       replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret";
-      registrationFile = builtins.toFile "heisenbridge-registration.yaml" (builtins.toJSON {
-        id = "heisenbridge";
-        url = "http://127.0.0.1:9898";
-        as_token = "@AS_TOKEN@";
-        hs_token = "@HS_TOKEN@";
-        rate_limited = false;
-        sender_localpart = "heisenbridge";
-        namespaces = {
-          users = [
-            {
-              regex = "@irc_.*";
-              exclusive = true;
-            }
-            {
-              regex = "@heisenbridge:.*";
-              exclusive = true;
-            }
-          ];
-          aliases = [ ];
-          rooms = [ ];
-        };
-      });
+      registrationFile = builtins.toFile "heisenbridge-registration.yaml" (
+        builtins.toJSON {
+          id = "heisenbridge";
+          url = "http://127.0.0.1:9898";
+          as_token = "@AS_TOKEN@";
+          hs_token = "@HS_TOKEN@";
+          rate_limited = false;
+          sender_localpart = "heisenbridge";
+          namespaces = {
+            users = [
+              {
+                regex = "@irc_.*";
+                exclusive = true;
+              }
+              {
+                regex = "@heisenbridge:.*";
+                exclusive = true;
+              }
+            ];
+            aliases = [ ];
+            rooms = [ ];
+          };
+        }
+      );
 
       # TODO(tlater): Starting with systemd 253 it will become possible
       # to do the credential setup as part of ExecStartPre/preStart
@@ -114,7 +117,7 @@ in
         RestrictRealtime = true;
         ProtectProc = "invisible";
         ProcSubset = "pid";
-        UMask = 0077;
+        UMask = 77;
 
         # For the identd port
         # CapabilityBoundingSet = ["CAP_NET_BIND_SERVICE"];
@@ -134,9 +137,7 @@ in
     use-auth-secret = true;
     static-auth-secret-file = config.sops.secrets."turn/secret".path;
     realm = turn-realm;
-    relay-ips = [
-      "116.202.158.55"
-    ];
+    relay-ips = [ "116.202.158.55" ];
 
     # SSL config
     #
@@ -245,9 +246,7 @@ in
 
   services.backups.conduit = {
     user = "root";
-    paths = [
-      "/var/lib/private/matrix-conduit/"
-    ];
+    paths = [ "/var/lib/private/matrix-conduit/" ];
     # Other services store their data in conduit, so no other services
     # need to be shut down currently.
     pauseServices = [ "conduit.service" ];
diff --git a/configuration/services/fail2ban.nix b/configuration/services/fail2ban.nix
index 1811046..f09668c 100644
--- a/configuration/services/fail2ban.nix
+++ b/configuration/services/fail2ban.nix
@@ -1,4 +1,5 @@
-{ pkgs, ... }: {
+{ pkgs, ... }:
+{
   services.fail2ban = {
     enable = true;
     extraPackages = [ pkgs.ipset ];
diff --git a/configuration/services/foundryvtt.nix b/configuration/services/foundryvtt.nix
index 3383ab3..614b818 100644
--- a/configuration/services/foundryvtt.nix
+++ b/configuration/services/foundryvtt.nix
@@ -1,8 +1,9 @@
-{ lib
-, config
-, flake-inputs
-, pkgs
-, ...
+{
+  lib,
+  config,
+  flake-inputs,
+  pkgs,
+  ...
 }:
 let
   domain = "foundryvtt.${config.services.nginx.domain}";
@@ -40,9 +41,7 @@ in
 
   services.backups.foundryvtt = {
     user = "foundryvtt";
-    paths = [
-      config.services.foundryvtt.dataDir
-    ];
+    paths = [ config.services.foundryvtt.dataDir ];
     pauseServices = [ "foundryvtt.service" ];
   };
 }
diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index 4ef6238..c88dd01 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -1,7 +1,8 @@
-{ pkgs
-, config
-, lib
-, ...
+{
+  pkgs,
+  config,
+  lib,
+  ...
 }:
 let
   domain = "gitea.${config.services.nginx.domain}";
@@ -34,9 +35,7 @@ in
       secretPath = config.sops.secrets."forgejo/metrics-token".path;
       runConfig = "${config.services.forgejo.customDir}/conf/app.ini";
     in
-    [
-      "+${replaceSecretBin} '#metricstoken#' '${secretPath}' '${runConfig}'"
-    ];
+    [ "+${replaceSecretBin} '#metricstoken#' '${secretPath}' '${runConfig}'" ];
 
   # Set up SSL
   services.nginx.virtualHosts."${domain}" =
diff --git a/configuration/services/metrics/exporters.nix b/configuration/services/metrics/exporters.nix
index e17be8e..e16b945 100644
--- a/configuration/services/metrics/exporters.nix
+++ b/configuration/services/metrics/exporters.nix
@@ -1,7 +1,8 @@
-{ config
-, pkgs
-, lib
-, ...
+{
+  config,
+  pkgs,
+  lib,
+  ...
 }:
 let
   yaml = pkgs.formats.yaml { };
@@ -20,9 +21,7 @@ in
               "tlater.com"
             ];
           in
-          [
-            "--config=${yaml.generate "domains.yml" conf}"
-          ];
+          [ "--config=${yaml.generate "domains.yml" conf}" ];
       };
 
       # System statistics
@@ -51,26 +50,21 @@ in
         listenAddress = "127.0.0.1";
         group = "nginx";
 
-        settings.namespaces =
-          lib.mapAttrsToList
-            (name: virtualHost: {
-              inherit name;
-              metrics_override.prefix = "nginxlog";
-              namespace_label = "vhost";
+        settings.namespaces = lib.mapAttrsToList (name: virtualHost: {
+          inherit name;
+          metrics_override.prefix = "nginxlog";
+          namespace_label = "vhost";
 
-              format = lib.concatStringsSep " " [
-                "$remote_addr - $remote_user [$time_local]"
-                ''"$request" $status $body_bytes_sent''
-                ''"$http_referer" "$http_user_agent"''
-                ''rt=$request_time uct="$upstream_connect_time"''
-                ''uht="$upstream_header_time" urt="$upstream_response_time"''
-              ];
+          format = lib.concatStringsSep " " [
+            "$remote_addr - $remote_user [$time_local]"
+            ''"$request" $status $body_bytes_sent''
+            ''"$http_referer" "$http_user_agent"''
+            ''rt=$request_time uct="$upstream_connect_time"''
+            ''uht="$upstream_header_time" urt="$upstream_response_time"''
+          ];
 
-              source.files = [
-                "/var/log/nginx/${name}/access.log"
-              ];
-            })
-            config.services.nginx.virtualHosts;
+          source.files = [ "/var/log/nginx/${name}/access.log" ];
+        }) config.services.nginx.virtualHosts;
       };
     };
 
@@ -86,7 +80,11 @@ in
             requires = [ "fail2ban.service" ];
             serviceConfig = {
               Group = "fail2ban";
-              RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
+              RestrictAddressFamilies = [
+                "AF_UNIX"
+                "AF_INET"
+                "AF_INET6"
+              ];
               ExecStart = lib.concatStringsSep " " [
                 "${pkgs.local.prometheus-fail2ban-exporter}/bin/fail2ban-prometheus-exporter"
                 "--collector.f2b.socket=/var/run/fail2ban/fail2ban.sock"
diff --git a/configuration/services/metrics/options.nix b/configuration/services/metrics/options.nix
index 552aec8..5dd17a3 100644
--- a/configuration/services/metrics/options.nix
+++ b/configuration/services/metrics/options.nix
@@ -1,7 +1,8 @@
-{ pkgs
-, config
-, lib
-, ...
+{
+  pkgs,
+  config,
+  lib,
+  ...
 }:
 let
   inherit (lib) types mkOption mkDefault;
@@ -11,87 +12,94 @@ in
   options = {
     services.prometheus = {
       extraExporters = mkOption {
-        type = types.attrsOf (types.submodule {
-          options = {
-            port = mkOption {
-              type = types.int;
-              description = "The port on which this exporter listens.";
+        type = types.attrsOf (
+          types.submodule {
+            options = {
+              port = mkOption {
+                type = types.int;
+                description = "The port on which this exporter listens.";
+              };
+              listenAddress = mkOption {
+                type = types.str;
+                default = "127.0.0.1";
+                description = "Address to listen on.";
+              };
+              serviceOpts = mkOption {
+                type = types.attrs;
+                description = "An attrset to be merged with the exporter's systemd service.";
+              };
             };
-            listenAddress = mkOption {
-              type = types.str;
-              default = "127.0.0.1";
-              description = "Address to listen on.";
-            };
-            serviceOpts = mkOption {
-              type = types.attrs;
-              description = "An attrset to be merged with the exporter's systemd service.";
-            };
-          };
-        });
+          }
+        );
       };
     };
 
     services.victoriametrics.scrapeConfigs = mkOption {
-      type = types.attrsOf (types.submodule ({ name
-                                             , self
-                                             , ...
-                                             }: {
-        options = {
-          job_name = mkOption {
-            type = types.str;
-            default = name;
-          };
-
-          extraSettings = mkOption {
-            type = types.anything;
-            description = ''
-              Other settings to set for this scrape config.
-            '';
-            default = { };
-          };
-
-          targets = mkOption {
-            type = types.listOf types.str;
-            description = lib.mdDoc ''
-              Addresses scrape targets for this config listen on.
-
-              Shortcut for `static_configs = lib.singleton {targets = [<targets>];}`
-            '';
-            default = [ ];
-          };
-
-          static_configs = mkOption {
-            default = [ ];
-            type = types.listOf (types.submodule {
-              options = {
-                targets = mkOption {
-                  type = types.listOf types.str;
-                  description = lib.mdDoc ''
-                    The addresses scrape targets for this config listen on.
-
-                    Must in `listenAddress:port` format.
-                  '';
-                };
-                labels = mkOption {
-                  type = types.attrsOf types.str;
-                  description = lib.mdDoc ''
-                    Labels to apply to all targets defined for this static config.
-                  '';
-                  default = { };
-                };
+      type = types.attrsOf (
+        types.submodule (
+          { name, self, ... }:
+          {
+            options = {
+              job_name = mkOption {
+                type = types.str;
+                default = name;
               };
-            });
-          };
-        };
-      }));
+
+              extraSettings = mkOption {
+                type = types.anything;
+                description = ''
+                  Other settings to set for this scrape config.
+                '';
+                default = { };
+              };
+
+              targets = mkOption {
+                type = types.listOf types.str;
+                description = lib.mdDoc ''
+                  Addresses scrape targets for this config listen on.
+
+                  Shortcut for `static_configs = lib.singleton {targets = [<targets>];}`
+                '';
+                default = [ ];
+              };
+
+              static_configs = mkOption {
+                default = [ ];
+                type = types.listOf (
+                  types.submodule {
+                    options = {
+                      targets = mkOption {
+                        type = types.listOf types.str;
+                        description = lib.mdDoc ''
+                          The addresses scrape targets for this config listen on.
+
+                          Must in `listenAddress:port` format.
+                        '';
+                      };
+                      labels = mkOption {
+                        type = types.attrsOf types.str;
+                        description = lib.mdDoc ''
+                          Labels to apply to all targets defined for this static config.
+                        '';
+                        default = { };
+                      };
+                    };
+                  }
+                );
+              };
+            };
+          }
+        )
+      );
     };
   };
 
   config = {
     systemd.services = lib.mkMerge [
-      (lib.mapAttrs'
-        (name: exporter:
-          lib.nameValuePair "prometheus-${name}-exporter" (lib.mkMerge [
+      (lib.mapAttrs' (
+        name: exporter:
+        lib.nameValuePair "prometheus-${name}-exporter" (
+          lib.mkMerge [
             {
               # Shamelessly copied from upstream because the upstream
               # module is an intractable mess
@@ -117,7 +125,10 @@ in
               serviceConfig.ProtectKernelTunables = true;
               serviceConfig.ProtectSystem = mkDefault "strict";
               serviceConfig.RemoveIPC = true;
-              serviceConfig.RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
+              serviceConfig.RestrictAddressFamilies = [
+                "AF_INET"
+                "AF_INET6"
+              ];
               serviceConfig.RestrictNamespaces = true;
               serviceConfig.RestrictRealtime = true;
               serviceConfig.RestrictSUIDSGID = true;
@@ -125,8 +136,9 @@ in
               serviceConfig.UMask = "0077";
             }
             exporter.serviceOpts
-          ]))
-        config.services.prometheus.extraExporters)
+          ]
+        )
+      ) config.services.prometheus.extraExporters)
 
       {
         vmagent-scrape-exporters =
@@ -134,24 +146,25 @@ in
             listenAddress = config.services.victoriametrics.listenAddress;
             vmAddr = (lib.optionalString (lib.hasPrefix ":" listenAddress) "127.0.0.1") + listenAddress;
             promscrape = yaml.generate "prometheus.yml" {
-              scrape_configs = lib.mapAttrsToList
-                (_: scrape:
-                  lib.recursiveUpdate
-                    {
-                      inherit (scrape) job_name;
-                      static_configs =
-                        scrape.static_configs
-                        ++ lib.optional (scrape.targets != [ ]) { targets = scrape.targets; };
-                    }
-                    scrape.extraSettings)
-                config.services.victoriametrics.scrapeConfigs;
+              scrape_configs = lib.mapAttrsToList (
+                _: scrape:
+                lib.recursiveUpdate {
+                  inherit (scrape) job_name;
+                  static_configs =
+                    scrape.static_configs
+                    ++ lib.optional (scrape.targets != [ ]) { targets = scrape.targets; };
+                } scrape.extraSettings
+              ) config.services.victoriametrics.scrapeConfigs;
             };
           in
           {
             enable = true;
             path = [ pkgs.victoriametrics ];
             wantedBy = [ "multi-user.target" ];
-            after = [ "network.target" "victoriametrics.service" ];
+            after = [
+              "network.target"
+              "victoriametrics.service"
+            ];
             serviceConfig = {
               ExecStart = [
                 (lib.concatStringsSep " " [
@@ -180,7 +193,10 @@ in
               ProtectKernelTunables = true;
               ProtectSystem = "strict";
               RemoveIPC = true;
-              RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
+              RestrictAddressFamilies = [
+                "AF_INET"
+                "AF_INET6"
+              ];
               RestrictNamespaces = true;
               RestrictRealtime = true;
               RestrictSUIDSGID = true;
@@ -195,19 +211,15 @@ in
 
     services.victoriametrics.scrapeConfigs =
       let
-        allExporters =
-          lib.mapAttrs
-            (name: exporter: {
-              inherit (exporter) listenAddress port;
-            })
-            ((lib.filterAttrs (_: exporter: builtins.isAttrs exporter && exporter.enable)
-              config.services.prometheus.exporters)
-            // config.services.prometheus.extraExporters);
+        allExporters = lib.mapAttrs (name: exporter: { inherit (exporter) listenAddress port; }) (
+          (lib.filterAttrs (
+            _: exporter: builtins.isAttrs exporter && exporter.enable
+          ) config.services.prometheus.exporters)
+          // config.services.prometheus.extraExporters
+        );
       in
-      lib.mapAttrs
-        (_: exporter: {
-          targets = [ "${exporter.listenAddress}:${toString exporter.port}" ];
-        })
-        allExporters;
+      lib.mapAttrs (_: exporter: {
+        targets = [ "${exporter.listenAddress}:${toString exporter.port}" ];
+      }) allExporters;
   };
 }
diff --git a/configuration/services/metrics/victoriametrics.nix b/configuration/services/metrics/victoriametrics.nix
index 695b89e..710cf70 100644
--- a/configuration/services/metrics/victoriametrics.nix
+++ b/configuration/services/metrics/victoriametrics.nix
@@ -1,9 +1,8 @@
-{ config, ... }: {
+{ config, ... }:
+{
   config.services.victoriametrics = {
     enable = true;
-    extraOptions = [
-      "-storage.minFreeDiskSpaceBytes=5GB"
-    ];
+    extraOptions = [ "-storage.minFreeDiskSpaceBytes=5GB" ];
 
     scrapeConfigs = {
       forgejo = {
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 30adf6e..63c7446 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -1,7 +1,8 @@
-{ pkgs
-, config
-, lib
-, ...
+{
+  pkgs,
+  config,
+  lib,
+  ...
 }:
 let
   # Update pending on rewrite of nextcloud news, though there is an
@@ -15,8 +16,8 @@ in
     inherit hostName;
 
     package = nextcloud;
-    phpPackage = lib.mkForce
-      (pkgs.php.override {
+    phpPackage = lib.mkForce (
+      pkgs.php.override {
         packageOverrides = final: prev: {
           extensions = prev.extensions // {
             pgsql = prev.extensions.pgsql.overrideAttrs (old: {
@@ -27,7 +28,8 @@ in
             });
           };
         };
-      });
+      }
+    );
     enable = true;
     maxUploadSize = "2G";
     https = true;
@@ -52,7 +54,14 @@ in
     };
 
     extraApps = {
-      inherit (pkgs.local) bookmarks calendar contacts cookbook news notes;
+      inherit (pkgs.local)
+        bookmarks
+        calendar
+        contacts
+        cookbook
+        news
+        notes
+        ;
     };
   };
 
diff --git a/configuration/services/postgres.nix b/configuration/services/postgres.nix
index 62dfb01..85a6843 100644
--- a/configuration/services/postgres.nix
+++ b/configuration/services/postgres.nix
@@ -1,4 +1,5 @@
-{ pkgs, ... }: {
+{ pkgs, ... }:
+{
   services.postgresql = {
     package = pkgs.postgresql_14;
     enable = true;
diff --git a/configuration/services/starbound.nix b/configuration/services/starbound.nix
index 3b54ee9..f5b23c3 100644
--- a/configuration/services/starbound.nix
+++ b/configuration/services/starbound.nix
@@ -1,7 +1,4 @@
-{ pkgs
-, lib
-, ...
-}:
+{ pkgs, lib, ... }:
 let
   inherit (lib) concatStringsSep;
 in
@@ -114,9 +111,7 @@ in
 
   services.backups.starbound = {
     user = "root";
-    paths = [
-      "/var/lib/private/starbound/storage/universe/"
-    ];
+    paths = [ "/var/lib/private/starbound/storage/universe/" ];
     pauseServices = [ "starbound.service" ];
   };
 }
diff --git a/configuration/services/wireguard.nix b/configuration/services/wireguard.nix
index 057a2e9..6f8f6a2 100644
--- a/configuration/services/wireguard.nix
+++ b/configuration/services/wireguard.nix
@@ -1,4 +1,5 @@
-{ config, ... }: {
+{ config, ... }:
+{
   # iptables needs to permit forwarding from wg0 to wg0
   networking.firewall.extraCommands = ''
     iptables -A FORWARD -i wg0 -o wg0 -j ACCEPT
diff --git a/flake.nix b/flake.nix
index 56f3972..6dbbaa5 100644
--- a/flake.nix
+++ b/flake.nix
@@ -33,13 +33,14 @@
   };
 
   outputs =
-    { self
-    , nixpkgs
-    , sops-nix
-    , nvfetcher
-    , deploy-rs
-    , ...
-    } @ inputs:
+    {
+      self,
+      nixpkgs,
+      sops-nix,
+      nvfetcher,
+      deploy-rs,
+      ...
+    }@inputs:
     let
       system = "x86_64-linux";
       pkgs = nixpkgs.legacyPackages.${system};
@@ -84,7 +85,12 @@
           };
 
           sshUser = "tlater";
-          sshOpts = [ "-p" "2222" "-o" "ForwardAgent=yes" ];
+          sshOpts = [
+            "-p"
+            "2222"
+            "-o"
+            "ForwardAgent=yes"
+          ];
         };
       };
 
@@ -144,10 +150,11 @@
       # Development environment #
       ###########################
       devShells.${system}.default = nixpkgs.legacyPackages.${system}.mkShell {
-        sopsPGPKeyDirs = [ "./keys/hosts/" "./keys/users/" ];
-        nativeBuildInputs = [
-          sops-nix.packages.${system}.sops-import-keys-hook
+        sopsPGPKeyDirs = [
+          "./keys/hosts/"
+          "./keys/users/"
         ];
+        nativeBuildInputs = [ sops-nix.packages.${system}.sops-import-keys-hook ];
 
         packages = with pkgs; [
           sops-nix.packages.${system}.sops-init-gpg-key
diff --git a/modules/default.nix b/modules/default.nix
index 9341a5a..e1db4cc 100644
--- a/modules/default.nix
+++ b/modules/default.nix
@@ -1,5 +1 @@
-{
-  imports = [
-    ./nginxExtensions.nix
-  ];
-}
+{ imports = [ ./nginxExtensions.nix ]; }
diff --git a/modules/nginxExtensions.nix b/modules/nginxExtensions.nix
index 3603756..bd505d3 100644
--- a/modules/nginxExtensions.nix
+++ b/modules/nginxExtensions.nix
@@ -1,8 +1,10 @@
-{ config
-, pkgs
-, lib
-, ...
-}: {
+{
+  config,
+  pkgs,
+  lib,
+  ...
+}:
+{
   options = {
     services.nginx.domain = lib.mkOption {
       type = lib.types.str;
@@ -12,10 +14,8 @@
     services.nginx.virtualHosts =
       let
         extraVirtualHostOptions =
-          { name
-          , config
-          , ...
-          }: {
+          { name, config, ... }:
+          {
             options = {
               enableHSTS = lib.mkEnableOption "Enable HSTS";
 
@@ -40,9 +40,7 @@
             };
           };
       in
-      lib.mkOption {
-        type = lib.types.attrsOf (lib.types.submodule extraVirtualHostOptions);
-      };
+      lib.mkOption { type = lib.types.attrsOf (lib.types.submodule extraVirtualHostOptions); };
   };
 
   config = {
@@ -51,11 +49,11 @@
       let
         confirm = ''[[ "tlater.net" = ${config.services.nginx.domain} ]]'';
       in
-      lib.mapAttrs'
-        (cert: _:
-          lib.nameValuePair "acme-${cert}" {
-            serviceConfig.ExecCondition = ''${pkgs.runtimeShell} -c '${confirm}' '';
-          })
-        config.security.acme.certs;
+      lib.mapAttrs' (
+        cert: _:
+        lib.nameValuePair "acme-${cert}" {
+          serviceConfig.ExecCondition = ''${pkgs.runtimeShell} -c '${confirm}' '';
+        }
+      ) config.security.acme.certs;
   };
 }
diff --git a/pkgs/afvalcalendar/default.nix b/pkgs/afvalcalendar/default.nix
index 12b868c..6392220 100644
--- a/pkgs/afvalcalendar/default.nix
+++ b/pkgs/afvalcalendar/default.nix
@@ -1,19 +1,12 @@
-{ pkgs
-, rustPlatform
-, ...
-}:
+{ pkgs, rustPlatform, ... }:
 rustPlatform.buildRustPackage {
   pname = "afvalcalendar";
   version = "0.1.0";
   src = ./.;
 
-  nativeBuildInputs = with pkgs; [
-    pkg-config
-  ];
+  nativeBuildInputs = with pkgs; [ pkg-config ];
 
-  buildInputs = with pkgs; [
-    openssl
-  ];
+  buildInputs = with pkgs; [ openssl ];
 
   cargoHash = "sha256-JXx6aUKdKbUTBCwlBw5i1hZy8ofCfSrhLCwFzqdA8cI=";
 }
diff --git a/pkgs/default.nix b/pkgs/default.nix
index 132d0f5..a9d7aa1 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -1,7 +1,4 @@
-{ pkgs
-, lib
-,
-}:
+{ pkgs, lib }:
 let
   inherit (builtins) fromJSON mapAttrs readFile;
   inherit (pkgs) callPackage;
@@ -13,7 +10,7 @@ in
   };
   afvalcalendar = callPackage ./afvalcalendar { };
 }
-  // (
+// (
   # Add nextcloud apps
   let
     mkNextcloudApp = pkgs.callPackage ./mkNextcloudApp.nix { };
diff --git a/pkgs/mkNextcloudApp.nix b/pkgs/mkNextcloudApp.nix
index 7453f44..095b0e8 100644
--- a/pkgs/mkNextcloudApp.nix
+++ b/pkgs/mkNextcloudApp.nix
@@ -1,7 +1,5 @@
-{ fetchNextcloudApp
-, lib
-,
-}: source:
+{ fetchNextcloudApp, lib }:
+source:
 fetchNextcloudApp {
   url = source.src.url;
   sha256 = source.src.sha256;
diff --git a/pkgs/prometheus/fail2ban-exporter.nix b/pkgs/prometheus/fail2ban-exporter.nix
index b74e35d..dc22b6c 100644
--- a/pkgs/prometheus/fail2ban-exporter.nix
+++ b/pkgs/prometheus/fail2ban-exporter.nix
@@ -1,7 +1,4 @@
-{ buildGoModule
-, sources
-,
-}:
+{ buildGoModule, sources }:
 buildGoModule {
   inherit (sources.prometheus-fail2ban-exporter) pname src version;
   vendorHash = "sha256-5o8p5p0U/c0WAIV5dACnWA3ThzSh2tt5LIFMb59i9GY=";
diff --git a/pkgs/starbound/default.nix b/pkgs/starbound/default.nix
index a8689f3..26f2184 100644
--- a/pkgs/starbound/default.nix
+++ b/pkgs/starbound/default.nix
@@ -1,19 +1,21 @@
-{ stdenv
-, lib
-, makeWrapper
-, patchelf
-, steamPackages
-, replace-secret
-,
+{
+  stdenv,
+  lib,
+  makeWrapper,
+  patchelf,
+  steamPackages,
+  replace-secret,
 }:
 let
   # Use the directory in which starbound is installed so steamcmd
   # doesn't have to be reinstalled constantly (we're using DynamicUser
   # with StateDirectory to persist this).
-  steamcmd = steamPackages.steamcmd.override {
-    steamRoot = "/var/lib/starbound/.steamcmd";
-  };
-  wrapperPath = lib.makeBinPath [ patchelf steamcmd replace-secret ];
+  steamcmd = steamPackages.steamcmd.override { steamRoot = "/var/lib/starbound/.steamcmd"; };
+  wrapperPath = lib.makeBinPath [
+    patchelf
+    steamcmd
+    replace-secret
+  ];
 in
 stdenv.mkDerivation {
   name = "starbound-update-script";

From d56fad518b0cfd0c2013f0ad50d69a36348d910a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 18 Aug 2024 20:41:58 +0200
Subject: [PATCH 163/212] git: Blame-ignore nixfmt commit

---
 .git-blame-ignore-revs | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index cee878d..df9d62b 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -1,6 +1,9 @@
 # Run this command to always ignore formatting commits in `git blame`
 # git config blame.ignoreRevsFile .git-blame-ignore-revs
 
+# Switch to nixfmt formatting
+04f7a7ef1d38906163afc9cddfa8ce2b0ebf3b45
+
 # Switch to nixpkgs-fmt formatting
 fd138d45e6a2cad89fead6e9f246ba282070d6b7
 

From c4ec382de9fed4afe99d425254d05ae8f7f586e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Thu, 24 Oct 2024 23:02:57 +0200
Subject: [PATCH 164/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'deploy-rs':
    'github:serokell/deploy-rs/3867348fa92bc892eba5d9ddb2d7a97b9e127a8a' (2024-06-12)
  → 'github:serokell/deploy-rs/aa07eb05537d4cd025e2310397a6adcedfe72c76' (2024-09-27)
• Updated input 'disko':
    'github:nix-community/disko/276a0d055a720691912c6a34abb724e395c8e38a' (2024-08-15)
  → 'github:nix-community/disko/09a776702b004fdf9c41a024e1299d575ee18a7d' (2024-10-23)
• Updated input 'foundryvtt':
    'github:reckenrode/nix-foundryvtt/699a175398410688214615a9d977354e9ef98d2d' (2024-08-03)
  → 'github:reckenrode/nix-foundryvtt/bf07f9dd916a97a091f8ab83358c2f295bea9ec9' (2024-09-18)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/1cbd3d585263dc620c483e138d352a39b9f0e3ec' (2024-08-17)
  → 'github:nixos/nixpkgs/00c24c17345ba867086a807a7869b12e05955c81' (2024-10-24)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/abcef4da4ebb72240bddc370a27263627e64877f' (2024-08-18)
  → 'github:nixos/nixpkgs/8b052aac04356e25b6ec1058c86de8792440362d' (2024-10-24)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/be0eec2d27563590194a9206f551a6f73d52fa34' (2024-08-12)
  → 'github:Mic92/sops-nix/78a0e634fc8981d6b564f08b6715c69a755c4c7d' (2024-10-24)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/556533a23879fc7e5f98dd2e0b31a6911a213171' (2024-07-21)
  → 'github:NixOS/nixpkgs/bb8c2cf7ea0dd2e18a52746b2c3a5b0c73b93c22' (2024-10-19)
---
 flake.lock | 42 +++++++++++++++++++++---------------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/flake.lock b/flake.lock
index 78327bf..61d58f4 100644
--- a/flake.lock
+++ b/flake.lock
@@ -7,11 +7,11 @@
         "utils": "utils"
       },
       "locked": {
-        "lastModified": 1718194053,
-        "narHash": "sha256-FaGrf7qwZ99ehPJCAwgvNY5sLCqQ3GDiE/6uLhxxwSY=",
+        "lastModified": 1727447169,
+        "narHash": "sha256-3KyjMPUKHkiWhwR91J1YchF6zb6gvckCAY1jOE+ne0U=",
         "owner": "serokell",
         "repo": "deploy-rs",
-        "rev": "3867348fa92bc892eba5d9ddb2d7a97b9e127a8a",
+        "rev": "aa07eb05537d4cd025e2310397a6adcedfe72c76",
         "type": "github"
       },
       "original": {
@@ -27,11 +27,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1723685519,
-        "narHash": "sha256-GkXQIoZmW2zCPp1YFtAYGg/xHNyFH/Mgm79lcs81rq0=",
+        "lastModified": 1729712798,
+        "narHash": "sha256-a+Aakkb+amHw4biOZ0iMo8xYl37uUL48YEXIC5PYJ/8=",
         "owner": "nix-community",
         "repo": "disko",
-        "rev": "276a0d055a720691912c6a34abb724e395c8e38a",
+        "rev": "09a776702b004fdf9c41a024e1299d575ee18a7d",
         "type": "github"
       },
       "original": {
@@ -157,11 +157,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1722661736,
-        "narHash": "sha256-0lujsK40JV/2PlqCjhZMGpHKL4vDKzJcnkFJYnG1WZA=",
+        "lastModified": 1726638033,
+        "narHash": "sha256-+hcgXKG5t/9wibv+8T9WASWItBAWb0tsmcZXH+VIYdw=",
         "owner": "reckenrode",
         "repo": "nix-foundryvtt",
-        "rev": "699a175398410688214615a9d977354e9ef98d2d",
+        "rev": "bf07f9dd916a97a091f8ab83358c2f295bea9ec9",
         "type": "github"
       },
       "original": {
@@ -210,11 +210,11 @@
     },
     "nixpkgs-stable": {
       "locked": {
-        "lastModified": 1721524707,
-        "narHash": "sha256-5NctRsoE54N86nWd0psae70YSLfrOek3Kv1e8KoXe/0=",
+        "lastModified": 1729357638,
+        "narHash": "sha256-66RHecx+zohbZwJVEPF7uuwHeqf8rykZTMCTqIrOew4=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "556533a23879fc7e5f98dd2e0b31a6911a213171",
+        "rev": "bb8c2cf7ea0dd2e18a52746b2c3a5b0c73b93c22",
         "type": "github"
       },
       "original": {
@@ -226,11 +226,11 @@
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1723957280,
-        "narHash": "sha256-J08Yqf2IJ73y7myI69qEKsQ048ibweG6FeJeCxbIdB4=",
+        "lastModified": 1729766066,
+        "narHash": "sha256-QLeNRaGsoIFfv2Kfd4rw2l1TTDb1i4gQzvClSmrk1l4=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "abcef4da4ebb72240bddc370a27263627e64877f",
+        "rev": "8b052aac04356e25b6ec1058c86de8792440362d",
         "type": "github"
       },
       "original": {
@@ -242,11 +242,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1723920526,
-        "narHash": "sha256-USs6A60raDKZ/8BEpqja1XjZIsRzADX+NtWKH6wIxIw=",
+        "lastModified": 1729762315,
+        "narHash": "sha256-l0HyBdB2drPowQm044HDWqMLWwf818G38flxL0bhwqU=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "1cbd3d585263dc620c483e138d352a39b9f0e3ec",
+        "rev": "00c24c17345ba867086a807a7869b12e05955c81",
         "type": "github"
       },
       "original": {
@@ -442,11 +442,11 @@
         "nixpkgs-stable": "nixpkgs-stable"
       },
       "locked": {
-        "lastModified": 1723501126,
-        "narHash": "sha256-N9IcHgj/p1+2Pvk8P4Zc1bfrMwld5PcosVA0nL6IGdE=",
+        "lastModified": 1729775275,
+        "narHash": "sha256-J2vtHq9sw1wWm0aTMXpEEAzsVCUMZDTEe5kiBYccpLE=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "be0eec2d27563590194a9206f551a6f73d52fa34",
+        "rev": "78a0e634fc8981d6b564f08b6715c69a755c4c7d",
         "type": "github"
       },
       "original": {

From cbbe555f075ddace197e563c40628c8a32cd50d3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 25 Oct 2024 00:17:29 +0200
Subject: [PATCH 165/212] bump: Update nextcloud

---
 configuration/services/nextcloud.nix   |  5 +----
 pkgs/_sources_nextcloud/generated.json | 30 +++++++++++++-------------
 pkgs/_sources_nextcloud/generated.nix  | 30 +++++++++++++-------------
 pkgs/nextcloud-apps.toml               | 10 +++++----
 4 files changed, 37 insertions(+), 38 deletions(-)

diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 63c7446..205d702 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -5,10 +5,7 @@
   ...
 }:
 let
-  # Update pending on rewrite of nextcloud news, though there is an
-  # alpha to switch to if it becomes necessary:
-  # https://github.com/nextcloud/news/issues/2610
-  nextcloud = pkgs.nextcloud28;
+  nextcloud = pkgs.nextcloud29;
   hostName = "nextcloud.${config.services.nginx.domain}";
 in
 {
diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
index 4071726..1c553ce 100644
--- a/pkgs/_sources_nextcloud/generated.json
+++ b/pkgs/_sources_nextcloud/generated.json
@@ -7,11 +7,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-V4zZsAwPn8QiCXEDqOgNFHaXqMOcHMpMbJ1Oz3Db0pc=",
+            "sha256": "sha256-7BTNFsNcqmDACpj5PMEiS71xtr50v7Sqo3qeCL+3J9s=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/bookmarks/releases/download/v14.2.4/bookmarks-14.2.4.tar.gz"
+            "url": "https://github.com/nextcloud/bookmarks/releases/download/v14.2.6/bookmarks-14.2.6.tar.gz"
         },
-        "version": "14.2.4"
+        "version": "14.2.6"
     },
     "calendar": {
         "cargoLocks": null,
@@ -21,11 +21,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-sipXeyOL4OhENz7V2beFeSYBAoFZdCWtqftIy0lsqEY=",
+            "sha256": "sha256-X2XcH7HpxgizCEJVrazGtzNQTBihFxvTq/ybK939cxo=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.7.15/calendar-v4.7.15.tar.gz"
+            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.7.16/calendar-v4.7.16.tar.gz"
         },
-        "version": "v4.7.15"
+        "version": "v4.7.16"
     },
     "contacts": {
         "cargoLocks": null,
@@ -49,11 +49,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-a8ekMnEzudHGiqHF53jPtgsVTOTc2QLuPg6YtTw5h68=",
+            "sha256": "sha256-Pfa+Xbopg20os+pnGgg+wpEX1MI5fz5JMb0K4a8rBhs=",
             "type": "tarball",
-            "url": "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.11.1/Cookbook-0.11.1.tar.gz"
+            "url": "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.11.2/Cookbook-0.11.2.tar.gz"
         },
-        "version": "0.11.1"
+        "version": "0.11.2"
     },
     "news": {
         "cargoLocks": null,
@@ -63,11 +63,11 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-AhTZGQCLeNgsRBF5w3+Lf9JtNN4D1QncB5t+odU+XUc=",
+            "sha256": "sha256-pnvyMZQ+NYMgH0Unfh5S19HdZSjnghgoUDAoi2KIXNI=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud/news/releases/download/25.0.0-alpha8/news.tar.gz"
+            "url": "https://github.com/nextcloud/news/releases/download/25.0.0-alpha12/news.tar.gz"
         },
-        "version": "25.0.0-alpha8"
+        "version": "25.0.0-alpha12"
     },
     "notes": {
         "cargoLocks": null,
@@ -77,10 +77,10 @@
         "passthru": null,
         "pinned": false,
         "src": {
-            "sha256": "sha256-A3QNWGWeC2OcZngMrh9NpYbU5qp5x9xiDcRfB9cRXBo=",
+            "sha256": "sha256-Cu73H0hJREbkskLbj56M8qUF1Tp4EazORlCF9rpPL90=",
             "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/notes/releases/download/v4.10.1/notes-v4.10.1.tar.gz"
+            "url": "https://github.com/nextcloud-releases/notes/releases/download/v4.11.0/notes-v4.11.0.tar.gz"
         },
-        "version": "v4.10.1"
+        "version": "v4.11.0"
     }
 }
\ No newline at end of file
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
index 53e26d1..da275cc 100644
--- a/pkgs/_sources_nextcloud/generated.nix
+++ b/pkgs/_sources_nextcloud/generated.nix
@@ -3,18 +3,18 @@
 {
   bookmarks = {
     pname = "bookmarks";
-    version = "14.2.4";
+    version = "14.2.6";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/bookmarks/releases/download/v14.2.4/bookmarks-14.2.4.tar.gz";
-      sha256 = "sha256-V4zZsAwPn8QiCXEDqOgNFHaXqMOcHMpMbJ1Oz3Db0pc=";
+      url = "https://github.com/nextcloud/bookmarks/releases/download/v14.2.6/bookmarks-14.2.6.tar.gz";
+      sha256 = "sha256-7BTNFsNcqmDACpj5PMEiS71xtr50v7Sqo3qeCL+3J9s=";
     };
   };
   calendar = {
     pname = "calendar";
-    version = "v4.7.15";
+    version = "v4.7.16";
     src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.7.15/calendar-v4.7.15.tar.gz";
-      sha256 = "sha256-sipXeyOL4OhENz7V2beFeSYBAoFZdCWtqftIy0lsqEY=";
+      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.7.16/calendar-v4.7.16.tar.gz";
+      sha256 = "sha256-X2XcH7HpxgizCEJVrazGtzNQTBihFxvTq/ybK939cxo=";
     };
   };
   contacts = {
@@ -27,26 +27,26 @@
   };
   cookbook = {
     pname = "cookbook";
-    version = "0.11.1";
+    version = "0.11.2";
     src = fetchTarball {
-      url = "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.11.1/Cookbook-0.11.1.tar.gz";
-      sha256 = "sha256-a8ekMnEzudHGiqHF53jPtgsVTOTc2QLuPg6YtTw5h68=";
+      url = "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.11.2/Cookbook-0.11.2.tar.gz";
+      sha256 = "sha256-Pfa+Xbopg20os+pnGgg+wpEX1MI5fz5JMb0K4a8rBhs=";
     };
   };
   news = {
     pname = "news";
-    version = "25.0.0-alpha8";
+    version = "25.0.0-alpha12";
     src = fetchTarball {
-      url = "https://github.com/nextcloud/news/releases/download/25.0.0-alpha8/news.tar.gz";
-      sha256 = "sha256-AhTZGQCLeNgsRBF5w3+Lf9JtNN4D1QncB5t+odU+XUc=";
+      url = "https://github.com/nextcloud/news/releases/download/25.0.0-alpha12/news.tar.gz";
+      sha256 = "sha256-pnvyMZQ+NYMgH0Unfh5S19HdZSjnghgoUDAoi2KIXNI=";
     };
   };
   notes = {
     pname = "notes";
-    version = "v4.10.1";
+    version = "v4.11.0";
     src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/notes/releases/download/v4.10.1/notes-v4.10.1.tar.gz";
-      sha256 = "sha256-A3QNWGWeC2OcZngMrh9NpYbU5qp5x9xiDcRfB9cRXBo=";
+      url = "https://github.com/nextcloud-releases/notes/releases/download/v4.11.0/notes-v4.11.0.tar.gz";
+      sha256 = "sha256-Cu73H0hJREbkskLbj56M8qUF1Tp4EazORlCF9rpPL90=";
     };
   };
 }
diff --git a/pkgs/nextcloud-apps.toml b/pkgs/nextcloud-apps.toml
index 89dccb4..4e6e0b2 100644
--- a/pkgs/nextcloud-apps.toml
+++ b/pkgs/nextcloud-apps.toml
@@ -1,10 +1,12 @@
 [bookmarks]
-src.github = "nextcloud/bookmarks"
-src.prefix = "v"
+# src.github = "nextcloud/bookmarks"
+# src.prefix = "v"
+src.manual = "14.2.6"
 fetch.tarball = "https://github.com/nextcloud/bookmarks/releases/download/v$ver/bookmarks-$ver.tar.gz"
 
 [calendar]
-src.github = "nextcloud-releases/calendar"
+# src.github = "nextcloud-releases/calendar"
+src.manual = "v4.7.16"
 fetch.tarball = "https://github.com/nextcloud-releases/calendar/releases/download/$ver/calendar-$ver.tar.gz"
 
 [contacts]
@@ -20,7 +22,7 @@ fetch.tarball = "https://github.com/christianlupus-nextcloud/cookbook-releases/r
 [news]
 # Update manually until angular rewrite is done
 # src.github = "nextcloud/news"
-src.manual = "25.0.0-alpha8"
+src.manual = "25.0.0-alpha12"
 fetch.tarball = "https://github.com/nextcloud/news/releases/download/$ver/news.tar.gz"
 
 [notes]

From 2d977f4f13ef75c86699b6147e1426165b3b38e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Thu, 28 Nov 2024 00:56:31 +0100
Subject: [PATCH 166/212] Update battery-manager

---
 flake.lock | 35 +++++++++++++++++------------------
 flake.nix  |  2 +-
 2 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/flake.lock b/flake.lock
index 61d58f4..a2017c6 100644
--- a/flake.lock
+++ b/flake.lock
@@ -137,11 +137,11 @@
         "systems": "systems_3"
       },
       "locked": {
-        "lastModified": 1705309234,
-        "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
+        "lastModified": 1726560853,
+        "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
+        "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
         "type": "github"
       },
       "original": {
@@ -179,11 +179,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1703863825,
-        "narHash": "sha256-rXwqjtwiGKJheXB43ybM8NwWB8rO2dSRrEqes0S7F5Y=",
+        "lastModified": 1729742964,
+        "narHash": "sha256-B4mzTcQ0FZHdpeWcpDYPERtyjJd/NIuaQ9+BV1h+MpA=",
         "owner": "nix-community",
         "repo": "nix-github-actions",
-        "rev": "5163432afc817cf8bd1f031418d1869e4c9d5547",
+        "rev": "e04df33f62cdcf93d73e9a04142464753a16db67",
         "type": "github"
       },
       "original": {
@@ -306,11 +306,11 @@
         "treefmt-nix": "treefmt-nix"
       },
       "locked": {
-        "lastModified": 1708589824,
-        "narHash": "sha256-2GOiFTkvs5MtVF65sC78KNVxQSmsxtk0WmV1wJ9V2ck=",
+        "lastModified": 1731205797,
+        "narHash": "sha256-F7N1mxH1VrkVNHR3JGNMRvp9+98KYO4b832KS8Gl2xI=",
         "owner": "nix-community",
         "repo": "poetry2nix",
-        "rev": "3c92540611f42d3fb2d0d084a6c694cd6544b609",
+        "rev": "f554d27c1544d9c56e5f1f8e2b8aff399803674e",
         "type": "github"
       },
       "original": {
@@ -420,16 +420,15 @@
         "poetry2nixi": "poetry2nixi"
       },
       "locked": {
-        "lastModified": 1712437610,
-        "narHash": "sha256-U0xIqSupo6yBVWQcHIcLPDKg5ShQIkV/0Ay+Xg3GIlk=",
-        "ref": "tlater/implement-nix-module",
-        "rev": "43c4f591328f194ca989b86cea49773104f75549",
-        "revCount": 7,
+        "lastModified": 1733296058,
+        "narHash": "sha256-2tYgb4TbvoLk+zsRdCPaglP0s9GCG5HOR9Jm9rsSiHU=",
+        "ref": "refs/heads/main",
+        "rev": "5f01c17df4dbe841bb6ccd85993c0d9b7368af72",
+        "revCount": 13,
         "type": "git",
         "url": "ssh://git@github.com/sonnenshift/battery-manager"
       },
       "original": {
-        "ref": "tlater/implement-nix-module",
         "type": "git",
         "url": "ssh://git@github.com/sonnenshift/battery-manager"
       }
@@ -545,11 +544,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1708335038,
-        "narHash": "sha256-ETLZNFBVCabo7lJrpjD6cAbnE11eDOjaQnznmg/6hAE=",
+        "lastModified": 1730120726,
+        "narHash": "sha256-LqHYIxMrl/1p3/kvm2ir925tZ8DkI0KA10djk8wecSk=",
         "owner": "numtide",
         "repo": "treefmt-nix",
-        "rev": "e504621290a1fd896631ddbc5e9c16f4366c9f65",
+        "rev": "9ef337e492a5555d8e17a51c911ff1f02635be15",
         "type": "github"
       },
       "original": {
diff --git a/flake.nix b/flake.nix
index 6dbbaa5..ea27f2d 100644
--- a/flake.nix
+++ b/flake.nix
@@ -27,7 +27,7 @@
     };
 
     sonnenshift = {
-      url = "git+ssh://git@github.com/sonnenshift/battery-manager?ref=tlater/implement-nix-module";
+      url = "git+ssh://git@github.com/sonnenshift/battery-manager";
       inputs.nixpkgs.follows = "nixpkgs";
     };
   };

From 7ebb2ca6d8d7f3d18a3ae6c88a6c565c28ed9406 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 18 Jan 2025 22:55:57 +0800
Subject: [PATCH 167/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/09a776702b004fdf9c41a024e1299d575ee18a7d?narHash=sha256-a%2BAakkb%2BamHw4biOZ0iMo8xYl37uUL48YEXIC5PYJ/8%3D' (2024-10-23)
  → 'github:nix-community/disko/bf0abfde48f469c256f2b0f481c6281ff04a5db2?narHash=sha256-rMEuiK69MDhjz1JgbaeQ9mBDXMJ2/P8vmOYRbFndXsk%3D' (2025-01-16)
• Updated input 'foundryvtt':
    'github:reckenrode/nix-foundryvtt/bf07f9dd916a97a091f8ab83358c2f295bea9ec9?narHash=sha256-%2BhcgXKG5t/9wibv%2B8T9WASWItBAWb0tsmcZXH%2BVIYdw%3D' (2024-09-18)
  → 'github:reckenrode/nix-foundryvtt/0a72a4bf64224c6584fd1b9e9f0012dd09af979a?narHash=sha256-vM9C1gFiQGa3nTYqmTBI8MoiUfprkQdepUBbxV7ECMQ%3D' (2025-01-17)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/8b052aac04356e25b6ec1058c86de8792440362d?narHash=sha256-QLeNRaGsoIFfv2Kfd4rw2l1TTDb1i4gQzvClSmrk1l4%3D' (2024-10-24)
  → 'github:nixos/nixpkgs/09c71b16e6efc9e90edae7eb8b63348702ff9a85?narHash=sha256-jtucJjcdryEZQw1g0RThPSPxCdWNHF42sLp8pmMMGDs%3D' (2025-01-18)
• Updated input 'nvfetcher':
    'github:berberman/nvfetcher/fa7609950023462c6f91c425de7610c0bb6b86ba?narHash=sha256-xZZBdKqe1ByITzvx65pVgGQ5jeb73MybjgrcfI84lEo%3D' (2024-06-13)
  → 'github:berberman/nvfetcher/bdb14eab6fe9cefc29efe01e60c3a3f616d6b62a?narHash=sha256-Z0BpHelaGQsE5VD9hBsBHsvMU9h%2BXt0kfkDJyFivZOU%3D' (2024-11-25)
• Updated input 'nvfetcher/flake-utils':
    'github:numtide/flake-utils/b1d9ab70662946ef0850d488da1c9019f3a9752a?narHash=sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ%3D' (2024-03-11)
  → 'github:numtide/flake-utils/11707dc2f618dd54ca8739b309ec4fc024de578b?narHash=sha256-l0KFg5HjrsfsO/JpG%2Br7fRrqm12kzFHyUHqHCVpMMbI%3D' (2024-11-13)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/78a0e634fc8981d6b564f08b6715c69a755c4c7d?narHash=sha256-J2vtHq9sw1wWm0aTMXpEEAzsVCUMZDTEe5kiBYccpLE%3D' (2024-10-24)
  → 'github:Mic92/sops-nix/4c4fb93f18b9072c6fa1986221f9a3d7bf1fe4b6?narHash=sha256-GXUE9%2BFgxoZU8v0p6ilBJ8NH7k8nKmZjp/7dmMrCv3o%3D' (2025-01-17)
• Removed input 'sops-nix/nixpkgs-stable'
---
 flake.lock | 63 ++++++++++++++++++++----------------------------------
 1 file changed, 23 insertions(+), 40 deletions(-)

diff --git a/flake.lock b/flake.lock
index a2017c6..9aff775 100644
--- a/flake.lock
+++ b/flake.lock
@@ -27,11 +27,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1729712798,
-        "narHash": "sha256-a+Aakkb+amHw4biOZ0iMo8xYl37uUL48YEXIC5PYJ/8=",
+        "lastModified": 1737038063,
+        "narHash": "sha256-rMEuiK69MDhjz1JgbaeQ9mBDXMJ2/P8vmOYRbFndXsk=",
         "owner": "nix-community",
         "repo": "disko",
-        "rev": "09a776702b004fdf9c41a024e1299d575ee18a7d",
+        "rev": "bf0abfde48f469c256f2b0f481c6281ff04a5db2",
         "type": "github"
       },
       "original": {
@@ -119,11 +119,11 @@
         "systems": "systems_2"
       },
       "locked": {
-        "lastModified": 1710146030,
-        "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
+        "lastModified": 1731533236,
+        "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
+        "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
         "type": "github"
       },
       "original": {
@@ -157,11 +157,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1726638033,
-        "narHash": "sha256-+hcgXKG5t/9wibv+8T9WASWItBAWb0tsmcZXH+VIYdw=",
+        "lastModified": 1737076827,
+        "narHash": "sha256-vM9C1gFiQGa3nTYqmTBI8MoiUfprkQdepUBbxV7ECMQ=",
         "owner": "reckenrode",
         "repo": "nix-foundryvtt",
-        "rev": "bf07f9dd916a97a091f8ab83358c2f295bea9ec9",
+        "rev": "0a72a4bf64224c6584fd1b9e9f0012dd09af979a",
         "type": "github"
       },
       "original": {
@@ -208,29 +208,13 @@
         "type": "github"
       }
     },
-    "nixpkgs-stable": {
-      "locked": {
-        "lastModified": 1729357638,
-        "narHash": "sha256-66RHecx+zohbZwJVEPF7uuwHeqf8rykZTMCTqIrOew4=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "bb8c2cf7ea0dd2e18a52746b2c3a5b0c73b93c22",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "release-24.05",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1729766066,
-        "narHash": "sha256-QLeNRaGsoIFfv2Kfd4rw2l1TTDb1i4gQzvClSmrk1l4=",
+        "lastModified": 1737192615,
+        "narHash": "sha256-jtucJjcdryEZQw1g0RThPSPxCdWNHF42sLp8pmMMGDs=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "8b052aac04356e25b6ec1058c86de8792440362d",
+        "rev": "09c71b16e6efc9e90edae7eb8b63348702ff9a85",
         "type": "github"
       },
       "original": {
@@ -242,16 +226,16 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1729762315,
-        "narHash": "sha256-l0HyBdB2drPowQm044HDWqMLWwf818G38flxL0bhwqU=",
+        "lastModified": 1737171713,
+        "narHash": "sha256-9mWmMXCto7e8U9hM8ZFozElv4dgOMTe308SSc7rEEFs=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "00c24c17345ba867086a807a7869b12e05955c81",
+        "rev": "8773174492fc61571b578f34a59953baba46471a",
         "type": "github"
       },
       "original": {
         "owner": "nixos",
-        "ref": "nixos-24.05-small",
+        "ref": "nixos-24.11-small",
         "repo": "nixpkgs",
         "type": "github"
       }
@@ -281,11 +265,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1718252448,
-        "narHash": "sha256-xZZBdKqe1ByITzvx65pVgGQ5jeb73MybjgrcfI84lEo=",
+        "lastModified": 1732501185,
+        "narHash": "sha256-Z0BpHelaGQsE5VD9hBsBHsvMU9h+Xt0kfkDJyFivZOU=",
         "owner": "berberman",
         "repo": "nvfetcher",
-        "rev": "fa7609950023462c6f91c425de7610c0bb6b86ba",
+        "rev": "bdb14eab6fe9cefc29efe01e60c3a3f616d6b62a",
         "type": "github"
       },
       "original": {
@@ -437,15 +421,14 @@
       "inputs": {
         "nixpkgs": [
           "nixpkgs"
-        ],
-        "nixpkgs-stable": "nixpkgs-stable"
+        ]
       },
       "locked": {
-        "lastModified": 1729775275,
-        "narHash": "sha256-J2vtHq9sw1wWm0aTMXpEEAzsVCUMZDTEe5kiBYccpLE=",
+        "lastModified": 1737107480,
+        "narHash": "sha256-GXUE9+FgxoZU8v0p6ilBJ8NH7k8nKmZjp/7dmMrCv3o=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "78a0e634fc8981d6b564f08b6715c69a755c4c7d",
+        "rev": "4c4fb93f18b9072c6fa1986221f9a3d7bf1fe4b6",
         "type": "github"
       },
       "original": {

From 84759f564a0687bd849dfbc5a51abf06e0dd44b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 18 Jan 2025 23:35:12 +0800
Subject: [PATCH 168/212] Sigh...

---
 configuration/services/wireguard.nix | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/configuration/services/wireguard.nix b/configuration/services/wireguard.nix
index 6f8f6a2..a5185c5 100644
--- a/configuration/services/wireguard.nix
+++ b/configuration/services/wireguard.nix
@@ -31,14 +31,6 @@
               PublicKey = "5mlnqEVJWks5OqgeFA2bLIrvST9TlCE81Btl+j4myz0=";
             };
           }
-
-          {
-            # yuanyuan
-            wireguardPeerConfig = {
-              AllowedIPs = [ "10.45.249.10/32" ];
-              PublicKey = "0UsFE2atz/O5P3OKQ8UHyyyGQNJbp1MeIWUJLuoerwE=";
-            };
-          }
         ];
       };
     };

From 34f88ee8d5e5b664251f309a2defe0be58f863a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 19 Jan 2025 00:11:22 +0800
Subject: [PATCH 169/212] chore: Remove afvalcalendar

---
 configuration/default.nix                |    1 -
 configuration/services/afvalcalendar.nix |   71 --
 pkgs/afvalcalendar/Cargo.lock            | 1430 ----------------------
 pkgs/afvalcalendar/Cargo.toml            |   16 -
 pkgs/afvalcalendar/default.nix           |   12 -
 pkgs/afvalcalendar/src/calendar.rs       |   43 -
 pkgs/afvalcalendar/src/main.rs           |   15 -
 pkgs/afvalcalendar/src/trash.rs          |   59 -
 pkgs/afvalcalendar/test.rest             |    4 -
 pkgs/default.nix                         |    1 -
 10 files changed, 1652 deletions(-)
 delete mode 100644 configuration/services/afvalcalendar.nix
 delete mode 100644 pkgs/afvalcalendar/Cargo.lock
 delete mode 100644 pkgs/afvalcalendar/Cargo.toml
 delete mode 100644 pkgs/afvalcalendar/default.nix
 delete mode 100644 pkgs/afvalcalendar/src/calendar.rs
 delete mode 100644 pkgs/afvalcalendar/src/main.rs
 delete mode 100644 pkgs/afvalcalendar/src/trash.rs
 delete mode 100644 pkgs/afvalcalendar/test.rest

diff --git a/configuration/default.nix b/configuration/default.nix
index 333488b..48ee8c4 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -15,7 +15,6 @@
     "${modulesPath}/profiles/minimal.nix"
     (import ../modules)
 
-    ./services/afvalcalendar.nix
     ./services/backups.nix
     ./services/battery-manager.nix
     ./services/conduit.nix
diff --git a/configuration/services/afvalcalendar.nix b/configuration/services/afvalcalendar.nix
deleted file mode 100644
index ec7d9f7..0000000
--- a/configuration/services/afvalcalendar.nix
+++ /dev/null
@@ -1,71 +0,0 @@
-{ pkgs, config, ... }:
-{
-  systemd.services.afvalcalendar = {
-    description = "Enschede afvalcalendar -> ical converter";
-    wantedBy = [ "multi-user.target" ];
-    after = [ "network.target" ];
-
-    script = ''
-      ${pkgs.local.afvalcalendar}/bin/afvalcalendar > /srv/afvalcalendar/afvalcalendar.ical
-    '';
-
-    startAt = "daily";
-
-    serviceConfig = {
-      DynamicUser = true;
-      ProtectHome = true; # Override the default (read-only)
-      PrivateDevices = true;
-      PrivateIPC = true;
-      PrivateUsers = true;
-      ProtectHostname = true;
-      ProtectClock = true;
-      ProtectKernelTunables = true;
-      ProtectKernelModules = true;
-      ProtectKernelLogs = true;
-      ProtectControlGroups = true;
-      RestrictAddressFamilies = [
-        "AF_UNIX"
-        "AF_INET"
-        "AF_INET6"
-      ];
-      RestrictNamespaces = true;
-      LockPersonality = true;
-      MemoryDenyWriteExecute = true;
-      RestrictRealtime = true;
-      RestrictSUIDSGID = true;
-      SystemCallArchitectures = "native";
-      SystemCallFilter = [
-        "@system-service"
-        "~@privileged @resources @setuid @keyring"
-      ];
-
-      Umask = 2;
-      SupplementaryGroups = "afvalcalendar-hosting";
-
-      ReadWritePaths = "/srv/afvalcalendar";
-    };
-  };
-
-  services.nginx.virtualHosts."afvalcalendar.${config.services.nginx.domain}" = {
-    forceSSL = true;
-    useACMEHost = "tlater.net";
-    enableHSTS = true;
-
-    root = "/srv/afvalcalendar";
-  };
-
-  users.groups.afvalcalendar-hosting = { };
-  systemd.tmpfiles.settings."10-afvalcalendar" = {
-    "/srv/afvalcalendar".d = {
-      user = "nginx";
-      group = "afvalcalendar-hosting";
-      mode = "0775";
-    };
-
-    "/srv/afvalcalendar/afvalcalendar.ical".f = {
-      user = "nginx";
-      group = "afvalcalendar-hosting";
-      mode = "0775";
-    };
-  };
-}
diff --git a/pkgs/afvalcalendar/Cargo.lock b/pkgs/afvalcalendar/Cargo.lock
deleted file mode 100644
index 24cace4..0000000
--- a/pkgs/afvalcalendar/Cargo.lock
+++ /dev/null
@@ -1,1430 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "addr2line"
-version = "0.21.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
-dependencies = [
- "gimli",
-]
-
-[[package]]
-name = "adler"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
-
-[[package]]
-name = "afvalcalendar"
-version = "0.1.0"
-dependencies = [
- "chrono",
- "hostname",
- "icalendar",
- "reqwest",
- "serde",
- "serde_json",
- "serde_repr",
- "tokio",
-]
-
-[[package]]
-name = "android-tzdata"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
-
-[[package]]
-name = "android_system_properties"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "autocfg"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
-
-[[package]]
-name = "backtrace"
-version = "0.3.69"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
-dependencies = [
- "addr2line",
- "cc",
- "cfg-if",
- "libc",
- "miniz_oxide",
- "object",
- "rustc-demangle",
-]
-
-[[package]]
-name = "base64"
-version = "0.21.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
-
-[[package]]
-name = "bitflags"
-version = "1.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
-
-[[package]]
-name = "bitflags"
-version = "2.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
-
-[[package]]
-name = "bumpalo"
-version = "3.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d32a994c2b3ca201d9b263612a374263f05e7adde37c4707f693dcd375076d1f"
-
-[[package]]
-name = "bytes"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
-
-[[package]]
-name = "cc"
-version = "1.0.83"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
-
-[[package]]
-name = "chrono"
-version = "0.4.34"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b"
-dependencies = [
- "android-tzdata",
- "iana-time-zone",
- "js-sys",
- "num-traits",
- "serde",
- "wasm-bindgen",
- "windows-targets 0.52.0",
-]
-
-[[package]]
-name = "cookie"
-version = "0.17.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24"
-dependencies = [
- "percent-encoding",
- "time",
- "version_check",
-]
-
-[[package]]
-name = "cookie_store"
-version = "0.20.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "387461abbc748185c3a6e1673d826918b450b87ff22639429c694619a83b6cf6"
-dependencies = [
- "cookie",
- "idna 0.3.0",
- "log",
- "publicsuffix",
- "serde",
- "serde_derive",
- "serde_json",
- "time",
- "url",
-]
-
-[[package]]
-name = "core-foundation"
-version = "0.9.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "core-foundation-sys"
-version = "0.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
-
-[[package]]
-name = "deranged"
-version = "0.3.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
-dependencies = [
- "powerfmt",
-]
-
-[[package]]
-name = "encoding_rs"
-version = "0.8.33"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "equivalent"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
-
-[[package]]
-name = "errno"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
-dependencies = [
- "libc",
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "fastrand"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
-
-[[package]]
-name = "fnv"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
-
-[[package]]
-name = "foreign-types"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
-dependencies = [
- "foreign-types-shared",
-]
-
-[[package]]
-name = "foreign-types-shared"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
-
-[[package]]
-name = "form_urlencoded"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
-dependencies = [
- "percent-encoding",
-]
-
-[[package]]
-name = "futures-channel"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
-dependencies = [
- "futures-core",
-]
-
-[[package]]
-name = "futures-core"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
-
-[[package]]
-name = "futures-sink"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
-
-[[package]]
-name = "futures-task"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
-
-[[package]]
-name = "futures-util"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
-dependencies = [
- "futures-core",
- "futures-task",
- "pin-project-lite",
- "pin-utils",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.2.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
-dependencies = [
- "cfg-if",
- "js-sys",
- "libc",
- "wasi",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "gimli"
-version = "0.28.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
-
-[[package]]
-name = "h2"
-version = "0.3.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9"
-dependencies = [
- "bytes",
- "fnv",
- "futures-core",
- "futures-sink",
- "futures-util",
- "http",
- "indexmap",
- "slab",
- "tokio",
- "tokio-util",
- "tracing",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.14.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
-
-[[package]]
-name = "hermit-abi"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd"
-
-[[package]]
-name = "hostname"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
-dependencies = [
- "libc",
- "match_cfg",
- "winapi",
-]
-
-[[package]]
-name = "http"
-version = "0.2.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb"
-dependencies = [
- "bytes",
- "fnv",
- "itoa",
-]
-
-[[package]]
-name = "http-body"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
-dependencies = [
- "bytes",
- "http",
- "pin-project-lite",
-]
-
-[[package]]
-name = "httparse"
-version = "1.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
-
-[[package]]
-name = "httpdate"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
-
-[[package]]
-name = "hyper"
-version = "0.14.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80"
-dependencies = [
- "bytes",
- "futures-channel",
- "futures-core",
- "futures-util",
- "h2",
- "http",
- "http-body",
- "httparse",
- "httpdate",
- "itoa",
- "pin-project-lite",
- "socket2",
- "tokio",
- "tower-service",
- "tracing",
- "want",
-]
-
-[[package]]
-name = "hyper-tls"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
-dependencies = [
- "bytes",
- "hyper",
- "native-tls",
- "tokio",
- "tokio-native-tls",
-]
-
-[[package]]
-name = "iana-time-zone"
-version = "0.1.60"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
-dependencies = [
- "android_system_properties",
- "core-foundation-sys",
- "iana-time-zone-haiku",
- "js-sys",
- "wasm-bindgen",
- "windows-core",
-]
-
-[[package]]
-name = "iana-time-zone-haiku"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "icalendar"
-version = "0.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa4ffbcf3325ae94554c5259ce0b8907d37133c066cb3d424a2fa96aa1f10088"
-dependencies = [
- "chrono",
- "iso8601",
- "nom",
- "uuid",
-]
-
-[[package]]
-name = "idna"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
-dependencies = [
- "unicode-bidi",
- "unicode-normalization",
-]
-
-[[package]]
-name = "idna"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
-dependencies = [
- "unicode-bidi",
- "unicode-normalization",
-]
-
-[[package]]
-name = "indexmap"
-version = "2.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177"
-dependencies = [
- "equivalent",
- "hashbrown",
-]
-
-[[package]]
-name = "ipnet"
-version = "2.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
-
-[[package]]
-name = "iso8601"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "924e5d73ea28f59011fec52a0d12185d496a9b075d360657aed2a5707f701153"
-dependencies = [
- "nom",
-]
-
-[[package]]
-name = "itoa"
-version = "1.0.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
-
-[[package]]
-name = "js-sys"
-version = "0.3.68"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee"
-dependencies = [
- "wasm-bindgen",
-]
-
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-
-[[package]]
-name = "libc"
-version = "0.2.153"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
-
-[[package]]
-name = "linux-raw-sys"
-version = "0.4.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
-
-[[package]]
-name = "log"
-version = "0.4.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
-
-[[package]]
-name = "match_cfg"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
-
-[[package]]
-name = "memchr"
-version = "2.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
-
-[[package]]
-name = "mime"
-version = "0.3.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
-
-[[package]]
-name = "minimal-lexical"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
-
-[[package]]
-name = "miniz_oxide"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
-dependencies = [
- "adler",
-]
-
-[[package]]
-name = "mio"
-version = "0.8.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
-dependencies = [
- "libc",
- "wasi",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "native-tls"
-version = "0.2.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
-dependencies = [
- "lazy_static",
- "libc",
- "log",
- "openssl",
- "openssl-probe",
- "openssl-sys",
- "schannel",
- "security-framework",
- "security-framework-sys",
- "tempfile",
-]
-
-[[package]]
-name = "nom"
-version = "7.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
-dependencies = [
- "memchr",
- "minimal-lexical",
-]
-
-[[package]]
-name = "num-conv"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
-
-[[package]]
-name = "num-traits"
-version = "0.2.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "num_cpus"
-version = "1.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
-dependencies = [
- "hermit-abi",
- "libc",
-]
-
-[[package]]
-name = "object"
-version = "0.32.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "once_cell"
-version = "1.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
-
-[[package]]
-name = "openssl"
-version = "0.10.64"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
-dependencies = [
- "bitflags 2.4.2",
- "cfg-if",
- "foreign-types",
- "libc",
- "once_cell",
- "openssl-macros",
- "openssl-sys",
-]
-
-[[package]]
-name = "openssl-macros"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "openssl-probe"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
-
-[[package]]
-name = "openssl-sys"
-version = "0.9.100"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae94056a791d0e1217d18b6cbdccb02c61e3054fc69893607f4067e3bb0b1fd1"
-dependencies = [
- "cc",
- "libc",
- "pkg-config",
- "vcpkg",
-]
-
-[[package]]
-name = "percent-encoding"
-version = "2.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
-
-[[package]]
-name = "pin-project-lite"
-version = "0.2.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
-
-[[package]]
-name = "pin-utils"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
-
-[[package]]
-name = "pkg-config"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
-
-[[package]]
-name = "powerfmt"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.78"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
-name = "psl-types"
-version = "2.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac"
-
-[[package]]
-name = "publicsuffix"
-version = "2.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457"
-dependencies = [
- "idna 0.3.0",
- "psl-types",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "reqwest"
-version = "0.11.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251"
-dependencies = [
- "base64",
- "bytes",
- "cookie",
- "cookie_store",
- "encoding_rs",
- "futures-core",
- "futures-util",
- "h2",
- "http",
- "http-body",
- "hyper",
- "hyper-tls",
- "ipnet",
- "js-sys",
- "log",
- "mime",
- "native-tls",
- "once_cell",
- "percent-encoding",
- "pin-project-lite",
- "rustls-pemfile",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "sync_wrapper",
- "system-configuration",
- "tokio",
- "tokio-native-tls",
- "tower-service",
- "url",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
- "winreg",
-]
-
-[[package]]
-name = "rustc-demangle"
-version = "0.1.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
-
-[[package]]
-name = "rustix"
-version = "0.38.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
-dependencies = [
- "bitflags 2.4.2",
- "errno",
- "libc",
- "linux-raw-sys",
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "rustls-pemfile"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
-dependencies = [
- "base64",
-]
-
-[[package]]
-name = "ryu"
-version = "1.0.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
-
-[[package]]
-name = "schannel"
-version = "0.1.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
-dependencies = [
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "security-framework"
-version = "2.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
-dependencies = [
- "bitflags 1.3.2",
- "core-foundation",
- "core-foundation-sys",
- "libc",
- "security-framework-sys",
-]
-
-[[package]]
-name = "security-framework-sys"
-version = "2.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "serde"
-version = "1.0.196"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.196"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde_json"
-version = "1.0.114"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
-dependencies = [
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "serde_repr"
-version = "0.1.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde_urlencoded"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
-dependencies = [
- "form_urlencoded",
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "slab"
-version = "0.4.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "socket2"
-version = "0.5.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
-dependencies = [
- "libc",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "syn"
-version = "2.0.49"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "sync_wrapper"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
-
-[[package]]
-name = "system-configuration"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
-dependencies = [
- "bitflags 1.3.2",
- "core-foundation",
- "system-configuration-sys",
-]
-
-[[package]]
-name = "system-configuration-sys"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "tempfile"
-version = "3.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67"
-dependencies = [
- "cfg-if",
- "fastrand",
- "rustix",
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "time"
-version = "0.3.34"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749"
-dependencies = [
- "deranged",
- "itoa",
- "num-conv",
- "powerfmt",
- "serde",
- "time-core",
- "time-macros",
-]
-
-[[package]]
-name = "time-core"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
-
-[[package]]
-name = "time-macros"
-version = "0.2.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774"
-dependencies = [
- "num-conv",
- "time-core",
-]
-
-[[package]]
-name = "tinyvec"
-version = "1.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
-dependencies = [
- "tinyvec_macros",
-]
-
-[[package]]
-name = "tinyvec_macros"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
-
-[[package]]
-name = "tokio"
-version = "1.36.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931"
-dependencies = [
- "backtrace",
- "bytes",
- "libc",
- "mio",
- "num_cpus",
- "pin-project-lite",
- "socket2",
- "tokio-macros",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "tokio-macros"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "tokio-native-tls"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
-dependencies = [
- "native-tls",
- "tokio",
-]
-
-[[package]]
-name = "tokio-util"
-version = "0.7.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
-dependencies = [
- "bytes",
- "futures-core",
- "futures-sink",
- "pin-project-lite",
- "tokio",
- "tracing",
-]
-
-[[package]]
-name = "tower-service"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
-
-[[package]]
-name = "tracing"
-version = "0.1.40"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
-dependencies = [
- "pin-project-lite",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-core"
-version = "0.1.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
-dependencies = [
- "once_cell",
-]
-
-[[package]]
-name = "try-lock"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
-
-[[package]]
-name = "unicode-bidi"
-version = "0.3.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
-
-[[package]]
-name = "unicode-ident"
-version = "1.0.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
-
-[[package]]
-name = "unicode-normalization"
-version = "0.1.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
-dependencies = [
- "tinyvec",
-]
-
-[[package]]
-name = "url"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
-dependencies = [
- "form_urlencoded",
- "idna 0.5.0",
- "percent-encoding",
-]
-
-[[package]]
-name = "uuid"
-version = "1.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
-dependencies = [
- "getrandom",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "vcpkg"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
-
-[[package]]
-name = "version_check"
-version = "0.9.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
-
-[[package]]
-name = "want"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
-dependencies = [
- "try-lock",
-]
-
-[[package]]
-name = "wasi"
-version = "0.11.0+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
-
-[[package]]
-name = "wasm-bindgen"
-version = "0.2.91"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f"
-dependencies = [
- "cfg-if",
- "wasm-bindgen-macro",
-]
-
-[[package]]
-name = "wasm-bindgen-backend"
-version = "0.2.91"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b"
-dependencies = [
- "bumpalo",
- "log",
- "once_cell",
- "proc-macro2",
- "quote",
- "syn",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-futures"
-version = "0.4.41"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97"
-dependencies = [
- "cfg-if",
- "js-sys",
- "wasm-bindgen",
- "web-sys",
-]
-
-[[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.91"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed"
-dependencies = [
- "quote",
- "wasm-bindgen-macro-support",
-]
-
-[[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.91"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "wasm-bindgen-backend",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.91"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838"
-
-[[package]]
-name = "web-sys"
-version = "0.3.68"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "winapi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
-dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-
-[[package]]
-name = "windows-core"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
-dependencies = [
- "windows-targets 0.52.0",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
-dependencies = [
- "windows-targets 0.48.5",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
-dependencies = [
- "windows-targets 0.52.0",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
-dependencies = [
- "windows_aarch64_gnullvm 0.48.5",
- "windows_aarch64_msvc 0.48.5",
- "windows_i686_gnu 0.48.5",
- "windows_i686_msvc 0.48.5",
- "windows_x86_64_gnu 0.48.5",
- "windows_x86_64_gnullvm 0.48.5",
- "windows_x86_64_msvc 0.48.5",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
-dependencies = [
- "windows_aarch64_gnullvm 0.52.0",
- "windows_aarch64_msvc 0.52.0",
- "windows_i686_gnu 0.52.0",
- "windows_i686_msvc 0.52.0",
- "windows_x86_64_gnu 0.52.0",
- "windows_x86_64_gnullvm 0.52.0",
- "windows_x86_64_msvc 0.52.0",
-]
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
-
-[[package]]
-name = "winreg"
-version = "0.50.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
-dependencies = [
- "cfg-if",
- "windows-sys 0.48.0",
-]
diff --git a/pkgs/afvalcalendar/Cargo.toml b/pkgs/afvalcalendar/Cargo.toml
deleted file mode 100644
index f37dff1..0000000
--- a/pkgs/afvalcalendar/Cargo.toml
+++ /dev/null
@@ -1,16 +0,0 @@
-[package]
-name = "afvalcalendar"
-version = "0.1.0"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-icalendar = "0.16.0"
-serde = { version = "1.0.195", features = ["derive"] }
-tokio = { version = "1.35.1", features = ["macros", "rt-multi-thread"] }
-reqwest = { version = "0.11", features = ["cookies", "json"] }
-chrono = { version = "0.4.34", features = ["serde"] }
-serde_json = "1.0.114"
-serde_repr = "0.1.18"
-hostname = "0.3.1"
diff --git a/pkgs/afvalcalendar/default.nix b/pkgs/afvalcalendar/default.nix
deleted file mode 100644
index 6392220..0000000
--- a/pkgs/afvalcalendar/default.nix
+++ /dev/null
@@ -1,12 +0,0 @@
-{ pkgs, rustPlatform, ... }:
-rustPlatform.buildRustPackage {
-  pname = "afvalcalendar";
-  version = "0.1.0";
-  src = ./.;
-
-  nativeBuildInputs = with pkgs; [ pkg-config ];
-
-  buildInputs = with pkgs; [ openssl ];
-
-  cargoHash = "sha256-JXx6aUKdKbUTBCwlBw5i1hZy8ofCfSrhLCwFzqdA8cI=";
-}
diff --git a/pkgs/afvalcalendar/src/calendar.rs b/pkgs/afvalcalendar/src/calendar.rs
deleted file mode 100644
index 2c76d7f..0000000
--- a/pkgs/afvalcalendar/src/calendar.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-use chrono::{Duration, NaiveDate};
-use icalendar::{Alarm, Calendar, Component, Event, EventLike, Property};
-
-use crate::trash::TrashType;
-
-pub(crate) fn calendar_from_pickup_dates(dates: Vec<(TrashType, NaiveDate)>) -> Calendar {
-    let mut ical = Calendar::new();
-    ical.name("Twente Milieu Afvalkalender");
-
-    let events = dates.iter().map(|date| {
-        let description = match date.0 {
-            TrashType::Grey => "Restafval wordt opgehaald",
-            TrashType::Green => "GFT wordt opgehaald",
-            TrashType::Paper => "Papier wordt opgehaald",
-            TrashType::Packages => "Verpakkingen worden opgehaald",
-        };
-
-        let color = Property::new(
-            "COLOR",
-            match date.0 {
-                TrashType::Grey => "darkgray",
-                TrashType::Green => "darkgreen",
-                TrashType::Paper => "royalblue",
-                TrashType::Packages => "darkorange",
-            },
-        );
-
-        let reminder = Alarm::display(description, -Duration::hours(5));
-
-        Event::new()
-            .all_day(date.1)
-            .summary(description)
-            .append_property(color)
-            .alarm(reminder)
-            .done()
-    });
-
-    for event in events {
-        ical.push(event);
-    }
-
-    ical.done()
-}
diff --git a/pkgs/afvalcalendar/src/main.rs b/pkgs/afvalcalendar/src/main.rs
deleted file mode 100644
index e8023f7..0000000
--- a/pkgs/afvalcalendar/src/main.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-mod calendar;
-mod trash;
-
-#[tokio::main]
-async fn main() {
-    match trash::get_pickup_dates().await {
-        Ok(dates) => {
-            let calendar = calendar::calendar_from_pickup_dates(dates);
-            calendar.print().unwrap();
-        }
-        Err(error) => {
-            eprintln!("{}", error);
-        }
-    }
-}
diff --git a/pkgs/afvalcalendar/src/trash.rs b/pkgs/afvalcalendar/src/trash.rs
deleted file mode 100644
index 89a84d0..0000000
--- a/pkgs/afvalcalendar/src/trash.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-use chrono::{Months, NaiveDate, NaiveDateTime, Utc};
-use serde::Deserialize;
-use serde_repr::Deserialize_repr;
-
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-struct CalendarAPIDatum {
-    pickup_dates: Vec<NaiveDateTime>,
-    pickup_type: TrashType,
-}
-
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-struct CalendarAPIResponse {
-    data_list: Vec<CalendarAPIDatum>,
-}
-
-#[derive(Copy, Clone, Deserialize_repr, Debug)]
-#[repr(u8)]
-pub(crate) enum TrashType {
-    Grey = 0,
-    Green = 1,
-    Paper = 2,
-    Packages = 10,
-}
-
-pub(crate) async fn get_pickup_dates() -> Result<Vec<(TrashType, NaiveDate)>, reqwest::Error> {
-    let today = Utc::now().date_naive();
-    let next_month = (today + Months::new(1)).to_string();
-    let today = today.to_string();
-
-    let client = reqwest::Client::new();
-
-    let params = [
-        ("companyCode", "8d97bb56-5afd-4cbc-a651-b4f7314264b4"),
-        ("uniqueAddressID", "1300002485"),
-        ("startDate", &today),
-        ("endDate", &next_month),
-    ];
-
-    let calendar = client
-        .post("https://twentemilieuapi.ximmio.com/api/GetCalendar")
-        .form(&params)
-        .send()
-        .await?
-        .json::<CalendarAPIResponse>()
-        .await?;
-
-    Ok(calendar
-        .data_list
-        .iter()
-        .flat_map(|datum| {
-            datum
-                .pickup_dates
-                .iter()
-                .map(|date| (datum.pickup_type, NaiveDate::from(*date)))
-        })
-        .collect::<Vec<(TrashType, NaiveDate)>>())
-}
diff --git a/pkgs/afvalcalendar/test.rest b/pkgs/afvalcalendar/test.rest
deleted file mode 100644
index d2d409e..0000000
--- a/pkgs/afvalcalendar/test.rest
+++ /dev/null
@@ -1,4 +0,0 @@
-POST https://twentemilieuapi.ximmio.com/api/GetCalendar
-Content-Type: application/x-www-form-urlencoded
-
-companyCode=8d97bb56-5afd-4cbc-a651-b4f7314264b4&uniqueAddressID=1300002485&startDate=2024-02-01&endDate=2024-02-29
diff --git a/pkgs/default.nix b/pkgs/default.nix
index a9d7aa1..24ade6f 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -8,7 +8,6 @@ in
   prometheus-fail2ban-exporter = callPackage ./prometheus/fail2ban-exporter.nix {
     sources = pkgs.callPackage ./_sources_pkgs/generated.nix { };
   };
-  afvalcalendar = callPackage ./afvalcalendar { };
 }
 // (
   # Add nextcloud apps

From b3be7bd88fc70c7d0262798fe241dc297352eaaa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 19 Jan 2025 00:09:40 +0800
Subject: [PATCH 170/212] bump: Update to NixOS 24.11

---
 configuration/default.nix                     |  2 -
 .../hardware-specific/hetzner/default.nix     |  8 +-
 configuration/services/metrics/options.nix    | 10 ++-
 configuration/services/nextcloud.nix          |  6 +-
 configuration/services/wireguard.nix          | 22 +++--
 flake.lock                                    | 61 ++++++++-----
 flake.nix                                     | 14 +--
 pkgs/_sources_nextcloud/generated.json        | 86 -------------------
 pkgs/_sources_nextcloud/generated.nix         | 52 -----------
 pkgs/default.nix                              | 11 +--
 pkgs/mkNextcloudApp.nix                       |  7 --
 pkgs/nextcloud-apps.toml                      | 30 -------
 12 files changed, 66 insertions(+), 243 deletions(-)
 delete mode 100644 pkgs/_sources_nextcloud/generated.json
 delete mode 100644 pkgs/_sources_nextcloud/generated.nix
 delete mode 100644 pkgs/mkNextcloudApp.nix
 delete mode 100644 pkgs/nextcloud-apps.toml

diff --git a/configuration/default.nix b/configuration/default.nix
index 48ee8c4..18d124e 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -35,13 +35,11 @@
     (final: prev: {
       local = import ../pkgs {
         pkgs = prev;
-        lib = prev.lib;
       };
     })
   ];
 
   nix = {
-    package = pkgs.nixFlakes;
     extraOptions = ''
       experimental-features = nix-command flakes
     '';
diff --git a/configuration/hardware-specific/hetzner/default.nix b/configuration/hardware-specific/hetzner/default.nix
index 6795377..3e35eb0 100644
--- a/configuration/hardware-specific/hetzner/default.nix
+++ b/configuration/hardware-specific/hetzner/default.nix
@@ -19,13 +19,11 @@
     addresses = [
       # IPv4
       {
-        addressConfig = {
-          Address = "116.202.158.55/32";
-          Peer = "116.202.158.1/32"; # Gateway
-        };
+        Address = "116.202.158.55/32";
+        Peer = "116.202.158.1/32"; # Gateway
       }
       # IPv6
-      { addressConfig.Address = "2a01:4f8:10b:3c85::2/64"; }
+      { Address = "2a01:4f8:10b:3c85::2/64"; }
     ];
 
     networkConfig = {
diff --git a/configuration/services/metrics/options.nix b/configuration/services/metrics/options.nix
index 5dd17a3..69cbd6b 100644
--- a/configuration/services/metrics/options.nix
+++ b/configuration/services/metrics/options.nix
@@ -213,7 +213,15 @@ in
       let
         allExporters = lib.mapAttrs (name: exporter: { inherit (exporter) listenAddress port; }) (
           (lib.filterAttrs (
-            _: exporter: builtins.isAttrs exporter && exporter.enable
+            name: exporter:
+            # A bunch of deprecated exporters that need to be ignored
+            !(builtins.elem name [
+              "minio"
+              "tor"
+              "unifi-poller"
+            ])
+            && builtins.isAttrs exporter
+            && exporter.enable
           ) config.services.prometheus.exporters)
           // config.services.prometheus.extraExporters
         );
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 205d702..45cfe80 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -18,10 +18,10 @@ in
         packageOverrides = final: prev: {
           extensions = prev.extensions // {
             pgsql = prev.extensions.pgsql.overrideAttrs (old: {
-              configureFlags = [ "--with-pgsql=${config.services.postgresql.package}" ];
+              configureFlags = [ "--with-pgsql=${lib.getDev config.services.postgresql.package}" ];
             });
             pdo_pgsql = prev.extensions.pdo_pgsql.overrideAttrs (old: {
-              configureFlags = [ "--with-pdo-pgsql=${config.services.postgresql.package}" ];
+              configureFlags = [ "--with-pdo-pgsql=${lib.getDev config.services.postgresql.package}" ];
             });
           };
         };
@@ -51,7 +51,7 @@ in
     };
 
     extraApps = {
-      inherit (pkgs.local)
+      inherit (config.services.nextcloud.package.packages.apps)
         bookmarks
         calendar
         contacts
diff --git a/configuration/services/wireguard.nix b/configuration/services/wireguard.nix
index a5185c5..bbab22e 100644
--- a/configuration/services/wireguard.nix
+++ b/configuration/services/wireguard.nix
@@ -24,12 +24,10 @@
         };
 
         wireguardPeers = [
+          # yui
           {
-            # yui
-            wireguardPeerConfig = {
-              AllowedIPs = [ "10.45.249.2/32" ];
-              PublicKey = "5mlnqEVJWks5OqgeFA2bLIrvST9TlCE81Btl+j4myz0=";
-            };
+            AllowedIPs = [ "10.45.249.2/32" ];
+            PublicKey = "5mlnqEVJWks5OqgeFA2bLIrvST9TlCE81Btl+j4myz0=";
           }
         ];
       };
@@ -40,23 +38,23 @@
         matchConfig.Name = "wg0";
 
         networkConfig = {
+          Description = "VLAN";
+
           Address = [
             "10.45.249.1/32"
             # TODO(tlater): Add IPv6 whenever that becomes relevant
           ];
 
-          IPForward = "yes";
+          IPv4Forwarding = "yes";
           IPv4ProxyARP = "yes";
         };
 
         routes = [
           {
-            routeConfig = {
-              Source = "10.45.249.0/24";
-              Destination = "10.45.249.0/24";
-              Gateway = "10.45.249.1";
-              GatewayOnLink = "no";
-            };
+            Source = "10.45.249.0/24";
+            Destination = "10.45.249.0/24";
+            Gateway = "10.45.249.1";
+            GatewayOnLink = "no";
           }
         ];
 
diff --git a/flake.lock b/flake.lock
index 9aff775..d349bea 100644
--- a/flake.lock
+++ b/flake.lock
@@ -47,11 +47,11 @@
         "pyproject-nix": "pyproject-nix"
       },
       "locked": {
-        "lastModified": 1719685993,
-        "narHash": "sha256-04gy1icwnGO3ZXF6r96yBm/C0PNPzeLxA/8xzzq0dBI=",
+        "lastModified": 1735160684,
+        "narHash": "sha256-n5CwhmqKxifuD4Sq4WuRP/h5LO6f23cGnSAuJemnd/4=",
         "owner": "nix-community",
         "repo": "dream2nix",
-        "rev": "1b5e01219a32324c8f6889fe1f4db933ec7932f6",
+        "rev": "8ce6284ff58208ed8961681276f82c2f8f978ef4",
         "type": "github"
       },
       "original": {
@@ -69,11 +69,11 @@
         "rust-analyzer-src": "rust-analyzer-src"
       },
       "locked": {
-        "lastModified": 1719815435,
-        "narHash": "sha256-K2xFp142onP35jcx7li10xUxNVEVRWjAdY8DSuR7Naw=",
+        "lastModified": 1737181903,
+        "narHash": "sha256-lvp77MhGzSN+ICd0MugppCjQR6cmlM2iAC5cjy2ZsaA=",
         "owner": "nix-community",
         "repo": "fenix",
-        "rev": "ebfe2c639111d7e82972a12711206afaeeda2450",
+        "rev": "ac79bb490b8c1af4bbc587b84c76f9527d6b14f7",
         "type": "github"
       },
       "original": {
@@ -114,6 +114,22 @@
         "type": "github"
       }
     },
+    "flake-compat_3": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1696426674,
+        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
+        "type": "github"
+      },
+      "original": {
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "type": "github"
+      }
+    },
     "flake-utils": {
       "inputs": {
         "systems": "systems_2"
@@ -242,11 +258,11 @@
     },
     "nixpkgs_3": {
       "locked": {
-        "lastModified": 1719468428,
-        "narHash": "sha256-vN5xJAZ4UGREEglh3lfbbkIj+MPEYMuqewMn4atZFaQ=",
+        "lastModified": 1729850857,
+        "narHash": "sha256-WvLXzNNnnw+qpFOmgaM3JUlNEH+T4s22b5i2oyyCpXE=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "1e3deb3d8a86a870d925760db1a5adecc64d329d",
+        "rev": "41dea55321e5a999b17033296ac05fe8a8b5a257",
         "type": "github"
       },
       "original": {
@@ -305,6 +321,7 @@
     },
     "purescript-overlay": {
       "inputs": {
+        "flake-compat": "flake-compat_3",
         "nixpkgs": [
           "tlaternet-webserver",
           "dream2nix",
@@ -313,11 +330,11 @@
         "slimlock": "slimlock"
       },
       "locked": {
-        "lastModified": 1696022621,
-        "narHash": "sha256-eMjFmsj2G1E0Q5XiibUNgFjTiSz0GxIeSSzzVdoN730=",
+        "lastModified": 1728546539,
+        "narHash": "sha256-Sws7w0tlnjD+Bjck1nv29NjC5DbL6nH5auL9Ex9Iz2A=",
         "owner": "thomashoneyman",
         "repo": "purescript-overlay",
-        "rev": "047c7933abd6da8aa239904422e22d190ce55ead",
+        "rev": "4ad4c15d07bd899d7346b331f377606631eb0ee4",
         "type": "github"
       },
       "original": {
@@ -359,11 +376,11 @@
     "rust-analyzer-src": {
       "flake": false,
       "locked": {
-        "lastModified": 1719760370,
-        "narHash": "sha256-fsxAuW6RxKZYjAP3biUC6C4vaYFhDfWv8lp1Tmx3ZCY=",
+        "lastModified": 1737140097,
+        "narHash": "sha256-m4SN8DeKzsP10EQFS7+2zgGfCrMhTfTt1H0QRNesD08=",
         "owner": "rust-lang",
         "repo": "rust-analyzer",
-        "rev": "ea7fdada6a0940b239ddbde2048a4d7dac1efe1e",
+        "rev": "f61bfa4d7feb84d07538d361fe77d34a29e3b375",
         "type": "github"
       },
       "original": {
@@ -383,11 +400,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1688610262,
-        "narHash": "sha256-Wg0ViDotFWGWqKIQzyYCgayeH8s4U1OZcTiWTQYdAp4=",
+        "lastModified": 1688756706,
+        "narHash": "sha256-xzkkMv3neJJJ89zo3o2ojp7nFeaZc2G0fYwNXNJRFlo=",
         "owner": "thomashoneyman",
         "repo": "slimlock",
-        "rev": "b5c6cdcaf636ebbebd0a1f32520929394493f1a6",
+        "rev": "cf72723f59e2340d24881fd7bf61cb113b4c407c",
         "type": "github"
       },
       "original": {
@@ -505,11 +522,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1719851829,
-        "narHash": "sha256-M5miiIbiwP4uArTyeIr/RKA857rP14AEJUe11AZsKAc=",
+        "lastModified": 1737271785,
+        "narHash": "sha256-yVdaaawYK1/q9V5btfGpxVCQBdyQx1WcFHYO0yX5bP8=",
         "ref": "refs/heads/master",
-        "rev": "4a099f27a27f4107ceb14969e2158eaabebcf1d4",
-        "revCount": 74,
+        "rev": "5d3d84836101ec9b9867a5f754c9ee1b9d4dc538",
+        "revCount": 76,
         "type": "git",
         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git"
       },
diff --git a/flake.nix b/flake.nix
index ea27f2d..e6f1dcb 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,7 +2,7 @@
   description = "tlater.net host configuration";
 
   inputs = {
-    nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05-small";
+    nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11-small";
     nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable-small";
     disko = {
       url = "github:nix-community/disko";
@@ -132,18 +132,6 @@
               ${nvfetcher-bin} -o _sources_pkgs -c nvfetcher.toml
             '').outPath;
         };
-
-        update-nextcloud-apps = {
-          type = "app";
-          program =
-            let
-              nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher";
-            in
-            (pkgs.writeShellScript "update-nextcloud-apps" ''
-              cd "$(git rev-parse --show-toplevel)/pkgs"
-              ${nvfetcher-bin} -o _sources_nextcloud -c nextcloud-apps.toml
-            '').outPath;
-        };
       };
 
       ###########################
diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json
deleted file mode 100644
index 1c553ce..0000000
--- a/pkgs/_sources_nextcloud/generated.json
+++ /dev/null
@@ -1,86 +0,0 @@
-{
-    "bookmarks": {
-        "cargoLocks": null,
-        "date": null,
-        "extract": null,
-        "name": "bookmarks",
-        "passthru": null,
-        "pinned": false,
-        "src": {
-            "sha256": "sha256-7BTNFsNcqmDACpj5PMEiS71xtr50v7Sqo3qeCL+3J9s=",
-            "type": "tarball",
-            "url": "https://github.com/nextcloud/bookmarks/releases/download/v14.2.6/bookmarks-14.2.6.tar.gz"
-        },
-        "version": "14.2.6"
-    },
-    "calendar": {
-        "cargoLocks": null,
-        "date": null,
-        "extract": null,
-        "name": "calendar",
-        "passthru": null,
-        "pinned": false,
-        "src": {
-            "sha256": "sha256-X2XcH7HpxgizCEJVrazGtzNQTBihFxvTq/ybK939cxo=",
-            "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.7.16/calendar-v4.7.16.tar.gz"
-        },
-        "version": "v4.7.16"
-    },
-    "contacts": {
-        "cargoLocks": null,
-        "date": null,
-        "extract": null,
-        "name": "contacts",
-        "passthru": null,
-        "pinned": false,
-        "src": {
-            "sha256": "sha256-HCEjiAqn6sTNXKW6O5X6Ta9Ll4ehvzmGZUj1c0ue2Xc=",
-            "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/contacts/releases/download/v5.5.3/contacts-v5.5.3.tar.gz"
-        },
-        "version": "v5.5.3"
-    },
-    "cookbook": {
-        "cargoLocks": null,
-        "date": null,
-        "extract": null,
-        "name": "cookbook",
-        "passthru": null,
-        "pinned": false,
-        "src": {
-            "sha256": "sha256-Pfa+Xbopg20os+pnGgg+wpEX1MI5fz5JMb0K4a8rBhs=",
-            "type": "tarball",
-            "url": "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.11.2/Cookbook-0.11.2.tar.gz"
-        },
-        "version": "0.11.2"
-    },
-    "news": {
-        "cargoLocks": null,
-        "date": null,
-        "extract": null,
-        "name": "news",
-        "passthru": null,
-        "pinned": false,
-        "src": {
-            "sha256": "sha256-pnvyMZQ+NYMgH0Unfh5S19HdZSjnghgoUDAoi2KIXNI=",
-            "type": "tarball",
-            "url": "https://github.com/nextcloud/news/releases/download/25.0.0-alpha12/news.tar.gz"
-        },
-        "version": "25.0.0-alpha12"
-    },
-    "notes": {
-        "cargoLocks": null,
-        "date": null,
-        "extract": null,
-        "name": "notes",
-        "passthru": null,
-        "pinned": false,
-        "src": {
-            "sha256": "sha256-Cu73H0hJREbkskLbj56M8qUF1Tp4EazORlCF9rpPL90=",
-            "type": "tarball",
-            "url": "https://github.com/nextcloud-releases/notes/releases/download/v4.11.0/notes-v4.11.0.tar.gz"
-        },
-        "version": "v4.11.0"
-    }
-}
\ No newline at end of file
diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix
deleted file mode 100644
index da275cc..0000000
--- a/pkgs/_sources_nextcloud/generated.nix
+++ /dev/null
@@ -1,52 +0,0 @@
-# This file was generated by nvfetcher, please do not modify it manually.
-{ fetchgit, fetchurl, fetchFromGitHub, dockerTools }:
-{
-  bookmarks = {
-    pname = "bookmarks";
-    version = "14.2.6";
-    src = fetchTarball {
-      url = "https://github.com/nextcloud/bookmarks/releases/download/v14.2.6/bookmarks-14.2.6.tar.gz";
-      sha256 = "sha256-7BTNFsNcqmDACpj5PMEiS71xtr50v7Sqo3qeCL+3J9s=";
-    };
-  };
-  calendar = {
-    pname = "calendar";
-    version = "v4.7.16";
-    src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.7.16/calendar-v4.7.16.tar.gz";
-      sha256 = "sha256-X2XcH7HpxgizCEJVrazGtzNQTBihFxvTq/ybK939cxo=";
-    };
-  };
-  contacts = {
-    pname = "contacts";
-    version = "v5.5.3";
-    src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/contacts/releases/download/v5.5.3/contacts-v5.5.3.tar.gz";
-      sha256 = "sha256-HCEjiAqn6sTNXKW6O5X6Ta9Ll4ehvzmGZUj1c0ue2Xc=";
-    };
-  };
-  cookbook = {
-    pname = "cookbook";
-    version = "0.11.2";
-    src = fetchTarball {
-      url = "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.11.2/Cookbook-0.11.2.tar.gz";
-      sha256 = "sha256-Pfa+Xbopg20os+pnGgg+wpEX1MI5fz5JMb0K4a8rBhs=";
-    };
-  };
-  news = {
-    pname = "news";
-    version = "25.0.0-alpha12";
-    src = fetchTarball {
-      url = "https://github.com/nextcloud/news/releases/download/25.0.0-alpha12/news.tar.gz";
-      sha256 = "sha256-pnvyMZQ+NYMgH0Unfh5S19HdZSjnghgoUDAoi2KIXNI=";
-    };
-  };
-  notes = {
-    pname = "notes";
-    version = "v4.11.0";
-    src = fetchTarball {
-      url = "https://github.com/nextcloud-releases/notes/releases/download/v4.11.0/notes-v4.11.0.tar.gz";
-      sha256 = "sha256-Cu73H0hJREbkskLbj56M8qUF1Tp4EazORlCF9rpPL90=";
-    };
-  };
-}
diff --git a/pkgs/default.nix b/pkgs/default.nix
index 24ade6f..131282d 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -1,6 +1,5 @@
-{ pkgs, lib }:
+{ pkgs }:
 let
-  inherit (builtins) fromJSON mapAttrs readFile;
   inherit (pkgs) callPackage;
 in
 {
@@ -9,11 +8,3 @@ in
     sources = pkgs.callPackage ./_sources_pkgs/generated.nix { };
   };
 }
-// (
-  # Add nextcloud apps
-  let
-    mkNextcloudApp = pkgs.callPackage ./mkNextcloudApp.nix { };
-    sources = fromJSON (readFile ./_sources_nextcloud/generated.json);
-  in
-  mapAttrs (_: source: mkNextcloudApp source) sources
-)
diff --git a/pkgs/mkNextcloudApp.nix b/pkgs/mkNextcloudApp.nix
deleted file mode 100644
index 095b0e8..0000000
--- a/pkgs/mkNextcloudApp.nix
+++ /dev/null
@@ -1,7 +0,0 @@
-{ fetchNextcloudApp, lib }:
-source:
-fetchNextcloudApp {
-  url = source.src.url;
-  sha256 = source.src.sha256;
-  license = "unlicense"; # Blatant lie
-}
diff --git a/pkgs/nextcloud-apps.toml b/pkgs/nextcloud-apps.toml
deleted file mode 100644
index 4e6e0b2..0000000
--- a/pkgs/nextcloud-apps.toml
+++ /dev/null
@@ -1,30 +0,0 @@
-[bookmarks]
-# src.github = "nextcloud/bookmarks"
-# src.prefix = "v"
-src.manual = "14.2.6"
-fetch.tarball = "https://github.com/nextcloud/bookmarks/releases/download/v$ver/bookmarks-$ver.tar.gz"
-
-[calendar]
-# src.github = "nextcloud-releases/calendar"
-src.manual = "v4.7.16"
-fetch.tarball = "https://github.com/nextcloud-releases/calendar/releases/download/$ver/calendar-$ver.tar.gz"
-
-[contacts]
-# src.github = "nextcloud-releases/contacts"
-src.manual = "v5.5.3"
-fetch.tarball = "https://github.com/nextcloud-releases/contacts/releases/download/$ver/contacts-$ver.tar.gz"
-
-[cookbook]
-src.github = "christianlupus-nextcloud/cookbook-releases"
-src.prefix = "v"
-fetch.tarball = "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v$ver/Cookbook-$ver.tar.gz"
-
-[news]
-# Update manually until angular rewrite is done
-# src.github = "nextcloud/news"
-src.manual = "25.0.0-alpha12"
-fetch.tarball = "https://github.com/nextcloud/news/releases/download/$ver/news.tar.gz"
-
-[notes]
-src.github = "nextcloud-releases/notes"
-fetch.tarball = "https://github.com/nextcloud-releases/notes/releases/download/$ver/notes-$ver.tar.gz"

From ac2913c1867bb3a090c30689e818ff630d41c9e0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 19 Jan 2025 01:35:15 +0800
Subject: [PATCH 171/212] chore: Ignore manual gcroots

---
 .gitignore | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitignore b/.gitignore
index dbee5b9..7512d76 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 /result
 *.qcow2
+/gcroots/

From 22e1ab609572f9d20a95faab1a59e874a12a9ab7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 19 Jan 2025 17:48:33 +0800
Subject: [PATCH 172/212] chore: Remove nextcloud apps that I don't really use
 anymore

---
 configuration/services/nextcloud.nix | 2 --
 1 file changed, 2 deletions(-)

diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 45cfe80..55ce7f8 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -52,12 +52,10 @@ in
 
     extraApps = {
       inherit (config.services.nextcloud.package.packages.apps)
-        bookmarks
         calendar
         contacts
         cookbook
         news
-        notes
         ;
     };
   };

From 9efc952c7c3b40948196bbdc802d34965196d0fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 19 Jan 2025 18:13:11 +0800
Subject: [PATCH 173/212] bump: Update nextcloud

---
 configuration/services/nextcloud.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 55ce7f8..e54df14 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -5,7 +5,7 @@
   ...
 }:
 let
-  nextcloud = pkgs.nextcloud29;
+  nextcloud = pkgs.nextcloud30;
   hostName = "nextcloud.${config.services.nginx.domain}";
 in
 {

From 73c06e6ec8c3ab1f2d41625d0d6a9f790a37eee9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Wed, 22 Jan 2025 01:56:58 +0800
Subject: [PATCH 174/212] chore: Renew encryption keys

---
 .sops.yaml            |   2 +-
 keys/production.yaml  |  82 ++++++------
 keys/staging.yaml     |  56 ++++-----
 keys/users/tlater.asc | 284 +++++++++++++++++++++++++++++++++---------
 4 files changed, 296 insertions(+), 128 deletions(-)

diff --git a/.sops.yaml b/.sops.yaml
index 7444d2c..bed2365 100644
--- a/.sops.yaml
+++ b/.sops.yaml
@@ -1,5 +1,5 @@
 keys:
-  - &tlater 535B61015823443941C744DD12264F6BBDFABA89
+  - &tlater B9C7AE554602D82B1AC2CFD0BC7BB2DB17C78E42!
   - &server_tlaternet 8a3737d48f1035fe6c3a0a8fd6a1976ca74c7f3b
   - &server_hetzner1 0af7641adb8aa843136cf6d047f71da3e5ad79f9
   - &server_staging 2f5caa73e7ceea4fcc8d2881fde587e6737d2dbc
diff --git a/keys/production.yaml b/keys/production.yaml
index da90860..6dd4c21 100644
--- a/keys/production.yaml
+++ b/keys/production.yaml
@@ -35,59 +35,59 @@ sops:
     lastmodified: "2024-04-15T23:13:18Z"
     mac: ENC[AES256_GCM,data:3/v+WgSWJ+VcBSBe1Wkis3z+tMmSjbKzLFqBB8xugc6DvgQG8J+1HRrPucLnpNNtEdmpyoTa72U6fPm6JnyUsuj5pLEghLprOJkqQNdRI06fllhw+9d3e3twx6D4oIIsVH6/io4ElXrGsGQTsfNbYhgn+987wa3WP5N25fBac3U=,iv:FL3tzPutOMN6IPkQfXIu/JOZT+OzUSqpMSQrUeXZQHE=,tag:jL1BTsYTA9XjrsjFszxZhA==,type:str]
     pgp:
-        - created_at: "2024-03-18T04:02:00Z"
+        - created_at: "2025-01-21T17:55:44Z"
           enc: |-
             -----BEGIN PGP MESSAGE-----
 
-            hQEMA7x7stsXx45CAQf7BjF+HR3WKdMyAV6R1M0+lqDz6hBHKyGH7YBB/QZBqRbK
-            3hdABIwWUsqpHjleEOp/Gj0VhZqwagqHxK4Fp5G0r3QBupbAO8u/+DNI8wll0Nva
-            dlOh0Jqp4E17TkERMQL02rrQ1ZmpOYmPkCd2//xkmWAQ1LatHWeRVSRxQBuMtPQi
-            btrefcQNjQCvS9/60dp8oTu8nxlFA4iHCBQKNIKVGqQH7jkdIfMPdUILjCkCiyCc
-            h+OxlHZZnpU6U9A+hjMBinvCzebSkZh48VX/T33Kr+4b0CBr1gR9MSXKG9f2MPQP
-            PMl6rPvqSqG6ddN9QDI+0HEHYaRvxPIV8uDS36tVxNJeAQHB5/6Lt7hJdYWgwf5E
-            TLgbZ0IxB17++6K++GlaG8WHO65l1jzmkPlN+ZGcwnhibDxnZjP6kqGqDFcZP4ge
-            cnV0KnhYcC59IooQYrWKzAJex9rnwPo7MGKV6XwZOQ==
-            =Hy9T
+            hQEMA7x7stsXx45CAQf6AjhhYCHhRvJx4xxiXPMTfpIpAvseB1CXVfuhfj2r2yrf
+            3HfJnNOSDBcmHdp9fiLJattqfsykcGisUDVIplCeA7cIJjH3sf8MuIJXDTLmvE0Z
+            BmV8LuwP/UPQSZzY3w1eTAoYT/by35gfJm4ofipft2qyIjQuBgOlrg/0swvBl7LK
+            47mI6mVdds8RutHw/xhJZeNjKF/5tADPJ2CHjOHbCQhLji13Kpm3yObOnM8K2SfV
+            P9uVudCFN/ZBiTlVkB7PsuitwZx1fW0SR3jcWxbRd17M2k2RAQQDUCqPKaoJ3T3f
+            r2ExwmyO4j7G2vkFv1RgQnhAoHqqRZ1nSjNw1+27MNJeAbT1ddia2TC5Q2zjRZY9
+            tRJi2pNZH9A424lpIBLnkPl5rpCR/UZ+bqhaQ9C2kFMldSldPn8dMiBy8XG0Trji
+            B6X44Q/0RCsJD3FS61GASIjaWdEX0DdSOdhtbtBLLQ==
+            =yLOx
             -----END PGP MESSAGE-----
-          fp: 535B61015823443941C744DD12264F6BBDFABA89
-        - created_at: "2024-03-18T04:02:00Z"
+          fp: B9C7AE554602D82B1AC2CFD0BC7BB2DB17C78E42!
+        - created_at: "2025-01-21T17:55:44Z"
           enc: |-
             -----BEGIN PGP MESSAGE-----
 
-            hQIMA9ahl2ynTH87AQ/+LNXxC3acjs2+c38gHZRW6Am4XFx1t/4tfxIgaaK/Boq8
-            PGU5CFNOMDGv8u/cwyDbfNM7GuL5g7vrLmBXzSV5ErZqc6bJ0+ZCNPTRIxP1Vxph
-            tWiDIyTwuqUzxWpOlSzii2Sqhlp8CyiWzBe95eIr96XzDCCtfzyCZ0BYyKgpHHxB
-            BltH0/+0JZFiR19zvf6M99AHwM8OddRQkXav+mRIJQpA87ovVZcAv5skYGJgNCqN
-            55fbskuYmqEnloQCZVJ2+2ZXK5Qn/uq4fLJCiIdZm4YsctJnV5spzZIL+dcOty65
-            Plk77BWzLaU5UOKCBAJWrK8oZSTGOrp4VZqb62DuqMRejG0JXmneIVk7p79yn5eA
-            ANVMGRF4b8RP9YUhzE8HACFzQebKpUU8XKv9+qsmO9Le5jUhU3UQeCSSzT/T5Dr8
-            kLDNtmW+mliQnxFlKcVWq2JIG+HaQD1KLOAl0JBNCOSLif2ofaHahuZ15agbYeis
-            hyrBY92EhzqYXHk/Kzv4ff4r+WUs9NN7R4Gg+wfWvMcTtVfbi4Ht+pjjTtCZwK1C
-            M8JebQn0NZSpVi3e7Xaz1fQ5Tqrg8PHZtkYGoIHLRPJQwLn9PHYtGzC3rFAk+Fqq
-            5WWHELxfcsZ6DakAGSXPK/80QhEZkpGmKizTwrEde+7fpEPxjdzUqlmH3rv7mFzS
-            WAGSiBIMjLR6ofb65vpghbwh6gXkpCtgUyINRhx/D+Kj5Z4lGD1u1I05DT1xD6VJ
-            FAbnH7oZ3PJecoAXgRT05FndFA1xfPMCkugmec8ML/sEZt+c3kbrXaA=
-            =MqS3
+            hQIMA9ahl2ynTH87AQ/9F/lyLXn60X5Slcd9I7VPdM6x4IjFI0UwMAhMVv0GeimD
+            9Mj1vKW+l1v0gFtqCGjANEEYpXMr109CES+m6z7dNXcIQeR6pyjW6uCTiPUK/ZO/
+            ZQyhJR0zsT15BTHc6c9Eso9YedsggpRAbjjVIlmrTJx52LfqYYGoRA0XqcLE6LUS
+            6v6KR/299zzSHsTFVon6wac9wY7i1XvL0Q7JiYSNV2cNADiCJdCIBw1UkaSVH1uz
+            sTVdoEoQ1m7hu9pgg4UksUzi9IV3xBpte82tlEK9p0M+RXK/02fjMTWcx3q5fnjN
+            pBu3HkVzLpAjAQHMQ/O2cgbjFmwgjp5APUhn3IBx5M3F2ypGICnAvsrjfzalTChN
+            nkCmTfLynNIL1bX7PViABX2Q/yXGzPqFDe96pPw2hGjOXmxjKxjDoLT2IHixYp4D
+            cxb5519/WmOMrFd4SJeGiUR2Ph/VBZBVGafRfGAKMzxi666igWjwSU0YSDYeEUW/
+            BalkkWoz/KQZ5HgQwL9dyp26/cjDtpIwe8jLKVNI6aWhZ2ZmBxFwNEB6fE1txOjf
+            ceIJAfm8y2qIolw3TpBAFk6s53jir17SrEux9VzfiEfFeQ0g5q7cjAs5HfhTOMfh
+            iuUnHcCFy27wd+8bPxEaRYR57u7hneenTn3BMuu1CZputDFJWRvweMZk3cH8tiXS
+            WAGpXw7aKGIOpxe7Ye5X+T3xvYCBN77aFQKkrOmHMWFCbkr2QfnwVanxmmL9BwxF
+            rf8pG+H0URxBAsy9RZzSC+dXugnwnNBse3wupXf5YkipLx3rX9gtz4Y=
+            =a7xO
             -----END PGP MESSAGE-----
           fp: 8a3737d48f1035fe6c3a0a8fd6a1976ca74c7f3b
-        - created_at: "2024-03-18T04:02:00Z"
+        - created_at: "2025-01-21T17:55:44Z"
           enc: |-
             -----BEGIN PGP MESSAGE-----
 
-            hQIMA0f3HaPlrXn5AQ/+N5NK5UJdtw5e7O9T4hfIhtMXci/og1cJiI64daSyNeDH
-            jq+CPJ8e73yiTPwu6wHHqfuEhlEuI6sJY0ZJVFU+h4SIBtG21veGEz7GzlYgBCJm
-            xvJHXjtM8AprqnFVO7Fj9QA/ik5QBP6ZpkOY7j8/qf1G7alOIne/MYRALXDvvIMH
-            HTWE+Y2N57yZK55Pokmdw10hawbrn/N1nt2Y7sa1+5TlRNtuA/+zLkXtEjRr5U3N
-            DId+hqCKgXDqKLBMkh4mZUTGOGsk8eeKAWwyPp9+8A5/0rfy+xOJYEjjHICXQMSE
-            zfe6qvj/fRJKGzT5lEzD+ZKHlR0zHEwGRfHqrVUTdPcPdKj3DZILjsoe5ba4VlAp
-            sS0CAYTg3YuWMT4iHuOQlY5IoQxHHrn7k8ox5iZULFecg58f6r6iJL3AepDYWAey
-            gtQXYBeaeCm5Ddwmd6TBVz8Q4bCVYIrHbVeAhSDkxfrWLc5UORggvLEWiXilGDJi
-            DzAv0MVHE2Wa3eOJLq05K2/LBqRBD1XYM3dcS6JSdFxWWMzvLdUOB4dAuPt9gpl9
-            liaA13Blw/ev+U4ADxptrl+QuYRbWz3z6rniYpluSrTbVCKFRoHXSGFPy5u8/N6O
-            QyjfoovIBxXKnbUq2kMoFa/qFpc1pDUn0sjQNsUBdtorAu3Up4icyoih7qwx2J3S
-            WAGB1jHWMfcsBJqPwjRYkqBf6MuwHAZWdd+zvj/fKfft9jtxLcCGOIM6QdfiWbl0
-            Wq4gHdH7OhSy+ZgRnaBRt/GAkzkHvfG68HfulviHZ1h2mrQN1y3mxpg=
-            =RCYB
+            hQIMA0f3HaPlrXn5ARAAph6bpRqnO1TKEE7K6cMCxCA9k3xj7hknBdHN1KlIQkeb
+            LUOW9lvxh96q/fQ3NvZXpEQqZoEgdhnYTHgr/Hqx7VSksSicOkJLorrBLELjP1Xo
+            FKTxRYQmgZmgmBc0u7+lF2t0VLey6DfsC9ehY2LQcRuY9WxxCp2nDjjR4wrfmMKi
+            i/SbpaM9Q29DpdNpwkSlTe2sKr+uMDVA2rCrjpisSDiUBgPe2eJEYPQJ7DHFxB4N
+            26NHS+QtUgZhAA1DOGYZvrXzqcZSeAPGk8WXY44KA7o2iRFw+TczpF/VaMHRR5vN
+            M62IoXGqnMIBau+tsiE1JEVg60DIHpBjsEY/WUgbNX02zfaHcp1OenxU4p7W19Xn
+            Y8psPm7JNzmi3+nItB2i3+OLQrumk6VaT021ykterc52tR/3ejCzQCsfbqDLnc/6
+            r2SvNVDiKpxQ/iFyHb0uLHWy0Jx0lYwmMUrThe1f4k/+m9fEPrA5v/1kTGY5o1Iy
+            aTuHE19VtB6V+g1H6ZRPr8g8wn/3pg1nC2vUoRzT+oUudxrijrUH8SSlwhu59y1z
+            7SrdMmtqA1/JsGNMawCLWd63u+/3GC9LmZzK2h/bV/R4DG5f8tsCpy9BrFAHqTMs
+            lZ3SONUUeM3uMOggQ/JT26EVxECmNGYIX1TYLOxcqisRXLbfco5LEc6T8PJvdivS
+            WAFr6kBMdoeWhUT8MdT5AJBm9mo95A0WM8I14pGrszaezfgo9zc2zs0ebdLEjhI4
+            jlTf4tXgK3RG455CRWOd9OA3ukR83W7UW6LYjoNaDWHw2RXZlb+hv8E=
+            =+MFT
             -----END PGP MESSAGE-----
           fp: 0af7641adb8aa843136cf6d047f71da3e5ad79f9
     unencrypted_suffix: _unencrypted
diff --git a/keys/staging.yaml b/keys/staging.yaml
index 17e7875..091424d 100644
--- a/keys/staging.yaml
+++ b/keys/staging.yaml
@@ -35,39 +35,39 @@ sops:
     lastmodified: "2024-04-15T23:13:27Z"
     mac: ENC[AES256_GCM,data:JhEVrKF2Jsqpdztcr3g5lMrgEFeLXfBRQTwQJ6PmLSNyDORcTU09TJPNWTPDnR5okDrvIU/wlzi5DZ8A0ebNhrKf6l0tNFBT9LSvQFHU5SBxqY/m8uEJKSrEC4IL5lugOOISDka2KSvYXVCXrumMHE5FnmOS/CgOZaZk6LUjPYA=,iv:ygygnSedcTo2Vsc56s2qrz1qkWchvSgvoiMTebRxQQ8=,tag:vf6z8rxsXmqzwpDy9Avifw==,type:str]
     pgp:
-        - created_at: "2023-12-29T15:25:27Z"
-          enc: |
+        - created_at: "2025-01-21T17:55:30Z"
+          enc: |-
             -----BEGIN PGP MESSAGE-----
 
-            hQEMA7x7stsXx45CAQf/RWxP6z7xjV5TqiA6lFhtygjrH9x3y1DUWG9aUb/dO+xH
-            zDbGMYqGe9RPlgi5sWPstdKXvCgs+AKNj93qJYMwEtaasJOinYXCGeAQmzg90+pt
-            bS6SoBHhGIxAvvLKKPtYx0V50I2reYR+32ux9bcrnzwIsV0P7/SSp1Cl8H+sotB8
-            yf+0ULXcpC+SYECmZqzR9qQ3S+3I6/+QS+QgWj4NsyF+apxnE9oQDcBLdYP4aKgR
-            JHERA9HYfDTKoS137pFHxgINqHkFRY6lhoZdz1yDzOjiPxd8YVfPdKyf022Rg+cX
-            J/Q2P+OhNZEG3gapNATp6wH3niovA89KwZKSmbTZOdJeAZ6NV6TiUP+TgGg5+CmV
-            pSLaGel2NZRnFVNdDFi0dsOwhHv3FpKhIpALJh08/jsmAAslfE7vVlcEnaoUJPTS
-            3v86AACUC5D/gUxmFrrED1qoxbELCmZ17xTwjQzxwg==
-            =KzdF
+            hQEMA7x7stsXx45CAQf9ELnm9TdXCIO6fTPiSCkKthx0tSHqBWX/s63158k4IUu7
+            v0WWgQy0SKFU3AwIFuVaAYEXB32SaOWKq2WbVAbFZU+xhyUmNe9asg9Fl24+zjGI
+            oYnPzv3lz/5vcI6Q9rZi8F2uIi2GQZnbscS1XfjA5u17uOalQpb0hjUXr0LMaUvU
+            Sggm1ZMKE1o1mHAWK6ZT9SrTMIroWFArJRZLS1eY/vI9ja7I5YR3z0MkLqIvdIp+
+            B4DsOXLlqAqtVoPGcK1CixQiXzzwyQAYHyJc3JFDpaF9Y4S5/bkMLGyQVMA259a+
+            W7ge+EngdJdXV8Unj4s7ndB1e1iM87Jc+4YOcA7jC9JeAR98n8GL+MN9vE8q2AsB
+            qSOXiGSwmAkhq7+ZwJHWlivlB1In0coyJ4eMd/yhyBuc2NrstO0t595HlA93GcLN
+            5JsXIFMqklqGSzE2KgEXhxa2aUoJxcpApVz2BLFPvg==
+            =X72N
             -----END PGP MESSAGE-----
-          fp: 535B61015823443941C744DD12264F6BBDFABA89
-        - created_at: "2023-12-29T15:25:27Z"
-          enc: |
+          fp: B9C7AE554602D82B1AC2CFD0BC7BB2DB17C78E42!
+        - created_at: "2025-01-21T17:55:30Z"
+          enc: |-
             -----BEGIN PGP MESSAGE-----
 
-            hQIMA/3lh+ZzfS28ARAAm729dMouF7juUeHAb+aHMoyZVKsXapxnxebkjE/LSIbz
-            IEZwegTNrtxQJLclV4Km2gUaBTcE4vLJCpB7YxZvk7JV9OdVKi97o9PcXUXbz9ej
-            /WomnEvFyyxTZGTiHU+L4kNudl8UAKhTt3P4fR3PLpTily75Kn53tzLFJuCO8fAY
-            I/YwQAzayxhPcxk3FuPsD/ONiG7mW8n2ZwfwgOkKXwnrlJv7DreKJRYzu/EeuvX/
-            d4oz+k+xofniOeZmQjZllzR7/++MBg/e1U9VocN1EAWpWHP5taLiThfnVSGDhlQM
-            +4WT5ezH6EuUQlAyQNpDaCincBvCHInhrNlUPOpW51nHMb0y3n4x2hMtZA0JbYEu
-            mkWTYDe65cHjImHXQk9oO2/v4oIyq7ywHX7g2hqVbbiLHZqqTaGfV8lP30+r6/UQ
-            29iAdWac1hY5HDzwbqpY6b38i60j4bkiS83xqrGYBy037bCFk1oHJqwxp5P7vrzr
-            rTv5NBr95BlwF+s8xPEPZneaEu7N3UnhhSzDWp1jgsCxN9b/XHarchNt70xEt2VS
-            xpgs9GEXhsJcbrFNPYqTkFb8vjLFI+poGPTfadW17j4Pp5ftIBRNdKvDG0ni/AIp
-            K98R/nvaHEFuX31SkL8ZUIRqhJm3JVqilFxLAJrqGuSN3jA6wKrimUYpK+t+64jS
-            WAEN9jHYFQDTVHix3g15S5YTGh5ROyqxouDhvSDFTmGtbm5W/HYgnkZmh53TgVeJ
-            Rph/O9QptculzTN+nEqshBhbjhl/uDsLsjLYo/O1AyCwTUSd3OKn6uU=
-            =zThh
+            hQIMA/3lh+ZzfS28AQ//TPVk5x8wZtKnNcbZjqmXUvi7FzaDMGYFNtiX+bQ17Lkm
+            qdo9TcH8gZI+xni6wlROQBVmu5MAVkT+NWnZIyxN7pokQPmb2v9zo7oyUPV70owU
+            dD/LDNVqgyFTVzWKco4wr8CUwQWhOJI9wM0sjTCOTTbCT5hYVnJOLe630sNG9G5b
+            cJYvaQFxKJeHKJq/DL1I9wT02gOE7vu2xh2OyEozEz3SlB7Bp2mGTLNSiOZBhbzh
+            DNwFRTeDc1Z/ACQJyoGEXkmj1VLyBFuCfXu4UvUQSmlfyCXKTD1/CUo2uiw1N44W
+            sYh5UpIrCU2eVAAXAiD1nB6dHxiau3QlapNQfbY2sOZVSnsB21yIja9C3aQN/0Q5
+            gRrKYcwULzLZ0Z3oQqQxQG9acU8L9CwjKJ1vOKgPVF7hcWkba2bLVsMMaK6seVNc
+            jazp9gDAj440S2aE86CdQvgcOEsfgPhBZrulYglbhW8ZaIN2SdjDN/xP1Tn5PadP
+            gS2DVgqILKPRMF4VavzV3uhEA77QF39Hr18SeToNWcDmfqNPNNf7HpnogstGPf3y
+            xrFAysLbD8IClU4LqI5M19akODON8qeQa5QD+jHOJmAYnMYNRmY/IwHb/SC5WyIm
+            EPNZg5E+q9cNrTKtEIuWec0SObqpaUz2E/Vt9+dge0uVgTA/QqPvMP7x19XBrRDS
+            WAFiKkv7MxImNgcqqe7D3StZoeNm+RXJiULaxxuR8qmMnmvaC+L7ggI4QR3TPQw2
+            mSoi7SkdjQUCa8ut15UwNHTGO+smbRs9aonGP4G7c1cOH90YYvR+BTs=
+            =q2IG
             -----END PGP MESSAGE-----
           fp: 2f5caa73e7ceea4fcc8d2881fde587e6737d2dbc
     unencrypted_suffix: _unencrypted
diff --git a/keys/users/tlater.asc b/keys/users/tlater.asc
index d9c50dd..d94a304 100644
--- a/keys/users/tlater.asc
+++ b/keys/users/tlater.asc
@@ -11,62 +11,230 @@ FMU/1LD0M+n+if7Ydw7RsMzgOnr4DEXYLtNtaOgebc/rZRu7Wkix+gvAYSTwV+ph
 eDSnFQZui1QXJ1gnzO6Hi4Xe4ChPwUrcIIAoJ07INWruF6nXo8h9dtpPOtMsIZ02
 Ena7OwfaCuKRf0hwNYERyZN+Lzc105BzUv0d9rsA6qlv4qlaG01Lz+2kdb1zhk7E
 8FYksFrdnSRwd1qYm4KKGJO/dKJat1sJI4ldK2rn2/O5Hrm9O9RaATT1QQARAQAB
-tDpUcmlzdGFuIERhbmnDq2wgTWFhdCAod29yaykgPHRyaXN0YW4ubWFhdEBjb2Rl
-dGhpbmsuY28udWs+iQJMBBMBCgA2FiEEU1thAVgjRDlBx0TdEiZPa736uokFAl4n
-HXICGwEECwkIBwQVCgkIBRYCAwEAAh4BAheAAAoJEBImT2u9+rqJy0oP/1rl/R4n
-oqJbVa4BCkUZI3wyVomibyodWed/nAFRT9BzapVWqrhYsZuOtv7Xy5/qzFHrxMOW
-9aaJ3Rz7lI72uy4o86AqwRdMmSsmgFDj+HEk98eUoZed3ijtAltR83xYzlpQuJ3+
-o+O+Vs+sUUAI57FZ/7RyEPzcxk/+9yU1aSGWGwjDP4tWR+Fe69kqCoCUskydU4IM
-Ss3LbNzEypVGG/GOa/rUlJ3n/XvG0HjjGm1g4tnelkE06zFDIbglhPKJNuLbeH1j
-RDUdj1iX81B5nFDr+ARr4zqS5PJFgyiQDxU7fDx55mTRuqQ8M/X8eYeK7PXn8w5U
-2DQgh1AEgfQrLbPdZ2lwf/aINHf5wRSGvxBKIAxXpsMt98RUfd+L//aPrl5Hwi6H
-ZKe0Pbkn/GwmKZq3iqd5uaN6vLqybl9cHHaQ58MPCb0guYAJD0higgrw1tgNMhX1
-RGAutfQCbgJhkzqgYQ2Ystd9ky+mf4L+d5Ct+ks9J/WkkjQ61A8WbtqR34iytE+P
-clR9Z+p1kgeF0mzN29ZYYrIxVFhxD7abBBZfzNLJPEmRiU7EstH0sqVtuD8G1Uec
-/u/v7NTECtUu1zq5BK09mV8ZkeqTkQKCx1iRyfD8JSFYYb3sGyYtCIaOvLnnQf93
-mhbzdlXAyHLshjzrHoF2TixCIpskMWx1zM/5tC1UcmlzdGFuIERhbmnDq2wgTWFh
-dCAodGxhdGVyKSA8dG1AdGxhdGVyLm5ldD6JAkwEEwEKADYWIQRTW2EBWCNEOUHH
-RN0SJk9rvfq6iQUCXica9AIbAQQLCQgHBBUKCQgFFgIDAQACHgECF4AACgkQEiZP
-a736uon/aA/6A0tn+otsfGfei9QxDgM255R1U76PdSVb2bEl4/IdSq4uw8CtM69b
-CesCoajj/qgXzEFhpijQ9pXZDpMDXk64EZtcO5T96RNXA8Oh5CkpnVXv2MOrFXVL
-Zc05EOh6qxMCRACliii7CyGExAbRU/TdhL86dWc06CAiMt0/vzYgHpy69jpomHsP
-OeWk8TghHsMHPHOpfk4sS8gYlvsKV7QDpW5sNPmbm/nCFr+PoR7R+BKnklhdX9HN
-d/Ha6KSXpEjzqIoI/X3TtYtTyhNdwZ0rbKPtQYqMi08dnr4INjED5kZvrVFr16s1
-nFp8CghrnnUq9t1hzFAnYTWX736/CU/0ZrANRVsaKdJ3tCey2OT+IdprYZlriFvO
-ZO9AD5BV/V/e+QFi7LUZEEmsK3AVFERmRxP+597ZyK4ozjc0s8aLI2q9O8GROGxR
-GHloGMH9Mv5T/gfBfyFtoMU3poYOHCfwvtt9sr5IuiaexsGKTSTqRUWhq9moiGb8
-mQxQnZwIoRuQkmcV1JlfuS2inSpnd/Ar7M+eFUjV/qjW4Pg6LUH5WQoZbTT/3TUS
-9qS1v10wLJNMIniYGZslh71yb937i6BsAKLzVP6VTsZgO4+8eoEpL46l1C/h/sTW
-gdWwG/cB8c3qgcYRTtn9t93TRofnxxr8pSVihe2TAzk6I1EKcf2DzymJAjMEEAEK
-AB0WIQTfYF3xdR5NoZx+auO0Z9GZCjri0AUCXiccgwAKCRC0Z9GZCjri0Mc3D/9X
-/OLjPBrwR2rnv7qGB8jhg304RskvYx/kzcSadp4JQhF8zD6Lzb+F/NRzaN09E9RD
-jsnF595UiOqQ9NUY1Ku0+1HicJHKg7chK11tQWQyjYZKyCc/WxoOye+G7LGjLLl0
-MpJ2uO/fgD5asF6ufXU0XDVPUGUBilM2NiEFuVRK51ZOmP7hrQYjMD+TSz3PfvT5
-xAyggGmDOswQGMYCRj2S/hIbTADkSVwG61OiPHWAKxIPaIK+MBJm04KM7bnZmTly
-4j7ZA9oj2MikMe2z5M99EYIIDauVy5N9R0qzaOcUCFZXDaoZpPfq1fwk5Aj9tG4S
-/FdlMZeYeJNHkk7ZNaZ0vdQf4P7lib6gv9V1XePB4WANoG1KRVSq8eVYQvlxlFhR
-EJjiuahoT59KhX1aC4tEmBo4yC0LwQ+G2Vw2DZMZHDo8IqP/wrAPGblyOlo09vr+
-Hqd7oyDSxiYFekttvLmS3wtD+Fz3X7xZ3NOooqemH1pKd4XYTTX2RNryEx+pIcMh
-Emkmyo9D8P/FgwB7qTj5ANOhEVY4zYWmYKDck8AlDe1VY/yQ8mo2cJWYKo1qdpI3
-mrdHBkDhNANwBfKBUu4zxrapBSrZvIYJd8YJjqvBX/EsqrQHb8Sf71HrZt8UILrQ
-WBhTC0/BETEay2BDgV8tP+9l3/lJyJZzRB8u6x4UtrkBDQReJx0UAQgAk+y5c4DR
-oWSiJvZMQ+w+Hz7hv4s8Q/xxvjVPmp921oYRk+qrMS963Qc9Zstn9RSI8ALZFksD
-gKDPZ+DAgF1FLkv9HqoggcE8iUU+WiYCVkxj4M67nmuOeUf/vIja4fxs/t0vJXkP
-U9/Hn2d5dyRyseZEYbxPdJvQGk6GJ1OO+h6hLos9GNrFB64SQug9j57YY2R5u+fU
-RwE/xg2YDb4xGH8sAyZkKRNFnfQ67cL1TdfcbKs9jrI2U6KFYbdWVbRgeWEQSlLS
-fIzQuUG73iHuo8FD2CKsag5smI9l4iV3W1UHEscc5soeDzLA2lH66sb/yl858bEJ
-KDci3k+wE3RQEwARAQABiQI7BBgBCgAmAhsMFiEEU1thAVgjRDlBx0TdEiZPa736
-uokFAmASBaMFCQPMHA8ACgkQEiZPa736uonUAw/4xh//cHEJ2UBgiei//8vBYR7E
-PB62NUmFXDphoAHB1xRMlFh3ljsU25hzXfTR1SyEvuYN9f7zmmW3ZmH0rV8xn0zb
-BCAORGmFm6auYV5x89Ika/ecoFAew8eeZbKuzT/ZWH9OEmGXoRP0eFAxDpOlEg85
-n+ErkRxnvc3VxUYt1swPhZ9Om/bZ26XzznJ11FztmYht6VXcB9jrpVwMjk5rAAAF
-LuK7Uiw9yQMaW8z7lcKQvAdiQ6j1TmGogIT3XAhVJkBNcMyb5qz+mylupMe69hs3
-L8I3PPMZJhT7ymll09KURChaGR8H3dohS2b/wLNdWoqMAyXqXWHDrZ83Uor/wzGh
-TQ6FHz0z8GMoiUgoU9GEQVu4vy2mjpR4vnHZ0pXP469rYdxQDkrfyuQSvbpYi9br
-ayllJQG8qoHXI92wugslD2CIeI14h8C14ZkOymI4uZCv0kR3mIxV9WVAanJyHVto
-HrYiHVt5TzJMqY0Eu3NPvr9W/B4x0srFOmM9MBivbTo4S3KDZEfRpqC5QCdw79qP
-spm35kqWIEpM+O4gc+zE4EHUbddu/68yXNaqvWRODg8mo8flFTZ5PvpIb/qNkPOG
-GDgPiiIae4ga6KNOS1STroHf63ort4G0zuQPzQg1N9ll4lo62OqDmW+25nzHC7yB
-PhCB2Dz76iQ5nDY4MQ==
-=R7Pm
+tC1UcmlzdGFuIERhbmnDq2wgTWFhdCAodGxhdGVyKSA8dG1AdGxhdGVyLm5ldD6J
+Ak8EEwEKADkCGwEECwkIBwQVCgkIBRYCAwEAAh4BAheAAhkBFiEEU1thAVgjRDlB
+x0TdEiZPa736uokFAmH0krIACgkQEiZPa736uomO9Q/8DauQv6uuYzuT0xIT4A7s
+xKZU8w3MoIv/z3DcJv9So81EYZBHvywKOkZyl8C0QX/Plkkpm8K72vTyD2FB3PtH
+jXdc+8l5a5uz3F22YOMGJHEgBNrCBii+BQ8sfDi6isbVbxGlpiYkm8BaEaXyC9Xv
+1AIu8s6VqzvED5oHB66yqGmr+4Nsij+37eYYkhxWO8UQzrYHHKkVqjchSrMtd/pe
+C3H9VXKXGaT8xLkkiPubPEH1DGQwfon5sfCOk0GOuFMKSdiKrW38MBJHPhNQqNtp
+kG35nKURQlWAXuxh7fCk3kcpSFFCs60XojA+R5+XlPSWpfHe45jbDzA6nyeQ7nfV
+kVxW6vYTGvZKT3QOHjaUePqaEqfmZz9KebsDF2W1+UzKMI7q7Q5ofH6Pp9gGd7cT
+Na2CGL4BHCH9qsQjWbDefuYxHOS1nVrgiSmt4FvXFMhmgLRwkRKJQuHmy6eGfI7D
+75648Jwy5ID/CiZV7vd1MdLZomV/lyb8VyChFYol3ErG4p04fZSdvZQMwemwji12
+j7vyj7GPKMf9dIx4+w25z58qE2En0fzmAeEfRA24o4XyQXy/tR24AmaR25i9/Cbj
+OtVioUaYEHQrwxTP/qXIMM3bwDjOuo3Lseil9x64dV5QooVp422W2KWlbnm/QWhW
+zmWDxZpubnUlYld5JPilPlGJAjMEEAEKAB0WIQTfYF3xdR5NoZx+auO0Z9GZCjri
+0AUCXiccgwAKCRC0Z9GZCjri0Mc3D/9X/OLjPBrwR2rnv7qGB8jhg304RskvYx/k
+zcSadp4JQhF8zD6Lzb+F/NRzaN09E9RDjsnF595UiOqQ9NUY1Ku0+1HicJHKg7ch
+K11tQWQyjYZKyCc/WxoOye+G7LGjLLl0MpJ2uO/fgD5asF6ufXU0XDVPUGUBilM2
+NiEFuVRK51ZOmP7hrQYjMD+TSz3PfvT5xAyggGmDOswQGMYCRj2S/hIbTADkSVwG
+61OiPHWAKxIPaIK+MBJm04KM7bnZmTly4j7ZA9oj2MikMe2z5M99EYIIDauVy5N9
+R0qzaOcUCFZXDaoZpPfq1fwk5Aj9tG4S/FdlMZeYeJNHkk7ZNaZ0vdQf4P7lib6g
+v9V1XePB4WANoG1KRVSq8eVYQvlxlFhREJjiuahoT59KhX1aC4tEmBo4yC0LwQ+G
+2Vw2DZMZHDo8IqP/wrAPGblyOlo09vr+Hqd7oyDSxiYFekttvLmS3wtD+Fz3X7xZ
+3NOooqemH1pKd4XYTTX2RNryEx+pIcMhEmkmyo9D8P/FgwB7qTj5ANOhEVY4zYWm
+YKDck8AlDe1VY/yQ8mo2cJWYKo1qdpI3mrdHBkDhNANwBfKBUu4zxrapBSrZvIYJ
+d8YJjqvBX/EsqrQHb8Sf71HrZt8UILrQWBhTC0/BETEay2BDgV8tP+9l3/lJyJZz
+RB8u6x4UtokCTAQTAQoANhYhBFNbYQFYI0Q5QcdE3RImT2u9+rqJBQJeJxr0AhsB
+BAsJCAcEFQoJCAUWAgMBAAIeAQIXgAAKCRASJk9rvfq6if9oD/oDS2f6i2x8Z96L
+1DEOAzbnlHVTvo91JVvZsSXj8h1Kri7DwK0zr1sJ6wKhqOP+qBfMQWGmKND2ldkO
+kwNeTrgRm1w7lP3pE1cDw6HkKSmdVe/Yw6sVdUtlzTkQ6HqrEwJEAKWKKLsLIYTE
+BtFT9N2Evzp1ZzToICIy3T+/NiAenLr2OmiYew855aTxOCEewwc8c6l+TixLyBiW
++wpXtAOlbmw0+Zub+cIWv4+hHtH4EqeSWF1f0c138dropJekSPOoigj9fdO1i1PK
+E13BnStso+1BioyLTx2evgg2MQPmRm+tUWvXqzWcWnwKCGuedSr23WHMUCdhNZfv
+fr8JT/RmsA1FWxop0ne0J7LY5P4h2mthmWuIW85k70APkFX9X975AWLstRkQSawr
+cBUURGZHE/7n3tnIrijONzSzxosjar07wZE4bFEYeWgYwf0y/lP+B8F/IW2gxTem
+hg4cJ/C+232yvki6Jp7GwYpNJOpFRaGr2aiIZvyZDFCdnAihG5CSZxXUmV+5LaKd
+Kmd38Cvsz54VSNX+qNbg+DotQflZChltNP/dNRL2pLW/XTAsk0wieJgZmyWHvXJv
+3fuLoGwAovNU/pVOxmA7j7x6gSkvjqXUL+H+xNaB1bAb9wHxzeqBxhFO2f233dNG
+h+fHGvylJWKF7ZMDOTojUQpx/YPPKbQ6VHJpc3RhbiBEYW5pw6tsIE1hYXQgKHdv
+cmspIDx0cmlzdGFuLm1hYXRAY29kZXRoaW5rLmNvLnVrPokCTAQTAQoANgIbAQQL
+CQgHBBUKCQgFFgIDAQACHgECF4AWIQRTW2EBWCNEOUHHRN0SJk9rvfq6iQUCYfSS
+sgAKCRASJk9rvfq6iTD2EACWRy0dijH+nF/Io3hZsr3TWhe+lmXCsAjc4wSBuqu6
+mPvYGLMKzY6iW/Z7RrVaLlM9BAhwcl11KHMkP7sNDNFzAomy11ofn/P2bQy1FTxI
+nSRj4NLDa9FybFPuyTG9buV58jYedXdWVaJuC0nLbi8wzkAEZCZEKRcQgIS1Bi0o
+qrGtx05RgBd/LDs4mUD9EB1kw7EoCOOQz1gL54pZvnN3Fw73guDnnBWtm0356+7h
+ZHjmXUBlbakdOZzVz73Dc5BTK6ma5aNrTBLccdxKXOKFCeyAVv+i5Hj26VEMdlVx
+Ja3xZznzbHNoU6K+/tcEJLkbCIaDEQaX6rmrJDuG8zWICf1zTVPRfa/oxuXASdUr
+4y2LAuz/m8zq2RKr3bv11AKifKIAP2vL2q6fZvZ4hrLJ3G6vHh/L1y5oy+l+eav9
+cER2bCweVeV6RhlBzwtej2ZB0J5MkF59OCK7OBfPJnmJCd33AuA74mlrzmi7x9um
+LQLPI9oZk9rQRj3FZ61Kv5jhJntDIDe2e1DK/vHnddtHeqbdH9Dx0NNl8/JWfSp8
+NccOBEzDe8nB+1sbvPyt7rUuZPhHzk3O45+k1pQrxZbIFGRPGZJkHdiOCWlG6m4A
+Pgul/U84sSnsberrQdyBBtMUoBV6jyVzUwI9/ZYHAZCguC4QG71zR31um2TB7kDt
+NYkCTAQTAQoANhYhBFNbYQFYI0Q5QcdE3RImT2u9+rqJBQJeJx1yAhsBBAsJCAcE
+FQoJCAUWAgMBAAIeAQIXgAAKCRASJk9rvfq6ictKD/9a5f0eJ6KiW1WuAQpFGSN8
+MlaJom8qHVnnf5wBUU/Qc2qVVqq4WLGbjrb+18uf6sxR68TDlvWmid0c+5SO9rsu
+KPOgKsEXTJkrJoBQ4/hxJPfHlKGXnd4o7QJbUfN8WM5aULid/qPjvlbPrFFACOex
+Wf+0chD83MZP/vclNWkhlhsIwz+LVkfhXuvZKgqAlLJMnVOCDErNy2zcxMqVRhvx
+jmv61JSd5/17xtB44xptYOLZ3pZBNOsxQyG4JYTyiTbi23h9Y0Q1HY9Yl/NQeZxQ
+6/gEa+M6kuTyRYMokA8VO3w8eeZk0bqkPDP1/HmHiuz15/MOVNg0IIdQBIH0Ky2z
+3WdpcH/2iDR3+cEUhr8QSiAMV6bDLffEVH3fi//2j65eR8Iuh2SntD25J/xsJima
+t4qnebmjery6sm5fXBx2kOfDDwm9ILmACQ9IYoIK8NbYDTIV9URgLrX0Am4CYZM6
+oGENmLLXfZMvpn+C/neQrfpLPSf1pJI0OtQPFm7akd+IsrRPj3JUfWfqdZIHhdJs
+zdvWWGKyMVRYcQ+2mwQWX8zSyTxJkYlOxLLR9LKlbbg/BtVHnP7v7+zUxArVLtc6
+uQStPZlfGZHqk5ECgsdYkcnw/CUhWGG97BsmLQiGjry550H/d5oW83ZVwMhy7IY8
+6x6Bdk4sQiKbJDFsdczP+YkCUgQwAQoAPBYhBFNbYQFYI0Q5QcdE3RImT2u9+rqJ
+BQJnj7iXHh0gTm8gbG9uZ2VyIHdvcmsgZm9yIENvZGV0aGluawAKCRASJk9rvfq6
+iVagD/oCuQ/RE4kpZLKo6kF4yBKMHX3jz4HpKYpnG/aBncr031zI8qpdgiVpnC4s
+pzbxah7/yBozsaCCTQo0s84Y3u2uD+XzKRujWoK23/+U0fgs06B98vzNEWeWTR67
+cdyL5VsFTSc2QiM18tgjMEAAcv6ts7YFKZXZYxsGrQ1Pn7ZD9xfJ2GXuPY0bAmX8
+ccDf6EQ/du6sICv5/C2kupOmbY93sMDCzQ10sz3O0P/xj9gFAg8m3AWU8IzmZQNx
+a/TPYCadglCxjDZcuIYDuG0DWWGdviEp4GARX+hrhBHDbqEUVhFwvZNfGSbCoICx
++sRZ3KHFjF9PV7b+2dOdYWa3ECSsm4R4e//AKruhH83yEOXuosbiZ+pc1LSxgfRy
+D2dKfOWC6yv9GO8CqpUmnoYZTSmuTZAp2Va8qh/B3M2Qv7GWRfvG5DgKXZBnv8Z0
+2XxclgTtWqixfE0Sr1RCAGk9c+/xjMwlkak9M+KJZgua7WDYvM3mGHm3XRgIc6T/
+6XgNTgerhdqozsDXSHdPApPfuQpNXNYY3frOiGsCfi/XlHsjIX0gd/1bgM9h8D8f
+rK8ebIQmId58S/q7hRqxnLW1+cccFOTDoUXJA2tq24t7A6hkdEwNgW0Kj4Mg2AsF
+GH3jVCAH1Y89i9NLknLsjhy56kef4m/770EjyO+pt63DujNWeLkBDQReJxz1AQgA
+1y1WKRdzA/SXJsU5qeZ7yAYVNGUYq44UVeJHDa6cEi302xxmI8ytSp9VBo6QhgGo
+J1vef8LYoB4Qv6AC9RnDtrS6SgomWcULh0RtS9hi4PX+MYY2kO4XRUKoliG/DIgA
+HuiRbeGTN3MHxAZYHGkT9gs6z71mDywCpXkv+pngjtdquXx4NdsEucBEC3l8eE+k
+AEJ1V5bp66+LH4UiW2FAi5UShn4QmKxvsxXzl0wJN89D1fXaBxOw5ZJuNV5i62KW
+QmV2N4P7FFZlxolHwu/Fn4Nd6x9l3G3TpWAq/wlyyFrL0KFt7/vGCiKG5N0u/RE/
+ZzWZcUji7iYXZuGIbpQhhQARAQABiQNyBBgBCgAmAhsCFiEEU1thAVgjRDlBx0Td
+EiZPa736uokFAmW8ZUIFCQl2e80BQMB0IAQZAQoAHRYhBKUpZWuzqrBd1I8zFkln
+D9d05DJoBQJeJxz1AAoJEElnD9d05DJo3lcIALppAubOBA0+Oxda2FZTyGr20+pK
+WSQ3HBhPOtWoO1D6OhDMaWTnF07gXC8EKG8pgwUFMDp8YlbBJJ6bAQ3NXlfxyPO4
+FS3BwaSB6p2pbm1bJCnOOjoF6H/IVOIqKPIhwQ5XR3BqVX1BmKsTCoYkwzLEs/uv
+3pT/rZ3lGDdBiwE6a3GMF7c5zNzRBLQSkHFIZLfCuyDfmKScPzBzAdf/ZCkDYMYw
++nbYsAn2yuW8z7FFdWiopYst4l2qlY11bntwH8+PWXvl+xiqA85Qa+OLGQ+usaX3
+TVEvcv6q8dHwEdOPuqbDEZV7JXjmmARSjfDWwXHzqgvejkzplG4RTBl/nKkJEBIm
+T2u9+rqJL+oP/2Uz2OuaLU5qsrj2o6Bv4nDGuEdGi2KR0NBqDWgISN+3pf+Fig/t
+M+CrSLE4ImydDeTYPav5iI48B3xvFVT/IE7YQN5pqVy4p6LQaxKZgaITJInAkl8r
+9wcCtY7+23n1AyoyqNvKJkik2ChANBu5oOSVxa6XGBTGxSEqdxoXm9pMmLOR7j9E
+ByMGYQqMrEnBvHeRk8UGHYGnRAZbAvNGGt8LaQygFhzqOBHXf6iTpjX+7cBIOKAB
+64onlpaGfUWsaNnlpdZDaSV4iDvpQu0wHlGozOLuuEi5nZ9ArIidtKt8PKWFaJSd
+BfexAKi1JYZv6RhURbBld6CS6/TdDyXF0MnxJrxRlVUt8a8mGJZ8i1qW69aQ8HEL
+u/rAGSxIj1LFkMio7fvtJe7v4rebsp0cvKsJde8aWqA6gNLns1enIpXLlaMtZ3rF
+YpeB5Wn3HqsXYC/k4jz+W0M99H+qVOn7rlvc44m/YQAZZAFX/iQ7fiXM+5t6gGje
+9wF4S2tZSzJFy62FUjEHtiULjZzqRUEWahnOvvGiMp7ZD/r6s191Ryg2BmUNn7LZ
+Wxx4k6ErZ+YroWjgUESacUmG+I4Oc0Va0rHE477qRHklyj94r2s6PtcEEtJjXv+k
+M59FIa6GVz1V5pf9rU8GQLCcGTTg/V9YpjSCRwPO4gzVEZdcVkDMKnu/iQNyBBgB
+CgAmAhsCFiEEU1thAVgjRDlBx0TdEiZPa736uokFAmeP2vYFCQtJ8YEBQMB0IAQZ
+AQoAHRYhBKUpZWuzqrBd1I8zFklnD9d05DJoBQJeJxz1AAoJEElnD9d05DJo3lcI
+ALppAubOBA0+Oxda2FZTyGr20+pKWSQ3HBhPOtWoO1D6OhDMaWTnF07gXC8EKG8p
+gwUFMDp8YlbBJJ6bAQ3NXlfxyPO4FS3BwaSB6p2pbm1bJCnOOjoF6H/IVOIqKPIh
+wQ5XR3BqVX1BmKsTCoYkwzLEs/uv3pT/rZ3lGDdBiwE6a3GMF7c5zNzRBLQSkHFI
+ZLfCuyDfmKScPzBzAdf/ZCkDYMYw+nbYsAn2yuW8z7FFdWiopYst4l2qlY11bntw
+H8+PWXvl+xiqA85Qa+OLGQ+usaX3TVEvcv6q8dHwEdOPuqbDEZV7JXjmmARSjfDW
+wXHzqgvejkzplG4RTBl/nKkJEBImT2u9+rqJZDQP/AlSEw5vH4/KJeemEcT/EbNs
+DjuxY6DIqcq8SlvgFsUypuamL3XBKKl478JiiYsvDnC1RDEGVMx5ZWohb/j6bmSN
+XbPGSnUxYwHl2QabCo/U3sZX9Tx8tmK8vFMLiZDsbqLaENbDjW+nlqRkuBUVVcUm
+zqgOIiZSN6lRPeFwodN2SGfz9jx3hkfxqlAJQpgX8F1NMv04uhzjD6gY757PHbG4
+oKizUDx/cW9g5IiBXjfsUs7Y7NtuhZgm3php25Kqgn1BsTqW5yb4hn9Xkib9hsId
+qXA6zQqvH32snTGdZsnCtcKVg7nSTf2ygL322y3zywS4EwOj66wloAbjEi01Q1rG
++qcV6Q9L32vcqd0YEh8iFN+sIMqii9B+K+773u7oFFVeCAHytoycpBJxEwsXNYqy
+gCK1LrIjBQZpWnkgGgIRmWdc1Tkw8UVcjxit16sCDVnOqWAsgPottOrCZ8mh0sjs
+gacoVN2vvP4LrYWCdaSrINKWKZAZGviwZ4JN3ihNGbjBx9QW58IhxWgxcQbkXtkr
+n8LvvqEgwjXwTBPaH0oRYQ+W04MLiBlRUm91O1Il9OBOQbjIImIqVrQhRXCK5rwj
+1K4punq4vy5gU8nySTp89flOkaupEf5HxCJYL0gHR834rNNOElEBz1FkfYGuUgHR
+15VVhgWwk5g6gBSxHRgquQENBF4nHRQBCACT7LlzgNGhZKIm9kxD7D4fPuG/izxD
+/HG+NU+an3bWhhGT6qsxL3rdBz1my2f1FIjwAtkWSwOAoM9n4MCAXUUuS/0eqiCB
+wTyJRT5aJgJWTGPgzruea455R/+8iNrh/Gz+3S8leQ9T38efZ3l3JHKx5kRhvE90
+m9AaToYnU476HqEuiz0Y2sUHrhJC6D2PnthjZHm759RHAT/GDZgNvjEYfywDJmQp
+E0Wd9DrtwvVN19xsqz2OsjZTooVht1ZVtGB5YRBKUtJ8jNC5QbveIe6jwUPYIqxq
+DmyYj2XiJXdbVQcSxxzmyh4PMsDaUfrqxv/KXznxsQkoNyLeT7ATdFATABEBAAGJ
+AjwEGAEKACYCGwwWIQRTW2EBWCNEOUHHRN0SJk9rvfq6iQUCZbxlUwUJCXZ7rgAK
+CRASJk9rvfq6iSKOD/45CB3J1W86NTmkHvdW2EMFyrJFNsp8sNdLdw18OVq62qZs
+HSAQaf+YIZkmf0fqUWVcE4FLZ24Vm15oU0Q3Dv793x+LfRPHTgYZDVcdfwFCW/fj
+FJfIdq0fSUUTOBMEiChAqiTp6Go7rrPOo7Y565b+QPOuSd6HueTlrZuUfTjuRrnu
+ImkMnbNWg5isSnTtzIqzMSIgdEtvbsry5O+OhGN9mLcBl9eeF3JdhYt/oYUAcr5M
+DwXuRd0VJrsKGEjtBoVS2+n8wk9aH7CidPDLpwR8a+q0PxQFXCxyKBpLKiQ3/IX8
+roaZNlZubmH3Q4doKZI0GnIupmSaRk9Byh1BYJegkA3ELkN3cpezVUvazs0v/Aes
+VBw5nWXvWJkY5U2aQC4PjfhM+4H5/8o0KB3Xdlmb125iwj9mVBGw1VWkQydEcZzG
+LIYP+ZHhCLE/wiqdCnFUy/IBT1ca0+j+d3KfWyx5G75PYwgB3Lzrkw5wa8pGPnMb
+MgP6GDNEOve2taQVGSe14+XW/8NSw7HfGIK+V/6E+jjdPZHDUQM6VzUO6TEaqcTe
+VyhAyiFUYV0oHr5b2w/7Y6XhZkjHmpyy8/5rL8fJ02iYOJ27BtM8l9Eupb7H8pH1
+yWTSrqIjDahFFrDQRVdCoZ2paOy1J7EMKcr3TB/8ZJhVpcf6Eq5zaQPk3qNh8okC
+PAQYAQoAJgIbDBYhBFNbYQFYI0Q5QcdE3RImT2u9+rqJBQJnj9r2BQkLSfFiAAoJ
+EBImT2u9+rqJDTgP+gPbgIPKEdiSonHgosE+vA0pvELjvrEOfWbBV4roXV/SpO5T
+NMx8npEHTEoi8Ef7ERrLklCHTtLkDAdKn3LCEA0OV2akTPB5Y2aiGrSfdJngvLpt
+bgdlPVCNwh0i0GjSfzgeQUlqjDDb4fO2asnX/2yX8pMZ/muunS8PNnc7tPqtBC+b
+MNLe8dxtmWi+TIRJq/fqZy4mnz/yh79sdLpN8ey9HFvkksSYd2xtY5uNPAUcE6sP
+B5jWGsR5jJKI17RCDjUculFm9gcw+ZoM3HO+Ikh6A7QUFbN1yGBtMcCHf+3YbKw6
+G1U2kR8WP1ZprcYXOkPugo7vbKlEA/TlAFTrPL0l6crV3ALhhT/6Ke6RdgBBMsyP
+hY5hV+VO8vA2FWXxF4xoAISuKtNXuMVdtUeAi6U+2C8dGoCGgZ0WLzApTSoNoasj
+j7ZNk3HN5m1cqiO6JKAMl9OB9E3C4YqfLuDDuWmSEjzicjAvvB36i9gA8Vsd4x96
+oSVsx+2TWfulxO2rrGvq3247DxxNNLVT2UuDYIEEb1MZXjWWRLzs1h4z8pN5e6ZB
+yQEqW3h9ortT6XtXsO8H7c0r+GtD+CPIfujKXH1XT0AgeeHJSEfPYtEGxVVt5N3i
+o46MIolcnit6ncHHjfOg23XPou2dgE7zIEMLrhnVowSIoBh7ChmnLcZBPVKTuQEN
+BF4nHSgBCAC1QMrJrjjWOjQf9wF5JC52EHtDh03grRHdS0PHlnc9kLDXYw8n41KE
+N2vE2skVTKBVufQhuckCAlXd6BpisW1YoyhaLs9Bcp6Un63VH3YvRvXzKtwXJHEv
+/5SnDrGqxo5UF6xTVTxC9ux0dnSSizAeQiremr9Zuzz4B25NJCiZ2lVZUOi8iG1m
+4082owuwZWIW6qrFWi3gUGtjz32EM3eUX75BE1ZcDap7BJj2GdYsMHO2iiHBZwQV
+OXd7Fvk/23f9IeQ95D2RMgeQun8OIF+7X5zaWzyzq1Tky4pijaSsUebnFk9Cxm6K
+Rg+yXgmIjpskskCY6kj82+wqFjPRIgxfABEBAAGJAjwEGAEKACYCGyAWIQRTW2EB
+WCNEOUHHRN0SJk9rvfq6iQUCZbxlUwUJCXZ7mgAKCRASJk9rvfq6iXZRD/0YRCw/
+kkoSSrjZHULWRM528PdX2oy1o5CICnbkWJMW/TTtr/qr18e7TwkkeEViLq+Y0F2T
+a3lpeEYAOBXc+i+2fSduJSijbHwkNYyS8kg/FEL0EDrzKGm04l+FMEpZpx9Uvye3
+Kfl5GQ8dKPMddXUyD0UtelbCjb1Ie1eglc0IgdPjYjzR9UDYgHDHqfwOFCReoOmF
+ZSBTPXKz4SdARI5B1Ilqqs8HgjMAX9VQkSS8tgJBJAUNA26WLtdAawLUccl8AFBY
+f8/k/E4wkyWaMt9DT465UL0ATaTYAB9J6JzmBAyiaiW4s9dkiMQoR/kFl9Kixs12
+VfgUID4bX9n4UPDNQZ/ocXACWRU0dIw9qHm7VHWmF/Aq4+68gVppwT8UhlBZRBTC
+HqtQh+7ft6+0FD0RpmrY3nOsyrEX1rTYBx4m3x7MY184y9Gxmg3f7rUEoH9zpe6B
+f7KhBT+jd6vpb3J5tNKO1ljRA/1axc5G1vr8TKwV6WAXw0Yhx/DBP2TrgxjYpymJ
+QpWrW1AN3YM+hDEenNblaamJsz2xOR1sHdegz7STsKEkxUbS963KoRAyRP80YUmr
+Jghi0E6uyHXWA0fJpBe4107kRK4LaEBmmGNgvX2MdNN+V7+uMM7uZKfCaLUhoR7J
+R9b2fP08YuRFKDhs7YwnF2QhYBQVG10B51X5OIkCPAQYAQoAJgIbIBYhBFNbYQFY
+I0Q5QcdE3RImT2u9+rqJBQJnj9r2BQkLSfFOAAoJEBImT2u9+rqJN6sQAIMCBOht
+7Vfcag9NAU4vi6avpPblvWmIh5JmGV2x808sJp/s6qOACGKDwB1RxmtnDUmuAcdx
+MuzVJaw11kf8u/nfn4yA3/ZbE4fJx7mfdkHgfrGDWEJc5xF5cDKV+XeBPUsJvdOO
+rl+xuBQZ9+wC5IwO6DrtxoEGEvWHfwzOGzf9czCqMTm/OPYHQG1/CuNfMznwv1d2
++riyj29PuMg3dktfTl4YZNGbPADo3imWvlCObyOfpnLvLJ77yin5YFQEzD3YPo9M
+SOOcQN1V9ZWdfVURLg0Lw0r4ybci2UyNLolsJ6mh8d7SjrSOmrYwaOYM6R0Pp6/C
+emxytol5QiiGFt7XJA11s96I444nBJKIXK8+em5lpLRELlLeiI78SfsVJC2Q2hUU
+9/9fodiDOdYNhdBKEBdWqeemgBcpX6/hX4HfAx6BrdYFLxIpdRyjXvCGfDg8cbR/
++dx1NaMj1zmVsOyPUxN/fXF7zR28qc93Rl1TCl0yMMtPeJbv7cAmlMBC9qjvoNfD
+JOGKCI5Wj8A3dpNp61gUa5RFxwqX8yiWgT+Zf9IdeQekHowk3lBdUDJSN6ABOHxo
++q7K6dkVhztlT4SUnO7dlFoYF8B9xhDm3HdJCl3wh5Rt/GKjsxVzHObOVbho8wvq
+7g+tSemUj0oNo/J5K2gr6IzEF5BfBukrCdVnuQINBF5Ss1kBEACuMP/sadvOLaHs
+KyQGwI8WNpsC8u58pqkv3LTvgOQs1t5mSqJ+vTGpp8B82V1iX0Wbu6WNAhOZXu53
+zcGRJQ/9Lq/6Uzh6epE9Pt9pA+5KNVtMiFRgGEZeN065a8X+aZmBGWb1+ZLyjLcR
+WxE7RFWNi5FdYkWW2rDNZLU2gBr61eQreZDV6DyfPJrIvp8u0H+V/Pv3jAweajTQ
+Pn/MzuAxMGK9fmizsBjMpSxBrm/g4Lp3Rt8RzdJoaf/8Yi4yI5pC4qnRszzT7PiW
+ChzeEOgEdveBiVLEpDaJ5m2DrhvRZqPfrJTiJaszXgr9HLGTshHA86X3zzi+5Wg9
+Cn3COvIL08bBcyVLsMLq6z0TQ6vjmotDyVe3VpDmI23+8X4UHgY+EEfbs63vy2j0
+7cdA+dpXr+6UC+Ic/ArAnJVlSPNVRDyTuxUR4d8EAC0saxnDWnrh2udIpdKirj/j
+kTZy4ftvKp/YvERO83Dk18Hv5gHaNWM3f3LEx77UwHs5rrVgpNrQqrcWdZMphduD
+Sf3xi43vaSMe09UP6bzNMvg+eu2mSxwZVpx+pVEWjhDe3jsMEdnV1vO2JgZX2Fjw
+DWHqqIaJAHqSeEP51FfVFnj95gowbQCkPKj3xioE81IDtkQ4lgGR4sSK46/pJQy7
+PjYiI3/Nr8S21mwoZ5sc9gVe5p+yRwARAQABiQI2BCgBCgAgFiEEU1thAVgjRDlB
+x0TdEiZPa736uokFAmeP2o8CHQMACgkQEiZPa736uonUSQ/9GVuZIooAMAZ7+gV9
+N05QU/HGpWGTaj4jSx+LiTU00cUx5zdtgG5AWQIPYmcVye8r/OnhPd4BRm6yK9f4
+S6CHGQjjgIB7cDMk5MqiMSBbdJgVh6oEC/42LcBbByubq+wdz6VnlXd30PzXBwjW
+aXJa1lc4X0GggrgBGXbWJMpwdea+xnYdgdyC7L66UQ3DwijGy0WB5ntMosRdq6ct
+gkdlELdyq2F/4DRbGfnWWmfgCFPs1h861XrdQY0HNj1L4y5H4YeY8Ivsraqv00JR
+Llwbakkh4nNdKbp6Cf8XtoDsLhHcKgpUN8wqoocWsFZ4acj3ggQD/7HV+xjlF5ov
++i/eCMBelitQuiROL3UYTZZ7X81LJrR6CNU+0c9v8w+chLhvWpYVM8XMziveHfw4
+4E6Gh/90PGQCfT+e5sjTSW1fEBTZ2ZC8YpplfS7/aKWi33Jn+f5mDZz8ZurJswmG
+CDgWSjyZDSB3ylgSo/u8sLtUPmBnIfkURANA/w15xVXbQn9wNuop1DwnCA8Q4dfy
+9wm0jR/5b/ddtXQXeuTOr8Se6XQODP2Yjty+bFSR4zpRkeri7jZ+AQYphcZHxALZ
+9xoBhPCCZp9g3jItCbcYbIbDTgjbFqT3JK0tg0Ea11s7W37DvJ3I3LujqmHnXvG9
+T6Zht1J3KxuUnvda2oUKfhuE/FeJBHIEGAEKACYCGw4WIQRTW2EBWCNEOUHHRN0S
+Jk9rvfq6iQUCZbxlUwUJCUrlaQJAwXQgBBkBCgAdFiEEmIAjjep/99rtvvjkNa7S
+nzgA4CkFAl5Ss1kACgkQNa7SnzgA4Cn3bRAAlzLmitlK8+fzwzo/Rkh/LnN9lXk/
+T/lOu8VgqGQM4FZ8Qe3QioUgR2g4ZH/jCoGTMfXK8EZ6q3cm6qF7GlK+T3aSOl4H
+QAodKps8m3vvlSQiq8KXowOAR5NtY5AS3yP7Q911fGFij0tOVW4QGbvqiXTeItvw
+qNcWNzvUbOu2QDQOAIP2ds5DvxRI8f4W4a+Eccd4B4w5n08Pw46uNu8yw/oFD5X6
+p1N5SBeDFQSy+PFqWWNzTjYJOUUswZRD6dk6dyybG4/f0VMUNapfQWOVMNMtBjYp
+Gwt84baLFTv2qpJgQO55cNYpDLwCUcvSDH11rOyL5wvkmuzx/tIuSX+Okt6QocIk
+pIDByShcPrZPoscVogTBEXPllQAcmWT8m303v9tUioNqz4YrjmbCr3gMtvobwVei
+z9WGmN8QKAW4JoSexXl6XMZHJqMM9MAlErxSxSxPHxoZNfunjShOgXJfCWXbajui
+KfQ2bGmNRw152nOA3Z8tNGtJEn5BmY5/M0WVYzFQD1w64Bh/XpIemGekEZYDgXJj
+gMcR7u6m1ds7tJV/XcoESeRmtksg3oM95wC/3lVusZ1fdHqUTMtzYCnGYhRbBak0
+qwiobZqJAN8g1gxXZYA902uCN9TOrz62Mh0u507MUPh1dZfayVR90tNa2PLN5s3Q
++pYwJKd727SQgUkJEBImT2u9+rqJK4YQAIG8rSAi1DKC7wq9BMV/lcBLCzDuAmtV
+xzTGIYKhLGf9jQQg6kztwr1dPyro/fMhBpr23WtghlReMxOKHFf+g1FdMg9Rr1gu
+mnfZxmVKkYaQEg31e+k8Nr/d6DcBym3NuR6rt4wHL6mxbfyJ0XsgknE+LhQaDgUc
++K2JKMm0udppKGDwm9vtqIbmMIQqh+EPG4MaqmXq1uncloEKYQ3Rs9IVz+vtifEC
+ydNX90gcIvGk9Nf4YzlBhPTj3mah+thdXfwmnELX++u63h8SqnEnFPJKHennqFTr
+GXUZ7D2mZj4VzzOzLaS9fQTtlSpKB6emh23fHndiDyr0ucKu2+3oVL3v8cqB9VeQ
++eKI6RdYMoygMezI4qu9fd6TkP1XicfDiXEMbmvBZ3ZQADC1Gb2kiRde/qZNewZu
+UGGBjXtmbzeGtENjaVy55/Vb29hhMkeXAW22aZnp01gPRoqR5hxhVLreqcKqVnlb
+W5FMvwFK/SYAAeFauQmGv++K3YFpin1rEKd6KQP4KmNVUDa4v09ImNrMCtwFMhSg
+wExue4DEExWrVRhZ8IczBAnXn1a1aZn3BlOaUeKyrcLQeLrGXhyQ3YV+LK8J5N9D
+Q65x2UVpB7BnxLsOe9+eIA2vyLFMw7hq3biljKmQXNMKIBseL+pGX/yE8Dzx36yI
+GmeDneCrlseO
+=ncr2
 -----END PGP PUBLIC KEY BLOCK-----

From 37c4613ab33678fd7c53e41f0c4bf667d2cbe1a7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Thu, 30 Jan 2025 04:01:09 +0800
Subject: [PATCH 175/212] fix: Add gateway for internet access in test envs

---
 configuration/hardware-specific/vm.nix | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/configuration/hardware-specific/vm.nix b/configuration/hardware-specific/vm.nix
index 1783956..225a846 100644
--- a/configuration/hardware-specific/vm.nix
+++ b/configuration/hardware-specific/vm.nix
@@ -15,6 +15,9 @@
 
   systemd.network.networks."10-eth0" = {
     matchConfig.Name = "eth0";
+    gateway = [
+      "192.168.9.1"
+    ];
     networkConfig = {
       Address = "192.168.9.2/24";
     };

From cf751d01992fec0e19957658f1866d98ed1ae720 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 31 Jan 2025 22:31:10 +0800
Subject: [PATCH 176/212] feat: Don't run battery manager in test VM

---
 configuration/hardware-specific/vm.nix | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/configuration/hardware-specific/vm.nix b/configuration/hardware-specific/vm.nix
index 225a846..db563fe 100644
--- a/configuration/hardware-specific/vm.nix
+++ b/configuration/hardware-specific/vm.nix
@@ -23,6 +23,9 @@
     };
   };
 
+  # Don't run this
+  services.batteryManager.enable = lib.mkForce false;
+
   # Both so we have a predictable key for the staging env, as well as
   # to have a static key for decrypting the sops secrets for the
   # staging env.

From 22981fdcdd70c30436fd34133af3f6e8c8e7ae29 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 24 Jan 2025 00:34:25 +0800
Subject: [PATCH 177/212] feat: Remove fail2ban

---
 configuration/default.nix                    |  1 -
 configuration/services/fail2ban.nix          | 43 -----------
 configuration/services/gitea.nix             | 18 -----
 configuration/services/metrics/exporters.nix | 28 -------
 configuration/services/metrics/options.nix   |  1 +
 configuration/services/nextcloud.nix         | 23 ------
 flake.lock                                   | 78 +-------------------
 flake.nix                                    | 17 -----
 pkgs/_sources_pkgs/generated.json            | 22 ------
 pkgs/_sources_pkgs/generated.nix             | 17 -----
 pkgs/default.nix                             |  3 -
 pkgs/nvfetcher.toml                          |  3 -
 pkgs/prometheus/fail2ban-exporter.nix        |  5 --
 13 files changed, 4 insertions(+), 255 deletions(-)
 delete mode 100644 configuration/services/fail2ban.nix
 delete mode 100644 pkgs/_sources_pkgs/generated.json
 delete mode 100644 pkgs/_sources_pkgs/generated.nix
 delete mode 100644 pkgs/nvfetcher.toml
 delete mode 100644 pkgs/prometheus/fail2ban-exporter.nix

diff --git a/configuration/default.nix b/configuration/default.nix
index 18d124e..a22f8fc 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -18,7 +18,6 @@
     ./services/backups.nix
     ./services/battery-manager.nix
     ./services/conduit.nix
-    ./services/fail2ban.nix
     ./services/foundryvtt.nix
     ./services/gitea.nix
     ./services/metrics
diff --git a/configuration/services/fail2ban.nix b/configuration/services/fail2ban.nix
deleted file mode 100644
index f09668c..0000000
--- a/configuration/services/fail2ban.nix
+++ /dev/null
@@ -1,43 +0,0 @@
-{ pkgs, ... }:
-{
-  services.fail2ban = {
-    enable = true;
-    extraPackages = [ pkgs.ipset ];
-    banaction = "iptables-ipset-proto6-allports";
-    bantime-increment.enable = true;
-
-    jails = {
-      nginx-botsearch = ''
-        enabled = true
-        logpath = /var/log/nginx/access.log
-      '';
-    };
-
-    ignoreIP = [
-      "127.0.0.0/8"
-      "10.0.0.0/8"
-      "172.16.0.0/12"
-      "192.168.0.0/16"
-    ];
-  };
-
-  # Allow metrics services to connect to the socket as well
-  users.groups.fail2ban = { };
-  systemd.services.fail2ban.serviceConfig = {
-    ExecStartPost =
-      "+"
-      + (pkgs.writeShellScript "fail2ban-post-start" ''
-        while ! [ -S /var/run/fail2ban/fail2ban.sock ]; do
-            sleep 1
-        done
-
-        while ! ${pkgs.netcat}/bin/nc -zU /var/run/fail2ban/fail2ban.sock; do
-            sleep 1
-        done
-
-        ${pkgs.coreutils}/bin/chown root:fail2ban /var/run/fail2ban /var/run/fail2ban/fail2ban.sock
-        ${pkgs.coreutils}/bin/chmod 660 /var/run/fail2ban/fail2ban.sock
-        ${pkgs.coreutils}/bin/chmod 710 /var/run/fail2ban
-      '');
-  };
-}
diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index c88dd01..da01cde 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -59,24 +59,6 @@ in
       };
     };
 
-  # Block repeated failed login attempts
-  #
-  # TODO(tlater): Update this - we switched to forgejo, who knows what
-  # the new matches are.
-  # environment.etc = {
-  #   "fail2ban/filter.d/gitea.conf".text = ''
-  #     [Definition]
-  #     failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>
-  #     journalmatch = _SYSTEMD_UNIT=forgejo.service + _COMM=forgejo + SYSLOG_IDENTIFIER=forgejo
-  #   '';
-  # };
-
-  # services.fail2ban.jails = {
-  #   gitea = ''
-  #     enabled = true
-  #   '';
-  # };
-
   services.backups.forgejo = {
     user = "forgejo";
     paths = [
diff --git a/configuration/services/metrics/exporters.nix b/configuration/services/metrics/exporters.nix
index e16b945..ecd69bd 100644
--- a/configuration/services/metrics/exporters.nix
+++ b/configuration/services/metrics/exporters.nix
@@ -68,34 +68,6 @@ in
       };
     };
 
-    extraExporters = {
-      fail2ban =
-        let
-          cfg = config.services.prometheus.extraExporters.fail2ban;
-        in
-        {
-          port = 9191;
-          serviceOpts = {
-            after = [ "fail2ban.service" ];
-            requires = [ "fail2ban.service" ];
-            serviceConfig = {
-              Group = "fail2ban";
-              RestrictAddressFamilies = [
-                "AF_UNIX"
-                "AF_INET"
-                "AF_INET6"
-              ];
-              ExecStart = lib.concatStringsSep " " [
-                "${pkgs.local.prometheus-fail2ban-exporter}/bin/fail2ban-prometheus-exporter"
-                "--collector.f2b.socket=/var/run/fail2ban/fail2ban.sock"
-                "--web.listen-address='${cfg.listenAddress}:${toString cfg.port}'"
-                "--collector.f2b.exit-on-socket-connection-error=true"
-              ];
-            };
-          };
-        };
-    };
-
     # TODO(tlater):
     #   - wireguard (?)
     #   - postgres (?)
diff --git a/configuration/services/metrics/options.nix b/configuration/services/metrics/options.nix
index 69cbd6b..8868c6c 100644
--- a/configuration/services/metrics/options.nix
+++ b/configuration/services/metrics/options.nix
@@ -12,6 +12,7 @@ in
   options = {
     services.prometheus = {
       extraExporters = mkOption {
+        default = { };
         type = types.attrsOf (
           types.submodule {
             options = {
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index e54df14..b5cb691 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -70,29 +70,6 @@ in
     # The upstream module already adds HSTS
   };
 
-  # Block repeated failed login attempts
-  environment.etc = {
-    "fail2ban/filter.d/nextcloud.conf".text = ''
-      [Definition]
-      _groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
-      failregex = \{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
-                  \{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error.
-      datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"
-      journalmatch = SYSLOG_IDENTIFIER=Nextcloud
-    '';
-  };
-
-  services.fail2ban.jails = {
-    nextcloud = ''
-      enabled = true
-
-      # Nextcloud does some throttling already, so we need to set
-      # these to something bigger.
-      findtime = 43200
-      bantime = 86400
-    '';
-  };
-
   services.backups.nextcloud = {
     user = "nextcloud";
     paths = [
diff --git a/flake.lock b/flake.lock
index d349bea..d761f4f 100644
--- a/flake.lock
+++ b/flake.lock
@@ -114,44 +114,10 @@
         "type": "github"
       }
     },
-    "flake-compat_3": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1696426674,
-        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
-        "owner": "edolstra",
-        "repo": "flake-compat",
-        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
-        "type": "github"
-      },
-      "original": {
-        "owner": "edolstra",
-        "repo": "flake-compat",
-        "type": "github"
-      }
-    },
     "flake-utils": {
       "inputs": {
         "systems": "systems_2"
       },
-      "locked": {
-        "lastModified": 1731533236,
-        "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
-        "type": "github"
-      },
-      "original": {
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "type": "github"
-      }
-    },
-    "flake-utils_2": {
-      "inputs": {
-        "systems": "systems_3"
-      },
       "locked": {
         "lastModified": 1726560853,
         "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
@@ -272,37 +238,15 @@
         "type": "github"
       }
     },
-    "nvfetcher": {
-      "inputs": {
-        "flake-compat": "flake-compat_2",
-        "flake-utils": "flake-utils",
-        "nixpkgs": [
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1732501185,
-        "narHash": "sha256-Z0BpHelaGQsE5VD9hBsBHsvMU9h+Xt0kfkDJyFivZOU=",
-        "owner": "berberman",
-        "repo": "nvfetcher",
-        "rev": "bdb14eab6fe9cefc29efe01e60c3a3f616d6b62a",
-        "type": "github"
-      },
-      "original": {
-        "owner": "berberman",
-        "repo": "nvfetcher",
-        "type": "github"
-      }
-    },
     "poetry2nixi": {
       "inputs": {
-        "flake-utils": "flake-utils_2",
+        "flake-utils": "flake-utils",
         "nix-github-actions": "nix-github-actions",
         "nixpkgs": [
           "sonnenshift",
           "nixpkgs"
         ],
-        "systems": "systems_4",
+        "systems": "systems_3",
         "treefmt-nix": "treefmt-nix"
       },
       "locked": {
@@ -321,7 +265,7 @@
     },
     "purescript-overlay": {
       "inputs": {
-        "flake-compat": "flake-compat_3",
+        "flake-compat": "flake-compat_2",
         "nixpkgs": [
           "tlaternet-webserver",
           "dream2nix",
@@ -367,7 +311,6 @@
         "foundryvtt": "foundryvtt",
         "nixpkgs": "nixpkgs_2",
         "nixpkgs-unstable": "nixpkgs-unstable",
-        "nvfetcher": "nvfetcher",
         "sonnenshift": "sonnenshift",
         "sops-nix": "sops-nix",
         "tlaternet-webserver": "tlaternet-webserver"
@@ -485,21 +428,6 @@
       }
     },
     "systems_3": {
-      "locked": {
-        "lastModified": 1681028828,
-        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
-        "owner": "nix-systems",
-        "repo": "default",
-        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nix-systems",
-        "repo": "default",
-        "type": "github"
-      }
-    },
-    "systems_4": {
       "locked": {
         "lastModified": 1681028828,
         "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
diff --git a/flake.nix b/flake.nix
index e6f1dcb..2253566 100644
--- a/flake.nix
+++ b/flake.nix
@@ -13,10 +13,6 @@
       url = "github:Mic92/sops-nix";
       inputs.nixpkgs.follows = "nixpkgs";
     };
-    nvfetcher = {
-      url = "github:berberman/nvfetcher";
-      inputs.nixpkgs.follows = "nixpkgs";
-    };
     tlaternet-webserver = {
       url = "git+https://gitea.tlater.net/tlaternet/tlaternet.git";
       inputs.nixpkgs.follows = "nixpkgs";
@@ -37,7 +33,6 @@
       self,
       nixpkgs,
       sops-nix,
-      nvfetcher,
       deploy-rs,
       ...
     }@inputs:
@@ -120,18 +115,6 @@
               ${vm.config.system.build.vm.outPath}/bin/run-testvm-vm
             '').outPath;
         };
-
-        update-pkgs = {
-          type = "app";
-          program =
-            let
-              nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher";
-            in
-            (pkgs.writeShellScript "update-pkgs" ''
-              cd "$(git rev-parse --show-toplevel)/pkgs"
-              ${nvfetcher-bin} -o _sources_pkgs -c nvfetcher.toml
-            '').outPath;
-        };
       };
 
       ###########################
diff --git a/pkgs/_sources_pkgs/generated.json b/pkgs/_sources_pkgs/generated.json
deleted file mode 100644
index cec5a92..0000000
--- a/pkgs/_sources_pkgs/generated.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-    "prometheus-fail2ban-exporter": {
-        "cargoLocks": null,
-        "date": null,
-        "extract": null,
-        "name": "prometheus-fail2ban-exporter",
-        "passthru": null,
-        "pinned": false,
-        "src": {
-            "deepClone": false,
-            "fetchSubmodules": false,
-            "leaveDotGit": false,
-            "name": null,
-            "rev": "v0.10.1",
-            "sha256": "sha256-zGEhDy3uXIbvx4agSA8Mx7bRtiZZtoDZGbNbHc9L+yI=",
-            "sparseCheckout": [],
-            "type": "git",
-            "url": "https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter"
-        },
-        "version": "v0.10.1"
-    }
-}
\ No newline at end of file
diff --git a/pkgs/_sources_pkgs/generated.nix b/pkgs/_sources_pkgs/generated.nix
deleted file mode 100644
index 95fd75e..0000000
--- a/pkgs/_sources_pkgs/generated.nix
+++ /dev/null
@@ -1,17 +0,0 @@
-# This file was generated by nvfetcher, please do not modify it manually.
-{ fetchgit, fetchurl, fetchFromGitHub, dockerTools }:
-{
-  prometheus-fail2ban-exporter = {
-    pname = "prometheus-fail2ban-exporter";
-    version = "v0.10.1";
-    src = fetchgit {
-      url = "https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter";
-      rev = "v0.10.1";
-      fetchSubmodules = false;
-      deepClone = false;
-      leaveDotGit = false;
-      sparseCheckout = [ ];
-      sha256 = "sha256-zGEhDy3uXIbvx4agSA8Mx7bRtiZZtoDZGbNbHc9L+yI=";
-    };
-  };
-}
diff --git a/pkgs/default.nix b/pkgs/default.nix
index 131282d..036afd4 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -4,7 +4,4 @@ let
 in
 {
   starbound = callPackage ./starbound { };
-  prometheus-fail2ban-exporter = callPackage ./prometheus/fail2ban-exporter.nix {
-    sources = pkgs.callPackage ./_sources_pkgs/generated.nix { };
-  };
 }
diff --git a/pkgs/nvfetcher.toml b/pkgs/nvfetcher.toml
deleted file mode 100644
index d0dfbe5..0000000
--- a/pkgs/nvfetcher.toml
+++ /dev/null
@@ -1,3 +0,0 @@
-[prometheus-fail2ban-exporter]
-src.manual = "v0.10.1" # No gitlab support in nvfetcher
-fetch.git = "https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter"
diff --git a/pkgs/prometheus/fail2ban-exporter.nix b/pkgs/prometheus/fail2ban-exporter.nix
deleted file mode 100644
index dc22b6c..0000000
--- a/pkgs/prometheus/fail2ban-exporter.nix
+++ /dev/null
@@ -1,5 +0,0 @@
-{ buildGoModule, sources }:
-buildGoModule {
-  inherit (sources.prometheus-fail2ban-exporter) pname src version;
-  vendorHash = "sha256-5o8p5p0U/c0WAIV5dACnWA3ThzSh2tt5LIFMb59i9GY=";
-}

From d0c6f2bcbe387ed451cfa5a83d3ad78c9725cc3a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 24 Jan 2025 00:35:23 +0800
Subject: [PATCH 178/212] feat: Add crowdsec module

---
 flake.lock                                    |  17 +
 flake.nix                                     |  29 +-
 modules/crowdsec/default.nix                  | 361 ++++++++++++++++++
 .../remediations/cs-firewall-bouncer.nix      |  90 +++++
 modules/crowdsec/remediations/default.nix     |   5 +
 modules/default.nix                           |   7 +-
 pkgs/crowdsec/_sources/generated.json         |  42 ++
 pkgs/crowdsec/_sources/generated.nix          |  27 ++
 pkgs/crowdsec/default.nix                     |   9 +
 pkgs/crowdsec/firewall-bouncer.nix            |  26 ++
 pkgs/crowdsec/hub.nix                         |   4 +
 pkgs/crowdsec/nvfetcher.toml                  |   7 +
 pkgs/default.nix                              |   6 +-
 13 files changed, 624 insertions(+), 6 deletions(-)
 create mode 100644 modules/crowdsec/default.nix
 create mode 100644 modules/crowdsec/remediations/cs-firewall-bouncer.nix
 create mode 100644 modules/crowdsec/remediations/default.nix
 create mode 100644 pkgs/crowdsec/_sources/generated.json
 create mode 100644 pkgs/crowdsec/_sources/generated.nix
 create mode 100644 pkgs/crowdsec/default.nix
 create mode 100644 pkgs/crowdsec/firewall-bouncer.nix
 create mode 100644 pkgs/crowdsec/hub.nix
 create mode 100644 pkgs/crowdsec/nvfetcher.toml

diff --git a/flake.lock b/flake.lock
index d761f4f..d86b361 100644
--- a/flake.lock
+++ b/flake.lock
@@ -190,6 +190,22 @@
         "type": "github"
       }
     },
+    "nixpkgs-crowdsec": {
+      "locked": {
+        "lastModified": 1738085579,
+        "narHash": "sha256-7mLjMrOiiIi0vI7BJwbEipYQzwA7JF/NWHP+LM4q5S8=",
+        "owner": "tlater",
+        "repo": "nixpkgs",
+        "rev": "426a7afc9a6ecfdac544bda4022acef31e36df34",
+        "type": "github"
+      },
+      "original": {
+        "owner": "tlater",
+        "ref": "tlater/fix-crowdsec",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
     "nixpkgs-unstable": {
       "locked": {
         "lastModified": 1737192615,
@@ -310,6 +326,7 @@
         "disko": "disko",
         "foundryvtt": "foundryvtt",
         "nixpkgs": "nixpkgs_2",
+        "nixpkgs-crowdsec": "nixpkgs-crowdsec",
         "nixpkgs-unstable": "nixpkgs-unstable",
         "sonnenshift": "sonnenshift",
         "sops-nix": "sops-nix",
diff --git a/flake.nix b/flake.nix
index 2253566..3d04d7c 100644
--- a/flake.nix
+++ b/flake.nix
@@ -26,6 +26,8 @@
       url = "git+ssh://git@github.com/sonnenshift/battery-manager";
       inputs.nixpkgs.follows = "nixpkgs";
     };
+
+    nixpkgs-crowdsec.url = "github:tlater/nixpkgs/tlater/fix-crowdsec";
   };
 
   outputs =
@@ -98,7 +100,16 @@
       # Garbage collection root #
       ###########################
 
-      packages.${system}.default = vm.config.system.build.vm;
+      packages.${system} =
+        let
+          localPkgs = import ./pkgs { inherit pkgs; };
+        in
+        {
+          default = vm.config.system.build.vm;
+          crowdsec = pkgs.callPackage "${inputs.nixpkgs-crowdsec}/pkgs/by-name/cr/crowdsec/package.nix" { };
+          crowdsec-hub = localPkgs.crowdsec.hub;
+          crowdsec-firewall-bouncer = localPkgs.crowdsec.firewall-bouncer;
+        };
 
       ###################
       # Utility scripts #
@@ -115,6 +126,22 @@
               ${vm.config.system.build.vm.outPath}/bin/run-testvm-vm
             '').outPath;
         };
+
+        update-crowdsec-packages =
+          let
+            git = pkgs.lib.getExe pkgs.git;
+            nvfetcher = pkgs.lib.getExe pkgs.nvfetcher;
+          in
+          {
+            type = "app";
+            program =
+              (pkgs.writeShellScript "update-crowdsec-packages" ''
+                cd "$(${git} rev-parse --show-toplevel)"
+                cd ./pkgs/crowdsec
+                ${nvfetcher}
+                echo 'Remember to update the vendorHash of any go packages!'
+              '').outPath;
+          };
       };
 
       ###########################
diff --git a/modules/crowdsec/default.nix b/modules/crowdsec/default.nix
new file mode 100644
index 0000000..915ca0b
--- /dev/null
+++ b/modules/crowdsec/default.nix
@@ -0,0 +1,361 @@
+{
+  flake-inputs,
+  pkgs,
+  lib,
+  config,
+  ...
+}:
+let
+  cfg = config.security.crowdsec;
+  settingsFormat = pkgs.formats.yaml { };
+
+  crowdsec = flake-inputs.self.packages.${pkgs.system}.crowdsec;
+
+  hub = pkgs.fetchFromGitHub {
+    owner = "crowdsecurity";
+    repo = "hub";
+    rev = "7a3b4753f4577257c0cbeb8f8f90c7f17d2ae008";
+    hash = "sha256-HB4jHyhiO8gjBkLmpo6bDbwhfm5m5nAtNlKhDkZjt2I=";
+  };
+
+  cscli = pkgs.writeShellScriptBin "cscli" ''
+    export PATH="$PATH:${crowdsec}/bin/"
+
+    sudo=exec
+    if [ "$USER" != "crowdsec" ]; then
+        sudo='exec /run/wrappers/bin/sudo -u crowdsec'
+    fi
+
+    $sudo ${crowdsec}/bin/cscli "$@"
+  '';
+in
+{
+  imports = [ ./remediations ];
+
+  options.security.crowdsec =
+    let
+      inherit (lib.types)
+        nullOr
+        listOf
+        package
+        path
+        str
+        ;
+    in
+    {
+      enable = lib.mkEnableOption "crowdsec";
+
+      package = lib.mkOption {
+        type = package;
+        default = crowdsec;
+      };
+
+      stateDirectory = lib.mkOption {
+        type = path;
+        readOnly = true;
+
+        description = ''
+          The state directory of the crowdsec instance. Cannot be
+          changed, but is exposed for downstream use.
+        '';
+      };
+
+      settings = lib.mkOption {
+        inherit (settingsFormat) type;
+        default = { };
+
+        description = ''
+          The crowdsec configuration. Refer to
+          <https://docs.crowdsec.net/docs/next/configuration/crowdsec_configuration/>
+          for details on supported values.
+        '';
+      };
+
+      parserWhitelist = lib.mkOption {
+        type = listOf str;
+        default = [ ];
+        description = ''
+          Set of IP addresses to add to a parser-based whitelist.
+
+          Addresses can be specified either as plain IP addresses or
+          in CIDR notation.
+        '';
+      };
+
+      hubConfigurations = {
+        collections = lib.mkOption {
+          type = listOf str;
+          description = ''
+            List of pre-made crowdsec collections to install.
+          '';
+        };
+
+        scenarios = lib.mkOption {
+          type = listOf str;
+          description = ''
+            List of pre-made crowdsec scenarios to install.
+          '';
+        };
+
+        parsers = lib.mkOption {
+          type = listOf str;
+          description = ''
+            List of pre-made crowdsec parsers to install.
+          '';
+        };
+
+        postoverflows = lib.mkOption {
+          type = listOf str;
+          description = ''
+            List of pre-made crowdsec postoverflows to install.
+          '';
+        };
+
+        appsecConfigs = lib.mkOption {
+          type = listOf str;
+          description = ''
+            List of pre-made crowdsec appsec configurations to install.
+          '';
+        };
+
+        appsecRules = lib.mkOption {
+          type = listOf str;
+          description = ''
+            List of pre-made crowdsec appsec rules to install.
+          '';
+        };
+      };
+
+      centralApiCredentials = lib.mkOption {
+        type = nullOr path;
+        default = null;
+
+        description = ''
+          The API key to access crowdsec's central API - this is
+          required to access any of the shared blocklists.
+
+          Use of this feature is optional, entering no API key (the
+          default) turns all sharing or receiving of blocked IPs off.
+
+          Note that adding the API key by itself does not enable
+          sharing of blocked IPs with the central API. This limits the
+          types of blocklists this instance can access.
+
+          To also turn sharing blocked IPs on, set
+          `api.server.online_client.sharing = true;`.
+        '';
+      };
+
+      ctiApiKey = lib.mkOption {
+        type = nullOr path;
+        default = null;
+
+        description = ''
+          The API key for crowdsec's CTI offering.
+        '';
+      };
+    };
+
+  config = lib.mkIf cfg.enable {
+    # Set up default settings; anything that *shouldn't* be changed is
+    # set to the default priority so that users need to use
+    # `lib.mkForce`.
+    security.crowdsec = {
+      stateDirectory = "/var/lib/crowdsec";
+
+      settings = {
+        common = {
+          daemonize = true;
+          # The default logs to files, which isn't the preferred way
+          # on NixOS
+          log_media = "stdout";
+        };
+
+        config_paths = {
+          config_dir = "${cfg.stateDirectory}/config/";
+          data_dir = "${cfg.stateDirectory}/data/";
+          # This "config" file is intended to be written to using the
+          # cscli tool, so you can temporarily make it so rules don't
+          # do anything but log what they *would* do for
+          # experimentation.
+          simulation_path = "${cfg.stateDirectory}/config/simulation.yaml";
+
+          pattern_dir = lib.mkDefault "${cfg.package}/share/crowdsec/config/patterns";
+
+          hub_dir = hub;
+          index_path = "${hub}/.index.json";
+
+          # Integrations aren't supported for now
+          notification_dir = lib.mkDefault "/var/empty/";
+          plugin_dir = lib.mkDefault "/var/empty/";
+        };
+
+        crowdsec_service.acquisition_path = lib.mkDefault "${cfg.package}/share/crowdsec/config/acquis.yaml";
+
+        cscli = {
+          prometheus_uri = lib.mkDefault "127.0.0.1:6060";
+        };
+
+        db_config = {
+          type = lib.mkDefault "sqlite";
+          db_path = lib.mkDefault "${cfg.stateDirectory}/data/crowdsec.db";
+          use_wal = lib.mkDefault true;
+          flush = {
+            max_items = lib.mkDefault 5000;
+            max_age = lib.mkDefault "7d";
+          };
+        };
+
+        api = {
+          cti = {
+            enabled = cfg.ctiApiKey != null;
+            key = cfg.ctiApiKey;
+          };
+          client.credentials_path = "${cfg.stateDirectory}/local_credentials.yaml";
+          server = {
+            listen_uri = lib.mkDefault "127.0.0.1:8080";
+            profiles_path = lib.mkDefault "${cfg.package}/share/crowdsec/config/profiles.yaml";
+            console_path = lib.mkDefault "${cfg.package}/share/crowdsec/config/console.yaml";
+
+            online_client = {
+              # By default, we don't let crowdsec phone home, since
+              # this is usually within NixOS users' concerns.
+              #
+              # TODO: Enable when this option becomes available
+              # (1.6.4, current nixpkgs-unstable)
+              # sharing = lib.mkDefault false;
+              credentials_path = cfg.centralApiCredentials;
+            };
+          };
+        };
+
+        # We enable prometheus by default, since cscli relies on it
+        # for metrics
+        prometheus = {
+          enabled = lib.mkDefault true;
+          level = lib.mkDefault "full";
+          listen_addr = lib.mkDefault "127.0.0.1";
+          listen_port = lib.mkDefault 6060;
+        };
+      };
+    };
+
+    systemd.packages = [
+      cfg.package
+    ];
+
+    environment = {
+      systemPackages = [
+        # To add completions; sadly need to hand-roll this since
+        # neither `symlinkJoin` nor `buildEnv` have collision
+        # handling.
+        (pkgs.runCommandNoCCLocal "cscli" { } ''
+          mkdir -p $out
+          ln -s ${cscli}/bin $out/bin
+          ln -s ${cfg.package}/share $out/share
+        '')
+      ];
+
+      etc."crowdsec/config.yaml".source = settingsFormat.generate "crowdsec-settings.yaml" cfg.settings;
+    };
+
+    systemd = {
+      tmpfiles.settings."10-crowdsec" = {
+        "${cfg.stateDirectory}".d = {
+          user = "crowdsec";
+          group = "crowdsec";
+          mode = "0700";
+        };
+
+        # This must be created for the setup service to work
+        "${cfg.stateDirectory}/config".d = {
+          user = "crowdsec";
+          group = "crowdsec";
+          mode = "0700";
+        };
+
+        "${cfg.stateDirectory}/config/parsers".d = lib.mkIf (cfg.parserWhitelist != [ ]) {
+          user = "crowdsec";
+          group = "crowdsec";
+          mode = "0700";
+        };
+
+        "${cfg.stateDirectory}/config/parsers/s02-enrich".d = lib.mkIf (cfg.parserWhitelist != [ ]) {
+          user = "crowdsec";
+          group = "crowdsec";
+          mode = "0700";
+        };
+
+        "${cfg.stateDirectory}/config/parsers/s02-enrich/nixos-whitelist.yaml" =
+          lib.mkIf (cfg.parserWhitelist != [ ])
+            {
+              "L+".argument =
+                (settingsFormat.generate "crowdsec-nixos-whitelist.yaml" {
+                  name = "nixos/parser-whitelist";
+                  description = "Parser whitelist generated by the crowdsec NixOS module";
+                  whitelist = {
+                    reason = "Filtered by NixOS whitelist";
+                    ip = lib.lists.filter (ip: !(lib.hasInfix "/" ip)) cfg.parserWhitelist;
+                    cidr = lib.lists.filter (ip: lib.hasInfix "/" ip) cfg.parserWhitelist;
+                  };
+                }).outPath;
+            };
+      };
+
+      services = {
+        crowdsec-setup = {
+          # TODO(tlater): Depend on tmpfiles path for
+          # /var/lib/crowdsec/config
+          description = "Crowdsec database and config preparation";
+
+          script = ''
+            if [ ! -e '${cfg.settings.config_paths.simulation_path}' ]; then
+                cp '${cfg.package}/share/crowdsec/config/simulation.yaml' '${cfg.settings.config_paths.simulation_path}'
+            fi
+
+            if [ ! -e '${cfg.settings.api.client.credentials_path}' ]; then
+                ${cfg.package}/bin/cscli machines add --auto --file '${cfg.settings.api.client.credentials_path}'
+            fi
+          '';
+
+          serviceConfig = {
+            User = "crowdsec";
+            Group = "crowdsec";
+            StateDirectory = "crowdsec";
+
+            Type = "oneshot";
+            RemainAfterExit = true;
+          };
+        };
+
+        # Note that the service basics are already defined upstream
+        crowdsec = {
+          enable = true;
+
+          after = [ "crowdsec-setup.service" ];
+          bindsTo = [ "crowdsec-setup.service" ];
+          wantedBy = [ "multi-user.target" ];
+
+          serviceConfig = {
+            User = "crowdsec";
+            Group = "crowdsec";
+            SupplementaryGroups = [ "systemd-journal" ];
+
+            StateDirectory = "crowdsec";
+          };
+        };
+      };
+    };
+
+    users = {
+      users.crowdsec = {
+        isSystemUser = true;
+        home = cfg.stateDirectory;
+        group = "crowdsec";
+      };
+      groups = {
+        crowdsec = { };
+      };
+    };
+  };
+}
diff --git a/modules/crowdsec/remediations/cs-firewall-bouncer.nix b/modules/crowdsec/remediations/cs-firewall-bouncer.nix
new file mode 100644
index 0000000..aa70552
--- /dev/null
+++ b/modules/crowdsec/remediations/cs-firewall-bouncer.nix
@@ -0,0 +1,90 @@
+{
+  flake-inputs,
+  pkgs,
+  lib,
+  config,
+  ...
+}:
+let
+  crowdsecCfg = config.security.crowdsec;
+  cfg = crowdsecCfg.remediationComponents.firewallBouncer;
+  settingsFormat = pkgs.formats.yaml { };
+  crowdsec-firewall-bouncer = flake-inputs.self.packages.${pkgs.system}.crowdsec-firewall-bouncer;
+in
+{
+  options.security.crowdsec.remediationComponents.firewallBouncer = {
+    enable = lib.mkEnableOption "cs-firewall-bouncer";
+
+    settings = lib.mkOption {
+      inherit (settingsFormat) type;
+      default = { };
+
+      description = ''
+        The bouncer configuration. Refer to
+        <https://docs.crowdsec.net/u/bouncers/firewall/> for details
+        on supported values.
+      '';
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    security.crowdsec.remediationComponents.firewallBouncer.settings = {
+      mode = lib.mkDefault "${if config.networking.nftables.enable then "nftables" else "iptables"}";
+      log_mode = "stdout";
+      iptables_chains = [
+        "nixos-fw"
+      ];
+
+      # Don't let users easily override this; unfortunately we need to
+      # set up this key through substitution at runtime.
+      api_key = lib.mkForce "\${API_KEY}";
+      api_url = lib.mkDefault "http://${crowdsecCfg.settings.api.server.listen_uri}";
+    };
+
+    systemd = {
+      packages = [ crowdsec-firewall-bouncer ];
+
+      services = {
+        crowdsec-firewall-bouncer-setup = {
+          description = "Crowdsec firewall bouncer config preparation";
+          script = ''
+            if [ ! -e '${crowdsecCfg.stateDirectory}/firewall_bouncer_credentials.yaml' ]; then
+                ${crowdsecCfg.package}/bin/cscli -oraw bouncers add "cs-firewall-bouncer-$(${pkgs.coreutils}/bin/date +%s)" > \
+                  ${crowdsecCfg.stateDirectory}/firewall_bouncer_credentials.yaml
+            fi
+
+            # Stdout redirection is deliberately used to forcibly
+            # overwrite the file if it exists
+            API_KEY="$(<${crowdsecCfg.stateDirectory}/firewall_bouncer_credentials.yaml)" \
+              ${lib.getExe pkgs.envsubst} \
+              -i ${settingsFormat.generate "crowdsec-firewall-bouncer.yaml" cfg.settings} \
+              > /var/lib/crowdsec/config/crowdsec-firewall-bouncer.yaml
+          '';
+
+          serviceConfig = {
+            User = "crowdsec";
+            Group = "crowdsec";
+
+            Type = "oneshot";
+            RemainAfterExit = true;
+          };
+        };
+
+        crowdsec-firewall-bouncer = {
+          enable = true;
+
+          after = [ "crowdsec-firewall-bouncer-setup.service" ];
+          bindsTo = [ "crowdsec-firewall-bouncer-setup.service" ];
+          requiredBy = [ "crowdsec.service" ];
+
+          path =
+            lib.optionals (cfg.settings.mode == "ipset" || cfg.settings.mode == "iptables") [
+              pkgs.ipset
+            ]
+            ++ lib.optional (cfg.settings.mode == "iptables") pkgs.iptables
+            ++ lib.optional (cfg.settings.mode == "nftables") pkgs.nftables;
+        };
+      };
+    };
+  };
+}
diff --git a/modules/crowdsec/remediations/default.nix b/modules/crowdsec/remediations/default.nix
new file mode 100644
index 0000000..7df6ade
--- /dev/null
+++ b/modules/crowdsec/remediations/default.nix
@@ -0,0 +1,5 @@
+{
+  imports = [
+    ./cs-firewall-bouncer.nix
+  ];
+}
diff --git a/modules/default.nix b/modules/default.nix
index e1db4cc..89f1752 100644
--- a/modules/default.nix
+++ b/modules/default.nix
@@ -1 +1,6 @@
-{ imports = [ ./nginxExtensions.nix ]; }
+{
+  imports = [
+    ./crowdsec
+    ./nginxExtensions.nix
+  ];
+}
diff --git a/pkgs/crowdsec/_sources/generated.json b/pkgs/crowdsec/_sources/generated.json
new file mode 100644
index 0000000..8485779
--- /dev/null
+++ b/pkgs/crowdsec/_sources/generated.json
@@ -0,0 +1,42 @@
+{
+    "crowdsec-firewall-bouncer": {
+        "cargoLocks": null,
+        "date": null,
+        "extract": null,
+        "name": "crowdsec-firewall-bouncer",
+        "passthru": null,
+        "pinned": false,
+        "src": {
+            "deepClone": false,
+            "fetchSubmodules": false,
+            "leaveDotGit": false,
+            "name": null,
+            "owner": "crowdsecurity",
+            "repo": "cs-firewall-bouncer",
+            "rev": "v0.0.31",
+            "sha256": "sha256-59MWll8v00CF4WA53gjHZSTFc8hpYaHENg9O7LgTCrA=",
+            "type": "github"
+        },
+        "version": "v0.0.31"
+    },
+    "crowdsec-hub": {
+        "cargoLocks": null,
+        "date": "2025-01-30",
+        "extract": null,
+        "name": "crowdsec-hub",
+        "passthru": null,
+        "pinned": false,
+        "src": {
+            "deepClone": false,
+            "fetchSubmodules": false,
+            "leaveDotGit": false,
+            "name": null,
+            "owner": "crowdsecurity",
+            "repo": "hub",
+            "rev": "8f102f5ac79af59d3024ca2771b65ec87411ac02",
+            "sha256": "sha256-8K1HkBg0++Au1dr2KMrl9b2ruqXdo+vqWngOCwL11Mo=",
+            "type": "github"
+        },
+        "version": "8f102f5ac79af59d3024ca2771b65ec87411ac02"
+    }
+}
\ No newline at end of file
diff --git a/pkgs/crowdsec/_sources/generated.nix b/pkgs/crowdsec/_sources/generated.nix
new file mode 100644
index 0000000..6f845ec
--- /dev/null
+++ b/pkgs/crowdsec/_sources/generated.nix
@@ -0,0 +1,27 @@
+# This file was generated by nvfetcher, please do not modify it manually.
+{ fetchgit, fetchurl, fetchFromGitHub, dockerTools }:
+{
+  crowdsec-firewall-bouncer = {
+    pname = "crowdsec-firewall-bouncer";
+    version = "v0.0.31";
+    src = fetchFromGitHub {
+      owner = "crowdsecurity";
+      repo = "cs-firewall-bouncer";
+      rev = "v0.0.31";
+      fetchSubmodules = false;
+      sha256 = "sha256-59MWll8v00CF4WA53gjHZSTFc8hpYaHENg9O7LgTCrA=";
+    };
+  };
+  crowdsec-hub = {
+    pname = "crowdsec-hub";
+    version = "8f102f5ac79af59d3024ca2771b65ec87411ac02";
+    src = fetchFromGitHub {
+      owner = "crowdsecurity";
+      repo = "hub";
+      rev = "8f102f5ac79af59d3024ca2771b65ec87411ac02";
+      fetchSubmodules = false;
+      sha256 = "sha256-8K1HkBg0++Au1dr2KMrl9b2ruqXdo+vqWngOCwL11Mo=";
+    };
+    date = "2025-01-30";
+  };
+}
diff --git a/pkgs/crowdsec/default.nix b/pkgs/crowdsec/default.nix
new file mode 100644
index 0000000..66faac3
--- /dev/null
+++ b/pkgs/crowdsec/default.nix
@@ -0,0 +1,9 @@
+{ pkgs }:
+let
+  sources = pkgs.callPackage ./_sources/generated.nix { };
+  callPackage = pkgs.lib.callPackageWith (pkgs // { inherit sources; });
+in
+{
+  hub = callPackage ./hub.nix { };
+  firewall-bouncer = callPackage ./firewall-bouncer.nix { };
+}
diff --git a/pkgs/crowdsec/firewall-bouncer.nix b/pkgs/crowdsec/firewall-bouncer.nix
new file mode 100644
index 0000000..86370c4
--- /dev/null
+++ b/pkgs/crowdsec/firewall-bouncer.nix
@@ -0,0 +1,26 @@
+{
+  lib,
+  sources,
+  buildGoModule,
+  envsubst,
+  coreutils,
+}:
+let
+  envsubstBin = lib.getExe envsubst;
+in
+buildGoModule {
+  inherit (sources.crowdsec-firewall-bouncer) pname version src;
+
+  vendorHash = "sha256-7Jxvg8UEjUxnIz1llvXyI2AefJ31OVdNzhWD/C8wU/Y=";
+
+  postInstall = ''
+    mkdir -p $out/lib/systemd/system
+
+    CFG=/var/lib/crowdsec/config BIN=$out/bin/cs-firewall-bouncer ${envsubstBin} \
+      -i ./config/crowdsec-firewall-bouncer.service \
+      -o $out/lib/systemd/system/crowdsec-firewall-bouncer.service
+
+    substituteInPlace $out/lib/systemd/system/crowdsec-firewall-bouncer.service \
+      --replace-fail /bin/sleep ${coreutils}/bin/sleep
+  '';
+}
diff --git a/pkgs/crowdsec/hub.nix b/pkgs/crowdsec/hub.nix
new file mode 100644
index 0000000..d057ca8
--- /dev/null
+++ b/pkgs/crowdsec/hub.nix
@@ -0,0 +1,4 @@
+{
+  sources,
+}:
+sources.crowdsec-hub.src
diff --git a/pkgs/crowdsec/nvfetcher.toml b/pkgs/crowdsec/nvfetcher.toml
new file mode 100644
index 0000000..2287dba
--- /dev/null
+++ b/pkgs/crowdsec/nvfetcher.toml
@@ -0,0 +1,7 @@
+[crowdsec-hub]
+src.git = "https://github.com/crowdsecurity/hub.git"
+fetch.github = "crowdsecurity/hub"
+
+[crowdsec-firewall-bouncer]
+src.github = "crowdsecurity/cs-firewall-bouncer"
+fetch.github = "crowdsecurity/cs-firewall-bouncer"
diff --git a/pkgs/default.nix b/pkgs/default.nix
index 036afd4..0e5de7a 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -1,7 +1,5 @@
 { pkgs }:
-let
-  inherit (pkgs) callPackage;
-in
 {
-  starbound = callPackage ./starbound { };
+  crowdsec = import ./crowdsec { inherit pkgs; };
+  starbound = pkgs.callPackage ./starbound { };
 }

From 40187d4b2d64f6835dcddef68edaa160d2219daa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Thu, 30 Jan 2025 03:50:08 +0800
Subject: [PATCH 179/212] feat: Add crowdsec to replace fail2ban

---
 configuration/default.nix                     |  1 +
 configuration/services/crowdsec.nix           | 35 +++++++++++++++++++
 .../services/metrics/victoriametrics.nix      | 16 +++++++++
 3 files changed, 52 insertions(+)
 create mode 100644 configuration/services/crowdsec.nix

diff --git a/configuration/default.nix b/configuration/default.nix
index a22f8fc..c9c71ec 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -18,6 +18,7 @@
     ./services/backups.nix
     ./services/battery-manager.nix
     ./services/conduit.nix
+    ./services/crowdsec.nix
     ./services/foundryvtt.nix
     ./services/gitea.nix
     ./services/metrics
diff --git a/configuration/services/crowdsec.nix b/configuration/services/crowdsec.nix
new file mode 100644
index 0000000..110602c
--- /dev/null
+++ b/configuration/services/crowdsec.nix
@@ -0,0 +1,35 @@
+{ pkgs, ... }:
+{
+  security.crowdsec = {
+    enable = true;
+
+    parserWhitelist = [
+      "1.64.239.213"
+    ];
+
+    settings.crowdsec_service.acquisition_path = pkgs.writeText "crowdsec-acquisitions.yaml" ''
+      ---
+      source: journalctl
+      journalctl_filter:
+        - "SYSLOG_IDENTIFIER=Nextcloud"
+      labels:
+        type: syslog
+      ---
+      source: journalctl
+      journalctl_filter:
+        - "SYSLOG_IDENTIFIER=sshd-session"
+      labels:
+        type: syslog
+      ---
+    '';
+
+    remediationComponents.firewallBouncer = {
+      enable = true;
+      settings.prometheus = {
+        enabled = true;
+        listen_addr = "127.0.0.1";
+        listen_port = "60601";
+      };
+    };
+  };
+}
diff --git a/configuration/services/metrics/victoriametrics.nix b/configuration/services/metrics/victoriametrics.nix
index 710cf70..5cfc614 100644
--- a/configuration/services/metrics/victoriametrics.nix
+++ b/configuration/services/metrics/victoriametrics.nix
@@ -10,6 +10,22 @@
         extraSettings.authorization.credentials_file = config.sops.secrets."forgejo/metrics-token".path;
       };
       coturn.targets = [ "127.0.0.1:9641" ];
+
+      crowdsec.targets =
+        let
+          address = config.security.crowdsec.settings.prometheus.listen_addr;
+          port = config.security.crowdsec.settings.prometheus.listen_port;
+        in
+        [ "${address}:${toString port}" ];
+
+      csFirewallBouncer.targets =
+        let
+          address =
+            config.security.crowdsec.remediationComponents.firewallBouncer.settings.prometheus.listen_addr;
+          port =
+            config.security.crowdsec.remediationComponents.firewallBouncer.settings.prometheus.listen_port;
+        in
+        [ "${address}:${toString port}" ];
     };
   };
 }

From 2831fdb0f27e2b3e6eb32f907681a07337a752ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 1 Feb 2025 17:57:32 +0800
Subject: [PATCH 180/212] feat(crowdsec): Add proper support for acquisitions

---
 modules/crowdsec/default.nix | 34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/modules/crowdsec/default.nix b/modules/crowdsec/default.nix
index 915ca0b..0d0ff1c 100644
--- a/modules/crowdsec/default.nix
+++ b/modules/crowdsec/default.nix
@@ -28,6 +28,12 @@ let
 
     $sudo ${crowdsec}/bin/cscli "$@"
   '';
+
+  acquisitions = ''
+    ---
+    ${lib.concatMapStringsSep "\n---\n" builtins.toJSON cfg.acquisitions}
+    ---
+  '';
 in
 {
   imports = [ ./remediations ];
@@ -82,6 +88,24 @@ in
         '';
       };
 
+      acquisitions = lib.mkOption {
+        type = listOf settingsFormat.type;
+        default = [ ];
+        description = ''
+          Log acquisitions.
+        '';
+      };
+
+      extraGroups = lib.mkOption {
+        type = listOf str;
+        default = [ ];
+        description = ''
+          Additional groups to make the service part of.
+
+          Required to permit reading from various log sources.
+        '';
+      };
+
       hubConfigurations = {
         collections = lib.mkOption {
           type = listOf str;
@@ -190,7 +214,13 @@ in
           plugin_dir = lib.mkDefault "/var/empty/";
         };
 
-        crowdsec_service.acquisition_path = lib.mkDefault "${cfg.package}/share/crowdsec/config/acquis.yaml";
+        crowdsec_service.acquisition_path =
+          # Using an if/else here because `mkMerge` does not work in
+          # YAML-type options
+          if cfg.acquisitions == [ ] then
+            "${cfg.package}/share/crowdsec/config/acquis.yaml"
+          else
+            pkgs.writeText "acquis.yaml" acquisitions;
 
         cscli = {
           prometheus_uri = lib.mkDefault "127.0.0.1:6060";
@@ -339,7 +369,7 @@ in
           serviceConfig = {
             User = "crowdsec";
             Group = "crowdsec";
-            SupplementaryGroups = [ "systemd-journal" ];
+            SupplementaryGroups = cfg.extraGroups;
 
             StateDirectory = "crowdsec";
           };

From 68450870cf3776f4f855cfdf117b24069777d3c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 1 Feb 2025 17:58:15 +0800
Subject: [PATCH 181/212] feat(crowdsec-service): Add nginx monitoring

---
 configuration/services/crowdsec.nix | 50 ++++++++++++++++++++---------
 1 file changed, 34 insertions(+), 16 deletions(-)

diff --git a/configuration/services/crowdsec.nix b/configuration/services/crowdsec.nix
index 110602c..4891cad 100644
--- a/configuration/services/crowdsec.nix
+++ b/configuration/services/crowdsec.nix
@@ -1,4 +1,4 @@
-{ pkgs, ... }:
+{ config, lib, ... }:
 {
   security.crowdsec = {
     enable = true;
@@ -7,21 +7,39 @@
       "1.64.239.213"
     ];
 
-    settings.crowdsec_service.acquisition_path = pkgs.writeText "crowdsec-acquisitions.yaml" ''
-      ---
-      source: journalctl
-      journalctl_filter:
-        - "SYSLOG_IDENTIFIER=Nextcloud"
-      labels:
-        type: syslog
-      ---
-      source: journalctl
-      journalctl_filter:
-        - "SYSLOG_IDENTIFIER=sshd-session"
-      labels:
-        type: syslog
-      ---
-    '';
+    extraGroups = [
+      "systemd-journal"
+      "nginx"
+    ];
+
+    acquisitions = [
+      {
+        source = "journalctl";
+        labels.type = "syslog";
+        journalctl_filter = [
+          "SYSLOG_IDENTIFIER=Nextcloud"
+        ];
+      }
+
+      {
+        source = "journalctl";
+        labels.type = "syslog";
+        journalctl_filter = [
+          "SYSLOG_IDENTIFIER=sshd-session"
+        ];
+      }
+
+      {
+        labels.type = "nginx";
+        filenames =
+          [
+            "/var/log/nginx/*.log"
+          ]
+          ++ lib.mapAttrsToList (
+            vHost: _: "/var/log/nginx/${vHost}/access.log"
+          ) config.services.nginx.virtualHosts;
+      }
+    ];
 
     remediationComponents.firewallBouncer = {
       enable = true;

From 78c81a10284d2202be058c8e51f24baa539cb116 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 1 Feb 2025 18:16:52 +0800
Subject: [PATCH 182/212] feat(acme): Switch to porkbun

---
 configuration/nginx.nix | 13 ++++++++++---
 configuration/sops.nix  | 12 ++++++++----
 keys/production.yaml    | 10 ++++++----
 keys/staging.yaml       | 10 ++++++----
 4 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/configuration/nginx.nix b/configuration/nginx.nix
index b38118b..0b72cc1 100644
--- a/configuration/nginx.nix
+++ b/configuration/nginx.nix
@@ -47,10 +47,17 @@
     acceptTerms = true;
 
     certs."tlater.net" = {
-      extraDomainNames = [ "*.tlater.net" ];
-      dnsProvider = "hetzner";
+      extraDomainNames = [
+        "*.tlater.net"
+        "tlater.com"
+        "*.tlater.com"
+      ];
+      dnsProvider = "porkbun";
       group = "nginx";
-      credentialFiles."HETZNER_API_KEY_FILE" = config.sops.secrets."hetzner-api".path;
+      credentialFiles = {
+        PORKBUN_API_KEY_FILE = config.sops.secrets."porkbun/api-key".path;
+        PORKBUN_SECRET_API_KEY_FILE = config.sops.secrets."porkbun/secret-api-key".path;
+      };
     };
   };
 
diff --git a/configuration/sops.nix b/configuration/sops.nix
index bc21834..bbfb888 100644
--- a/configuration/sops.nix
+++ b/configuration/sops.nix
@@ -34,16 +34,20 @@
       "heisenbridge/as-token" = { };
       "heisenbridge/hs-token" = { };
 
-      "hetzner-api" = {
-        owner = "acme";
-      };
-
       # Nextcloud
       "nextcloud/tlater" = {
         owner = "nextcloud";
         group = "nextcloud";
       };
 
+      # Porkbub/ACME
+      "porkbun/api-key" = {
+        owner = "acme";
+      };
+      "porkbun/secret-api-key" = {
+        owner = "acme";
+      };
+
       # Restic
       "restic/local-backups" = {
         owner = "root";
diff --git a/keys/production.yaml b/keys/production.yaml
index 6dd4c21..19df9bd 100644
--- a/keys/production.yaml
+++ b/keys/production.yaml
@@ -1,4 +1,6 @@
-hetzner-api: ENC[AES256_GCM,data:OsUfo86AzcBe/OELkfB5brEfsZ4gkbeehxwIVUBwQgE=,iv:Bt/cjlZ6oZEVUOQjWMDL7/mfL3HWLFAw1tEGeLMgeKg=,tag:TMU2XiHlMgP4aes10mIQYQ==,type:str]
+porkbun:
+    api-key: ENC[AES256_GCM,data:p3lqvGc8m2U/12rBPjoNR7hxQyD52CyEen/V8q59k5CSJZSqzZS8M5vEXFBsUMjz2lrmKM4pgtz4wa2fWK6Ty4LJCaI=,iv:OQC3FpwTtPmqHvDbA41mWF7LGYwC/jD2ZMBsE8ktNOg=,tag:kq5hUR7TBgczuGcXpsdu2A==,type:str]
+    secret-api-key: ENC[AES256_GCM,data:zV5PTKf45Zab8uW8mbuXmPNzciq6tV9OF0wUND7YnRk/DjZneYWItAsNBVoM+iHA+XsUPDoeKo6hoJiGkH/cCQ8WvuM=,iv:yr1M5DlgI8k6BgzNz3HRnqspHOrQuf2PmoZS1HGp0v8=,tag:JkNNziMMfKFZV2hnx5lXRg==,type:str]
 battery-manager:
     email: ENC[AES256_GCM,data:rYLUACXR/n+bLBmZ,iv:sUBEkh2+7qGjHZ5R23e/hoCiyTA7GTL4bJvXmxjZ5Sw=,tag:fdPMllaQQfRgX0WZKIre4g==,type:str]
     password: ENC[AES256_GCM,data:7cokZa6Q6ahSeiFPz+cV,iv:vz405P0IcG9FsAQXlY7mi78GuushQUKJm2irG6buGzc=,tag:JLHG2jTkJDGbinAq9dXRsQ==,type:str]
@@ -32,8 +34,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2024-04-15T23:13:18Z"
-    mac: ENC[AES256_GCM,data:3/v+WgSWJ+VcBSBe1Wkis3z+tMmSjbKzLFqBB8xugc6DvgQG8J+1HRrPucLnpNNtEdmpyoTa72U6fPm6JnyUsuj5pLEghLprOJkqQNdRI06fllhw+9d3e3twx6D4oIIsVH6/io4ElXrGsGQTsfNbYhgn+987wa3WP5N25fBac3U=,iv:FL3tzPutOMN6IPkQfXIu/JOZT+OzUSqpMSQrUeXZQHE=,tag:jL1BTsYTA9XjrsjFszxZhA==,type:str]
+    lastmodified: "2025-02-01T10:16:20Z"
+    mac: ENC[AES256_GCM,data:oFJNljU0RJdgsdK7qRXKCqRs7kPXgHqSyYcexEs8kXFnn68mKHNKKfl7skepCPKk0U7h6JqJQ+EOnAA0eo6mraBAMKLSXUcucTzqsfcI+V04rYcP2nGPMUiNDGdKHCcb6OmBhfvKw7+elnonPxKsBlyK31AqB9RFDKaTKXpcNMw=,iv:Q9t7ZkUrevHm5I4JBW95TfvZ88dl2Fq3Yq/E642dV6s=,tag:p2XWfii168qq29wX/RCJuQ==,type:str]
     pgp:
         - created_at: "2025-01-21T17:55:44Z"
           enc: |-
@@ -91,4 +93,4 @@ sops:
             -----END PGP MESSAGE-----
           fp: 0af7641adb8aa843136cf6d047f71da3e5ad79f9
     unencrypted_suffix: _unencrypted
-    version: 3.8.1
+    version: 3.9.2
diff --git a/keys/staging.yaml b/keys/staging.yaml
index 091424d..67e47ad 100644
--- a/keys/staging.yaml
+++ b/keys/staging.yaml
@@ -1,4 +1,6 @@
-hetzner-api: ENC[AES256_GCM,data:1Zjp003j60g=,iv:+vDcyiqYm4A9CMIrW4oGZKdZiczatBcvfL4qYYhKwCg=,tag:Xeu8JuRm+b+5RO+wFR2M8w==,type:str]
+porkbun:
+    api-key: ENC[AES256_GCM,data:A5J1sqwq6hs=,iv:77Mar3IX7mq7z7x6s9sSeGNVYc1Wv78HptJElEC7z3Q=,tag:eM/EF9TxKu+zcbJ1SYXiuA==,type:str]
+    secret-api-key: ENC[AES256_GCM,data:8Xv+jWYaWMI=,iv:li4tdY0pch5lksftMmfMVS729caAwfaacoztaQ49az0=,tag:KhfElBGzVH4ByFPfuQsdhw==,type:str]
 battery-manager:
     email: ENC[AES256_GCM,data:LM/EGzWHfVQ=,iv:jFaoUQuUfuGoOyj/GFpdI8TerH/c8D9fjvio+IEt2Tc=,tag:IWLiN011JEnHRLIXWQgfmA==,type:str]
     password: ENC[AES256_GCM,data:SUxjqS7SJHM=,iv:LvdKk88S+nSImh6/ZezbFGLCUBu1Lpdu+neF2xyHdBg=,tag:rcMyZuW4FVNbcbz00wQKBg==,type:str]
@@ -32,8 +34,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2024-04-15T23:13:27Z"
-    mac: ENC[AES256_GCM,data:JhEVrKF2Jsqpdztcr3g5lMrgEFeLXfBRQTwQJ6PmLSNyDORcTU09TJPNWTPDnR5okDrvIU/wlzi5DZ8A0ebNhrKf6l0tNFBT9LSvQFHU5SBxqY/m8uEJKSrEC4IL5lugOOISDka2KSvYXVCXrumMHE5FnmOS/CgOZaZk6LUjPYA=,iv:ygygnSedcTo2Vsc56s2qrz1qkWchvSgvoiMTebRxQQ8=,tag:vf6z8rxsXmqzwpDy9Avifw==,type:str]
+    lastmodified: "2025-02-01T10:16:31Z"
+    mac: ENC[AES256_GCM,data:N4RQHOyWvSXW16fepQvRznNbmGerct03kptyiY3IoTpYaJ+43cyFjW15ZqfpaRFyV66QIeqmceqV8c4eP8YSndj6e55e04w0RCyqREXQlFPR6Eh5elaBenokoJhjF6BCsq+xX1C+LUEcxiR/dgy5cwA3mAD/dLCm+G11a06EG6k=,iv:wt5fEOVP6CXHCzmMH9hNCQDDgPa66bLMOa39Eipux9Y=,tag:kWZPnWD1stANVAmWmvOjCg==,type:str]
     pgp:
         - created_at: "2025-01-21T17:55:30Z"
           enc: |-
@@ -71,4 +73,4 @@ sops:
             -----END PGP MESSAGE-----
           fp: 2f5caa73e7ceea4fcc8d2881fde587e6737d2dbc
     unencrypted_suffix: _unencrypted
-    version: 3.8.1
+    version: 3.9.2

From e1989a6009f0b5e7a8e7433498e55fe286aba94d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 8 Feb 2025 05:29:35 +0800
Subject: [PATCH 183/212] fix(crowdsec): Filter out events against matrix

---
 configuration/services/crowdsec.nix | 39 ++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/configuration/services/crowdsec.nix b/configuration/services/crowdsec.nix
index 4891cad..f6f3c80 100644
--- a/configuration/services/crowdsec.nix
+++ b/configuration/services/crowdsec.nix
@@ -1,4 +1,9 @@
-{ config, lib, ... }:
+{
+  pkgs,
+  config,
+  lib,
+  ...
+}:
 {
   security.crowdsec = {
     enable = true;
@@ -50,4 +55,36 @@
       };
     };
   };
+
+  # Add whitelists for matrix
+  systemd.tmpfiles.settings."10-matrix" =
+    let
+      stateDir = config.security.crowdsec.stateDirectory;
+    in
+    {
+      "${stateDir}/config/postoverflows".d = {
+        user = "crowdsec";
+        group = "crowdsec";
+        mode = "0700";
+      };
+
+      "${stateDir}/config/postoverflows/s01-whitelist".d = {
+        user = "crowdsec";
+        group = "crowdsec";
+        mode = "0700";
+      };
+
+      "${stateDir}/config/postoverflows/s01-whitelist/matrix-whitelist.yaml"."L+".argument =
+        ((pkgs.formats.yaml { }).generate "crowdsec-matrix-whitelist.yaml" {
+          name = "tetsumaki/matrix";
+          description = "custom matrix whitelist";
+          whitelist = {
+            reason = "whitelist false positive for matrix";
+            expression = [
+              "evt.Overflow.Alert.Events[0].GetMeta('target_fqdn') == '${config.services.matrix-conduit.settings.global.server_name}'"
+              "evt.Overflow.Alert.GetScenario() in ['crowdsecurity/http-probing', 'crowdsecurity/http-crawl-non_statics']"
+            ];
+          };
+        }).outPath;
+    };
 }

From e11b6f810bd504af9783174bb9f8cebbd7f995c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 7 Feb 2025 01:39:57 +0800
Subject: [PATCH 184/212] feat(crowdsec): Switch to whitelisting wireguard IP

My IP address is not static, and grafana seems to comfortably produce
enough traffic to get me IP banned.
---
 configuration/services/crowdsec.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configuration/services/crowdsec.nix b/configuration/services/crowdsec.nix
index f6f3c80..6e0f367 100644
--- a/configuration/services/crowdsec.nix
+++ b/configuration/services/crowdsec.nix
@@ -9,7 +9,7 @@
     enable = true;
 
     parserWhitelist = [
-      "1.64.239.213"
+      "10.45.249.2"
     ];
 
     extraGroups = [

From c939b935bfe4f4d201bc4e5b8fe4edb192f120f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 8 Feb 2025 05:47:44 +0800
Subject: [PATCH 185/212] feat(conduit): Refactor matrix appservices and add
 matrix-hookshot

---
 configuration/default.nix                     |   2 +-
 .../{conduit.nix => conduit/default.nix}      |  91 +----------
 .../services/conduit/heisenbridge.nix         |  78 ++++++++++
 configuration/services/conduit/lib.nix        |  67 ++++++++
 .../services/conduit/matrix-hookshot.nix      | 144 ++++++++++++++++++
 .../services/metrics/victoriametrics.nix      |   4 +
 configuration/sops.nix                        |   4 +
 keys/production.yaml                          |   7 +-
 keys/staging.yaml                             |   7 +-
 9 files changed, 313 insertions(+), 91 deletions(-)
 rename configuration/services/{conduit.nix => conduit/default.nix} (62%)
 create mode 100644 configuration/services/conduit/heisenbridge.nix
 create mode 100644 configuration/services/conduit/lib.nix
 create mode 100644 configuration/services/conduit/matrix-hookshot.nix

diff --git a/configuration/default.nix b/configuration/default.nix
index c9c71ec..239f9f6 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -17,7 +17,7 @@
 
     ./services/backups.nix
     ./services/battery-manager.nix
-    ./services/conduit.nix
+    ./services/conduit
     ./services/crowdsec.nix
     ./services/foundryvtt.nix
     ./services/gitea.nix
diff --git a/configuration/services/conduit.nix b/configuration/services/conduit/default.nix
similarity index 62%
rename from configuration/services/conduit.nix
rename to configuration/services/conduit/default.nix
index 4e53241..c3803f4 100644
--- a/configuration/services/conduit.nix
+++ b/configuration/services/conduit/default.nix
@@ -1,5 +1,4 @@
 {
-  pkgs,
   config,
   lib,
   ...
@@ -12,6 +11,11 @@ let
   turn-realm = "turn.${config.services.nginx.domain}";
 in
 {
+  imports = [
+    ./heisenbridge.nix
+    ./matrix-hookshot.nix
+  ];
+
   services.matrix-conduit = {
     enable = true;
     settings.global = {
@@ -40,91 +44,6 @@ in
     };
   };
 
-  systemd.services.heisenbridge =
-    let
-      replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret";
-      registrationFile = builtins.toFile "heisenbridge-registration.yaml" (
-        builtins.toJSON {
-          id = "heisenbridge";
-          url = "http://127.0.0.1:9898";
-          as_token = "@AS_TOKEN@";
-          hs_token = "@HS_TOKEN@";
-          rate_limited = false;
-          sender_localpart = "heisenbridge";
-          namespaces = {
-            users = [
-              {
-                regex = "@irc_.*";
-                exclusive = true;
-              }
-              {
-                regex = "@heisenbridge:.*";
-                exclusive = true;
-              }
-            ];
-            aliases = [ ];
-            rooms = [ ];
-          };
-        }
-      );
-
-      # TODO(tlater): Starting with systemd 253 it will become possible
-      # to do the credential setup as part of ExecStartPre/preStart
-      # instead.
-      #
-      # This will also make it possible to actually set caps on the
-      # heisenbridge process using systemd, so that we can run the
-      # identd process.
-      execScript = pkgs.writeShellScript "heisenbridge" ''
-        cp ${registrationFile} "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml"
-        chmod 600 $RUNTIME_DIRECTORY/heisenbridge-registration.yaml
-        ${replaceSecretBin} '@AS_TOKEN@' "$CREDENTIALS_DIRECTORY/heisenbridge_as-token" "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml"
-        ${replaceSecretBin} '@HS_TOKEN@' "$CREDENTIALS_DIRECTORY/heisenbridge_hs-token" "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml"
-        chmod 400 $RUNTIME_DIRECTORY/heisenbridge-registration.yaml
-
-        ${pkgs.heisenbridge}/bin/heisenbridge \
-            --config $RUNTIME_DIRECTORY/heisenbridge-registration.yaml \
-            --owner @tlater:matrix.tlater.net \
-            'http://localhost:${toString cfg.settings.global.port}'
-      '';
-    in
-    {
-      description = "Matrix<->IRC bridge";
-      wantedBy = [ "multi-user.target" ];
-      after = [ "conduit.service" ];
-
-      serviceConfig = {
-        Type = "simple";
-
-        LoadCredential = "heisenbridge:/run/secrets/heisenbridge";
-
-        ExecStart = execScript;
-
-        DynamicUser = true;
-        RuntimeDirectory = "heisenbridge";
-        RuntimeDirectoryMode = "0700";
-
-        RestrictNamespaces = true;
-        PrivateUsers = true;
-        ProtectHostname = true;
-        ProtectClock = true;
-        ProtectKernelTunables = true;
-        ProtectKernelModules = true;
-        ProtectKernelLogs = true;
-        ProtectControlGroups = true;
-        RestrictAddressFamilies = [ "AF_INET AF_INET6" ];
-        LockPersonality = true;
-        RestrictRealtime = true;
-        ProtectProc = "invisible";
-        ProcSubset = "pid";
-        UMask = 77;
-
-        # For the identd port
-        # CapabilityBoundingSet = ["CAP_NET_BIND_SERVICE"];
-        # AmbientCapabilities = ["CAP_NET_BIND_SERVICE"];
-      };
-    };
-
   # Pass in the TURN secret via EnvironmentFile, not supported by
   # upstream module currently.
   #
diff --git a/configuration/services/conduit/heisenbridge.nix b/configuration/services/conduit/heisenbridge.nix
new file mode 100644
index 0000000..f0f7e49
--- /dev/null
+++ b/configuration/services/conduit/heisenbridge.nix
@@ -0,0 +1,78 @@
+{
+  pkgs,
+  lib,
+  config,
+  ...
+}:
+let
+  conduitCfg = config.services.matrix-conduit;
+  matrixLib = pkgs.callPackage ./lib.nix { };
+in
+{
+  systemd.services.heisenbridge =
+    let
+      registration = matrixLib.writeRegistrationScript {
+        id = "heisenbridge";
+        url = "http://127.0.0.1:9898";
+        sender_localpart = "heisenbridge";
+
+        namespaces = {
+          users = [
+            {
+              regex = "@irc_.*";
+              exclusive = true;
+            }
+            {
+              regex = "@heisenbridge:.*";
+              exclusive = true;
+            }
+          ];
+
+          aliases = [ ];
+          rooms = [ ];
+        };
+      };
+    in
+    {
+      description = "Matrix<->IRC bridge";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "conduit.service" ];
+
+      serviceConfig = {
+        Type = "exec";
+
+        LoadCredential = "heisenbridge:/run/secrets/heisenbridge";
+
+        inherit (registration) ExecStartPre;
+        ExecStart = lib.concatStringsSep " " [
+          "${lib.getExe pkgs.heisenbridge}"
+          "--config \${RUNTIME_DIRECTORY}/heisenbridge-registration.yaml"
+          "--owner @tlater:matrix.tlater.net"
+          "http://localhost:${toString conduitCfg.settings.global.port}"
+        ];
+
+        DynamicUser = true;
+        RuntimeDirectory = "heisenbridge";
+        RuntimeDirectoryMode = "0700";
+
+        RestrictNamespaces = true;
+        PrivateUsers = true;
+        ProtectHostname = true;
+        ProtectClock = true;
+        ProtectKernelTunables = true;
+        ProtectKernelModules = true;
+        ProtectKernelLogs = true;
+        ProtectControlGroups = true;
+        RestrictAddressFamilies = [ "AF_INET AF_INET6" ];
+        LockPersonality = true;
+        RestrictRealtime = true;
+        ProtectProc = "invisible";
+        ProcSubset = "pid";
+        UMask = 77;
+
+        # For the identd port
+        # CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
+        # AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
+      };
+    };
+}
diff --git a/configuration/services/conduit/lib.nix b/configuration/services/conduit/lib.nix
new file mode 100644
index 0000000..ef407cf
--- /dev/null
+++ b/configuration/services/conduit/lib.nix
@@ -0,0 +1,67 @@
+{
+  lib,
+  writeShellScript,
+  formats,
+  replace-secret,
+}:
+let
+  replaceSecretBin = "${lib.getExe replace-secret}";
+in
+{
+  # Write a script that will set up the service's registration.yaml
+  # with secrets from systemd credentials.
+  #
+  # The credentials should be named `${id}_as-token` and
+  # `${id}_hs-token`.
+  #
+  # This registration file needs to be manually added to conduit by
+  # messaging the admin with the yaml file.
+  #
+  # TODO(tlater): Conduwuit seems to support a CLI interface for this,
+  # may want to migrate to that sometime.
+  writeRegistrationScript =
+    {
+      id, # Must be unique among all registered appservices/bots
+      url, # The URL on which the service listens
+      sender_localpart,
+      rate_limited ? false,
+      namespaces ? {
+        aliases = [ ];
+        rooms = [ ];
+        users = [ ];
+      },
+      extraSettings ? { },
+      # The location to place the file; assumes systemd runtime dir
+      runtimeRegistration ? "$RUNTIME_DIRECTORY/${id}-registration.yaml",
+    }:
+    let
+      registrationFile = (formats.yaml { }).generate "${id}-registration.yaml" (
+        {
+          inherit
+            id
+            url
+            sender_localpart
+            rate_limited
+            namespaces
+            ;
+
+          as_token = "@AS_TOKEN@";
+          hs_token = "@HS_TOKEN@";
+        }
+        // extraSettings
+      );
+    in
+    {
+      inherit runtimeRegistration;
+      ExecStartPre = writeShellScript "${id}-registration-setup.sh" ''
+        cp -f ${registrationFile} "${runtimeRegistration}"
+        chmod 600 "${runtimeRegistration}"
+
+        # Write actual secrets into config
+        ${replaceSecretBin} '@AS_TOKEN@' "$CREDENTIALS_DIRECTORY/${id}_as-token" "${runtimeRegistration}"
+        ${replaceSecretBin} '@HS_TOKEN@' "$CREDENTIALS_DIRECTORY/${id}_hs-token" "${runtimeRegistration}"
+
+        chmod 400 "${runtimeRegistration}"
+      '';
+    };
+}
diff --git a/configuration/services/conduit/matrix-hookshot.nix b/configuration/services/conduit/matrix-hookshot.nix
new file mode 100644
index 0000000..6f11728
--- /dev/null
+++ b/configuration/services/conduit/matrix-hookshot.nix
@@ -0,0 +1,144 @@
+{
+  pkgs,
+  lib,
+  config,
+  ...
+}:
+let
+  matrixLib = pkgs.callPackage ./lib.nix { };
+
+  cfg = config.services.matrix-hookshot;
+  conduitCfg = config.services.matrix-conduit;
+
+  domain = conduitCfg.settings.global.server_name;
+
+  registration = matrixLib.writeRegistrationScript {
+    id = "matrix-hookshot";
+    url = "http://127.0.0.1:9993";
+    sender_localpart = "hookshot";
+
+    namespaces = {
+      aliases = [ ];
+      rooms = [ ];
+      users = [
+        {
+          regex = "@${cfg.settings.generic.userIdPrefix}.*:${domain}";
+          exclusive = true;
+        }
+      ];
+    };
+
+    # Encryption support
+    extraSettings = {
+      "de.sorunome.msc2409.push_ephemeral" = true;
+      push_ephemeral = true;
+      "org.matrix.msc3202" = true;
+    };
+
+    runtimeRegistration = "${cfg.registrationFile}";
+  };
+in
+{
+  systemd.services.matrix-hookshot = {
+    serviceConfig = {
+      Type = lib.mkForce "exec";
+
+      LoadCredential = "matrix-hookshot:/run/secrets/matrix-hookshot";
+      inherit (registration) ExecStartPre;
+
+      # Some library in matrix-hookshot wants a home directory
+      Environment = [ "HOME=/run/matrix-hookshot" ];
+
+      DynamicUser = true;
+      StateDirectory = "matrix-hookshot";
+      RuntimeDirectory = "matrix-hookshot";
+      RuntimeDirectoryMode = "0700";
+
+      RestrictNamespaces = true;
+      PrivateUsers = true;
+      ProtectHostname = true;
+      ProtectClock = true;
+      ProtectKernelTunables = true;
+      ProtectKernelModules = true;
+      ProtectKernelLogs = true;
+      ProtectControlGroups = true;
+      RestrictAddressFamilies = [ "AF_INET AF_INET6" ];
+      LockPersonality = true;
+      RestrictRealtime = true;
+      ProtectProc = "invisible";
+      ProcSubset = "pid";
+      UMask = 77;
+    };
+  };
+
+  services.matrix-hookshot = {
+    enable = true;
+
+    serviceDependencies = [
+      "conduit.service"
+    ];
+
+    registrationFile = "/run/matrix-hookshot/registration.yaml";
+
+    settings = {
+      bridge = {
+        inherit domain;
+        url = "http://localhost:${toString conduitCfg.settings.global.port}";
+        mediaUrl = conduitCfg.settings.global.well_known.client;
+        port = 9993;
+        bindAddress = "127.0.0.1";
+      };
+
+      bot.displayname = "Hookshot";
+
+      generic = {
+        enabled = true;
+        outbound = false;
+        # Only allow webhooks from localhost for the moment
+        urlPrefix = "http://127.0.0.1:9000/webhook";
+        userIdPrefix = "_webhooks_";
+        allowJsTransformationFunctions = true;
+      };
+
+      encryption.storagePath = "/var/lib/matrix-hookshot/cryptostore";
+
+      permissions = [
+        {
+          actor = "matrix.tlater.net";
+          services = [
+            {
+              service = "*";
+              level = "notifications";
+            }
+          ];
+        }
+        {
+          actor = "@tlater:matrix.tlater.net";
+          services = [
+            {
+              service = "*";
+              level = "admin";
+            }
+          ];
+        }
+      ];
+
+      listeners = [
+        {
+          port = 9000;
+          resources = [
+            "webhooks"
+          ];
+        }
+        {
+          port = 9001;
+          resources = [
+            "metrics"
+          ];
+        }
+      ];
+
+      metrics.enable = true;
+    };
+  };
+}
diff --git a/configuration/services/metrics/victoriametrics.nix b/configuration/services/metrics/victoriametrics.nix
index 5cfc614..d72215e 100644
--- a/configuration/services/metrics/victoriametrics.nix
+++ b/configuration/services/metrics/victoriametrics.nix
@@ -26,6 +26,10 @@
             config.security.crowdsec.remediationComponents.firewallBouncer.settings.prometheus.listen_port;
         in
         [ "${address}:${toString port}" ];
+
+      # Configured in the hookshot listeners, but it's hard to filter
+      # the correct values out of that config.
+      matrixHookshot.targets = [ "127.0.0.1:9001" ];
     };
   };
 }
diff --git a/configuration/sops.nix b/configuration/sops.nix
index bbfb888..4800e6b 100644
--- a/configuration/sops.nix
+++ b/configuration/sops.nix
@@ -34,6 +34,10 @@
       "heisenbridge/as-token" = { };
       "heisenbridge/hs-token" = { };
 
+      # Matrix-hookshot
+      "matrix-hookshot/as-token" = { };
+      "matrix-hookshot/hs-token" = { };
+
       # Nextcloud
       "nextcloud/tlater" = {
         owner = "nextcloud";
diff --git a/keys/production.yaml b/keys/production.yaml
index 19df9bd..0e906bd 100644
--- a/keys/production.yaml
+++ b/keys/production.yaml
@@ -16,6 +16,9 @@ steam:
 heisenbridge:
     as-token: ENC[AES256_GCM,data:+2yo6T18j34622H8ZWblAFB2phLw1q0k0vUQEZ5sFj7dQaRnkEiAMi0R3p17Zq0pOtGEC0RRZuPLYkcZ1oKP0w==,iv:lGwrQYp//FufpmJocrLIVyy9RK7lEEVcpAi0wmkjr34=,tag:yV06UbhAYJQz36O2XdhY+A==,type:str]
     hs-token: ENC[AES256_GCM,data:u52WpkQFd/J7JFoE/rfNluebyZQLOokvkVdL7+AEAvrhJhrkJli1ztkD79lbC+6tGUH4tT3T+nX9wvGKnrRUQg==,iv:as+9fVuvMg2IoE2WIKD9mHi+znhNcWRh5Zq+yr0xcDQ=,tag:mZ7fh7U0MfgI8hyq/28Bcg==,type:str]
+matrix-hookshot:
+    as-token: ENC[AES256_GCM,data:nXTanPhDyDF7R3AllLqpM5dzljBrHwlh1KJnTGIi5PhbDY2lPj4+uXkMEwvm1u+hQjPyM7vKZPfK+0/dms6Y7A==,iv:fSakJN+yai0gfOJKFxxaxgyUtk0pNmIeqVgrdq92/24=,tag:Qc7+SUnm5/Nq5+QIScR9kQ==,type:str]
+    hs-token: ENC[AES256_GCM,data:Bwyj0JTTN0NNnwOs1zA8CqbtZSNcvlINeT7QVc2eJiHda92J6vQk7bSxy6KuqCN9DxlUsK13ggYjNORY2vic5w==,iv:Npnp8arYQ3Yb6CXrnKgE03hD7ZjGINPa/DwFI8D+5tA=,tag:FqNE6yI0nF4puEUw9MGAjQ==,type:str]
 wireguard:
     server-key: ENC[AES256_GCM,data:mXb7ZznJHf5CgV8rI4uzPBATMRbmd7LimgtCkQM9kAjbIaGwUBqJZBN3fXs=,iv:3Po1Orinzov9rnEm9cLzgJY1PeD+5Jl9115MriABHh8=,tag:E/2CjDO1JCvJzxCnqKcNyw==,type:str]
 restic:
@@ -34,8 +37,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2025-02-01T10:16:20Z"
-    mac: ENC[AES256_GCM,data:oFJNljU0RJdgsdK7qRXKCqRs7kPXgHqSyYcexEs8kXFnn68mKHNKKfl7skepCPKk0U7h6JqJQ+EOnAA0eo6mraBAMKLSXUcucTzqsfcI+V04rYcP2nGPMUiNDGdKHCcb6OmBhfvKw7+elnonPxKsBlyK31AqB9RFDKaTKXpcNMw=,iv:Q9t7ZkUrevHm5I4JBW95TfvZ88dl2Fq3Yq/E642dV6s=,tag:p2XWfii168qq29wX/RCJuQ==,type:str]
+    lastmodified: "2025-02-07T19:44:49Z"
+    mac: ENC[AES256_GCM,data:+0hpd/E7GxK/27f2Itf0hDV+3Ga4gHb8xxLutJ32HLBWLZ5Y+dN03xgkz8jBTiM+BeHwS4gz70Cs9X3zLMHbosWVuIV9DLuRaHRq/IU9KiADwqmCySZALqCf3+T5QKZr3Qs4AZJHwaAXkRX9HbnRFriIAFDJW/BGdIHdoROquxY=,iv:TeXI8LGqHVa5wo61sGdNbZ2nJvSlPdgn9R3Lq5qUggU=,tag:TFort5wxVTdi9LMlMeT/DQ==,type:str]
     pgp:
         - created_at: "2025-01-21T17:55:44Z"
           enc: |-
diff --git a/keys/staging.yaml b/keys/staging.yaml
index 67e47ad..876d60e 100644
--- a/keys/staging.yaml
+++ b/keys/staging.yaml
@@ -16,6 +16,9 @@ steam:
 heisenbridge:
     as-token: ENC[AES256_GCM,data:tXbOeo7nv8I=,iv:wJAKcOXX9nGIw4n38ThOoj29u7dUWhsxSQG/p79JlEw=,tag:rTVaGS2UuWcea1uBa8YX2g==,type:str]
     hs-token: ENC[AES256_GCM,data:VBwvwomv0Xg=,iv:q6INtJ+rg+QiXj8uBdBzQYQZUBBXp+9odxDHwvu8Jxc=,tag:XKhm8nxygAkKaiVPJ2Fcdg==,type:str]
+matrix-hookshot:
+    as-token: ENC[AES256_GCM,data:uSUOo4f2KqA=,iv:Xb9G8Ecv6m59m51kDw2bOfq3SMJt4g9/6/EdH74R+KM=,tag:K9MSfO2c2Y4rlf0eYrmTnw==,type:str]
+    hs-token: ENC[AES256_GCM,data:0KsyA06InL4=,iv:zAR0Y1fk8SyodcSLBHlQ8I+BAmttz9Hkd8Q3OREFqs4=,tag:t1Et8N/3seq95DeGoUd7Sw==,type:str]
 wireguard:
     server-key: ENC[AES256_GCM,data:FvY897XdKoa/mckE8JQLCkklsnYD6Wz1wpsu5t3uhEnW3iarnDQxF9msuYU=,iv:jqGXfekM+Vs+J9b5nlZ5Skd1ZKHajoUo2Dc4tMYPm1w=,tag:EehikjI/FCU8wqtpvJRamQ==,type:str]
 restic:
@@ -34,8 +37,8 @@ sops:
     azure_kv: []
     hc_vault: []
     age: []
-    lastmodified: "2025-02-01T10:16:31Z"
-    mac: ENC[AES256_GCM,data:N4RQHOyWvSXW16fepQvRznNbmGerct03kptyiY3IoTpYaJ+43cyFjW15ZqfpaRFyV66QIeqmceqV8c4eP8YSndj6e55e04w0RCyqREXQlFPR6Eh5elaBenokoJhjF6BCsq+xX1C+LUEcxiR/dgy5cwA3mAD/dLCm+G11a06EG6k=,iv:wt5fEOVP6CXHCzmMH9hNCQDDgPa66bLMOa39Eipux9Y=,tag:kWZPnWD1stANVAmWmvOjCg==,type:str]
+    lastmodified: "2025-02-07T17:43:24Z"
+    mac: ENC[AES256_GCM,data:akmD/bfgeTyFzW1quvM16cdj0fC6+CbJ8WyX9173H11yKGxvE1USQYcErpl1SHOx9Jk8LVb7f+MsUm2fjQF1MEq6xaWI74jem12lZ9CGXFaTL7e87JvfbK7pV+aKpxSBBNFyJgbYm30ibdUwxwKmNVfPb1e0HT9qwenvoV7RobM=,iv:mKqOW0ULXL711uczUbRf9NPo6uPTQoS/IbR46S+JID4=,tag:vE6NYzYLbQHDImov1XGTcg==,type:str]
     pgp:
         - created_at: "2025-01-21T17:55:30Z"
           enc: |-

From 92f5040cbc66e77386572412aed2e821cec0e079 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Mon, 10 Feb 2025 03:04:44 +0800
Subject: [PATCH 186/212] fix(grafana): Fix root URL

---
 configuration/services/metrics/grafana.nix | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/configuration/services/metrics/grafana.nix b/configuration/services/metrics/grafana.nix
index 5c779f2..e597cff 100644
--- a/configuration/services/metrics/grafana.nix
+++ b/configuration/services/metrics/grafana.nix
@@ -6,7 +6,10 @@ in
   services.grafana = {
     enable = true;
     settings = {
-      server.http_port = 3001; # Default overlaps with gitea
+      server = {
+        http_port = 3001; # Default overlaps with gitea
+        root_url = "https://metrics.tlater.net";
+      };
 
       security = {
         admin_user = "tlater";

From 07b5064a85dd3766cbc43866afc31f3462ef748e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 11 Feb 2025 02:56:43 +0800
Subject: [PATCH 187/212] feat(metrics): Add blackbox exporter

---
 configuration/services/metrics/exporters.nix  | 15 +++++++-
 configuration/services/metrics/options.nix    |  3 +-
 .../services/metrics/victoriametrics.nix      | 35 ++++++++++++++++++-
 3 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/configuration/services/metrics/exporters.nix b/configuration/services/metrics/exporters.nix
index ecd69bd..a47a701 100644
--- a/configuration/services/metrics/exporters.nix
+++ b/configuration/services/metrics/exporters.nix
@@ -10,6 +10,20 @@ in
 {
   services.prometheus = {
     exporters = {
+      blackbox = {
+        enable = true;
+        listenAddress = "127.0.0.1";
+        configFile = yaml.generate "blackbox.yaml" {
+          modules = {
+            http_2xx = {
+              prober = "http";
+              timeout = "5s";
+              http.preferred_ip_protocol = "ip4";
+            };
+          };
+        };
+      };
+
       # Periodically check domain registration status
       domain = {
         enable = true;
@@ -71,7 +85,6 @@ in
     # TODO(tlater):
     #   - wireguard (?)
     #   - postgres (?)
-    #   - blackbox (?) (curl to see if http and similar is up)
     #   - ssl_exporter (?)
   };
 }
diff --git a/configuration/services/metrics/options.nix b/configuration/services/metrics/options.nix
index 8868c6c..d69ecfb 100644
--- a/configuration/services/metrics/options.nix
+++ b/configuration/services/metrics/options.nix
@@ -47,7 +47,7 @@ in
               };
 
               extraSettings = mkOption {
-                type = types.anything;
+                inherit (pkgs.formats.yaml { }) type;
                 description = ''
                   Other settings to set for this scrape config.
                 '';
@@ -217,6 +217,7 @@ in
             name: exporter:
             # A bunch of deprecated exporters that need to be ignored
             !(builtins.elem name [
+              "blackbox"
               "minio"
               "tor"
               "unifi-poller"
diff --git a/configuration/services/metrics/victoriametrics.nix b/configuration/services/metrics/victoriametrics.nix
index d72215e..eca65d0 100644
--- a/configuration/services/metrics/victoriametrics.nix
+++ b/configuration/services/metrics/victoriametrics.nix
@@ -1,4 +1,8 @@
-{ config, ... }:
+{ config, lib, ... }:
+let
+  blackbox_host = config.services.prometheus.exporters.blackbox.listenAddress;
+  blackbox_port = config.services.prometheus.exporters.blackbox.port;
+in
 {
   config.services.victoriametrics = {
     enable = true;
@@ -9,6 +13,35 @@
         targets = [ "127.0.0.1:${toString config.services.forgejo.settings.server.HTTP_PORT}" ];
         extraSettings.authorization.credentials_file = config.sops.secrets."forgejo/metrics-token".path;
       };
+
+      blackbox = {
+        static_configs = lib.singleton {
+          targets = lib.mapAttrsToList (vHost: _: "https://${vHost}") config.services.nginx.virtualHosts;
+        };
+
+        extraSettings = {
+          metrics_path = "/probe";
+          params.module = [ "http_2xx" ];
+
+          relabel_configs = [
+            {
+              source_labels = [ "__address__" ];
+              target_label = "__param_target";
+            }
+            {
+              source_labels = [ "__param_target" ];
+              target_label = "instance";
+            }
+            {
+              target_label = "__address__";
+              replacement = "${blackbox_host}:${toString blackbox_port}";
+            }
+          ];
+        };
+      };
+
+      blackbox_exporter.targets = [ "${blackbox_host}:${toString blackbox_port}" ];
+
       coturn.targets = [ "127.0.0.1:9641" ];
 
       crowdsec.targets =

From 5be7d3f10ed59e4bb53c8d65af6174fdab35d1ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 8 Feb 2025 01:59:36 +0800
Subject: [PATCH 188/212] fix(vm): Make sops not break if running without
 battery manager

---
 configuration/sops.nix | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/configuration/sops.nix b/configuration/sops.nix
index 4800e6b..3a1c3d8 100644
--- a/configuration/sops.nix
+++ b/configuration/sops.nix
@@ -1,14 +1,15 @@
+{ config, lib, ... }:
 {
   sops = {
     defaultSopsFile = ../keys/production.yaml;
 
     secrets = {
-      "battery-manager/email" = {
+      "battery-manager/email" = lib.mkIf config.services.batteryManager.enable {
         owner = "battery-manager";
         group = "battery-manager";
       };
 
-      "battery-manager/password" = {
+      "battery-manager/password" = lib.mkIf config.services.batteryManager.enable {
         owner = "battery-manager";
         group = "battery-manager";
       };

From b93ea1aaca49c9aaf170bb13892b0ec9fbc3b84b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 7 Feb 2025 02:47:16 +0800
Subject: [PATCH 189/212] bump(flake.lock): Update sonnenshift input

---
 flake.lock | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/flake.lock b/flake.lock
index d86b361..7f117e9 100644
--- a/flake.lock
+++ b/flake.lock
@@ -266,11 +266,11 @@
         "treefmt-nix": "treefmt-nix"
       },
       "locked": {
-        "lastModified": 1731205797,
-        "narHash": "sha256-F7N1mxH1VrkVNHR3JGNMRvp9+98KYO4b832KS8Gl2xI=",
+        "lastModified": 1738741221,
+        "narHash": "sha256-UiTOA89yQV5YNlO1ZAp4IqJUGWOnTyBC83netvt8rQE=",
         "owner": "nix-community",
         "repo": "poetry2nix",
-        "rev": "f554d27c1544d9c56e5f1f8e2b8aff399803674e",
+        "rev": "be1fe795035d3d36359ca9135b26dcc5321b31fb",
         "type": "github"
       },
       "original": {
@@ -381,11 +381,11 @@
         "poetry2nixi": "poetry2nixi"
       },
       "locked": {
-        "lastModified": 1733296058,
-        "narHash": "sha256-2tYgb4TbvoLk+zsRdCPaglP0s9GCG5HOR9Jm9rsSiHU=",
+        "lastModified": 1738867540,
+        "narHash": "sha256-co2Fs1VoWtTzo7IAeRtaNnyofoUWFOv/Aa/+vSorurA=",
         "ref": "refs/heads/main",
-        "rev": "5f01c17df4dbe841bb6ccd85993c0d9b7368af72",
-        "revCount": 13,
+        "rev": "c6eeff42799c9d4073a241056198004d89bf87df",
+        "revCount": 15,
         "type": "git",
         "url": "ssh://git@github.com/sonnenshift/battery-manager"
       },
@@ -454,8 +454,9 @@
         "type": "github"
       },
       "original": {
-        "id": "systems",
-        "type": "indirect"
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
       }
     },
     "tlaternet-webserver": {

From 3c7b6a7163628216c754bf564cd39e5793c36e61 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 16 Feb 2025 18:35:16 +0800
Subject: [PATCH 190/212] bump: Update inputs

---
 flake.lock                            | 41 ++++++++-------------------
 flake.nix                             |  3 --
 modules/crowdsec/default.nix          |  9 ++----
 pkgs/crowdsec/_sources/generated.json |  8 +++---
 pkgs/crowdsec/_sources/generated.nix  |  8 +++---
 5 files changed, 23 insertions(+), 46 deletions(-)

diff --git a/flake.lock b/flake.lock
index 7f117e9..b2487b6 100644
--- a/flake.lock
+++ b/flake.lock
@@ -27,11 +27,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1737038063,
-        "narHash": "sha256-rMEuiK69MDhjz1JgbaeQ9mBDXMJ2/P8vmOYRbFndXsk=",
+        "lastModified": 1739634831,
+        "narHash": "sha256-xFnU+uUl48Icas2wPQ+ZzlL2O3n8f6J2LrzNK9f2nng=",
         "owner": "nix-community",
         "repo": "disko",
-        "rev": "bf0abfde48f469c256f2b0f481c6281ff04a5db2",
+        "rev": "fa5746ecea1772cf59b3f34c5816ab3531478142",
         "type": "github"
       },
       "original": {
@@ -190,29 +190,13 @@
         "type": "github"
       }
     },
-    "nixpkgs-crowdsec": {
-      "locked": {
-        "lastModified": 1738085579,
-        "narHash": "sha256-7mLjMrOiiIi0vI7BJwbEipYQzwA7JF/NWHP+LM4q5S8=",
-        "owner": "tlater",
-        "repo": "nixpkgs",
-        "rev": "426a7afc9a6ecfdac544bda4022acef31e36df34",
-        "type": "github"
-      },
-      "original": {
-        "owner": "tlater",
-        "ref": "tlater/fix-crowdsec",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1737192615,
-        "narHash": "sha256-jtucJjcdryEZQw1g0RThPSPxCdWNHF42sLp8pmMMGDs=",
+        "lastModified": 1739611738,
+        "narHash": "sha256-3bnOIZz8KXtzcaXGuH9Eriv0HiQyr1EIfcye+VHLQZE=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "09c71b16e6efc9e90edae7eb8b63348702ff9a85",
+        "rev": "31ff66eb77d02e9ac34b7256a02edb1c43fb9998",
         "type": "github"
       },
       "original": {
@@ -224,11 +208,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1737171713,
-        "narHash": "sha256-9mWmMXCto7e8U9hM8ZFozElv4dgOMTe308SSc7rEEFs=",
+        "lastModified": 1739578539,
+        "narHash": "sha256-jGiez5BtGGJUB/LXzRa+4AQurMO9acc1B69kBfgQhJc=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "8773174492fc61571b578f34a59953baba46471a",
+        "rev": "30d4471a8a2a13b716530d3aad60b9846ea5ff83",
         "type": "github"
       },
       "original": {
@@ -326,7 +310,6 @@
         "disko": "disko",
         "foundryvtt": "foundryvtt",
         "nixpkgs": "nixpkgs_2",
-        "nixpkgs-crowdsec": "nixpkgs-crowdsec",
         "nixpkgs-unstable": "nixpkgs-unstable",
         "sonnenshift": "sonnenshift",
         "sops-nix": "sops-nix",
@@ -401,11 +384,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1737107480,
-        "narHash": "sha256-GXUE9+FgxoZU8v0p6ilBJ8NH7k8nKmZjp/7dmMrCv3o=",
+        "lastModified": 1739262228,
+        "narHash": "sha256-7JAGezJ0Dn5qIyA2+T4Dt/xQgAbhCglh6lzCekTVMeU=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "4c4fb93f18b9072c6fa1986221f9a3d7bf1fe4b6",
+        "rev": "07af005bb7d60c7f118d9d9f5530485da5d1e975",
         "type": "github"
       },
       "original": {
diff --git a/flake.nix b/flake.nix
index 3d04d7c..b31d108 100644
--- a/flake.nix
+++ b/flake.nix
@@ -26,8 +26,6 @@
       url = "git+ssh://git@github.com/sonnenshift/battery-manager";
       inputs.nixpkgs.follows = "nixpkgs";
     };
-
-    nixpkgs-crowdsec.url = "github:tlater/nixpkgs/tlater/fix-crowdsec";
   };
 
   outputs =
@@ -106,7 +104,6 @@
         in
         {
           default = vm.config.system.build.vm;
-          crowdsec = pkgs.callPackage "${inputs.nixpkgs-crowdsec}/pkgs/by-name/cr/crowdsec/package.nix" { };
           crowdsec-hub = localPkgs.crowdsec.hub;
           crowdsec-firewall-bouncer = localPkgs.crowdsec.firewall-bouncer;
         };
diff --git a/modules/crowdsec/default.nix b/modules/crowdsec/default.nix
index 0d0ff1c..c0003a5 100644
--- a/modules/crowdsec/default.nix
+++ b/modules/crowdsec/default.nix
@@ -1,5 +1,4 @@
 {
-  flake-inputs,
   pkgs,
   lib,
   config,
@@ -9,8 +8,6 @@ let
   cfg = config.security.crowdsec;
   settingsFormat = pkgs.formats.yaml { };
 
-  crowdsec = flake-inputs.self.packages.${pkgs.system}.crowdsec;
-
   hub = pkgs.fetchFromGitHub {
     owner = "crowdsecurity";
     repo = "hub";
@@ -19,14 +16,14 @@ let
   };
 
   cscli = pkgs.writeShellScriptBin "cscli" ''
-    export PATH="$PATH:${crowdsec}/bin/"
+    export PATH="$PATH:${cfg.package}/bin/"
 
     sudo=exec
     if [ "$USER" != "crowdsec" ]; then
         sudo='exec /run/wrappers/bin/sudo -u crowdsec'
     fi
 
-    $sudo ${crowdsec}/bin/cscli "$@"
+    $sudo ${cfg.package}/bin/cscli "$@"
   '';
 
   acquisitions = ''
@@ -53,7 +50,7 @@ in
 
       package = lib.mkOption {
         type = package;
-        default = crowdsec;
+        default = pkgs.crowdsec;
       };
 
       stateDirectory = lib.mkOption {
diff --git a/pkgs/crowdsec/_sources/generated.json b/pkgs/crowdsec/_sources/generated.json
index 8485779..634bc18 100644
--- a/pkgs/crowdsec/_sources/generated.json
+++ b/pkgs/crowdsec/_sources/generated.json
@@ -21,7 +21,7 @@
     },
     "crowdsec-hub": {
         "cargoLocks": null,
-        "date": "2025-01-30",
+        "date": "2025-02-16",
         "extract": null,
         "name": "crowdsec-hub",
         "passthru": null,
@@ -33,10 +33,10 @@
             "name": null,
             "owner": "crowdsecurity",
             "repo": "hub",
-            "rev": "8f102f5ac79af59d3024ca2771b65ec87411ac02",
-            "sha256": "sha256-8K1HkBg0++Au1dr2KMrl9b2ruqXdo+vqWngOCwL11Mo=",
+            "rev": "f7d7f476f88a4af05e1cfb3994536990adecfb57",
+            "sha256": "sha256-m78uipryHDKixJzrF4K59ioAJ3WJN1JlXEC0DNVMCJ8=",
             "type": "github"
         },
-        "version": "8f102f5ac79af59d3024ca2771b65ec87411ac02"
+        "version": "f7d7f476f88a4af05e1cfb3994536990adecfb57"
     }
 }
\ No newline at end of file
diff --git a/pkgs/crowdsec/_sources/generated.nix b/pkgs/crowdsec/_sources/generated.nix
index 6f845ec..7ef44e6 100644
--- a/pkgs/crowdsec/_sources/generated.nix
+++ b/pkgs/crowdsec/_sources/generated.nix
@@ -14,14 +14,14 @@
   };
   crowdsec-hub = {
     pname = "crowdsec-hub";
-    version = "8f102f5ac79af59d3024ca2771b65ec87411ac02";
+    version = "f7d7f476f88a4af05e1cfb3994536990adecfb57";
     src = fetchFromGitHub {
       owner = "crowdsecurity";
       repo = "hub";
-      rev = "8f102f5ac79af59d3024ca2771b65ec87411ac02";
+      rev = "f7d7f476f88a4af05e1cfb3994536990adecfb57";
       fetchSubmodules = false;
-      sha256 = "sha256-8K1HkBg0++Au1dr2KMrl9b2ruqXdo+vqWngOCwL11Mo=";
+      sha256 = "sha256-m78uipryHDKixJzrF4K59ioAJ3WJN1JlXEC0DNVMCJ8=";
     };
-    date = "2025-01-30";
+    date = "2025-02-16";
   };
 }

From 586ab969a4bed26a3df9b1861deb4194234af40b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 21 Feb 2025 04:09:35 +0800
Subject: [PATCH 191/212] feat(battery-manager): Switch to rust version

---
 configuration/services/battery-manager.nix |   6 +-
 configuration/sops.nix                     |  11 +-
 flake.lock                                 | 846 +++++++++++++++++++--
 flake.nix                                  |   2 +-
 4 files changed, 799 insertions(+), 66 deletions(-)

diff --git a/configuration/services/battery-manager.nix b/configuration/services/battery-manager.nix
index a16cca1..9da7e32 100644
--- a/configuration/services/battery-manager.nix
+++ b/configuration/services/battery-manager.nix
@@ -4,9 +4,13 @@
 
   services.batteryManager = {
     enable = true;
-    battery = "3ca39300-c523-4315-b9a3-d030f85a9373";
 
     emailFile = "${config.sops.secrets."battery-manager/email".path}";
     passwordFile = "${config.sops.secrets."battery-manager/password".path}";
+
+    settings = {
+      battery_id = "3ca39300-c523-4315-b9a3-d030f85a9373";
+      log_level = "DEBUG";
+    };
   };
 }
diff --git a/configuration/sops.nix b/configuration/sops.nix
index 3a1c3d8..0337438 100644
--- a/configuration/sops.nix
+++ b/configuration/sops.nix
@@ -1,18 +1,11 @@
-{ config, lib, ... }:
 {
   sops = {
     defaultSopsFile = ../keys/production.yaml;
 
     secrets = {
-      "battery-manager/email" = lib.mkIf config.services.batteryManager.enable {
-        owner = "battery-manager";
-        group = "battery-manager";
-      };
+      "battery-manager/email" = { };
 
-      "battery-manager/password" = lib.mkIf config.services.batteryManager.enable {
-        owner = "battery-manager";
-        group = "battery-manager";
-      };
+      "battery-manager/password" = { };
 
       # Gitea
       "forgejo/metrics-token" = {
diff --git a/flake.lock b/flake.lock
index b2487b6..276b8b2 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1,5 +1,206 @@
 {
   "nodes": {
+    "cachix": {
+      "inputs": {
+        "devenv": [
+          "sonnenshift",
+          "crate2nix"
+        ],
+        "flake-compat": [
+          "sonnenshift",
+          "crate2nix"
+        ],
+        "nixpkgs": "nixpkgs_3",
+        "pre-commit-hooks": [
+          "sonnenshift",
+          "crate2nix"
+        ]
+      },
+      "locked": {
+        "lastModified": 1709700175,
+        "narHash": "sha256-A0/6ZjLmT9qdYzKHmevnEIC7G+GiZ4UCr8v0poRPzds=",
+        "owner": "cachix",
+        "repo": "cachix",
+        "rev": "be97b37989f11b724197b5f4c7ffd78f12c8c4bf",
+        "type": "github"
+      },
+      "original": {
+        "owner": "cachix",
+        "ref": "latest",
+        "repo": "cachix",
+        "type": "github"
+      }
+    },
+    "cachix_2": {
+      "inputs": {
+        "devenv": [
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable"
+        ],
+        "flake-compat": [
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable"
+        ],
+        "nixpkgs": "nixpkgs_4",
+        "pre-commit-hooks": [
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable"
+        ]
+      },
+      "locked": {
+        "lastModified": 1716549461,
+        "narHash": "sha256-lHy5kgx6J8uD+16SO47dPrbob98sh+W1tf4ceSqPVK4=",
+        "owner": "cachix",
+        "repo": "cachix",
+        "rev": "e2bb269fb8c0828d5d4d2d7b8d09ea85abcacbd4",
+        "type": "github"
+      },
+      "original": {
+        "owner": "cachix",
+        "ref": "latest",
+        "repo": "cachix",
+        "type": "github"
+      }
+    },
+    "cachix_3": {
+      "inputs": {
+        "devenv": [
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
+          "crate2nix_stable"
+        ],
+        "flake-compat": [
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
+          "crate2nix_stable"
+        ],
+        "nixpkgs": "nixpkgs_5",
+        "pre-commit-hooks": [
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
+          "crate2nix_stable"
+        ]
+      },
+      "locked": {
+        "lastModified": 1716549461,
+        "narHash": "sha256-lHy5kgx6J8uD+16SO47dPrbob98sh+W1tf4ceSqPVK4=",
+        "owner": "cachix",
+        "repo": "cachix",
+        "rev": "e2bb269fb8c0828d5d4d2d7b8d09ea85abcacbd4",
+        "type": "github"
+      },
+      "original": {
+        "owner": "cachix",
+        "ref": "latest",
+        "repo": "cachix",
+        "type": "github"
+      }
+    },
+    "crate2nix": {
+      "inputs": {
+        "cachix": "cachix",
+        "crate2nix_stable": "crate2nix_stable",
+        "devshell": "devshell_3",
+        "flake-compat": "flake-compat_4",
+        "flake-parts": "flake-parts_3",
+        "nix-test-runner": "nix-test-runner_3",
+        "nixpkgs": [
+          "sonnenshift",
+          "nixpkgs"
+        ],
+        "pre-commit-hooks": "pre-commit-hooks_3"
+      },
+      "locked": {
+        "lastModified": 1739473963,
+        "narHash": "sha256-ItAhpjNUzEWd/cgZVyW/jvoGbCec4TK29e1Mnmn1oJE=",
+        "owner": "nix-community",
+        "repo": "crate2nix",
+        "rev": "be31feae9a82c225c0fd1bdf978565dc452a483a",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "repo": "crate2nix",
+        "type": "github"
+      }
+    },
+    "crate2nix_stable": {
+      "inputs": {
+        "cachix": "cachix_2",
+        "crate2nix_stable": "crate2nix_stable_2",
+        "devshell": "devshell_2",
+        "flake-compat": "flake-compat_3",
+        "flake-parts": "flake-parts_2",
+        "nix-test-runner": "nix-test-runner_2",
+        "nixpkgs": "nixpkgs_7",
+        "pre-commit-hooks": "pre-commit-hooks_2"
+      },
+      "locked": {
+        "lastModified": 1719760004,
+        "narHash": "sha256-esWhRnt7FhiYq0CcIxw9pvH+ybOQmWBfHYMtleaMhBE=",
+        "owner": "nix-community",
+        "repo": "crate2nix",
+        "rev": "1dee214bb20855fa3e1e7bb98d28922ddaff8c57",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "ref": "0.14.1",
+        "repo": "crate2nix",
+        "type": "github"
+      }
+    },
+    "crate2nix_stable_2": {
+      "inputs": {
+        "cachix": "cachix_3",
+        "crate2nix_stable": "crate2nix_stable_3",
+        "devshell": "devshell",
+        "flake-compat": "flake-compat_2",
+        "flake-parts": "flake-parts",
+        "nix-test-runner": "nix-test-runner",
+        "nixpkgs": "nixpkgs_6",
+        "pre-commit-hooks": "pre-commit-hooks"
+      },
+      "locked": {
+        "lastModified": 1712821484,
+        "narHash": "sha256-rGT3CW64cJS9nlnWPFWSc1iEa3dNZecVVuPVGzcsHe8=",
+        "owner": "nix-community",
+        "repo": "crate2nix",
+        "rev": "42883afcad3823fa5811e967fb7bff54bc3c9d6d",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "ref": "0.14.0",
+        "repo": "crate2nix",
+        "type": "github"
+      }
+    },
+    "crate2nix_stable_3": {
+      "inputs": {
+        "flake-utils": "flake-utils"
+      },
+      "locked": {
+        "lastModified": 1702842982,
+        "narHash": "sha256-A9AowkHIjsy1a4LuiPiVP88FMxyCWK41flZEZOUuwQM=",
+        "owner": "nix-community",
+        "repo": "crate2nix",
+        "rev": "75ac2973affa6b9b4f661a7b592cba6e4f51d426",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "ref": "0.12.0",
+        "repo": "crate2nix",
+        "type": "github"
+      }
+    },
     "deploy-rs": {
       "inputs": {
         "flake-compat": "flake-compat",
@@ -20,6 +221,78 @@
         "type": "github"
       }
     },
+    "devshell": {
+      "inputs": {
+        "flake-utils": "flake-utils_2",
+        "nixpkgs": [
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
+          "crate2nix_stable",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1717408969,
+        "narHash": "sha256-Q0OEFqe35fZbbRPPRdrjTUUChKVhhWXz3T9ZSKmaoVY=",
+        "owner": "numtide",
+        "repo": "devshell",
+        "rev": "1ebbe68d57457c8cae98145410b164b5477761f4",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "devshell",
+        "type": "github"
+      }
+    },
+    "devshell_2": {
+      "inputs": {
+        "flake-utils": "flake-utils_3",
+        "nixpkgs": [
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1717408969,
+        "narHash": "sha256-Q0OEFqe35fZbbRPPRdrjTUUChKVhhWXz3T9ZSKmaoVY=",
+        "owner": "numtide",
+        "repo": "devshell",
+        "rev": "1ebbe68d57457c8cae98145410b164b5477761f4",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "devshell",
+        "type": "github"
+      }
+    },
+    "devshell_3": {
+      "inputs": {
+        "flake-utils": "flake-utils_4",
+        "nixpkgs": [
+          "sonnenshift",
+          "crate2nix",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1711099426,
+        "narHash": "sha256-HzpgM/wc3aqpnHJJ2oDqPBkNsqWbW0WfWUO8lKu8nGk=",
+        "owner": "numtide",
+        "repo": "devshell",
+        "rev": "2d45b54ca4a183f2fdcf4b19c895b64fbf620ee8",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "devshell",
+        "type": "github"
+      }
+    },
     "disko": {
       "inputs": {
         "nixpkgs": [
@@ -42,7 +315,7 @@
     },
     "dream2nix": {
       "inputs": {
-        "nixpkgs": "nixpkgs_3",
+        "nixpkgs": "nixpkgs_8",
         "purescript-overlay": "purescript-overlay",
         "pyproject-nix": "pyproject-nix"
       },
@@ -99,6 +372,48 @@
       }
     },
     "flake-compat_2": {
+      "locked": {
+        "lastModified": 1696426674,
+        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
+        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
+        "revCount": 57,
+        "type": "tarball",
+        "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
+      },
+      "original": {
+        "type": "tarball",
+        "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
+      }
+    },
+    "flake-compat_3": {
+      "locked": {
+        "lastModified": 1696426674,
+        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
+        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
+        "revCount": 57,
+        "type": "tarball",
+        "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
+      },
+      "original": {
+        "type": "tarball",
+        "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
+      }
+    },
+    "flake-compat_4": {
+      "locked": {
+        "lastModified": 1696426674,
+        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
+        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
+        "revCount": 57,
+        "type": "tarball",
+        "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
+      },
+      "original": {
+        "type": "tarball",
+        "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
+      }
+    },
+    "flake-compat_5": {
       "flake": false,
       "locked": {
         "lastModified": 1696426674,
@@ -114,16 +429,157 @@
         "type": "github"
       }
     },
+    "flake-parts": {
+      "inputs": {
+        "nixpkgs-lib": [
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
+          "crate2nix_stable",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1719745305,
+        "narHash": "sha256-xwgjVUpqSviudEkpQnioeez1Uo2wzrsMaJKJClh+Bls=",
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "rev": "c3c5ecc05edc7dafba779c6c1a61cd08ac6583e9",
+        "type": "github"
+      },
+      "original": {
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "type": "github"
+      }
+    },
+    "flake-parts_2": {
+      "inputs": {
+        "nixpkgs-lib": [
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1719745305,
+        "narHash": "sha256-xwgjVUpqSviudEkpQnioeez1Uo2wzrsMaJKJClh+Bls=",
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "rev": "c3c5ecc05edc7dafba779c6c1a61cd08ac6583e9",
+        "type": "github"
+      },
+      "original": {
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "type": "github"
+      }
+    },
+    "flake-parts_3": {
+      "inputs": {
+        "nixpkgs-lib": [
+          "sonnenshift",
+          "crate2nix",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1712014858,
+        "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
+        "type": "github"
+      },
+      "original": {
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "type": "github"
+      }
+    },
     "flake-utils": {
       "inputs": {
         "systems": "systems_2"
       },
       "locked": {
-        "lastModified": 1726560853,
-        "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
+        "lastModified": 1694529238,
+        "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
+        "rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "flake-utils_2": {
+      "inputs": {
+        "systems": "systems_3"
+      },
+      "locked": {
+        "lastModified": 1701680307,
+        "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "flake-utils_3": {
+      "inputs": {
+        "systems": "systems_4"
+      },
+      "locked": {
+        "lastModified": 1701680307,
+        "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "flake-utils_4": {
+      "inputs": {
+        "systems": "systems_5"
+      },
+      "locked": {
+        "lastModified": 1701680307,
+        "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "flake-utils_5": {
+      "inputs": {
+        "systems": "systems_6"
+      },
+      "locked": {
+        "lastModified": 1710146030,
+        "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
         "type": "github"
       },
       "original": {
@@ -152,25 +608,123 @@
         "type": "github"
       }
     },
-    "nix-github-actions": {
+    "gitignore": {
       "inputs": {
         "nixpkgs": [
           "sonnenshift",
-          "poetry2nixi",
+          "crate2nix",
+          "crate2nix_stable",
+          "crate2nix_stable",
+          "pre-commit-hooks",
           "nixpkgs"
         ]
       },
       "locked": {
-        "lastModified": 1729742964,
-        "narHash": "sha256-B4mzTcQ0FZHdpeWcpDYPERtyjJd/NIuaQ9+BV1h+MpA=",
-        "owner": "nix-community",
-        "repo": "nix-github-actions",
-        "rev": "e04df33f62cdcf93d73e9a04142464753a16db67",
+        "lastModified": 1709087332,
+        "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
+        "owner": "hercules-ci",
+        "repo": "gitignore.nix",
+        "rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
         "type": "github"
       },
       "original": {
-        "owner": "nix-community",
-        "repo": "nix-github-actions",
+        "owner": "hercules-ci",
+        "repo": "gitignore.nix",
+        "type": "github"
+      }
+    },
+    "gitignore_2": {
+      "inputs": {
+        "nixpkgs": [
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
+          "pre-commit-hooks",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1709087332,
+        "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
+        "owner": "hercules-ci",
+        "repo": "gitignore.nix",
+        "rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
+        "type": "github"
+      },
+      "original": {
+        "owner": "hercules-ci",
+        "repo": "gitignore.nix",
+        "type": "github"
+      }
+    },
+    "gitignore_3": {
+      "inputs": {
+        "nixpkgs": [
+          "sonnenshift",
+          "crate2nix",
+          "pre-commit-hooks",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1709087332,
+        "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
+        "owner": "hercules-ci",
+        "repo": "gitignore.nix",
+        "rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
+        "type": "github"
+      },
+      "original": {
+        "owner": "hercules-ci",
+        "repo": "gitignore.nix",
+        "type": "github"
+      }
+    },
+    "nix-test-runner": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1588761593,
+        "narHash": "sha256-FKJykltAN/g3eIceJl4SfDnnyuH2jHImhMrXS2KvGIs=",
+        "owner": "stoeffel",
+        "repo": "nix-test-runner",
+        "rev": "c45d45b11ecef3eb9d834c3b6304c05c49b06ca2",
+        "type": "github"
+      },
+      "original": {
+        "owner": "stoeffel",
+        "repo": "nix-test-runner",
+        "type": "github"
+      }
+    },
+    "nix-test-runner_2": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1588761593,
+        "narHash": "sha256-FKJykltAN/g3eIceJl4SfDnnyuH2jHImhMrXS2KvGIs=",
+        "owner": "stoeffel",
+        "repo": "nix-test-runner",
+        "rev": "c45d45b11ecef3eb9d834c3b6304c05c49b06ca2",
+        "type": "github"
+      },
+      "original": {
+        "owner": "stoeffel",
+        "repo": "nix-test-runner",
+        "type": "github"
+      }
+    },
+    "nix-test-runner_3": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1588761593,
+        "narHash": "sha256-FKJykltAN/g3eIceJl4SfDnnyuH2jHImhMrXS2KvGIs=",
+        "owner": "stoeffel",
+        "repo": "nix-test-runner",
+        "rev": "c45d45b11ecef3eb9d834c3b6304c05c49b06ca2",
+        "type": "github"
+      },
+      "original": {
+        "owner": "stoeffel",
+        "repo": "nix-test-runner",
         "type": "github"
       }
     },
@@ -223,6 +777,80 @@
       }
     },
     "nixpkgs_3": {
+      "locked": {
+        "lastModified": 1700612854,
+        "narHash": "sha256-yrQ8osMD+vDLGFX7pcwsY/Qr5PUd6OmDMYJZzZi0+zc=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "19cbff58383a4ae384dea4d1d0c823d72b49d614",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixos-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs_4": {
+      "locked": {
+        "lastModified": 1715534503,
+        "narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "2057814051972fa1453ddfb0d98badbea9b83c06",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixos-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs_5": {
+      "locked": {
+        "lastModified": 1715534503,
+        "narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "2057814051972fa1453ddfb0d98badbea9b83c06",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixos-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs_6": {
+      "locked": {
+        "lastModified": 1719506693,
+        "narHash": "sha256-C8e9S7RzshSdHB7L+v9I51af1gDM5unhJ2xO1ywxNH8=",
+        "path": "/nix/store/4p0avw1s3vf27hspgqsrqs37gxk4i83i-source",
+        "rev": "b2852eb9365c6de48ffb0dc2c9562591f652242a",
+        "type": "path"
+      },
+      "original": {
+        "id": "nixpkgs",
+        "type": "indirect"
+      }
+    },
+    "nixpkgs_7": {
+      "locked": {
+        "lastModified": 1719506693,
+        "narHash": "sha256-C8e9S7RzshSdHB7L+v9I51af1gDM5unhJ2xO1ywxNH8=",
+        "path": "/nix/store/4p0avw1s3vf27hspgqsrqs37gxk4i83i-source",
+        "rev": "b2852eb9365c6de48ffb0dc2c9562591f652242a",
+        "type": "path"
+      },
+      "original": {
+        "id": "nixpkgs",
+        "type": "indirect"
+      }
+    },
+    "nixpkgs_8": {
       "locked": {
         "lastModified": 1729850857,
         "narHash": "sha256-WvLXzNNnnw+qpFOmgaM3JUlNEH+T4s22b5i2oyyCpXE=",
@@ -238,34 +866,118 @@
         "type": "github"
       }
     },
-    "poetry2nixi": {
+    "pre-commit-hooks": {
       "inputs": {
-        "flake-utils": "flake-utils",
-        "nix-github-actions": "nix-github-actions",
+        "flake-compat": [
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
+          "crate2nix_stable",
+          "flake-compat"
+        ],
+        "gitignore": "gitignore",
         "nixpkgs": [
           "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
+          "crate2nix_stable",
           "nixpkgs"
         ],
-        "systems": "systems_3",
-        "treefmt-nix": "treefmt-nix"
+        "nixpkgs-stable": [
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
+          "crate2nix_stable",
+          "nixpkgs"
+        ]
       },
       "locked": {
-        "lastModified": 1738741221,
-        "narHash": "sha256-UiTOA89yQV5YNlO1ZAp4IqJUGWOnTyBC83netvt8rQE=",
-        "owner": "nix-community",
-        "repo": "poetry2nix",
-        "rev": "be1fe795035d3d36359ca9135b26dcc5321b31fb",
+        "lastModified": 1719259945,
+        "narHash": "sha256-F1h+XIsGKT9TkGO3omxDLEb/9jOOsI6NnzsXFsZhry4=",
+        "owner": "cachix",
+        "repo": "pre-commit-hooks.nix",
+        "rev": "0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07",
         "type": "github"
       },
       "original": {
-        "owner": "nix-community",
-        "repo": "poetry2nix",
+        "owner": "cachix",
+        "repo": "pre-commit-hooks.nix",
+        "type": "github"
+      }
+    },
+    "pre-commit-hooks_2": {
+      "inputs": {
+        "flake-compat": [
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
+          "flake-compat"
+        ],
+        "gitignore": "gitignore_2",
+        "nixpkgs": [
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
+          "nixpkgs"
+        ],
+        "nixpkgs-stable": [
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1719259945,
+        "narHash": "sha256-F1h+XIsGKT9TkGO3omxDLEb/9jOOsI6NnzsXFsZhry4=",
+        "owner": "cachix",
+        "repo": "pre-commit-hooks.nix",
+        "rev": "0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07",
+        "type": "github"
+      },
+      "original": {
+        "owner": "cachix",
+        "repo": "pre-commit-hooks.nix",
+        "type": "github"
+      }
+    },
+    "pre-commit-hooks_3": {
+      "inputs": {
+        "flake-compat": [
+          "sonnenshift",
+          "crate2nix",
+          "flake-compat"
+        ],
+        "flake-utils": "flake-utils_5",
+        "gitignore": "gitignore_3",
+        "nixpkgs": [
+          "sonnenshift",
+          "crate2nix",
+          "nixpkgs"
+        ],
+        "nixpkgs-stable": [
+          "sonnenshift",
+          "crate2nix",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1712055707,
+        "narHash": "sha256-4XLvuSIDZJGS17xEwSrNuJLL7UjDYKGJSbK1WWX2AK8=",
+        "owner": "cachix",
+        "repo": "pre-commit-hooks.nix",
+        "rev": "e35aed5fda3cc79f88ed7f1795021e559582093a",
+        "type": "github"
+      },
+      "original": {
+        "owner": "cachix",
+        "repo": "pre-commit-hooks.nix",
         "type": "github"
       }
     },
     "purescript-overlay": {
       "inputs": {
-        "flake-compat": "flake-compat_2",
+        "flake-compat": "flake-compat_5",
         "nixpkgs": [
           "tlaternet-webserver",
           "dream2nix",
@@ -358,21 +1070,22 @@
     },
     "sonnenshift": {
       "inputs": {
+        "crate2nix": "crate2nix",
         "nixpkgs": [
           "nixpkgs"
-        ],
-        "poetry2nixi": "poetry2nixi"
+        ]
       },
       "locked": {
-        "lastModified": 1738867540,
-        "narHash": "sha256-co2Fs1VoWtTzo7IAeRtaNnyofoUWFOv/Aa/+vSorurA=",
-        "ref": "refs/heads/main",
-        "rev": "c6eeff42799c9d4073a241056198004d89bf87df",
-        "revCount": 15,
+        "lastModified": 1740082109,
+        "narHash": "sha256-WdRNkwsIotFOSymee/yQyH46RmYtuxd1FENhvGL4KRc=",
+        "ref": "tlater/rust-rewrite",
+        "rev": "a1b48cf2ba194054e2d8816c94a84cebc4fb5de0",
+        "revCount": 23,
         "type": "git",
         "url": "ssh://git@github.com/sonnenshift/battery-manager"
       },
       "original": {
+        "ref": "tlater/rust-rewrite",
         "type": "git",
         "url": "ssh://git@github.com/sonnenshift/battery-manager"
       }
@@ -442,6 +1155,51 @@
         "type": "github"
       }
     },
+    "systems_4": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    },
+    "systems_5": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    },
+    "systems_6": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    },
     "tlaternet-webserver": {
       "inputs": {
         "dream2nix": "dream2nix",
@@ -464,28 +1222,6 @@
         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git"
       }
     },
-    "treefmt-nix": {
-      "inputs": {
-        "nixpkgs": [
-          "sonnenshift",
-          "poetry2nixi",
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1730120726,
-        "narHash": "sha256-LqHYIxMrl/1p3/kvm2ir925tZ8DkI0KA10djk8wecSk=",
-        "owner": "numtide",
-        "repo": "treefmt-nix",
-        "rev": "9ef337e492a5555d8e17a51c911ff1f02635be15",
-        "type": "github"
-      },
-      "original": {
-        "owner": "numtide",
-        "repo": "treefmt-nix",
-        "type": "github"
-      }
-    },
     "utils": {
       "inputs": {
         "systems": "systems"
diff --git a/flake.nix b/flake.nix
index b31d108..737a17f 100644
--- a/flake.nix
+++ b/flake.nix
@@ -23,7 +23,7 @@
     };
 
     sonnenshift = {
-      url = "git+ssh://git@github.com/sonnenshift/battery-manager";
+      url = "git+ssh://git@github.com/sonnenshift/battery-manager?ref=tlater/rust-rewrite";
       inputs.nixpkgs.follows = "nixpkgs";
     };
   };

From a60cb7f60cc58e2696f171884f9130d451b3d2c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 16 Feb 2025 18:46:25 +0800
Subject: [PATCH 192/212] chore(coturn): Switch to letsencrypt certificate

Fixes #107
---
 configuration/nginx.nix                       |  8 ++++++-
 configuration/services/conduit/default.nix    | 11 +++++----
 configuration/services/metrics/exporters.nix  | 10 ++++++++
 .../services/metrics/victoriametrics.nix      | 24 +++++++++++++++++++
 4 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/configuration/nginx.nix b/configuration/nginx.nix
index 0b72cc1..3ec3bd9 100644
--- a/configuration/nginx.nix
+++ b/configuration/nginx.nix
@@ -53,7 +53,7 @@
         "*.tlater.com"
       ];
       dnsProvider = "porkbun";
-      group = "nginx";
+      group = "ssl-cert";
       credentialFiles = {
         PORKBUN_API_KEY_FILE = config.sops.secrets."porkbun/api-key".path;
         PORKBUN_SECRET_API_KEY_FILE = config.sops.secrets."porkbun/secret-api-key".path;
@@ -61,6 +61,12 @@
     };
   };
 
+  users.groups.ssl-cert = { };
+
+  systemd.services.nginx.serviceConfig.SupplementaryGroups = [
+    config.security.acme.certs."tlater.net".group
+  ];
+
   services.backups.acme = {
     user = "acme";
     paths = lib.mapAttrsToList (
diff --git a/configuration/services/conduit/default.nix b/configuration/services/conduit/default.nix
index c3803f4..c7e4ab4 100644
--- a/configuration/services/conduit/default.nix
+++ b/configuration/services/conduit/default.nix
@@ -50,6 +50,10 @@ in
   # See also https://gitlab.com/famedly/conduit/-/issues/314
   systemd.services.conduit.serviceConfig.EnvironmentFile = config.sops.secrets."turn/env".path;
 
+  systemd.services.coturn.serviceConfig.SupplementaryGroups = [
+    config.security.acme.certs."tlater.net".group
+  ];
+
   services.coturn = {
     enable = true;
     no-cli = true;
@@ -59,11 +63,8 @@ in
     relay-ips = [ "116.202.158.55" ];
 
     # SSL config
-    #
-    # TODO(tlater): Switch to letsencrypt once google fix:
-    #  https://github.com/vector-im/element-android/issues/1533
-    pkey = config.sops.secrets."turn/ssl-key".path;
-    cert = config.sops.secrets."turn/ssl-cert".path;
+    pkey = "${config.security.acme.certs."tlater.net".directory}/key.pem";
+    cert = "${config.security.acme.certs."tlater.net".directory}/fullchain.pem";
 
     # Based on suggestions from
     # https://github.com/matrix-org/synapse/blob/develop/docs/turn-howto.md
diff --git a/configuration/services/metrics/exporters.nix b/configuration/services/metrics/exporters.nix
index a47a701..78ba684 100644
--- a/configuration/services/metrics/exporters.nix
+++ b/configuration/services/metrics/exporters.nix
@@ -20,6 +20,16 @@ in
               timeout = "5s";
               http.preferred_ip_protocol = "ip4";
             };
+
+            turn_server = {
+              prober = "tcp";
+              timeout = "5s";
+              tcp = {
+                preferred_ip_protocol = "ip4";
+                source_ip_address = "116.202.158.55";
+                tls = true;
+              };
+            };
           };
         };
       };
diff --git a/configuration/services/metrics/victoriametrics.nix b/configuration/services/metrics/victoriametrics.nix
index eca65d0..4a78d46 100644
--- a/configuration/services/metrics/victoriametrics.nix
+++ b/configuration/services/metrics/victoriametrics.nix
@@ -40,6 +40,30 @@ in
         };
       };
 
+      blackbox_turn = {
+        targets = [ "turn.tlater.net:${toString config.services.coturn.tls-listening-port}" ];
+
+        extraSettings = {
+          metrics_path = "/probe";
+          params.module = [ "turn_server" ];
+
+          relabel_configs = [
+            {
+              source_labels = [ "__address__" ];
+              target_label = "__param_target";
+            }
+            {
+              source_labels = [ "__param_target" ];
+              target_label = "instance";
+            }
+            {
+              target_label = "__address__";
+              replacement = "${blackbox_host}:${toString blackbox_port}";
+            }
+          ];
+        };
+      };
+
       blackbox_exporter.targets = [ "${blackbox_host}:${toString blackbox_port}" ];
 
       coturn.targets = [ "127.0.0.1:9641" ];

From be1d739b400a5c16c7b51c82916960b30692995c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 23 Feb 2025 01:43:13 +0800
Subject: [PATCH 193/212] bump: Update inputs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/fa5746ecea1772cf59b3f34c5816ab3531478142?narHash=sha256-xFnU%2BuUl48Icas2wPQ%2BZzlL2O3n8f6J2LrzNK9f2nng%3D' (2025-02-15)
  → 'github:nix-community/disko/15dbf8cebd8e2655a883b74547108e089f051bf0?narHash=sha256-lSOXdgW/1zi/SSu7xp71v%2B55D5Egz8ACv0STkj7fhbs%3D' (2025-02-18)
• Updated input 'foundryvtt':
    'github:reckenrode/nix-foundryvtt/0a72a4bf64224c6584fd1b9e9f0012dd09af979a?narHash=sha256-vM9C1gFiQGa3nTYqmTBI8MoiUfprkQdepUBbxV7ECMQ%3D' (2025-01-17)
  → 'github:reckenrode/nix-foundryvtt/a7fa493ba2c623cf90e83756b62285b3b58f18d2?narHash=sha256-u3m%2BawbdL%2B0BKk8IWidsWMr%2BR0ian3GZMUlH7623kd8%3D' (2025-02-16)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/30d4471a8a2a13b716530d3aad60b9846ea5ff83?narHash=sha256-jGiez5BtGGJUB/LXzRa%2B4AQurMO9acc1B69kBfgQhJc%3D' (2025-02-15)
  → 'github:nixos/nixpkgs/11415c7ae8539d6292f2928317ee7a8410b28bb9?narHash=sha256-SSYxFhqCOb3aiPb6MmN68yEzBIltfom8IgRz7phHscM%3D' (2025-02-21)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/31ff66eb77d02e9ac34b7256a02edb1c43fb9998?narHash=sha256-3bnOIZz8KXtzcaXGuH9Eriv0HiQyr1EIfcye%2BVHLQZE%3D' (2025-02-15)
  → 'github:nixos/nixpkgs/8465e233b0668cf162c608a92e62e8d78c1ba7e4?narHash=sha256-wzBbGGZ6i1VVBA/cDJaLfuuGYCUriD7fwsLgJJHRVRk%3D' (2025-02-22)
---
 flake.lock                            | 27 +++++++++++++--------------
 flake.nix                             |  2 +-
 pkgs/crowdsec/_sources/generated.json |  8 ++++----
 pkgs/crowdsec/_sources/generated.nix  |  8 ++++----
 4 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/flake.lock b/flake.lock
index 276b8b2..37c3d5f 100644
--- a/flake.lock
+++ b/flake.lock
@@ -300,11 +300,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1739634831,
-        "narHash": "sha256-xFnU+uUl48Icas2wPQ+ZzlL2O3n8f6J2LrzNK9f2nng=",
+        "lastModified": 1739841949,
+        "narHash": "sha256-lSOXdgW/1zi/SSu7xp71v+55D5Egz8ACv0STkj7fhbs=",
         "owner": "nix-community",
         "repo": "disko",
-        "rev": "fa5746ecea1772cf59b3f34c5816ab3531478142",
+        "rev": "15dbf8cebd8e2655a883b74547108e089f051bf0",
         "type": "github"
       },
       "original": {
@@ -595,11 +595,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1737076827,
-        "narHash": "sha256-vM9C1gFiQGa3nTYqmTBI8MoiUfprkQdepUBbxV7ECMQ=",
+        "lastModified": 1739712626,
+        "narHash": "sha256-u3m+awbdL+0BKk8IWidsWMr+R0ian3GZMUlH7623kd8=",
         "owner": "reckenrode",
         "repo": "nix-foundryvtt",
-        "rev": "0a72a4bf64224c6584fd1b9e9f0012dd09af979a",
+        "rev": "a7fa493ba2c623cf90e83756b62285b3b58f18d2",
         "type": "github"
       },
       "original": {
@@ -746,11 +746,11 @@
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1739611738,
-        "narHash": "sha256-3bnOIZz8KXtzcaXGuH9Eriv0HiQyr1EIfcye+VHLQZE=",
+        "lastModified": 1740215764,
+        "narHash": "sha256-wzBbGGZ6i1VVBA/cDJaLfuuGYCUriD7fwsLgJJHRVRk=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "31ff66eb77d02e9ac34b7256a02edb1c43fb9998",
+        "rev": "8465e233b0668cf162c608a92e62e8d78c1ba7e4",
         "type": "github"
       },
       "original": {
@@ -762,11 +762,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1739578539,
-        "narHash": "sha256-jGiez5BtGGJUB/LXzRa+4AQurMO9acc1B69kBfgQhJc=",
+        "lastModified": 1740162160,
+        "narHash": "sha256-SSYxFhqCOb3aiPb6MmN68yEzBIltfom8IgRz7phHscM=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "30d4471a8a2a13b716530d3aad60b9846ea5ff83",
+        "rev": "11415c7ae8539d6292f2928317ee7a8410b28bb9",
         "type": "github"
       },
       "original": {
@@ -1078,14 +1078,13 @@
       "locked": {
         "lastModified": 1740082109,
         "narHash": "sha256-WdRNkwsIotFOSymee/yQyH46RmYtuxd1FENhvGL4KRc=",
-        "ref": "tlater/rust-rewrite",
+        "ref": "refs/heads/main",
         "rev": "a1b48cf2ba194054e2d8816c94a84cebc4fb5de0",
         "revCount": 23,
         "type": "git",
         "url": "ssh://git@github.com/sonnenshift/battery-manager"
       },
       "original": {
-        "ref": "tlater/rust-rewrite",
         "type": "git",
         "url": "ssh://git@github.com/sonnenshift/battery-manager"
       }
diff --git a/flake.nix b/flake.nix
index 737a17f..b31d108 100644
--- a/flake.nix
+++ b/flake.nix
@@ -23,7 +23,7 @@
     };
 
     sonnenshift = {
-      url = "git+ssh://git@github.com/sonnenshift/battery-manager?ref=tlater/rust-rewrite";
+      url = "git+ssh://git@github.com/sonnenshift/battery-manager";
       inputs.nixpkgs.follows = "nixpkgs";
     };
   };
diff --git a/pkgs/crowdsec/_sources/generated.json b/pkgs/crowdsec/_sources/generated.json
index 634bc18..ac251aa 100644
--- a/pkgs/crowdsec/_sources/generated.json
+++ b/pkgs/crowdsec/_sources/generated.json
@@ -21,7 +21,7 @@
     },
     "crowdsec-hub": {
         "cargoLocks": null,
-        "date": "2025-02-16",
+        "date": "2025-02-22",
         "extract": null,
         "name": "crowdsec-hub",
         "passthru": null,
@@ -33,10 +33,10 @@
             "name": null,
             "owner": "crowdsecurity",
             "repo": "hub",
-            "rev": "f7d7f476f88a4af05e1cfb3994536990adecfb57",
-            "sha256": "sha256-m78uipryHDKixJzrF4K59ioAJ3WJN1JlXEC0DNVMCJ8=",
+            "rev": "f9883cd6c7d1913c13e4a3a69d9a0b887a7d57df",
+            "sha256": "sha256-45pUln7Qj5luY9I9BE2qhzjH7kv4IbYvNoEX3/4AVVg=",
             "type": "github"
         },
-        "version": "f7d7f476f88a4af05e1cfb3994536990adecfb57"
+        "version": "f9883cd6c7d1913c13e4a3a69d9a0b887a7d57df"
     }
 }
\ No newline at end of file
diff --git a/pkgs/crowdsec/_sources/generated.nix b/pkgs/crowdsec/_sources/generated.nix
index 7ef44e6..9c63cc5 100644
--- a/pkgs/crowdsec/_sources/generated.nix
+++ b/pkgs/crowdsec/_sources/generated.nix
@@ -14,14 +14,14 @@
   };
   crowdsec-hub = {
     pname = "crowdsec-hub";
-    version = "f7d7f476f88a4af05e1cfb3994536990adecfb57";
+    version = "f9883cd6c7d1913c13e4a3a69d9a0b887a7d57df";
     src = fetchFromGitHub {
       owner = "crowdsecurity";
       repo = "hub";
-      rev = "f7d7f476f88a4af05e1cfb3994536990adecfb57";
+      rev = "f9883cd6c7d1913c13e4a3a69d9a0b887a7d57df";
       fetchSubmodules = false;
-      sha256 = "sha256-m78uipryHDKixJzrF4K59ioAJ3WJN1JlXEC0DNVMCJ8=";
+      sha256 = "sha256-45pUln7Qj5luY9I9BE2qhzjH7kv4IbYvNoEX3/4AVVg=";
     };
-    date = "2025-02-16";
+    date = "2025-02-22";
   };
 }

From e4a7fa8764f2c283e0d1d989e53d61e078ed48d1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 28 Feb 2025 01:47:58 +0800
Subject: [PATCH 194/212] feat(grafana): Use the victoriametrics metrics plugin

---
 configuration/services/metrics/grafana.nix | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/configuration/services/metrics/grafana.nix b/configuration/services/metrics/grafana.nix
index e597cff..d14b908 100644
--- a/configuration/services/metrics/grafana.nix
+++ b/configuration/services/metrics/grafana.nix
@@ -1,4 +1,4 @@
-{ config, ... }:
+{ pkgs, config, ... }:
 let
   domain = "metrics.${config.services.nginx.domain}";
 in
@@ -28,6 +28,10 @@ in
       };
     };
 
+    declarativePlugins = [
+      pkgs.grafanaPlugins.victoriametrics-metrics-datasource
+    ];
+
     provision = {
       enable = true;
 
@@ -35,7 +39,9 @@ in
         {
           name = "Victoriametrics - tlater.net";
           url = "http://localhost:8428";
-          type = "prometheus";
+          type = "victoriametrics-metrics-datasource";
+          access = "proxy";
+          isDefault = true;
         }
       ];
     };

From a398790ef496f6cac8a485b2a3ef1d065e48d639 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 28 Feb 2025 01:43:10 +0800
Subject: [PATCH 195/212] feat(metrics): Add victorialogs

---
 configuration/services/metrics/default.nix    |   1 +
 configuration/services/metrics/grafana.nix    |  15 ++-
 .../services/metrics/victorialogs.nix         | 110 ++++++++++++++++++
 3 files changed, 125 insertions(+), 1 deletion(-)
 create mode 100644 configuration/services/metrics/victorialogs.nix

diff --git a/configuration/services/metrics/default.nix b/configuration/services/metrics/default.nix
index 84e126a..fe250fe 100644
--- a/configuration/services/metrics/default.nix
+++ b/configuration/services/metrics/default.nix
@@ -5,5 +5,6 @@
     ./exporters.nix
     ./grafana.nix
     ./victoriametrics.nix
+    ./victorialogs.nix
   ];
 }
diff --git a/configuration/services/metrics/grafana.nix b/configuration/services/metrics/grafana.nix
index d14b908..b872833 100644
--- a/configuration/services/metrics/grafana.nix
+++ b/configuration/services/metrics/grafana.nix
@@ -1,4 +1,9 @@
-{ pkgs, config, ... }:
+{
+  pkgs,
+  config,
+  flake-inputs,
+  ...
+}:
 let
   domain = "metrics.${config.services.nginx.domain}";
 in
@@ -30,6 +35,7 @@ in
 
     declarativePlugins = [
       pkgs.grafanaPlugins.victoriametrics-metrics-datasource
+      flake-inputs.nixpkgs-unstable.legacyPackages.${pkgs.system}.grafanaPlugins.victoriametrics-logs-datasource
     ];
 
     provision = {
@@ -43,6 +49,13 @@ in
           access = "proxy";
           isDefault = true;
         }
+
+        {
+          name = "Victorialogs - tlater.net";
+          url = "http://${config.services.victorialogs.bindAddress}";
+          type = "victoriametrics-logs-datasource";
+          access = "proxy";
+        }
       ];
     };
   };
diff --git a/configuration/services/metrics/victorialogs.nix b/configuration/services/metrics/victorialogs.nix
new file mode 100644
index 0000000..ed74c59
--- /dev/null
+++ b/configuration/services/metrics/victorialogs.nix
@@ -0,0 +1,110 @@
+{
+  config,
+  pkgs,
+  lib,
+  ...
+}:
+let
+  cfg = config.services.victorialogs;
+  pkg = pkgs.victoriametrics;
+  dirname = "victorialogs";
+in
+{
+  options.services.victorialogs =
+    let
+      inherit (lib.types) str;
+    in
+    {
+      listenAddress = lib.mkOption {
+        default = ":9428";
+        type = str;
+      };
+
+      bindAddress = lib.mkOption {
+        readOnly = true;
+        type = str;
+        description = ''
+          Final address on which victorialogs listens.
+        '';
+      };
+    };
+
+  config = {
+    services.victorialogs.bindAddress =
+      (lib.optionalString (lib.hasPrefix ":" cfg.listenAddress) "127.0.0.1") + cfg.listenAddress;
+
+    services.journald.upload = {
+      enable = true;
+      settings.Upload = {
+        URL = "http://${cfg.bindAddress}/insert/journald";
+        NetworkTimeoutSec = "20s";
+      };
+    };
+
+    systemd.services."systemd-journal-upload".after = [ "victorialogs.service" ];
+
+    systemd.services.victorialogs = {
+      description = "VictoriaLogs log database";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network.target" ];
+      startLimitBurst = 5;
+
+      serviceConfig = {
+        ExecStart = lib.escapeShellArgs [
+          "${pkg}/bin/victoria-logs"
+          "-storageDataPath=/var/lib/${dirname}"
+          "-httpListenAddr=${cfg.listenAddress}"
+        ];
+
+        DynamicUser = true;
+        RestartSec = 1;
+        Restart = "on-failure";
+        RuntimeDirectory = dirname;
+        RuntimeDirectoryMode = "0700";
+        StateDirectory = dirname;
+        StateDirectoryMode = "0700";
+
+        LimitNOFILE = 1048576;
+
+        # Hardening
+        DeviceAllow = [ "/dev/null rw" ];
+        DevicePolicy = "strict";
+        LockPersonality = true;
+        MemoryDenyWriteExecute = true;
+        NoNewPrivileges = true;
+        PrivateDevices = true;
+        PrivateTmp = true;
+        PrivateUsers = true;
+        ProtectClock = true;
+        ProtectControlGroups = true;
+        ProtectHome = true;
+        ProtectHostname = true;
+        ProtectKernelLogs = true;
+        ProtectKernelModules = true;
+        ProtectKernelTunables = true;
+        ProtectProc = "invisible";
+        ProtectSystem = "full";
+        RemoveIPC = true;
+        RestrictAddressFamilies = [
+          "AF_INET"
+          "AF_INET6"
+          "AF_UNIX"
+        ];
+        RestrictNamespaces = true;
+        RestrictRealtime = true;
+        RestrictSUIDSGID = true;
+        SystemCallArchitectures = "native";
+        SystemCallFilter = [
+          "@system-service"
+          "~@privileged"
+        ];
+      };
+
+      postStart = lib.mkBefore ''
+        until ${lib.getBin pkgs.curl}/bin/curl -s -o /dev/null http://${cfg.bindAddress}/ping; do
+          sleep 1;
+        done
+      '';
+    };
+  };
+}

From 3c6afa0c66544826169432018f82ae22169c12cf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 4 Apr 2025 21:06:27 +0800
Subject: [PATCH 196/212] feat(matrix): Switch to conduwuit

This fixes support for the new sliding sync API.
---
 .../hardware-specific/hetzner/disko.nix       |  11 +
 configuration/services/conduit/default.nix    |  19 +-
 flake.lock                                    | 912 +++++++++++++++---
 flake.nix                                     |   4 +
 4 files changed, 807 insertions(+), 139 deletions(-)

diff --git a/configuration/hardware-specific/hetzner/disko.nix b/configuration/hardware-specific/hetzner/disko.nix
index cc15471..7e1acd7 100644
--- a/configuration/hardware-specific/hetzner/disko.nix
+++ b/configuration/hardware-specific/hetzner/disko.nix
@@ -80,6 +80,17 @@
                     inherit mountOptions;
                     mountpoint = "/var";
                   };
+                  "/volume/var/lib/private/matrix-conduit" = {
+                    mountOptions = [
+                      # Explicitly don't compress here, since
+                      # conduwuit's database does compression by
+                      # itself, and relies on being able to read the
+                      # raw file data from disk (which is impossible
+                      # if btrfs compresses it)
+                      "noatime"
+                    ];
+                    mountpoint = "/var/lib/private/matrix-conduit";
+                  };
                   "/volume/nix-store" = {
                     inherit mountOptions;
                     mountpoint = "/nix";
diff --git a/configuration/services/conduit/default.nix b/configuration/services/conduit/default.nix
index c7e4ab4..5a2b8ac 100644
--- a/configuration/services/conduit/default.nix
+++ b/configuration/services/conduit/default.nix
@@ -1,4 +1,6 @@
 {
+  pkgs,
+  flake-inputs,
   config,
   lib,
   ...
@@ -18,10 +20,12 @@ in
 
   services.matrix-conduit = {
     enable = true;
+    package = flake-inputs.conduwuit.packages.${pkgs.system}.default;
     settings.global = {
       address = "127.0.0.1";
       server_name = domain;
-      database_backend = "rocksdb";
+      new_user_displayname_suffix = "🦆";
+      allow_check_for_updates = true;
 
       # Set up delegation: https://docs.conduit.rs/delegation.html#automatic-recommended
       # This is primarily to make sliding sync work
@@ -44,11 +48,14 @@ in
     };
   };
 
-  # Pass in the TURN secret via EnvironmentFile, not supported by
-  # upstream module currently.
-  #
-  # See also https://gitlab.com/famedly/conduit/-/issues/314
-  systemd.services.conduit.serviceConfig.EnvironmentFile = config.sops.secrets."turn/env".path;
+  systemd.services.conduit.serviceConfig = {
+    ExecStart = lib.mkForce "${config.services.matrix-conduit.package}/bin/conduwuit";
+    # Pass in the TURN secret via EnvironmentFile, not supported by
+    # upstream module currently.
+    #
+    # See also https://gitlab.com/famedly/conduit/-/issues/314
+    EnvironmentFile = config.sops.secrets."turn/env".path;
+  };
 
   systemd.services.coturn.serviceConfig.SupplementaryGroups = [
     config.security.acme.certs."tlater.net".group
diff --git a/flake.lock b/flake.lock
index 37c3d5f..3f3fc39 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1,6 +1,86 @@
 {
   "nodes": {
+    "attic": {
+      "inputs": {
+        "crane": "crane",
+        "flake-compat": "flake-compat",
+        "flake-parts": "flake-parts",
+        "nix-github-actions": "nix-github-actions",
+        "nixpkgs": "nixpkgs",
+        "nixpkgs-stable": "nixpkgs-stable"
+      },
+      "locked": {
+        "lastModified": 1738524606,
+        "narHash": "sha256-hPYEJ4juK3ph7kbjbvv7PlU1D9pAkkhl+pwx8fZY53U=",
+        "owner": "zhaofengli",
+        "repo": "attic",
+        "rev": "ff8a897d1f4408ebbf4d45fa9049c06b3e1e3f4e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "zhaofengli",
+        "ref": "main",
+        "repo": "attic",
+        "type": "github"
+      }
+    },
     "cachix": {
+      "inputs": {
+        "devenv": "devenv",
+        "flake-compat": "flake-compat_2",
+        "git-hooks": "git-hooks",
+        "nixpkgs": "nixpkgs_4"
+      },
+      "locked": {
+        "lastModified": 1737621947,
+        "narHash": "sha256-8HFvG7fvIFbgtaYAY2628Tb89fA55nPm2jSiNs0/Cws=",
+        "owner": "cachix",
+        "repo": "cachix",
+        "rev": "f65a3cd5e339c223471e64c051434616e18cc4f5",
+        "type": "github"
+      },
+      "original": {
+        "owner": "cachix",
+        "ref": "master",
+        "repo": "cachix",
+        "type": "github"
+      }
+    },
+    "cachix_2": {
+      "inputs": {
+        "devenv": [
+          "conduwuit",
+          "cachix",
+          "devenv"
+        ],
+        "flake-compat": [
+          "conduwuit",
+          "cachix",
+          "devenv"
+        ],
+        "git-hooks": [
+          "conduwuit",
+          "cachix",
+          "devenv"
+        ],
+        "nixpkgs": "nixpkgs_2"
+      },
+      "locked": {
+        "lastModified": 1728672398,
+        "narHash": "sha256-KxuGSoVUFnQLB2ZcYODW7AVPAh9JqRlD5BrfsC/Q4qs=",
+        "owner": "cachix",
+        "repo": "cachix",
+        "rev": "aac51f698309fd0f381149214b7eee213c66ef0a",
+        "type": "github"
+      },
+      "original": {
+        "owner": "cachix",
+        "ref": "latest",
+        "repo": "cachix",
+        "type": "github"
+      }
+    },
+    "cachix_3": {
       "inputs": {
         "devenv": [
           "sonnenshift",
@@ -10,7 +90,7 @@
           "sonnenshift",
           "crate2nix"
         ],
-        "nixpkgs": "nixpkgs_3",
+        "nixpkgs": "nixpkgs_7",
         "pre-commit-hooks": [
           "sonnenshift",
           "crate2nix"
@@ -31,7 +111,7 @@
         "type": "github"
       }
     },
-    "cachix_2": {
+    "cachix_4": {
       "inputs": {
         "devenv": [
           "sonnenshift",
@@ -43,7 +123,7 @@
           "crate2nix",
           "crate2nix_stable"
         ],
-        "nixpkgs": "nixpkgs_4",
+        "nixpkgs": "nixpkgs_8",
         "pre-commit-hooks": [
           "sonnenshift",
           "crate2nix",
@@ -65,7 +145,7 @@
         "type": "github"
       }
     },
-    "cachix_3": {
+    "cachix_5": {
       "inputs": {
         "devenv": [
           "sonnenshift",
@@ -79,7 +159,7 @@
           "crate2nix_stable",
           "crate2nix_stable"
         ],
-        "nixpkgs": "nixpkgs_5",
+        "nixpkgs": "nixpkgs_9",
         "pre-commit-hooks": [
           "sonnenshift",
           "crate2nix",
@@ -102,13 +182,98 @@
         "type": "github"
       }
     },
+    "complement": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1741891349,
+        "narHash": "sha256-YvrzOWcX7DH1drp5SGa+E/fc7wN3hqFtPbqPjZpOu1Q=",
+        "owner": "girlbossceo",
+        "repo": "complement",
+        "rev": "e587b3df569cba411aeac7c20b6366d03c143745",
+        "type": "github"
+      },
+      "original": {
+        "owner": "girlbossceo",
+        "ref": "main",
+        "repo": "complement",
+        "type": "github"
+      }
+    },
+    "conduwuit": {
+      "inputs": {
+        "attic": "attic",
+        "cachix": "cachix",
+        "complement": "complement",
+        "crane": "crane_2",
+        "fenix": "fenix",
+        "flake-compat": "flake-compat_3",
+        "flake-utils": "flake-utils",
+        "liburing": "liburing",
+        "nix-filter": "nix-filter",
+        "nixpkgs": [
+          "nixpkgs"
+        ],
+        "rocksdb": "rocksdb"
+      },
+      "locked": {
+        "lastModified": 1743473828,
+        "narHash": "sha256-x/sfh6LCHGAz8rL23GHhH7dac1LtHBbRRJi1p8gOdtI=",
+        "owner": "girlbossceo",
+        "repo": "conduwuit",
+        "rev": "0f81c1e1ccdcb0c5c6d5a27e82f16eb37b1e61c8",
+        "type": "github"
+      },
+      "original": {
+        "owner": "girlbossceo",
+        "repo": "conduwuit",
+        "type": "github"
+      }
+    },
+    "crane": {
+      "inputs": {
+        "nixpkgs": [
+          "conduwuit",
+          "attic",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1722960479,
+        "narHash": "sha256-NhCkJJQhD5GUib8zN9JrmYGMwt4lCRp6ZVNzIiYCl0Y=",
+        "owner": "ipetkov",
+        "repo": "crane",
+        "rev": "4c6c77920b8d44cd6660c1621dea6b3fc4b4c4f4",
+        "type": "github"
+      },
+      "original": {
+        "owner": "ipetkov",
+        "repo": "crane",
+        "type": "github"
+      }
+    },
+    "crane_2": {
+      "locked": {
+        "lastModified": 1739936662,
+        "narHash": "sha256-x4syUjNUuRblR07nDPeLDP7DpphaBVbUaSoeZkFbGSk=",
+        "owner": "ipetkov",
+        "repo": "crane",
+        "rev": "19de14aaeb869287647d9461cbd389187d8ecdb7",
+        "type": "github"
+      },
+      "original": {
+        "owner": "ipetkov",
+        "ref": "master",
+        "repo": "crane",
+        "type": "github"
+      }
+    },
     "crate2nix": {
       "inputs": {
-        "cachix": "cachix",
+        "cachix": "cachix_3",
         "crate2nix_stable": "crate2nix_stable",
         "devshell": "devshell_3",
-        "flake-compat": "flake-compat_4",
-        "flake-parts": "flake-parts_3",
+        "flake-compat": "flake-compat_7",
+        "flake-parts": "flake-parts_5",
         "nix-test-runner": "nix-test-runner_3",
         "nixpkgs": [
           "sonnenshift",
@@ -132,13 +297,13 @@
     },
     "crate2nix_stable": {
       "inputs": {
-        "cachix": "cachix_2",
+        "cachix": "cachix_4",
         "crate2nix_stable": "crate2nix_stable_2",
         "devshell": "devshell_2",
-        "flake-compat": "flake-compat_3",
-        "flake-parts": "flake-parts_2",
+        "flake-compat": "flake-compat_6",
+        "flake-parts": "flake-parts_4",
         "nix-test-runner": "nix-test-runner_2",
-        "nixpkgs": "nixpkgs_7",
+        "nixpkgs": "nixpkgs_11",
         "pre-commit-hooks": "pre-commit-hooks_2"
       },
       "locked": {
@@ -158,13 +323,13 @@
     },
     "crate2nix_stable_2": {
       "inputs": {
-        "cachix": "cachix_3",
+        "cachix": "cachix_5",
         "crate2nix_stable": "crate2nix_stable_3",
         "devshell": "devshell",
-        "flake-compat": "flake-compat_2",
-        "flake-parts": "flake-parts",
+        "flake-compat": "flake-compat_5",
+        "flake-parts": "flake-parts_3",
         "nix-test-runner": "nix-test-runner",
-        "nixpkgs": "nixpkgs_6",
+        "nixpkgs": "nixpkgs_10",
         "pre-commit-hooks": "pre-commit-hooks"
       },
       "locked": {
@@ -184,7 +349,7 @@
     },
     "crate2nix_stable_3": {
       "inputs": {
-        "flake-utils": "flake-utils"
+        "flake-utils": "flake-utils_2"
       },
       "locked": {
         "lastModified": 1702842982,
@@ -203,8 +368,8 @@
     },
     "deploy-rs": {
       "inputs": {
-        "flake-compat": "flake-compat",
-        "nixpkgs": "nixpkgs",
+        "flake-compat": "flake-compat_4",
+        "nixpkgs": "nixpkgs_5",
         "utils": "utils"
       },
       "locked": {
@@ -221,9 +386,43 @@
         "type": "github"
       }
     },
+    "devenv": {
+      "inputs": {
+        "cachix": "cachix_2",
+        "flake-compat": [
+          "conduwuit",
+          "cachix",
+          "flake-compat"
+        ],
+        "git-hooks": [
+          "conduwuit",
+          "cachix",
+          "git-hooks"
+        ],
+        "nix": "nix",
+        "nixpkgs": [
+          "conduwuit",
+          "cachix",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1733323168,
+        "narHash": "sha256-d5DwB4MZvlaQpN6OQ4SLYxb5jA4UH5EtV5t5WOtjLPU=",
+        "owner": "cachix",
+        "repo": "devenv",
+        "rev": "efa9010b8b1cfd5dd3c7ed1e172a470c3b84a064",
+        "type": "github"
+      },
+      "original": {
+        "owner": "cachix",
+        "repo": "devenv",
+        "type": "github"
+      }
+    },
     "devshell": {
       "inputs": {
-        "flake-utils": "flake-utils_2",
+        "flake-utils": "flake-utils_3",
         "nixpkgs": [
           "sonnenshift",
           "crate2nix",
@@ -248,7 +447,7 @@
     },
     "devshell_2": {
       "inputs": {
-        "flake-utils": "flake-utils_3",
+        "flake-utils": "flake-utils_4",
         "nixpkgs": [
           "sonnenshift",
           "crate2nix",
@@ -272,7 +471,7 @@
     },
     "devshell_3": {
       "inputs": {
-        "flake-utils": "flake-utils_4",
+        "flake-utils": "flake-utils_5",
         "nixpkgs": [
           "sonnenshift",
           "crate2nix",
@@ -315,7 +514,7 @@
     },
     "dream2nix": {
       "inputs": {
-        "nixpkgs": "nixpkgs_8",
+        "nixpkgs": "nixpkgs_12",
         "purescript-overlay": "purescript-overlay",
         "pyproject-nix": "pyproject-nix"
       },
@@ -336,11 +535,34 @@
     "fenix": {
       "inputs": {
         "nixpkgs": [
-          "tlaternet-webserver",
+          "conduwuit",
           "nixpkgs"
         ],
         "rust-analyzer-src": "rust-analyzer-src"
       },
+      "locked": {
+        "lastModified": 1740724364,
+        "narHash": "sha256-D1jLIueJx1dPrP09ZZwTrPf4cubV+TsFMYbpYYTVj6A=",
+        "owner": "nix-community",
+        "repo": "fenix",
+        "rev": "edf7d9e431cda8782e729253835f178a356d3aab",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "ref": "main",
+        "repo": "fenix",
+        "type": "github"
+      }
+    },
+    "fenix_2": {
+      "inputs": {
+        "nixpkgs": [
+          "tlaternet-webserver",
+          "nixpkgs"
+        ],
+        "rust-analyzer-src": "rust-analyzer-src_2"
+      },
       "locked": {
         "lastModified": 1737181903,
         "narHash": "sha256-lvp77MhGzSN+ICd0MugppCjQR6cmlM2iAC5cjy2ZsaA=",
@@ -372,34 +594,55 @@
       }
     },
     "flake-compat_2": {
+      "flake": false,
       "locked": {
-        "lastModified": 1696426674,
-        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
-        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
-        "revCount": 57,
-        "type": "tarball",
-        "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
+        "lastModified": 1733328505,
+        "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
+        "type": "github"
       },
       "original": {
-        "type": "tarball",
-        "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "type": "github"
       }
     },
     "flake-compat_3": {
+      "flake": false,
       "locked": {
-        "lastModified": 1696426674,
-        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
-        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
-        "revCount": 57,
-        "type": "tarball",
-        "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
+        "lastModified": 1733328505,
+        "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
+        "type": "github"
       },
       "original": {
-        "type": "tarball",
-        "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
+        "owner": "edolstra",
+        "ref": "master",
+        "repo": "flake-compat",
+        "type": "github"
       }
     },
     "flake-compat_4": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1696426674,
+        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
+        "type": "github"
+      },
+      "original": {
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "type": "github"
+      }
+    },
+    "flake-compat_5": {
       "locked": {
         "lastModified": 1696426674,
         "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
@@ -413,7 +656,35 @@
         "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
       }
     },
-    "flake-compat_5": {
+    "flake-compat_6": {
+      "locked": {
+        "lastModified": 1696426674,
+        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
+        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
+        "revCount": 57,
+        "type": "tarball",
+        "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
+      },
+      "original": {
+        "type": "tarball",
+        "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
+      }
+    },
+    "flake-compat_7": {
+      "locked": {
+        "lastModified": 1696426674,
+        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
+        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
+        "revCount": 57,
+        "type": "tarball",
+        "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
+      },
+      "original": {
+        "type": "tarball",
+        "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
+      }
+    },
+    "flake-compat_8": {
       "flake": false,
       "locked": {
         "lastModified": 1696426674,
@@ -430,6 +701,52 @@
       }
     },
     "flake-parts": {
+      "inputs": {
+        "nixpkgs-lib": [
+          "conduwuit",
+          "attic",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1722555600,
+        "narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=",
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "rev": "8471fe90ad337a8074e957b69ca4d0089218391d",
+        "type": "github"
+      },
+      "original": {
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "type": "github"
+      }
+    },
+    "flake-parts_2": {
+      "inputs": {
+        "nixpkgs-lib": [
+          "conduwuit",
+          "cachix",
+          "devenv",
+          "nix",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1712014858,
+        "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
+        "type": "github"
+      },
+      "original": {
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "type": "github"
+      }
+    },
+    "flake-parts_3": {
       "inputs": {
         "nixpkgs-lib": [
           "sonnenshift",
@@ -453,7 +770,7 @@
         "type": "github"
       }
     },
-    "flake-parts_2": {
+    "flake-parts_4": {
       "inputs": {
         "nixpkgs-lib": [
           "sonnenshift",
@@ -476,7 +793,7 @@
         "type": "github"
       }
     },
-    "flake-parts_3": {
+    "flake-parts_5": {
       "inputs": {
         "nixpkgs-lib": [
           "sonnenshift",
@@ -500,18 +817,19 @@
     },
     "flake-utils": {
       "inputs": {
-        "systems": "systems_2"
+        "systems": "systems"
       },
       "locked": {
-        "lastModified": 1694529238,
-        "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
+        "lastModified": 1731533236,
+        "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
+        "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
         "type": "github"
       },
       "original": {
         "owner": "numtide",
+        "ref": "main",
         "repo": "flake-utils",
         "type": "github"
       }
@@ -521,11 +839,11 @@
         "systems": "systems_3"
       },
       "locked": {
-        "lastModified": 1701680307,
-        "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
+        "lastModified": 1694529238,
+        "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
+        "rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
         "type": "github"
       },
       "original": {
@@ -574,6 +892,24 @@
       "inputs": {
         "systems": "systems_6"
       },
+      "locked": {
+        "lastModified": 1701680307,
+        "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "flake-utils_6": {
+      "inputs": {
+        "systems": "systems_7"
+      },
       "locked": {
         "lastModified": 1710146030,
         "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
@@ -608,14 +944,41 @@
         "type": "github"
       }
     },
+    "git-hooks": {
+      "inputs": {
+        "flake-compat": [
+          "conduwuit",
+          "cachix",
+          "flake-compat"
+        ],
+        "gitignore": "gitignore",
+        "nixpkgs": [
+          "conduwuit",
+          "cachix",
+          "nixpkgs"
+        ],
+        "nixpkgs-stable": "nixpkgs-stable_2"
+      },
+      "locked": {
+        "lastModified": 1733318908,
+        "narHash": "sha256-SVQVsbafSM1dJ4fpgyBqLZ+Lft+jcQuMtEL3lQWx2Sk=",
+        "owner": "cachix",
+        "repo": "git-hooks.nix",
+        "rev": "6f4e2a2112050951a314d2733a994fbab94864c6",
+        "type": "github"
+      },
+      "original": {
+        "owner": "cachix",
+        "repo": "git-hooks.nix",
+        "type": "github"
+      }
+    },
     "gitignore": {
       "inputs": {
         "nixpkgs": [
-          "sonnenshift",
-          "crate2nix",
-          "crate2nix_stable",
-          "crate2nix_stable",
-          "pre-commit-hooks",
+          "conduwuit",
+          "cachix",
+          "git-hooks",
           "nixpkgs"
         ]
       },
@@ -639,6 +1002,7 @@
           "sonnenshift",
           "crate2nix",
           "crate2nix_stable",
+          "crate2nix_stable",
           "pre-commit-hooks",
           "nixpkgs"
         ]
@@ -662,6 +1026,7 @@
         "nixpkgs": [
           "sonnenshift",
           "crate2nix",
+          "crate2nix_stable",
           "pre-commit-hooks",
           "nixpkgs"
         ]
@@ -680,6 +1045,141 @@
         "type": "github"
       }
     },
+    "gitignore_4": {
+      "inputs": {
+        "nixpkgs": [
+          "sonnenshift",
+          "crate2nix",
+          "pre-commit-hooks",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1709087332,
+        "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
+        "owner": "hercules-ci",
+        "repo": "gitignore.nix",
+        "rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
+        "type": "github"
+      },
+      "original": {
+        "owner": "hercules-ci",
+        "repo": "gitignore.nix",
+        "type": "github"
+      }
+    },
+    "libgit2": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1697646580,
+        "narHash": "sha256-oX4Z3S9WtJlwvj0uH9HlYcWv+x1hqp8mhXl7HsLu2f0=",
+        "owner": "libgit2",
+        "repo": "libgit2",
+        "rev": "45fd9ed7ae1a9b74b957ef4f337bc3c8b3df01b5",
+        "type": "github"
+      },
+      "original": {
+        "owner": "libgit2",
+        "repo": "libgit2",
+        "type": "github"
+      }
+    },
+    "liburing": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1740613216,
+        "narHash": "sha256-NpPOBqNND3Qe9IwqYs0mJLGTmIx7e6FgUEBAnJ+1ZLA=",
+        "owner": "axboe",
+        "repo": "liburing",
+        "rev": "e1003e496e66f9b0ae06674869795edf772d5500",
+        "type": "github"
+      },
+      "original": {
+        "owner": "axboe",
+        "ref": "master",
+        "repo": "liburing",
+        "type": "github"
+      }
+    },
+    "nix": {
+      "inputs": {
+        "flake-compat": [
+          "conduwuit",
+          "cachix",
+          "devenv"
+        ],
+        "flake-parts": "flake-parts_2",
+        "libgit2": "libgit2",
+        "nixpkgs": "nixpkgs_3",
+        "nixpkgs-23-11": [
+          "conduwuit",
+          "cachix",
+          "devenv"
+        ],
+        "nixpkgs-regression": [
+          "conduwuit",
+          "cachix",
+          "devenv"
+        ],
+        "pre-commit-hooks": [
+          "conduwuit",
+          "cachix",
+          "devenv"
+        ]
+      },
+      "locked": {
+        "lastModified": 1727438425,
+        "narHash": "sha256-X8ES7I1cfNhR9oKp06F6ir4Np70WGZU5sfCOuNBEwMg=",
+        "owner": "domenkozar",
+        "repo": "nix",
+        "rev": "f6c5ae4c1b2e411e6b1e6a8181cc84363d6a7546",
+        "type": "github"
+      },
+      "original": {
+        "owner": "domenkozar",
+        "ref": "devenv-2.24",
+        "repo": "nix",
+        "type": "github"
+      }
+    },
+    "nix-filter": {
+      "locked": {
+        "lastModified": 1731533336,
+        "narHash": "sha256-oRam5PS1vcrr5UPgALW0eo1m/5/pls27Z/pabHNy2Ms=",
+        "owner": "numtide",
+        "repo": "nix-filter",
+        "rev": "f7653272fd234696ae94229839a99b73c9ab7de0",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "ref": "main",
+        "repo": "nix-filter",
+        "type": "github"
+      }
+    },
+    "nix-github-actions": {
+      "inputs": {
+        "nixpkgs": [
+          "conduwuit",
+          "attic",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1729742964,
+        "narHash": "sha256-B4mzTcQ0FZHdpeWcpDYPERtyjJd/NIuaQ9+BV1h+MpA=",
+        "owner": "nix-community",
+        "repo": "nix-github-actions",
+        "rev": "e04df33f62cdcf93d73e9a04142464753a16db67",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "repo": "nix-github-actions",
+        "type": "github"
+      }
+    },
     "nix-test-runner": {
       "flake": false,
       "locked": {
@@ -730,11 +1230,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1702272962,
-        "narHash": "sha256-D+zHwkwPc6oYQ4G3A1HuadopqRwUY/JkMwHz1YF7j4Q=",
+        "lastModified": 1726042813,
+        "narHash": "sha256-LnNKCCxnwgF+575y0pxUdlGZBO/ru1CtGHIqQVfvjlA=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "e97b3e4186bcadf0ef1b6be22b8558eab1cdeb5d",
+        "rev": "159be5db480d1df880a0135ca0bfed84c2f88353",
         "type": "github"
       },
       "original": {
@@ -744,6 +1244,38 @@
         "type": "github"
       }
     },
+    "nixpkgs-stable": {
+      "locked": {
+        "lastModified": 1724316499,
+        "narHash": "sha256-Qb9MhKBUTCfWg/wqqaxt89Xfi6qTD3XpTzQ9eXi3JmE=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "797f7dc49e0bc7fab4b57c021cdf68f595e47841",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixos-24.05",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs-stable_2": {
+      "locked": {
+        "lastModified": 1730741070,
+        "narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "d063c1dd113c91ab27959ba540c0d9753409edf3",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixos-24.05",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
     "nixpkgs-unstable": {
       "locked": {
         "lastModified": 1740215764,
@@ -760,71 +1292,7 @@
         "type": "github"
       }
     },
-    "nixpkgs_2": {
-      "locked": {
-        "lastModified": 1740162160,
-        "narHash": "sha256-SSYxFhqCOb3aiPb6MmN68yEzBIltfom8IgRz7phHscM=",
-        "owner": "nixos",
-        "repo": "nixpkgs",
-        "rev": "11415c7ae8539d6292f2928317ee7a8410b28bb9",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nixos",
-        "ref": "nixos-24.11-small",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
-    "nixpkgs_3": {
-      "locked": {
-        "lastModified": 1700612854,
-        "narHash": "sha256-yrQ8osMD+vDLGFX7pcwsY/Qr5PUd6OmDMYJZzZi0+zc=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "19cbff58383a4ae384dea4d1d0c823d72b49d614",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "nixos-unstable",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
-    "nixpkgs_4": {
-      "locked": {
-        "lastModified": 1715534503,
-        "narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "2057814051972fa1453ddfb0d98badbea9b83c06",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "nixos-unstable",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
-    "nixpkgs_5": {
-      "locked": {
-        "lastModified": 1715534503,
-        "narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "2057814051972fa1453ddfb0d98badbea9b83c06",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "nixos-unstable",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
-    "nixpkgs_6": {
+    "nixpkgs_10": {
       "locked": {
         "lastModified": 1719506693,
         "narHash": "sha256-C8e9S7RzshSdHB7L+v9I51af1gDM5unhJ2xO1ywxNH8=",
@@ -837,7 +1305,7 @@
         "type": "indirect"
       }
     },
-    "nixpkgs_7": {
+    "nixpkgs_11": {
       "locked": {
         "lastModified": 1719506693,
         "narHash": "sha256-C8e9S7RzshSdHB7L+v9I51af1gDM5unhJ2xO1ywxNH8=",
@@ -850,7 +1318,7 @@
         "type": "indirect"
       }
     },
-    "nixpkgs_8": {
+    "nixpkgs_12": {
       "locked": {
         "lastModified": 1729850857,
         "narHash": "sha256-WvLXzNNnnw+qpFOmgaM3JUlNEH+T4s22b5i2oyyCpXE=",
@@ -866,6 +1334,134 @@
         "type": "github"
       }
     },
+    "nixpkgs_2": {
+      "locked": {
+        "lastModified": 1730531603,
+        "narHash": "sha256-Dqg6si5CqIzm87sp57j5nTaeBbWhHFaVyG7V6L8k3lY=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "7ffd9ae656aec493492b44d0ddfb28e79a1ea25d",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixos-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs_3": {
+      "locked": {
+        "lastModified": 1717432640,
+        "narHash": "sha256-+f9c4/ZX5MWDOuB1rKoWj+lBNm0z0rs4CK47HBLxy1o=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "88269ab3044128b7c2f4c7d68448b2fb50456870",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "release-24.05",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs_4": {
+      "locked": {
+        "lastModified": 1733212471,
+        "narHash": "sha256-M1+uCoV5igihRfcUKrr1riygbe73/dzNnzPsmaLCmpo=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "55d15ad12a74eb7d4646254e13638ad0c4128776",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixos-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs_5": {
+      "locked": {
+        "lastModified": 1702272962,
+        "narHash": "sha256-D+zHwkwPc6oYQ4G3A1HuadopqRwUY/JkMwHz1YF7j4Q=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "e97b3e4186bcadf0ef1b6be22b8558eab1cdeb5d",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixpkgs-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs_6": {
+      "locked": {
+        "lastModified": 1740162160,
+        "narHash": "sha256-SSYxFhqCOb3aiPb6MmN68yEzBIltfom8IgRz7phHscM=",
+        "owner": "nixos",
+        "repo": "nixpkgs",
+        "rev": "11415c7ae8539d6292f2928317ee7a8410b28bb9",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nixos",
+        "ref": "nixos-24.11-small",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs_7": {
+      "locked": {
+        "lastModified": 1700612854,
+        "narHash": "sha256-yrQ8osMD+vDLGFX7pcwsY/Qr5PUd6OmDMYJZzZi0+zc=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "19cbff58383a4ae384dea4d1d0c823d72b49d614",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixos-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs_8": {
+      "locked": {
+        "lastModified": 1715534503,
+        "narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "2057814051972fa1453ddfb0d98badbea9b83c06",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixos-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs_9": {
+      "locked": {
+        "lastModified": 1715534503,
+        "narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "2057814051972fa1453ddfb0d98badbea9b83c06",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixos-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
     "pre-commit-hooks": {
       "inputs": {
         "flake-compat": [
@@ -875,7 +1471,7 @@
           "crate2nix_stable",
           "flake-compat"
         ],
-        "gitignore": "gitignore",
+        "gitignore": "gitignore_2",
         "nixpkgs": [
           "sonnenshift",
           "crate2nix",
@@ -913,7 +1509,7 @@
           "crate2nix_stable",
           "flake-compat"
         ],
-        "gitignore": "gitignore_2",
+        "gitignore": "gitignore_3",
         "nixpkgs": [
           "sonnenshift",
           "crate2nix",
@@ -948,8 +1544,8 @@
           "crate2nix",
           "flake-compat"
         ],
-        "flake-utils": "flake-utils_5",
-        "gitignore": "gitignore_3",
+        "flake-utils": "flake-utils_6",
+        "gitignore": "gitignore_4",
         "nixpkgs": [
           "sonnenshift",
           "crate2nix",
@@ -977,7 +1573,7 @@
     },
     "purescript-overlay": {
       "inputs": {
-        "flake-compat": "flake-compat_5",
+        "flake-compat": "flake-compat_8",
         "nixpkgs": [
           "tlaternet-webserver",
           "dream2nix",
@@ -1016,12 +1612,30 @@
         "type": "github"
       }
     },
+    "rocksdb": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1741308171,
+        "narHash": "sha256-YdBvdQ75UJg5ffwNjxizpviCVwVDJnBkM8ZtGIduMgY=",
+        "owner": "girlbossceo",
+        "repo": "rocksdb",
+        "rev": "3ce04794bcfbbb0d2e6f81ae35fc4acf688b6986",
+        "type": "github"
+      },
+      "original": {
+        "owner": "girlbossceo",
+        "ref": "v9.11.1",
+        "repo": "rocksdb",
+        "type": "github"
+      }
+    },
     "root": {
       "inputs": {
+        "conduwuit": "conduwuit",
         "deploy-rs": "deploy-rs",
         "disko": "disko",
         "foundryvtt": "foundryvtt",
-        "nixpkgs": "nixpkgs_2",
+        "nixpkgs": "nixpkgs_6",
         "nixpkgs-unstable": "nixpkgs-unstable",
         "sonnenshift": "sonnenshift",
         "sops-nix": "sops-nix",
@@ -1029,6 +1643,23 @@
       }
     },
     "rust-analyzer-src": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1740691488,
+        "narHash": "sha256-Fs6vBrByuiOf2WO77qeMDMTXcTGzrIMqLBv+lNeywwM=",
+        "owner": "rust-lang",
+        "repo": "rust-analyzer",
+        "rev": "fe3eda77d3a7ce212388bda7b6cec8bffcc077e5",
+        "type": "github"
+      },
+      "original": {
+        "owner": "rust-lang",
+        "ref": "nightly",
+        "repo": "rust-analyzer",
+        "type": "github"
+      }
+    },
+    "rust-analyzer-src_2": {
       "flake": false,
       "locked": {
         "lastModified": 1737140097,
@@ -1199,10 +1830,25 @@
         "type": "github"
       }
     },
+    "systems_7": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    },
     "tlaternet-webserver": {
       "inputs": {
         "dream2nix": "dream2nix",
-        "fenix": "fenix",
+        "fenix": "fenix_2",
         "nixpkgs": [
           "nixpkgs"
         ]
@@ -1223,7 +1869,7 @@
     },
     "utils": {
       "inputs": {
-        "systems": "systems"
+        "systems": "systems_2"
       },
       "locked": {
         "lastModified": 1701680307,
diff --git a/flake.nix b/flake.nix
index b31d108..4f17def 100644
--- a/flake.nix
+++ b/flake.nix
@@ -4,6 +4,10 @@
   inputs = {
     nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11-small";
     nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable-small";
+    conduwuit = {
+      url = "github:girlbossceo/conduwuit";
+      inputs.nixpkgs.follows = "nixpkgs";
+    };
     disko = {
       url = "github:nix-community/disko";
       inputs.nixpkgs.follows = "nixpkgs";

From ee760bfa1ba04d642b38ad589495016ccb6622ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 4 Apr 2025 21:07:15 +0800
Subject: [PATCH 197/212] feat(victoriametrics): Add missing scrape configs

---
 configuration/services/conduit/matrix-hookshot.nix | 2 +-
 configuration/services/metrics/victoriametrics.nix | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/configuration/services/conduit/matrix-hookshot.nix b/configuration/services/conduit/matrix-hookshot.nix
index 6f11728..c1f16dc 100644
--- a/configuration/services/conduit/matrix-hookshot.nix
+++ b/configuration/services/conduit/matrix-hookshot.nix
@@ -138,7 +138,7 @@ in
         }
       ];
 
-      metrics.enable = true;
+      metrics.enabled = true;
     };
   };
 }
diff --git a/configuration/services/metrics/victoriametrics.nix b/configuration/services/metrics/victoriametrics.nix
index 4a78d46..53864d6 100644
--- a/configuration/services/metrics/victoriametrics.nix
+++ b/configuration/services/metrics/victoriametrics.nix
@@ -87,6 +87,8 @@ in
       # Configured in the hookshot listeners, but it's hard to filter
       # the correct values out of that config.
       matrixHookshot.targets = [ "127.0.0.1:9001" ];
+
+      victorialogs.targets = [ config.services.victorialogs.bindAddress ];
     };
   };
 }

From b396835f88cb8760a777e869b155418f51da0e74 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 4 Apr 2025 21:17:00 +0800
Subject: [PATCH 198/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'conduwuit':
    'github:girlbossceo/conduwuit/0f81c1e1ccdcb0c5c6d5a27e82f16eb37b1e61c8' (2025-04-01)
  → 'github:girlbossceo/conduwuit/00f7745ec4ebcea5f892376c5de5db1299f71696' (2025-04-04)
• Updated input 'disko':
    'github:nix-community/disko/15dbf8cebd8e2655a883b74547108e089f051bf0' (2025-02-18)
  → 'github:nix-community/disko/329d3d7e8bc63dd30c39e14e6076db590a6eabe6' (2025-04-02)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/11415c7ae8539d6292f2928317ee7a8410b28bb9' (2025-02-21)
  → 'github:nixos/nixpkgs/bdb91860de2f719b57eef819b5617762f7120c70' (2025-04-03)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/8465e233b0668cf162c608a92e62e8d78c1ba7e4' (2025-02-22)
  → 'github:nixos/nixpkgs/a462b946265ed006720d02153882780b12a8376d' (2025-04-04)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/07af005bb7d60c7f118d9d9f5530485da5d1e975' (2025-02-11)
  → 'github:Mic92/sops-nix/cff8437c5fe8c68fc3a840a21bf1f4dc801da40d' (2025-04-04)
---
 flake.lock | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/flake.lock b/flake.lock
index 3f3fc39..83911d7 100644
--- a/flake.lock
+++ b/flake.lock
@@ -216,11 +216,11 @@
         "rocksdb": "rocksdb"
       },
       "locked": {
-        "lastModified": 1743473828,
-        "narHash": "sha256-x/sfh6LCHGAz8rL23GHhH7dac1LtHBbRRJi1p8gOdtI=",
+        "lastModified": 1743735594,
+        "narHash": "sha256-aaP8OjY4fkpxk2JdSggx9S3Rk+P+VhuivT6aRpLxoj0=",
         "owner": "girlbossceo",
         "repo": "conduwuit",
-        "rev": "0f81c1e1ccdcb0c5c6d5a27e82f16eb37b1e61c8",
+        "rev": "00f7745ec4ebcea5f892376c5de5db1299f71696",
         "type": "github"
       },
       "original": {
@@ -499,11 +499,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1739841949,
-        "narHash": "sha256-lSOXdgW/1zi/SSu7xp71v+55D5Egz8ACv0STkj7fhbs=",
+        "lastModified": 1743598667,
+        "narHash": "sha256-ViE7NoFWytYO2uJONTAX35eGsvTYXNHjWALeHAg8OQY=",
         "owner": "nix-community",
         "repo": "disko",
-        "rev": "15dbf8cebd8e2655a883b74547108e089f051bf0",
+        "rev": "329d3d7e8bc63dd30c39e14e6076db590a6eabe6",
         "type": "github"
       },
       "original": {
@@ -1278,11 +1278,11 @@
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1740215764,
-        "narHash": "sha256-wzBbGGZ6i1VVBA/cDJaLfuuGYCUriD7fwsLgJJHRVRk=",
+        "lastModified": 1743732435,
+        "narHash": "sha256-RrWgOj3F1N6kDG0xatvZzP0p1Zq00yhcTMlaj4bWi5E=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "8465e233b0668cf162c608a92e62e8d78c1ba7e4",
+        "rev": "a462b946265ed006720d02153882780b12a8376d",
         "type": "github"
       },
       "original": {
@@ -1400,11 +1400,11 @@
     },
     "nixpkgs_6": {
       "locked": {
-        "lastModified": 1740162160,
-        "narHash": "sha256-SSYxFhqCOb3aiPb6MmN68yEzBIltfom8IgRz7phHscM=",
+        "lastModified": 1743703532,
+        "narHash": "sha256-s1KLDALEeqy+ttrvqV3jx9mBZEvmthQErTVOAzbjHZs=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "11415c7ae8539d6292f2928317ee7a8410b28bb9",
+        "rev": "bdb91860de2f719b57eef819b5617762f7120c70",
         "type": "github"
       },
       "original": {
@@ -1727,11 +1727,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1739262228,
-        "narHash": "sha256-7JAGezJ0Dn5qIyA2+T4Dt/xQgAbhCglh6lzCekTVMeU=",
+        "lastModified": 1743756170,
+        "narHash": "sha256-2b11EYa08oqDmF3zEBLkG1AoNn9rB1k39ew/T/mSvbU=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "07af005bb7d60c7f118d9d9f5530485da5d1e975",
+        "rev": "cff8437c5fe8c68fc3a840a21bf1f4dc801da40d",
         "type": "github"
       },
       "original": {

From e37c589654c67863d32ad63ed1643b4a08f99188 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 4 Apr 2025 21:21:03 +0800
Subject: [PATCH 199/212] bump(crowdsec-hub): Update hub

---
 pkgs/crowdsec/_sources/generated.json | 8 ++++----
 pkgs/crowdsec/_sources/generated.nix  | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/pkgs/crowdsec/_sources/generated.json b/pkgs/crowdsec/_sources/generated.json
index ac251aa..97c4e87 100644
--- a/pkgs/crowdsec/_sources/generated.json
+++ b/pkgs/crowdsec/_sources/generated.json
@@ -21,7 +21,7 @@
     },
     "crowdsec-hub": {
         "cargoLocks": null,
-        "date": "2025-02-22",
+        "date": "2025-04-04",
         "extract": null,
         "name": "crowdsec-hub",
         "passthru": null,
@@ -33,10 +33,10 @@
             "name": null,
             "owner": "crowdsecurity",
             "repo": "hub",
-            "rev": "f9883cd6c7d1913c13e4a3a69d9a0b887a7d57df",
-            "sha256": "sha256-45pUln7Qj5luY9I9BE2qhzjH7kv4IbYvNoEX3/4AVVg=",
+            "rev": "eebc5f71379ea8f4de4a26f6695e0340444c719c",
+            "sha256": "sha256-/jhsqumekdOHDbHjBP8KvAICsSNhCg5ejMT3jSRiROo=",
             "type": "github"
         },
-        "version": "f9883cd6c7d1913c13e4a3a69d9a0b887a7d57df"
+        "version": "eebc5f71379ea8f4de4a26f6695e0340444c719c"
     }
 }
\ No newline at end of file
diff --git a/pkgs/crowdsec/_sources/generated.nix b/pkgs/crowdsec/_sources/generated.nix
index 9c63cc5..aca88b2 100644
--- a/pkgs/crowdsec/_sources/generated.nix
+++ b/pkgs/crowdsec/_sources/generated.nix
@@ -14,14 +14,14 @@
   };
   crowdsec-hub = {
     pname = "crowdsec-hub";
-    version = "f9883cd6c7d1913c13e4a3a69d9a0b887a7d57df";
+    version = "eebc5f71379ea8f4de4a26f6695e0340444c719c";
     src = fetchFromGitHub {
       owner = "crowdsecurity";
       repo = "hub";
-      rev = "f9883cd6c7d1913c13e4a3a69d9a0b887a7d57df";
+      rev = "eebc5f71379ea8f4de4a26f6695e0340444c719c";
       fetchSubmodules = false;
-      sha256 = "sha256-45pUln7Qj5luY9I9BE2qhzjH7kv4IbYvNoEX3/4AVVg=";
+      sha256 = "sha256-/jhsqumekdOHDbHjBP8KvAICsSNhCg5ejMT3jSRiROo=";
     };
-    date = "2025-02-22";
+    date = "2025-04-04";
   };
 }

From 89f9196ef0405d2b82a8330a4e00f45c5a8b7e28 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 4 Apr 2025 21:35:24 +0800
Subject: [PATCH 200/212] fix(victorialogs): Use new upstream module

---
 .../services/metrics/victorialogs.nix         | 100 +++---------------
 1 file changed, 12 insertions(+), 88 deletions(-)

diff --git a/configuration/services/metrics/victorialogs.nix b/configuration/services/metrics/victorialogs.nix
index ed74c59..ae47c39 100644
--- a/configuration/services/metrics/victorialogs.nix
+++ b/configuration/services/metrics/victorialogs.nix
@@ -1,37 +1,26 @@
 {
   config,
-  pkgs,
   lib,
   ...
 }:
 let
   cfg = config.services.victorialogs;
-  pkg = pkgs.victoriametrics;
-  dirname = "victorialogs";
 in
 {
-  options.services.victorialogs =
-    let
-      inherit (lib.types) str;
-    in
-    {
-      listenAddress = lib.mkOption {
-        default = ":9428";
-        type = str;
-      };
-
-      bindAddress = lib.mkOption {
-        readOnly = true;
-        type = str;
-        description = ''
-          Final address on which victorialogs listens.
-        '';
-      };
-    };
+  options.services.victorialogs.bindAddress = lib.mkOption {
+    readOnly = true;
+    type = lib.types.str;
+    description = ''
+      Final address on which victorialogs listens.
+    '';
+  };
 
   config = {
-    services.victorialogs.bindAddress =
-      (lib.optionalString (lib.hasPrefix ":" cfg.listenAddress) "127.0.0.1") + cfg.listenAddress;
+    services.victorialogs = {
+      enable = true;
+      bindAddress =
+        (lib.optionalString (lib.hasPrefix ":" cfg.listenAddress) "127.0.0.1") + cfg.listenAddress;
+    };
 
     services.journald.upload = {
       enable = true;
@@ -40,71 +29,6 @@ in
         NetworkTimeoutSec = "20s";
       };
     };
-
     systemd.services."systemd-journal-upload".after = [ "victorialogs.service" ];
-
-    systemd.services.victorialogs = {
-      description = "VictoriaLogs log database";
-      wantedBy = [ "multi-user.target" ];
-      after = [ "network.target" ];
-      startLimitBurst = 5;
-
-      serviceConfig = {
-        ExecStart = lib.escapeShellArgs [
-          "${pkg}/bin/victoria-logs"
-          "-storageDataPath=/var/lib/${dirname}"
-          "-httpListenAddr=${cfg.listenAddress}"
-        ];
-
-        DynamicUser = true;
-        RestartSec = 1;
-        Restart = "on-failure";
-        RuntimeDirectory = dirname;
-        RuntimeDirectoryMode = "0700";
-        StateDirectory = dirname;
-        StateDirectoryMode = "0700";
-
-        LimitNOFILE = 1048576;
-
-        # Hardening
-        DeviceAllow = [ "/dev/null rw" ];
-        DevicePolicy = "strict";
-        LockPersonality = true;
-        MemoryDenyWriteExecute = true;
-        NoNewPrivileges = true;
-        PrivateDevices = true;
-        PrivateTmp = true;
-        PrivateUsers = true;
-        ProtectClock = true;
-        ProtectControlGroups = true;
-        ProtectHome = true;
-        ProtectHostname = true;
-        ProtectKernelLogs = true;
-        ProtectKernelModules = true;
-        ProtectKernelTunables = true;
-        ProtectProc = "invisible";
-        ProtectSystem = "full";
-        RemoveIPC = true;
-        RestrictAddressFamilies = [
-          "AF_INET"
-          "AF_INET6"
-          "AF_UNIX"
-        ];
-        RestrictNamespaces = true;
-        RestrictRealtime = true;
-        RestrictSUIDSGID = true;
-        SystemCallArchitectures = "native";
-        SystemCallFilter = [
-          "@system-service"
-          "~@privileged"
-        ];
-      };
-
-      postStart = lib.mkBefore ''
-        until ${lib.getBin pkgs.curl}/bin/curl -s -o /dev/null http://${cfg.bindAddress}/ping; do
-          sleep 1;
-        done
-      '';
-    };
   };
 }

From cfbc2999d75e53afe0e8e9bfed53f97086144394 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 17 May 2025 14:48:39 +0800
Subject: [PATCH 201/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'conduwuit':
    'github:girlbossceo/conduwuit/00f7745ec4ebcea5f892376c5de5db1299f71696' (2025-04-04)
  → 'github:girlbossceo/conduwuit/d8311a5ff672fdc4729d956af5e3af8646b0670d' (2025-04-09)
• Updated input 'disko':
    'github:nix-community/disko/329d3d7e8bc63dd30c39e14e6076db590a6eabe6' (2025-04-02)
  → 'github:nix-community/disko/ec7c109a4f794fce09aad87239eab7f66540b888' (2025-05-15)
• Updated input 'foundryvtt':
    'github:reckenrode/nix-foundryvtt/a7fa493ba2c623cf90e83756b62285b3b58f18d2' (2025-02-16)
  → 'github:reckenrode/nix-foundryvtt/f1b401831d796dd94cf5a11b65fd169a199d4ff0' (2025-05-10)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/bdb91860de2f719b57eef819b5617762f7120c70' (2025-04-03)
  → 'github:nixos/nixpkgs/d6c9326e40bb557ebb8c040b4375590bc06413f8' (2025-05-16)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/a462b946265ed006720d02153882780b12a8376d' (2025-04-04)
  → 'github:nixos/nixpkgs/b965e4c283060415956ccd39eee4ca34a6a56cf8' (2025-05-16)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/cff8437c5fe8c68fc3a840a21bf1f4dc801da40d' (2025-04-04)
  → 'github:Mic92/sops-nix/e93ee1d900ad264d65e9701a5c6f895683433386' (2025-05-05)
---
 flake.lock | 36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/flake.lock b/flake.lock
index 83911d7..80f2bc5 100644
--- a/flake.lock
+++ b/flake.lock
@@ -216,11 +216,11 @@
         "rocksdb": "rocksdb"
       },
       "locked": {
-        "lastModified": 1743735594,
-        "narHash": "sha256-aaP8OjY4fkpxk2JdSggx9S3Rk+P+VhuivT6aRpLxoj0=",
+        "lastModified": 1744169934,
+        "narHash": "sha256-5YyHmPUUrXXrczWayji9327knihVTKnmjX+vX6+p6d0=",
         "owner": "girlbossceo",
         "repo": "conduwuit",
-        "rev": "00f7745ec4ebcea5f892376c5de5db1299f71696",
+        "rev": "d8311a5ff672fdc4729d956af5e3af8646b0670d",
         "type": "github"
       },
       "original": {
@@ -499,11 +499,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1743598667,
-        "narHash": "sha256-ViE7NoFWytYO2uJONTAX35eGsvTYXNHjWALeHAg8OQY=",
+        "lastModified": 1747274630,
+        "narHash": "sha256-87RJwXbfOHyzTB9LYagAQ6vOZhszCvd8Gvudu+gf3qo=",
         "owner": "nix-community",
         "repo": "disko",
-        "rev": "329d3d7e8bc63dd30c39e14e6076db590a6eabe6",
+        "rev": "ec7c109a4f794fce09aad87239eab7f66540b888",
         "type": "github"
       },
       "original": {
@@ -931,11 +931,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1739712626,
-        "narHash": "sha256-u3m+awbdL+0BKk8IWidsWMr+R0ian3GZMUlH7623kd8=",
+        "lastModified": 1746877938,
+        "narHash": "sha256-N9J96pSPg4vbozV+ZZ++dwLnMIf2Le6ONNMO0kZCj1M=",
         "owner": "reckenrode",
         "repo": "nix-foundryvtt",
-        "rev": "a7fa493ba2c623cf90e83756b62285b3b58f18d2",
+        "rev": "f1b401831d796dd94cf5a11b65fd169a199d4ff0",
         "type": "github"
       },
       "original": {
@@ -1278,11 +1278,11 @@
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1743732435,
-        "narHash": "sha256-RrWgOj3F1N6kDG0xatvZzP0p1Zq00yhcTMlaj4bWi5E=",
+        "lastModified": 1747413287,
+        "narHash": "sha256-hOnqJr0tZBERWa29JWf9B3/8qr82mlt/UlKPvS7iYzA=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "a462b946265ed006720d02153882780b12a8376d",
+        "rev": "b965e4c283060415956ccd39eee4ca34a6a56cf8",
         "type": "github"
       },
       "original": {
@@ -1400,11 +1400,11 @@
     },
     "nixpkgs_6": {
       "locked": {
-        "lastModified": 1743703532,
-        "narHash": "sha256-s1KLDALEeqy+ttrvqV3jx9mBZEvmthQErTVOAzbjHZs=",
+        "lastModified": 1747418223,
+        "narHash": "sha256-DkCYFm09AR2+FPKcT7lD8iIMNXqTdesVvwKpCnqKiYg=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "bdb91860de2f719b57eef819b5617762f7120c70",
+        "rev": "d6c9326e40bb557ebb8c040b4375590bc06413f8",
         "type": "github"
       },
       "original": {
@@ -1727,11 +1727,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1743756170,
-        "narHash": "sha256-2b11EYa08oqDmF3zEBLkG1AoNn9rB1k39ew/T/mSvbU=",
+        "lastModified": 1746485181,
+        "narHash": "sha256-PxrrSFLaC7YuItShxmYbMgSuFFuwxBB+qsl9BZUnRvg=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "cff8437c5fe8c68fc3a840a21bf1f4dc801da40d",
+        "rev": "e93ee1d900ad264d65e9701a5c6f895683433386",
         "type": "github"
       },
       "original": {

From 1bef207356fce8770249aad33bc13ed16594ea19 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 17 May 2025 15:46:03 +0800
Subject: [PATCH 202/212] bump(crowdsec-up): Update hub

---
 pkgs/crowdsec/_sources/generated.json | 8 ++++----
 pkgs/crowdsec/_sources/generated.nix  | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/pkgs/crowdsec/_sources/generated.json b/pkgs/crowdsec/_sources/generated.json
index 97c4e87..f3c8f01 100644
--- a/pkgs/crowdsec/_sources/generated.json
+++ b/pkgs/crowdsec/_sources/generated.json
@@ -21,7 +21,7 @@
     },
     "crowdsec-hub": {
         "cargoLocks": null,
-        "date": "2025-04-04",
+        "date": "2025-05-17",
         "extract": null,
         "name": "crowdsec-hub",
         "passthru": null,
@@ -33,10 +33,10 @@
             "name": null,
             "owner": "crowdsecurity",
             "repo": "hub",
-            "rev": "eebc5f71379ea8f4de4a26f6695e0340444c719c",
-            "sha256": "sha256-/jhsqumekdOHDbHjBP8KvAICsSNhCg5ejMT3jSRiROo=",
+            "rev": "850614b9fcd4298f559b422c5ac685a69aa2e5ff",
+            "sha256": "sha256-96MMwFN5KongQA3YJVSuk7Kanbr1gR94CCyiflmez2k=",
             "type": "github"
         },
-        "version": "eebc5f71379ea8f4de4a26f6695e0340444c719c"
+        "version": "850614b9fcd4298f559b422c5ac685a69aa2e5ff"
     }
 }
\ No newline at end of file
diff --git a/pkgs/crowdsec/_sources/generated.nix b/pkgs/crowdsec/_sources/generated.nix
index aca88b2..19a7f5a 100644
--- a/pkgs/crowdsec/_sources/generated.nix
+++ b/pkgs/crowdsec/_sources/generated.nix
@@ -14,14 +14,14 @@
   };
   crowdsec-hub = {
     pname = "crowdsec-hub";
-    version = "eebc5f71379ea8f4de4a26f6695e0340444c719c";
+    version = "850614b9fcd4298f559b422c5ac685a69aa2e5ff";
     src = fetchFromGitHub {
       owner = "crowdsecurity";
       repo = "hub";
-      rev = "eebc5f71379ea8f4de4a26f6695e0340444c719c";
+      rev = "850614b9fcd4298f559b422c5ac685a69aa2e5ff";
       fetchSubmodules = false;
-      sha256 = "sha256-/jhsqumekdOHDbHjBP8KvAICsSNhCg5ejMT3jSRiROo=";
+      sha256 = "sha256-96MMwFN5KongQA3YJVSuk7Kanbr1gR94CCyiflmez2k=";
     };
-    date = "2025-04-04";
+    date = "2025-05-17";
   };
 }

From 09b90433e6d448b84540d8a1341dc2b089bbcd21 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 17 May 2025 15:46:26 +0800
Subject: [PATCH 203/212] feat(conduit): Switch from conduwuit to continuwuity

---
 configuration/services/conduit/default.nix |  2 +-
 flake.lock                                 | 59 +++++++++++-----------
 flake.nix                                  |  4 +-
 3 files changed, 33 insertions(+), 32 deletions(-)

diff --git a/configuration/services/conduit/default.nix b/configuration/services/conduit/default.nix
index 5a2b8ac..94d401a 100644
--- a/configuration/services/conduit/default.nix
+++ b/configuration/services/conduit/default.nix
@@ -20,7 +20,7 @@ in
 
   services.matrix-conduit = {
     enable = true;
-    package = flake-inputs.conduwuit.packages.${pkgs.system}.default;
+    package = flake-inputs.continuwuity.packages.${pkgs.system}.default;
     settings.global = {
       address = "127.0.0.1";
       server_name = domain;
diff --git a/flake.lock b/flake.lock
index 80f2bc5..c17c613 100644
--- a/flake.lock
+++ b/flake.lock
@@ -49,17 +49,17 @@
     "cachix_2": {
       "inputs": {
         "devenv": [
-          "conduwuit",
+          "continuwuity",
           "cachix",
           "devenv"
         ],
         "flake-compat": [
-          "conduwuit",
+          "continuwuity",
           "cachix",
           "devenv"
         ],
         "git-hooks": [
-          "conduwuit",
+          "continuwuity",
           "cachix",
           "devenv"
         ],
@@ -199,7 +199,7 @@
         "type": "github"
       }
     },
-    "conduwuit": {
+    "continuwuity": {
       "inputs": {
         "attic": "attic",
         "cachix": "cachix",
@@ -216,23 +216,24 @@
         "rocksdb": "rocksdb"
       },
       "locked": {
-        "lastModified": 1744169934,
-        "narHash": "sha256-5YyHmPUUrXXrczWayji9327knihVTKnmjX+vX6+p6d0=",
-        "owner": "girlbossceo",
-        "repo": "conduwuit",
-        "rev": "d8311a5ff672fdc4729d956af5e3af8646b0670d",
-        "type": "github"
+        "lastModified": 1745186840,
+        "narHash": "sha256-Oq2scBu3Ewao828BT1QGffqIqF5WoH9HMXEXKg1YU0o=",
+        "ref": "refs/tags/v0.5.0-rc.5",
+        "rev": "0a0f327ae034f5c44b12a3154cc1143aff10291c",
+        "revCount": 5147,
+        "type": "git",
+        "url": "https://forgejo.ellis.link/continuwuation/continuwuity.git"
       },
       "original": {
-        "owner": "girlbossceo",
-        "repo": "conduwuit",
-        "type": "github"
+        "ref": "refs/tags/v0.5.0-rc.5",
+        "type": "git",
+        "url": "https://forgejo.ellis.link/continuwuation/continuwuity.git"
       }
     },
     "crane": {
       "inputs": {
         "nixpkgs": [
-          "conduwuit",
+          "continuwuity",
           "attic",
           "nixpkgs"
         ]
@@ -390,18 +391,18 @@
       "inputs": {
         "cachix": "cachix_2",
         "flake-compat": [
-          "conduwuit",
+          "continuwuity",
           "cachix",
           "flake-compat"
         ],
         "git-hooks": [
-          "conduwuit",
+          "continuwuity",
           "cachix",
           "git-hooks"
         ],
         "nix": "nix",
         "nixpkgs": [
-          "conduwuit",
+          "continuwuity",
           "cachix",
           "nixpkgs"
         ]
@@ -535,7 +536,7 @@
     "fenix": {
       "inputs": {
         "nixpkgs": [
-          "conduwuit",
+          "continuwuity",
           "nixpkgs"
         ],
         "rust-analyzer-src": "rust-analyzer-src"
@@ -703,7 +704,7 @@
     "flake-parts": {
       "inputs": {
         "nixpkgs-lib": [
-          "conduwuit",
+          "continuwuity",
           "attic",
           "nixpkgs"
         ]
@@ -725,7 +726,7 @@
     "flake-parts_2": {
       "inputs": {
         "nixpkgs-lib": [
-          "conduwuit",
+          "continuwuity",
           "cachix",
           "devenv",
           "nix",
@@ -947,13 +948,13 @@
     "git-hooks": {
       "inputs": {
         "flake-compat": [
-          "conduwuit",
+          "continuwuity",
           "cachix",
           "flake-compat"
         ],
         "gitignore": "gitignore",
         "nixpkgs": [
-          "conduwuit",
+          "continuwuity",
           "cachix",
           "nixpkgs"
         ],
@@ -976,7 +977,7 @@
     "gitignore": {
       "inputs": {
         "nixpkgs": [
-          "conduwuit",
+          "continuwuity",
           "cachix",
           "git-hooks",
           "nixpkgs"
@@ -1104,7 +1105,7 @@
     "nix": {
       "inputs": {
         "flake-compat": [
-          "conduwuit",
+          "continuwuity",
           "cachix",
           "devenv"
         ],
@@ -1112,17 +1113,17 @@
         "libgit2": "libgit2",
         "nixpkgs": "nixpkgs_3",
         "nixpkgs-23-11": [
-          "conduwuit",
+          "continuwuity",
           "cachix",
           "devenv"
         ],
         "nixpkgs-regression": [
-          "conduwuit",
+          "continuwuity",
           "cachix",
           "devenv"
         ],
         "pre-commit-hooks": [
-          "conduwuit",
+          "continuwuity",
           "cachix",
           "devenv"
         ]
@@ -1161,7 +1162,7 @@
     "nix-github-actions": {
       "inputs": {
         "nixpkgs": [
-          "conduwuit",
+          "continuwuity",
           "attic",
           "nixpkgs"
         ]
@@ -1631,7 +1632,7 @@
     },
     "root": {
       "inputs": {
-        "conduwuit": "conduwuit",
+        "continuwuity": "continuwuity",
         "deploy-rs": "deploy-rs",
         "disko": "disko",
         "foundryvtt": "foundryvtt",
diff --git a/flake.nix b/flake.nix
index 4f17def..bdb60ed 100644
--- a/flake.nix
+++ b/flake.nix
@@ -4,8 +4,8 @@
   inputs = {
     nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11-small";
     nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable-small";
-    conduwuit = {
-      url = "github:girlbossceo/conduwuit";
+    continuwuity = {
+      url = "git+https://forgejo.ellis.link/continuwuation/continuwuity.git?ref=refs/tags/v0.5.0-rc.5";
       inputs.nixpkgs.follows = "nixpkgs";
     };
     disko = {

From fc991a0b07c2c1821bafd34fc0ffaff2b0bcc29f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 20 May 2025 01:06:44 +0800
Subject: [PATCH 204/212] fix(metrics-exporters): Fix dbus socket access for
 DynamicUsers

This broke the systemd exporter, I don't fully know what caused the
breakage, though.

See
https://discourse.nixos.org/t/systemd-exporter-couldnt-get-dbus-connection-read-unix-run-dbus-system-bus-socket-recvmsg-connection-reset-by-peer/
---
 configuration/services/metrics/exporters.nix | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configuration/services/metrics/exporters.nix b/configuration/services/metrics/exporters.nix
index 78ba684..80a3480 100644
--- a/configuration/services/metrics/exporters.nix
+++ b/configuration/services/metrics/exporters.nix
@@ -97,4 +97,6 @@ in
     #   - postgres (?)
     #   - ssl_exporter (?)
   };
+
+  services.dbus.implementation = "broker";
 }

From 5c6b697e55e95e13f009cbcc4dcef4d070e83aee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 20 May 2025 20:37:05 +0800
Subject: [PATCH 205/212] feat(checks): Add linters

---
 checks/default.nix | 52 ++++++++++++++++++++++++++++++++++++++++++++++
 checks/lints.nu    | 39 ++++++++++++++++++++++++++++++++++
 flake.nix          |  2 +-
 3 files changed, 92 insertions(+), 1 deletion(-)
 create mode 100644 checks/default.nix
 create mode 100644 checks/lints.nu

diff --git a/checks/default.nix b/checks/default.nix
new file mode 100644
index 0000000..80279ba
--- /dev/null
+++ b/checks/default.nix
@@ -0,0 +1,52 @@
+{
+  self,
+  nixpkgs,
+  deploy-rs,
+  system,
+  ...
+}:
+let
+  pkgs = nixpkgs.legacyPackages.${system};
+
+  runNuCheck =
+    {
+      name,
+      packages,
+      check,
+    }:
+    pkgs.stdenvNoCC.mkDerivation {
+      inherit name;
+
+      src = nixpkgs.lib.cleanSourceWith {
+        src = self;
+        filter = nixpkgs.lib.cleanSourceFilter;
+      };
+
+      dontPatch = true;
+      dontConfigure = true;
+      dontBuild = true;
+      dontInstall = true;
+      dontFixup = true;
+      doCheck = true;
+
+      checkInputs = nixpkgs.lib.singleton pkgs.nushell ++ packages;
+
+      checkPhase = ''
+        nu ${check}
+      '';
+    };
+in
+nixpkgs.lib.recursiveUpdate {
+  lints = runNuCheck {
+    name = "lints";
+
+    packages = [
+      pkgs.deadnix
+      pkgs.nixfmt-rfc-style
+      pkgs.shellcheck
+      pkgs.statix
+    ];
+
+    check = ./lints.nu;
+  };
+} (deploy-rs.lib.${system}.deployChecks self.deploy)
diff --git a/checks/lints.nu b/checks/lints.nu
new file mode 100644
index 0000000..ffc2047
--- /dev/null
+++ b/checks/lints.nu
@@ -0,0 +1,39 @@
+#!/usr/bin/env nu
+
+let shell_files = ls **/*.sh | get name
+let nix_files = ls **/*.nix | where name !~ "hardware-configuration.nix|_sources" | get name
+
+let linters = [
+  ([shellcheck] ++ $shell_files)
+  ([nixfmt --check --strict] ++ $nix_files)
+  ([deadnix --fail] ++ $nix_files)
+  ([statix check] ++ $nix_files)
+]
+
+mkdir $env.out
+
+def run-linter [linterArgs: list<string>] {
+  print $'Running ($linterArgs.0)...'
+
+  let exit_code = try {
+    ^$linterArgs.0 ...($linterArgs | skip 1)
+    $env.LAST_EXIT_CODE
+  } catch {|e| $e.exit_code}
+
+  [$linterArgs.0, $exit_code]
+}
+
+let results = $linters | each {|linter| run-linter $linter}
+
+print 'Linter results:'
+
+let success = $results | each {|result|
+  match $result.1 {
+    0 => {print $'(ansi green)($result.0)(ansi reset)'}
+    _ => {print $'(ansi red)($result.0)(ansi reset)'}
+  }
+
+  $result.1
+} | math sum
+
+exit $success
diff --git a/flake.nix b/flake.nix
index bdb60ed..6747c24 100644
--- a/flake.nix
+++ b/flake.nix
@@ -96,7 +96,7 @@
       #########
       # Tests #
       #########
-      checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
+      checks.${system} = import ./checks (inputs // { inherit system; });
 
       ###########################
       # Garbage collection root #

From 63b3cbe00be80ccb4b221aad64eb657ae5c96d70 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 20 May 2025 20:38:43 +0800
Subject: [PATCH 206/212] style(treewide): Apply linter suggestions

---
 checks/default.nix                            |  11 +-
 configuration/default.nix                     |  10 +-
 configuration/hardware-specific/vm.nix        |  35 +--
 configuration/nginx.nix                       |  78 ++---
 configuration/services/backups.nix            |   4 +-
 configuration/services/conduit/default.nix    | 286 +++++++++---------
 .../services/conduit/matrix-hookshot.nix      |  12 +-
 configuration/services/crowdsec.nix           |  16 +-
 configuration/services/foundryvtt.nix         |  58 ++--
 configuration/services/gitea.nix              | 114 +++----
 configuration/services/metrics/exporters.nix  |   2 +-
 configuration/services/metrics/options.nix    |  68 +++--
 .../services/metrics/victorialogs.nix         |   6 +-
 configuration/services/nextcloud.nix          | 152 +++++-----
 configuration/services/webserver.nix          |   2 +-
 flake.nix                                     |   2 -
 modules/crowdsec/default.nix                  |   4 +-
 .../remediations/cs-firewall-bouncer.nix      |  11 +-
 modules/crowdsec/remediations/default.nix     |   6 +-
 pkgs/crowdsec/hub.nix                         |   5 +-
 20 files changed, 432 insertions(+), 450 deletions(-)

diff --git a/checks/default.nix b/checks/default.nix
index 80279ba..f3db4ce 100644
--- a/checks/default.nix
+++ b/checks/default.nix
@@ -8,6 +8,15 @@
 let
   pkgs = nixpkgs.legacyPackages.${system};
 
+  statix' = pkgs.statix.overrideAttrs (old: {
+    patches = old.patches ++ [
+      (pkgs.fetchpatch {
+        url = "https://github.com/oppiliappan/statix/commit/925dec39bb705acbbe77178b4d658fe1b752abbb.patch";
+        hash = "sha256-0wacO6wuYJ4ufN9PGucRVJucFdFFNF+NoHYIrLXsCWs=";
+      })
+    ];
+  });
+
   runNuCheck =
     {
       name,
@@ -44,7 +53,7 @@ nixpkgs.lib.recursiveUpdate {
       pkgs.deadnix
       pkgs.nixfmt-rfc-style
       pkgs.shellcheck
-      pkgs.statix
+      statix'
     ];
 
     check = ./lints.nu;
diff --git a/configuration/default.nix b/configuration/default.nix
index 239f9f6..544e20c 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -1,7 +1,5 @@
 {
   config,
-  pkgs,
-  lib,
   modulesPath,
   flake-inputs,
   ...
@@ -31,13 +29,7 @@
     ./sops.nix
   ];
 
-  nixpkgs.overlays = [
-    (final: prev: {
-      local = import ../pkgs {
-        pkgs = prev;
-      };
-    })
-  ];
+  nixpkgs.overlays = [ (_: prev: { local = import ../pkgs { pkgs = prev; }; }) ];
 
   nix = {
     extraOptions = ''
diff --git a/configuration/hardware-specific/vm.nix b/configuration/hardware-specific/vm.nix
index db563fe..71870fb 100644
--- a/configuration/hardware-specific/vm.nix
+++ b/configuration/hardware-specific/vm.nix
@@ -6,26 +6,35 @@
   boot.kernelParams = [ "nomodeset" ];
 
   networking.hostName = "testvm";
-  # Sets the base domain for nginx to a local domain so that we can
-  # easily test locally with the VM.
-  services.nginx.domain = "dev.local";
+
+  services = {
+    # Sets the base domain for nginx to a local domain so that we can
+    # easily test locally with the VM.
+    nginx.domain = "dev.local";
+
+    # Don't run this
+    batteryManager.enable = lib.mkForce false;
+
+    openssh.hostKeys = lib.mkForce [
+      {
+        type = "rsa";
+        bits = 4096;
+        path = "/etc/staging.key";
+      }
+    ];
+  };
 
   # Use the staging secrets
   sops.defaultSopsFile = lib.mkOverride 99 ../../keys/staging.yaml;
 
   systemd.network.networks."10-eth0" = {
     matchConfig.Name = "eth0";
-    gateway = [
-      "192.168.9.1"
-    ];
+    gateway = [ "192.168.9.1" ];
     networkConfig = {
       Address = "192.168.9.2/24";
     };
   };
 
-  # Don't run this
-  services.batteryManager.enable = lib.mkForce false;
-
   # Both so we have a predictable key for the staging env, as well as
   # to have a static key for decrypting the sops secrets for the
   # staging env.
@@ -34,14 +43,6 @@
     source = ../../keys/hosts/staging.key;
   };
 
-  services.openssh.hostKeys = lib.mkForce [
-    {
-      type = "rsa";
-      bits = 4096;
-      path = "/etc/staging.key";
-    }
-  ];
-
   virtualisation.vmVariant = {
     virtualisation = {
       memorySize = 3941;
diff --git a/configuration/nginx.nix b/configuration/nginx.nix
index 3ec3bd9..3abef7f 100644
--- a/configuration/nginx.nix
+++ b/configuration/nginx.nix
@@ -1,40 +1,49 @@
 { config, lib, ... }:
 {
-  services.nginx = {
-    enable = true;
-    recommendedTlsSettings = true;
-    recommendedOptimisation = true;
-    recommendedGzipSettings = true;
-    recommendedProxySettings = true;
-    clientMaxBodySize = "10G";
+  services = {
+    nginx = {
+      enable = true;
+      recommendedTlsSettings = true;
+      recommendedOptimisation = true;
+      recommendedGzipSettings = true;
+      recommendedProxySettings = true;
+      clientMaxBodySize = "10G";
 
-    statusPage = true; # For metrics, should be accessible only from localhost
+      statusPage = true; # For metrics, should be accessible only from localhost
 
-    commonHttpConfig = ''
-      log_format upstream_time '$remote_addr - $remote_user [$time_local] '
-                         '"$request" $status $body_bytes_sent '
-                         '"$http_referer" "$http_user_agent" '
-                         'rt=$request_time uct="$upstream_connect_time" '
-                         'uht="$upstream_header_time" urt="$upstream_response_time"';
-    '';
-  };
+      commonHttpConfig = ''
+        log_format upstream_time '$remote_addr - $remote_user [$time_local] '
+                           '"$request" $status $body_bytes_sent '
+                           '"$http_referer" "$http_user_agent" '
+                           'rt=$request_time uct="$upstream_connect_time" '
+                           'uht="$upstream_header_time" urt="$upstream_response_time"';
+      '';
+    };
 
-  services.logrotate.settings =
-    {
-      # Override the default, just keep fewer logs
-      nginx.rotate = 6;
-    }
-    // lib.mapAttrs' (
-      virtualHost: _:
-      lib.nameValuePair "/var/log/nginx/${virtualHost}/access.log" {
-        frequency = "daily";
-        rotate = 2;
-        compress = true;
-        delaycompress = true;
-        su = "${config.services.nginx.user} ${config.services.nginx.group}";
-        postrotate = "[ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`";
+    logrotate.settings =
+      {
+        # Override the default, just keep fewer logs
+        nginx.rotate = 6;
       }
-    ) config.services.nginx.virtualHosts;
+      // lib.mapAttrs' (
+        virtualHost: _:
+        lib.nameValuePair "/var/log/nginx/${virtualHost}/access.log" {
+          frequency = "daily";
+          rotate = 2;
+          compress = true;
+          delaycompress = true;
+          su = "${config.services.nginx.user} ${config.services.nginx.group}";
+          postrotate = "[ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`";
+        }
+      ) config.services.nginx.virtualHosts;
+
+    backups.acme = {
+      user = "acme";
+      paths = lib.mapAttrsToList (
+        virtualHost: _: "/var/lib/acme/${virtualHost}"
+      ) config.services.nginx.virtualHosts;
+    };
+  };
 
   systemd.tmpfiles.rules = lib.mapAttrsToList (
     virtualHost: _:
@@ -66,11 +75,4 @@
   systemd.services.nginx.serviceConfig.SupplementaryGroups = [
     config.security.acme.certs."tlater.net".group
   ];
-
-  services.backups.acme = {
-    user = "acme";
-    paths = lib.mapAttrsToList (
-      virtualHost: _: "/var/lib/acme/${virtualHost}"
-    ) config.services.nginx.virtualHosts;
-  };
 }
diff --git a/configuration/services/backups.nix b/configuration/services/backups.nix
index 81e3554..baa61e3 100644
--- a/configuration/services/backups.nix
+++ b/configuration/services/backups.nix
@@ -57,7 +57,7 @@ in
       '';
       type = types.attrsOf (
         types.submodule (
-          { config, name, ... }:
+          { name, ... }:
           {
             options = {
               user = lib.mkOption {
@@ -246,7 +246,7 @@ in
         };
       }
       // lib.mapAttrs' (
-        name: backup:
+        name: _:
         lib.nameValuePair "backup-${name}" {
           wantedBy = [ "timers.target" ];
           timerConfig = {
diff --git a/configuration/services/conduit/default.nix b/configuration/services/conduit/default.nix
index 94d401a..58abc49 100644
--- a/configuration/services/conduit/default.nix
+++ b/configuration/services/conduit/default.nix
@@ -18,33 +18,153 @@ in
     ./matrix-hookshot.nix
   ];
 
-  services.matrix-conduit = {
-    enable = true;
-    package = flake-inputs.continuwuity.packages.${pkgs.system}.default;
-    settings.global = {
-      address = "127.0.0.1";
-      server_name = domain;
-      new_user_displayname_suffix = "🦆";
-      allow_check_for_updates = true;
+  services = {
+    matrix-conduit = {
+      enable = true;
+      package = flake-inputs.continuwuity.packages.${pkgs.system}.default;
+      settings.global = {
+        address = "127.0.0.1";
+        server_name = domain;
+        new_user_displayname_suffix = "🦆";
+        allow_check_for_updates = true;
 
-      # Set up delegation: https://docs.conduit.rs/delegation.html#automatic-recommended
-      # This is primarily to make sliding sync work
-      well_known = {
-        client = "https://${domain}";
-        server = "${domain}:443";
+        # Set up delegation: https://docs.conduit.rs/delegation.html#automatic-recommended
+        # This is primarily to make sliding sync work
+        well_known = {
+          client = "https://${domain}";
+          server = "${domain}:443";
+        };
+
+        turn_uris =
+          let
+            address = "${config.services.coturn.realm}:${toString config.services.coturn.listening-port}";
+            tls-address = "${config.services.coturn.realm}:${toString config.services.coturn.tls-listening-port}";
+          in
+          [
+            "turn:${address}?transport=udp"
+            "turn:${address}?transport=tcp"
+            "turns:${tls-address}?transport=udp"
+            "turns:${tls-address}?transport=tcp"
+          ];
       };
+    };
 
-      turn_uris =
-        let
-          address = "${config.services.coturn.realm}:${toString config.services.coturn.listening-port}";
-          tls-address = "${config.services.coturn.realm}:${toString config.services.coturn.tls-listening-port}";
-        in
-        [
-          "turn:${address}?transport=udp"
-          "turn:${address}?transport=tcp"
-          "turns:${tls-address}?transport=udp"
-          "turns:${tls-address}?transport=tcp"
-        ];
+    coturn = {
+      enable = true;
+      no-cli = true;
+      use-auth-secret = true;
+      static-auth-secret-file = config.sops.secrets."turn/secret".path;
+      realm = turn-realm;
+      relay-ips = [ "116.202.158.55" ];
+
+      # SSL config
+      pkey = "${config.security.acme.certs."tlater.net".directory}/key.pem";
+      cert = "${config.security.acme.certs."tlater.net".directory}/fullchain.pem";
+
+      # Based on suggestions from
+      # https://github.com/matrix-org/synapse/blob/develop/docs/turn-howto.md
+      # and
+      # https://www.foxypossibilities.com/2018/05/19/setting-up-a-turn-sever-for-matrix-on-nixos/
+      no-tcp-relay = true;
+      secure-stun = true;
+      extraConfig = ''
+        # Deny various local IP ranges, see
+        # https://www.rtcsec.com/article/cve-2020-26262-bypass-of-coturns-access-control-protection/
+        no-multicast-peers
+        denied-peer-ip=0.0.0.0-0.255.255.255
+        denied-peer-ip=10.0.0.0-10.255.255.255
+        denied-peer-ip=100.64.0.0-100.127.255.255
+        denied-peer-ip=127.0.0.0-127.255.255.255
+        denied-peer-ip=169.254.0.0-169.254.255.255
+        denied-peer-ip=172.16.0.0-172.31.255.255
+        denied-peer-ip=192.0.0.0-192.0.0.255
+        denied-peer-ip=192.0.2.0-192.0.2.255
+        denied-peer-ip=192.88.99.0-192.88.99.255
+        denied-peer-ip=192.168.0.0-192.168.255.255
+        denied-peer-ip=198.18.0.0-198.19.255.255
+        denied-peer-ip=198.51.100.0-198.51.100.255
+        denied-peer-ip=203.0.113.0-203.0.113.255
+        denied-peer-ip=240.0.0.0-255.255.255.255 denied-peer-ip=::1
+        denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff
+        denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255
+        denied-peer-ip=100::-100::ffff:ffff:ffff:ffff
+        denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff
+        denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+        denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+        denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+
+        # *Allow* any IP addresses that we explicitly set as relay IPs
+        ${concatMapStringsSep "\n" (ip: "allowed-peer-ip=${ip}") config.services.coturn.relay-ips}
+
+        # Various other security settings
+        no-tlsv1
+        no-tlsv1_1
+
+        # Monitoring
+        prometheus
+      '';
+    };
+
+    nginx.virtualHosts."${domain}" = {
+      useACMEHost = "tlater.net";
+
+      listen = [
+        {
+          addr = "0.0.0.0";
+          port = 80;
+        }
+        {
+          addr = "[::0]";
+          port = 80;
+        }
+        {
+          addr = "0.0.0.0";
+          port = 443;
+          ssl = true;
+        }
+        {
+          addr = "[::0]";
+          port = 443;
+          ssl = true;
+        }
+        {
+          addr = "0.0.0.0";
+          port = 8448;
+          ssl = true;
+        }
+        {
+          addr = "[::0]";
+          port = 8448;
+          ssl = true;
+        }
+      ];
+
+      forceSSL = true;
+      enableHSTS = true;
+      extraConfig = ''
+        merge_slashes off;
+      '';
+
+      locations = {
+        "/_matrix" = {
+          proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}";
+          # Recommended by conduit
+          extraConfig = ''
+            proxy_buffering off;
+          '';
+        };
+        "/.well-known/matrix" = {
+          proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}";
+        };
+      };
+    };
+
+    backups.conduit = {
+      user = "root";
+      paths = [ "/var/lib/private/matrix-conduit/" ];
+      # Other services store their data in conduit, so no other services
+      # need to be shut down currently.
+      pauseServices = [ "conduit.service" ];
     };
   };
 
@@ -60,122 +180,4 @@ in
   systemd.services.coturn.serviceConfig.SupplementaryGroups = [
     config.security.acme.certs."tlater.net".group
   ];
-
-  services.coturn = {
-    enable = true;
-    no-cli = true;
-    use-auth-secret = true;
-    static-auth-secret-file = config.sops.secrets."turn/secret".path;
-    realm = turn-realm;
-    relay-ips = [ "116.202.158.55" ];
-
-    # SSL config
-    pkey = "${config.security.acme.certs."tlater.net".directory}/key.pem";
-    cert = "${config.security.acme.certs."tlater.net".directory}/fullchain.pem";
-
-    # Based on suggestions from
-    # https://github.com/matrix-org/synapse/blob/develop/docs/turn-howto.md
-    # and
-    # https://www.foxypossibilities.com/2018/05/19/setting-up-a-turn-sever-for-matrix-on-nixos/
-    no-tcp-relay = true;
-    secure-stun = true;
-    extraConfig = ''
-      # Deny various local IP ranges, see
-      # https://www.rtcsec.com/article/cve-2020-26262-bypass-of-coturns-access-control-protection/
-      no-multicast-peers
-      denied-peer-ip=0.0.0.0-0.255.255.255
-      denied-peer-ip=10.0.0.0-10.255.255.255
-      denied-peer-ip=100.64.0.0-100.127.255.255
-      denied-peer-ip=127.0.0.0-127.255.255.255
-      denied-peer-ip=169.254.0.0-169.254.255.255
-      denied-peer-ip=172.16.0.0-172.31.255.255
-      denied-peer-ip=192.0.0.0-192.0.0.255
-      denied-peer-ip=192.0.2.0-192.0.2.255
-      denied-peer-ip=192.88.99.0-192.88.99.255
-      denied-peer-ip=192.168.0.0-192.168.255.255
-      denied-peer-ip=198.18.0.0-198.19.255.255
-      denied-peer-ip=198.51.100.0-198.51.100.255
-      denied-peer-ip=203.0.113.0-203.0.113.255
-      denied-peer-ip=240.0.0.0-255.255.255.255 denied-peer-ip=::1
-      denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff
-      denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255
-      denied-peer-ip=100::-100::ffff:ffff:ffff:ffff
-      denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff
-      denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff
-      denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
-      denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
-
-      # *Allow* any IP addresses that we explicitly set as relay IPs
-      ${concatMapStringsSep "\n" (ip: "allowed-peer-ip=${ip}") config.services.coturn.relay-ips}
-
-      # Various other security settings
-      no-tlsv1
-      no-tlsv1_1
-
-      # Monitoring
-      prometheus
-    '';
-  };
-
-  services.nginx.virtualHosts."${domain}" = {
-    useACMEHost = "tlater.net";
-
-    listen = [
-      {
-        addr = "0.0.0.0";
-        port = 80;
-      }
-      {
-        addr = "[::0]";
-        port = 80;
-      }
-      {
-        addr = "0.0.0.0";
-        port = 443;
-        ssl = true;
-      }
-      {
-        addr = "[::0]";
-        port = 443;
-        ssl = true;
-      }
-      {
-        addr = "0.0.0.0";
-        port = 8448;
-        ssl = true;
-      }
-      {
-        addr = "[::0]";
-        port = 8448;
-        ssl = true;
-      }
-    ];
-
-    forceSSL = true;
-    enableHSTS = true;
-    extraConfig = ''
-      merge_slashes off;
-    '';
-
-    locations = {
-      "/_matrix" = {
-        proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}";
-        # Recommended by conduit
-        extraConfig = ''
-          proxy_buffering off;
-        '';
-      };
-      "/.well-known/matrix" = {
-        proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}";
-      };
-    };
-  };
-
-  services.backups.conduit = {
-    user = "root";
-    paths = [ "/var/lib/private/matrix-conduit/" ];
-    # Other services store their data in conduit, so no other services
-    # need to be shut down currently.
-    pauseServices = [ "conduit.service" ];
-  };
 }
diff --git a/configuration/services/conduit/matrix-hookshot.nix b/configuration/services/conduit/matrix-hookshot.nix
index c1f16dc..6846d99 100644
--- a/configuration/services/conduit/matrix-hookshot.nix
+++ b/configuration/services/conduit/matrix-hookshot.nix
@@ -74,9 +74,7 @@ in
   services.matrix-hookshot = {
     enable = true;
 
-    serviceDependencies = [
-      "conduit.service"
-    ];
+    serviceDependencies = [ "conduit.service" ];
 
     registrationFile = "/run/matrix-hookshot/registration.yaml";
 
@@ -126,15 +124,11 @@ in
       listeners = [
         {
           port = 9000;
-          resources = [
-            "webhooks"
-          ];
+          resources = [ "webhooks" ];
         }
         {
           port = 9001;
-          resources = [
-            "metrics"
-          ];
+          resources = [ "metrics" ];
         }
       ];
 
diff --git a/configuration/services/crowdsec.nix b/configuration/services/crowdsec.nix
index 6e0f367..b736047 100644
--- a/configuration/services/crowdsec.nix
+++ b/configuration/services/crowdsec.nix
@@ -8,9 +8,7 @@
   security.crowdsec = {
     enable = true;
 
-    parserWhitelist = [
-      "10.45.249.2"
-    ];
+    parserWhitelist = [ "10.45.249.2" ];
 
     extraGroups = [
       "systemd-journal"
@@ -21,25 +19,19 @@
       {
         source = "journalctl";
         labels.type = "syslog";
-        journalctl_filter = [
-          "SYSLOG_IDENTIFIER=Nextcloud"
-        ];
+        journalctl_filter = [ "SYSLOG_IDENTIFIER=Nextcloud" ];
       }
 
       {
         source = "journalctl";
         labels.type = "syslog";
-        journalctl_filter = [
-          "SYSLOG_IDENTIFIER=sshd-session"
-        ];
+        journalctl_filter = [ "SYSLOG_IDENTIFIER=sshd-session" ];
       }
 
       {
         labels.type = "nginx";
         filenames =
-          [
-            "/var/log/nginx/*.log"
-          ]
+          [ "/var/log/nginx/*.log" ]
           ++ lib.mapAttrsToList (
             vHost: _: "/var/log/nginx/${vHost}/access.log"
           ) config.services.nginx.virtualHosts;
diff --git a/configuration/services/foundryvtt.nix b/configuration/services/foundryvtt.nix
index 614b818..f25bbcd 100644
--- a/configuration/services/foundryvtt.nix
+++ b/configuration/services/foundryvtt.nix
@@ -11,37 +11,39 @@ in
 {
   imports = [ flake-inputs.foundryvtt.nixosModules.foundryvtt ];
 
-  services.foundryvtt = {
-    enable = true;
-    hostName = domain;
-    minifyStaticFiles = true;
-    proxySSL = true;
-    proxyPort = 443;
-    package = flake-inputs.foundryvtt.packages.${pkgs.system}.foundryvtt_11;
+  services = {
+    foundryvtt = {
+      enable = true;
+      hostName = domain;
+      minifyStaticFiles = true;
+      proxySSL = true;
+      proxyPort = 443;
+      package = flake-inputs.foundryvtt.packages.${pkgs.system}.foundryvtt_11;
+    };
+
+    nginx.virtualHosts."${domain}" =
+      let
+        inherit (config.services.foundryvtt) port;
+      in
+      {
+        forceSSL = true;
+        useACMEHost = "tlater.net";
+        enableHSTS = true;
+
+        locations."/" = {
+          proxyWebsockets = true;
+          proxyPass = "http://localhost:${toString port}";
+        };
+      };
+
+    backups.foundryvtt = {
+      user = "foundryvtt";
+      paths = [ config.services.foundryvtt.dataDir ];
+      pauseServices = [ "foundryvtt.service" ];
+    };
   };
 
   # Want to start it manually when I need it, not have it constantly
   # running
   systemd.services.foundryvtt.wantedBy = lib.mkForce [ ];
-
-  services.nginx.virtualHosts."${domain}" =
-    let
-      inherit (config.services.foundryvtt) port;
-    in
-    {
-      forceSSL = true;
-      useACMEHost = "tlater.net";
-      enableHSTS = true;
-
-      locations."/" = {
-        proxyWebsockets = true;
-        proxyPass = "http://localhost:${toString port}";
-      };
-    };
-
-  services.backups.foundryvtt = {
-    user = "foundryvtt";
-    paths = [ config.services.foundryvtt.dataDir ];
-    pauseServices = [ "foundryvtt.service" ];
-  };
 }
diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index da01cde..613d30c 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -8,24 +8,68 @@ let
   domain = "gitea.${config.services.nginx.domain}";
 in
 {
-  services.forgejo = {
-    enable = true;
-    database.type = "postgres";
+  services = {
+    forgejo = {
+      enable = true;
+      database.type = "postgres";
 
-    settings = {
-      server = {
-        DOMAIN = domain;
-        HTTP_ADDR = "127.0.0.1";
-        ROOT_URL = "https://${domain}/";
-        SSH_PORT = 2222;
+      settings = {
+        server = {
+          DOMAIN = domain;
+          HTTP_ADDR = "127.0.0.1";
+          ROOT_URL = "https://${domain}/";
+          SSH_PORT = 2222;
+        };
+
+        metrics = {
+          ENABLED = true;
+          TOKEN = "#metricstoken#";
+        };
+        service.DISABLE_REGISTRATION = true;
+        session.COOKIE_SECURE = true;
+      };
+    };
+
+    # Set up SSL
+    nginx.virtualHosts."${domain}" =
+      let
+        httpAddress = config.services.forgejo.settings.server.HTTP_ADDR;
+        httpPort = config.services.forgejo.settings.server.HTTP_PORT;
+      in
+      {
+        forceSSL = true;
+        useACMEHost = "tlater.net";
+        enableHSTS = true;
+
+        locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}";
+        locations."/metrics" = {
+          extraConfig = ''
+            access_log off;
+            allow 127.0.0.1;
+            ${lib.optionalString config.networking.enableIPv6 "allow ::1;"}
+            deny all;
+          '';
+        };
       };
 
-      metrics = {
-        ENABLED = true;
-        TOKEN = "#metricstoken#";
+    backups.forgejo = {
+      user = "forgejo";
+      paths = [
+        "/var/lib/forgejo/forgejo-db.sql"
+        "/var/lib/forgejo/repositories/"
+        "/var/lib/forgejo/data/"
+        "/var/lib/forgejo/custom/"
+        # Conf is backed up via nix
+      ];
+      preparation = {
+        packages = [ config.services.postgresql.package ];
+        text = "pg_dump ${config.services.forgejo.database.name} --file=/var/lib/forgejo/forgejo-db.sql";
       };
-      service.DISABLE_REGISTRATION = true;
-      session.COOKIE_SECURE = true;
+      cleanup = {
+        packages = [ pkgs.coreutils ];
+        text = "rm /var/lib/forgejo/forgejo-db.sql";
+      };
+      pauseServices = [ "forgejo.service" ];
     };
   };
 
@@ -36,46 +80,4 @@ in
       runConfig = "${config.services.forgejo.customDir}/conf/app.ini";
     in
     [ "+${replaceSecretBin} '#metricstoken#' '${secretPath}' '${runConfig}'" ];
-
-  # Set up SSL
-  services.nginx.virtualHosts."${domain}" =
-    let
-      httpAddress = config.services.forgejo.settings.server.HTTP_ADDR;
-      httpPort = config.services.forgejo.settings.server.HTTP_PORT;
-    in
-    {
-      forceSSL = true;
-      useACMEHost = "tlater.net";
-      enableHSTS = true;
-
-      locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}";
-      locations."/metrics" = {
-        extraConfig = ''
-          access_log off;
-          allow 127.0.0.1;
-          ${lib.optionalString config.networking.enableIPv6 "allow ::1;"}
-          deny all;
-        '';
-      };
-    };
-
-  services.backups.forgejo = {
-    user = "forgejo";
-    paths = [
-      "/var/lib/forgejo/forgejo-db.sql"
-      "/var/lib/forgejo/repositories/"
-      "/var/lib/forgejo/data/"
-      "/var/lib/forgejo/custom/"
-      # Conf is backed up via nix
-    ];
-    preparation = {
-      packages = [ config.services.postgresql.package ];
-      text = "pg_dump ${config.services.forgejo.database.name} --file=/var/lib/forgejo/forgejo-db.sql";
-    };
-    cleanup = {
-      packages = [ pkgs.coreutils ];
-      text = "rm /var/lib/forgejo/forgejo-db.sql";
-    };
-    pauseServices = [ "forgejo.service" ];
-  };
 }
diff --git a/configuration/services/metrics/exporters.nix b/configuration/services/metrics/exporters.nix
index 80a3480..52c2a46 100644
--- a/configuration/services/metrics/exporters.nix
+++ b/configuration/services/metrics/exporters.nix
@@ -74,7 +74,7 @@ in
         listenAddress = "127.0.0.1";
         group = "nginx";
 
-        settings.namespaces = lib.mapAttrsToList (name: virtualHost: {
+        settings.namespaces = lib.mapAttrsToList (name: _: {
           inherit name;
           metrics_override.prefix = "nginxlog";
           namespace_label = "vhost";
diff --git a/configuration/services/metrics/options.nix b/configuration/services/metrics/options.nix
index d69ecfb..e1b0761 100644
--- a/configuration/services/metrics/options.nix
+++ b/configuration/services/metrics/options.nix
@@ -38,7 +38,7 @@ in
     services.victoriametrics.scrapeConfigs = mkOption {
       type = types.attrsOf (
         types.submodule (
-          { name, self, ... }:
+          { name, ... }:
           {
             options = {
               job_name = mkOption {
@@ -106,35 +106,37 @@ in
               # module is an intractable mess
               wantedBy = [ "multi-user.target" ];
               after = [ "network.target" ];
-              serviceConfig.Restart = mkDefault "always";
-              serviceConfig.PrivateTmp = mkDefault true;
-              serviceConfig.WorkingDirectory = mkDefault /tmp;
-              serviceConfig.DynamicUser = mkDefault true;
-              # Hardening
-              serviceConfig.CapabilityBoundingSet = mkDefault [ "" ];
-              serviceConfig.DeviceAllow = [ "" ];
-              serviceConfig.LockPersonality = true;
-              serviceConfig.MemoryDenyWriteExecute = true;
-              serviceConfig.NoNewPrivileges = true;
-              serviceConfig.PrivateDevices = mkDefault true;
-              serviceConfig.ProtectClock = mkDefault true;
-              serviceConfig.ProtectControlGroups = true;
-              serviceConfig.ProtectHome = true;
-              serviceConfig.ProtectHostname = true;
-              serviceConfig.ProtectKernelLogs = true;
-              serviceConfig.ProtectKernelModules = true;
-              serviceConfig.ProtectKernelTunables = true;
-              serviceConfig.ProtectSystem = mkDefault "strict";
-              serviceConfig.RemoveIPC = true;
-              serviceConfig.RestrictAddressFamilies = [
-                "AF_INET"
-                "AF_INET6"
-              ];
-              serviceConfig.RestrictNamespaces = true;
-              serviceConfig.RestrictRealtime = true;
-              serviceConfig.RestrictSUIDSGID = true;
-              serviceConfig.SystemCallArchitectures = "native";
-              serviceConfig.UMask = "0077";
+              serviceConfig = {
+                Restart = mkDefault "always";
+                PrivateTmp = mkDefault true;
+                WorkingDirectory = mkDefault /tmp;
+                DynamicUser = mkDefault true;
+                # Hardening
+                CapabilityBoundingSet = mkDefault [ "" ];
+                DeviceAllow = [ "" ];
+                LockPersonality = true;
+                MemoryDenyWriteExecute = true;
+                NoNewPrivileges = true;
+                PrivateDevices = mkDefault true;
+                ProtectClock = mkDefault true;
+                ProtectControlGroups = true;
+                ProtectHome = true;
+                ProtectHostname = true;
+                ProtectKernelLogs = true;
+                ProtectKernelModules = true;
+                ProtectKernelTunables = true;
+                ProtectSystem = mkDefault "strict";
+                RemoveIPC = true;
+                RestrictAddressFamilies = [
+                  "AF_INET"
+                  "AF_INET6"
+                ];
+                RestrictNamespaces = true;
+                RestrictRealtime = true;
+                RestrictSUIDSGID = true;
+                SystemCallArchitectures = "native";
+                UMask = "0077";
+              };
             }
             exporter.serviceOpts
           ]
@@ -144,7 +146,7 @@ in
       {
         vmagent-scrape-exporters =
           let
-            listenAddress = config.services.victoriametrics.listenAddress;
+            inherit (config.services.victoriametrics) listenAddress;
             vmAddr = (lib.optionalString (lib.hasPrefix ":" listenAddress) "127.0.0.1") + listenAddress;
             promscrape = yaml.generate "prometheus.yml" {
               scrape_configs = lib.mapAttrsToList (
@@ -153,7 +155,7 @@ in
                   inherit (scrape) job_name;
                   static_configs =
                     scrape.static_configs
-                    ++ lib.optional (scrape.targets != [ ]) { targets = scrape.targets; };
+                    ++ lib.optional (scrape.targets != [ ]) { inherit (scrape) targets; };
                 } scrape.extraSettings
               ) config.services.victoriametrics.scrapeConfigs;
             };
@@ -212,7 +214,7 @@ in
 
     services.victoriametrics.scrapeConfigs =
       let
-        allExporters = lib.mapAttrs (name: exporter: { inherit (exporter) listenAddress port; }) (
+        allExporters = lib.mapAttrs (_: exporter: { inherit (exporter) listenAddress port; }) (
           (lib.filterAttrs (
             name: exporter:
             # A bunch of deprecated exporters that need to be ignored
diff --git a/configuration/services/metrics/victorialogs.nix b/configuration/services/metrics/victorialogs.nix
index ae47c39..413659a 100644
--- a/configuration/services/metrics/victorialogs.nix
+++ b/configuration/services/metrics/victorialogs.nix
@@ -1,8 +1,4 @@
-{
-  config,
-  lib,
-  ...
-}:
+{ config, lib, ... }:
 let
   cfg = config.services.victorialogs;
 in
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index b5cb691..2f8fa76 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -9,93 +9,95 @@ let
   hostName = "nextcloud.${config.services.nginx.domain}";
 in
 {
-  services.nextcloud = {
-    inherit hostName;
+  services = {
+    nextcloud = {
+      inherit hostName;
 
-    package = nextcloud;
-    phpPackage = lib.mkForce (
-      pkgs.php.override {
-        packageOverrides = final: prev: {
-          extensions = prev.extensions // {
-            pgsql = prev.extensions.pgsql.overrideAttrs (old: {
-              configureFlags = [ "--with-pgsql=${lib.getDev config.services.postgresql.package}" ];
-            });
-            pdo_pgsql = prev.extensions.pdo_pgsql.overrideAttrs (old: {
-              configureFlags = [ "--with-pdo-pgsql=${lib.getDev config.services.postgresql.package}" ];
-            });
+      package = nextcloud;
+      phpPackage = lib.mkForce (
+        pkgs.php.override {
+          packageOverrides = _: prev: {
+            extensions = prev.extensions // {
+              pgsql = prev.extensions.pgsql.overrideAttrs (_: {
+                configureFlags = [ "--with-pgsql=${lib.getDev config.services.postgresql.package}" ];
+              });
+              pdo_pgsql = prev.extensions.pdo_pgsql.overrideAttrs (_: {
+                configureFlags = [ "--with-pdo-pgsql=${lib.getDev config.services.postgresql.package}" ];
+              });
+            };
           };
-        };
-      }
-    );
-    enable = true;
-    maxUploadSize = "2G";
-    https = true;
+        }
+      );
+      enable = true;
+      maxUploadSize = "2G";
+      https = true;
 
-    configureRedis = true;
+      configureRedis = true;
 
-    config = {
-      dbtype = "pgsql";
-      dbhost = "/run/postgresql";
+      config = {
+        dbtype = "pgsql";
+        dbhost = "/run/postgresql";
 
-      adminuser = "tlater";
-      adminpassFile = config.sops.secrets."nextcloud/tlater".path;
+        adminuser = "tlater";
+        adminpassFile = config.sops.secrets."nextcloud/tlater".path;
+      };
+
+      settings = {
+        default_phone_region = "AT";
+        overwriteprotocol = "https";
+      };
+
+      phpOptions = {
+        "opcache.interned_strings_buffer" = "16";
+      };
+
+      extraApps = {
+        inherit (config.services.nextcloud.package.packages.apps)
+          calendar
+          contacts
+          cookbook
+          news
+          ;
+      };
     };
 
-    settings = {
-      default_phone_region = "AT";
-      overwriteprotocol = "https";
+    # Set up SSL
+    nginx.virtualHosts."${hostName}" = {
+      forceSSL = true;
+      useACMEHost = "tlater.net";
+      # The upstream module already adds HSTS
     };
 
-    phpOptions = {
-      "opcache.interned_strings_buffer" = "16";
-    };
-
-    extraApps = {
-      inherit (config.services.nextcloud.package.packages.apps)
-        calendar
-        contacts
-        cookbook
-        news
-        ;
+    backups.nextcloud = {
+      user = "nextcloud";
+      paths = [
+        "/var/lib/nextcloud/nextcloud-db.sql"
+        "/var/lib/nextcloud/data/"
+        "/var/lib/nextcloud/config/config.php"
+      ];
+      preparation = {
+        packages = [
+          config.services.postgresql.package
+          config.services.nextcloud.occ
+        ];
+        text = ''
+          nextcloud-occ maintenance:mode --on
+          pg_dump ${config.services.nextcloud.config.dbname} --file=/var/lib/nextcloud/nextcloud-db.sql
+        '';
+      };
+      cleanup = {
+        packages = [
+          pkgs.coreutils
+          config.services.nextcloud.occ
+        ];
+        text = ''
+          rm /var/lib/nextcloud/nextcloud-db.sql
+          nextcloud-occ maintenance:mode --off
+        '';
+      };
     };
   };
 
   # Ensure that this service doesn't start before postgres is ready
   systemd.services.nextcloud-setup.after = [ "postgresql.service" ];
-
-  # Set up SSL
-  services.nginx.virtualHosts."${hostName}" = {
-    forceSSL = true;
-    useACMEHost = "tlater.net";
-    # The upstream module already adds HSTS
-  };
-
-  services.backups.nextcloud = {
-    user = "nextcloud";
-    paths = [
-      "/var/lib/nextcloud/nextcloud-db.sql"
-      "/var/lib/nextcloud/data/"
-      "/var/lib/nextcloud/config/config.php"
-    ];
-    preparation = {
-      packages = [
-        config.services.postgresql.package
-        config.services.nextcloud.occ
-      ];
-      text = ''
-        nextcloud-occ maintenance:mode --on
-        pg_dump ${config.services.nextcloud.config.dbname} --file=/var/lib/nextcloud/nextcloud-db.sql
-      '';
-    };
-    cleanup = {
-      packages = [
-        pkgs.coreutils
-        config.services.nextcloud.occ
-      ];
-      text = ''
-        rm /var/lib/nextcloud/nextcloud-db.sql
-        nextcloud-occ maintenance:mode --off
-      '';
-    };
-  };
 }
diff --git a/configuration/services/webserver.nix b/configuration/services/webserver.nix
index e6b49b3..864f6c0 100644
--- a/configuration/services/webserver.nix
+++ b/configuration/services/webserver.nix
@@ -1,6 +1,6 @@
 { config, ... }:
 let
-  domain = config.services.nginx.domain;
+  inherit (config.services.nginx) domain;
 in
 {
   services.tlaternet-webserver = {
diff --git a/flake.nix b/flake.nix
index 6747c24..90716e5 100644
--- a/flake.nix
+++ b/flake.nix
@@ -121,8 +121,6 @@
         run-vm = {
           type = "app";
           program =
-            let
-            in
             (pkgs.writeShellScript "" ''
               ${vm.config.system.build.vm.outPath}/bin/run-testvm-vm
             '').outPath;
diff --git a/modules/crowdsec/default.nix b/modules/crowdsec/default.nix
index c0003a5..ac93c4a 100644
--- a/modules/crowdsec/default.nix
+++ b/modules/crowdsec/default.nix
@@ -267,9 +267,7 @@ in
       };
     };
 
-    systemd.packages = [
-      cfg.package
-    ];
+    systemd.packages = [ cfg.package ];
 
     environment = {
       systemPackages = [
diff --git a/modules/crowdsec/remediations/cs-firewall-bouncer.nix b/modules/crowdsec/remediations/cs-firewall-bouncer.nix
index aa70552..42accc6 100644
--- a/modules/crowdsec/remediations/cs-firewall-bouncer.nix
+++ b/modules/crowdsec/remediations/cs-firewall-bouncer.nix
@@ -6,10 +6,11 @@
   ...
 }:
 let
+  inherit (flake-inputs.self.packages.${pkgs.system}) crowdsec-firewall-bouncer;
+
   crowdsecCfg = config.security.crowdsec;
   cfg = crowdsecCfg.remediationComponents.firewallBouncer;
   settingsFormat = pkgs.formats.yaml { };
-  crowdsec-firewall-bouncer = flake-inputs.self.packages.${pkgs.system}.crowdsec-firewall-bouncer;
 in
 {
   options.security.crowdsec.remediationComponents.firewallBouncer = {
@@ -31,9 +32,7 @@ in
     security.crowdsec.remediationComponents.firewallBouncer.settings = {
       mode = lib.mkDefault "${if config.networking.nftables.enable then "nftables" else "iptables"}";
       log_mode = "stdout";
-      iptables_chains = [
-        "nixos-fw"
-      ];
+      iptables_chains = [ "nixos-fw" ];
 
       # Don't let users easily override this; unfortunately we need to
       # set up this key through substitution at runtime.
@@ -78,9 +77,7 @@ in
           requiredBy = [ "crowdsec.service" ];
 
           path =
-            lib.optionals (cfg.settings.mode == "ipset" || cfg.settings.mode == "iptables") [
-              pkgs.ipset
-            ]
+            lib.optionals (cfg.settings.mode == "ipset" || cfg.settings.mode == "iptables") [ pkgs.ipset ]
             ++ lib.optional (cfg.settings.mode == "iptables") pkgs.iptables
             ++ lib.optional (cfg.settings.mode == "nftables") pkgs.nftables;
         };
diff --git a/modules/crowdsec/remediations/default.nix b/modules/crowdsec/remediations/default.nix
index 7df6ade..c3c0790 100644
--- a/modules/crowdsec/remediations/default.nix
+++ b/modules/crowdsec/remediations/default.nix
@@ -1,5 +1 @@
-{
-  imports = [
-    ./cs-firewall-bouncer.nix
-  ];
-}
+{ imports = [ ./cs-firewall-bouncer.nix ]; }
diff --git a/pkgs/crowdsec/hub.nix b/pkgs/crowdsec/hub.nix
index d057ca8..1b8c9b3 100644
--- a/pkgs/crowdsec/hub.nix
+++ b/pkgs/crowdsec/hub.nix
@@ -1,4 +1 @@
-{
-  sources,
-}:
-sources.crowdsec-hub.src
+{ sources }: sources.crowdsec-hub.src

From 8d0be61483178428191cf79f55705ff20cb2b8cb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Tue, 20 May 2025 20:49:16 +0800
Subject: [PATCH 207/212] chore(ignore-revs): Ignore linter changes in `blame`

---
 .git-blame-ignore-revs | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index df9d62b..40e5d59 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -9,3 +9,6 @@ fd138d45e6a2cad89fead6e9f246ba282070d6b7
 
 # Switch to alejandra formatting
 046a88905ddfa7f9edc3291c310dbb985dee34f9
+
+# Apply wide linting
+63b3cbe00be80ccb4b221aad64eb657ae5c96d70

From 913944cff37a3007574525735c854d4be6dd97eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 23 May 2025 11:40:19 +0800
Subject: [PATCH 208/212] feat(immich): Add immich service

---
 configuration/default.nix                     |  1 +
 configuration/services/immich.nix             | 65 +++++++++++++++++++
 .../services/metrics/victoriametrics.nix      |  5 ++
 3 files changed, 71 insertions(+)
 create mode 100644 configuration/services/immich.nix

diff --git a/configuration/default.nix b/configuration/default.nix
index 544e20c..0377e9c 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -19,6 +19,7 @@
     ./services/crowdsec.nix
     ./services/foundryvtt.nix
     ./services/gitea.nix
+    ./services/immich.nix
     ./services/metrics
     ./services/nextcloud.nix
     ./services/webserver.nix
diff --git a/configuration/services/immich.nix b/configuration/services/immich.nix
new file mode 100644
index 0000000..b74c877
--- /dev/null
+++ b/configuration/services/immich.nix
@@ -0,0 +1,65 @@
+{
+  pkgs,
+  config,
+  lib,
+  ...
+}:
+let
+  hostName = "immich.${config.services.nginx.domain}";
+in
+{
+  services.immich = {
+    enable = true;
+    settings.server.externalDomain = "https://${hostName}";
+
+    environment.IMMICH_TELEMETRY_INCLUDE = "all";
+  };
+
+  services.nginx.virtualHosts.${hostName} =
+    let
+      local = "http://${config.services.immich.host}:${toString config.services.immich.port}";
+    in
+    {
+      forceSSL = true;
+      useACMEHost = "tlater.net";
+      enableHSTS = true;
+
+      locations."/" = {
+        proxyPass = local;
+        proxyWebsockets = true;
+      };
+      locations."/metrics" = {
+        extraConfig = ''
+          access_log off;
+          allow 127.0.0.1;
+          ${lib.optionalString config.networking.enableIPv6 "allow ::1;"}
+          deny all;
+        '';
+      };
+    };
+
+  backups.immich =
+    let
+      db-dump = "${config.services.immich.mediaLocation}/immich-db.sql";
+    in
+    {
+      user = "immich";
+      paths = [ config.services.immich.mediaLocation ];
+
+      preparation = {
+        packages = [ config.services.postgresql.package ];
+        text = ''
+          pg_dump ${config.services.immich.database.name} --clean --if-exists --file=${db-dump}
+        '';
+      };
+
+      cleanup = {
+        packages = [ pkgs.coreutils ];
+        text = "rm ${db-dump}";
+      };
+      pauseServices = [
+        "immich-server.service"
+        "immich-machine-learning.service"
+      ];
+    };
+}
diff --git a/configuration/services/metrics/victoriametrics.nix b/configuration/services/metrics/victoriametrics.nix
index 53864d6..f37b8b0 100644
--- a/configuration/services/metrics/victoriametrics.nix
+++ b/configuration/services/metrics/victoriametrics.nix
@@ -84,6 +84,11 @@ in
         in
         [ "${address}:${toString port}" ];
 
+      immich.targets = [
+        "127.0.0.1:8081"
+        "127.0.0.1:8082"
+      ];
+
       # Configured in the hookshot listeners, but it's hard to filter
       # the correct values out of that config.
       matrixHookshot.targets = [ "127.0.0.1:9001" ];

From b067bbc8c004af4780f8306c3ad7de466a9d823f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 24 May 2025 05:32:55 +0800
Subject: [PATCH 209/212] fix(immich): Set the correct backup attribute

---
 configuration/services/immich.nix | 106 +++++++++++++++---------------
 1 file changed, 54 insertions(+), 52 deletions(-)

diff --git a/configuration/services/immich.nix b/configuration/services/immich.nix
index b74c877..516ea3e 100644
--- a/configuration/services/immich.nix
+++ b/configuration/services/immich.nix
@@ -8,58 +8,60 @@ let
   hostName = "immich.${config.services.nginx.domain}";
 in
 {
-  services.immich = {
-    enable = true;
-    settings.server.externalDomain = "https://${hostName}";
+  services = {
+    immich = {
+      enable = true;
+      settings.server.externalDomain = "https://${hostName}";
 
-    environment.IMMICH_TELEMETRY_INCLUDE = "all";
+      environment.IMMICH_TELEMETRY_INCLUDE = "all";
+    };
+
+    nginx.virtualHosts.${hostName} =
+      let
+        local = "http://${config.services.immich.host}:${toString config.services.immich.port}";
+      in
+      {
+        forceSSL = true;
+        useACMEHost = "tlater.net";
+        enableHSTS = true;
+
+        locations."/" = {
+          proxyPass = local;
+          proxyWebsockets = true;
+        };
+        locations."/metrics" = {
+          extraConfig = ''
+            access_log off;
+            allow 127.0.0.1;
+            ${lib.optionalString config.networking.enableIPv6 "allow ::1;"}
+            deny all;
+          '';
+        };
+      };
+
+    backups.immich =
+      let
+        db-dump = "${config.services.immich.mediaLocation}/immich-db.sql";
+      in
+      {
+        user = "immich";
+        paths = [ config.services.immich.mediaLocation ];
+
+        preparation = {
+          packages = [ config.services.postgresql.package ];
+          text = ''
+            pg_dump ${config.services.immich.database.name} --clean --if-exists --file=${db-dump}
+          '';
+        };
+
+        cleanup = {
+          packages = [ pkgs.coreutils ];
+          text = "rm ${db-dump}";
+        };
+        pauseServices = [
+          "immich-server.service"
+          "immich-machine-learning.service"
+        ];
+      };
   };
-
-  services.nginx.virtualHosts.${hostName} =
-    let
-      local = "http://${config.services.immich.host}:${toString config.services.immich.port}";
-    in
-    {
-      forceSSL = true;
-      useACMEHost = "tlater.net";
-      enableHSTS = true;
-
-      locations."/" = {
-        proxyPass = local;
-        proxyWebsockets = true;
-      };
-      locations."/metrics" = {
-        extraConfig = ''
-          access_log off;
-          allow 127.0.0.1;
-          ${lib.optionalString config.networking.enableIPv6 "allow ::1;"}
-          deny all;
-        '';
-      };
-    };
-
-  backups.immich =
-    let
-      db-dump = "${config.services.immich.mediaLocation}/immich-db.sql";
-    in
-    {
-      user = "immich";
-      paths = [ config.services.immich.mediaLocation ];
-
-      preparation = {
-        packages = [ config.services.postgresql.package ];
-        text = ''
-          pg_dump ${config.services.immich.database.name} --clean --if-exists --file=${db-dump}
-        '';
-      };
-
-      cleanup = {
-        packages = [ pkgs.coreutils ];
-        text = "rm ${db-dump}";
-      };
-      pauseServices = [
-        "immich-server.service"
-        "immich-machine-learning.service"
-      ];
-    };
 }

From fc6be0c4c27dd00283bacb7c5cd3bcf1d5bab09c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 24 May 2025 22:53:33 +0800
Subject: [PATCH 210/212] chore(treewide): Upgrade to NixOS 25.05

---
 configuration/services/conduit/default.nix    |  3 +-
 .../services/conduit/matrix-hookshot.nix      | 42 +++++++++++++++----
 configuration/services/metrics/grafana.nix    |  9 +---
 configuration/services/nextcloud.nix          |  6 +--
 flake.nix                                     |  7 +---
 modules/crowdsec/default.nix                  |  5 +--
 6 files changed, 43 insertions(+), 29 deletions(-)

diff --git a/configuration/services/conduit/default.nix b/configuration/services/conduit/default.nix
index 58abc49..4ba5271 100644
--- a/configuration/services/conduit/default.nix
+++ b/configuration/services/conduit/default.nix
@@ -1,6 +1,5 @@
 {
   pkgs,
-  flake-inputs,
   config,
   lib,
   ...
@@ -21,7 +20,7 @@ in
   services = {
     matrix-conduit = {
       enable = true;
-      package = flake-inputs.continuwuity.packages.${pkgs.system}.default;
+      package = pkgs.matrix-continuwuity;
       settings.global = {
         address = "127.0.0.1";
         server_name = domain;
diff --git a/configuration/services/conduit/matrix-hookshot.nix b/configuration/services/conduit/matrix-hookshot.nix
index 6846d99..6b788b2 100644
--- a/configuration/services/conduit/matrix-hookshot.nix
+++ b/configuration/services/conduit/matrix-hookshot.nix
@@ -29,16 +29,29 @@ let
     };
 
     # Encryption support
-    extraSettings = {
-      "de.sorunome.msc2409.push_ephemeral" = true;
-      push_ephemeral = true;
-      "org.matrix.msc3202" = true;
-    };
+    # TODO(tlater): Enable when
+    # https://github.com/matrix-org/matrix-hookshot/issues/1060 is
+    # fixed
+    # extraSettings = {
+    #   "de.sorunome.msc2409.push_ephemeral" = true;
+    #   push_ephemeral = true;
+    #   "org.matrix.msc3202" = true;
+    # };
 
     runtimeRegistration = "${cfg.registrationFile}";
   };
 in
 {
+  # users = {
+  #   users.matrix-hookshot = {
+  #     home = "/run/matrix-hookshot";
+  #     group = "matrix-hookshot";
+  #     isSystemUser = true;
+  #   };
+
+  #   groups.matrix-hookshot = { };
+  # };
+
   systemd.services.matrix-hookshot = {
     serviceConfig = {
       Type = lib.mkForce "exec";
@@ -49,6 +62,7 @@ in
       # Some library in matrix-hookshot wants a home directory
       Environment = [ "HOME=/run/matrix-hookshot" ];
 
+      # User = "matrix-hookshot";
       DynamicUser = true;
       StateDirectory = "matrix-hookshot";
       RuntimeDirectory = "matrix-hookshot";
@@ -62,7 +76,11 @@ in
       ProtectKernelModules = true;
       ProtectKernelLogs = true;
       ProtectControlGroups = true;
-      RestrictAddressFamilies = [ "AF_INET AF_INET6" ];
+      RestrictAddressFamilies = [
+        # "AF_UNIX"
+        "AF_INET"
+        "AF_INET6"
+      ];
       LockPersonality = true;
       RestrictRealtime = true;
       ProtectProc = "invisible";
@@ -71,6 +89,11 @@ in
     };
   };
 
+  # services.redis.servers.matrix-hookshot = {
+  #   enable = true;
+  #   user = "matrix-hookshot";
+  # };
+
   services.matrix-hookshot = {
     enable = true;
 
@@ -89,6 +112,8 @@ in
 
       bot.displayname = "Hookshot";
 
+      # cache.redisUri = "redis://${config.services.redis.servers.matrix-hookshot.unixSocket}";
+
       generic = {
         enabled = true;
         outbound = false;
@@ -98,7 +123,10 @@ in
         allowJsTransformationFunctions = true;
       };
 
-      encryption.storagePath = "/var/lib/matrix-hookshot/cryptostore";
+      # TODO(tlater): Enable when
+      # https://github.com/matrix-org/matrix-hookshot/issues/1060 is
+      # fixed
+      # encryption.storagePath = "/var/lib/matrix-hookshot/cryptostore";
 
       permissions = [
         {
diff --git a/configuration/services/metrics/grafana.nix b/configuration/services/metrics/grafana.nix
index b872833..b30806c 100644
--- a/configuration/services/metrics/grafana.nix
+++ b/configuration/services/metrics/grafana.nix
@@ -1,9 +1,4 @@
-{
-  pkgs,
-  config,
-  flake-inputs,
-  ...
-}:
+{ pkgs, config, ... }:
 let
   domain = "metrics.${config.services.nginx.domain}";
 in
@@ -35,7 +30,7 @@ in
 
     declarativePlugins = [
       pkgs.grafanaPlugins.victoriametrics-metrics-datasource
-      flake-inputs.nixpkgs-unstable.legacyPackages.${pkgs.system}.grafanaPlugins.victoriametrics-logs-datasource
+      pkgs.grafanaPlugins.victoriametrics-logs-datasource
     ];
 
     provision = {
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 2f8fa76..4af77a9 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -5,7 +5,7 @@
   ...
 }:
 let
-  nextcloud = pkgs.nextcloud30;
+  nextcloud = pkgs.nextcloud31;
   hostName = "nextcloud.${config.services.nginx.domain}";
 in
 {
@@ -19,10 +19,10 @@ in
           packageOverrides = _: prev: {
             extensions = prev.extensions // {
               pgsql = prev.extensions.pgsql.overrideAttrs (_: {
-                configureFlags = [ "--with-pgsql=${lib.getDev config.services.postgresql.package}" ];
+                configureFlags = [ "--with-pgsql=${lib.getDev config.services.postgresql.package.pg_config}" ];
               });
               pdo_pgsql = prev.extensions.pdo_pgsql.overrideAttrs (_: {
-                configureFlags = [ "--with-pdo-pgsql=${lib.getDev config.services.postgresql.package}" ];
+                configureFlags = [ "--with-pdo-pgsql=${lib.getDev config.services.postgresql.package.pg_config}" ];
               });
             };
           };
diff --git a/flake.nix b/flake.nix
index 90716e5..da8455f 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,12 +2,7 @@
   description = "tlater.net host configuration";
 
   inputs = {
-    nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11-small";
-    nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable-small";
-    continuwuity = {
-      url = "git+https://forgejo.ellis.link/continuwuation/continuwuity.git?ref=refs/tags/v0.5.0-rc.5";
-      inputs.nixpkgs.follows = "nixpkgs";
-    };
+    nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05-small";
     disko = {
       url = "github:nix-community/disko";
       inputs.nixpkgs.follows = "nixpkgs";
diff --git a/modules/crowdsec/default.nix b/modules/crowdsec/default.nix
index ac93c4a..44e6bc5 100644
--- a/modules/crowdsec/default.nix
+++ b/modules/crowdsec/default.nix
@@ -247,10 +247,7 @@ in
             online_client = {
               # By default, we don't let crowdsec phone home, since
               # this is usually within NixOS users' concerns.
-              #
-              # TODO: Enable when this option becomes available
-              # (1.6.4, current nixpkgs-unstable)
-              # sharing = lib.mkDefault false;
+              sharing = lib.mkDefault false;
               credentials_path = cfg.centralApiCredentials;
             };
           };

From f2cbeebbb5c9634e9b82a3bb672b3dbbb15739fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sat, 24 May 2025 18:28:51 +0800
Subject: [PATCH 211/212] flake.lock: Update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/ec7c109a4f794fce09aad87239eab7f66540b888' (2025-05-15)
  → 'github:nix-community/disko/df522e787fdffc4f32ed3e1fca9ed0968a384d62' (2025-05-20)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/b965e4c283060415956ccd39eee4ca34a6a56cf8' (2025-05-16)
  → 'github:nixos/nixpkgs/c3ee76c437067f1ae09d6e530df46a3f80977992' (2025-05-24)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/e93ee1d900ad264d65e9701a5c6f895683433386' (2025-05-05)
  → 'github:Mic92/sops-nix/8d215e1c981be3aa37e47aeabd4e61bb069548fd' (2025-05-18)
---
 flake.lock | 932 ++++++++---------------------------------------------
 1 file changed, 134 insertions(+), 798 deletions(-)

diff --git a/flake.lock b/flake.lock
index c17c613..885b579 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1,86 +1,6 @@
 {
   "nodes": {
-    "attic": {
-      "inputs": {
-        "crane": "crane",
-        "flake-compat": "flake-compat",
-        "flake-parts": "flake-parts",
-        "nix-github-actions": "nix-github-actions",
-        "nixpkgs": "nixpkgs",
-        "nixpkgs-stable": "nixpkgs-stable"
-      },
-      "locked": {
-        "lastModified": 1738524606,
-        "narHash": "sha256-hPYEJ4juK3ph7kbjbvv7PlU1D9pAkkhl+pwx8fZY53U=",
-        "owner": "zhaofengli",
-        "repo": "attic",
-        "rev": "ff8a897d1f4408ebbf4d45fa9049c06b3e1e3f4e",
-        "type": "github"
-      },
-      "original": {
-        "owner": "zhaofengli",
-        "ref": "main",
-        "repo": "attic",
-        "type": "github"
-      }
-    },
     "cachix": {
-      "inputs": {
-        "devenv": "devenv",
-        "flake-compat": "flake-compat_2",
-        "git-hooks": "git-hooks",
-        "nixpkgs": "nixpkgs_4"
-      },
-      "locked": {
-        "lastModified": 1737621947,
-        "narHash": "sha256-8HFvG7fvIFbgtaYAY2628Tb89fA55nPm2jSiNs0/Cws=",
-        "owner": "cachix",
-        "repo": "cachix",
-        "rev": "f65a3cd5e339c223471e64c051434616e18cc4f5",
-        "type": "github"
-      },
-      "original": {
-        "owner": "cachix",
-        "ref": "master",
-        "repo": "cachix",
-        "type": "github"
-      }
-    },
-    "cachix_2": {
-      "inputs": {
-        "devenv": [
-          "continuwuity",
-          "cachix",
-          "devenv"
-        ],
-        "flake-compat": [
-          "continuwuity",
-          "cachix",
-          "devenv"
-        ],
-        "git-hooks": [
-          "continuwuity",
-          "cachix",
-          "devenv"
-        ],
-        "nixpkgs": "nixpkgs_2"
-      },
-      "locked": {
-        "lastModified": 1728672398,
-        "narHash": "sha256-KxuGSoVUFnQLB2ZcYODW7AVPAh9JqRlD5BrfsC/Q4qs=",
-        "owner": "cachix",
-        "repo": "cachix",
-        "rev": "aac51f698309fd0f381149214b7eee213c66ef0a",
-        "type": "github"
-      },
-      "original": {
-        "owner": "cachix",
-        "ref": "latest",
-        "repo": "cachix",
-        "type": "github"
-      }
-    },
-    "cachix_3": {
       "inputs": {
         "devenv": [
           "sonnenshift",
@@ -90,7 +10,7 @@
           "sonnenshift",
           "crate2nix"
         ],
-        "nixpkgs": "nixpkgs_7",
+        "nixpkgs": "nixpkgs_3",
         "pre-commit-hooks": [
           "sonnenshift",
           "crate2nix"
@@ -111,7 +31,7 @@
         "type": "github"
       }
     },
-    "cachix_4": {
+    "cachix_2": {
       "inputs": {
         "devenv": [
           "sonnenshift",
@@ -123,7 +43,7 @@
           "crate2nix",
           "crate2nix_stable"
         ],
-        "nixpkgs": "nixpkgs_8",
+        "nixpkgs": "nixpkgs_4",
         "pre-commit-hooks": [
           "sonnenshift",
           "crate2nix",
@@ -145,7 +65,7 @@
         "type": "github"
       }
     },
-    "cachix_5": {
+    "cachix_3": {
       "inputs": {
         "devenv": [
           "sonnenshift",
@@ -159,7 +79,7 @@
           "crate2nix_stable",
           "crate2nix_stable"
         ],
-        "nixpkgs": "nixpkgs_9",
+        "nixpkgs": "nixpkgs_5",
         "pre-commit-hooks": [
           "sonnenshift",
           "crate2nix",
@@ -182,99 +102,13 @@
         "type": "github"
       }
     },
-    "complement": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1741891349,
-        "narHash": "sha256-YvrzOWcX7DH1drp5SGa+E/fc7wN3hqFtPbqPjZpOu1Q=",
-        "owner": "girlbossceo",
-        "repo": "complement",
-        "rev": "e587b3df569cba411aeac7c20b6366d03c143745",
-        "type": "github"
-      },
-      "original": {
-        "owner": "girlbossceo",
-        "ref": "main",
-        "repo": "complement",
-        "type": "github"
-      }
-    },
-    "continuwuity": {
-      "inputs": {
-        "attic": "attic",
-        "cachix": "cachix",
-        "complement": "complement",
-        "crane": "crane_2",
-        "fenix": "fenix",
-        "flake-compat": "flake-compat_3",
-        "flake-utils": "flake-utils",
-        "liburing": "liburing",
-        "nix-filter": "nix-filter",
-        "nixpkgs": [
-          "nixpkgs"
-        ],
-        "rocksdb": "rocksdb"
-      },
-      "locked": {
-        "lastModified": 1745186840,
-        "narHash": "sha256-Oq2scBu3Ewao828BT1QGffqIqF5WoH9HMXEXKg1YU0o=",
-        "ref": "refs/tags/v0.5.0-rc.5",
-        "rev": "0a0f327ae034f5c44b12a3154cc1143aff10291c",
-        "revCount": 5147,
-        "type": "git",
-        "url": "https://forgejo.ellis.link/continuwuation/continuwuity.git"
-      },
-      "original": {
-        "ref": "refs/tags/v0.5.0-rc.5",
-        "type": "git",
-        "url": "https://forgejo.ellis.link/continuwuation/continuwuity.git"
-      }
-    },
-    "crane": {
-      "inputs": {
-        "nixpkgs": [
-          "continuwuity",
-          "attic",
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1722960479,
-        "narHash": "sha256-NhCkJJQhD5GUib8zN9JrmYGMwt4lCRp6ZVNzIiYCl0Y=",
-        "owner": "ipetkov",
-        "repo": "crane",
-        "rev": "4c6c77920b8d44cd6660c1621dea6b3fc4b4c4f4",
-        "type": "github"
-      },
-      "original": {
-        "owner": "ipetkov",
-        "repo": "crane",
-        "type": "github"
-      }
-    },
-    "crane_2": {
-      "locked": {
-        "lastModified": 1739936662,
-        "narHash": "sha256-x4syUjNUuRblR07nDPeLDP7DpphaBVbUaSoeZkFbGSk=",
-        "owner": "ipetkov",
-        "repo": "crane",
-        "rev": "19de14aaeb869287647d9461cbd389187d8ecdb7",
-        "type": "github"
-      },
-      "original": {
-        "owner": "ipetkov",
-        "ref": "master",
-        "repo": "crane",
-        "type": "github"
-      }
-    },
     "crate2nix": {
       "inputs": {
-        "cachix": "cachix_3",
+        "cachix": "cachix",
         "crate2nix_stable": "crate2nix_stable",
         "devshell": "devshell_3",
-        "flake-compat": "flake-compat_7",
-        "flake-parts": "flake-parts_5",
+        "flake-compat": "flake-compat_4",
+        "flake-parts": "flake-parts_3",
         "nix-test-runner": "nix-test-runner_3",
         "nixpkgs": [
           "sonnenshift",
@@ -298,13 +132,13 @@
     },
     "crate2nix_stable": {
       "inputs": {
-        "cachix": "cachix_4",
+        "cachix": "cachix_2",
         "crate2nix_stable": "crate2nix_stable_2",
         "devshell": "devshell_2",
-        "flake-compat": "flake-compat_6",
-        "flake-parts": "flake-parts_4",
+        "flake-compat": "flake-compat_3",
+        "flake-parts": "flake-parts_2",
         "nix-test-runner": "nix-test-runner_2",
-        "nixpkgs": "nixpkgs_11",
+        "nixpkgs": "nixpkgs_7",
         "pre-commit-hooks": "pre-commit-hooks_2"
       },
       "locked": {
@@ -324,13 +158,13 @@
     },
     "crate2nix_stable_2": {
       "inputs": {
-        "cachix": "cachix_5",
+        "cachix": "cachix_3",
         "crate2nix_stable": "crate2nix_stable_3",
         "devshell": "devshell",
-        "flake-compat": "flake-compat_5",
-        "flake-parts": "flake-parts_3",
+        "flake-compat": "flake-compat_2",
+        "flake-parts": "flake-parts",
         "nix-test-runner": "nix-test-runner",
-        "nixpkgs": "nixpkgs_10",
+        "nixpkgs": "nixpkgs_6",
         "pre-commit-hooks": "pre-commit-hooks"
       },
       "locked": {
@@ -350,7 +184,7 @@
     },
     "crate2nix_stable_3": {
       "inputs": {
-        "flake-utils": "flake-utils_2"
+        "flake-utils": "flake-utils"
       },
       "locked": {
         "lastModified": 1702842982,
@@ -369,8 +203,8 @@
     },
     "deploy-rs": {
       "inputs": {
-        "flake-compat": "flake-compat_4",
-        "nixpkgs": "nixpkgs_5",
+        "flake-compat": "flake-compat",
+        "nixpkgs": "nixpkgs",
         "utils": "utils"
       },
       "locked": {
@@ -387,43 +221,9 @@
         "type": "github"
       }
     },
-    "devenv": {
-      "inputs": {
-        "cachix": "cachix_2",
-        "flake-compat": [
-          "continuwuity",
-          "cachix",
-          "flake-compat"
-        ],
-        "git-hooks": [
-          "continuwuity",
-          "cachix",
-          "git-hooks"
-        ],
-        "nix": "nix",
-        "nixpkgs": [
-          "continuwuity",
-          "cachix",
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1733323168,
-        "narHash": "sha256-d5DwB4MZvlaQpN6OQ4SLYxb5jA4UH5EtV5t5WOtjLPU=",
-        "owner": "cachix",
-        "repo": "devenv",
-        "rev": "efa9010b8b1cfd5dd3c7ed1e172a470c3b84a064",
-        "type": "github"
-      },
-      "original": {
-        "owner": "cachix",
-        "repo": "devenv",
-        "type": "github"
-      }
-    },
     "devshell": {
       "inputs": {
-        "flake-utils": "flake-utils_3",
+        "flake-utils": "flake-utils_2",
         "nixpkgs": [
           "sonnenshift",
           "crate2nix",
@@ -448,7 +248,7 @@
     },
     "devshell_2": {
       "inputs": {
-        "flake-utils": "flake-utils_4",
+        "flake-utils": "flake-utils_3",
         "nixpkgs": [
           "sonnenshift",
           "crate2nix",
@@ -472,7 +272,7 @@
     },
     "devshell_3": {
       "inputs": {
-        "flake-utils": "flake-utils_5",
+        "flake-utils": "flake-utils_4",
         "nixpkgs": [
           "sonnenshift",
           "crate2nix",
@@ -500,11 +300,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1747274630,
-        "narHash": "sha256-87RJwXbfOHyzTB9LYagAQ6vOZhszCvd8Gvudu+gf3qo=",
+        "lastModified": 1747742835,
+        "narHash": "sha256-kYL4GCwwznsypvsnA20oyvW8zB/Dvn6K5G/tgMjVMT4=",
         "owner": "nix-community",
         "repo": "disko",
-        "rev": "ec7c109a4f794fce09aad87239eab7f66540b888",
+        "rev": "df522e787fdffc4f32ed3e1fca9ed0968a384d62",
         "type": "github"
       },
       "original": {
@@ -515,7 +315,7 @@
     },
     "dream2nix": {
       "inputs": {
-        "nixpkgs": "nixpkgs_12",
+        "nixpkgs": "nixpkgs_8",
         "purescript-overlay": "purescript-overlay",
         "pyproject-nix": "pyproject-nix"
       },
@@ -534,35 +334,12 @@
       }
     },
     "fenix": {
-      "inputs": {
-        "nixpkgs": [
-          "continuwuity",
-          "nixpkgs"
-        ],
-        "rust-analyzer-src": "rust-analyzer-src"
-      },
-      "locked": {
-        "lastModified": 1740724364,
-        "narHash": "sha256-D1jLIueJx1dPrP09ZZwTrPf4cubV+TsFMYbpYYTVj6A=",
-        "owner": "nix-community",
-        "repo": "fenix",
-        "rev": "edf7d9e431cda8782e729253835f178a356d3aab",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nix-community",
-        "ref": "main",
-        "repo": "fenix",
-        "type": "github"
-      }
-    },
-    "fenix_2": {
       "inputs": {
         "nixpkgs": [
           "tlaternet-webserver",
           "nixpkgs"
         ],
-        "rust-analyzer-src": "rust-analyzer-src_2"
+        "rust-analyzer-src": "rust-analyzer-src"
       },
       "locked": {
         "lastModified": 1737181903,
@@ -595,97 +372,48 @@
       }
     },
     "flake-compat_2": {
-      "flake": false,
       "locked": {
-        "lastModified": 1733328505,
-        "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
-        "owner": "edolstra",
-        "repo": "flake-compat",
-        "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
-        "type": "github"
+        "lastModified": 1696426674,
+        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
+        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
+        "revCount": 57,
+        "type": "tarball",
+        "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
       },
       "original": {
-        "owner": "edolstra",
-        "repo": "flake-compat",
-        "type": "github"
+        "type": "tarball",
+        "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
       }
     },
     "flake-compat_3": {
-      "flake": false,
       "locked": {
-        "lastModified": 1733328505,
-        "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
-        "owner": "edolstra",
-        "repo": "flake-compat",
-        "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
-        "type": "github"
+        "lastModified": 1696426674,
+        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
+        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
+        "revCount": 57,
+        "type": "tarball",
+        "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
       },
       "original": {
-        "owner": "edolstra",
-        "ref": "master",
-        "repo": "flake-compat",
-        "type": "github"
+        "type": "tarball",
+        "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
       }
     },
     "flake-compat_4": {
-      "flake": false,
       "locked": {
         "lastModified": 1696426674,
         "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
-        "owner": "edolstra",
-        "repo": "flake-compat",
         "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
-        "type": "github"
+        "revCount": 57,
+        "type": "tarball",
+        "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
       },
       "original": {
-        "owner": "edolstra",
-        "repo": "flake-compat",
-        "type": "github"
+        "type": "tarball",
+        "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
       }
     },
     "flake-compat_5": {
-      "locked": {
-        "lastModified": 1696426674,
-        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
-        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
-        "revCount": 57,
-        "type": "tarball",
-        "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
-      },
-      "original": {
-        "type": "tarball",
-        "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
-      }
-    },
-    "flake-compat_6": {
-      "locked": {
-        "lastModified": 1696426674,
-        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
-        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
-        "revCount": 57,
-        "type": "tarball",
-        "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
-      },
-      "original": {
-        "type": "tarball",
-        "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
-      }
-    },
-    "flake-compat_7": {
-      "locked": {
-        "lastModified": 1696426674,
-        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
-        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
-        "revCount": 57,
-        "type": "tarball",
-        "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
-      },
-      "original": {
-        "type": "tarball",
-        "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
-      }
-    },
-    "flake-compat_8": {
       "flake": false,
       "locked": {
         "lastModified": 1696426674,
@@ -704,17 +432,19 @@
     "flake-parts": {
       "inputs": {
         "nixpkgs-lib": [
-          "continuwuity",
-          "attic",
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
+          "crate2nix_stable",
           "nixpkgs"
         ]
       },
       "locked": {
-        "lastModified": 1722555600,
-        "narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=",
+        "lastModified": 1719745305,
+        "narHash": "sha256-xwgjVUpqSviudEkpQnioeez1Uo2wzrsMaJKJClh+Bls=",
         "owner": "hercules-ci",
         "repo": "flake-parts",
-        "rev": "8471fe90ad337a8074e957b69ca4d0089218391d",
+        "rev": "c3c5ecc05edc7dafba779c6c1a61cd08ac6583e9",
         "type": "github"
       },
       "original": {
@@ -726,19 +456,18 @@
     "flake-parts_2": {
       "inputs": {
         "nixpkgs-lib": [
-          "continuwuity",
-          "cachix",
-          "devenv",
-          "nix",
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
           "nixpkgs"
         ]
       },
       "locked": {
-        "lastModified": 1712014858,
-        "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
+        "lastModified": 1719745305,
+        "narHash": "sha256-xwgjVUpqSviudEkpQnioeez1Uo2wzrsMaJKJClh+Bls=",
         "owner": "hercules-ci",
         "repo": "flake-parts",
-        "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
+        "rev": "c3c5ecc05edc7dafba779c6c1a61cd08ac6583e9",
         "type": "github"
       },
       "original": {
@@ -748,53 +477,6 @@
       }
     },
     "flake-parts_3": {
-      "inputs": {
-        "nixpkgs-lib": [
-          "sonnenshift",
-          "crate2nix",
-          "crate2nix_stable",
-          "crate2nix_stable",
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1719745305,
-        "narHash": "sha256-xwgjVUpqSviudEkpQnioeez1Uo2wzrsMaJKJClh+Bls=",
-        "owner": "hercules-ci",
-        "repo": "flake-parts",
-        "rev": "c3c5ecc05edc7dafba779c6c1a61cd08ac6583e9",
-        "type": "github"
-      },
-      "original": {
-        "owner": "hercules-ci",
-        "repo": "flake-parts",
-        "type": "github"
-      }
-    },
-    "flake-parts_4": {
-      "inputs": {
-        "nixpkgs-lib": [
-          "sonnenshift",
-          "crate2nix",
-          "crate2nix_stable",
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1719745305,
-        "narHash": "sha256-xwgjVUpqSviudEkpQnioeez1Uo2wzrsMaJKJClh+Bls=",
-        "owner": "hercules-ci",
-        "repo": "flake-parts",
-        "rev": "c3c5ecc05edc7dafba779c6c1a61cd08ac6583e9",
-        "type": "github"
-      },
-      "original": {
-        "owner": "hercules-ci",
-        "repo": "flake-parts",
-        "type": "github"
-      }
-    },
-    "flake-parts_5": {
       "inputs": {
         "nixpkgs-lib": [
           "sonnenshift",
@@ -818,19 +500,18 @@
     },
     "flake-utils": {
       "inputs": {
-        "systems": "systems"
+        "systems": "systems_2"
       },
       "locked": {
-        "lastModified": 1731533236,
-        "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
+        "lastModified": 1694529238,
+        "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
+        "rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
         "type": "github"
       },
       "original": {
         "owner": "numtide",
-        "ref": "main",
         "repo": "flake-utils",
         "type": "github"
       }
@@ -840,11 +521,11 @@
         "systems": "systems_3"
       },
       "locked": {
-        "lastModified": 1694529238,
-        "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
+        "lastModified": 1701680307,
+        "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
+        "rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
         "type": "github"
       },
       "original": {
@@ -893,24 +574,6 @@
       "inputs": {
         "systems": "systems_6"
       },
-      "locked": {
-        "lastModified": 1701680307,
-        "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
-        "type": "github"
-      },
-      "original": {
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "type": "github"
-      }
-    },
-    "flake-utils_6": {
-      "inputs": {
-        "systems": "systems_7"
-      },
       "locked": {
         "lastModified": 1710146030,
         "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
@@ -945,41 +608,14 @@
         "type": "github"
       }
     },
-    "git-hooks": {
-      "inputs": {
-        "flake-compat": [
-          "continuwuity",
-          "cachix",
-          "flake-compat"
-        ],
-        "gitignore": "gitignore",
-        "nixpkgs": [
-          "continuwuity",
-          "cachix",
-          "nixpkgs"
-        ],
-        "nixpkgs-stable": "nixpkgs-stable_2"
-      },
-      "locked": {
-        "lastModified": 1733318908,
-        "narHash": "sha256-SVQVsbafSM1dJ4fpgyBqLZ+Lft+jcQuMtEL3lQWx2Sk=",
-        "owner": "cachix",
-        "repo": "git-hooks.nix",
-        "rev": "6f4e2a2112050951a314d2733a994fbab94864c6",
-        "type": "github"
-      },
-      "original": {
-        "owner": "cachix",
-        "repo": "git-hooks.nix",
-        "type": "github"
-      }
-    },
     "gitignore": {
       "inputs": {
         "nixpkgs": [
-          "continuwuity",
-          "cachix",
-          "git-hooks",
+          "sonnenshift",
+          "crate2nix",
+          "crate2nix_stable",
+          "crate2nix_stable",
+          "pre-commit-hooks",
           "nixpkgs"
         ]
       },
@@ -1003,7 +639,6 @@
           "sonnenshift",
           "crate2nix",
           "crate2nix_stable",
-          "crate2nix_stable",
           "pre-commit-hooks",
           "nixpkgs"
         ]
@@ -1027,7 +662,6 @@
         "nixpkgs": [
           "sonnenshift",
           "crate2nix",
-          "crate2nix_stable",
           "pre-commit-hooks",
           "nixpkgs"
         ]
@@ -1046,141 +680,6 @@
         "type": "github"
       }
     },
-    "gitignore_4": {
-      "inputs": {
-        "nixpkgs": [
-          "sonnenshift",
-          "crate2nix",
-          "pre-commit-hooks",
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1709087332,
-        "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
-        "owner": "hercules-ci",
-        "repo": "gitignore.nix",
-        "rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
-        "type": "github"
-      },
-      "original": {
-        "owner": "hercules-ci",
-        "repo": "gitignore.nix",
-        "type": "github"
-      }
-    },
-    "libgit2": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1697646580,
-        "narHash": "sha256-oX4Z3S9WtJlwvj0uH9HlYcWv+x1hqp8mhXl7HsLu2f0=",
-        "owner": "libgit2",
-        "repo": "libgit2",
-        "rev": "45fd9ed7ae1a9b74b957ef4f337bc3c8b3df01b5",
-        "type": "github"
-      },
-      "original": {
-        "owner": "libgit2",
-        "repo": "libgit2",
-        "type": "github"
-      }
-    },
-    "liburing": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1740613216,
-        "narHash": "sha256-NpPOBqNND3Qe9IwqYs0mJLGTmIx7e6FgUEBAnJ+1ZLA=",
-        "owner": "axboe",
-        "repo": "liburing",
-        "rev": "e1003e496e66f9b0ae06674869795edf772d5500",
-        "type": "github"
-      },
-      "original": {
-        "owner": "axboe",
-        "ref": "master",
-        "repo": "liburing",
-        "type": "github"
-      }
-    },
-    "nix": {
-      "inputs": {
-        "flake-compat": [
-          "continuwuity",
-          "cachix",
-          "devenv"
-        ],
-        "flake-parts": "flake-parts_2",
-        "libgit2": "libgit2",
-        "nixpkgs": "nixpkgs_3",
-        "nixpkgs-23-11": [
-          "continuwuity",
-          "cachix",
-          "devenv"
-        ],
-        "nixpkgs-regression": [
-          "continuwuity",
-          "cachix",
-          "devenv"
-        ],
-        "pre-commit-hooks": [
-          "continuwuity",
-          "cachix",
-          "devenv"
-        ]
-      },
-      "locked": {
-        "lastModified": 1727438425,
-        "narHash": "sha256-X8ES7I1cfNhR9oKp06F6ir4Np70WGZU5sfCOuNBEwMg=",
-        "owner": "domenkozar",
-        "repo": "nix",
-        "rev": "f6c5ae4c1b2e411e6b1e6a8181cc84363d6a7546",
-        "type": "github"
-      },
-      "original": {
-        "owner": "domenkozar",
-        "ref": "devenv-2.24",
-        "repo": "nix",
-        "type": "github"
-      }
-    },
-    "nix-filter": {
-      "locked": {
-        "lastModified": 1731533336,
-        "narHash": "sha256-oRam5PS1vcrr5UPgALW0eo1m/5/pls27Z/pabHNy2Ms=",
-        "owner": "numtide",
-        "repo": "nix-filter",
-        "rev": "f7653272fd234696ae94229839a99b73c9ab7de0",
-        "type": "github"
-      },
-      "original": {
-        "owner": "numtide",
-        "ref": "main",
-        "repo": "nix-filter",
-        "type": "github"
-      }
-    },
-    "nix-github-actions": {
-      "inputs": {
-        "nixpkgs": [
-          "continuwuity",
-          "attic",
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1729742964,
-        "narHash": "sha256-B4mzTcQ0FZHdpeWcpDYPERtyjJd/NIuaQ9+BV1h+MpA=",
-        "owner": "nix-community",
-        "repo": "nix-github-actions",
-        "rev": "e04df33f62cdcf93d73e9a04142464753a16db67",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nix-community",
-        "repo": "nix-github-actions",
-        "type": "github"
-      }
-    },
     "nix-test-runner": {
       "flake": false,
       "locked": {
@@ -1230,160 +729,6 @@
       }
     },
     "nixpkgs": {
-      "locked": {
-        "lastModified": 1726042813,
-        "narHash": "sha256-LnNKCCxnwgF+575y0pxUdlGZBO/ru1CtGHIqQVfvjlA=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "159be5db480d1df880a0135ca0bfed84c2f88353",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "nixpkgs-unstable",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
-    "nixpkgs-stable": {
-      "locked": {
-        "lastModified": 1724316499,
-        "narHash": "sha256-Qb9MhKBUTCfWg/wqqaxt89Xfi6qTD3XpTzQ9eXi3JmE=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "797f7dc49e0bc7fab4b57c021cdf68f595e47841",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "nixos-24.05",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
-    "nixpkgs-stable_2": {
-      "locked": {
-        "lastModified": 1730741070,
-        "narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "d063c1dd113c91ab27959ba540c0d9753409edf3",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "nixos-24.05",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
-    "nixpkgs-unstable": {
-      "locked": {
-        "lastModified": 1747413287,
-        "narHash": "sha256-hOnqJr0tZBERWa29JWf9B3/8qr82mlt/UlKPvS7iYzA=",
-        "owner": "nixos",
-        "repo": "nixpkgs",
-        "rev": "b965e4c283060415956ccd39eee4ca34a6a56cf8",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nixos",
-        "ref": "nixos-unstable-small",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
-    "nixpkgs_10": {
-      "locked": {
-        "lastModified": 1719506693,
-        "narHash": "sha256-C8e9S7RzshSdHB7L+v9I51af1gDM5unhJ2xO1ywxNH8=",
-        "path": "/nix/store/4p0avw1s3vf27hspgqsrqs37gxk4i83i-source",
-        "rev": "b2852eb9365c6de48ffb0dc2c9562591f652242a",
-        "type": "path"
-      },
-      "original": {
-        "id": "nixpkgs",
-        "type": "indirect"
-      }
-    },
-    "nixpkgs_11": {
-      "locked": {
-        "lastModified": 1719506693,
-        "narHash": "sha256-C8e9S7RzshSdHB7L+v9I51af1gDM5unhJ2xO1ywxNH8=",
-        "path": "/nix/store/4p0avw1s3vf27hspgqsrqs37gxk4i83i-source",
-        "rev": "b2852eb9365c6de48ffb0dc2c9562591f652242a",
-        "type": "path"
-      },
-      "original": {
-        "id": "nixpkgs",
-        "type": "indirect"
-      }
-    },
-    "nixpkgs_12": {
-      "locked": {
-        "lastModified": 1729850857,
-        "narHash": "sha256-WvLXzNNnnw+qpFOmgaM3JUlNEH+T4s22b5i2oyyCpXE=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "41dea55321e5a999b17033296ac05fe8a8b5a257",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "nixpkgs-unstable",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
-    "nixpkgs_2": {
-      "locked": {
-        "lastModified": 1730531603,
-        "narHash": "sha256-Dqg6si5CqIzm87sp57j5nTaeBbWhHFaVyG7V6L8k3lY=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "7ffd9ae656aec493492b44d0ddfb28e79a1ea25d",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "nixos-unstable",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
-    "nixpkgs_3": {
-      "locked": {
-        "lastModified": 1717432640,
-        "narHash": "sha256-+f9c4/ZX5MWDOuB1rKoWj+lBNm0z0rs4CK47HBLxy1o=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "88269ab3044128b7c2f4c7d68448b2fb50456870",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "release-24.05",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
-    "nixpkgs_4": {
-      "locked": {
-        "lastModified": 1733212471,
-        "narHash": "sha256-M1+uCoV5igihRfcUKrr1riygbe73/dzNnzPsmaLCmpo=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "55d15ad12a74eb7d4646254e13638ad0c4128776",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "nixos-unstable",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
-    "nixpkgs_5": {
       "locked": {
         "lastModified": 1702272962,
         "narHash": "sha256-D+zHwkwPc6oYQ4G3A1HuadopqRwUY/JkMwHz1YF7j4Q=",
@@ -1399,23 +744,23 @@
         "type": "github"
       }
     },
-    "nixpkgs_6": {
+    "nixpkgs_2": {
       "locked": {
-        "lastModified": 1747418223,
-        "narHash": "sha256-DkCYFm09AR2+FPKcT7lD8iIMNXqTdesVvwKpCnqKiYg=",
+        "lastModified": 1748085680,
+        "narHash": "sha256-XG90Q/040NiV70gAVvoYbXg1lULbiwIzfkWmwSINyGQ=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "d6c9326e40bb557ebb8c040b4375590bc06413f8",
+        "rev": "4e6eeca5ed45465087274fc9dc6bc2011254a0f3",
         "type": "github"
       },
       "original": {
         "owner": "nixos",
-        "ref": "nixos-24.11-small",
+        "ref": "nixos-25.05-small",
         "repo": "nixpkgs",
         "type": "github"
       }
     },
-    "nixpkgs_7": {
+    "nixpkgs_3": {
       "locked": {
         "lastModified": 1700612854,
         "narHash": "sha256-yrQ8osMD+vDLGFX7pcwsY/Qr5PUd6OmDMYJZzZi0+zc=",
@@ -1431,7 +776,7 @@
         "type": "github"
       }
     },
-    "nixpkgs_8": {
+    "nixpkgs_4": {
       "locked": {
         "lastModified": 1715534503,
         "narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=",
@@ -1447,7 +792,7 @@
         "type": "github"
       }
     },
-    "nixpkgs_9": {
+    "nixpkgs_5": {
       "locked": {
         "lastModified": 1715534503,
         "narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=",
@@ -1463,6 +808,48 @@
         "type": "github"
       }
     },
+    "nixpkgs_6": {
+      "locked": {
+        "lastModified": 1719506693,
+        "narHash": "sha256-C8e9S7RzshSdHB7L+v9I51af1gDM5unhJ2xO1ywxNH8=",
+        "path": "/nix/store/4p0avw1s3vf27hspgqsrqs37gxk4i83i-source",
+        "rev": "b2852eb9365c6de48ffb0dc2c9562591f652242a",
+        "type": "path"
+      },
+      "original": {
+        "id": "nixpkgs",
+        "type": "indirect"
+      }
+    },
+    "nixpkgs_7": {
+      "locked": {
+        "lastModified": 1719506693,
+        "narHash": "sha256-C8e9S7RzshSdHB7L+v9I51af1gDM5unhJ2xO1ywxNH8=",
+        "path": "/nix/store/4p0avw1s3vf27hspgqsrqs37gxk4i83i-source",
+        "rev": "b2852eb9365c6de48ffb0dc2c9562591f652242a",
+        "type": "path"
+      },
+      "original": {
+        "id": "nixpkgs",
+        "type": "indirect"
+      }
+    },
+    "nixpkgs_8": {
+      "locked": {
+        "lastModified": 1729850857,
+        "narHash": "sha256-WvLXzNNnnw+qpFOmgaM3JUlNEH+T4s22b5i2oyyCpXE=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "41dea55321e5a999b17033296ac05fe8a8b5a257",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixpkgs-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
     "pre-commit-hooks": {
       "inputs": {
         "flake-compat": [
@@ -1472,7 +859,7 @@
           "crate2nix_stable",
           "flake-compat"
         ],
-        "gitignore": "gitignore_2",
+        "gitignore": "gitignore",
         "nixpkgs": [
           "sonnenshift",
           "crate2nix",
@@ -1510,7 +897,7 @@
           "crate2nix_stable",
           "flake-compat"
         ],
-        "gitignore": "gitignore_3",
+        "gitignore": "gitignore_2",
         "nixpkgs": [
           "sonnenshift",
           "crate2nix",
@@ -1545,8 +932,8 @@
           "crate2nix",
           "flake-compat"
         ],
-        "flake-utils": "flake-utils_6",
-        "gitignore": "gitignore_4",
+        "flake-utils": "flake-utils_5",
+        "gitignore": "gitignore_3",
         "nixpkgs": [
           "sonnenshift",
           "crate2nix",
@@ -1574,7 +961,7 @@
     },
     "purescript-overlay": {
       "inputs": {
-        "flake-compat": "flake-compat_8",
+        "flake-compat": "flake-compat_5",
         "nixpkgs": [
           "tlaternet-webserver",
           "dream2nix",
@@ -1613,54 +1000,18 @@
         "type": "github"
       }
     },
-    "rocksdb": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1741308171,
-        "narHash": "sha256-YdBvdQ75UJg5ffwNjxizpviCVwVDJnBkM8ZtGIduMgY=",
-        "owner": "girlbossceo",
-        "repo": "rocksdb",
-        "rev": "3ce04794bcfbbb0d2e6f81ae35fc4acf688b6986",
-        "type": "github"
-      },
-      "original": {
-        "owner": "girlbossceo",
-        "ref": "v9.11.1",
-        "repo": "rocksdb",
-        "type": "github"
-      }
-    },
     "root": {
       "inputs": {
-        "continuwuity": "continuwuity",
         "deploy-rs": "deploy-rs",
         "disko": "disko",
         "foundryvtt": "foundryvtt",
-        "nixpkgs": "nixpkgs_6",
-        "nixpkgs-unstable": "nixpkgs-unstable",
+        "nixpkgs": "nixpkgs_2",
         "sonnenshift": "sonnenshift",
         "sops-nix": "sops-nix",
         "tlaternet-webserver": "tlaternet-webserver"
       }
     },
     "rust-analyzer-src": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1740691488,
-        "narHash": "sha256-Fs6vBrByuiOf2WO77qeMDMTXcTGzrIMqLBv+lNeywwM=",
-        "owner": "rust-lang",
-        "repo": "rust-analyzer",
-        "rev": "fe3eda77d3a7ce212388bda7b6cec8bffcc077e5",
-        "type": "github"
-      },
-      "original": {
-        "owner": "rust-lang",
-        "ref": "nightly",
-        "repo": "rust-analyzer",
-        "type": "github"
-      }
-    },
-    "rust-analyzer-src_2": {
       "flake": false,
       "locked": {
         "lastModified": 1737140097,
@@ -1728,11 +1079,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1746485181,
-        "narHash": "sha256-PxrrSFLaC7YuItShxmYbMgSuFFuwxBB+qsl9BZUnRvg=",
+        "lastModified": 1747603214,
+        "narHash": "sha256-lAblXm0VwifYCJ/ILPXJwlz0qNY07DDYdLD+9H+Wc8o=",
         "owner": "Mic92",
         "repo": "sops-nix",
-        "rev": "e93ee1d900ad264d65e9701a5c6f895683433386",
+        "rev": "8d215e1c981be3aa37e47aeabd4e61bb069548fd",
         "type": "github"
       },
       "original": {
@@ -1831,25 +1182,10 @@
         "type": "github"
       }
     },
-    "systems_7": {
-      "locked": {
-        "lastModified": 1681028828,
-        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
-        "owner": "nix-systems",
-        "repo": "default",
-        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nix-systems",
-        "repo": "default",
-        "type": "github"
-      }
-    },
     "tlaternet-webserver": {
       "inputs": {
         "dream2nix": "dream2nix",
-        "fenix": "fenix_2",
+        "fenix": "fenix",
         "nixpkgs": [
           "nixpkgs"
         ]
@@ -1870,7 +1206,7 @@
     },
     "utils": {
       "inputs": {
-        "systems": "systems_2"
+        "systems": "systems"
       },
       "locked": {
         "lastModified": 1701680307,

From 94ec261a94a844f33d5f98e5633f260449e7cf64 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Sun, 25 May 2025 02:11:31 +0800
Subject: [PATCH 212/212] chore(foundryvtt): Upgrade to version 13

---
 configuration/services/foundryvtt.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configuration/services/foundryvtt.nix b/configuration/services/foundryvtt.nix
index f25bbcd..6c475a3 100644
--- a/configuration/services/foundryvtt.nix
+++ b/configuration/services/foundryvtt.nix
@@ -18,7 +18,7 @@ in
       minifyStaticFiles = true;
       proxySSL = true;
       proxyPort = 443;
-      package = flake-inputs.foundryvtt.packages.${pkgs.system}.foundryvtt_11;
+      package = flake-inputs.foundryvtt.packages.${pkgs.system}.foundryvtt_13;
     };
 
     nginx.virtualHosts."${domain}" =