From 33c3eb5581aefd17864198bae0df27b3ad6c4bd9 Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Mon, 4 Dec 2023 16:18:12 +0100
Subject: [PATCH 01/24] Package Version Bump. Now Using Svelte 5 Preview

---
 package.json |  36 ++--
 yarn.lock    | 538 +++++++++++++++++++++++++--------------------------
 2 files changed, 286 insertions(+), 288 deletions(-)

diff --git a/package.json b/package.json
index d46a881..ca88aec 100644
--- a/package.json
+++ b/package.json
@@ -12,37 +12,37 @@
     "format": "prettier --plugin-search-dir . --write ."
   },
   "devDependencies": {
+    "@fontsource/fira-mono": "^4.5.10",
+    "@neoconfetti/svelte": "^1.0.0",
+    "@skeletonlabs/skeleton": "2.0.0",
+    "@skeletonlabs/tw-plugin": "0.1.0",
     "@sveltejs/adapter-auto": "^2.0.0",
     "@sveltejs/kit": "^1.20.4",
+    "@types/cookie": "^0.5.1",
+    "@types/node": "20.6.0",
     "@typescript-eslint/eslint-plugin": "^5.45.0",
     "@typescript-eslint/parser": "^5.45.0",
+    "autoprefixer": "10.4.15",
     "eslint": "^8.28.0",
     "eslint-config-prettier": "^8.5.0",
     "eslint-plugin-svelte": "^2.30.0",
+    "postcss": "8.4.29",
+    "postcss-load-config": "^4.0.1",
     "prettier": "^2.8.0",
     "prettier-plugin-svelte": "^2.10.1",
-    "svelte": "^4.0.5",
+    "svelte": "^5.0.0-next.17",
     "svelte-check": "^3.4.3",
+    "svelte-loading-spinners": "^0.3.4",
+    "tailwindcss": "3.3.3",
     "tslib": "^2.4.1",
     "typescript": "^5.0.0",
     "vite": "^4.4.2",
-    "postcss": "8.4.29",
-    "autoprefixer": "10.4.15",
-    "tailwindcss": "3.3.3",
-    "@skeletonlabs/skeleton": "2.0.0",
-    "@skeletonlabs/tw-plugin": "0.1.0",
-    "vite-plugin-tailwind-purgecss": "0.1.3",
-    "@types/node": "20.6.0",
-    "@fontsource/fira-mono": "^4.5.10",
-		"@neoconfetti/svelte": "^1.0.0",
-		"@types/cookie": "^0.5.1",
-		"postcss-load-config": "^4.0.1",
-		"svelte-loading-spinners": "^0.3.4"
+    "vite-plugin-tailwind-purgecss": "0.1.3"
   },
   "type": "module",
   "dependencies": {
-		"chart.js": "^4.3.3",
-		"chartjs-plugin-datalabels": "^2.2.0",
-		"svelte-chartjs": "^3.1.2"
-	}
-}
\ No newline at end of file
+    "chart.js": "^4.3.3",
+    "chartjs-plugin-datalabels": "^2.2.0",
+    "svelte-chartjs": "^3.1.2"
+  }
+}
diff --git a/yarn.lock b/yarn.lock
index 7b1bb66..e4ab8dc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -138,14 +138,14 @@
     eslint-visitor-keys "^3.3.0"
 
 "@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1":
-  version "4.8.0"
-  resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.8.0.tgz#11195513186f68d42fbf449f9a7136b2c0c92005"
-  integrity sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==
+  version "4.10.0"
+  resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63"
+  integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==
 
-"@eslint/eslintrc@^2.1.2":
-  version "2.1.2"
-  resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.2.tgz#c6936b4b328c64496692f76944e755738be62396"
-  integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==
+"@eslint/eslintrc@^2.1.4":
+  version "2.1.4"
+  resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad"
+  integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==
   dependencies:
     ajv "^6.12.4"
     debug "^4.3.2"
@@ -157,22 +157,27 @@
     minimatch "^3.1.2"
     strip-json-comments "^3.1.1"
 
-"@eslint/js@8.49.0":
-  version "8.49.0"
-  resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.49.0.tgz#86f79756004a97fa4df866835093f1df3d03c333"
-  integrity sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==
+"@eslint/js@8.55.0":
+  version "8.55.0"
+  resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.55.0.tgz#b721d52060f369aa259cf97392403cb9ce892ec6"
+  integrity sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==
+
+"@fastify/busboy@^2.0.0":
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.0.tgz#0709e9f4cb252351c609c6e6d8d6779a8d25edff"
+  integrity sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==
 
 "@fontsource/fira-mono@^4.5.10":
   version "4.5.10"
   resolved "https://registry.yarnpkg.com/@fontsource/fira-mono/-/fira-mono-4.5.10.tgz#443be4b2b4fc6e685b88431fcfdaf8d5f5639bbf"
   integrity sha512-bxUnRP8xptGRo8YXeY073DSpfK74XpSb0ZyRNpHV9WvLnJ7TwPOjZll8hTMin7zLC6iOp59pDZ8EQDj1gzgAQQ==
 
-"@humanwhocodes/config-array@^0.11.11":
-  version "0.11.11"
-  resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.11.tgz#88a04c570dbbc7dd943e4712429c3df09bc32844"
-  integrity sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==
+"@humanwhocodes/config-array@^0.11.13":
+  version "0.11.13"
+  resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297"
+  integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==
   dependencies:
-    "@humanwhocodes/object-schema" "^1.2.1"
+    "@humanwhocodes/object-schema" "^2.0.1"
     debug "^4.1.1"
     minimatch "^3.0.5"
 
@@ -181,10 +186,10 @@
   resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
   integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
 
-"@humanwhocodes/object-schema@^1.2.1":
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
-  integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
+"@humanwhocodes/object-schema@^2.0.1":
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044"
+  integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==
 
 "@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2":
   version "0.3.3"
@@ -210,10 +215,10 @@
   resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
   integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
 
-"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9":
-  version "0.3.19"
-  resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811"
-  integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==
+"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9":
+  version "0.3.20"
+  resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f"
+  integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==
   dependencies:
     "@jridgewell/resolve-uri" "^3.1.0"
     "@jridgewell/sourcemap-codec" "^1.4.14"
@@ -267,65 +272,65 @@
   integrity sha512-ufnm4FS+s/khuho4yJ/uqfW91u2YXnH3E5N541MtX9XjmoimQzYIcxWyTIuX9AM/brIPP6M6l0et3nRx17CRoQ==
 
 "@sveltejs/adapter-auto@^2.0.0":
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/@sveltejs/adapter-auto/-/adapter-auto-2.1.0.tgz#cb36fd7081e3c4b1c9a9192b1a23c8c82dce8a1b"
-  integrity sha512-o2pZCfATFtA/Gw/BB0Xm7k4EYaekXxaPGER3xGSY3FvzFJGTlJlZjBseaXwYSM94lZ0HniOjTokN3cWaLX6fow==
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/@sveltejs/adapter-auto/-/adapter-auto-2.1.1.tgz#e055c71bdb8d2923d63db089752675f70ab1a0f3"
+  integrity sha512-nzi6x/7/3Axh5VKQ8Eed3pYxastxoa06Y/bFhWb7h3Nu+nGRVxKAy3+hBJgmPCwWScy8n0TsstZjSVKfyrIHkg==
   dependencies:
-    import-meta-resolve "^3.0.0"
+    import-meta-resolve "^4.0.0"
 
 "@sveltejs/kit@^1.20.4":
-  version "1.24.1"
-  resolved "https://registry.yarnpkg.com/@sveltejs/kit/-/kit-1.24.1.tgz#ec9aa74ebde06b24db9ad629a62771fbd3b1c747"
-  integrity sha512-u2FO0q62Se9UZ0g9kXaWYi+54vTK70BKaPScOcx6jLMRou4CUZgDTNKnRhsbJgPMgaLkOH0j3o/fKlZ6jBfgSg==
+  version "1.27.6"
+  resolved "https://registry.yarnpkg.com/@sveltejs/kit/-/kit-1.27.6.tgz#2feea84413205422887e01326d979edd9a982dff"
+  integrity sha512-GsjTkMbKzXdbeRg0tk8S7HNShQ4879ftRr0ZHaZfjbig1xQwG57Bvcm9U9/mpLJtCapLbLWUnygKrgcLISLC8A==
   dependencies:
-    "@sveltejs/vite-plugin-svelte" "^2.4.1"
+    "@sveltejs/vite-plugin-svelte" "^2.5.0"
     "@types/cookie" "^0.5.1"
     cookie "^0.5.0"
     devalue "^4.3.1"
     esm-env "^1.0.0"
     kleur "^4.1.5"
     magic-string "^0.30.0"
-    mime "^3.0.0"
+    mrmime "^1.0.1"
     sade "^1.8.1"
     set-cookie-parser "^2.6.0"
     sirv "^2.0.2"
     tiny-glob "^0.2.9"
-    undici "~5.23.0"
+    undici "~5.26.2"
 
-"@sveltejs/vite-plugin-svelte-inspector@^1.0.3":
+"@sveltejs/vite-plugin-svelte-inspector@^1.0.4":
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-1.0.4.tgz#c99fcb73aaa845a3e2c0563409aeb3ee0b863add"
   integrity sha512-zjiuZ3yydBtwpF3bj0kQNV0YXe+iKE545QGZVTaylW3eAzFr+pJ/cwK8lZEaRp4JtaJXhD5DyWAV4AxLh6DgaQ==
   dependencies:
     debug "^4.3.4"
 
-"@sveltejs/vite-plugin-svelte@^2.4.1":
-  version "2.4.5"
-  resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.4.5.tgz#55ba60ce37dfa3acf76b4ec54955011a34cd49a2"
-  integrity sha512-UJKsFNwhzCVuiZd06jM/psscyNJNDwjQC+qIeb7GBJK9iWeQCcIyfcPWDvbCudfcJggY9jtxJeeaZH7uny93FQ==
+"@sveltejs/vite-plugin-svelte@^2.5.0":
+  version "2.5.3"
+  resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.5.3.tgz#23f810d0c38d159491845175c2566a51639be3fc"
+  integrity sha512-erhNtXxE5/6xGZz/M9eXsmI7Pxa6MS7jyTy06zN3Ck++ldrppOnOlJwHHTsMC7DHDQdgUp4NAc4cDNQ9eGdB/w==
   dependencies:
-    "@sveltejs/vite-plugin-svelte-inspector" "^1.0.3"
+    "@sveltejs/vite-plugin-svelte-inspector" "^1.0.4"
     debug "^4.3.4"
     deepmerge "^4.3.1"
     kleur "^4.1.5"
-    magic-string "^0.30.2"
+    magic-string "^0.30.3"
     svelte-hmr "^0.15.3"
     vitefu "^0.2.4"
 
 "@types/cookie@^0.5.1":
-  version "0.5.2"
-  resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.5.2.tgz#9bf9d62c838c85a07c92fdf2334c2c14fd9c59a9"
-  integrity sha512-DBpRoJGKJZn7RY92dPrgoMew8xCWc2P71beqsjyhEI/Ds9mOyVmBwtekyfhpwFIVt1WrxTonFifiOZ62V8CnNA==
+  version "0.5.4"
+  resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.5.4.tgz#7e70a20cd695bc48d46b08c2505874cd68b760e0"
+  integrity sha512-7z/eR6O859gyWIAjuvBWFzNURmf2oPBmJlfVWkwehU5nzIyjwBsTh7WMmEEV4JFnHuQ3ex4oyTvfKzcyJVDBNA==
 
 "@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.1":
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194"
-  integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
+  integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
 
 "@types/json-schema@^7.0.9":
-  version "7.0.12"
-  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb"
-  integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==
+  version "7.0.15"
+  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
+  integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
 
 "@types/node@20.6.0":
   version "20.6.0"
@@ -333,14 +338,14 @@
   integrity sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==
 
 "@types/pug@^2.0.6":
-  version "2.0.6"
-  resolved "https://registry.yarnpkg.com/@types/pug/-/pug-2.0.6.tgz#f830323c88172e66826d0bde413498b61054b5a6"
-  integrity sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==
+  version "2.0.10"
+  resolved "https://registry.yarnpkg.com/@types/pug/-/pug-2.0.10.tgz#52f8dbd6113517aef901db20b4f3fca543b88c1f"
+  integrity sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==
 
 "@types/semver@^7.3.12":
-  version "7.5.1"
-  resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.1.tgz#0480eeb7221eb9bc398ad7432c9d7e14b1a5a367"
-  integrity sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==
+  version "7.5.6"
+  resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339"
+  integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==
 
 "@typescript-eslint/eslint-plugin@^5.45.0":
   version "5.62.0"
@@ -426,15 +431,25 @@
     "@typescript-eslint/types" "5.62.0"
     eslint-visitor-keys "^3.3.0"
 
+"@ungap/structured-clone@^1.2.0":
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406"
+  integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==
+
 acorn-jsx@^5.3.2:
   version "5.3.2"
   resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
   integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
 
+acorn-typescript@^1.4.11:
+  version "1.4.11"
+  resolved "https://registry.yarnpkg.com/acorn-typescript/-/acorn-typescript-1.4.11.tgz#c4003ddb0e3d700e1ee41c5e843cab44a50f2a0a"
+  integrity sha512-cRGgp+4HMxMZAiMS61ZmQ3iuU/+A4g4ZYZsyLZdmvrEVN/TOwfJ40rPWcLqi3H5ut75SYAdOOJj6QGCcrkK57w==
+
 acorn@^8.10.0, acorn@^8.9.0:
-  version "8.10.0"
-  resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5"
-  integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==
+  version "8.11.2"
+  resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b"
+  integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==
 
 ajv@^6.12.4:
   version "6.12.6"
@@ -505,10 +520,10 @@ autoprefixer@10.4.15:
     picocolors "^1.0.0"
     postcss-value-parser "^4.2.0"
 
-axobject-query@^3.2.1:
-  version "3.2.1"
-  resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a"
-  integrity sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==
+axobject-query@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-4.0.0.tgz#04a4c90dce33cc5d606c76d6216e3b250ff70dab"
+  integrity sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==
   dependencies:
     dequal "^2.0.3"
 
@@ -545,27 +560,20 @@ braces@^3.0.2, braces@~3.0.2:
     fill-range "^7.0.1"
 
 browserslist@^4.21.10:
-  version "4.21.10"
-  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0"
-  integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==
+  version "4.22.2"
+  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.2.tgz#704c4943072bd81ea18997f3bd2180e89c77874b"
+  integrity sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==
   dependencies:
-    caniuse-lite "^1.0.30001517"
-    electron-to-chromium "^1.4.477"
-    node-releases "^2.0.13"
-    update-browserslist-db "^1.0.11"
+    caniuse-lite "^1.0.30001565"
+    electron-to-chromium "^1.4.601"
+    node-releases "^2.0.14"
+    update-browserslist-db "^1.0.13"
 
 buffer-crc32@^0.2.5:
   version "0.2.13"
   resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
   integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
 
-busboy@^1.6.0:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893"
-  integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==
-  dependencies:
-    streamsearch "^1.1.0"
-
 callsites@^3.0.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
@@ -576,10 +584,10 @@ camelcase-css@^2.0.1:
   resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5"
   integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
 
-caniuse-lite@^1.0.30001517, caniuse-lite@^1.0.30001520:
-  version "1.0.30001532"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001532.tgz#c6a4d5d2da6d2b967f0ee5e12e7f680db6ad2fca"
-  integrity sha512-FbDFnNat3nMnrROzqrsg314zhqN5LGQ1kyyMk2opcrwGbVGpHRhgCWtAgD5YJUqNAiQ+dklreil/c3Qf1dfCTw==
+caniuse-lite@^1.0.30001520, caniuse-lite@^1.0.30001565:
+  version "1.0.30001566"
+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz#61a8e17caf3752e3e426d4239c549ebbb37fef0d"
+  integrity sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==
 
 chalk@^4.0.0:
   version "4.1.2"
@@ -616,17 +624,6 @@ chokidar@^3.4.1, chokidar@^3.5.3:
   optionalDependencies:
     fsevents "~2.3.2"
 
-code-red@^1.0.3:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/code-red/-/code-red-1.0.4.tgz#59ba5c9d1d320a4ef795bc10a28bd42bfebe3e35"
-  integrity sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==
-  dependencies:
-    "@jridgewell/sourcemap-codec" "^1.4.15"
-    "@types/estree" "^1.0.1"
-    acorn "^8.10.0"
-    estree-walker "^3.0.3"
-    periscopic "^3.1.0"
-
 color-convert@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
@@ -668,14 +665,6 @@ cross-spawn@^7.0.2:
     shebang-command "^2.0.0"
     which "^2.0.1"
 
-css-tree@^2.3.1:
-  version "2.3.1"
-  resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20"
-  integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==
-  dependencies:
-    mdn-data "2.0.30"
-    source-map-js "^1.0.1"
-
 cssesc@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
@@ -737,10 +726,10 @@ doctrine@^3.0.0:
   dependencies:
     esutils "^2.0.2"
 
-electron-to-chromium@^1.4.477:
-  version "1.4.513"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.513.tgz#41a50bf749aa7d8058ffbf7a131fc3327a7b1675"
-  integrity sha512-cOB0xcInjm+E5qIssHeXJ29BaUyWpMyFKT5RB3bsLENDheCja0wMkHJyiPl0NBE/VzDI7JDuNEQWhe6RitEUcw==
+electron-to-chromium@^1.4.601:
+  version "1.4.601"
+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.601.tgz#cac69868548aee89961ffe63ff5a7716f0685b75"
+  integrity sha512-SpwUMDWe9tQu8JX5QCO1+p/hChAi9AE9UpoC3rcHVc+gdCGlbT3SGb5I1klgb952HRIyvt9wZhSz9bNBYz9swA==
 
 es6-promise@^3.1.2:
   version "3.3.1"
@@ -785,21 +774,27 @@ escape-string-regexp@^4.0.0:
   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
   integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
 
+eslint-compat-utils@^0.1.2:
+  version "0.1.2"
+  resolved "https://registry.yarnpkg.com/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz#f45e3b5ced4c746c127cf724fb074cd4e730d653"
+  integrity sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==
+
 eslint-config-prettier@^8.5.0:
   version "8.10.0"
   resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11"
   integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==
 
 eslint-plugin-svelte@^2.30.0:
-  version "2.33.1"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-svelte/-/eslint-plugin-svelte-2.33.1.tgz#316dd89e007483154a0d8e49b32d4cebe0c6a0c9"
-  integrity sha512-veYmyjsbt8ikXdaa6pLsgytdlzJpZZKw9vRaQlRBNKaLNmrbsdJulwiWfcDZ7tYJdaVpRB4iDFn/fuPeebxUVg==
+  version "2.35.1"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-svelte/-/eslint-plugin-svelte-2.35.1.tgz#7b1e3c263b09dbc9293c25fe02d03d309725d2b9"
+  integrity sha512-IF8TpLnROSGy98Z3NrsKXWDSCbNY2ReHDcrYTuXZMbfX7VmESISR78TWgO9zdg4Dht1X8coub5jKwHzP0ExRug==
   dependencies:
     "@eslint-community/eslint-utils" "^4.2.0"
     "@jridgewell/sourcemap-codec" "^1.4.14"
     debug "^4.3.1"
+    eslint-compat-utils "^0.1.2"
     esutils "^2.0.3"
-    known-css-properties "^0.28.0"
+    known-css-properties "^0.29.0"
     postcss "^8.4.5"
     postcss-load-config "^3.1.4"
     postcss-safe-parser "^6.0.0"
@@ -829,17 +824,18 @@ eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4
   integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
 
 eslint@^8.28.0:
-  version "8.49.0"
-  resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.49.0.tgz#09d80a89bdb4edee2efcf6964623af1054bf6d42"
-  integrity sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==
+  version "8.55.0"
+  resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.55.0.tgz#078cb7b847d66f2c254ea1794fa395bf8e7e03f8"
+  integrity sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==
   dependencies:
     "@eslint-community/eslint-utils" "^4.2.0"
     "@eslint-community/regexpp" "^4.6.1"
-    "@eslint/eslintrc" "^2.1.2"
-    "@eslint/js" "8.49.0"
-    "@humanwhocodes/config-array" "^0.11.11"
+    "@eslint/eslintrc" "^2.1.4"
+    "@eslint/js" "8.55.0"
+    "@humanwhocodes/config-array" "^0.11.13"
     "@humanwhocodes/module-importer" "^1.0.1"
     "@nodelib/fs.walk" "^1.2.8"
+    "@ungap/structured-clone" "^1.2.0"
     ajv "^6.12.4"
     chalk "^4.0.0"
     cross-spawn "^7.0.2"
@@ -892,6 +888,14 @@ esquery@^1.4.2:
   dependencies:
     estraverse "^5.1.0"
 
+esrap@^1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/esrap/-/esrap-1.2.1.tgz#8d95bc428920b82cc1084d662c2a0ace65724b0c"
+  integrity sha512-dhkcOLfN/aDdMFI1iwPEcy/XqAZzGNfgfEJjZozy2tia6u0dQoZyXzkRshHTckuNsM+c0CYQndY+uRFe3N+AIQ==
+  dependencies:
+    "@jridgewell/sourcemap-codec" "^1.4.15"
+    "@types/estree" "^1.0.1"
+
 esrecurse@^4.3.0:
   version "4.3.0"
   resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
@@ -909,7 +913,7 @@ estraverse@^5.1.0, estraverse@^5.2.0:
   resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
   integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
 
-estree-walker@^3.0.0, estree-walker@^3.0.3:
+estree-walker@^3.0.3:
   version "3.0.3"
   resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d"
   integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==
@@ -927,9 +931,9 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
   integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
 
 fast-glob@^3.2.12, fast-glob@^3.2.7, fast-glob@^3.2.9:
-  version "3.3.1"
-  resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4"
-  integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==
+  version "3.3.2"
+  resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129"
+  integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==
   dependencies:
     "@nodelib/fs.stat" "^2.0.2"
     "@nodelib/fs.walk" "^1.2.3"
@@ -977,23 +981,23 @@ find-up@^5.0.0:
     path-exists "^4.0.0"
 
 flat-cache@^3.0.4:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.1.0.tgz#0e54ab4a1a60fe87e2946b6b00657f1c99e1af3f"
-  integrity sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee"
+  integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==
   dependencies:
-    flatted "^3.2.7"
+    flatted "^3.2.9"
     keyv "^4.5.3"
     rimraf "^3.0.2"
 
-flatted@^3.2.7:
-  version "3.2.7"
-  resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787"
-  integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
+flatted@^3.2.9:
+  version "3.2.9"
+  resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf"
+  integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==
 
 fraction.js@^4.2.0:
-  version "4.3.6"
-  resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.6.tgz#e9e3acec6c9a28cf7bc36cbe35eea4ceb2c5c92d"
-  integrity sha512-n2aZ9tNfYDwaHhvFTkhFErqOMIb8uyzSQ+vGJBjZyanAKZVbGUQ1sngfk9FdkBw7G26O7AgNjLcecLffD1c7eg==
+  version "4.3.7"
+  resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
+  integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==
 
 fs.realpath@^1.0.0:
   version "1.0.0"
@@ -1005,10 +1009,10 @@ fsevents@~2.3.2:
   resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
   integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
 
-function-bind@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
-  integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
+function-bind@^1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
+  integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
 
 glob-parent@^5.1.2, glob-parent@~5.1.2:
   version "5.1.2"
@@ -1060,9 +1064,9 @@ glob@^8.0.3:
     once "^1.3.0"
 
 globals@^13.19.0:
-  version "13.21.0"
-  resolved "https://registry.yarnpkg.com/globals/-/globals-13.21.0.tgz#163aae12f34ef502f5153cfbdd3600f36c63c571"
-  integrity sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==
+  version "13.23.0"
+  resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02"
+  integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==
   dependencies:
     type-fest "^0.20.2"
 
@@ -1103,17 +1107,17 @@ has-flag@^4.0.0:
   resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
   integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
 
-has@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
-  integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
+hasown@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c"
+  integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==
   dependencies:
-    function-bind "^1.1.1"
+    function-bind "^1.1.2"
 
 ignore@^5.2.0:
-  version "5.2.4"
-  resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324"
-  integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
+  version "5.3.0"
+  resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78"
+  integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==
 
 import-fresh@^3.2.1:
   version "3.3.0"
@@ -1123,10 +1127,10 @@ import-fresh@^3.2.1:
     parent-module "^1.0.0"
     resolve-from "^4.0.0"
 
-import-meta-resolve@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/import-meta-resolve/-/import-meta-resolve-3.0.0.tgz#94a6aabc623874fbc2f3525ec1300db71c6cbc11"
-  integrity sha512-4IwhLhNNA8yy445rPjD/lWh++7hMDOml2eHtd58eG7h+qK3EryMuuRbsHGPikCoAgIkkDnckKfWSk2iDla/ejg==
+import-meta-resolve@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz#0b1195915689f60ab00f830af0f15cc841e8919e"
+  integrity sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==
 
 imurmurhash@^0.1.4:
   version "0.1.4"
@@ -1154,11 +1158,11 @@ is-binary-path@~2.1.0:
     binary-extensions "^2.0.0"
 
 is-core-module@^2.13.0:
-  version "2.13.0"
-  resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db"
-  integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==
+  version "2.13.1"
+  resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384"
+  integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==
   dependencies:
-    has "^1.0.3"
+    hasown "^2.0.0"
 
 is-extglob@^2.1.1:
   version "2.1.1"
@@ -1182,10 +1186,10 @@ is-path-inside@^3.0.3:
   resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
   integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
 
-is-reference@^3.0.0, is-reference@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-3.0.1.tgz#d400f4260f7e55733955e60d361d827eb4d3b831"
-  integrity sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w==
+is-reference@^3.0.1:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-3.0.2.tgz#154747a01f45cd962404ee89d43837af2cba247c"
+  integrity sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==
   dependencies:
     "@types/estree" "*"
 
@@ -1195,9 +1199,9 @@ isexe@^2.0.0:
   integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
 
 jiti@^1.18.2:
-  version "1.20.0"
-  resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.20.0.tgz#2d823b5852ee8963585c8dd8b7992ffc1ae83b42"
-  integrity sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==
+  version "1.21.0"
+  resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d"
+  integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==
 
 js-yaml@^4.1.0:
   version "4.1.0"
@@ -1222,9 +1226,9 @@ json-stable-stringify-without-jsonify@^1.0.1:
   integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
 
 keyv@^4.5.3:
-  version "4.5.3"
-  resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.3.tgz#00873d2b046df737963157bd04f294ca818c9c25"
-  integrity sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==
+  version "4.5.4"
+  resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93"
+  integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==
   dependencies:
     json-buffer "3.0.1"
 
@@ -1233,10 +1237,10 @@ kleur@^4.1.5:
   resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780"
   integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==
 
-known-css-properties@^0.28.0:
-  version "0.28.0"
-  resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.28.0.tgz#8a8be010f368b3036fe6ab0ef4bbbed972bd6274"
-  integrity sha512-9pSL5XB4J+ifHP0e0jmmC98OGC1nL8/JjS+fi6mnTlIf//yt/MfVLtKg7S6nCtj/8KTcWX7nRlY0XywoYY1ISQ==
+known-css-properties@^0.29.0:
+  version "0.29.0"
+  resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.29.0.tgz#e8ba024fb03886f23cb882e806929f32d814158f"
+  integrity sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==
 
 levn@^0.4.1:
   version "0.4.1"
@@ -1251,6 +1255,11 @@ lilconfig@^2.0.5, lilconfig@^2.1.0:
   resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52"
   integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==
 
+lilconfig@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.0.0.tgz#f8067feb033b5b74dab4602a5f5029420be749bc"
+  integrity sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==
+
 lines-and-columns@^1.1.6:
   version "1.2.4"
   resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
@@ -1287,18 +1296,13 @@ magic-string@^0.27.0:
   dependencies:
     "@jridgewell/sourcemap-codec" "^1.4.13"
 
-magic-string@^0.30.0, magic-string@^0.30.2:
-  version "0.30.3"
-  resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.3.tgz#403755dfd9d6b398dfa40635d52e96c5ac095b85"
-  integrity sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==
+magic-string@^0.30.0, magic-string@^0.30.3, magic-string@^0.30.4:
+  version "0.30.5"
+  resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9"
+  integrity sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==
   dependencies:
     "@jridgewell/sourcemap-codec" "^1.4.15"
 
-mdn-data@2.0.30:
-  version "2.0.30"
-  resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc"
-  integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==
-
 merge2@^1.3.0, merge2@^1.4.1:
   version "1.4.1"
   resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
@@ -1312,11 +1316,6 @@ micromatch@^4.0.4, micromatch@^4.0.5:
     braces "^3.0.2"
     picomatch "^2.3.1"
 
-mime@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7"
-  integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==
-
 min-indent@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
@@ -1353,7 +1352,7 @@ mri@^1.1.0:
   resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"
   integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==
 
-mrmime@^1.0.0:
+mrmime@^1.0.0, mrmime@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.1.tgz#5f90c825fad4bdd41dc914eff5d1a8cfdaf24f27"
   integrity sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==
@@ -1372,10 +1371,10 @@ mz@^2.7.0:
     object-assign "^4.0.1"
     thenify-all "^1.0.0"
 
-nanoid@^3.3.6:
-  version "3.3.6"
-  resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c"
-  integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
+nanoid@^3.3.6, nanoid@^3.3.7:
+  version "3.3.7"
+  resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
+  integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
 
 natural-compare-lite@^1.4.0:
   version "1.4.0"
@@ -1387,10 +1386,10 @@ natural-compare@^1.4.0:
   resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
   integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
 
-node-releases@^2.0.13:
-  version "2.0.13"
-  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d"
-  integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==
+node-releases@^2.0.14:
+  version "2.0.14"
+  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b"
+  integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==
 
 normalize-path@^3.0.0, normalize-path@~3.0.0:
   version "3.0.0"
@@ -1477,15 +1476,6 @@ path-type@^4.0.0:
   resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
   integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
 
-periscopic@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/periscopic/-/periscopic-3.1.0.tgz#7e9037bf51c5855bd33b48928828db4afa79d97a"
-  integrity sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==
-  dependencies:
-    "@types/estree" "^1.0.0"
-    estree-walker "^3.0.0"
-    is-reference "^3.0.0"
-
 picocolors@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
@@ -1531,12 +1521,12 @@ postcss-load-config@^3.1.4:
     yaml "^1.10.2"
 
 postcss-load-config@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.1.tgz#152383f481c2758274404e4962743191d73875bd"
-  integrity sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz#7159dcf626118d33e299f485d6afe4aff7c4a3e3"
+  integrity sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==
   dependencies:
-    lilconfig "^2.0.5"
-    yaml "^2.1.1"
+    lilconfig "^3.0.0"
+    yaml "^2.3.4"
 
 postcss-nested@^6.0.1:
   version "6.0.1"
@@ -1550,10 +1540,10 @@ postcss-safe-parser@^6.0.0:
   resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz#bb4c29894171a94bc5c996b9a30317ef402adaa1"
   integrity sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==
 
-postcss-scss@^4.0.7:
-  version "4.0.8"
-  resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-4.0.8.tgz#12a4991a902a782d4e9b86b1f217d5181c6c4f32"
-  integrity sha512-Cr0X8Eu7xMhE96PJck6ses/uVVXDtE5ghUTKNUYgm8ozgP2TkgV3LWs3WgLV1xaSSLq8ZFiXaUrj0LVgG1fGEA==
+postcss-scss@^4.0.8:
+  version "4.0.9"
+  resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-4.0.9.tgz#a03c773cd4c9623cb04ce142a52afcec74806685"
+  integrity sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==
 
 postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.7:
   version "6.0.13"
@@ -1568,7 +1558,7 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0:
   resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
   integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
 
-postcss@8.4.29, postcss@^8.4.23, postcss@^8.4.27, postcss@^8.4.28, postcss@^8.4.4, postcss@^8.4.5:
+postcss@8.4.29:
   version "8.4.29"
   resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.29.tgz#33bc121cf3b3688d4ddef50be869b2a54185a1dd"
   integrity sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==
@@ -1577,6 +1567,15 @@ postcss@8.4.29, postcss@^8.4.23, postcss@^8.4.27, postcss@^8.4.28, postcss@^8.4.
     picocolors "^1.0.0"
     source-map-js "^1.0.2"
 
+postcss@^8.4.23, postcss@^8.4.27, postcss@^8.4.29, postcss@^8.4.4, postcss@^8.4.5:
+  version "8.4.32"
+  resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.32.tgz#1dac6ac51ab19adb21b8b34fd2d93a86440ef6c9"
+  integrity sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==
+  dependencies:
+    nanoid "^3.3.7"
+    picocolors "^1.0.0"
+    source-map-js "^1.0.2"
+
 prelude-ls@^1.2.1:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
@@ -1593,9 +1592,9 @@ prettier@^2.8.0:
   integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==
 
 punycode@^2.1.0:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f"
-  integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
+  version "2.3.1"
+  resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
+  integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
 
 purgecss@6.0.0-alpha.0:
   version "6.0.0-alpha.0"
@@ -1632,9 +1631,9 @@ resolve-from@^4.0.0:
   integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
 
 resolve@^1.1.7, resolve@^1.22.2:
-  version "1.22.4"
-  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34"
-  integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==
+  version "1.22.8"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
+  integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
   dependencies:
     is-core-module "^2.13.0"
     path-parse "^1.0.7"
@@ -1660,9 +1659,9 @@ rimraf@^3.0.2:
     glob "^7.1.3"
 
 rollup@^3.27.1:
-  version "3.29.0"
-  resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.0.tgz#1b40e64818afc979c7e5bef93de675829288986b"
-  integrity sha512-nszM8DINnx1vSS+TpbWKMkxem0CDWk3cSit/WWCBVs9/JZ1I/XLwOsiUglYuYReaeWWSsW9kge5zE5NZtf/a4w==
+  version "3.29.4"
+  resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981"
+  integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==
   optionalDependencies:
     fsevents "~2.3.2"
 
@@ -1738,16 +1737,11 @@ sorcery@^0.11.0:
     minimist "^1.2.0"
     sander "^0.5.0"
 
-source-map-js@^1.0.1, source-map-js@^1.0.2:
+source-map-js@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
   integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
 
-streamsearch@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764"
-  integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
-
 strip-ansi@^6.0.1:
   version "6.0.1"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
@@ -1798,9 +1792,9 @@ svelte-chartjs@^3.1.2:
   integrity sha512-3+6gY2IJ9Ua8R9pk3iS1ypa7Z9OoXCJb9oPwIfTp7caJM+X+RrWnH2CTkGAq7FeSxc2nnmW08tYN88Q8Y+5M+w==
 
 svelte-check@^3.4.3:
-  version "3.5.1"
-  resolved "https://registry.yarnpkg.com/svelte-check/-/svelte-check-3.5.1.tgz#88265b41623b9374ff35b69802497287073d693d"
-  integrity sha512-+Zb4iHxAhdUtcUg/WJPRjlS1RJalIsWAe9Mz6G1zyznSs7dDkT7VUBdXc3q7Iwg49O/VrZgyJRvOJkjuBfKjFA==
+  version "3.6.2"
+  resolved "https://registry.yarnpkg.com/svelte-check/-/svelte-check-3.6.2.tgz#a6922160e17e93c6f5fa2b18ec342cc4c70d60ab"
+  integrity sha512-E6iFh4aUCGJLRz6QZXH3gcN/VFfkzwtruWSRmlKrLWQTiO6VzLsivR6q02WYLGNAGecV3EocqZuCDrC2uttZ0g==
   dependencies:
     "@jridgewell/trace-mapping" "^0.3.17"
     chokidar "^3.4.1"
@@ -1808,19 +1802,19 @@ svelte-check@^3.4.3:
     import-fresh "^3.2.1"
     picocolors "^1.0.0"
     sade "^1.7.4"
-    svelte-preprocess "^5.0.4"
+    svelte-preprocess "^5.1.0"
     typescript "^5.0.3"
 
 "svelte-eslint-parser@>=0.33.0 <1.0.0":
-  version "0.33.0"
-  resolved "https://registry.yarnpkg.com/svelte-eslint-parser/-/svelte-eslint-parser-0.33.0.tgz#66a0779e3d336c44bfdb6e72e0a74e33b1f84fb7"
-  integrity sha512-5awZ6Bs+Tb/zQwa41PSdcLynAVQTwW0HGyCBjtbAQ59taLZqDgQSMzRlDmapjZdDtzERm0oXDZNE0E+PKJ6ryg==
+  version "0.33.1"
+  resolved "https://registry.yarnpkg.com/svelte-eslint-parser/-/svelte-eslint-parser-0.33.1.tgz#c64dbed2fad099577429b3c39377f6b8d36e5d97"
+  integrity sha512-vo7xPGTlKBGdLH8T5L64FipvTrqv3OQRx9d2z5X05KKZDlF4rQk8KViZO4flKERY+5BiVdOh7zZ7JGJWo5P0uA==
   dependencies:
     eslint-scope "^7.0.0"
     eslint-visitor-keys "^3.0.0"
     espree "^9.0.0"
-    postcss "^8.4.28"
-    postcss-scss "^4.0.7"
+    postcss "^8.4.29"
+    postcss-scss "^4.0.8"
 
 svelte-hmr@^0.15.3:
   version "0.15.3"
@@ -1832,10 +1826,10 @@ svelte-loading-spinners@^0.3.4:
   resolved "https://registry.yarnpkg.com/svelte-loading-spinners/-/svelte-loading-spinners-0.3.4.tgz#af11d0f9ef0943026415c931900c10fea02a88a5"
   integrity sha512-vKaW71QMCBcTNijAGc0mUl8k3DQ66iYmp6MB8BMGCXyWk82bTrcLy8FOnSm9fE+8q6TwzD6PLUoYFHt0II93Xw==
 
-svelte-preprocess@^5.0.4:
-  version "5.0.4"
-  resolved "https://registry.yarnpkg.com/svelte-preprocess/-/svelte-preprocess-5.0.4.tgz#2123898e079a074f7f4ef1799e10e037f5bcc55b"
-  integrity sha512-ABia2QegosxOGsVlsSBJvoWeXy1wUKSfF7SWJdTjLAbx/Y3SrVevvvbFNQqrSJw89+lNSsM58SipmZJ5SRi5iw==
+svelte-preprocess@^5.1.0:
+  version "5.1.1"
+  resolved "https://registry.yarnpkg.com/svelte-preprocess/-/svelte-preprocess-5.1.1.tgz#53d7107c2e8b307afd4418e06239177c4de12025"
+  integrity sha512-p/Dp4hmrBW5mrCCq29lEMFpIJT2FZsRlouxEc5qpbOmXRbaFs7clLs8oKPwD3xCFyZfv1bIhvOzpQkhMEVQdMw==
   dependencies:
     "@types/pug" "^2.0.6"
     detect-indent "^6.1.0"
@@ -1843,24 +1837,23 @@ svelte-preprocess@^5.0.4:
     sorcery "^0.11.0"
     strip-indent "^3.0.0"
 
-svelte@^4.0.5:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/svelte/-/svelte-4.2.0.tgz#0e4304c15524450b22fba02516eb72efbd8847b6"
-  integrity sha512-kVsdPjDbLrv74SmLSUzAsBGquMs4MPgWGkGLpH+PjOYnFOziAvENVzgJmyOCV2gntxE32aNm8/sqNKD6LbIpeQ==
+svelte@^5.0.0-next.17:
+  version "5.0.0-next.17"
+  resolved "https://registry.yarnpkg.com/svelte/-/svelte-5.0.0-next.17.tgz#5fe86849daa0d990754402b10b48e7b60d7a6de9"
+  integrity sha512-+TiGAi3kqwIIXtB3h1sLs3cD/KMdk3L/zEArfw0ZeqqO/hLrRGRvnTxspgktxYLHG9trBn6Xx9zD2Eekze7CCA==
   dependencies:
     "@ampproject/remapping" "^2.2.1"
     "@jridgewell/sourcemap-codec" "^1.4.15"
-    "@jridgewell/trace-mapping" "^0.3.18"
-    acorn "^8.9.0"
+    acorn "^8.10.0"
+    acorn-typescript "^1.4.11"
     aria-query "^5.3.0"
-    axobject-query "^3.2.1"
-    code-red "^1.0.3"
-    css-tree "^2.3.1"
-    estree-walker "^3.0.3"
+    axobject-query "^4.0.0"
+    esm-env "^1.0.0"
+    esrap "^1.2.1"
     is-reference "^3.0.1"
     locate-character "^3.0.0"
-    magic-string "^0.30.0"
-    periscopic "^3.1.0"
+    magic-string "^0.30.4"
+    zimmerframe "^1.1.0"
 
 tailwindcss@3.3.3:
   version "3.3.3"
@@ -1964,21 +1957,21 @@ type-fest@^0.20.2:
   integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
 
 typescript@^5.0.0, typescript@^5.0.3:
-  version "5.2.2"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78"
-  integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==
+  version "5.3.2"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.2.tgz#00d1c7c1c46928c5845c1ee8d0cc2791031d4c43"
+  integrity sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==
 
-undici@~5.23.0:
-  version "5.23.0"
-  resolved "https://registry.yarnpkg.com/undici/-/undici-5.23.0.tgz#e7bdb0ed42cebe7b7aca87ced53e6eaafb8f8ca0"
-  integrity sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg==
+undici@~5.26.2:
+  version "5.26.5"
+  resolved "https://registry.yarnpkg.com/undici/-/undici-5.26.5.tgz#f6dc8c565e3cad8c4475b187f51a13e505092838"
+  integrity sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw==
   dependencies:
-    busboy "^1.6.0"
+    "@fastify/busboy" "^2.0.0"
 
-update-browserslist-db@^1.0.11:
-  version "1.0.11"
-  resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940"
-  integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==
+update-browserslist-db@^1.0.13:
+  version "1.0.13"
+  resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4"
+  integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==
   dependencies:
     escalade "^3.1.1"
     picocolors "^1.0.0"
@@ -2004,9 +1997,9 @@ vite-plugin-tailwind-purgecss@0.1.3:
     purgecss "6.0.0-alpha.0"
 
 vite@^4.4.2:
-  version "4.4.9"
-  resolved "https://registry.yarnpkg.com/vite/-/vite-4.4.9.tgz#1402423f1a2f8d66fd8d15e351127c7236d29d3d"
-  integrity sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==
+  version "4.5.1"
+  resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.1.tgz#3370986e1ed5dbabbf35a6c2e1fb1e18555b968a"
+  integrity sha512-AXXFaAJ8yebyqzoNB9fu2pHoo/nWX+xZlaRwoeYUxEqBO+Zj4msE5G+BhGBll9lYEKv9Hfks52PAF2X7qDYXQA==
   dependencies:
     esbuild "^0.18.10"
     postcss "^8.4.27"
@@ -2015,9 +2008,9 @@ vite@^4.4.2:
     fsevents "~2.3.2"
 
 vitefu@^0.2.4:
-  version "0.2.4"
-  resolved "https://registry.yarnpkg.com/vitefu/-/vitefu-0.2.4.tgz#212dc1a9d0254afe65e579351bed4e25d81e0b35"
-  integrity sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==
+  version "0.2.5"
+  resolved "https://registry.yarnpkg.com/vitefu/-/vitefu-0.2.5.tgz#c1b93c377fbdd3e5ddd69840ea3aa70b40d90969"
+  integrity sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==
 
 which@^2.0.1:
   version "2.0.2"
@@ -2041,12 +2034,17 @@ yaml@^1.10.2:
   resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
   integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
 
-yaml@^2.1.1:
-  version "2.3.2"
-  resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.2.tgz#f522db4313c671a0ca963a75670f1c12ea909144"
-  integrity sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==
+yaml@^2.3.4:
+  version "2.3.4"
+  resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.4.tgz#53fc1d514be80aabf386dc6001eb29bf3b7523b2"
+  integrity sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==
 
 yocto-queue@^0.1.0:
   version "0.1.0"
   resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
   integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
+
+zimmerframe@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/zimmerframe/-/zimmerframe-1.1.0.tgz#29f2b760d11228490109808e2b56ba67f25af199"
+  integrity sha512-+AmV37r9NPUy7KcuG0Fde9AAFSD88kN5pnqvD7Pkp5WLLK0jct7hAtIDXXFDCRk3l5Mc1r2Sth3gfP2ZLE+/Qw==

From 59c2fd8f2d96e32915143c696f6e90f551aed734 Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Tue, 5 Dec 2023 19:24:27 +0100
Subject: [PATCH 02/24] Remove most of Skeleton-UI

---
 .gitignore                                    |   3 +-
 package.json                                  |  17 +-
 src/app.html                                  |   4 +-
 src/lib/components/NavigationElement.svelte   |   0
 src/lib/stores/UserSettingsStore.ts           |   0
 src/lib/types/themes.ts                       |   0
 src/lib/types/userSettings.ts                 |   0
 src/routes/account/+page.svelte               |   0
 src/routes/archive/+page.svelte               |   0
 src/routes/current/+page.svelte               |   0
 src/routes/{ => legacy}/about/+page.svelte    |   0
 src/routes/{ => legacy}/about/+page.ts        |   0
 src/routes/{ => legacy}/graphs/+layout.svelte |   0
 src/routes/{ => legacy}/graphs/+layout.ts     |   0
 src/routes/{ => legacy}/graphs/+page.svelte   |   0
 .../graphs/GameGroupSelection.svelte          |   0
 .../{ => legacy}/graphs/GameSelection.svelte  |   0
 src/routes/{ => legacy}/graphs/SubNav.svelte  |   0
 .../graphs/excel-style/+page.svelte           |   0
 .../{ => legacy}/graphs/tab/+page.svelte      |   0
 .../{ => legacy}/graphs/tab2/+page.svelte     |   0
 .../{ => legacy}/legacy-graphs/+page.svelte   |   0
 .../{ => legacy}/legacy-graphs/+page.ts       |   0
 .../legacy-graphs/EmpireStats.svelte          |   0
 .../legacy-graphs/EthicsBar.svelte            |   0
 .../legacy-graphs/EthicsWeb.svelte            |   0
 .../{ => legacy}/legacy-graphs/PopsPie.svelte |   0
 src/routes/{ => legacy}/sign-up/+page.svelte  |   0
 src/routes/{ => legacy}/sign-up/+page.ts      |   0
 src/routes/settings/+page.svelte              |   0
 svelte.config.js                              |   4 +-
 tailwind.config.js                            |  30 ++
 tailwind.config.ts                            |  31 --
 vite.config.ts                                |   3 +-
 yarn.lock                                     | 271 +++++++++++-------
 35 files changed, 217 insertions(+), 146 deletions(-)
 create mode 100644 src/lib/components/NavigationElement.svelte
 create mode 100644 src/lib/stores/UserSettingsStore.ts
 create mode 100644 src/lib/types/themes.ts
 create mode 100644 src/lib/types/userSettings.ts
 create mode 100644 src/routes/account/+page.svelte
 create mode 100644 src/routes/archive/+page.svelte
 create mode 100644 src/routes/current/+page.svelte
 rename src/routes/{ => legacy}/about/+page.svelte (100%)
 rename src/routes/{ => legacy}/about/+page.ts (100%)
 rename src/routes/{ => legacy}/graphs/+layout.svelte (100%)
 rename src/routes/{ => legacy}/graphs/+layout.ts (100%)
 rename src/routes/{ => legacy}/graphs/+page.svelte (100%)
 rename src/routes/{ => legacy}/graphs/GameGroupSelection.svelte (100%)
 rename src/routes/{ => legacy}/graphs/GameSelection.svelte (100%)
 rename src/routes/{ => legacy}/graphs/SubNav.svelte (100%)
 rename src/routes/{ => legacy}/graphs/excel-style/+page.svelte (100%)
 rename src/routes/{ => legacy}/graphs/tab/+page.svelte (100%)
 rename src/routes/{ => legacy}/graphs/tab2/+page.svelte (100%)
 rename src/routes/{ => legacy}/legacy-graphs/+page.svelte (100%)
 rename src/routes/{ => legacy}/legacy-graphs/+page.ts (100%)
 rename src/routes/{ => legacy}/legacy-graphs/EmpireStats.svelte (100%)
 rename src/routes/{ => legacy}/legacy-graphs/EthicsBar.svelte (100%)
 rename src/routes/{ => legacy}/legacy-graphs/EthicsWeb.svelte (100%)
 rename src/routes/{ => legacy}/legacy-graphs/PopsPie.svelte (100%)
 rename src/routes/{ => legacy}/sign-up/+page.svelte (100%)
 rename src/routes/{ => legacy}/sign-up/+page.ts (100%)
 create mode 100644 src/routes/settings/+page.svelte
 create mode 100644 tailwind.config.js
 delete mode 100644 tailwind.config.ts

diff --git a/.gitignore b/.gitignore
index a47df63..8808712 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,4 +11,5 @@ node_modules
 vite.config.js.timestamp-*
 vite.config.ts.timestamp-*
 
-/.vscode
\ No newline at end of file
+/.vscode
+/.idea
\ No newline at end of file
diff --git a/package.json b/package.json
index ca88aec..b8f5151 100644
--- a/package.json
+++ b/package.json
@@ -14,35 +14,34 @@
   "devDependencies": {
     "@fontsource/fira-mono": "^4.5.10",
     "@neoconfetti/svelte": "^1.0.0",
-    "@skeletonlabs/skeleton": "2.0.0",
-    "@skeletonlabs/tw-plugin": "0.1.0",
     "@sveltejs/adapter-auto": "^2.0.0",
     "@sveltejs/kit": "^1.20.4",
     "@types/cookie": "^0.5.1",
-    "@types/node": "20.6.0",
+    "@types/node": "^20.6.0",
     "@typescript-eslint/eslint-plugin": "^5.45.0",
     "@typescript-eslint/parser": "^5.45.0",
-    "autoprefixer": "10.4.15",
+    "autoprefixer": "^10.4.15",
     "eslint": "^8.28.0",
     "eslint-config-prettier": "^8.5.0",
     "eslint-plugin-svelte": "^2.30.0",
-    "postcss": "8.4.29",
+    "postcss": "^8.4.29",
     "postcss-load-config": "^4.0.1",
     "prettier": "^2.8.0",
     "prettier-plugin-svelte": "^2.10.1",
     "svelte": "^5.0.0-next.17",
     "svelte-check": "^3.4.3",
     "svelte-loading-spinners": "^0.3.4",
-    "tailwindcss": "3.3.3",
     "tslib": "^2.4.1",
     "typescript": "^5.0.0",
-    "vite": "^4.4.2",
-    "vite-plugin-tailwind-purgecss": "0.1.3"
+    "vite": "^4.4.2"
   },
   "type": "module",
   "dependencies": {
     "chart.js": "^4.3.3",
     "chartjs-plugin-datalabels": "^2.2.0",
-    "svelte-chartjs": "^3.1.2"
+    "flowbite": "^2.2.0",
+    "flowbite-svelte": "^0.44.20",
+    "svelte-chartjs": "^3.1.2",
+    "tailwindcss": "^3.3.6"
   }
 }
diff --git a/src/app.html b/src/app.html
index be76506..7a50504 100644
--- a/src/app.html
+++ b/src/app.html
@@ -6,7 +6,7 @@
 		<meta name="viewport" content="width=device-width" />
 		%sveltekit.head%
 	</head>
-	<body data-sveltekit-preload-data="hover" data-theme="wintry">
-		<div style="display: contents" class="h-screen overflow-hidden contents">%sveltekit.body%</div>
+	<body data-sveltekit-preload-data="hover">
+		<div style="display: contents;" class="h-screen overflow-hidden contents">%sveltekit.body%</div>
 	</body>
 </html>
diff --git a/src/lib/components/NavigationElement.svelte b/src/lib/components/NavigationElement.svelte
new file mode 100644
index 0000000..e69de29
diff --git a/src/lib/stores/UserSettingsStore.ts b/src/lib/stores/UserSettingsStore.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/lib/types/themes.ts b/src/lib/types/themes.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/lib/types/userSettings.ts b/src/lib/types/userSettings.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/routes/account/+page.svelte b/src/routes/account/+page.svelte
new file mode 100644
index 0000000..e69de29
diff --git a/src/routes/archive/+page.svelte b/src/routes/archive/+page.svelte
new file mode 100644
index 0000000..e69de29
diff --git a/src/routes/current/+page.svelte b/src/routes/current/+page.svelte
new file mode 100644
index 0000000..e69de29
diff --git a/src/routes/about/+page.svelte b/src/routes/legacy/about/+page.svelte
similarity index 100%
rename from src/routes/about/+page.svelte
rename to src/routes/legacy/about/+page.svelte
diff --git a/src/routes/about/+page.ts b/src/routes/legacy/about/+page.ts
similarity index 100%
rename from src/routes/about/+page.ts
rename to src/routes/legacy/about/+page.ts
diff --git a/src/routes/graphs/+layout.svelte b/src/routes/legacy/graphs/+layout.svelte
similarity index 100%
rename from src/routes/graphs/+layout.svelte
rename to src/routes/legacy/graphs/+layout.svelte
diff --git a/src/routes/graphs/+layout.ts b/src/routes/legacy/graphs/+layout.ts
similarity index 100%
rename from src/routes/graphs/+layout.ts
rename to src/routes/legacy/graphs/+layout.ts
diff --git a/src/routes/graphs/+page.svelte b/src/routes/legacy/graphs/+page.svelte
similarity index 100%
rename from src/routes/graphs/+page.svelte
rename to src/routes/legacy/graphs/+page.svelte
diff --git a/src/routes/graphs/GameGroupSelection.svelte b/src/routes/legacy/graphs/GameGroupSelection.svelte
similarity index 100%
rename from src/routes/graphs/GameGroupSelection.svelte
rename to src/routes/legacy/graphs/GameGroupSelection.svelte
diff --git a/src/routes/graphs/GameSelection.svelte b/src/routes/legacy/graphs/GameSelection.svelte
similarity index 100%
rename from src/routes/graphs/GameSelection.svelte
rename to src/routes/legacy/graphs/GameSelection.svelte
diff --git a/src/routes/graphs/SubNav.svelte b/src/routes/legacy/graphs/SubNav.svelte
similarity index 100%
rename from src/routes/graphs/SubNav.svelte
rename to src/routes/legacy/graphs/SubNav.svelte
diff --git a/src/routes/graphs/excel-style/+page.svelte b/src/routes/legacy/graphs/excel-style/+page.svelte
similarity index 100%
rename from src/routes/graphs/excel-style/+page.svelte
rename to src/routes/legacy/graphs/excel-style/+page.svelte
diff --git a/src/routes/graphs/tab/+page.svelte b/src/routes/legacy/graphs/tab/+page.svelte
similarity index 100%
rename from src/routes/graphs/tab/+page.svelte
rename to src/routes/legacy/graphs/tab/+page.svelte
diff --git a/src/routes/graphs/tab2/+page.svelte b/src/routes/legacy/graphs/tab2/+page.svelte
similarity index 100%
rename from src/routes/graphs/tab2/+page.svelte
rename to src/routes/legacy/graphs/tab2/+page.svelte
diff --git a/src/routes/legacy-graphs/+page.svelte b/src/routes/legacy/legacy-graphs/+page.svelte
similarity index 100%
rename from src/routes/legacy-graphs/+page.svelte
rename to src/routes/legacy/legacy-graphs/+page.svelte
diff --git a/src/routes/legacy-graphs/+page.ts b/src/routes/legacy/legacy-graphs/+page.ts
similarity index 100%
rename from src/routes/legacy-graphs/+page.ts
rename to src/routes/legacy/legacy-graphs/+page.ts
diff --git a/src/routes/legacy-graphs/EmpireStats.svelte b/src/routes/legacy/legacy-graphs/EmpireStats.svelte
similarity index 100%
rename from src/routes/legacy-graphs/EmpireStats.svelte
rename to src/routes/legacy/legacy-graphs/EmpireStats.svelte
diff --git a/src/routes/legacy-graphs/EthicsBar.svelte b/src/routes/legacy/legacy-graphs/EthicsBar.svelte
similarity index 100%
rename from src/routes/legacy-graphs/EthicsBar.svelte
rename to src/routes/legacy/legacy-graphs/EthicsBar.svelte
diff --git a/src/routes/legacy-graphs/EthicsWeb.svelte b/src/routes/legacy/legacy-graphs/EthicsWeb.svelte
similarity index 100%
rename from src/routes/legacy-graphs/EthicsWeb.svelte
rename to src/routes/legacy/legacy-graphs/EthicsWeb.svelte
diff --git a/src/routes/legacy-graphs/PopsPie.svelte b/src/routes/legacy/legacy-graphs/PopsPie.svelte
similarity index 100%
rename from src/routes/legacy-graphs/PopsPie.svelte
rename to src/routes/legacy/legacy-graphs/PopsPie.svelte
diff --git a/src/routes/sign-up/+page.svelte b/src/routes/legacy/sign-up/+page.svelte
similarity index 100%
rename from src/routes/sign-up/+page.svelte
rename to src/routes/legacy/sign-up/+page.svelte
diff --git a/src/routes/sign-up/+page.ts b/src/routes/legacy/sign-up/+page.ts
similarity index 100%
rename from src/routes/sign-up/+page.ts
rename to src/routes/legacy/sign-up/+page.ts
diff --git a/src/routes/settings/+page.svelte b/src/routes/settings/+page.svelte
new file mode 100644
index 0000000..e69de29
diff --git a/svelte.config.js b/svelte.config.js
index 1eac3be..8649df1 100644
--- a/svelte.config.js
+++ b/svelte.config.js
@@ -7,7 +7,9 @@ const config = {
 	extensions: ['.svelte'],
 	// Consult https://kit.svelte.dev/docs/integrations#preprocessors
 	// for more information about preprocessors
-	preprocess: [ vitePreprocess()],
+	preprocess: [ vitePreprocess({
+		postcss: true
+	})],
 	
 	kit: {
 		// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
diff --git a/tailwind.config.js b/tailwind.config.js
new file mode 100644
index 0000000..b7651cb
--- /dev/null
+++ b/tailwind.config.js
@@ -0,0 +1,30 @@
+module.exports = {
+	mode: 'jit',
+	purge: ['./src/**/*.svelte', './src/**/*.html'],
+	darkMode: false,
+	theme: {
+		extend: {},
+	},
+	variants: {
+		extend: {
+		},
+	},
+	plugins: [],
+	safelist: [
+		{
+			pattern: /bg-.+/,
+		},
+		{
+			pattern: /text-.+/,
+		},
+		{
+			pattern: /primary-.+/,
+		},
+		{
+			pattern: /secondary-.+/,
+		},
+		{
+			pattern: /border-.+/,
+		},
+	]
+}
\ No newline at end of file
diff --git a/tailwind.config.ts b/tailwind.config.ts
deleted file mode 100644
index 847c1a3..0000000
--- a/tailwind.config.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { join } from 'path'
-import type { Config } from 'tailwindcss'
-import { skeleton } from '@skeletonlabs/tw-plugin'
-import plugin from 'tailwindcss/plugin'
-
-export default {
-	darkMode: 'class',
-	content: ['./src/**/*.{html,js,svelte,ts}', join(require.resolve('@skeletonlabs/skeleton'), '../**/*.{html,js,svelte,ts}')],
-	theme: {
-		extend: {},
-	},
-	plugins: [
-		skeleton({
-			themes: {
-				preset: [
-					{
-						name: 'wintry',
-						enhancements: true,
-					},
-				],
-			},
-		}),
-    plugin(function({ addBase, theme }) {
-      addBase({
-        'h1': { fontSize: theme('fontSize.2xl') },
-        'h2': { fontSize: theme('fontSize.xl') },
-        'h3': { fontSize: theme('fontSize.lg') },
-      })
-    })
-	],
-} satisfies Config;
diff --git a/vite.config.ts b/vite.config.ts
index f995799..2712374 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,9 +1,8 @@
-import { purgeCss } from 'vite-plugin-tailwind-purgecss';
 import { sveltekit } from '@sveltejs/kit/vite';
 import { defineConfig } from 'vite';
 
 export default defineConfig({
-	plugins: [sveltekit(), purgeCss()],
+	plugins: [sveltekit()],
   server: {
     host: true,
     port: 8004,
diff --git a/yarn.lock b/yarn.lock
index e4ab8dc..cf2d741 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -20,6 +20,13 @@
     "@jridgewell/gen-mapping" "^0.3.0"
     "@jridgewell/trace-mapping" "^0.3.9"
 
+"@babel/runtime@^7.23.5":
+  version "7.23.5"
+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.5.tgz#11edb98f8aeec529b82b211028177679144242db"
+  integrity sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==
+  dependencies:
+    regenerator-runtime "^0.14.0"
+
 "@esbuild/android-arm64@0.18.20":
   version "0.18.20"
   resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622"
@@ -167,6 +174,26 @@
   resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.0.tgz#0709e9f4cb252351c609c6e6d8d6779a8d25edff"
   integrity sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==
 
+"@floating-ui/core@^1.4.2":
+  version "1.5.1"
+  resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.1.tgz#62707d7ec585d0929f882321a1b1f4ea9c680da5"
+  integrity sha512-QgcKYwzcc8vvZ4n/5uklchy8KVdjJwcOeI+HnnTNclJjs2nYsy23DOCf+sSV1kBwD9yDAoVKCkv/gEPzgQU3Pw==
+  dependencies:
+    "@floating-ui/utils" "^0.1.3"
+
+"@floating-ui/dom@^1.5.3":
+  version "1.5.3"
+  resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.5.3.tgz#54e50efcb432c06c23cd33de2b575102005436fa"
+  integrity sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==
+  dependencies:
+    "@floating-ui/core" "^1.4.2"
+    "@floating-ui/utils" "^0.1.3"
+
+"@floating-ui/utils@^0.1.3":
+  version "0.1.6"
+  resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.6.tgz#22958c042e10b67463997bd6ea7115fe28cbcaf9"
+  integrity sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==
+
 "@fontsource/fira-mono@^4.5.10":
   version "4.5.10"
   resolved "https://registry.yarnpkg.com/@fontsource/fira-mono/-/fira-mono-4.5.10.tgz#443be4b2b4fc6e685b88431fcfdaf8d5f5639bbf"
@@ -259,17 +286,10 @@
   resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.23.tgz#498e41218ab3b6a1419c735e5c6ae2c5ed609b6c"
   integrity sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==
 
-"@skeletonlabs/skeleton@2.0.0":
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/@skeletonlabs/skeleton/-/skeleton-2.0.0.tgz#8bff64a64bbff07814eac5bc305af2751482a8ce"
-  integrity sha512-8SaDK3kEUU57cSb/5a984EbINgnOPzShlkwPkduAhqc71SEqhRvx+RlLEpe1174NAYi00oi//LguIAYuVrSfBA==
-  dependencies:
-    esm-env "1.0.0"
-
-"@skeletonlabs/tw-plugin@0.1.0":
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/@skeletonlabs/tw-plugin/-/tw-plugin-0.1.0.tgz#75f0af8b8428afc664e0d1d53df5e6813a6e6ed5"
-  integrity sha512-ufnm4FS+s/khuho4yJ/uqfW91u2YXnH3E5N541MtX9XjmoimQzYIcxWyTIuX9AM/brIPP6M6l0et3nRx17CRoQ==
+"@popperjs/core@^2.9.3":
+  version "2.11.8"
+  resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f"
+  integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==
 
 "@sveltejs/adapter-auto@^2.0.0":
   version "2.1.1"
@@ -322,7 +342,7 @@
   resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.5.4.tgz#7e70a20cd695bc48d46b08c2505874cd68b760e0"
   integrity sha512-7z/eR6O859gyWIAjuvBWFzNURmf2oPBmJlfVWkwehU5nzIyjwBsTh7WMmEEV4JFnHuQ3ex4oyTvfKzcyJVDBNA==
 
-"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.1":
+"@types/estree@*", "@types/estree@^1.0.1":
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
   integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
@@ -332,10 +352,12 @@
   resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
   integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
 
-"@types/node@20.6.0":
-  version "20.6.0"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-20.6.0.tgz#9d7daa855d33d4efec8aea88cd66db1c2f0ebe16"
-  integrity sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==
+"@types/node@^20.6.0":
+  version "20.10.3"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.3.tgz#4900adcc7fc189d5af5bb41da8f543cea6962030"
+  integrity sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==
+  dependencies:
+    undici-types "~5.26.4"
 
 "@types/pug@^2.0.6":
   version "2.0.10"
@@ -436,6 +458,11 @@
   resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406"
   integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==
 
+"@yr/monotone-cubic-spline@^1.0.3":
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz#7272d89f8e4f6fb7a1600c28c378cc18d3b577b9"
+  integrity sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==
+
 acorn-jsx@^5.3.2:
   version "5.3.2"
   resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
@@ -486,6 +513,19 @@ anymatch@~3.1.2:
     normalize-path "^3.0.0"
     picomatch "^2.0.4"
 
+apexcharts@^3.44.0:
+  version "3.44.1"
+  resolved "https://registry.yarnpkg.com/apexcharts/-/apexcharts-3.44.1.tgz#0d4ae8650dc12d3e75beb667dcc0dc1d4ff8c155"
+  integrity sha512-nWd6bWf8E+c3YOsB0j0R4MOebMv1rBRWsK6aA11jF+pbag9IuBl4zrT4L42fxmDdLMcf5t3trWIXiGJmbLi2tA==
+  dependencies:
+    "@yr/monotone-cubic-spline" "^1.0.3"
+    svg.draggable.js "^2.2.2"
+    svg.easing.js "^2.0.0"
+    svg.filter.js "^2.0.2"
+    svg.pathmorphing.js "^0.1.3"
+    svg.resize.js "^1.4.3"
+    svg.select.js "^3.0.1"
+
 arg@^5.0.2:
   version "5.0.2"
   resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c"
@@ -508,14 +548,14 @@ array-union@^2.1.0:
   resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
   integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
 
-autoprefixer@10.4.15:
-  version "10.4.15"
-  resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.15.tgz#a1230f4aeb3636b89120b34a1f513e2f6834d530"
-  integrity sha512-KCuPB8ZCIqFdA4HwKXsvz7j6gvSDNhDP7WnUjBleRkKjPdvCmHFuQ77ocavI8FT6NdvlBnE2UFr2H4Mycn8Vew==
+autoprefixer@^10.4.15:
+  version "10.4.16"
+  resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.16.tgz#fad1411024d8670880bdece3970aa72e3572feb8"
+  integrity sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==
   dependencies:
     browserslist "^4.21.10"
-    caniuse-lite "^1.0.30001520"
-    fraction.js "^4.2.0"
+    caniuse-lite "^1.0.30001538"
+    fraction.js "^4.3.6"
     normalize-range "^0.1.2"
     picocolors "^1.0.0"
     postcss-value-parser "^4.2.0"
@@ -545,13 +585,6 @@ brace-expansion@^1.1.7:
     balanced-match "^1.0.0"
     concat-map "0.0.1"
 
-brace-expansion@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
-  integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
-  dependencies:
-    balanced-match "^1.0.0"
-
 braces@^3.0.2, braces@~3.0.2:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
@@ -584,7 +617,7 @@ camelcase-css@^2.0.1:
   resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5"
   integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
 
-caniuse-lite@^1.0.30001520, caniuse-lite@^1.0.30001565:
+caniuse-lite@^1.0.30001538, caniuse-lite@^1.0.30001565:
   version "1.0.30001566"
   resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz#61a8e17caf3752e3e426d4239c549ebbb37fef0d"
   integrity sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==
@@ -636,11 +669,6 @@ color-name@~1.1.4:
   resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
   integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
 
-commander@^10.0.0:
-  version "10.0.1"
-  resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06"
-  integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==
-
 commander@^4.0.0:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
@@ -867,7 +895,7 @@ eslint@^8.28.0:
     strip-ansi "^6.0.1"
     text-table "^0.2.0"
 
-esm-env@1.0.0, esm-env@^1.0.0:
+esm-env@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/esm-env/-/esm-env-1.0.0.tgz#b124b40b180711690a4cb9b00d16573391950413"
   integrity sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==
@@ -913,13 +941,6 @@ estraverse@^5.1.0, estraverse@^5.2.0:
   resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
   integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
 
-estree-walker@^3.0.3:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d"
-  integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==
-  dependencies:
-    "@types/estree" "^1.0.0"
-
 esutils@^2.0.2, esutils@^2.0.3:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
@@ -930,7 +951,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
   resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
   integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
 
-fast-glob@^3.2.12, fast-glob@^3.2.7, fast-glob@^3.2.9:
+fast-glob@^3.2.7, fast-glob@^3.2.9, fast-glob@^3.3.0:
   version "3.3.2"
   resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129"
   integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==
@@ -994,7 +1015,25 @@ flatted@^3.2.9:
   resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf"
   integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==
 
-fraction.js@^4.2.0:
+flowbite-svelte@^0.44.20:
+  version "0.44.20"
+  resolved "https://registry.yarnpkg.com/flowbite-svelte/-/flowbite-svelte-0.44.20.tgz#e2e39e18a28172d96dfeec107ee7e98f4957321f"
+  integrity sha512-juvzolgEvGEga8PIe+vpzGf9/xfpvd4p9ZgtSPpWQLZB8iyY/ebbKb5HNu60uqoehdokFuy/0htBBLNmP2yd/g==
+  dependencies:
+    "@floating-ui/dom" "^1.5.3"
+    apexcharts "^3.44.0"
+    flowbite "^2.2.0"
+    tailwind-merge "^2.0.0"
+
+flowbite@^2.2.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/flowbite/-/flowbite-2.2.0.tgz#638c223fa808241e1f64b4e068f819281d4c7c71"
+  integrity sha512-Eq0qWz4a5nlxaGuUcspzpu+8Ny0A7lKEJEKcuPpkdSoF8tWjbKeuVVgKk8/q10ZE9bhXh1GHBXdCsRxu0LZTNQ==
+  dependencies:
+    "@popperjs/core" "^2.9.3"
+    mini-svg-data-uri "^1.4.3"
+
+fraction.js@^4.3.6:
   version "4.3.7"
   resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
   integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==
@@ -1052,17 +1091,6 @@ glob@^7.1.3:
     once "^1.3.0"
     path-is-absolute "^1.0.0"
 
-glob@^8.0.3:
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e"
-  integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==
-  dependencies:
-    fs.realpath "^1.0.0"
-    inflight "^1.0.4"
-    inherits "2"
-    minimatch "^5.0.1"
-    once "^1.3.0"
-
 globals@^13.19.0:
   version "13.23.0"
   resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02"
@@ -1198,7 +1226,7 @@ isexe@^2.0.0:
   resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
   integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
 
-jiti@^1.18.2:
+jiti@^1.19.1:
   version "1.21.0"
   resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d"
   integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==
@@ -1321,6 +1349,11 @@ min-indent@^1.0.0:
   resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
   integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
 
+mini-svg-data-uri@^1.4.3:
+  version "1.4.4"
+  resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz#8ab0aabcdf8c29ad5693ca595af19dd2ead09939"
+  integrity sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==
+
 minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
   version "3.1.2"
   resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
@@ -1328,13 +1361,6 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
   dependencies:
     brace-expansion "^1.1.7"
 
-minimatch@^5.0.1:
-  version "5.1.6"
-  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
-  integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
-  dependencies:
-    brace-expansion "^2.0.1"
-
 minimist@^1.2.0, minimist@^1.2.6:
   version "1.2.8"
   resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
@@ -1371,7 +1397,7 @@ mz@^2.7.0:
     object-assign "^4.0.1"
     thenify-all "^1.0.0"
 
-nanoid@^3.3.6, nanoid@^3.3.7:
+nanoid@^3.3.7:
   version "3.3.7"
   resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
   integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
@@ -1545,7 +1571,7 @@ postcss-scss@^4.0.8:
   resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-4.0.9.tgz#a03c773cd4c9623cb04ce142a52afcec74806685"
   integrity sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==
 
-postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.7:
+postcss-selector-parser@^6.0.11:
   version "6.0.13"
   resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b"
   integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==
@@ -1558,16 +1584,7 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0:
   resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
   integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
 
-postcss@8.4.29:
-  version "8.4.29"
-  resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.29.tgz#33bc121cf3b3688d4ddef50be869b2a54185a1dd"
-  integrity sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==
-  dependencies:
-    nanoid "^3.3.6"
-    picocolors "^1.0.0"
-    source-map-js "^1.0.2"
-
-postcss@^8.4.23, postcss@^8.4.27, postcss@^8.4.29, postcss@^8.4.4, postcss@^8.4.5:
+postcss@^8.4.23, postcss@^8.4.27, postcss@^8.4.29, postcss@^8.4.5:
   version "8.4.32"
   resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.32.tgz#1dac6ac51ab19adb21b8b34fd2d93a86440ef6c9"
   integrity sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==
@@ -1596,16 +1613,6 @@ punycode@^2.1.0:
   resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
   integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
 
-purgecss@6.0.0-alpha.0:
-  version "6.0.0-alpha.0"
-  resolved "https://registry.yarnpkg.com/purgecss/-/purgecss-6.0.0-alpha.0.tgz#c4a9eef9cc056b6807b4ef3e11f6a12a5f93ec2d"
-  integrity sha512-UC7d7uIyZsky+srEsSXny9BkbTcVn3ZtBCNX3rW3DsqJKhvUXFRpufA4ktcHzWF0+JLZgmsqjUm/8R82x9bHpw==
-  dependencies:
-    commander "^10.0.0"
-    glob "^8.0.3"
-    postcss "^8.4.4"
-    postcss-selector-parser "^6.0.7"
-
 queue-microtask@^1.2.2:
   version "1.2.3"
   resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
@@ -1625,6 +1632,11 @@ readdirp@~3.6.0:
   dependencies:
     picomatch "^2.2.1"
 
+regenerator-runtime@^0.14.0:
+  version "0.14.0"
+  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
+  integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==
+
 resolve-from@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
@@ -1855,20 +1867,82 @@ svelte@^5.0.0-next.17:
     magic-string "^0.30.4"
     zimmerframe "^1.1.0"
 
-tailwindcss@3.3.3:
-  version "3.3.3"
-  resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.3.tgz#90da807393a2859189e48e9e7000e6880a736daf"
-  integrity sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==
+svg.draggable.js@^2.2.2:
+  version "2.2.2"
+  resolved "https://registry.yarnpkg.com/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz#c514a2f1405efb6f0263e7958f5b68fce50603ba"
+  integrity sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==
+  dependencies:
+    svg.js "^2.0.1"
+
+svg.easing.js@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/svg.easing.js/-/svg.easing.js-2.0.0.tgz#8aa9946b0a8e27857a5c40a10eba4091e5691f12"
+  integrity sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==
+  dependencies:
+    svg.js ">=2.3.x"
+
+svg.filter.js@^2.0.2:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/svg.filter.js/-/svg.filter.js-2.0.2.tgz#91008e151389dd9230779fcbe6e2c9a362d1c203"
+  integrity sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==
+  dependencies:
+    svg.js "^2.2.5"
+
+svg.js@>=2.3.x, svg.js@^2.0.1, svg.js@^2.2.5, svg.js@^2.4.0, svg.js@^2.6.5:
+  version "2.7.1"
+  resolved "https://registry.yarnpkg.com/svg.js/-/svg.js-2.7.1.tgz#eb977ed4737001eab859949b4a398ee1bb79948d"
+  integrity sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==
+
+svg.pathmorphing.js@^0.1.3:
+  version "0.1.3"
+  resolved "https://registry.yarnpkg.com/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz#c25718a1cc7c36e852ecabc380e758ac09bb2b65"
+  integrity sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==
+  dependencies:
+    svg.js "^2.4.0"
+
+svg.resize.js@^1.4.3:
+  version "1.4.3"
+  resolved "https://registry.yarnpkg.com/svg.resize.js/-/svg.resize.js-1.4.3.tgz#885abd248e0cd205b36b973c4b578b9a36f23332"
+  integrity sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==
+  dependencies:
+    svg.js "^2.6.5"
+    svg.select.js "^2.1.2"
+
+svg.select.js@^2.1.2:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/svg.select.js/-/svg.select.js-2.1.2.tgz#e41ce13b1acff43a7441f9f8be87a2319c87be73"
+  integrity sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==
+  dependencies:
+    svg.js "^2.2.5"
+
+svg.select.js@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/svg.select.js/-/svg.select.js-3.0.1.tgz#a4198e359f3825739226415f82176a90ea5cc917"
+  integrity sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==
+  dependencies:
+    svg.js "^2.6.5"
+
+tailwind-merge@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.1.0.tgz#541b407e0ec255651e92571d96b685e48f01999c"
+  integrity sha512-l11VvI4nSwW7MtLSLYT4ldidDEUwQAMWuSHk7l4zcXZDgnCRa0V3OdCwFfM7DCzakVXMNRwAeje9maFFXT71dQ==
+  dependencies:
+    "@babel/runtime" "^7.23.5"
+
+tailwindcss@^3.3.6:
+  version "3.3.6"
+  resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.6.tgz#4dd7986bf4902ad385d90d45fd4b2fa5fab26d5f"
+  integrity sha512-AKjF7qbbLvLaPieoKeTjG1+FyNZT6KaJMJPFeQyLfIp7l82ggH1fbHJSsYIvnbTFQOlkh+gBYpyby5GT1LIdLw==
   dependencies:
     "@alloc/quick-lru" "^5.2.0"
     arg "^5.0.2"
     chokidar "^3.5.3"
     didyoumean "^1.2.2"
     dlv "^1.1.3"
-    fast-glob "^3.2.12"
+    fast-glob "^3.3.0"
     glob-parent "^6.0.2"
     is-glob "^4.0.3"
-    jiti "^1.18.2"
+    jiti "^1.19.1"
     lilconfig "^2.1.0"
     micromatch "^4.0.5"
     normalize-path "^3.0.0"
@@ -1961,6 +2035,11 @@ typescript@^5.0.0, typescript@^5.0.3:
   resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.2.tgz#00d1c7c1c46928c5845c1ee8d0cc2791031d4c43"
   integrity sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==
 
+undici-types@~5.26.4:
+  version "5.26.5"
+  resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
+  integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
+
 undici@~5.26.2:
   version "5.26.5"
   resolved "https://registry.yarnpkg.com/undici/-/undici-5.26.5.tgz#f6dc8c565e3cad8c4475b187f51a13e505092838"
@@ -1988,14 +2067,6 @@ util-deprecate@^1.0.2:
   resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
   integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
 
-vite-plugin-tailwind-purgecss@0.1.3:
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/vite-plugin-tailwind-purgecss/-/vite-plugin-tailwind-purgecss-0.1.3.tgz#61f2ccc038cc716412e1ae51b4858bb77a50c9df"
-  integrity sha512-VVz9fwKBEEFSbj/rKxtwtczvoSrIqbzbo6S+MT7gH0CsmKNwlx947VMoV8B085ocxGCuFlddOPRDszNXLi2nTQ==
-  dependencies:
-    estree-walker "^3.0.3"
-    purgecss "6.0.0-alpha.0"
-
 vite@^4.4.2:
   version "4.5.1"
   resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.1.tgz#3370986e1ed5dbabbf35a6c2e1fb1e18555b968a"

From 47aadc9ef561950f2012e85d01cc376d79016271 Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Tue, 5 Dec 2023 19:24:56 +0100
Subject: [PATCH 03/24] Rework Top Level Components to not use Skeleton

---
 src/routes/+layout.svelte | 39 ++++++++------------
 src/routes/Header.svelte  | 76 ++++++++++++++++++++++++---------------
 2 files changed, 62 insertions(+), 53 deletions(-)

diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index df499eb..111c283 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -1,18 +1,19 @@
+<svelte:options runes={true} />
+
 <script lang="ts">
 	import '../app.postcss';
-
-	import { Modal, autoModeWatcher, type ModalComponent, getModalStore, type ModalSettings, initializeStores } from '@skeletonlabs/skeleton';
+	import { browser } from '$app/environment';
+	import { writable } from 'svelte/store';
+	import { themes } from '$lib/types/themes'
 	import { apiBaseUrl } from '$lib/components/consts';
 	import { LeanChellarisDataStore } from '$lib/stores/ChellarisData';
 	import Header from './Header.svelte';
-	import { AppShell } from '@skeletonlabs/skeleton';
 	import Settings from './Settings.svelte';
 	import AdminSelectedGameStore from '$lib/stores/admin-page/GameStore';
 	import type { ChellarisGameInfo } from '$lib/types/chellaris';
+	import UserSettingsStore from '$lib/stores/UserSettingsStore';
 
-	initializeStores();
-
-	$: {
+/*	$: {
 		fetch(apiBaseUrl + '/v3/ethics').then((res) => {
 			res.json().then((data) => {
 				$LeanChellarisDataStore.ethics = data.ethics;
@@ -33,33 +34,23 @@
 				
 			});
 		});
-	}
+	}*/
 
 
 
-	const modalComponentRegistry: Record<string, ModalComponent> = {
-		settingsModal: {
-			ref: Settings,
-			props: { background: 'bg-red-500'}
-		}
-	}
-
 </script>
 
-<svelte:head>{@html `<script>${autoModeWatcher.toString()} autoModeWatcher();</script>`}</svelte:head>
-
-<Modal components={modalComponentRegistry}/>
-
-<AppShell regionPage="relative">
-	<svelte:fragment slot="header">
-		<Header/>
-	</svelte:fragment>
+<div class="
+	bg-{themes[$UserSettingsStore.themeId].backgroundColor}
+	text-{themes[$UserSettingsStore.themeId].textColor}
+	h-full" >
+	<Header/>
 	<!-- (sidebarLeft) -->
 	<!-- (sidebarRight) -->
 	<!-- <svelte:fragment slot="pageHeader">Page Header</svelte:fragment> -->
 	<!-- Router Slot -->
-	<slot />
 	<!-- ---- / ---- -->
 	<!-- (pageFooter) -->
 	<!-- (footer) -->
-</AppShell>
+</div>
+
diff --git a/src/routes/Header.svelte b/src/routes/Header.svelte
index b1b8cab..c97fe29 100644
--- a/src/routes/Header.svelte
+++ b/src/routes/Header.svelte
@@ -1,55 +1,73 @@
 <script lang="ts">
 	import { page } from '$app/stores';
 	import discord from '$lib/images/discord.svg';
-	import { AppBar, LightSwitch, TabAnchor, TabGroup, getModalStore, type ModalSettings } from '@skeletonlabs/skeleton';
 	import Settings from './Settings.svelte';
 	import Button from '$lib/components/Button.svelte';
+	import NavigationElement from '$lib/components/NavigationElement.svelte';
+	import { themes } from '$lib/types/themes';
+	import UserSettingsStore from '$lib/stores/UserSettingsStore';
 
 	let showSettings = false;
 
-	const modalStore = getModalStore();
-
 	const openSettings = () => {
-		const settings: ModalSettings = {
-			type: 'component',
-			component: 'settingsModal'
-		};
-		modalStore.trigger(settings);
+		// open the settings I guess
+	}
+
+	let user = {
+		loggedIn: true, // DEBUG
+		admin: true, // DEBUG
+	}
+
+	function nextTheme() {
+		if ($UserSettingsStore.themeId + 1 < themes.length) {
+			$UserSettingsStore.themeId += 1
+		}
+		else {
+			$UserSettingsStore.themeId = 0
+		}
 	}
 	
 </script>
 
-<AppBar gridColumns="grid-cols-3" slotDefault="place-self-center" slotTrail="place-content-end">
-	<svelte:fragment slot="lead">
-		<p />
-	</svelte:fragment>
-	<TabGroup
-		padding="px-4 py-2"
+<div class="flex gap-2 flex-row">
+	<!-- spacer -->
+	<ul class="flex gap-2 flex-row">
+		<NavigationElement href="/">Home</NavigationElement>
+		<NavigationElement href="/current">Game [Current Game]</NavigationElement>
+		<NavigationElement href="/archive">Archives</NavigationElement>
+		{#if user.loggedIn && user.admin}
+			<NavigationElement href="/admin"></NavigationElement>
+		{/if}
+		<div class="dropdown" href="user.loggedIn ? /account | /login"></div>
+		<Button onclick={nextTheme}>Theme</Button>
+		<NavigationElement href="/settings">Settings</NavigationElement>
+		{#if user.loggedIn}
+			<NavigationElement href="/account">Account</NavigationElement>
+		{:else}
+			<NavigationElement href="/login">Login</NavigationElement>
+		{/if}
+	</ul>
+	<!-- spacer -->
+		<!--padding="px-4 py-2"
 		justify="justify-center"
 		rounded="rounded-tr-xl rounded-tl-xl"
 		border="border-b-2 border-primary-500"
 		active="variant-glass-primary hover:variant-ghost-primary"
-		hover="hover:variant-ghost-primary"
-	>
-		<!--<div aria-current={$page.url.pathname.startsWith('/sign-up') ? 'page' : undefined}>
+		<div aria-current={$page.url.pathname.startsWith('/sign-up') ? 'page' : undefined}>
 		<a href="/sign-up">Empire Sign-Up</a>
 	</div>-->
-		<TabAnchor class="mr-1" href="/" selected={$page.url.pathname === '/'}>Home</TabAnchor>
-		<TabAnchor class="mx-1" href="/graphs" selected={$page.url.pathname.startsWith('/graphs')}>Graphs</TabAnchor>
-		<TabAnchor class="mx-1" href="/legacy-graphs" selected={$page.url.pathname === '/legacy-graphs'}>Game 15 Graphs</TabAnchor>
-		<TabAnchor class="mx-1" href="/admin" selected={$page.url.pathname === '/admin'}>Admin Menu</TabAnchor>
-		<TabAnchor class="ml-1" href="/about" selected={$page.url.pathname === '/about'}>About</TabAnchor>
-	</TabGroup>
+		<!--padding="px-4 py-2"
+		justify="justify-center"
+		rounded="rounded-tr-xl rounded-tl-xl"
+		border="border-b-2 border-primary-500"
+		active="variant-glass-primary hover:variant-ghost-primary"
+		hover="hover:variant-ghost-primary"-->
 
-	<svelte:fragment slot="trail">
-		<Button text="Settings" action={openSettings} />
-			<LightSwitch />
+		<div class="lightswitch" />
 		<div>
 			<!-- Logo -->
 			<a class="lg:!ml-0 w-[32px] lg:w-auto overflow-hidden" href="https://discord.gg/invite/BYNeHaPNh9" target="_blank" rel="noopener noreferrer">
 				<img width="32px" height="32px" src={discord} alt="Discord" />
 			</a>
 		</div>
-	</svelte:fragment>
-</AppBar>
-<div />
+</div>

From f0c66fb4a227e0d4cf6c84f8b9aa443945fc714f Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Tue, 5 Dec 2023 19:25:14 +0100
Subject: [PATCH 04/24] move Svelte-4 components to legacy route

---
 src/routes/legacy/graphs/+layout.svelte  | 2 +-
 src/routes/legacy/graphs/+layout.ts      | 4 ++--
 src/routes/legacy/legacy-graphs/+page.ts | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/routes/legacy/graphs/+layout.svelte b/src/routes/legacy/graphs/+layout.svelte
index bd82165..31030e5 100644
--- a/src/routes/legacy/graphs/+layout.svelte
+++ b/src/routes/legacy/graphs/+layout.svelte
@@ -1,6 +1,6 @@
 <script lang="ts">
 	import SubNav from './SubNav.svelte';
-	import '../../app.postcss';
+	import '../../../app.postcss';
 	import { goto } from "$app/navigation";
 	import { page } from "$app/stores";
 	import GraphsTabStore from '$lib/stores/GraphsTab';
diff --git a/src/routes/legacy/graphs/+layout.ts b/src/routes/legacy/graphs/+layout.ts
index 0541d0b..9591a8b 100644
--- a/src/routes/legacy/graphs/+layout.ts
+++ b/src/routes/legacy/graphs/+layout.ts
@@ -2,8 +2,8 @@ import ChellarisDataStore from '$lib/stores/ChellarisData';
 import SelectedGameStore from '$lib/stores/GameFilter';
 import SelectedGameGroupsStore, { type SelectedChellarisGroups } from "$lib/stores/GameGroupFilter";
 import GraphsTabStore from '$lib/stores/GraphsTab';
-import type { LayoutLoad } from "./$types";
-import type { ChellarisInfo } from '../../lib/types/chellaris';
+import type { LayoutLoad } from "../../../../.svelte-kit/types/src/routes";
+import type { ChellarisInfo } from '$lib/types/chellaris';
 import { apiBaseUrl } from '$lib/components/consts';
 
 export const load: LayoutLoad = async ({ fetch }) => {
diff --git a/src/routes/legacy/legacy-graphs/+page.ts b/src/routes/legacy/legacy-graphs/+page.ts
index e0d0ebd..df462e4 100644
--- a/src/routes/legacy/legacy-graphs/+page.ts
+++ b/src/routes/legacy/legacy-graphs/+page.ts
@@ -1,5 +1,5 @@
 import { apiBaseUrl } from "$lib/components/consts";
-import type { PageLoad } from "../$types";
+import type { PageLoad } from "../../../../.svelte-kit/types/src/routes";
 
 export const  load: PageLoad = async ({ fetch }) => {
   const popsRet: { speciesArray: Array<number> } = await (await fetch(apiBaseUrl + '/v1/species')).json();

From fdbb265ae62fd22c520c8e95fa307bb903203487 Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Tue, 5 Dec 2023 19:25:34 +0100
Subject: [PATCH 05/24] Modify some lib components for Svelte 5

---
 src/lib/components/Button.svelte            | 12 ++++++---
 src/lib/components/NavigationElement.svelte |  8 ++++++
 src/lib/stores/UserSettingsStore.ts         |  6 +++++
 src/lib/types/themes.ts                     | 27 +++++++++++++++++++++
 src/lib/types/userSettings.ts               |  8 ++++++
 5 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/src/lib/components/Button.svelte b/src/lib/components/Button.svelte
index a046d0b..72e5cc9 100644
--- a/src/lib/components/Button.svelte
+++ b/src/lib/components/Button.svelte
@@ -1,6 +1,12 @@
+<svelte:options runes={true} />
+
 <script lang="ts">
-	export let text: string;
-	export let action: any = () => {};
+	import UserSettingsStore from '$lib/stores/UserSettingsStore';
+	import { themes } from '$lib/types/themes';
+
+	let {children, onclick} = $props()
+
+	let themeId = $derived($UserSettingsStore.themeId)
 </script>
 
-<button class="btn px-4 py-2 mx-2 rounded-token variant-ringed-primary hover:variant-filled-primary active:variant-filled-primary" on:click={action}>{text}</button>
+<button {onclick} class="border-2 border-{themes[themeId].primaryAction} hover:border-{themes[themeId].secondaryAction}">{@render children()}</button>
diff --git a/src/lib/components/NavigationElement.svelte b/src/lib/components/NavigationElement.svelte
index e69de29..41e8e48 100644
--- a/src/lib/components/NavigationElement.svelte
+++ b/src/lib/components/NavigationElement.svelte
@@ -0,0 +1,8 @@
+<script lang="ts">
+	let {href} = $props()
+	// {$page.url.pathname === '/'}
+</script>
+
+<li>
+	<a {href}><slot /></a>
+</li>
\ No newline at end of file
diff --git a/src/lib/stores/UserSettingsStore.ts b/src/lib/stores/UserSettingsStore.ts
index e69de29..b3cf208 100644
--- a/src/lib/stores/UserSettingsStore.ts
+++ b/src/lib/stores/UserSettingsStore.ts
@@ -0,0 +1,6 @@
+import { writable, type Writable } from "svelte/store";
+import { UserSettings } from '$lib/types/userSettings';
+
+const UserSettingsStore: Writable<UserSettings> = writable(new UserSettings());
+
+export default UserSettingsStore;
\ No newline at end of file
diff --git a/src/lib/types/themes.ts b/src/lib/types/themes.ts
index e69de29..8578112 100644
--- a/src/lib/types/themes.ts
+++ b/src/lib/types/themes.ts
@@ -0,0 +1,27 @@
+export type Theme = {
+	backgroundColor: string,
+	textColor: string,
+	primaryAction: string,
+	secondaryAction: string,
+}
+const lightTheme = {
+	backgroundColor: "slate-50",
+	textColor:  "slate-950",
+	primaryAction: "sky-300",
+	secondaryAction: "sky-600",
+}
+
+const darkTheme = {
+	backgroundColor: "slate-950",
+	textColor: "slate-50",
+	primaryAction: "sky-300",
+	secondaryAction: "sky-600",
+}
+
+export const themes = [
+	lightTheme,
+	darkTheme
+]
+
+
+
diff --git a/src/lib/types/userSettings.ts b/src/lib/types/userSettings.ts
index e69de29..0fa295e 100644
--- a/src/lib/types/userSettings.ts
+++ b/src/lib/types/userSettings.ts
@@ -0,0 +1,8 @@
+export class UserSettings {
+	themeId: number
+
+	constructor() {
+		this.themeId = 1 // DEBUG
+		return this
+	}
+}
\ No newline at end of file

From 4eef07de011f1125844d810a77e9bcbea39c7014 Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Tue, 5 Dec 2023 20:27:38 +0100
Subject: [PATCH 06/24] Dummy content

---
 src/routes/+layout.svelte                | 3 +--
 src/routes/+page.svelte                  | 9 ++++++---
 src/routes/archive/+page.svelte          | 6 ++++++
 src/routes/archive/[gameId]/+page.svelte | 8 ++++++++
 src/routes/archive/[gameId]/+page.ts     | 8 ++++++++
 src/routes/current/+page.svelte          | 3 +++
 src/routes/login/+page.svelte            | 3 +++
 src/routes/settings/+page.svelte         | 3 +++
 8 files changed, 38 insertions(+), 5 deletions(-)
 create mode 100644 src/routes/archive/[gameId]/+page.svelte
 create mode 100644 src/routes/archive/[gameId]/+page.ts
 create mode 100644 src/routes/login/+page.svelte

diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index 111c283..e298d02 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -36,8 +36,6 @@
 		});
 	}*/
 
-
-
 </script>
 
 <div class="
@@ -45,6 +43,7 @@
 	text-{themes[$UserSettingsStore.themeId].textColor}
 	h-full" >
 	<Header/>
+	<slot />
 	<!-- (sidebarLeft) -->
 	<!-- (sidebarRight) -->
 	<!-- <svelte:fragment slot="pageHeader">Page Header</svelte:fragment> -->
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 7e2e4a5..679ee1c 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -1,13 +1,16 @@
 <!-- YOU CAN DELETE EVERYTHING IN THIS PAGE -->
+<script lang="ts">
+</script>
 
-<div class="container h-full mx-auto flex justify-center items-center">
+<div class="container h-full mx-auto flex flex-col justify-center items-center">
+	<h1>Chellaris</h1>
 	<div class="space-y-5">
 		<ul>
 			<li>
-				<a class="hover:text-primary-500" href="/graphs">Graphs</a>
+				<a class="hover:text-primary-500" href="/current">Current Game</a>
 			</li>
 			<li>
-				<a class="hover:text-primary-500" href="/legacy-graphs">Game 15 Graphs</a>
+				<a class="hover:text-primary-500" href="/archive/1">Previous Game</a>
 			</li>
 		</ul>
 	</div>
diff --git a/src/routes/archive/+page.svelte b/src/routes/archive/+page.svelte
index e69de29..26dd315 100644
--- a/src/routes/archive/+page.svelte
+++ b/src/routes/archive/+page.svelte
@@ -0,0 +1,6 @@
+<script lang="ts">
+</script>
+
+<div>
+	PREVIOUS GAMES PAGE
+</div>
\ No newline at end of file
diff --git a/src/routes/archive/[gameId]/+page.svelte b/src/routes/archive/[gameId]/+page.svelte
new file mode 100644
index 0000000..28de675
--- /dev/null
+++ b/src/routes/archive/[gameId]/+page.svelte
@@ -0,0 +1,8 @@
+<script lang="ts">
+	import type { PageData } from './$types'
+	export let data: PageData;
+</script>
+
+<div>
+	PREVIOUS GAME {data.gameId} PAGE
+</div>
\ No newline at end of file
diff --git a/src/routes/archive/[gameId]/+page.ts b/src/routes/archive/[gameId]/+page.ts
new file mode 100644
index 0000000..615ae85
--- /dev/null
+++ b/src/routes/archive/[gameId]/+page.ts
@@ -0,0 +1,8 @@
+import { error } from '@sveltejs/kit';
+
+/** @type {import('./$types').PageLoad} */
+export function load({ params }) {
+	return {
+		gameId: params.gameId
+	}
+}
\ No newline at end of file
diff --git a/src/routes/current/+page.svelte b/src/routes/current/+page.svelte
index e69de29..3e66a31 100644
--- a/src/routes/current/+page.svelte
+++ b/src/routes/current/+page.svelte
@@ -0,0 +1,3 @@
+<div>
+	CURRENT GAME PAGE
+</div>
\ No newline at end of file
diff --git a/src/routes/login/+page.svelte b/src/routes/login/+page.svelte
new file mode 100644
index 0000000..9a179ee
--- /dev/null
+++ b/src/routes/login/+page.svelte
@@ -0,0 +1,3 @@
+<div>
+	LOGIN PAGE
+</div>
\ No newline at end of file
diff --git a/src/routes/settings/+page.svelte b/src/routes/settings/+page.svelte
index e69de29..a264b02 100644
--- a/src/routes/settings/+page.svelte
+++ b/src/routes/settings/+page.svelte
@@ -0,0 +1,3 @@
+<div>
+	SETTINGS PAGE
+</div>
\ No newline at end of file

From 8da05a33cb3ee906072ad66876f0330447b8bed8 Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Wed, 6 Dec 2023 21:00:13 +0100
Subject: [PATCH 07/24] Move Components to new Directory

---
 src/lib/components/consts.ts                               | 2 --
 src/lib/{components => components_custom}/Button.svelte    | 0
 src/lib/{components => components_custom}/DropDown.svelte  | 0
 .../DropDownElement.svelte                                 | 0
 .../LoadingSpinner.svelte                                  | 0
 .../LoadingSpinnerLocal.svelte                             | 0
 src/lib/components_custom/consts.ts                        | 2 ++
 src/routes/+layout.svelte                                  | 2 +-
 src/routes/Settings.svelte                                 | 7 ++-----
 src/routes/admin/+page.server.ts                           | 2 +-
 src/routes/admin/+page.svelte                              | 4 ++--
 src/routes/admin/+page.ts                                  | 2 +-
 src/routes/admin/EmpireDetails.svelte                      | 6 +++---
 src/routes/legacy/graphs/+layout.ts                        | 2 +-
 src/routes/legacy/graphs/GameGroupSelection.svelte         | 4 ++--
 src/routes/legacy/graphs/GameSelection.svelte              | 4 ++--
 src/routes/legacy/graphs/excel-style/+page.svelte          | 2 +-
 src/routes/legacy/legacy-graphs/+page.svelte               | 2 +-
 src/routes/legacy/legacy-graphs/+page.ts                   | 2 +-
 19 files changed, 20 insertions(+), 23 deletions(-)
 delete mode 100644 src/lib/components/consts.ts
 rename src/lib/{components => components_custom}/Button.svelte (100%)
 rename src/lib/{components => components_custom}/DropDown.svelte (100%)
 rename src/lib/{components => components_custom}/DropDownElement.svelte (100%)
 rename src/lib/{components => components_custom}/LoadingSpinner.svelte (100%)
 rename src/lib/{components => components_custom}/LoadingSpinnerLocal.svelte (100%)
 create mode 100644 src/lib/components_custom/consts.ts

diff --git a/src/lib/components/consts.ts b/src/lib/components/consts.ts
deleted file mode 100644
index de9f2a5..0000000
--- a/src/lib/components/consts.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export const apiBaseUrl = 'https://wip.chellaris.net/api';
-export const MACHINE_GROUP_ID = 12;
\ No newline at end of file
diff --git a/src/lib/components/Button.svelte b/src/lib/components_custom/Button.svelte
similarity index 100%
rename from src/lib/components/Button.svelte
rename to src/lib/components_custom/Button.svelte
diff --git a/src/lib/components/DropDown.svelte b/src/lib/components_custom/DropDown.svelte
similarity index 100%
rename from src/lib/components/DropDown.svelte
rename to src/lib/components_custom/DropDown.svelte
diff --git a/src/lib/components/DropDownElement.svelte b/src/lib/components_custom/DropDownElement.svelte
similarity index 100%
rename from src/lib/components/DropDownElement.svelte
rename to src/lib/components_custom/DropDownElement.svelte
diff --git a/src/lib/components/LoadingSpinner.svelte b/src/lib/components_custom/LoadingSpinner.svelte
similarity index 100%
rename from src/lib/components/LoadingSpinner.svelte
rename to src/lib/components_custom/LoadingSpinner.svelte
diff --git a/src/lib/components/LoadingSpinnerLocal.svelte b/src/lib/components_custom/LoadingSpinnerLocal.svelte
similarity index 100%
rename from src/lib/components/LoadingSpinnerLocal.svelte
rename to src/lib/components_custom/LoadingSpinnerLocal.svelte
diff --git a/src/lib/components_custom/consts.ts b/src/lib/components_custom/consts.ts
new file mode 100644
index 0000000..ee213af
--- /dev/null
+++ b/src/lib/components_custom/consts.ts
@@ -0,0 +1,2 @@
+export const apiBaseUrl = 'https://www.chellaris.net/api';
+export const MACHINE_GROUP_ID = 12;
\ No newline at end of file
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index e298d02..6ecd8e0 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -5,7 +5,7 @@
 	import { browser } from '$app/environment';
 	import { writable } from 'svelte/store';
 	import { themes } from '$lib/types/themes'
-	import { apiBaseUrl } from '$lib/components/consts';
+	import { apiBaseUrl } from '$lib/components_custom/consts';
 	import { LeanChellarisDataStore } from '$lib/stores/ChellarisData';
 	import Header from './Header.svelte';
 	import Settings from './Settings.svelte';
diff --git a/src/routes/Settings.svelte b/src/routes/Settings.svelte
index 2abc279..bce137d 100644
--- a/src/routes/Settings.svelte
+++ b/src/routes/Settings.svelte
@@ -1,12 +1,9 @@
 <script lang="ts">
 	import { browser } from "$app/environment";
-	import Button from "$lib/components/Button.svelte";
+	import Button from "$lib/components_custom/Button.svelte";
 	import AuthTokenStore from "$lib/stores/AuthTokenStore";
-	import { getModalStore } from "@skeletonlabs/skeleton";
 	import { fade, slide } from "svelte/transition";
 
-  const modalStore = getModalStore();
-
   let showAuthSaved = false;
   let showPlaceholder = true;
 
@@ -32,7 +29,7 @@
   const handleSubmit = () => {
     console.log("submitted ", gameGroupSettings);
     document.cookie = "authToken=" + authToken;
-    modalStore.close();
+    // somehow close the modal
   }
 
   let gameGroupSettings: [] = [];
diff --git a/src/routes/admin/+page.server.ts b/src/routes/admin/+page.server.ts
index c2ec326..095d527 100644
--- a/src/routes/admin/+page.server.ts
+++ b/src/routes/admin/+page.server.ts
@@ -1,4 +1,4 @@
-import { apiBaseUrl } from "$lib/components/consts";
+import { apiBaseUrl } from "$lib/components_custom/consts";
 import { redirect } from "@sveltejs/kit";
 
 export async function load({ cookies }) {
diff --git a/src/routes/admin/+page.svelte b/src/routes/admin/+page.svelte
index 08820c1..b3a0629 100644
--- a/src/routes/admin/+page.svelte
+++ b/src/routes/admin/+page.svelte
@@ -1,7 +1,7 @@
 <script lang="ts">
 	import { browser } from '$app/environment';
-	import LoadingSpinnerLocal from '$lib/components/LoadingSpinnerLocal.svelte';
-	import { apiBaseUrl } from '$lib/components/consts';
+	import LoadingSpinnerLocal from '$lib/components_custom/LoadingSpinnerLocal.svelte';
+	import { apiBaseUrl } from '$lib/components_custom/consts';
 	import AuthTokenStore from '$lib/stores/AuthTokenStore';
 	import AdminSelectedEmpireStore from '$lib/stores/admin-page/EmpireStore';
 	import AdminSelectedGameStore from '$lib/stores/admin-page/GameStore';
diff --git a/src/routes/admin/+page.ts b/src/routes/admin/+page.ts
index cfcaf41..7f1afa1 100644
--- a/src/routes/admin/+page.ts
+++ b/src/routes/admin/+page.ts
@@ -1,4 +1,4 @@
-import { apiBaseUrl } from "$lib/components/consts";
+import { apiBaseUrl } from "$lib/components_custom/consts";
 import AdminSelectedEmpireStore from "$lib/stores/admin-page/EmpireStore";
 import AdminSelectedGameStore from "$lib/stores/admin-page/GameStore";
 import type { ChellarisGameInfo } from "$lib/types/chellaris";
diff --git a/src/routes/admin/EmpireDetails.svelte b/src/routes/admin/EmpireDetails.svelte
index 5b78bee..6b68cc8 100644
--- a/src/routes/admin/EmpireDetails.svelte
+++ b/src/routes/admin/EmpireDetails.svelte
@@ -1,7 +1,7 @@
 <script lang="ts">
-	import DropDown from '$lib/components/DropDown.svelte';
-	import DropDownElement from '$lib/components/DropDownElement.svelte';
-	import { MACHINE_GROUP_ID, apiBaseUrl } from '$lib/components/consts';
+	import DropDown from '$lib/components_custom/DropDown.svelte';
+	import DropDownElement from '$lib/components_custom/DropDownElement.svelte';
+	import { MACHINE_GROUP_ID, apiBaseUrl } from '$lib/components_custom/consts';
 	import { LeanChellarisDataStore } from '$lib/stores/ChellarisData';
 	import type { ChellarisEmpire, ChellarisGameGroup } from '$lib/types/chellaris';
 	import type { EmpireEthic } from '$lib/types/stellaris';
diff --git a/src/routes/legacy/graphs/+layout.ts b/src/routes/legacy/graphs/+layout.ts
index 9591a8b..c1116df 100644
--- a/src/routes/legacy/graphs/+layout.ts
+++ b/src/routes/legacy/graphs/+layout.ts
@@ -4,7 +4,7 @@ import SelectedGameGroupsStore, { type SelectedChellarisGroups } from "$lib/stor
 import GraphsTabStore from '$lib/stores/GraphsTab';
 import type { LayoutLoad } from "../../../../.svelte-kit/types/src/routes";
 import type { ChellarisInfo } from '$lib/types/chellaris';
-import { apiBaseUrl } from '$lib/components/consts';
+import { apiBaseUrl } from '$lib/components_custom/consts';
 
 export const load: LayoutLoad = async ({ fetch }) => {
   let store: string | null;
diff --git a/src/routes/legacy/graphs/GameGroupSelection.svelte b/src/routes/legacy/graphs/GameGroupSelection.svelte
index 22384c5..1491983 100644
--- a/src/routes/legacy/graphs/GameGroupSelection.svelte
+++ b/src/routes/legacy/graphs/GameGroupSelection.svelte
@@ -1,6 +1,6 @@
 <script lang="ts">
-	import DropDown from '$lib/components/DropDown.svelte';
-	import DropDownElement from '$lib/components/DropDownElement.svelte';
+	import DropDown from '$lib/components_custom/DropDown.svelte';
+	import DropDownElement from '$lib/components_custom/DropDownElement.svelte';
 	import SelectedGameGroupsStore from '$lib/stores/GameGroupFilter';
 	import SelectedGameStore from '$lib/stores/GameFilter';
 	import ChellarisDataStore from '$lib/stores/ChellarisData';
diff --git a/src/routes/legacy/graphs/GameSelection.svelte b/src/routes/legacy/graphs/GameSelection.svelte
index 11d2017..6d8e5f5 100644
--- a/src/routes/legacy/graphs/GameSelection.svelte
+++ b/src/routes/legacy/graphs/GameSelection.svelte
@@ -1,6 +1,6 @@
 <script lang="ts">
-	import DropDown from '$lib/components/DropDown.svelte';
-	import DropDownElement from '$lib/components/DropDownElement.svelte';
+	import DropDown from '$lib/components_custom/DropDown.svelte';
+	import DropDownElement from '$lib/components_custom/DropDownElement.svelte';
 	import SelectedGameStore from '$lib/stores/GameFilter';
 	import ChellarisDataStore from '$lib/stores/ChellarisData';
 
diff --git a/src/routes/legacy/graphs/excel-style/+page.svelte b/src/routes/legacy/graphs/excel-style/+page.svelte
index 7236806..b065e61 100644
--- a/src/routes/legacy/graphs/excel-style/+page.svelte
+++ b/src/routes/legacy/graphs/excel-style/+page.svelte
@@ -4,7 +4,7 @@
 	import type { ChellarisGameGroup, ChellarisInfo, ChellarisEmpire, ChellarisGame } from '$lib/types/chellaris';
 	import ChellarisDataStore from '$lib/stores/ChellarisData';
 	import GraphsTabStore from '$lib/stores/GraphsTab';
-	import LoadingSpinner from '$lib/components/LoadingSpinner.svelte';
+	import LoadingSpinner from '$lib/components_custom/LoadingSpinner.svelte';
 
 	$: selectedGame = $ChellarisDataStore.games[$SelectedGameStore];
 	$: selectedGameGroupData = $SelectedGameGroupsStore[$SelectedGameStore];
diff --git a/src/routes/legacy/legacy-graphs/+page.svelte b/src/routes/legacy/legacy-graphs/+page.svelte
index 24a771a..13a7053 100644
--- a/src/routes/legacy/legacy-graphs/+page.svelte
+++ b/src/routes/legacy/legacy-graphs/+page.svelte
@@ -3,7 +3,7 @@
 	import EthicsBar from './EthicsBar.svelte';
 	import PopsPie from './PopsPie.svelte';
 	import EmpireStats from './EmpireStats.svelte';
-	import LoadingSpinner from '$lib/components/LoadingSpinner.svelte';
+	import LoadingSpinner from '$lib/components_custom/LoadingSpinner.svelte';
 	import { navigating } from '$app/stores';
 	import { fade } from 'svelte/transition';
 
diff --git a/src/routes/legacy/legacy-graphs/+page.ts b/src/routes/legacy/legacy-graphs/+page.ts
index df462e4..179df87 100644
--- a/src/routes/legacy/legacy-graphs/+page.ts
+++ b/src/routes/legacy/legacy-graphs/+page.ts
@@ -1,4 +1,4 @@
-import { apiBaseUrl } from "$lib/components/consts";
+import { apiBaseUrl } from "$lib/components_custom/consts";
 import type { PageLoad } from "../../../../.svelte-kit/types/src/routes";
 
 export const  load: PageLoad = async ({ fetch }) => {

From 3fd683b6eeeab26822de4a3a7cff1952b2b956b2 Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Wed, 6 Dec 2023 21:00:46 +0100
Subject: [PATCH 08/24] Add shadcn UI

---
 .../ui/avatar/avatar-fallback.svelte          | 19 ++++++
 .../components/ui/avatar/avatar-image.svelte  | 18 ++++++
 src/lib/components/ui/avatar/avatar.svelte    | 21 +++++++
 src/lib/components/ui/avatar/index.ts         | 13 ++++
 src/lib/components/ui/button/button.svelte    | 25 ++++++++
 src/lib/components/ui/button/index.ts         | 52 ++++++++++++++++
 .../dropdown-menu-checkbox-item.svelte        | 35 +++++++++++
 .../dropdown-menu-content.svelte              | 26 ++++++++
 .../dropdown-menu/dropdown-menu-item.svelte   | 31 ++++++++++
 .../dropdown-menu/dropdown-menu-label.svelte  | 19 ++++++
 .../dropdown-menu-radio-group.svelte          | 11 ++++
 .../dropdown-menu-radio-item.svelte           | 35 +++++++++++
 .../dropdown-menu-separator.svelte            | 14 +++++
 .../dropdown-menu-shortcut.svelte             | 16 +++++
 .../dropdown-menu-sub-content.svelte          | 29 +++++++++
 .../dropdown-menu-sub-trigger.svelte          | 32 ++++++++++
 src/lib/components/ui/dropdown-menu/index.ts  | 48 ++++++++++++++
 src/lib/components/ui/menubar/index.ts        | 52 ++++++++++++++++
 .../ui/menubar/menubar-checkbox-item.svelte   | 33 ++++++++++
 .../ui/menubar/menubar-content.svelte         | 28 +++++++++
 .../components/ui/menubar/menubar-item.svelte | 31 ++++++++++
 .../ui/menubar/menubar-label.svelte           | 18 ++++++
 .../ui/menubar/menubar-radio-item.svelte      | 34 ++++++++++
 .../ui/menubar/menubar-separator.svelte       | 13 ++++
 .../ui/menubar/menubar-shortcut.svelte        | 18 ++++++
 .../ui/menubar/menubar-sub-content.svelte     | 25 ++++++++
 .../ui/menubar/menubar-sub-trigger.svelte     | 32 ++++++++++
 .../ui/menubar/menubar-trigger.svelte         | 23 +++++++
 src/lib/components/ui/menubar/menubar.svelte  | 18 ++++++
 src/lib/components/ui/separator/index.ts      |  7 +++
 .../components/ui/separator/separator.svelte  | 22 +++++++
 src/lib/utils.ts                              | 62 +++++++++++++++++++
 32 files changed, 860 insertions(+)
 create mode 100644 src/lib/components/ui/avatar/avatar-fallback.svelte
 create mode 100644 src/lib/components/ui/avatar/avatar-image.svelte
 create mode 100644 src/lib/components/ui/avatar/avatar.svelte
 create mode 100644 src/lib/components/ui/avatar/index.ts
 create mode 100644 src/lib/components/ui/button/button.svelte
 create mode 100644 src/lib/components/ui/button/index.ts
 create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte
 create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte
 create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte
 create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte
 create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte
 create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte
 create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte
 create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte
 create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte
 create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte
 create mode 100644 src/lib/components/ui/dropdown-menu/index.ts
 create mode 100644 src/lib/components/ui/menubar/index.ts
 create mode 100644 src/lib/components/ui/menubar/menubar-checkbox-item.svelte
 create mode 100644 src/lib/components/ui/menubar/menubar-content.svelte
 create mode 100644 src/lib/components/ui/menubar/menubar-item.svelte
 create mode 100644 src/lib/components/ui/menubar/menubar-label.svelte
 create mode 100644 src/lib/components/ui/menubar/menubar-radio-item.svelte
 create mode 100644 src/lib/components/ui/menubar/menubar-separator.svelte
 create mode 100644 src/lib/components/ui/menubar/menubar-shortcut.svelte
 create mode 100644 src/lib/components/ui/menubar/menubar-sub-content.svelte
 create mode 100644 src/lib/components/ui/menubar/menubar-sub-trigger.svelte
 create mode 100644 src/lib/components/ui/menubar/menubar-trigger.svelte
 create mode 100644 src/lib/components/ui/menubar/menubar.svelte
 create mode 100644 src/lib/components/ui/separator/index.ts
 create mode 100644 src/lib/components/ui/separator/separator.svelte
 create mode 100644 src/lib/utils.ts

diff --git a/src/lib/components/ui/avatar/avatar-fallback.svelte b/src/lib/components/ui/avatar/avatar-fallback.svelte
new file mode 100644
index 0000000..3b9b24c
--- /dev/null
+++ b/src/lib/components/ui/avatar/avatar-fallback.svelte
@@ -0,0 +1,19 @@
+<script lang="ts">
+	import { Avatar as AvatarPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+
+	type $$Props = AvatarPrimitive.FallbackProps;
+
+	let className: $$Props["class"] = undefined;
+	export { className as class };
+</script>
+
+<AvatarPrimitive.Fallback
+	class={cn(
+		"flex h-full w-full items-center justify-center rounded-full bg-muted",
+		className
+	)}
+	{...$$restProps}
+>
+	<slot />
+</AvatarPrimitive.Fallback>
diff --git a/src/lib/components/ui/avatar/avatar-image.svelte b/src/lib/components/ui/avatar/avatar-image.svelte
new file mode 100644
index 0000000..27b0e7d
--- /dev/null
+++ b/src/lib/components/ui/avatar/avatar-image.svelte
@@ -0,0 +1,18 @@
+<script lang="ts">
+	import { Avatar as AvatarPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+
+	type $$Props = AvatarPrimitive.ImageProps;
+
+	let className: $$Props["class"] = undefined;
+	export let src: $$Props["src"] = undefined;
+	export let alt: $$Props["alt"] = undefined;
+	export { className as class };
+</script>
+
+<AvatarPrimitive.Image
+	{src}
+	{alt}
+	class={cn("aspect-square h-full w-full", className)}
+	{...$$restProps}
+/>
diff --git a/src/lib/components/ui/avatar/avatar.svelte b/src/lib/components/ui/avatar/avatar.svelte
new file mode 100644
index 0000000..b8a6ee1
--- /dev/null
+++ b/src/lib/components/ui/avatar/avatar.svelte
@@ -0,0 +1,21 @@
+<script lang="ts">
+	import { Avatar as AvatarPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+
+	type $$Props = AvatarPrimitive.Props;
+
+	let className: $$Props["class"] = undefined;
+	export let delayMs: $$Props["delayMs"] = undefined;
+	export { className as class };
+</script>
+
+<AvatarPrimitive.Root
+	{delayMs}
+	class={cn(
+		"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
+		className
+	)}
+	{...$$restProps}
+>
+	<slot />
+</AvatarPrimitive.Root>
diff --git a/src/lib/components/ui/avatar/index.ts b/src/lib/components/ui/avatar/index.ts
new file mode 100644
index 0000000..b08c780
--- /dev/null
+++ b/src/lib/components/ui/avatar/index.ts
@@ -0,0 +1,13 @@
+import Root from "./avatar.svelte";
+import Image from "./avatar-image.svelte";
+import Fallback from "./avatar-fallback.svelte";
+
+export {
+	Root,
+	Image,
+	Fallback,
+	//
+	Root as Avatar,
+	Image as AvatarImage,
+	Fallback as AvatarFallback
+};
diff --git a/src/lib/components/ui/button/button.svelte b/src/lib/components/ui/button/button.svelte
new file mode 100644
index 0000000..a128f14
--- /dev/null
+++ b/src/lib/components/ui/button/button.svelte
@@ -0,0 +1,25 @@
+<script lang="ts">
+	import { Button as ButtonPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+	import { buttonVariants, type Props, type Events } from ".";
+
+	type $$Props = Props;
+	type $$Events = Events;
+
+	let className: $$Props["class"] = undefined;
+	export let variant: $$Props["variant"] = "default";
+	export let size: $$Props["size"] = "default";
+	export let builders: $$Props["builders"] = [];
+	export { className as class };
+</script>
+
+<ButtonPrimitive.Root
+	{builders}
+	class={cn(buttonVariants({ variant, size, className }))}
+	type="button"
+	{...$$restProps}
+	on:click
+	on:keydown
+>
+	<slot />
+</ButtonPrimitive.Root>
diff --git a/src/lib/components/ui/button/index.ts b/src/lib/components/ui/button/index.ts
new file mode 100644
index 0000000..9787e3e
--- /dev/null
+++ b/src/lib/components/ui/button/index.ts
@@ -0,0 +1,52 @@
+import type { Button as ButtonPrimitive } from "bits-ui";
+import { tv, type VariantProps } from "tailwind-variants";
+import Root from "./button.svelte";
+
+const buttonVariants = tv({
+	base: "inline-flex items-center justify-center rounded-md text-sm font-medium whitespace-nowrap transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
+	variants: {
+		variant: {
+			default:
+				"bg-primary text-primary-foreground shadow hover:bg-primary/90",
+			destructive:
+				"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
+			outline:
+				"border border-input bg-transparent shadow-sm hover:bg-accent hover:text-accent-foreground",
+			secondary:
+				"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
+			ghost: "hover:bg-accent hover:text-accent-foreground",
+			link: "text-primary underline-offset-4 hover:underline"
+		},
+		size: {
+			default: "h-9 px-4 py-2",
+			sm: "h-8 rounded-md px-3 text-xs",
+			lg: "h-10 rounded-md px-8",
+			icon: "h-9 w-9"
+		}
+	},
+	defaultVariants: {
+		variant: "default",
+		size: "default"
+	}
+});
+
+type Variant = VariantProps<typeof buttonVariants>["variant"];
+type Size = VariantProps<typeof buttonVariants>["size"];
+
+type Props = ButtonPrimitive.Props & {
+	variant?: Variant;
+	size?: Size;
+};
+
+type Events = ButtonPrimitive.Events;
+
+export {
+	Root,
+	type Props,
+	type Events,
+	//
+	Root as Button,
+	type Props as ButtonProps,
+	type Events as ButtonEvents,
+	buttonVariants
+};
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte
new file mode 100644
index 0000000..727dbd5
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte
@@ -0,0 +1,35 @@
+<script lang="ts">
+	import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+	import { Check } from "radix-icons-svelte";
+
+	type $$Props = DropdownMenuPrimitive.CheckboxItemProps;
+	type $$Events = DropdownMenuPrimitive.CheckboxItemEvents;
+
+	let className: $$Props["class"] = undefined;
+	export let checked: $$Props["checked"] = undefined;
+	export { className as class };
+</script>
+
+<DropdownMenuPrimitive.CheckboxItem
+	bind:checked
+	class={cn(
+		"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
+		className
+	)}
+	{...$$restProps}
+	on:click
+	on:keydown
+	on:focusin
+	on:focusout
+	on:pointerdown
+	on:pointerleave
+	on:pointermove
+>
+	<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
+		<DropdownMenuPrimitive.CheckboxIndicator>
+			<Check class="h-4 w-4" />
+		</DropdownMenuPrimitive.CheckboxIndicator>
+	</span>
+	<slot />
+</DropdownMenuPrimitive.CheckboxItem>
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte
new file mode 100644
index 0000000..3d09fe9
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte
@@ -0,0 +1,26 @@
+<script lang="ts">
+	import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
+	import { cn, flyAndScale } from "$lib/utils";
+
+	type $$Props = DropdownMenuPrimitive.ContentProps;
+
+	let className: $$Props["class"] = undefined;
+	export let sideOffset: $$Props["sideOffset"] = 4;
+	export let transition: $$Props["transition"] = flyAndScale;
+	export let transitionConfig: $$Props["transitionConfig"] = undefined;
+	export { className as class };
+</script>
+
+<DropdownMenuPrimitive.Content
+	{transition}
+	{transitionConfig}
+	{sideOffset}
+	class={cn(
+		"z-50 min-w-[8rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none",
+		className
+	)}
+	{...$$restProps}
+	on:keydown
+>
+	<slot />
+</DropdownMenuPrimitive.Content>
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte
new file mode 100644
index 0000000..aaf9d71
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte
@@ -0,0 +1,31 @@
+<script lang="ts">
+	import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+
+	type $$Props = DropdownMenuPrimitive.ItemProps & {
+		inset?: boolean;
+	};
+	type $$Events = DropdownMenuPrimitive.ItemEvents;
+
+	let className: $$Props["class"] = undefined;
+	export let inset: $$Props["inset"] = undefined;
+	export { className as class };
+</script>
+
+<DropdownMenuPrimitive.Item
+	class={cn(
+		"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
+		inset && "pl-8",
+		className
+	)}
+	on:click
+	on:keydown
+	on:focusin
+	on:focusout
+	on:pointerdown
+	on:pointerleave
+	on:pointermove
+	{...$$restProps}
+>
+	<slot />
+</DropdownMenuPrimitive.Item>
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte
new file mode 100644
index 0000000..a7fb3c4
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte
@@ -0,0 +1,19 @@
+<script lang="ts">
+	import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+
+	type $$Props = DropdownMenuPrimitive.LabelProps & {
+		inset?: boolean;
+	};
+
+	let className: $$Props["class"] = undefined;
+	export let inset: $$Props["inset"] = undefined;
+	export { className as class };
+</script>
+
+<DropdownMenuPrimitive.Label
+	class={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
+	{...$$restProps}
+>
+	<slot />
+</DropdownMenuPrimitive.Label>
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte
new file mode 100644
index 0000000..1c74ae1
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte
@@ -0,0 +1,11 @@
+<script lang="ts">
+	import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
+
+	type $$Props = DropdownMenuPrimitive.RadioGroupProps;
+
+	export let value: $$Props["value"] = undefined;
+</script>
+
+<DropdownMenuPrimitive.RadioGroup {...$$restProps} bind:value>
+	<slot />
+</DropdownMenuPrimitive.RadioGroup>
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte
new file mode 100644
index 0000000..e518364
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte
@@ -0,0 +1,35 @@
+<script lang="ts">
+	import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+	import { DotFilled } from "radix-icons-svelte";
+
+	type $$Props = DropdownMenuPrimitive.RadioItemProps;
+	type $$Events = DropdownMenuPrimitive.RadioItemEvents;
+
+	let className: $$Props["class"] = undefined;
+	export let value: DropdownMenuPrimitive.RadioItemProps["value"];
+	export { className as class };
+</script>
+
+<DropdownMenuPrimitive.RadioItem
+	class={cn(
+		"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
+		className
+	)}
+	{value}
+	{...$$restProps}
+	on:click
+	on:keydown
+	on:focusin
+	on:focusout
+	on:pointerdown
+	on:pointerleave
+	on:pointermove
+>
+	<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
+		<DropdownMenuPrimitive.RadioIndicator>
+			<DotFilled class="h-4 w-4 fill-current" />
+		</DropdownMenuPrimitive.RadioIndicator>
+	</span>
+	<slot />
+</DropdownMenuPrimitive.RadioItem>
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte
new file mode 100644
index 0000000..775f8fe
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte
@@ -0,0 +1,14 @@
+<script lang="ts">
+	import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+
+	type $$Props = DropdownMenuPrimitive.SeparatorProps;
+
+	let className: $$Props["class"] = undefined;
+	export { className as class };
+</script>
+
+<DropdownMenuPrimitive.Separator
+	class={cn("-mx-1 my-1 h-px bg-muted", className)}
+	{...$$restProps}
+/>
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte
new file mode 100644
index 0000000..caf24ad
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte
@@ -0,0 +1,16 @@
+<script lang="ts">
+	import { cn } from "$lib/utils";
+	import type { HTMLAttributes } from "svelte/elements";
+
+	type $$Props = HTMLAttributes<HTMLSpanElement>;
+
+	let className: $$Props["class"] = undefined;
+	export { className as class };
+</script>
+
+<span
+	class={cn("ml-auto text-xs tracking-widest opacity-60", className)}
+	{...$$restProps}
+>
+	<slot />
+</span>
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte
new file mode 100644
index 0000000..eec9bfa
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte
@@ -0,0 +1,29 @@
+<script lang="ts">
+	import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
+	import { cn, flyAndScale } from "$lib/utils";
+
+	type $$Props = DropdownMenuPrimitive.SubContentProps;
+
+	let className: $$Props["class"] = undefined;
+	export let transition: $$Props["transition"] = flyAndScale;
+	export let transitionConfig: $$Props["transitionConfig"] = {
+		x: -10,
+		y: 0
+	};
+	export { className as class };
+</script>
+
+<DropdownMenuPrimitive.SubContent
+	{transition}
+	{transitionConfig}
+	class={cn(
+		"z-50 min-w-[8rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-lg focus:outline-none",
+		className
+	)}
+	{...$$restProps}
+	on:keydown
+	on:focusout
+	on:pointermove
+>
+	<slot />
+</DropdownMenuPrimitive.SubContent>
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte
new file mode 100644
index 0000000..d3a5ad3
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte
@@ -0,0 +1,32 @@
+<script lang="ts">
+	import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+	import { ChevronRight } from "radix-icons-svelte";
+
+	type $$Props = DropdownMenuPrimitive.SubTriggerProps & {
+		inset?: boolean;
+	};
+	type $$Events = DropdownMenuPrimitive.SubTriggerEvents;
+
+	let className: $$Props["class"] = undefined;
+	export let inset: $$Props["inset"] = undefined;
+	export { className as class };
+</script>
+
+<DropdownMenuPrimitive.SubTrigger
+	class={cn(
+		"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[highlighted]:bg-accent data-[state=open]:bg-accent",
+		inset && "pl-8",
+		className
+	)}
+	{...$$restProps}
+	on:click
+	on:keydown
+	on:focusin
+	on:focusout
+	on:pointerleave
+	on:pointermove
+>
+	<slot />
+	<ChevronRight class="ml-auto h-4 w-4" />
+</DropdownMenuPrimitive.SubTrigger>
diff --git a/src/lib/components/ui/dropdown-menu/index.ts b/src/lib/components/ui/dropdown-menu/index.ts
new file mode 100644
index 0000000..313213a
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/index.ts
@@ -0,0 +1,48 @@
+import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
+import Item from "./dropdown-menu-item.svelte";
+import Label from "./dropdown-menu-label.svelte";
+import Content from "./dropdown-menu-content.svelte";
+import Shortcut from "./dropdown-menu-shortcut.svelte";
+import RadioItem from "./dropdown-menu-radio-item.svelte";
+import Separator from "./dropdown-menu-separator.svelte";
+import RadioGroup from "./dropdown-menu-radio-group.svelte";
+import SubContent from "./dropdown-menu-sub-content.svelte";
+import SubTrigger from "./dropdown-menu-sub-trigger.svelte";
+import CheckboxItem from "./dropdown-menu-checkbox-item.svelte";
+
+const Sub = DropdownMenuPrimitive.Sub;
+const Root = DropdownMenuPrimitive.Root;
+const Trigger = DropdownMenuPrimitive.Trigger;
+const Group = DropdownMenuPrimitive.Group;
+
+export {
+	Sub,
+	Root,
+	Item,
+	Label,
+	Group,
+	Trigger,
+	Content,
+	Shortcut,
+	Separator,
+	RadioItem,
+	SubContent,
+	SubTrigger,
+	RadioGroup,
+	CheckboxItem,
+	//
+	Root as DropdownMenu,
+	Sub as DropdownMenuSub,
+	Item as DropdownMenuItem,
+	Label as DropdownMenuLabel,
+	Group as DropdownMenuGroup,
+	Content as DropdownMenuContent,
+	Trigger as DropdownMenuTrigger,
+	Shortcut as DropdownMenuShortcut,
+	RadioItem as DropdownMenuRadioItem,
+	Separator as DropdownMenuSeparator,
+	RadioGroup as DropdownMenuRadioGroup,
+	SubContent as DropdownMenuSubContent,
+	SubTrigger as DropdownMenuSubTrigger,
+	CheckboxItem as DropdownMenuCheckboxItem
+};
diff --git a/src/lib/components/ui/menubar/index.ts b/src/lib/components/ui/menubar/index.ts
new file mode 100644
index 0000000..733ab08
--- /dev/null
+++ b/src/lib/components/ui/menubar/index.ts
@@ -0,0 +1,52 @@
+import { Menubar as MenubarPrimitive } from "bits-ui";
+
+import Root from "./menubar.svelte";
+import CheckboxItem from "./menubar-checkbox-item.svelte";
+import Content from "./menubar-content.svelte";
+import Item from "./menubar-item.svelte";
+import Label from "./menubar-label.svelte";
+import RadioItem from "./menubar-radio-item.svelte";
+import Separator from "./menubar-separator.svelte";
+import Shortcut from "./menubar-shortcut.svelte";
+import SubContent from "./menubar-sub-content.svelte";
+import SubTrigger from "./menubar-sub-trigger.svelte";
+import Trigger from "./menubar-trigger.svelte";
+
+const Menu = MenubarPrimitive.Menu;
+const Group = MenubarPrimitive.Group;
+const Sub = MenubarPrimitive.Sub;
+const RadioGroup = MenubarPrimitive.RadioGroup;
+
+export {
+	Root,
+	CheckboxItem,
+	Content,
+	Item,
+	Label,
+	RadioItem,
+	Separator,
+	Shortcut,
+	SubContent,
+	SubTrigger,
+	Trigger,
+	Menu,
+	Group,
+	Sub,
+	RadioGroup,
+	//
+	Root as Menubar,
+	CheckboxItem as MenubarCheckboxItem,
+	Content as MenubarContent,
+	Item as MenubarItem,
+	Label as MenubarLabel,
+	RadioItem as MenubarRadioItem,
+	Separator as MenubarSeparator,
+	Shortcut as MenubarShortcut,
+	SubContent as MenubarSubContent,
+	SubTrigger as MenubarSubTrigger,
+	Trigger as MenubarTrigger,
+	Menu as MenubarMenu,
+	Group as MenubarGroup,
+	Sub as MenubarSub,
+	RadioGroup as MenubarRadioGroup
+};
diff --git a/src/lib/components/ui/menubar/menubar-checkbox-item.svelte b/src/lib/components/ui/menubar/menubar-checkbox-item.svelte
new file mode 100644
index 0000000..a98439a
--- /dev/null
+++ b/src/lib/components/ui/menubar/menubar-checkbox-item.svelte
@@ -0,0 +1,33 @@
+<script lang="ts">
+	import { Menubar as MenubarPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+	import { Check } from "radix-icons-svelte";
+
+	type $$Props = MenubarPrimitive.CheckboxItemProps;
+	let className: $$Props["class"] = undefined;
+	export { className as class };
+	export let checked: $$Props["checked"] = undefined;
+</script>
+
+<MenubarPrimitive.CheckboxItem
+	bind:checked
+	class={cn(
+		"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
+		className
+	)}
+	{...$$restProps}
+	on:click
+	on:keydown
+	on:focusin
+	on:focusout
+	on:pointerleave
+	on:pointermove
+	on:pointerdown
+>
+	<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
+		<MenubarPrimitive.CheckboxIndicator>
+			<Check class="h-4 w-4" />
+		</MenubarPrimitive.CheckboxIndicator>
+	</span>
+	<slot />
+</MenubarPrimitive.CheckboxItem>
diff --git a/src/lib/components/ui/menubar/menubar-content.svelte b/src/lib/components/ui/menubar/menubar-content.svelte
new file mode 100644
index 0000000..20f61c7
--- /dev/null
+++ b/src/lib/components/ui/menubar/menubar-content.svelte
@@ -0,0 +1,28 @@
+<script lang="ts">
+	import { Menubar as MenubarPrimitive } from "bits-ui";
+	import { cn, flyAndScale } from "$lib/utils";
+
+	type $$Props = MenubarPrimitive.ContentProps;
+	let className: $$Props["class"] = undefined;
+	export let align: $$Props["align"] = "start";
+	export let alignOffset: $$Props["alignOffset"] = -4;
+	export let sideOffset: $$Props["sideOffset"] = 8;
+	export let transition: $$Props["transition"] = flyAndScale;
+	export let transitionConfig: $$Props["transitionConfig"] = undefined;
+	export { className as class };
+</script>
+
+<MenubarPrimitive.Content
+	{transition}
+	{transitionConfig}
+	{sideOffset}
+	{align}
+	{alignOffset}
+	class={cn(
+		"z-50 min-w-[12rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none",
+		className
+	)}
+	{...$$restProps}
+>
+	<slot />
+</MenubarPrimitive.Content>
diff --git a/src/lib/components/ui/menubar/menubar-item.svelte b/src/lib/components/ui/menubar/menubar-item.svelte
new file mode 100644
index 0000000..53af5c1
--- /dev/null
+++ b/src/lib/components/ui/menubar/menubar-item.svelte
@@ -0,0 +1,31 @@
+<script lang="ts">
+	import { Menubar as MenubarPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+
+	type $$Props = MenubarPrimitive.ItemProps & {
+		inset?: boolean;
+	};
+	type $$Events = MenubarPrimitive.ItemEvents;
+
+	let className: $$Props["class"] = undefined;
+	export let inset: $$Props["inset"] = undefined;
+	export { className as class };
+</script>
+
+<MenubarPrimitive.Item
+	class={cn(
+		"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
+		inset && "pl-8",
+		className
+	)}
+	{...$$restProps}
+	on:click
+	on:keydown
+	on:focusin
+	on:focusout
+	on:pointerleave
+	on:pointermove
+	on:pointerdown
+>
+	<slot />
+</MenubarPrimitive.Item>
diff --git a/src/lib/components/ui/menubar/menubar-label.svelte b/src/lib/components/ui/menubar/menubar-label.svelte
new file mode 100644
index 0000000..710619f
--- /dev/null
+++ b/src/lib/components/ui/menubar/menubar-label.svelte
@@ -0,0 +1,18 @@
+<script lang="ts">
+	import { Menubar as MenubarPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+
+	type $$Props = MenubarPrimitive.LabelProps & {
+		inset?: boolean;
+	};
+	let className: $$Props["class"] = undefined;
+	export let inset: $$Props["inset"] = undefined;
+	export { className as class };
+</script>
+
+<MenubarPrimitive.Label
+	class={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
+	{...$$restProps}
+>
+	<slot />
+</MenubarPrimitive.Label>
diff --git a/src/lib/components/ui/menubar/menubar-radio-item.svelte b/src/lib/components/ui/menubar/menubar-radio-item.svelte
new file mode 100644
index 0000000..bf1e2d3
--- /dev/null
+++ b/src/lib/components/ui/menubar/menubar-radio-item.svelte
@@ -0,0 +1,34 @@
+<script lang="ts">
+	import { Menubar as MenubarPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+	import { DotFilled } from "radix-icons-svelte";
+
+	type $$Props = MenubarPrimitive.RadioItemProps;
+	type $$Events = MenubarPrimitive.RadioItemEvents;
+	let className: $$Props["class"] = undefined;
+	export let value: $$Props["value"];
+	export { className as class };
+</script>
+
+<MenubarPrimitive.RadioItem
+	{value}
+	class={cn(
+		"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
+		className
+	)}
+	{...$$restProps}
+	on:click
+	on:keydown
+	on:focusin
+	on:focusout
+	on:pointerleave
+	on:pointermove
+	on:pointerdown
+>
+	<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
+		<MenubarPrimitive.RadioIndicator>
+			<DotFilled class="h-4 w-4 fill-current" />
+		</MenubarPrimitive.RadioIndicator>
+	</span>
+	<slot />
+</MenubarPrimitive.RadioItem>
diff --git a/src/lib/components/ui/menubar/menubar-separator.svelte b/src/lib/components/ui/menubar/menubar-separator.svelte
new file mode 100644
index 0000000..90851d6
--- /dev/null
+++ b/src/lib/components/ui/menubar/menubar-separator.svelte
@@ -0,0 +1,13 @@
+<script lang="ts">
+	import { Menubar as MenubarPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+
+	type $$Props = MenubarPrimitive.SeparatorProps;
+	let className: $$Props["class"] = undefined;
+	export { className as class };
+</script>
+
+<MenubarPrimitive.Separator
+	class={cn("-mx-1 my-1 h-px bg-muted", className)}
+	{...$$restProps}
+/>
diff --git a/src/lib/components/ui/menubar/menubar-shortcut.svelte b/src/lib/components/ui/menubar/menubar-shortcut.svelte
new file mode 100644
index 0000000..82309a0
--- /dev/null
+++ b/src/lib/components/ui/menubar/menubar-shortcut.svelte
@@ -0,0 +1,18 @@
+<script lang="ts">
+	import { cn } from "$lib/utils";
+	import type { HTMLAttributes } from "svelte/elements";
+
+	type $$Props = HTMLAttributes<HTMLSpanElement>;
+	let className: $$Props["class"] = undefined;
+	export { className as class };
+</script>
+
+<span
+	class={cn(
+		"ml-auto text-xs tracking-widest text-muted-foreground",
+		className
+	)}
+	{...$$restProps}
+>
+	<slot />
+</span>
diff --git a/src/lib/components/ui/menubar/menubar-sub-content.svelte b/src/lib/components/ui/menubar/menubar-sub-content.svelte
new file mode 100644
index 0000000..287b756
--- /dev/null
+++ b/src/lib/components/ui/menubar/menubar-sub-content.svelte
@@ -0,0 +1,25 @@
+<script lang="ts">
+	import { Menubar as MenubarPrimitive } from "bits-ui";
+	import { cn, flyAndScale } from "$lib/utils";
+
+	type $$Props = MenubarPrimitive.SubContentProps;
+	let className: $$Props["class"] = undefined;
+	export let transition: $$Props["transition"] = flyAndScale;
+	export let transitionConfig: $$Props["transitionConfig"] = {
+		x: -10,
+		y: 0
+	};
+	export { className as class };
+</script>
+
+<MenubarPrimitive.SubContent
+	{transition}
+	{transitionConfig}
+	class={cn(
+		"z-50 min-w-[8rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-lg focus:outline-none",
+		className
+	)}
+	{...$$restProps}
+>
+	<slot />
+</MenubarPrimitive.SubContent>
diff --git a/src/lib/components/ui/menubar/menubar-sub-trigger.svelte b/src/lib/components/ui/menubar/menubar-sub-trigger.svelte
new file mode 100644
index 0000000..329ee24
--- /dev/null
+++ b/src/lib/components/ui/menubar/menubar-sub-trigger.svelte
@@ -0,0 +1,32 @@
+<script lang="ts">
+	import { Menubar as MenubarPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+	import { ChevronRight } from "radix-icons-svelte";
+
+	type $$Props = MenubarPrimitive.SubTriggerProps & {
+		inset?: boolean;
+	};
+	type $$Events = MenubarPrimitive.SubTriggerEvents;
+
+	let className: $$Props["class"] = undefined;
+	export let inset: $$Props["inset"] = undefined;
+	export { className as class };
+</script>
+
+<MenubarPrimitive.SubTrigger
+	class={cn(
+		"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
+		inset && "pl-8",
+		className
+	)}
+	{...$$restProps}
+	on:click
+	on:keydown
+	on:focusin
+	on:focusout
+	on:pointerleave
+	on:pointermove
+>
+	<slot />
+	<ChevronRight class="ml-auto h-4 w-4" />
+</MenubarPrimitive.SubTrigger>
diff --git a/src/lib/components/ui/menubar/menubar-trigger.svelte b/src/lib/components/ui/menubar/menubar-trigger.svelte
new file mode 100644
index 0000000..c6dfe97
--- /dev/null
+++ b/src/lib/components/ui/menubar/menubar-trigger.svelte
@@ -0,0 +1,23 @@
+<script lang="ts">
+	import { Menubar as MenubarPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+
+	type $$Props = MenubarPrimitive.TriggerProps;
+	type $$Events = MenubarPrimitive.TriggerEvents;
+
+	let className: $$Props["class"] = undefined;
+	export { className as class };
+</script>
+
+<MenubarPrimitive.Trigger
+	class={cn(
+		"flex cursor-default select-none items-center rounded-sm px-3 py-1 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
+		className
+	)}
+	{...$$restProps}
+	on:click
+	on:keydown
+	on:pointerenter
+>
+	<slot />
+</MenubarPrimitive.Trigger>
diff --git a/src/lib/components/ui/menubar/menubar.svelte b/src/lib/components/ui/menubar/menubar.svelte
new file mode 100644
index 0000000..4ed491a
--- /dev/null
+++ b/src/lib/components/ui/menubar/menubar.svelte
@@ -0,0 +1,18 @@
+<script lang="ts">
+	import { Menubar as MenubarPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+
+	type $$Props = MenubarPrimitive.Props;
+
+	let className: $$Props["class"] = undefined;
+	export { className as class };
+</script>
+
+<MenubarPrimitive.Root
+	class={cn(
+		"flex h-9 items-center space-x-1 rounded-md border bg-background p-1 shadow-sm",
+		className
+	)}
+>
+	<slot />
+</MenubarPrimitive.Root>
diff --git a/src/lib/components/ui/separator/index.ts b/src/lib/components/ui/separator/index.ts
new file mode 100644
index 0000000..dbfb139
--- /dev/null
+++ b/src/lib/components/ui/separator/index.ts
@@ -0,0 +1,7 @@
+import Root from "./separator.svelte";
+
+export {
+	Root,
+	//
+	Root as Separator
+};
diff --git a/src/lib/components/ui/separator/separator.svelte b/src/lib/components/ui/separator/separator.svelte
new file mode 100644
index 0000000..bf9127a
--- /dev/null
+++ b/src/lib/components/ui/separator/separator.svelte
@@ -0,0 +1,22 @@
+<script lang="ts">
+	import { Separator as SeparatorPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+
+	type $$Props = SeparatorPrimitive.Props;
+
+	let className: $$Props["class"] = undefined;
+	export let orientation: $$Props["orientation"] = "horizontal";
+	export let decorative: $$Props["decorative"] = undefined;
+	export { className as class };
+</script>
+
+<SeparatorPrimitive.Root
+	class={cn(
+		"shrink-0 bg-border",
+		orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
+		className
+	)}
+	{orientation}
+	{decorative}
+	{...$$restProps}
+/>
diff --git a/src/lib/utils.ts b/src/lib/utils.ts
new file mode 100644
index 0000000..230a1fb
--- /dev/null
+++ b/src/lib/utils.ts
@@ -0,0 +1,62 @@
+import { type ClassValue, clsx } from "clsx";
+import { twMerge } from "tailwind-merge";
+import { cubicOut } from "svelte/easing";
+import type { TransitionConfig } from "svelte/transition";
+
+export function cn(...inputs: ClassValue[]) {
+    return twMerge(clsx(inputs));
+}
+
+type FlyAndScaleParams = {
+    y?: number;
+    x?: number;
+    start?: number;
+    duration?: number;
+};
+
+export const flyAndScale = (
+    node: Element,
+    params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 }
+): TransitionConfig => {
+    const style = getComputedStyle(node);
+    const transform = style.transform === "none" ? "" : style.transform;
+
+    const scaleConversion = (
+        valueA: number,
+        scaleA: [number, number],
+        scaleB: [number, number]
+    ) => {
+        const [minA, maxA] = scaleA;
+        const [minB, maxB] = scaleB;
+
+        const percentage = (valueA - minA) / (maxA - minA);
+        const valueB = percentage * (maxB - minB) + minB;
+
+        return valueB;
+    };
+
+    const styleToString = (
+        style: Record<string, number | string | undefined>
+    ): string => {
+        return Object.keys(style).reduce((str, key) => {
+            if (style[key] === undefined) return str;
+            return str + `${key}:${style[key]};`;
+        }, "");
+    };
+
+    return {
+        duration: params.duration ?? 200,
+        delay: 0,
+        css: (t) => {
+            const y = scaleConversion(t, [0, 1], [params.y ?? 5, 0]);
+            const x = scaleConversion(t, [0, 1], [params.x ?? 0, 0]);
+            const scale = scaleConversion(t, [0, 1], [params.start ?? 0.95, 1]);
+
+            return styleToString({
+                transform: `${transform} translate3d(${x}px, ${y}px, 0) scale(${scale})`,
+                opacity: t
+            });
+        },
+        easing: cubicOut
+    };
+};
\ No newline at end of file

From 596b9d7f790d89b345c24274c16822043617a4de Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Wed, 6 Dec 2023 21:01:02 +0100
Subject: [PATCH 09/24] Moved Account to Profile

---
 src/routes/{account => profile}/+page.svelte | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename src/routes/{account => profile}/+page.svelte (100%)

diff --git a/src/routes/account/+page.svelte b/src/routes/profile/+page.svelte
similarity index 100%
rename from src/routes/account/+page.svelte
rename to src/routes/profile/+page.svelte

From fb4425a20c41f464ee40c1b4672312d75c29234d Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Wed, 6 Dec 2023 21:01:39 +0100
Subject: [PATCH 10/24] Removed Various orphan packages, added UI yarn alias

---
 package.json |   9 ++-
 yarn.lock    | 172 +++++++++++++++++++++++++--------------------------
 2 files changed, 91 insertions(+), 90 deletions(-)

diff --git a/package.json b/package.json
index b8f5151..109e5ea 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,8 @@
     "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
     "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
     "lint": "prettier --plugin-search-dir . --check . && eslint .",
-    "format": "prettier --plugin-search-dir . --write ."
+    "format": "prettier --plugin-search-dir . --write .",
+    "ui": "npx shadcn-svelte@latest"
   },
   "devDependencies": {
     "@fontsource/fira-mono": "^4.5.10",
@@ -37,11 +38,15 @@
   },
   "type": "module",
   "dependencies": {
+    "bits-ui": "^0.11.3",
     "chart.js": "^4.3.3",
     "chartjs-plugin-datalabels": "^2.2.0",
+    "clsx": "^2.0.0",
     "flowbite": "^2.2.0",
-    "flowbite-svelte": "^0.44.20",
+    "radix-icons-svelte": "^1.2.1",
     "svelte-chartjs": "^3.1.2",
+    "tailwind-merge": "^2.1.0",
+    "tailwind-variants": "^0.1.18",
     "tailwindcss": "^3.3.6"
   }
 }
diff --git a/yarn.lock b/yarn.lock
index cf2d741..a7107d2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -174,14 +174,14 @@
   resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.0.tgz#0709e9f4cb252351c609c6e6d8d6779a8d25edff"
   integrity sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==
 
-"@floating-ui/core@^1.4.2":
-  version "1.5.1"
-  resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.1.tgz#62707d7ec585d0929f882321a1b1f4ea9c680da5"
-  integrity sha512-QgcKYwzcc8vvZ4n/5uklchy8KVdjJwcOeI+HnnTNclJjs2nYsy23DOCf+sSV1kBwD9yDAoVKCkv/gEPzgQU3Pw==
+"@floating-ui/core@^1.3.1", "@floating-ui/core@^1.4.2":
+  version "1.5.2"
+  resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.2.tgz#53a0f7a98c550e63134d504f26804f6b83dbc071"
+  integrity sha512-Ii3MrfY/GAIN3OhXNzpCKaLxHQfJF9qvwq/kEJYdqDxeIHa01K8sldugal6TmeeXl+WMvhv9cnVzUTaFFJF09A==
   dependencies:
     "@floating-ui/utils" "^0.1.3"
 
-"@floating-ui/dom@^1.5.3":
+"@floating-ui/dom@^1.4.5":
   version "1.5.3"
   resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.5.3.tgz#54e50efcb432c06c23cd33de2b575102005436fa"
   integrity sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==
@@ -218,6 +218,13 @@
   resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044"
   integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==
 
+"@internationalized/date@^3.5.0":
+  version "3.5.0"
+  resolved "https://registry.yarnpkg.com/@internationalized/date/-/date-3.5.0.tgz#67f1dd62355f05140cc80e324842e9bfb4553abe"
+  integrity sha512-nw0Q+oRkizBWMioseI8+2TeUPEyopJVz5YxoYVzR0W1v+2YytiYah7s/ot35F149q/xAg4F1gT/6eTd+tsUpFQ==
+  dependencies:
+    "@swc/helpers" "^0.5.0"
+
 "@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2":
   version "0.3.3"
   resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098"
@@ -255,6 +262,18 @@
   resolved "https://registry.yarnpkg.com/@kurkle/color/-/color-0.3.2.tgz#5acd38242e8bde4f9986e7913c8fdf49d3aa199f"
   integrity sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==
 
+"@melt-ui/svelte@0.64.5":
+  version "0.64.5"
+  resolved "https://registry.yarnpkg.com/@melt-ui/svelte/-/svelte-0.64.5.tgz#8157a6da20c45eb3fb60a2bcc7f3f4c428352985"
+  integrity sha512-nPQA2guLuLitpZ6A968eWyGMC2riTKLq4R26hPRLdzP/JHCpd9yvddgMwil8JKbUKjT2dC3i358vUqeUOGxknA==
+  dependencies:
+    "@floating-ui/core" "^1.3.1"
+    "@floating-ui/dom" "^1.4.5"
+    "@internationalized/date" "^3.5.0"
+    dequal "^2.0.3"
+    focus-trap "^7.5.2"
+    nanoid "^4.0.2"
+
 "@neoconfetti/svelte@^1.0.0":
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/@neoconfetti/svelte/-/svelte-1.0.0.tgz#84a7f98981ad546d959d8c99460da8cebdf70301"
@@ -337,6 +356,13 @@
     svelte-hmr "^0.15.3"
     vitefu "^0.2.4"
 
+"@swc/helpers@^0.5.0":
+  version "0.5.3"
+  resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.3.tgz#98c6da1e196f5f08f977658b80d6bd941b5f294f"
+  integrity sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A==
+  dependencies:
+    tslib "^2.4.0"
+
 "@types/cookie@^0.5.1":
   version "0.5.4"
   resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.5.4.tgz#7e70a20cd695bc48d46b08c2505874cd68b760e0"
@@ -458,11 +484,6 @@
   resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406"
   integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==
 
-"@yr/monotone-cubic-spline@^1.0.3":
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz#7272d89f8e4f6fb7a1600c28c378cc18d3b577b9"
-  integrity sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==
-
 acorn-jsx@^5.3.2:
   version "5.3.2"
   resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
@@ -513,19 +534,6 @@ anymatch@~3.1.2:
     normalize-path "^3.0.0"
     picomatch "^2.0.4"
 
-apexcharts@^3.44.0:
-  version "3.44.1"
-  resolved "https://registry.yarnpkg.com/apexcharts/-/apexcharts-3.44.1.tgz#0d4ae8650dc12d3e75beb667dcc0dc1d4ff8c155"
-  integrity sha512-nWd6bWf8E+c3YOsB0j0R4MOebMv1rBRWsK6aA11jF+pbag9IuBl4zrT4L42fxmDdLMcf5t3trWIXiGJmbLi2tA==
-  dependencies:
-    "@yr/monotone-cubic-spline" "^1.0.3"
-    svg.draggable.js "^2.2.2"
-    svg.easing.js "^2.0.0"
-    svg.filter.js "^2.0.2"
-    svg.pathmorphing.js "^0.1.3"
-    svg.resize.js "^1.4.3"
-    svg.select.js "^3.0.1"
-
 arg@^5.0.2:
   version "5.0.2"
   resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c"
@@ -577,6 +585,15 @@ binary-extensions@^2.0.0:
   resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
   integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
 
+bits-ui@^0.11.3:
+  version "0.11.3"
+  resolved "https://registry.yarnpkg.com/bits-ui/-/bits-ui-0.11.3.tgz#624e2fecf780565dc9beac00c17745647dfa0356"
+  integrity sha512-WV8XCkLW1u9vStdifgAiCmz5UW3u65Jm05SLuj0SOxQP6pkZIwnt1Nq61QOWsOEUeqYcQrp2VZsX1bhMuTVNpg==
+  dependencies:
+    "@internationalized/date" "^3.5.0"
+    "@melt-ui/svelte" "0.64.5"
+    nanoid "^5.0.4"
+
 brace-expansion@^1.1.7:
   version "1.1.11"
   resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -657,6 +674,11 @@ chokidar@^3.4.1, chokidar@^3.5.3:
   optionalDependencies:
     fsevents "~2.3.2"
 
+clsx@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b"
+  integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==
+
 color-convert@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
@@ -1015,16 +1037,6 @@ flatted@^3.2.9:
   resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf"
   integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==
 
-flowbite-svelte@^0.44.20:
-  version "0.44.20"
-  resolved "https://registry.yarnpkg.com/flowbite-svelte/-/flowbite-svelte-0.44.20.tgz#e2e39e18a28172d96dfeec107ee7e98f4957321f"
-  integrity sha512-juvzolgEvGEga8PIe+vpzGf9/xfpvd4p9ZgtSPpWQLZB8iyY/ebbKb5HNu60uqoehdokFuy/0htBBLNmP2yd/g==
-  dependencies:
-    "@floating-ui/dom" "^1.5.3"
-    apexcharts "^3.44.0"
-    flowbite "^2.2.0"
-    tailwind-merge "^2.0.0"
-
 flowbite@^2.2.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/flowbite/-/flowbite-2.2.0.tgz#638c223fa808241e1f64b4e068f819281d4c7c71"
@@ -1033,6 +1045,13 @@ flowbite@^2.2.0:
     "@popperjs/core" "^2.9.3"
     mini-svg-data-uri "^1.4.3"
 
+focus-trap@^7.5.2:
+  version "7.5.4"
+  resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-7.5.4.tgz#6c4e342fe1dae6add9c2aa332a6e7a0bbd495ba2"
+  integrity sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==
+  dependencies:
+    tabbable "^6.2.0"
+
 fraction.js@^4.3.6:
   version "4.3.7"
   resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
@@ -1402,6 +1421,16 @@ nanoid@^3.3.7:
   resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
   integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
 
+nanoid@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-4.0.2.tgz#140b3c5003959adbebf521c170f282c5e7f9fb9e"
+  integrity sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==
+
+nanoid@^5.0.4:
+  version "5.0.4"
+  resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-5.0.4.tgz#d2b608d8169d7da669279127615535705aa52edf"
+  integrity sha512-vAjmBf13gsmhXSgBrtIclinISzFFy22WwCYoyilZlsrRXNIHSwgFQ1bEdjRwMT3aoadeIF6HMuDRlOxzfXV8ig==
+
 natural-compare-lite@^1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4"
@@ -1618,6 +1647,11 @@ queue-microtask@^1.2.2:
   resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
   integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
 
+radix-icons-svelte@^1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/radix-icons-svelte/-/radix-icons-svelte-1.2.1.tgz#532706b0cd838cb8a832b1d7098d06c7f7ab534f"
+  integrity sha512-svmiMd0ocpdTm9cvAz0klcZpnh639lVctj6psQiawd4pYalVzOG4cX+JizAgRckyTAsRVdzObP7D2EBrSfdghA==
+
 read-cache@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774"
@@ -1867,68 +1901,30 @@ svelte@^5.0.0-next.17:
     magic-string "^0.30.4"
     zimmerframe "^1.1.0"
 
-svg.draggable.js@^2.2.2:
-  version "2.2.2"
-  resolved "https://registry.yarnpkg.com/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz#c514a2f1405efb6f0263e7958f5b68fce50603ba"
-  integrity sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==
-  dependencies:
-    svg.js "^2.0.1"
+tabbable@^6.2.0:
+  version "6.2.0"
+  resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97"
+  integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==
 
-svg.easing.js@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/svg.easing.js/-/svg.easing.js-2.0.0.tgz#8aa9946b0a8e27857a5c40a10eba4091e5691f12"
-  integrity sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==
-  dependencies:
-    svg.js ">=2.3.x"
+tailwind-merge@^1.14.0:
+  version "1.14.0"
+  resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-1.14.0.tgz#e677f55d864edc6794562c63f5001f45093cdb8b"
+  integrity sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ==
 
-svg.filter.js@^2.0.2:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/svg.filter.js/-/svg.filter.js-2.0.2.tgz#91008e151389dd9230779fcbe6e2c9a362d1c203"
-  integrity sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==
-  dependencies:
-    svg.js "^2.2.5"
-
-svg.js@>=2.3.x, svg.js@^2.0.1, svg.js@^2.2.5, svg.js@^2.4.0, svg.js@^2.6.5:
-  version "2.7.1"
-  resolved "https://registry.yarnpkg.com/svg.js/-/svg.js-2.7.1.tgz#eb977ed4737001eab859949b4a398ee1bb79948d"
-  integrity sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==
-
-svg.pathmorphing.js@^0.1.3:
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz#c25718a1cc7c36e852ecabc380e758ac09bb2b65"
-  integrity sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==
-  dependencies:
-    svg.js "^2.4.0"
-
-svg.resize.js@^1.4.3:
-  version "1.4.3"
-  resolved "https://registry.yarnpkg.com/svg.resize.js/-/svg.resize.js-1.4.3.tgz#885abd248e0cd205b36b973c4b578b9a36f23332"
-  integrity sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==
-  dependencies:
-    svg.js "^2.6.5"
-    svg.select.js "^2.1.2"
-
-svg.select.js@^2.1.2:
-  version "2.1.2"
-  resolved "https://registry.yarnpkg.com/svg.select.js/-/svg.select.js-2.1.2.tgz#e41ce13b1acff43a7441f9f8be87a2319c87be73"
-  integrity sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==
-  dependencies:
-    svg.js "^2.2.5"
-
-svg.select.js@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/svg.select.js/-/svg.select.js-3.0.1.tgz#a4198e359f3825739226415f82176a90ea5cc917"
-  integrity sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==
-  dependencies:
-    svg.js "^2.6.5"
-
-tailwind-merge@^2.0.0:
+tailwind-merge@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.1.0.tgz#541b407e0ec255651e92571d96b685e48f01999c"
   integrity sha512-l11VvI4nSwW7MtLSLYT4ldidDEUwQAMWuSHk7l4zcXZDgnCRa0V3OdCwFfM7DCzakVXMNRwAeje9maFFXT71dQ==
   dependencies:
     "@babel/runtime" "^7.23.5"
 
+tailwind-variants@^0.1.18:
+  version "0.1.18"
+  resolved "https://registry.yarnpkg.com/tailwind-variants/-/tailwind-variants-0.1.18.tgz#6ed75fe906ffb1ffa0db703e96d9994ea8cd48fc"
+  integrity sha512-yoydMYm3FbZRw7wak+E2sqwYv2Uo3YWRqVZR03DGqDGm0ytzDrEnWO/Q/GMHdhaz8adOvycKw/bwCgQFCfmfhg==
+  dependencies:
+    tailwind-merge "^1.14.0"
+
 tailwindcss@^3.3.6:
   version "3.3.6"
   resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.6.tgz#4dd7986bf4902ad385d90d45fd4b2fa5fab26d5f"
@@ -2006,7 +2002,7 @@ tslib@^1.8.1:
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
   integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
 
-tslib@^2.4.1:
+tslib@^2.4.0, tslib@^2.4.1:
   version "2.6.2"
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
   integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==

From 69574ae1243136f99fdd8befd7ce985c61ba5ce7 Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Wed, 6 Dec 2023 21:01:54 +0100
Subject: [PATCH 11/24] shadcn UI config changes

---
 components.json    | 13 +++++++
 src/app.postcss    | 78 ++++++++++++++++++++++++++++++++++++++--
 tailwind.config.js | 88 ++++++++++++++++++++++++++++++++--------------
 3 files changed, 149 insertions(+), 30 deletions(-)
 create mode 100644 components.json

diff --git a/components.json b/components.json
new file mode 100644
index 0000000..42519ae
--- /dev/null
+++ b/components.json
@@ -0,0 +1,13 @@
+{
+  "$schema": "https://shadcn-svelte.com/schema.json",
+  "style": "new-york",
+  "tailwind": {
+    "config": "tailwind.config.js",
+    "css": "src/app.postcss",
+    "baseColor": "slate"
+  },
+  "aliases": {
+    "components": "$lib/components",
+    "utils": "$lib/utils"
+  }
+}
\ No newline at end of file
diff --git a/src/app.postcss b/src/app.postcss
index 3445e3b..6ff7062 100644
--- a/src/app.postcss
+++ b/src/app.postcss
@@ -1,6 +1,78 @@
 @tailwind base;
 @tailwind components;
 @tailwind utilities;
-@tailwind variants;
-
-html, body { @apply h-full overflow-hidden; }
\ No newline at end of file
+ 
+@layer base {
+  :root {
+    --background: 0 0% 100%;
+    --foreground: 222.2 84% 4.9%;
+ 
+    --muted: 210 40% 96.1%;
+    --muted-foreground: 215.4 16.3% 46.9%;
+ 
+    --popover: 0 0% 100%;
+    --popover-foreground: 222.2 84% 4.9%;
+ 
+    --card: 0 0% 100%;
+    --card-foreground: 222.2 84% 4.9%;
+ 
+    --border: 214.3 31.8% 91.4%;
+    --input: 214.3 31.8% 91.4%;
+ 
+    --primary: 222.2 47.4% 11.2%;
+    --primary-foreground: 210 40% 98%;
+ 
+    --secondary: 210 40% 96.1%;
+    --secondary-foreground: 222.2 47.4% 11.2%;
+ 
+    --accent: 210 40% 96.1%;
+    --accent-foreground: 222.2 47.4% 11.2%;
+ 
+    --destructive: 0 72.2% 50.6%;
+    --destructive-foreground: 210 40% 98%;
+ 
+    --ring: 222.2 84% 4.9%;
+ 
+    --radius: 0.5rem;
+  }
+ 
+  .dark {
+    --background: 222.2 84% 4.9%;
+    --foreground: 210 40% 98%;
+ 
+    --muted: 217.2 32.6% 17.5%;
+    --muted-foreground: 215 20.2% 65.1%;
+ 
+    --popover: 222.2 84% 4.9%;
+    --popover-foreground: 210 40% 98%;
+ 
+    --card: 222.2 84% 4.9%;
+    --card-foreground: 210 40% 98%;
+ 
+    --border: 217.2 32.6% 17.5%;
+    --input: 217.2 32.6% 17.5%;
+ 
+    --primary: 210 40% 98%;
+    --primary-foreground: 222.2 47.4% 11.2%;
+ 
+    --secondary: 217.2 32.6% 17.5%;
+    --secondary-foreground: 210 40% 98%;
+ 
+    --accent: 217.2 32.6% 17.5%;
+    --accent-foreground: 210 40% 98%;
+ 
+    --destructive: 0 62.8% 30.6%;
+    --destructive-foreground: 210 40% 98%;
+ 
+    --ring: hsl(212.7,26.8%,83.9);
+  }
+}
+ 
+@layer base {
+  * {
+    @apply border-border;
+  }
+  body {
+    @apply bg-background text-foreground;
+  }
+}
\ No newline at end of file
diff --git a/tailwind.config.js b/tailwind.config.js
index b7651cb..8d260d9 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -1,30 +1,64 @@
-module.exports = {
-	mode: 'jit',
-	purge: ['./src/**/*.svelte', './src/**/*.html'],
-	darkMode: false,
+import { fontFamily } from "tailwindcss/defaultTheme";
+
+/** @type {import('tailwindcss').Config} */
+const config = {
+	darkMode: ["class"],
+	content: ["./src/**/*.{html,js,svelte,ts}"],
+  safelist: ["dark"],
 	theme: {
-		extend: {},
-	},
-	variants: {
+		container: {
+			center: true,
+			padding: "2rem",
+			screens: {
+				"2xl": "1400px"
+			}
+		},
 		extend: {
-		},
+			colors: {
+				border: "hsl(var(--border) / <alpha-value>)",
+				input: "hsl(var(--input) / <alpha-value>)",
+				ring: "hsl(var(--ring) / <alpha-value>)",
+				background: "hsl(var(--background) / <alpha-value>)",
+				foreground: "hsl(var(--foreground) / <alpha-value>)",
+				primary: {
+					DEFAULT: "hsl(var(--primary) / <alpha-value>)",
+					foreground: "hsl(var(--primary-foreground) / <alpha-value>)"
+				},
+				secondary: {
+					DEFAULT: "hsl(var(--secondary) / <alpha-value>)",
+					foreground: "hsl(var(--secondary-foreground) / <alpha-value>)"
+				},
+				destructive: {
+					DEFAULT: "hsl(var(--destructive) / <alpha-value>)",
+					foreground: "hsl(var(--destructive-foreground) / <alpha-value>)"
+				},
+				muted: {
+					DEFAULT: "hsl(var(--muted) / <alpha-value>)",
+					foreground: "hsl(var(--muted-foreground) / <alpha-value>)"
+				},
+				accent: {
+					DEFAULT: "hsl(var(--accent) / <alpha-value>)",
+					foreground: "hsl(var(--accent-foreground) / <alpha-value>)"
+				},
+				popover: {
+					DEFAULT: "hsl(var(--popover) / <alpha-value>)",
+					foreground: "hsl(var(--popover-foreground) / <alpha-value>)"
+				},
+				card: {
+					DEFAULT: "hsl(var(--card) / <alpha-value>)",
+					foreground: "hsl(var(--card-foreground) / <alpha-value>)"
+				}
+			},
+			borderRadius: {
+				lg: "var(--radius)",
+				md: "calc(var(--radius) - 2px)",
+				sm: "calc(var(--radius) - 4px)"
+			},
+			fontFamily: {
+				sans: [...fontFamily.sans]
+			}
+		}
 	},
-	plugins: [],
-	safelist: [
-		{
-			pattern: /bg-.+/,
-		},
-		{
-			pattern: /text-.+/,
-		},
-		{
-			pattern: /primary-.+/,
-		},
-		{
-			pattern: /secondary-.+/,
-		},
-		{
-			pattern: /border-.+/,
-		},
-	]
-}
\ No newline at end of file
+};
+
+export default config;

From 17e52b12d0b4fc97179ebc27c4388606541efe3c Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Wed, 6 Dec 2023 21:02:07 +0100
Subject: [PATCH 12/24] Reworked Navbar to use shadcn

---
 src/lib/components/NavigationElement.svelte |   8 --
 src/routes/+layout.svelte                   |   8 +-
 src/routes/+page.svelte                     |   7 +-
 src/routes/Header.svelte                    | 140 ++++++++++++++------
 4 files changed, 104 insertions(+), 59 deletions(-)
 delete mode 100644 src/lib/components/NavigationElement.svelte

diff --git a/src/lib/components/NavigationElement.svelte b/src/lib/components/NavigationElement.svelte
deleted file mode 100644
index 41e8e48..0000000
--- a/src/lib/components/NavigationElement.svelte
+++ /dev/null
@@ -1,8 +0,0 @@
-<script lang="ts">
-	let {href} = $props()
-	// {$page.url.pathname === '/'}
-</script>
-
-<li>
-	<a {href}><slot /></a>
-</li>
\ No newline at end of file
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index 6ecd8e0..fe62969 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -38,15 +38,9 @@
 
 </script>
 
-<div class="
-	bg-{themes[$UserSettingsStore.themeId].backgroundColor}
-	text-{themes[$UserSettingsStore.themeId].textColor}
-	h-full" >
+<div class="h-full" >
 	<Header/>
 	<slot />
-	<!-- (sidebarLeft) -->
-	<!-- (sidebarRight) -->
-	<!-- <svelte:fragment slot="pageHeader">Page Header</svelte:fragment> -->
 	<!-- Router Slot -->
 	<!-- ---- / ---- -->
 	<!-- (pageFooter) -->
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 679ee1c..dd66140 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -2,7 +2,12 @@
 <script lang="ts">
 </script>
 
-<div class="container h-full mx-auto flex flex-col justify-center items-center">
+<svelte:head>
+	<title>Home</title>
+	<meta name="description" content="Landing Page for the Chellaris Multiplayer Group" />
+</svelte:head>
+
+<div class="container py-2 h-full mx-auto flex flex-col justify-center items-center">
 	<h1>Chellaris</h1>
 	<div class="space-y-5">
 		<ul>
diff --git a/src/routes/Header.svelte b/src/routes/Header.svelte
index c97fe29..861ab9b 100644
--- a/src/routes/Header.svelte
+++ b/src/routes/Header.svelte
@@ -1,23 +1,27 @@
 <script lang="ts">
 	import { page } from '$app/stores';
 	import discord from '$lib/images/discord.svg';
-	import Settings from './Settings.svelte';
-	import Button from '$lib/components/Button.svelte';
-	import NavigationElement from '$lib/components/NavigationElement.svelte';
+	import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
+	import { Button } from '$lib/components/ui/button';
 	import { themes } from '$lib/types/themes';
 	import UserSettingsStore from '$lib/stores/UserSettingsStore';
-
-	let showSettings = false;
-
-	const openSettings = () => {
-		// open the settings I guess
-	}
+	import * as Avatar from '$lib/components/ui/avatar';
+	import { Exit } from 'radix-icons-svelte';
+	import { Separator } from '$lib/components/ui/separator';
 
 	let user = {
 		loggedIn: true, // DEBUG
 		admin: true, // DEBUG
 	}
 
+	function login() {
+		user.loggedIn = true;
+	}
+
+	function logout() {
+		user.loggedIn = false;
+	}
+
 	function nextTheme() {
 		if ($UserSettingsStore.themeId + 1 < themes.length) {
 			$UserSettingsStore.themeId += 1
@@ -29,45 +33,95 @@
 	
 </script>
 
-<div class="flex gap-2 flex-row">
+<div class="flex gap-2 items-center justify-center py-3 bg-primary-foreground">
 	<!-- spacer -->
-	<ul class="flex gap-2 flex-row">
-		<NavigationElement href="/">Home</NavigationElement>
-		<NavigationElement href="/current">Game [Current Game]</NavigationElement>
-		<NavigationElement href="/archive">Archives</NavigationElement>
+		<Button
+			variant="ghost"
+			href="/"
+			class="{$page.url.pathname == '/' ? 'text-accent-foreground bg-accent' : ''}"
+		>
+			Home
+		</Button>
+		<Button
+			variant="ghost"
+			href="/current"
+			class="{$page.url.pathname == '/current' ? 'text-accent-foreground bg-accent' : ''}"
+		>
+			Game [Current Game]
+		</Button>
+		<Button
+			variant="ghost"
+			href="/archive"
+			class="{$page.url.pathname.startsWith('/archive') ? 'text-accent-foreground bg-accent' : ''}"
+		>
+			Archives
+		</Button>
 		{#if user.loggedIn && user.admin}
-			<NavigationElement href="/admin"></NavigationElement>
+			<Button
+				variant="ghost"
+				href="/admin"
+				class="{$page.url.pathname == '/admin' ? 'text-accent-foreground bg-accent' : ''}"
+			>
+				Admin
+			</Button>
 		{/if}
 		<div class="dropdown" href="user.loggedIn ? /account | /login"></div>
-		<Button onclick={nextTheme}>Theme</Button>
-		<NavigationElement href="/settings">Settings</NavigationElement>
 		{#if user.loggedIn}
-			<NavigationElement href="/account">Account</NavigationElement>
+			<DropdownMenu.Root>
+				<DropdownMenu.Trigger asChild let:builder>
+					<Button
+						variant="ghost"
+						builders={[builder]}
+						class="relative h-8 w-8 rounded-full"
+					>
+						<Avatar.Root class="h-8 w-8">
+							<Avatar.Image src="/avatar.png" alt="@user" />
+							<Avatar.Fallback>US</Avatar.Fallback>
+						</Avatar.Root>
+					</Button>
+				</DropdownMenu.Trigger>
+				<DropdownMenu.Content class="w-56">
+					<DropdownMenu.Label class="font-normal">
+						<div class="flex flex-col space-y-1 items-start">
+							<p class="text-sm font-medium leading-none">User Display</p>
+							<p class="text-xs leading-none text-muted-foreground">@User</p>
+						</div>
+					</DropdownMenu.Label>
+					<DropdownMenu.Separator />
+					<DropdownMenu.Group>
+						<DropdownMenu.Item href="/profile">
+							Profile
+						</DropdownMenu.Item>
+						<DropdownMenu.Item href="/settings">
+							Settings
+						</DropdownMenu.Item>
+					</DropdownMenu.Group>
+					<DropdownMenu.Separator />
+					<DropdownMenu.Item class="flex flex-row space-x-1" on:click={logout}>
+						<p>Log out </p>
+						<Exit />
+					</DropdownMenu.Item>
+				</DropdownMenu.Content>
+			</DropdownMenu.Root>
 		{:else}
-			<NavigationElement href="/login">Login</NavigationElement>
+			<Button
+				variant="ghost"
+				class="relative"
+			>
+				Log in
+			</Button>
 		{/if}
-	</ul>
-	<!-- spacer -->
-		<!--padding="px-4 py-2"
-		justify="justify-center"
-		rounded="rounded-tr-xl rounded-tl-xl"
-		border="border-b-2 border-primary-500"
-		active="variant-glass-primary hover:variant-ghost-primary"
-		<div aria-current={$page.url.pathname.startsWith('/sign-up') ? 'page' : undefined}>
-		<a href="/sign-up">Empire Sign-Up</a>
-	</div>-->
-		<!--padding="px-4 py-2"
-		justify="justify-center"
-		rounded="rounded-tr-xl rounded-tl-xl"
-		border="border-b-2 border-primary-500"
-		active="variant-glass-primary hover:variant-ghost-primary"
-		hover="hover:variant-ghost-primary"-->
-
-		<div class="lightswitch" />
-		<div>
-			<!-- Logo -->
-			<a class="lg:!ml-0 w-[32px] lg:w-auto overflow-hidden" href="https://discord.gg/invite/BYNeHaPNh9" target="_blank" rel="noopener noreferrer">
-				<img width="32px" height="32px" src={discord} alt="Discord" />
-			</a>
-		</div>
+	<Button
+		variant="link"
+		href="https://discord.gg/invite/BYNeHaPNh9"
+		target="_blank"
+		rel="noopener noreferrer"
+		class="h-8 w-8 items-center flex"
+	>
+		<Avatar.Root class="h-6 w-6">
+			<Avatar.Image src={discord} alt="DC" />
+			<Avatar.Fallback>US</Avatar.Fallback>
+		</Avatar.Root>
+	</Button>
 </div>
+<Separator orientation="horizontal"></Separator>

From c0c38e7aa7b7b7e6ffd59dde5b26f0c3a840ce7f Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Sat, 9 Dec 2023 18:52:40 +0100
Subject: [PATCH 13/24] Added several UI components from shadcn

---
 .../components/ui/checkbox/checkbox.svelte    | 36 +++++++++++++++++++
 src/lib/components/ui/checkbox/index.ts       |  6 ++++
 .../ui/collapsible/collapsible-content.svelte | 14 ++++++++
 src/lib/components/ui/collapsible/index.ts    | 15 ++++++++
 src/lib/components/ui/label/index.ts          |  7 ++++
 src/lib/components/ui/label/label.svelte      | 19 ++++++++++
 6 files changed, 97 insertions(+)
 create mode 100644 src/lib/components/ui/checkbox/checkbox.svelte
 create mode 100644 src/lib/components/ui/checkbox/index.ts
 create mode 100644 src/lib/components/ui/collapsible/collapsible-content.svelte
 create mode 100644 src/lib/components/ui/collapsible/index.ts
 create mode 100644 src/lib/components/ui/label/index.ts
 create mode 100644 src/lib/components/ui/label/label.svelte

diff --git a/src/lib/components/ui/checkbox/checkbox.svelte b/src/lib/components/ui/checkbox/checkbox.svelte
new file mode 100644
index 0000000..8a435ea
--- /dev/null
+++ b/src/lib/components/ui/checkbox/checkbox.svelte
@@ -0,0 +1,36 @@
+<script lang="ts">
+	import { Checkbox as CheckboxPrimitive } from "bits-ui";
+	import { Check, Minus } from "radix-icons-svelte";
+	import { cn } from "$lib/utils";
+
+	type $$Props = CheckboxPrimitive.Props;
+	type $$Events = CheckboxPrimitive.Events;
+
+	let className: $$Props["class"] = undefined;
+	export let checked: $$Props["checked"] = false;
+	export { className as class };
+</script>
+
+<CheckboxPrimitive.Root
+	class={cn(
+		"box-content peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50",
+		className
+	)}
+	bind:checked
+	on:click
+	{...$$restProps}
+>
+	<CheckboxPrimitive.Indicator
+		class={cn("flex items-center justify-center text-current h-4 w-4")}
+		let:isChecked
+		let:isIndeterminate
+	>
+		{#if isIndeterminate}
+			<Minus class="h-3.5 w-3.5" />
+		{:else}
+			<Check
+				class={cn("h-3.5 w-3.5", !isChecked && "text-transparent")}
+			/>
+		{/if}
+	</CheckboxPrimitive.Indicator>
+</CheckboxPrimitive.Root>
diff --git a/src/lib/components/ui/checkbox/index.ts b/src/lib/components/ui/checkbox/index.ts
new file mode 100644
index 0000000..5fba5a4
--- /dev/null
+++ b/src/lib/components/ui/checkbox/index.ts
@@ -0,0 +1,6 @@
+import Root from "./checkbox.svelte";
+export {
+	Root,
+	//
+	Root as Checkbox
+};
diff --git a/src/lib/components/ui/collapsible/collapsible-content.svelte b/src/lib/components/ui/collapsible/collapsible-content.svelte
new file mode 100644
index 0000000..14849d6
--- /dev/null
+++ b/src/lib/components/ui/collapsible/collapsible-content.svelte
@@ -0,0 +1,14 @@
+<script lang="ts">
+	import { Collapsible as CollapsiblePrimitive } from "bits-ui";
+	import { slide } from "svelte/transition";
+	type $$Props = CollapsiblePrimitive.ContentProps;
+
+	export let transition: $$Props["transition"] = slide;
+	export let transitionConfig: $$Props["transitionConfig"] = {
+		duration: 150
+	};
+</script>
+
+<CollapsiblePrimitive.Content {transition} {transitionConfig} {...$$restProps}>
+	<slot />
+</CollapsiblePrimitive.Content>
diff --git a/src/lib/components/ui/collapsible/index.ts b/src/lib/components/ui/collapsible/index.ts
new file mode 100644
index 0000000..04c3c2a
--- /dev/null
+++ b/src/lib/components/ui/collapsible/index.ts
@@ -0,0 +1,15 @@
+import { Collapsible as CollapsiblePrimitive } from "bits-ui";
+import Content from "./collapsible-content.svelte";
+
+const Root = CollapsiblePrimitive.Root;
+const Trigger = CollapsiblePrimitive.Trigger;
+
+export {
+	Root,
+	Content,
+	Trigger,
+	//
+	Root as Collapsible,
+	Content as CollapsibleContent,
+	Trigger as CollapsibleTrigger
+};
diff --git a/src/lib/components/ui/label/index.ts b/src/lib/components/ui/label/index.ts
new file mode 100644
index 0000000..2c3128c
--- /dev/null
+++ b/src/lib/components/ui/label/index.ts
@@ -0,0 +1,7 @@
+import Root from "./label.svelte";
+
+export {
+	Root,
+	//
+	Root as Label
+};
diff --git a/src/lib/components/ui/label/label.svelte b/src/lib/components/ui/label/label.svelte
new file mode 100644
index 0000000..c4a542b
--- /dev/null
+++ b/src/lib/components/ui/label/label.svelte
@@ -0,0 +1,19 @@
+<script lang="ts">
+	import { Label as LabelPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+
+	type $$Props = LabelPrimitive.Props;
+
+	let className: $$Props["class"] = undefined;
+	export { className as class };
+</script>
+
+<LabelPrimitive.Root
+	class={cn(
+		"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
+		className
+	)}
+	{...$$restProps}
+>
+	<slot />
+</LabelPrimitive.Root>

From e2bbc2f1ebe039bd7c8b111d54fefebd80414245 Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Sat, 9 Dec 2023 18:52:53 +0100
Subject: [PATCH 14/24] Admin "new" route auth checking

---
 src/routes/admin/new/+page.server.ts |  16 +++
 src/routes/admin/new/+page.svelte    | 159 +++++++++++++++++++++++++++
 2 files changed, 175 insertions(+)
 create mode 100644 src/routes/admin/new/+page.server.ts
 create mode 100644 src/routes/admin/new/+page.svelte

diff --git a/src/routes/admin/new/+page.server.ts b/src/routes/admin/new/+page.server.ts
new file mode 100644
index 0000000..a811fbc
--- /dev/null
+++ b/src/routes/admin/new/+page.server.ts
@@ -0,0 +1,16 @@
+import { apiBaseUrl } from "$lib/components_custom/consts";
+import { redirect } from "@sveltejs/kit";
+
+export async function load({ cookies }) {
+  const auth = await (await fetch(apiBaseUrl + "/v3/auth", {
+    headers: {
+      'Content-Type': 'application/json',
+      'x-api-key': cookies.get("authToken") || ""
+    }
+  })).json();
+
+  /*if (!auth.admin && !auth.moderator) {
+    throw redirect(303, '/401');
+  }*/
+  console.log("WARNING: Admin Auth Check is disabled! DO NOT USE IN PRODUCTION")
+}
diff --git a/src/routes/admin/new/+page.svelte b/src/routes/admin/new/+page.svelte
new file mode 100644
index 0000000..b0c4bc8
--- /dev/null
+++ b/src/routes/admin/new/+page.svelte
@@ -0,0 +1,159 @@
+<svelte:options runes={true} />
+
+<script lang="ts">
+	import { Separator } from '$lib/components/ui/separator';
+	import * as Collapsible from "$lib/components/ui/collapsible";
+	import { Button } from '$lib/components/ui/button';
+	import { CaretDown, CaretRight } from 'radix-icons-svelte';
+	import { Checkbox } from '$lib/components/ui/checkbox';
+	import { Label } from '$lib/components/ui/label';
+
+	// Dummy Data, Replace with API fetch
+	function defaultGroups() {
+		return [
+			{
+				id: 0,
+				checked: false,
+				name: "Test Group 1"
+			},
+			{
+				id: 1,
+				checked: false,
+				name: "Test Group 2"
+			}
+		]
+	}
+
+	type Group = {
+		id: number,
+		checked: boolean,
+		name: string
+	}
+
+	type Game = {
+		id: number,
+		checked: boolean,
+		name: string,
+		groups: Array<Group>
+	}
+
+	let games: Array<Game> = $state([
+		{
+			id: 0,
+			checked: false,
+			name: "Test 1",
+			groups: defaultGroups()
+		},
+		{
+			id: 1,
+			checked: false,
+			name: "Test 2",
+			groups: defaultGroups()
+		},
+		{
+			id: 2,
+			checked: false,
+			name: "Test 3",
+			groups: defaultGroups()
+		},
+		{
+			id: 3,
+			checked: false,
+			name: "Test 4",
+			groups: defaultGroups()
+		}
+	])
+
+	$effect(() => {
+		console.log(games)
+	})
+
+
+	function toggleGame(id: number) {
+		games[id].checked = !games[id].checked;
+		games = games;
+	}
+
+	let test = $state([
+		true,
+		false,
+		true
+	])
+
+	let filterWidth = 90
+</script>
+
+<div class="h-full grid grid-cols-5">
+	<div class="p-2 flex flex-col items-center border-r-2 border-accent">
+		<h2 class="py-2">Editing Mode</h2>
+		<Separator orientation="horizontal" class="w-[{filterWidth}%]" />
+		<h2 class="py-2">Filters</h2>
+		<Separator orientation="horizontal" class="w-[{filterWidth}%]" />
+		<Collapsible.Root class="w-[{filterWidth}%] space-y-2 py-2">
+			<Collapsible.Trigger asChild let:builder>
+				<Button builders={[builder]} variant="ghost" size="sm" class="w-full p-0 justify-start">
+					{#if builder["data-state"] == "open"}
+						<CaretDown />
+					{:else}
+						<CaretRight />
+					{/if}
+					<h4 class="rounded-md text-sm font-semibold text-left align-middle">
+						Games
+					</h4>
+				</Button>
+			</Collapsible.Trigger>
+			<Collapsible.Content class="space-y-2">
+				{#each games as game}
+					<div class="pl-4 flex items-center space-x-2">
+						<Checkbox id="{game.id.toString()}" checked={game.checked} on:click={() => game.checked = !game.checked} />
+						<Label
+							for="{game.id.toString()}"
+							class=""
+						>
+							{game.name}
+						</Label>
+					</div>
+				{/each}
+			</Collapsible.Content>
+		</Collapsible.Root>
+		<Separator orientation="horizontal" class="w-[{filterWidth}%]" />
+		<Collapsible.Root class="w-[{filterWidth}%] space-y-2 py-2">
+			<Collapsible.Trigger asChild let:builder>
+				<Button builders={[builder]} variant="ghost" size="sm" class="w-full p-0 justify-start">
+					{#if builder["data-state"] == "open"}
+						<CaretDown />
+					{:else}
+						<CaretRight />
+					{/if}
+					<h4 class="rounded-md text-sm font-semibold text-left align-middle">
+						Groups
+					</h4>
+				</Button>
+			</Collapsible.Trigger>
+			<Collapsible.Content class="space-y-2">
+				{#if games.filter(value => value.checked == true).length == 0}
+					<div class="pl-4 flex flex-col items-center space-x-2 text-muted-foreground">
+						<Label class="text-center" >No Games Selected</Label>
+					</div>
+				{/if}
+				{#each games as game}
+					{#if game.checked}
+						{#each game.groups as group}
+							<div class="pl-4 flex items-center space-x-2">
+								<Checkbox id="{game.id}-{group.id}" checked={group.checked} on:click={() => {games[game.id].groups[group.id].checked = !group.checked}} />
+								<Label
+									for="{game.id}-{group.id}"
+									class=""
+								>
+									{game.name} {group.name}
+								</Label>
+							</div>
+						{/each}
+					{/if}
+				{/each}
+			</Collapsible.Content>
+		</Collapsible.Root>
+	</div>
+	<div class="col-span-2 border-r-2 border-accent">B</div>
+	<div class=""></div>
+</div>
\ No newline at end of file

From 59a0cb4bc9b9df63632db00294375079cb22af1c Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Sat, 9 Dec 2023 18:53:07 +0100
Subject: [PATCH 15/24] Temporary Auth disable on Admin page for testing

---
 src/routes/admin/+page.server.ts | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/routes/admin/+page.server.ts b/src/routes/admin/+page.server.ts
index 095d527..a811fbc 100644
--- a/src/routes/admin/+page.server.ts
+++ b/src/routes/admin/+page.server.ts
@@ -9,7 +9,8 @@ export async function load({ cookies }) {
     }
   })).json();
 
-  if (!auth.admin && !auth.moderator) {
+  /*if (!auth.admin && !auth.moderator) {
     throw redirect(303, '/401');
-  }
+  }*/
+  console.log("WARNING: Admin Auth Check is disabled! DO NOT USE IN PRODUCTION")
 }

From 0ac6065a8327422fcefbab97741925978dacb852 Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Sat, 9 Dec 2023 18:53:45 +0100
Subject: [PATCH 16/24] Svelte Rune Mode fixes

---
 src/routes/+layout.svelte | 13 +++++++------
 src/routes/+page.svelte   |  3 ++-
 src/routes/Header.svelte  |  5 ++++-
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index fe62969..9bf1287 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -2,6 +2,7 @@
 
 <script lang="ts">
 	import '../app.postcss';
+	import { page } from '$app/stores';
 	import { browser } from '$app/environment';
 	import { writable } from 'svelte/store';
 	import { themes } from '$lib/types/themes'
@@ -38,12 +39,12 @@
 
 </script>
 
-<div class="h-full" >
-	<Header/>
+<Header {page}/>
+<div class="m-4 border-2 border-accent rounded-lg h-[calc(100%-5.75rem-1px)]">
 	<slot />
-	<!-- Router Slot -->
-	<!-- ---- / ---- -->
-	<!-- (pageFooter) -->
-	<!-- (footer) -->
 </div>
+<!-- Router Slot -->
+<!-- ---- / ---- -->
+<!-- (pageFooter) -->
+<!-- (footer) -->
 
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index dd66140..27819f9 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -1,4 +1,5 @@
-<!-- YOU CAN DELETE EVERYTHING IN THIS PAGE -->
+<svelte:options runes={true} />
+
 <script lang="ts">
 </script>
 
diff --git a/src/routes/Header.svelte b/src/routes/Header.svelte
index 861ab9b..422612b 100644
--- a/src/routes/Header.svelte
+++ b/src/routes/Header.svelte
@@ -1,5 +1,6 @@
+<svelte:options runes={true} />
+
 <script lang="ts">
-	import { page } from '$app/stores';
 	import discord from '$lib/images/discord.svg';
 	import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
 	import { Button } from '$lib/components/ui/button';
@@ -9,6 +10,8 @@
 	import { Exit } from 'radix-icons-svelte';
 	import { Separator } from '$lib/components/ui/separator';
 
+	let { page } = $props()
+
 	let user = {
 		loggedIn: true, // DEBUG
 		admin: true, // DEBUG

From bbe681d6d9beb031feafc544bc90a0370c7ca87f Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Sat, 9 Dec 2023 18:54:00 +0100
Subject: [PATCH 17/24] Svelte 5 Version Bump (fixed #each block problems)

---
 yarn.lock | 54 +++++++++++++++++++++++++++---------------------------
 1 file changed, 27 insertions(+), 27 deletions(-)

diff --git a/yarn.lock b/yarn.lock
index a7107d2..45ef183 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -301,9 +301,9 @@
     fastq "^1.6.0"
 
 "@polka/url@^1.0.0-next.20":
-  version "1.0.0-next.23"
-  resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.23.tgz#498e41218ab3b6a1419c735e5c6ae2c5ed609b6c"
-  integrity sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==
+  version "1.0.0-next.24"
+  resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.24.tgz#58601079e11784d20f82d0585865bb42305c4df3"
+  integrity sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==
 
 "@popperjs/core@^2.9.3":
   version "2.11.8"
@@ -318,9 +318,9 @@
     import-meta-resolve "^4.0.0"
 
 "@sveltejs/kit@^1.20.4":
-  version "1.27.6"
-  resolved "https://registry.yarnpkg.com/@sveltejs/kit/-/kit-1.27.6.tgz#2feea84413205422887e01326d979edd9a982dff"
-  integrity sha512-GsjTkMbKzXdbeRg0tk8S7HNShQ4879ftRr0ZHaZfjbig1xQwG57Bvcm9U9/mpLJtCapLbLWUnygKrgcLISLC8A==
+  version "1.27.7"
+  resolved "https://registry.yarnpkg.com/@sveltejs/kit/-/kit-1.27.7.tgz#9d31f4d9057a5460cc071088d61d2b599b360469"
+  integrity sha512-AzXYDoYt42clCBwLF9GTHsXyg2DFR31Ncyt8yxu8Aw4tgB433V+w+hcr1RTfAN9zKW2J2PY9FMQ8FoX/4Vw8CA==
   dependencies:
     "@sveltejs/vite-plugin-svelte" "^2.5.0"
     "@types/cookie" "^0.5.1"
@@ -379,9 +379,9 @@
   integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
 
 "@types/node@^20.6.0":
-  version "20.10.3"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.3.tgz#4900adcc7fc189d5af5bb41da8f543cea6962030"
-  integrity sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==
+  version "20.10.4"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.4.tgz#b246fd84d55d5b1b71bf51f964bd514409347198"
+  integrity sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==
   dependencies:
     undici-types "~5.26.4"
 
@@ -490,9 +490,9 @@ acorn-jsx@^5.3.2:
   integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
 
 acorn-typescript@^1.4.11:
-  version "1.4.11"
-  resolved "https://registry.yarnpkg.com/acorn-typescript/-/acorn-typescript-1.4.11.tgz#c4003ddb0e3d700e1ee41c5e843cab44a50f2a0a"
-  integrity sha512-cRGgp+4HMxMZAiMS61ZmQ3iuU/+A4g4ZYZsyLZdmvrEVN/TOwfJ40rPWcLqi3H5ut75SYAdOOJj6QGCcrkK57w==
+  version "1.4.12"
+  resolved "https://registry.yarnpkg.com/acorn-typescript/-/acorn-typescript-1.4.12.tgz#5e91360b039c590e0f9ee3934c15469666a8eb1a"
+  integrity sha512-G/oj3oiBmYlc+6SJZYMRz+SPgSgBWqEXPzhO55dYvT4x8SJM+HkxU5o5OPFstxsMMk1tXPYtYCyd7jUdHZy8Eg==
 
 acorn@^8.10.0, acorn@^8.9.0:
   version "8.11.2"
@@ -586,9 +586,9 @@ binary-extensions@^2.0.0:
   integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
 
 bits-ui@^0.11.3:
-  version "0.11.3"
-  resolved "https://registry.yarnpkg.com/bits-ui/-/bits-ui-0.11.3.tgz#624e2fecf780565dc9beac00c17745647dfa0356"
-  integrity sha512-WV8XCkLW1u9vStdifgAiCmz5UW3u65Jm05SLuj0SOxQP6pkZIwnt1Nq61QOWsOEUeqYcQrp2VZsX1bhMuTVNpg==
+  version "0.11.6"
+  resolved "https://registry.yarnpkg.com/bits-ui/-/bits-ui-0.11.6.tgz#ae730ee66a6ca2571257321123482c604de06cb9"
+  integrity sha512-m/8A1InhFoEgRcK6wF4W2pCNq0gV0U4aNVHIcr8ZDqzHT2r5sK5v7ZBoLfpte1rNO35wZ+R0PxxWx058IXGjBQ==
   dependencies:
     "@internationalized/date" "^3.5.0"
     "@melt-ui/svelte" "0.64.5"
@@ -648,9 +648,9 @@ chalk@^4.0.0:
     supports-color "^7.1.0"
 
 chart.js@^4.3.3:
-  version "4.4.0"
-  resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-4.4.0.tgz#df843fdd9ec6bd88d7f07e2b95348d221bd2698c"
-  integrity sha512-vQEj6d+z0dcsKLlQvbKIMYFHd3t8W/7L2vfJIbYcfyPcRx92CsHqECpueN8qVGNlKyDcr5wBrYAYKnfu/9Q1hQ==
+  version "4.4.1"
+  resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-4.4.1.tgz#ac5dc0e69a7758909158a96fe80ce43b3bb96a9f"
+  integrity sha512-C74QN1bxwV1v2PEujhmKjOZ7iUM4w6BWs23Md/6aOZZSlwMzeCIDGuZay++rBgChYru7/+QFeoQW0fQoP534Dg==
   dependencies:
     "@kurkle/color" "^0.3.0"
 
@@ -777,9 +777,9 @@ doctrine@^3.0.0:
     esutils "^2.0.2"
 
 electron-to-chromium@^1.4.601:
-  version "1.4.601"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.601.tgz#cac69868548aee89961ffe63ff5a7716f0685b75"
-  integrity sha512-SpwUMDWe9tQu8JX5QCO1+p/hChAi9AE9UpoC3rcHVc+gdCGlbT3SGb5I1klgb952HRIyvt9wZhSz9bNBYz9swA==
+  version "1.4.609"
+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.609.tgz#5790a70aaa96de232501b56e14b64d17aff93988"
+  integrity sha512-ihiCP7PJmjoGNuLpl7TjNA8pCQWu09vGyjlPYw1Rqww4gvNuCcmvl+44G+2QyJ6S2K4o+wbTS++Xz0YN8Q9ERw==
 
 es6-promise@^3.1.2:
   version "3.3.1"
@@ -1884,9 +1884,9 @@ svelte-preprocess@^5.1.0:
     strip-indent "^3.0.0"
 
 svelte@^5.0.0-next.17:
-  version "5.0.0-next.17"
-  resolved "https://registry.yarnpkg.com/svelte/-/svelte-5.0.0-next.17.tgz#5fe86849daa0d990754402b10b48e7b60d7a6de9"
-  integrity sha512-+TiGAi3kqwIIXtB3h1sLs3cD/KMdk3L/zEArfw0ZeqqO/hLrRGRvnTxspgktxYLHG9trBn6Xx9zD2Eekze7CCA==
+  version "5.0.0-next.22"
+  resolved "https://registry.yarnpkg.com/svelte/-/svelte-5.0.0-next.22.tgz#a4c6a872128a5e6f0e244f906b1d953573d01ebb"
+  integrity sha512-N2ss/7v2mP9Ru95Caj2+9bAL8I7DUdqCpymBG9MVAVb8nJPQIsQsS87Wd5VCeyyzni1gDzcK5ogoLJ5nkwDJfg==
   dependencies:
     "@ampproject/remapping" "^2.2.1"
     "@jridgewell/sourcemap-codec" "^1.4.15"
@@ -2027,9 +2027,9 @@ type-fest@^0.20.2:
   integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
 
 typescript@^5.0.0, typescript@^5.0.3:
-  version "5.3.2"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.2.tgz#00d1c7c1c46928c5845c1ee8d0cc2791031d4c43"
-  integrity sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==
+  version "5.3.3"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37"
+  integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==
 
 undici-types@~5.26.4:
   version "5.26.5"

From 79bdf1bc6c7f88fabdf390845dff5b2011ab140e Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Sat, 9 Dec 2023 18:54:09 +0100
Subject: [PATCH 18/24] Use entire site height by default

---
 src/app.html | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/app.html b/src/app.html
index 7a50504..1a2afae 100644
--- a/src/app.html
+++ b/src/app.html
@@ -1,12 +1,12 @@
 <!DOCTYPE html>
-<html lang="en" class="dark">
+<html lang="en" class="dark h-full">
 	<head>
 		<meta charset="utf-8" />
 		<link rel="icon" href="%sveltekit.assets%/favicon.png" />
 		<meta name="viewport" content="width=device-width" />
 		%sveltekit.head%
 	</head>
-	<body data-sveltekit-preload-data="hover">
-		<div style="display: contents;" class="h-screen overflow-hidden contents">%sveltekit.body%</div>
+	<body class="h-full w-full" data-sveltekit-preload-data="hover">
+		%sveltekit.body%
 	</body>
 </html>

From 792b11248ab0fb79d81d399f90336d909678f658 Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Sun, 10 Dec 2023 23:19:42 +0100
Subject: [PATCH 19/24] Package.json Version Bump

---
 package.json | 2 +-
 yarn.lock    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/package.json b/package.json
index 109e5ea..b0ac2bf 100644
--- a/package.json
+++ b/package.json
@@ -38,7 +38,7 @@
   },
   "type": "module",
   "dependencies": {
-    "bits-ui": "^0.11.3",
+    "bits-ui": "^0.11.6",
     "chart.js": "^4.3.3",
     "chartjs-plugin-datalabels": "^2.2.0",
     "clsx": "^2.0.0",
diff --git a/yarn.lock b/yarn.lock
index 45ef183..0b6c188 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -585,7 +585,7 @@ binary-extensions@^2.0.0:
   resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
   integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
 
-bits-ui@^0.11.3:
+bits-ui@^0.11.6:
   version "0.11.6"
   resolved "https://registry.yarnpkg.com/bits-ui/-/bits-ui-0.11.6.tgz#ae730ee66a6ca2571257321123482c604de06cb9"
   integrity sha512-m/8A1InhFoEgRcK6wF4W2pCNq0gV0U4aNVHIcr8ZDqzHT2r5sK5v7ZBoLfpte1rNO35wZ+R0PxxWx058IXGjBQ==

From cf477b1f25270faacffe7fcd0721457f0d16a562 Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Sun, 10 Dec 2023 23:21:13 +0100
Subject: [PATCH 20/24] Updates to Navbar Account PopOver

---
 src/routes/Header.svelte                   | 156 +++++++++++++--------
 src/routes/{login => sign-up}/+page.svelte |   0
 2 files changed, 101 insertions(+), 55 deletions(-)
 rename src/routes/{login => sign-up}/+page.svelte (100%)

diff --git a/src/routes/Header.svelte b/src/routes/Header.svelte
index 422612b..8e6e534 100644
--- a/src/routes/Header.svelte
+++ b/src/routes/Header.svelte
@@ -2,27 +2,36 @@
 
 <script lang="ts">
 	import discord from '$lib/images/discord.svg';
-	import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
 	import { Button } from '$lib/components/ui/button';
 	import { themes } from '$lib/types/themes';
 	import UserSettingsStore from '$lib/stores/UserSettingsStore';
 	import * as Avatar from '$lib/components/ui/avatar';
-	import { Exit } from 'radix-icons-svelte';
+	import { CaretDown, CaretRight, Exit, EyeClosed, EyeOpen } from 'radix-icons-svelte';
 	import { Separator } from '$lib/components/ui/separator';
+	import * as Popover from '$lib/components/ui/popover';
 
 	let { page } = $props()
 
-	let user = {
-		loggedIn: true, // DEBUG
-		admin: true, // DEBUG
+	type User = {
+		token: string,
+		tokenVisible: boolean,
+		discord: string | undefined,
+		picture: string | undefined,
+		admin: boolean
 	}
 
-	function login() {
+	/*let user: User | undefined = $state({
 		user.loggedIn = true;
-	}
+		tokenVisible: false,
+		discord: "neshura",
+		picture: "/avatar.png",
+		admin: true, // DEBUG
+	})*/
+
+	let user: User | undefined = $state(undefined);
 
 	function logout() {
-		user.loggedIn = false;
+		user = undefined
 	}
 
 	function nextTheme() {
@@ -38,6 +47,18 @@
 
 <div class="flex gap-2 items-center justify-center py-3 bg-primary-foreground">
 	<!-- spacer -->
+		<Button
+			variant="link"
+			href="https://discord.gg/invite/BYNeHaPNh9"
+			target="_blank"
+			rel="noopener noreferrer"
+			class="h-8 w-8 items-center flex"
+		>
+			<Avatar.Root class="h-6 w-6">
+				<Avatar.Image src={discord} alt="DC" />
+				<Avatar.Fallback>US</Avatar.Fallback>
+			</Avatar.Root>
+		</Button>
 		<Button
 			variant="ghost"
 			href="/"
@@ -59,7 +80,7 @@
 		>
 			Archives
 		</Button>
-		{#if user.loggedIn && user.admin}
+		{#if user != undefined && user.admin}
 			<Button
 				variant="ghost"
 				href="/admin"
@@ -67,64 +88,89 @@
 			>
 				Admin
 			</Button>
+			<Button
+				variant="ghost"
+				href="/admin/new"
+				class="{$page.url.pathname == '/admin/new' ? 'text-accent-foreground bg-accent' : ''}"
+			>
+				Admin (New)
+			</Button>
 		{/if}
-		<div class="dropdown" href="user.loggedIn ? /account | /login"></div>
-		{#if user.loggedIn}
-			<DropdownMenu.Root>
-				<DropdownMenu.Trigger asChild let:builder>
+		{#if user != undefined}
+			<Popover.Root>
+				<Popover.Trigger>
 					<Button
 						variant="ghost"
-						builders={[builder]}
-						class="relative h-8 w-8 rounded-full"
+						class="relative h-8 w-8 rounded-full align-middle"
 					>
 						<Avatar.Root class="h-8 w-8">
-							<Avatar.Image src="/avatar.png" alt="@user" />
+							<Avatar.Image src={user.picture} alt="@user" />
 							<Avatar.Fallback>US</Avatar.Fallback>
 						</Avatar.Root>
 					</Button>
-				</DropdownMenu.Trigger>
-				<DropdownMenu.Content class="w-56">
-					<DropdownMenu.Label class="font-normal">
-						<div class="flex flex-col space-y-1 items-start">
-							<p class="text-sm font-medium leading-none">User Display</p>
-							<p class="text-xs leading-none text-muted-foreground">@User</p>
+				</Popover.Trigger>
+				<Popover.Content class="w-56 p-0">
+					<div class="w-full p-1">
+						<div class="px-2 py-1.5 font-normal">
+							<div class="flex flex-row items-center gap-1">
+								{#if user.tokenVisible}
+									<p class="text-sm font-medium leading-none w-12">{user.token}</p> <!--Make the UserToken hidden by default-->
+								{:else}
+									<p class="text-sm font-medium leading-none w-12">******</p>
+								{/if}
+								<Button variant="ghost" size="sm" class="p-0 h-2 justify-start" on:click={() => {user.tokenVisible = !user.tokenVisible}}>
+									{#if user.tokenVisible}
+										<EyeOpen />
+									{:else}
+										<EyeClosed />
+									{/if}
+								</Button>
+							</div>
+							{#if user.discord}
+								<p class="mt-1 text-xs leading-none text-muted-foreground">@{user.discord}</p>
+							{/if}
 						</div>
-					</DropdownMenu.Label>
-					<DropdownMenu.Separator />
-					<DropdownMenu.Group>
-						<DropdownMenu.Item href="/profile">
+					</div>
+					<Separator orientation="horizontal" />
+					<div class="w-full p-1">
+						<Button variant="ghost" class="justify-start h-8 px-2 py-1.5 text-sm w-full" href="/profile">
 							Profile
-						</DropdownMenu.Item>
-						<DropdownMenu.Item href="/settings">
+						</Button>
+						<Button variant="ghost" class="justify-start h-8 px-2 py-1.5 text-sm w-full" href="/settings">
 							Settings
-						</DropdownMenu.Item>
-					</DropdownMenu.Group>
-					<DropdownMenu.Separator />
-					<DropdownMenu.Item class="flex flex-row space-x-1" on:click={logout}>
-						<p>Log out </p>
-						<Exit />
-					</DropdownMenu.Item>
-				</DropdownMenu.Content>
-			</DropdownMenu.Root>
+						</Button>
+					</div>
+					<Separator orientation="horizontal" />
+					<div class="w-full p-1">
+						<Button variant="ghost" class="flex flex-row items-center justify-start h-8 space-x-1 px-2 py-1.5 text-sm w-full" on:click={logout}>
+							<p>Log out </p>
+							<Exit />
+						</Button>
+					</div>
+				</Popover.Content>
+			</Popover.Root>
 		{:else}
-			<Button
-				variant="ghost"
-				class="relative"
-			>
-				Log in
-			</Button>
+			<Popover.Root>
+				<Popover.Trigger>
+					<Button
+						variant="ghost"
+						class="relative"
+					>
+						Log In
+					</Button>
+				</Popover.Trigger>
+				<Popover.Content class="w-56 p-1">
+					<Button variant="ghost" class="justify-start h-8 px-2 py-1.5 text-sm w-full" href="/profile">
+						Token:
+
+						Log In
+					</Button>
+					<Button variant="ghost" class="flex flex-row items-center justify-start h-8 space-x-1 px-2 py-1.5 text-sm w-full" on:click={logout}>
+						<p>Sign Up </p>
+						<Exit />
+					</Button>
+				</Popover.Content>
+			</Popover.Root>
 		{/if}
-	<Button
-		variant="link"
-		href="https://discord.gg/invite/BYNeHaPNh9"
-		target="_blank"
-		rel="noopener noreferrer"
-		class="h-8 w-8 items-center flex"
-	>
-		<Avatar.Root class="h-6 w-6">
-			<Avatar.Image src={discord} alt="DC" />
-			<Avatar.Fallback>US</Avatar.Fallback>
-		</Avatar.Root>
-	</Button>
 </div>
 <Separator orientation="horizontal"></Separator>
diff --git a/src/routes/login/+page.svelte b/src/routes/sign-up/+page.svelte
similarity index 100%
rename from src/routes/login/+page.svelte
rename to src/routes/sign-up/+page.svelte

From 4d6f3c23c392bb7be304e07a851d71685e80e4e6 Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Sun, 10 Dec 2023 23:21:35 +0100
Subject: [PATCH 21/24] Add Shadcn Components

---
 src/lib/components/ui/popover/index.ts        | 14 ++++++++
 .../ui/popover/popover-content.svelte         | 27 ++++++++++++++
 src/lib/components/ui/select/index.ts         | 34 ++++++++++++++++++
 .../ui/select/select-content.svelte           | 36 +++++++++++++++++++
 .../components/ui/select/select-item.svelte   | 35 ++++++++++++++++++
 .../components/ui/select/select-label.svelte  | 16 +++++++++
 .../ui/select/select-separator.svelte         | 14 ++++++++
 .../ui/select/select-trigger.svelte           | 24 +++++++++++++
 src/lib/components/ui/skeleton/index.ts       |  7 ++++
 .../components/ui/skeleton/skeleton.svelte    | 14 ++++++++
 10 files changed, 221 insertions(+)
 create mode 100644 src/lib/components/ui/popover/index.ts
 create mode 100644 src/lib/components/ui/popover/popover-content.svelte
 create mode 100644 src/lib/components/ui/select/index.ts
 create mode 100644 src/lib/components/ui/select/select-content.svelte
 create mode 100644 src/lib/components/ui/select/select-item.svelte
 create mode 100644 src/lib/components/ui/select/select-label.svelte
 create mode 100644 src/lib/components/ui/select/select-separator.svelte
 create mode 100644 src/lib/components/ui/select/select-trigger.svelte
 create mode 100644 src/lib/components/ui/skeleton/index.ts
 create mode 100644 src/lib/components/ui/skeleton/skeleton.svelte

diff --git a/src/lib/components/ui/popover/index.ts b/src/lib/components/ui/popover/index.ts
new file mode 100644
index 0000000..66063f5
--- /dev/null
+++ b/src/lib/components/ui/popover/index.ts
@@ -0,0 +1,14 @@
+import { Popover as PopoverPrimitive } from "bits-ui";
+import Content from "./popover-content.svelte";
+const Root = PopoverPrimitive.Root;
+const Trigger = PopoverPrimitive.Trigger;
+
+export {
+	Root,
+	Content,
+	Trigger,
+	//
+	Root as Popover,
+	Content as PopoverContent,
+	Trigger as PopoverTrigger
+};
diff --git a/src/lib/components/ui/popover/popover-content.svelte b/src/lib/components/ui/popover/popover-content.svelte
new file mode 100644
index 0000000..db19f36
--- /dev/null
+++ b/src/lib/components/ui/popover/popover-content.svelte
@@ -0,0 +1,27 @@
+<script lang="ts">
+	import { Popover as PopoverPrimitive } from "bits-ui";
+	import { cn, flyAndScale } from "$lib/utils";
+
+	type $$Props = PopoverPrimitive.ContentProps;
+
+	let className: $$Props["class"] = undefined;
+	export let transition: $$Props["transition"] = flyAndScale;
+	export let transitionConfig: $$Props["transitionConfig"] = undefined;
+	export let align: $$Props["align"] = "center";
+	export let sideOffset: $$Props["sideOffset"] = 4;
+	export { className as class };
+</script>
+
+<PopoverPrimitive.Content
+	{transition}
+	{transitionConfig}
+	{align}
+	{sideOffset}
+	{...$$restProps}
+	class={cn(
+		"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none",
+		className
+	)}
+>
+	<slot />
+</PopoverPrimitive.Content>
diff --git a/src/lib/components/ui/select/index.ts b/src/lib/components/ui/select/index.ts
new file mode 100644
index 0000000..a682496
--- /dev/null
+++ b/src/lib/components/ui/select/index.ts
@@ -0,0 +1,34 @@
+import { Select as SelectPrimitive } from "bits-ui";
+
+import Label from "./select-label.svelte";
+import Item from "./select-item.svelte";
+import Content from "./select-content.svelte";
+import Trigger from "./select-trigger.svelte";
+import Separator from "./select-separator.svelte";
+
+const Root = SelectPrimitive.Root;
+const Group = SelectPrimitive.Group;
+const Input = SelectPrimitive.Input;
+const Value = SelectPrimitive.Value;
+
+export {
+	Root,
+	Item,
+	Group,
+	Input,
+	Label,
+	Value,
+	Content,
+	Trigger,
+	Separator,
+	//
+	Root as Select,
+	Item as SelectItem,
+	Group as SelectGroup,
+	Input as SelectInput,
+	Label as SelectLabel,
+	Value as SelectValue,
+	Content as SelectContent,
+	Trigger as SelectTrigger,
+	Separator as SelectSeparator
+};
diff --git a/src/lib/components/ui/select/select-content.svelte b/src/lib/components/ui/select/select-content.svelte
new file mode 100644
index 0000000..72afc71
--- /dev/null
+++ b/src/lib/components/ui/select/select-content.svelte
@@ -0,0 +1,36 @@
+<script lang="ts">
+	import { Select as SelectPrimitive } from "bits-ui";
+	import { cn, flyAndScale } from "$lib/utils";
+	import { scale } from "svelte/transition";
+
+	type $$Props = SelectPrimitive.ContentProps;
+
+	let className: $$Props["class"] = undefined;
+	export let sideOffset: $$Props["sideOffset"] = 4;
+	export let inTransition: $$Props["inTransition"] = flyAndScale;
+	export let inTransitionConfig: $$Props["inTransitionConfig"] = undefined;
+	export let outTransition: $$Props["outTransition"] = scale;
+	export let outTransitionConfig: $$Props["outTransitionConfig"] = {
+		start: 0.95,
+		opacity: 0,
+		duration: 50
+	};
+	export { className as class };
+</script>
+
+<SelectPrimitive.Content
+	{inTransition}
+	{inTransitionConfig}
+	{outTransition}
+	{outTransitionConfig}
+	{sideOffset}
+	class={cn(
+		"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md focus:outline-none",
+		className
+	)}
+	{...$$restProps}
+>
+	<div class="w-full p-1">
+		<slot />
+	</div>
+</SelectPrimitive.Content>
diff --git a/src/lib/components/ui/select/select-item.svelte b/src/lib/components/ui/select/select-item.svelte
new file mode 100644
index 0000000..cd583a1
--- /dev/null
+++ b/src/lib/components/ui/select/select-item.svelte
@@ -0,0 +1,35 @@
+<script lang="ts">
+	import { cn } from "$lib/utils";
+	import { Select as SelectPrimitive } from "bits-ui";
+	import { Check } from "radix-icons-svelte";
+
+	type $$Props = SelectPrimitive.ItemProps;
+	type $$Events = Required<SelectPrimitive.ItemEvents>;
+
+	let className: $$Props["class"] = undefined;
+	export let value: $$Props["value"];
+	export let label: $$Props["label"] = undefined;
+	export let disabled: $$Props["disabled"] = undefined;
+	export { className as class };
+</script>
+
+<SelectPrimitive.Item
+	{value}
+	{disabled}
+	{label}
+	class={cn(
+		"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
+		className
+	)}
+	{...$$restProps}
+	on:click
+	on:pointermove
+	on:focusin
+>
+	<span class="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
+		<SelectPrimitive.ItemIndicator>
+			<Check class="h-4 w-4" />
+		</SelectPrimitive.ItemIndicator>
+	</span>
+	<slot />
+</SelectPrimitive.Item>
diff --git a/src/lib/components/ui/select/select-label.svelte b/src/lib/components/ui/select/select-label.svelte
new file mode 100644
index 0000000..7175e6f
--- /dev/null
+++ b/src/lib/components/ui/select/select-label.svelte
@@ -0,0 +1,16 @@
+<script lang="ts">
+	import { Select as SelectPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+
+	type $$Props = SelectPrimitive.LabelProps;
+
+	let className: $$Props["class"] = undefined;
+	export { className as class };
+</script>
+
+<SelectPrimitive.Label
+	class={cn("px-2 py-1.5 text-sm font-semibold", className)}
+	{...$$restProps}
+>
+	<slot />
+</SelectPrimitive.Label>
diff --git a/src/lib/components/ui/select/select-separator.svelte b/src/lib/components/ui/select/select-separator.svelte
new file mode 100644
index 0000000..aa028c4
--- /dev/null
+++ b/src/lib/components/ui/select/select-separator.svelte
@@ -0,0 +1,14 @@
+<script lang="ts">
+	import { Select as SelectPrimitive } from "bits-ui";
+	import { cn } from "$lib/utils";
+
+	type $$Props = SelectPrimitive.SeparatorProps;
+
+	let className: $$Props["class"] = undefined;
+	export { className as class };
+</script>
+
+<SelectPrimitive.Separator
+	class={cn("-mx-1 my-1 h-px bg-muted", className)}
+	{...$$restProps}
+/>
diff --git a/src/lib/components/ui/select/select-trigger.svelte b/src/lib/components/ui/select/select-trigger.svelte
new file mode 100644
index 0000000..bc8eedc
--- /dev/null
+++ b/src/lib/components/ui/select/select-trigger.svelte
@@ -0,0 +1,24 @@
+<script lang="ts">
+	import { Select as SelectPrimitive } from "bits-ui";
+	import { CaretSort } from "radix-icons-svelte";
+	import { cn } from "$lib/utils";
+
+	type $$Props = SelectPrimitive.TriggerProps;
+	type $$Events = SelectPrimitive.TriggerEvents;
+
+	let className: $$Props["class"] = undefined;
+	export { className as class };
+</script>
+
+<SelectPrimitive.Trigger
+	class={cn(
+		"flex h-9 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
+		className
+	)}
+	{...$$restProps}
+>
+	<slot />
+	<div>
+		<CaretSort class="h-4 w-4 opacity-50" />
+	</div>
+</SelectPrimitive.Trigger>
diff --git a/src/lib/components/ui/skeleton/index.ts b/src/lib/components/ui/skeleton/index.ts
new file mode 100644
index 0000000..2be5c50
--- /dev/null
+++ b/src/lib/components/ui/skeleton/index.ts
@@ -0,0 +1,7 @@
+import Root from "./skeleton.svelte";
+
+export {
+	Root,
+	//
+	Root as Skeleton
+};
diff --git a/src/lib/components/ui/skeleton/skeleton.svelte b/src/lib/components/ui/skeleton/skeleton.svelte
new file mode 100644
index 0000000..cdd92be
--- /dev/null
+++ b/src/lib/components/ui/skeleton/skeleton.svelte
@@ -0,0 +1,14 @@
+<script lang="ts">
+	import { cn } from "$lib/utils";
+	import type { HTMLAttributes } from "svelte/elements";
+
+	type $$Props = HTMLAttributes<HTMLDivElement>;
+
+	let className: $$Props["class"] = undefined;
+	export { className as class };
+</script>
+
+<div
+	class={cn("animate-pulse rounded-md bg-primary/10", className)}
+	{...$$restProps}
+/>

From 01e301eb60271293b4f40310936374515f760422 Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Sun, 10 Dec 2023 23:21:54 +0100
Subject: [PATCH 22/24] Implemented Mode Select and FIlters for Admin Page

---
 src/routes/admin/new/+page.svelte | 377 +++++++++++++++++++++++-------
 1 file changed, 295 insertions(+), 82 deletions(-)

diff --git a/src/routes/admin/new/+page.svelte b/src/routes/admin/new/+page.svelte
index b0c4bc8..56fe350 100644
--- a/src/routes/admin/new/+page.svelte
+++ b/src/routes/admin/new/+page.svelte
@@ -7,27 +7,61 @@
 	import { CaretDown, CaretRight } from 'radix-icons-svelte';
 	import { Checkbox } from '$lib/components/ui/checkbox';
 	import { Label } from '$lib/components/ui/label';
+	import { Skeleton } from '$lib/components/ui/skeleton';
+	import { range } from 'svelte-loading-spinners/utils';
+	import * as Select from '$lib/components/ui/select';
+	import AdminSelectedGameStore from '$lib/stores/admin-page/GameStore';
+	import AdminSelectedGroupStore from '$lib/stores/admin-page/GroupStore';
+	import AdminSelectedEmpireStore from '$lib/stores/admin-page/EmpireStore';
+	import {
+		type ChellarisEmpire,
+		type ChellarisGameGroup,
+		type ChellarisGameInfo,
+		createBlankEmpire
+	} from '$lib/types/chellaris';
+	import { apiBaseUrl } from '$lib/components_custom/consts';
 
 	// Dummy Data, Replace with API fetch
+	function defaultEmpires() {
+		return [
+			{
+				id: 0,
+				name: "Test Empire 1"
+			},
+			{
+				id: 1,
+				name: "Test Empire 2"
+			}
+		]
+	}
+
 	function defaultGroups() {
 		return [
 			{
 				id: 0,
 				checked: false,
-				name: "Test Group 1"
+				name: "Test Group 1",
+				empires: defaultEmpires()
 			},
 			{
 				id: 1,
 				checked: false,
-				name: "Test Group 2"
+				name: "Test Group 2",
+				empires: defaultEmpires()
 			}
 		]
 	}
 
+	type Empire = {
+		id: number,
+		name: string
+	}
+
 	type Group = {
 		id: number,
 		checked: boolean,
-		name: string
+		name: string,
+		empires: Array<Empire>
 	}
 
 	type Game = {
@@ -64,96 +98,275 @@
 		}
 	])
 
+	let filteredGames = $derived(games.filter(game => game.checked))
+	let filteredGroups = $derived(filteredGames.flatMap(game => game.groups.filter(group => group.checked)))
+
 	$effect(() => {
 		console.log(games)
 	})
 
+	const modes = [
+		{ value: "Game", label: "Games" },
+		{ value: "Group", label: "Groups" },
+		{ value: "Empire", label: "Empires" },
+		{ value: "Ethic", label: "Ethics" },
+		{ value: "Portrait", label: "Portraits" },
+		{ value: "User", label: "Users" }
+	];
 
-	function toggleGame(id: number) {
-		games[id].checked = !games[id].checked;
-		games = games;
+	let modeSelect = $state(modes[0]);
+
+	// Helper Function
+
+	function newGame() {
+		let newGame = {
+			id: games.length,
+			checked: false,
+			name: `Test ${games.length + 1}`,
+			groups: defaultGroups()
+		}
+		return newGame
 	}
 
-	let test = $state([
-		true,
-		false,
-		true
-	])
-
-	let filterWidth = 90
 </script>
 
 <div class="h-full grid grid-cols-5">
-	<div class="p-2 flex flex-col items-center border-r-2 border-accent">
-		<h2 class="py-2">Editing Mode</h2>
-		<Separator orientation="horizontal" class="w-[{filterWidth}%]" />
-		<h2 class="py-2">Filters</h2>
-		<Separator orientation="horizontal" class="w-[{filterWidth}%]" />
-		<Collapsible.Root class="w-[{filterWidth}%] space-y-2 py-2">
-			<Collapsible.Trigger asChild let:builder>
-				<Button builders={[builder]} variant="ghost" size="sm" class="w-full p-0 justify-start">
-					{#if builder["data-state"] == "open"}
-						<CaretDown />
-					{:else}
-						<CaretRight />
-					{/if}
-					<h4 class="rounded-md text-sm font-semibold text-left align-middle">
-						Games
-					</h4>
-				</Button>
-			</Collapsible.Trigger>
-			<Collapsible.Content class="space-y-2">
-				{#each games as game}
-					<div class="pl-4 flex items-center space-x-2">
-						<Checkbox id="{game.id.toString()}" checked={game.checked} on:click={() => game.checked = !game.checked} />
-						<Label
-							for="{game.id.toString()}"
-							class=""
-						>
-							{game.name}
-						</Label>
-					</div>
-				{/each}
-			</Collapsible.Content>
-		</Collapsible.Root>
-		<Separator orientation="horizontal" class="w-[{filterWidth}%]" />
-		<Collapsible.Root class="w-[{filterWidth}%] space-y-2 py-2">
-			<Collapsible.Trigger asChild let:builder>
-				<Button builders={[builder]} variant="ghost" size="sm" class="w-full p-0 justify-start">
-					{#if builder["data-state"] == "open"}
-						<CaretDown />
-					{:else}
-						<CaretRight />
-					{/if}
-					<h4 class="rounded-md text-sm font-semibold text-left align-middle">
-						Groups
-					</h4>
-				</Button>
-			</Collapsible.Trigger>
-			<Collapsible.Content class="space-y-2">
-				{#if games.filter(value => value.checked == true).length == 0}
-					<div class="pl-4 flex flex-col items-center space-x-2 text-muted-foreground">
-						<Label class="text-center" >No Games Selected</Label>
-					</div>
-				{/if}
-				{#each games as game}
-					{#if game.checked}
-						{#each game.groups as group}
-							<div class="pl-4 flex items-center space-x-2">
-								<Checkbox id="{game.id}-{group.id}" checked={group.checked} on:click={() => {games[game.id].groups[group.id].checked = !group.checked}} />
-								<Label
-									for="{game.id}-{group.id}"
-									class=""
-								>
-									{game.name} {group.name}
-								</Label>
-							</div>
+	<div class="pt-4 px-2 flex flex-col items-center border-r-2 border-accent gap-2">
+		<div class="flex flex-row gap-2">
+			<h2 class="self-center">
+				Editing
+			</h2>
+			<Select.Root bind:selected={modeSelect}>
+				<Select.Trigger class="w-28">
+					<Select.Value />
+				</Select.Trigger>
+				<Select.Content>
+					<Select.Group>
+						{#each modes as mode}
+							<Select.Item value={mode.value} label={mode.label}>
+								{mode.label}
+							</Select.Item>
 						{/each}
+					</Select.Group>
+				</Select.Content>
+				<Select.Input name="modeSelect" />
+			</Select.Root>
+		</div>
+		<Separator orientation="horizontal" class="w-[90%]" />
+		<h2>{modeSelect.value} Filters</h2>
+		{#if modeSelect.value == modes[0].value}
+
+		{:else if modeSelect.value == modes[1].value}
+			<Separator orientation="horizontal" class="w-[90%]" />
+			<Collapsible.Root class="w-[90%] space-y-2">
+				<Collapsible.Trigger asChild let:builder>
+					<Button builders={[builder]} variant="ghost" size="sm" class="w-full p-0 justify-start">
+						{#if builder["data-state"] == "open"}
+							<CaretDown />
+						{:else}
+							<CaretRight />
+						{/if}
+						<h4 class="rounded-md text-sm font-semibold text-left align-middle">
+							Games
+						</h4>
+					</Button>
+				</Collapsible.Trigger>
+				<Collapsible.Content class="space-y-2">
+					{#each games as game}
+						<div class="pl-4 flex items-center space-x-2">
+							<Checkbox id="{game.id.toString()}" checked={game.checked} on:click={() => game.checked = !game.checked} />
+							<Label
+								for="{game.id.toString()}"
+								class=""
+							>
+								{game.name}
+							</Label>
+						</div>
+					{/each}
+				</Collapsible.Content>
+			</Collapsible.Root>
+			<Separator orientation="horizontal" class="w-[90%]" />
+		{:else if modeSelect.value == modes[2].value}
+			<Separator orientation="horizontal" class="w-[90%]" />
+			<Collapsible.Root class="w-[90%] space-y-2">
+				<Collapsible.Trigger asChild let:builder>
+					<Button builders={[builder]} variant="ghost" size="sm" class="w-full p-0 justify-start">
+						{#if builder["data-state"] == "open"}
+							<CaretDown />
+						{:else}
+							<CaretRight />
+						{/if}
+						<h4 class="rounded-md text-sm font-semibold text-left align-middle">
+							Games
+						</h4>
+					</Button>
+				</Collapsible.Trigger>
+				<Collapsible.Content class="space-y-2">
+					{#each games as game}
+						<div class="pl-4 flex items-center space-x-2">
+							<Checkbox id="{game.id.toString()}" checked={game.checked} on:click={() => game.checked = !game.checked} />
+							<Label
+								for="{game.id.toString()}"
+								class=""
+							>
+								{game.name}
+							</Label>
+						</div>
+					{/each}
+				</Collapsible.Content>
+			</Collapsible.Root>
+			<Collapsible.Root class="w-[90%] space-y-2">
+				<Collapsible.Trigger asChild let:builder>
+					<Button builders={[builder]} variant="ghost" size="sm" class="w-full p-0 justify-start">
+						{#if builder["data-state"] == "open"}
+							<CaretDown />
+						{:else}
+							<CaretRight />
+						{/if}
+						<h4 class="rounded-md text-sm font-semibold text-left align-middle">
+							Groups
+						</h4>
+					</Button>
+				</Collapsible.Trigger>
+				<Collapsible.Content class="space-y-2">
+					{#if games.filter(value => value.checked == true).length == 0}
+						<div class="pl-4 flex flex-col items-center space-x-2 text-muted-foreground">
+							<Label class="text-center" >No Games Selected</Label>
+						</div>
 					{/if}
-				{/each}
-			</Collapsible.Content>
-		</Collapsible.Root>
+					{#each games as game}
+						{#if game.checked}
+							{#each game.groups as group}
+								<div class="pl-4 flex items-center space-x-2">
+									<Checkbox id="{game.id}-{group.id}" checked={group.checked} on:click={() => {games[game.id].groups[group.id].checked = !group.checked}} />
+									<Label
+										for="{game.id}-{group.id}"
+										class=""
+									>
+										{game.name} {group.name}
+									</Label>
+								</div>
+							{/each}
+						{/if}
+					{/each}
+				</Collapsible.Content>
+			</Collapsible.Root>
+			<Separator orientation="horizontal" class="w-[90%]" />
+		{:else if modeSelect.value == modes[3].value}
+			<Separator orientation="horizontal" class="w-[90%]" />
+			<Collapsible.Root class="w-[90%] space-y-2">
+				<Collapsible.Trigger asChild let:builder>
+					<Button builders={[builder]} variant="ghost" size="sm" class="w-full p-0 justify-start">
+						{#if builder["data-state"] == "open"}
+							<CaretDown />
+						{:else}
+							<CaretRight />
+						{/if}
+						<h4 class="rounded-md text-sm font-semibold text-left align-middle">
+							Games
+						</h4>
+					</Button>
+				</Collapsible.Trigger>
+				<Collapsible.Content class="space-y-2">
+					{#each games as game}
+						<div class="pl-4 flex items-center space-x-2">
+							<Checkbox id="{game.id.toString()}" checked={game.checked} on:click={() => game.checked = !game.checked} />
+							<Label
+								for="{game.id.toString()}"
+								class=""
+							>
+								{game.name}
+							</Label>
+						</div>
+					{/each}
+				</Collapsible.Content>
+			</Collapsible.Root>
+			<Separator orientation="horizontal" class="w-[90%]" />
+		{:else if modeSelect.value == modes[4].value}
+			<Separator orientation="horizontal" class="w-[90%]" />
+			<Collapsible.Root class="w-[90%] space-y-2">
+				<Collapsible.Trigger asChild let:builder>
+					<Button builders={[builder]} variant="ghost" size="sm" class="w-full p-0 justify-start">
+						{#if builder["data-state"] == "open"}
+							<CaretDown />
+						{:else}
+							<CaretRight />
+						{/if}
+						<h4 class="rounded-md text-sm font-semibold text-left align-middle">
+							Games
+						</h4>
+					</Button>
+				</Collapsible.Trigger>
+				<Collapsible.Content class="space-y-2">
+					{#each games as game}
+						<div class="pl-4 flex items-center space-x-2">
+							<Checkbox id="{game.id.toString()}" checked={game.checked} on:click={() => game.checked = !game.checked} />
+							<Label
+								for="{game.id.toString()}"
+								class=""
+							>
+								{game.name}
+							</Label>
+						</div>
+					{/each}
+				</Collapsible.Content>
+			</Collapsible.Root>
+			<Separator orientation="horizontal" class="w-[90%]" />
+		{/if}
+
+	</div>
+	<div class="pt-6 px-3 flex flex-col col-span-2 items-center border-r-2 border-accent text-center text-muted-foreground gap-2 overflow-y-scroll">
+		{#if modeSelect.value == modes[0].value}
+			{#each games as game}
+				<!--<Skeleton class="h-12 w-[90%]" />-->
+				<div class="px-6 h-12 w-[90%] flex flex-row items-center border-2 rounded-md bg-primary/10">
+					<p class="text-primary">{game.name}</p>
+				</div>
+			{:else}
+				No Content
+			{/each}
+			<Button
+				class="px-6 h-12 w-[90%] flex flex-row items-center border-2 rounded-md bg-primary/10 text-primary hover:bg-primary/5"
+				on:click={() => {games.push(newGame())}}
+			>
+				Add Game
+			</Button>
+		{:else if modeSelect.value == modes[1].value}
+			{#each filteredGames as game}
+				{#each game.groups as group}
+					<Skeleton class="h-12 w-[90%]" />
+				{/each}
+			{:else}
+				No Content
+			{/each}
+			<Button>Add Group</Button>
+		{:else if modeSelect.value == modes[2].value}
+			{console.log(filteredGroups)}
+			{#each filteredGroups as group}
+				{#each group.empires as empire}
+					<Skeleton class="h-12 w-[90%]" />
+				{/each}
+			{:else}
+				No Content
+			{/each}
+			<Button>Add Empire</Button>
+		{:else if modeSelect.value == modes[3].value}
+			{#each filteredGames as game}
+				<Skeleton class="h-12 w-[90%]" />
+			{:else}
+				No Content
+			{/each}
+			<Button>Add Ethic</Button>
+		{:else if modeSelect.value == modes[4].value}
+			{#each filteredGames as game}
+				<Skeleton class="h-12 w-[90%]" />
+			{:else}
+				No Content
+			{/each}
+			<Button>Add Portrait</Button>
+		{/if}
+	</div>
+	<div class="pt-6 px-3 flex flex-col col-span-2 text-center text-muted-foreground">
+		No Content
 	</div>
-	<div class="col-span-2 border-r-2 border-accent">B</div>
-	<div class=""></div>
 </div>
\ No newline at end of file

From c571f084d74fdfb0cb7cc4118be3ec891bcd9648 Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Mon, 11 Dec 2023 20:16:04 +0100
Subject: [PATCH 23/24] Add Input Component from shadcn

---
 src/lib/components/ui/input/index.ts     | 25 ++++++++++++++++++
 src/lib/components/ui/input/input.svelte | 33 ++++++++++++++++++++++++
 2 files changed, 58 insertions(+)
 create mode 100644 src/lib/components/ui/input/index.ts
 create mode 100644 src/lib/components/ui/input/input.svelte

diff --git a/src/lib/components/ui/input/index.ts b/src/lib/components/ui/input/index.ts
new file mode 100644
index 0000000..914dce5
--- /dev/null
+++ b/src/lib/components/ui/input/index.ts
@@ -0,0 +1,25 @@
+import Root from "./input.svelte";
+
+type FormInputEvent<T extends Event = Event> = T & {
+	currentTarget: EventTarget & HTMLInputElement;
+};
+export type InputEvents = {
+	blur: FormInputEvent<FocusEvent>;
+	change: FormInputEvent<Event>;
+	click: FormInputEvent<MouseEvent>;
+	focus: FormInputEvent<FocusEvent>;
+	keydown: FormInputEvent<KeyboardEvent>;
+	keypress: FormInputEvent<KeyboardEvent>;
+	keyup: FormInputEvent<KeyboardEvent>;
+	mouseover: FormInputEvent<MouseEvent>;
+	mouseenter: FormInputEvent<MouseEvent>;
+	mouseleave: FormInputEvent<MouseEvent>;
+	paste: FormInputEvent<ClipboardEvent>;
+	input: FormInputEvent<InputEvent>;
+};
+
+export {
+	Root,
+	//
+	Root as Input
+};
diff --git a/src/lib/components/ui/input/input.svelte b/src/lib/components/ui/input/input.svelte
new file mode 100644
index 0000000..bdfec17
--- /dev/null
+++ b/src/lib/components/ui/input/input.svelte
@@ -0,0 +1,33 @@
+<script lang="ts">
+	import type { HTMLInputAttributes } from "svelte/elements";
+	import { cn } from "$lib/utils";
+	import type { InputEvents } from ".";
+
+	type $$Props = HTMLInputAttributes;
+	type $$Events = InputEvents;
+
+	let className: $$Props["class"] = undefined;
+	export let value: $$Props["value"] = undefined;
+	export { className as class };
+</script>
+
+<input
+	class={cn(
+		"flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-foreground file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
+		className
+	)}
+	bind:value
+	on:blur
+	on:change
+	on:click
+	on:focus
+	on:keydown
+	on:keypress
+	on:keyup
+	on:mouseover
+	on:mouseenter
+	on:mouseleave
+	on:paste
+	on:input
+	{...$$restProps}
+/>

From a458f1d600304cbc939ca0df195cf4ba8c5e0f22 Mon Sep 17 00:00:00 2001
From: Neshura <neshura@neshweb.net>
Date: Mon, 11 Dec 2023 20:16:20 +0100
Subject: [PATCH 24/24] Rework Header Component for Auth handling

---
 src/routes/+layout.svelte       |  8 ++-
 src/routes/Header.svelte        | 94 ++++++++++++++++++++-------------
 src/routes/sign-up/+page.svelte | 13 ++++-
 3 files changed, 73 insertions(+), 42 deletions(-)

diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index 9bf1287..1ab084b 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -2,7 +2,6 @@
 
 <script lang="ts">
 	import '../app.postcss';
-	import { page } from '$app/stores';
 	import { browser } from '$app/environment';
 	import { writable } from 'svelte/store';
 	import { themes } from '$lib/types/themes'
@@ -13,6 +12,11 @@
 	import AdminSelectedGameStore from '$lib/stores/admin-page/GameStore';
 	import type { ChellarisGameInfo } from '$lib/types/chellaris';
 	import UserSettingsStore from '$lib/stores/UserSettingsStore';
+	import AuthTokenStore from '$lib/stores/AuthTokenStore';
+
+	if (browser) {
+		$AuthTokenStore = document.cookie.split("=")[document.cookie.split("=").length - 1];
+	}
 
 /*	$: {
 		fetch(apiBaseUrl + '/v3/ethics').then((res) => {
@@ -39,7 +43,7 @@
 
 </script>
 
-<Header {page}/>
+<Header />
 <div class="m-4 border-2 border-accent rounded-lg h-[calc(100%-5.75rem-1px)]">
 	<slot />
 </div>
diff --git a/src/routes/Header.svelte b/src/routes/Header.svelte
index 8e6e534..4f83254 100644
--- a/src/routes/Header.svelte
+++ b/src/routes/Header.svelte
@@ -1,16 +1,15 @@
 <svelte:options runes={true} />
 
 <script lang="ts">
+	import { page } from '$app/stores';
 	import discord from '$lib/images/discord.svg';
+	import AuthTokenStore from '$lib/stores/AuthTokenStore';
+	import { Exit, EyeClosed, EyeOpen } from 'radix-icons-svelte';
 	import { Button } from '$lib/components/ui/button';
-	import { themes } from '$lib/types/themes';
-	import UserSettingsStore from '$lib/stores/UserSettingsStore';
-	import * as Avatar from '$lib/components/ui/avatar';
-	import { CaretDown, CaretRight, Exit, EyeClosed, EyeOpen } from 'radix-icons-svelte';
 	import { Separator } from '$lib/components/ui/separator';
+	import { Input } from '$lib/components/ui/input';
 	import * as Popover from '$lib/components/ui/popover';
-
-	let { page } = $props()
+	import * as Avatar from '$lib/components/ui/avatar';
 
 	type User = {
 		token: string,
@@ -20,29 +19,46 @@
 		admin: boolean
 	}
 
-	/*let user: User | undefined = $state({
-		user.loggedIn = true;
-		tokenVisible: false,
-		discord: "neshura",
-		picture: "/avatar.png",
-		admin: true, // DEBUG
-	})*/
-
 	let user: User | undefined = $state(undefined);
 
-	function logout() {
+	function handleLogout() {
+		$AuthTokenStore = ""
+		document.cookie = "authToken=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/"
 		user = undefined
 	}
 
-	function nextTheme() {
-		if ($UserSettingsStore.themeId + 1 < themes.length) {
-			$UserSettingsStore.themeId += 1
+	async function handleLogin() {
+		// pretend we are handling the login via a fetch
+		await new Promise((resolve) => setTimeout(resolve, 200));
+		let ret = {
+			token: $AuthTokenStore,
+			discord: "neshura",
+			picture: "/avatar.png",
+			admin: true
+		}
+
+		if (true) {
+			const d = new Date();
+			let authExpiryDays = 14
+			d.setTime(d.getTime() + (authExpiryDays*24*60*60*1000));
+			document.cookie = "authToken=" + ret.token + "; expires=" + d.toUTCString() + "; path=/";
+
+			user = {
+				token: ret.token,
+				tokenVisible: false,
+				discord: ret.discord ?? undefined,
+				picture: ret.picture ?? undefined,
+				admin: ret.admin
+			}
 		}
 		else {
-			$UserSettingsStore.themeId = 0
+			// handle login failure
 		}
 	}
-	
+
+	if ($AuthTokenStore != "") {
+		handleLogin()
+	}
 </script>
 
 <div class="flex gap-2 items-center justify-center py-3 bg-primary-foreground">
@@ -62,14 +78,14 @@
 		<Button
 			variant="ghost"
 			href="/"
-			class="{$page.url.pathname == '/' ? 'text-accent-foreground bg-accent' : ''}"
+			class="{$page.url.pathname === '/' ? 'text-accent-foreground bg-accent' : ''}"
 		>
 			Home
 		</Button>
 		<Button
 			variant="ghost"
 			href="/current"
-			class="{$page.url.pathname == '/current' ? 'text-accent-foreground bg-accent' : ''}"
+			class="{$page.url.pathname === '/current' ? 'text-accent-foreground bg-accent' : ''}"
 		>
 			Game [Current Game]
 		</Button>
@@ -80,23 +96,23 @@
 		>
 			Archives
 		</Button>
-		{#if user != undefined && user.admin}
+		{#if user !== undefined && user.admin}
 			<Button
 				variant="ghost"
 				href="/admin"
-				class="{$page.url.pathname == '/admin' ? 'text-accent-foreground bg-accent' : ''}"
+				class="{$page.url.pathname === '/admin' ? 'text-accent-foreground bg-accent' : ''}"
 			>
 				Admin
 			</Button>
 			<Button
 				variant="ghost"
 				href="/admin/new"
-				class="{$page.url.pathname == '/admin/new' ? 'text-accent-foreground bg-accent' : ''}"
+				class="{$page.url.pathname === '/admin/new' ? 'text-accent-foreground bg-accent' : ''}"
 			>
 				Admin (New)
 			</Button>
 		{/if}
-		{#if user != undefined}
+		{#if user !== undefined}
 			<Popover.Root>
 				<Popover.Trigger>
 					<Button
@@ -118,7 +134,7 @@
 								{:else}
 									<p class="text-sm font-medium leading-none w-12">******</p>
 								{/if}
-								<Button variant="ghost" size="sm" class="p-0 h-2 justify-start" on:click={() => {user.tokenVisible = !user.tokenVisible}}>
+								<Button variant="ghost" size="sm" class="p-0 h-2 justify-start" on:click={() => {if (user !== undefined) user.tokenVisible = !user.tokenVisible}}>
 									{#if user.tokenVisible}
 										<EyeOpen />
 									{:else}
@@ -142,7 +158,7 @@
 					</div>
 					<Separator orientation="horizontal" />
 					<div class="w-full p-1">
-						<Button variant="ghost" class="flex flex-row items-center justify-start h-8 space-x-1 px-2 py-1.5 text-sm w-full" on:click={logout}>
+						<Button variant="ghost" class="flex flex-row items-center justify-start h-8 space-x-1 px-2 py-1.5 text-sm w-full" on:click={handleLogout}>
 							<p>Log out </p>
 							<Exit />
 						</Button>
@@ -159,16 +175,18 @@
 						Log In
 					</Button>
 				</Popover.Trigger>
-				<Popover.Content class="w-56 p-1">
-					<Button variant="ghost" class="justify-start h-8 px-2 py-1.5 text-sm w-full" href="/profile">
-						Token:
-
-						Log In
-					</Button>
-					<Button variant="ghost" class="flex flex-row items-center justify-start h-8 space-x-1 px-2 py-1.5 text-sm w-full" on:click={logout}>
-						<p>Sign Up </p>
-						<Exit />
-					</Button>
+				<Popover.Content class="w-40 p-1 ">
+					<form class="flex flex-col items-center gap-1" on:submit={handleLogin}>
+						<Input type="text" placeholder="User Token" bind:value={$AuthTokenStore} />
+						<div class="flex flex-row">
+							<Button variant="link" class="flex flex-row items-center h-8 space-x-1 px-2 py-1.5 text-sm w-full text-muted-foreground" href="/sign-up" >
+								Sign Up
+							</Button>
+							<Button variant="secondary" class="justify-start h-8 px-2 py-1.5 text-sm w-full" type="submit">
+								Log In
+							</Button>
+						</div>
+					</form>
 				</Popover.Content>
 			</Popover.Root>
 		{/if}
diff --git a/src/routes/sign-up/+page.svelte b/src/routes/sign-up/+page.svelte
index 9a179ee..beac4b5 100644
--- a/src/routes/sign-up/+page.svelte
+++ b/src/routes/sign-up/+page.svelte
@@ -1,3 +1,12 @@
-<div>
-	LOGIN PAGE
+<script lang="ts">
+
+</script>
+
+<div class="flex flex-col items-center justify-center h-full">
+	<p>
+		Get an Account!
+	</p>
+	<p>
+		WIP
+	</p>
 </div>
\ No newline at end of file