diff --git a/html/admin.html b/html/admin.html
index fff725b..da08aea 100644
--- a/html/admin.html
+++ b/html/admin.html
@@ -615,22 +615,22 @@
                             <thead>
                                 <tr>
                                     <th><input type="checkbox" value="" id="accounts-select-all"></th>
-                                    <th class="table-inline my-2">{{ .strings.username }}</th>
+                                    <th class="table-inline my-2 accounts-header-username">{{ .strings.username }}</th>
                                     {{ if .jellyfinLogin }}
-                                    <th class="text-center-i">{{ .strings.accessJFA }}</th>
+                                    <th class="text-center-i accounts-header-access-jfa">{{ .strings.accessJFA }}</th>
                                     {{ end }}
-                                    <th>{{ .strings.emailAddress }}</th>
+                                    <th class="accounts-header-email">{{ .strings.emailAddress }}</th>
                                     {{ if .telegramEnabled }}
-                                    <th class="text-center-i">Telegram</th>
+                                    <th class="text-center-i accounts-header-telegram">Telegram</th>
                                     {{ end }}
                                     {{ if .matrixEnabled }}
-                                    <th class="text-center-i">Matrix</th>
+                                    <th class="text-center-i accounts-header-matrix">Matrix</th>
                                     {{ end }}
                                     {{ if .discordEnabled }}
-                                    <th class="text-center-i">Discord</th>
+                                    <th class="text-center-i accounts-header-discord">Discord</th>
                                     {{ end }}
-                                    <th>{{ .strings.expiry }}</th>
-                                    <th>{{ .strings.lastActiveTime }}</th>
+                                    <th class="accounts-header-expiry">{{ .strings.expiry }}</th>
+                                    <th class="accounts-header-last-active">{{ .strings.lastActiveTime }}</th>
                                 </tr>
                             </thead>
                             <tbody id="accounts-list"></tbody>
diff --git a/package-lock.json b/package-lock.json
index a3bd7f9..b84905b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,7 +14,7 @@
         "a17t": "^0.10.1",
         "browserslist": "^4.21.7",
         "cheerio": "^1.0.0-rc.12",
-        "esbuild": "^0.18.1",
+        "esbuild": "^0.18.2",
         "fs-cheerio": "^3.0.0",
         "inline-source": "^8.0.2",
         "jsdom": "^22.1.0",
@@ -56,9 +56,9 @@
       }
     },
     "node_modules/@esbuild/android-arm": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.1.tgz",
-      "integrity": "sha512-8+QS98jqdreHLvCojIke8NjcuelB+Osysazr15EhkUIuG0Ov5WK26XgPYWViCTjHnKQxbpS86/JryBOkEpyrBA==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.2.tgz",
+      "integrity": "sha512-YAnQBHlY0IvYtvY0avnXjI8ywW23emEjk5XExqbFmypath+Snq9MgY1IS47rnqBKVSqnl0ElDt221ZgaeRrkXg==",
       "cpu": [
         "arm"
       ],
@@ -71,9 +71,9 @@
       }
     },
     "node_modules/@esbuild/android-arm64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.1.tgz",
-      "integrity": "sha512-l5V0IWGTYfQMzl4ulgIHKMZPwabIS4a39ZvtkPwL6LYiX3UtL76sylA6eFKufJCB43mwEYqbXoBSMn++NpxILw==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.2.tgz",
+      "integrity": "sha512-1Y2pb0hLdmji8I0zBwNsYSDN7zJSQqufgLOuOsrrod00WEAgKywQR5MB/E046Is/YTP4bgcPS4BioaSDBaLaTg==",
       "cpu": [
         "arm64"
       ],
@@ -86,9 +86,9 @@
       }
     },
     "node_modules/@esbuild/android-x64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.1.tgz",
-      "integrity": "sha512-1y8/bRek6EYxQeGTUfwL2mmj6NAeXZ3h5YSc4W2Y/kduI1B8VhT4x5X0VxrcGkIKef4N5qCdziRxvei/YUfESg==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.2.tgz",
+      "integrity": "sha512-P047Mh3pj8uYVE3A/B3QDX6nG8dKbHLJ+48R6Y0CRXCJ5PkXJxdHOTaS8SYs6eSR3FFU6/YQ5TishQXVHX7F5A==",
       "cpu": [
         "x64"
       ],
@@ -101,9 +101,9 @@
       }
     },
     "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.1.tgz",
-      "integrity": "sha512-FFT/on9qQTOntdloQvgfwFkRhNI5l/TCNXZS1CpH6JQd0boR637aThi9g9FYs4o31Ao72/jPZFDiRln5Cu6R2A==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.2.tgz",
+      "integrity": "sha512-a3Rkqd0tGVYMEKNy9SstWEdeBmM60l8FVD5o4rmwHr3xO1LbLqtCJSrWGbnf37hevo6m437mURVmpEHOmkXeTA==",
       "cpu": [
         "arm64"
       ],
@@ -116,9 +116,9 @@
       }
     },
     "node_modules/@esbuild/darwin-x64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.1.tgz",
-      "integrity": "sha512-p/ZIUt+NlW8qRNVTXoKJgRuc49teazvmXBquoGOm5D6IAimTfWJVJrEivqpoMKyDS/0/PxDMRM2lrkxlSa7XeQ==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.2.tgz",
+      "integrity": "sha512-cvH58adz9L10JNsIcgtkWNS/1eutjRTi3rtWz1s3ZhR64BpdmkxJBAXE/UjqybyNAWLhaN8mPJdlYI2f+tQA7g==",
       "cpu": [
         "x64"
       ],
@@ -131,9 +131,9 @@
       }
     },
     "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.1.tgz",
-      "integrity": "sha512-eYUDR3thO96ULRf4rJcG9TJ/sQc6Z/YNe16mC/KvVeAOtzmeTXiPMETEv/iMqTCxZhYkHyQG/mYbAxPBWC2mcg==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.2.tgz",
+      "integrity": "sha512-68rGMGUdgmq+c5IvseCMqY4yaa2CAY/DIILMBA6bEU1caISF7fXnV69B1uU4s3ERuVDcasVVwiAFyNxCtkS6Zg==",
       "cpu": [
         "arm64"
       ],
@@ -146,9 +146,9 @@
       }
     },
     "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.1.tgz",
-      "integrity": "sha512-w03zjxyg51qktv0JKsV+AbY3uSb1Awifs8IkKQSUXdP3sdPxxmPzZLrlJ1+LjKZRiSa4yP/Haayi/hriNVoIdQ==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.2.tgz",
+      "integrity": "sha512-ZSR9On/rXoYuAtrXo5hYKy7OuZwKZyFh2rr6L3TX4UeR1tWLf84aLyAFt7e0tlRbh4zNgqFx+ePWmsSHw7L9Bw==",
       "cpu": [
         "x64"
       ],
@@ -161,9 +161,9 @@
       }
     },
     "node_modules/@esbuild/linux-arm": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.1.tgz",
-      "integrity": "sha512-d6FXeb8F/cuXtSZuVHQN0Rz3gs3g2Xy/M4KJJRzbKsBx3pwCQuRdSrYxcr7g0PFN8geIOspiLQnUzwONyMA3Bw==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.2.tgz",
+      "integrity": "sha512-jAbA75qJ70T5AOdmw9X8675ppeRfj7j57sOypoZ4mQlfQ/LKF8eoeLzTYVo8+aqLKqeIIl0vQ4hKOB0FyG98Zg==",
       "cpu": [
         "arm"
       ],
@@ -176,9 +176,9 @@
       }
     },
     "node_modules/@esbuild/linux-arm64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.1.tgz",
-      "integrity": "sha512-dHlvkKAVlYNt5LPg1GUha99QiaEGKEC21zpHVAxs7hhW6EkR8nN3iWmyndGXxVJm4K7e4lKAzl8ekPqSr5gAXQ==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.2.tgz",
+      "integrity": "sha512-DFKavAzbu/n9HXWuetxmYN10XnfzW7FgOgpcrGD8eXaiu77KdgB+OVWA83x9FtDYtsoFpfdlDuVFAQFfrhu77A==",
       "cpu": [
         "arm64"
       ],
@@ -191,9 +191,9 @@
       }
     },
     "node_modules/@esbuild/linux-ia32": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.1.tgz",
-      "integrity": "sha512-QHS4duBPuAsLZP82sNeoqTXAJ1mNU4QcfmYtBN/jNvQJXb6n0im8F4ljFSAQbivt1jl1OnKL8HhlLUeKY75nLg==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.2.tgz",
+      "integrity": "sha512-VEaK3Z+vJyDwwPsP0sovaEw1foDzrMs7XQNYEIFkOwMjSe2BipKRKUUyrznil0p8qqsK7U8W+T7oNqZpgdnD2Q==",
       "cpu": [
         "ia32"
       ],
@@ -206,9 +206,9 @@
       }
     },
     "node_modules/@esbuild/linux-loong64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.1.tgz",
-      "integrity": "sha512-g4YSiF/qBvXvJhSowxaR7Ei/79otL48Qfjviuo+FpXREykA9nSe407T5ZvezFXryFgdf44Fe8lWpjvtQ+n42cQ==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.2.tgz",
+      "integrity": "sha512-Af1uZdB0oeJo4PW67l9aw94oakSamFxhC6ltC2eDkndozd9QygVNMTF7s7uxTLjo+BJqyVqG9wjmLCYF1o4NmA==",
       "cpu": [
         "loong64"
       ],
@@ -221,9 +221,9 @@
       }
     },
     "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.1.tgz",
-      "integrity": "sha512-/G1fzmaR5u2S9wgQhiQEhWRct0+GMpuNjhll59uv5Tjojlma9MUPinVnvpw9Re+Idb6gxe6kmzUxFP2YkC/svg==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.2.tgz",
+      "integrity": "sha512-WcTbt61+9dREuOFKXac4Qg+3OuRhLxPL9lmkI2P7fGuq/fWS2qq+AvGGVLMyk+OtXGDjyQolcEDeYlRoOmjRYQ==",
       "cpu": [
         "mips64el"
       ],
@@ -236,9 +236,9 @@
       }
     },
     "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.1.tgz",
-      "integrity": "sha512-NkDjIvleUc3lSV1VI3QE9Oh5mz3nY11H5TCbi4DJ8X09FGwHN5pDVXdAsQYPGjlt/frXZzq6x7vMmTOb5VyBog==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.2.tgz",
+      "integrity": "sha512-Ov+VHayvCPb52axma6+xm8QDawRjwHscPXedHg4U92DxlhKQ0H+6onRiC3J9kKI50p8pKKypprpCWrRrXjZN7Q==",
       "cpu": [
         "ppc64"
       ],
@@ -251,9 +251,9 @@
       }
     },
     "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.1.tgz",
-      "integrity": "sha512-IhN7Nz+HyDRnMQOLcCl6m5BgQMITMhS9O1hOqgAUIy6FI0m/0zTSkZHtvMmSIpOy1uleaGqfNDA9SM3nBeTATQ==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.2.tgz",
+      "integrity": "sha512-qW37zzKKN9C5l5LnVDriOK0eZRzQeixhtrfd5C78PAsTE15GeHU9G0oyT/u/IkNjEBjXWpTZOOHKNbjhrvuL9g==",
       "cpu": [
         "riscv64"
       ],
@@ -266,9 +266,9 @@
       }
     },
     "node_modules/@esbuild/linux-s390x": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.1.tgz",
-      "integrity": "sha512-u9iRg0eUUIyBbg5hANvRBYRaAnhVemAA2+pi3IgrzQTMeR/uPHQtJI3XInNZkNR6ACA4Fdl8N941p81XygeqWQ==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.2.tgz",
+      "integrity": "sha512-izzEFMRO8LaQIlX22+fTgP5I7Os3T51mtAWsRNpZ5pMfQIa9PqtgFAoRcb10DV+/YkH/TMMxQIlevUvDS6E4vw==",
       "cpu": [
         "s390x"
       ],
@@ -281,9 +281,9 @@
       }
     },
     "node_modules/@esbuild/linux-x64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.1.tgz",
-      "integrity": "sha512-0QeWU0a0+RmxPCDt+plXS7/hVMJtfde/LaSzs6X3UTr4FYA0hYpnwDzGXxumcPLzt5c8ctugPuKat0tmRb7noQ==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.2.tgz",
+      "integrity": "sha512-y5yqQ1ww4FfI9bQ1ZP/0k1rcgA6Ql2/AgzvqpowN0Q5tXDZkCavPdJbFXKrqA43vd1UTXt+AutTHYJ7km6e2Eg==",
       "cpu": [
         "x64"
       ],
@@ -296,9 +296,9 @@
       }
     },
     "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.1.tgz",
-      "integrity": "sha512-eFL7sxibN8wKuwrRf3HRkcjELALlfl/TavJ8P4J+BJfnkXOITF7zx4tTmGkzK8OwAR9snT2kEfp1Ictc80atGw==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.2.tgz",
+      "integrity": "sha512-usNjpKFf83X4o60gdMD47NCblaSZ6DARf31/FyCzxOgnF80mJ+RhDs9RTqgyfH8KyduO5mjgInw9+ct286ayYA==",
       "cpu": [
         "x64"
       ],
@@ -311,9 +311,9 @@
       }
     },
     "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.1.tgz",
-      "integrity": "sha512-riCQUnngF2xYUzr0XDdrGEEz0nqnocch0No7SBIQM22wTRi5gt5WqTQexGd/2u2Z19d0rVYQbKBelaJ1dwe9bg==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.2.tgz",
+      "integrity": "sha512-6urzy1+VwcPuhG+5jwHA8lD9E87E5+ey3qKw2EhRS+qUmMxLvfwP8szWC2JHVGZDPEDge6fgn0pBj+y9rxDLwQ==",
       "cpu": [
         "x64"
       ],
@@ -326,9 +326,9 @@
       }
     },
     "node_modules/@esbuild/sunos-x64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.1.tgz",
-      "integrity": "sha512-6lTop2k+GMkWlrwMy2+55xIBXKfXOi6uzWYypXZZP8HxXG3Mb5N4O71z2KzisVNJtYK2VlQRNbmGtUzIQIhHAw==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.2.tgz",
+      "integrity": "sha512-SMZPTACsvpKYAIl9o8nhnmMn6/lp62iMeV/2EBMtj+sW6dXwW9b0cLjihkBv4PG1CCRlwWKPZo43imqZxC95ZA==",
       "cpu": [
         "x64"
       ],
@@ -341,9 +341,9 @@
       }
     },
     "node_modules/@esbuild/win32-arm64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.1.tgz",
-      "integrity": "sha512-d6wt4g9GluZp7xCmgpm7gY6wy0mjcBHbKeeK9MYrlWNFJd8KBcD2uCil8kFuaH3Dt6AUz62D0wIoDETFsZ01Tg==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.2.tgz",
+      "integrity": "sha512-H2zzjPdzSDNwUnZdZf9/xfm0CYqHFXuenCMAx+tRzIRqWUT6MmZ9/q7722KnAZ6uPpq0RLs7EjCIIfmt6CaRGg==",
       "cpu": [
         "arm64"
       ],
@@ -356,9 +356,9 @@
       }
     },
     "node_modules/@esbuild/win32-ia32": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.1.tgz",
-      "integrity": "sha512-z51DOtcwECu4WlqJUhu39AVnnpaVmTvXei0EQxc99QK7ZJyn4tj0EelYkMBZckpqzqB/GyGSLwEclKtRJ0l2uw==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.2.tgz",
+      "integrity": "sha512-lfyjTN+FrKgvNvrH7nOLtaz58J/8coZOo4LQwgBMP4D7ZOurhvluXS3GjePLzq9GbWnJDZdKCKbMKhZPPcdJJA==",
       "cpu": [
         "ia32"
       ],
@@ -371,9 +371,9 @@
       }
     },
     "node_modules/@esbuild/win32-x64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.1.tgz",
-      "integrity": "sha512-6tdeuCLT+l9QuCFaYsNtULO6xH2fgJObvICMCsOZvkqIey6FUXVVju5aO+OZjxswy7WgKadhI1k/nq2wQSmB+Q==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.2.tgz",
+      "integrity": "sha512-Q4nIjqWXjxkELwd7kVepsJxbQ/6ERNsHpjz1j+IKjwSYw+g06U0RQOy5xh848AHvgr9itnGLa3cT2G5t0dBFsw==",
       "cpu": [
         "x64"
       ],
@@ -1641,9 +1641,9 @@
       }
     },
     "node_modules/esbuild": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.1.tgz",
-      "integrity": "sha512-ZUvsIx2wPjpj86b805UwbGJu47Kxgr2UTio9rGhWpBr1oOVk88exzoieOgTweX0UcVCwSAk3z2WvNALpTcpQZw==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.2.tgz",
+      "integrity": "sha512-1P4sK9gXVcjvrrUjE94Hbo9goU+T6U1sdzLf+JJ+3uI6GEb4e4n3Wrqto9hZHUWabblpT2ifmC61LhZnLyTNFw==",
       "hasInstallScript": true,
       "bin": {
         "esbuild": "bin/esbuild"
@@ -1652,28 +1652,28 @@
         "node": ">=12"
       },
       "optionalDependencies": {
-        "@esbuild/android-arm": "0.18.1",
-        "@esbuild/android-arm64": "0.18.1",
-        "@esbuild/android-x64": "0.18.1",
-        "@esbuild/darwin-arm64": "0.18.1",
-        "@esbuild/darwin-x64": "0.18.1",
-        "@esbuild/freebsd-arm64": "0.18.1",
-        "@esbuild/freebsd-x64": "0.18.1",
-        "@esbuild/linux-arm": "0.18.1",
-        "@esbuild/linux-arm64": "0.18.1",
-        "@esbuild/linux-ia32": "0.18.1",
-        "@esbuild/linux-loong64": "0.18.1",
-        "@esbuild/linux-mips64el": "0.18.1",
-        "@esbuild/linux-ppc64": "0.18.1",
-        "@esbuild/linux-riscv64": "0.18.1",
-        "@esbuild/linux-s390x": "0.18.1",
-        "@esbuild/linux-x64": "0.18.1",
-        "@esbuild/netbsd-x64": "0.18.1",
-        "@esbuild/openbsd-x64": "0.18.1",
-        "@esbuild/sunos-x64": "0.18.1",
-        "@esbuild/win32-arm64": "0.18.1",
-        "@esbuild/win32-ia32": "0.18.1",
-        "@esbuild/win32-x64": "0.18.1"
+        "@esbuild/android-arm": "0.18.2",
+        "@esbuild/android-arm64": "0.18.2",
+        "@esbuild/android-x64": "0.18.2",
+        "@esbuild/darwin-arm64": "0.18.2",
+        "@esbuild/darwin-x64": "0.18.2",
+        "@esbuild/freebsd-arm64": "0.18.2",
+        "@esbuild/freebsd-x64": "0.18.2",
+        "@esbuild/linux-arm": "0.18.2",
+        "@esbuild/linux-arm64": "0.18.2",
+        "@esbuild/linux-ia32": "0.18.2",
+        "@esbuild/linux-loong64": "0.18.2",
+        "@esbuild/linux-mips64el": "0.18.2",
+        "@esbuild/linux-ppc64": "0.18.2",
+        "@esbuild/linux-riscv64": "0.18.2",
+        "@esbuild/linux-s390x": "0.18.2",
+        "@esbuild/linux-x64": "0.18.2",
+        "@esbuild/netbsd-x64": "0.18.2",
+        "@esbuild/openbsd-x64": "0.18.2",
+        "@esbuild/sunos-x64": "0.18.2",
+        "@esbuild/win32-arm64": "0.18.2",
+        "@esbuild/win32-ia32": "0.18.2",
+        "@esbuild/win32-x64": "0.18.2"
       }
     },
     "node_modules/escalade": {
@@ -6791,135 +6791,135 @@
       }
     },
     "@esbuild/android-arm": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.1.tgz",
-      "integrity": "sha512-8+QS98jqdreHLvCojIke8NjcuelB+Osysazr15EhkUIuG0Ov5WK26XgPYWViCTjHnKQxbpS86/JryBOkEpyrBA==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.2.tgz",
+      "integrity": "sha512-YAnQBHlY0IvYtvY0avnXjI8ywW23emEjk5XExqbFmypath+Snq9MgY1IS47rnqBKVSqnl0ElDt221ZgaeRrkXg==",
       "optional": true
     },
     "@esbuild/android-arm64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.1.tgz",
-      "integrity": "sha512-l5V0IWGTYfQMzl4ulgIHKMZPwabIS4a39ZvtkPwL6LYiX3UtL76sylA6eFKufJCB43mwEYqbXoBSMn++NpxILw==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.2.tgz",
+      "integrity": "sha512-1Y2pb0hLdmji8I0zBwNsYSDN7zJSQqufgLOuOsrrod00WEAgKywQR5MB/E046Is/YTP4bgcPS4BioaSDBaLaTg==",
       "optional": true
     },
     "@esbuild/android-x64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.1.tgz",
-      "integrity": "sha512-1y8/bRek6EYxQeGTUfwL2mmj6NAeXZ3h5YSc4W2Y/kduI1B8VhT4x5X0VxrcGkIKef4N5qCdziRxvei/YUfESg==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.2.tgz",
+      "integrity": "sha512-P047Mh3pj8uYVE3A/B3QDX6nG8dKbHLJ+48R6Y0CRXCJ5PkXJxdHOTaS8SYs6eSR3FFU6/YQ5TishQXVHX7F5A==",
       "optional": true
     },
     "@esbuild/darwin-arm64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.1.tgz",
-      "integrity": "sha512-FFT/on9qQTOntdloQvgfwFkRhNI5l/TCNXZS1CpH6JQd0boR637aThi9g9FYs4o31Ao72/jPZFDiRln5Cu6R2A==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.2.tgz",
+      "integrity": "sha512-a3Rkqd0tGVYMEKNy9SstWEdeBmM60l8FVD5o4rmwHr3xO1LbLqtCJSrWGbnf37hevo6m437mURVmpEHOmkXeTA==",
       "optional": true
     },
     "@esbuild/darwin-x64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.1.tgz",
-      "integrity": "sha512-p/ZIUt+NlW8qRNVTXoKJgRuc49teazvmXBquoGOm5D6IAimTfWJVJrEivqpoMKyDS/0/PxDMRM2lrkxlSa7XeQ==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.2.tgz",
+      "integrity": "sha512-cvH58adz9L10JNsIcgtkWNS/1eutjRTi3rtWz1s3ZhR64BpdmkxJBAXE/UjqybyNAWLhaN8mPJdlYI2f+tQA7g==",
       "optional": true
     },
     "@esbuild/freebsd-arm64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.1.tgz",
-      "integrity": "sha512-eYUDR3thO96ULRf4rJcG9TJ/sQc6Z/YNe16mC/KvVeAOtzmeTXiPMETEv/iMqTCxZhYkHyQG/mYbAxPBWC2mcg==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.2.tgz",
+      "integrity": "sha512-68rGMGUdgmq+c5IvseCMqY4yaa2CAY/DIILMBA6bEU1caISF7fXnV69B1uU4s3ERuVDcasVVwiAFyNxCtkS6Zg==",
       "optional": true
     },
     "@esbuild/freebsd-x64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.1.tgz",
-      "integrity": "sha512-w03zjxyg51qktv0JKsV+AbY3uSb1Awifs8IkKQSUXdP3sdPxxmPzZLrlJ1+LjKZRiSa4yP/Haayi/hriNVoIdQ==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.2.tgz",
+      "integrity": "sha512-ZSR9On/rXoYuAtrXo5hYKy7OuZwKZyFh2rr6L3TX4UeR1tWLf84aLyAFt7e0tlRbh4zNgqFx+ePWmsSHw7L9Bw==",
       "optional": true
     },
     "@esbuild/linux-arm": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.1.tgz",
-      "integrity": "sha512-d6FXeb8F/cuXtSZuVHQN0Rz3gs3g2Xy/M4KJJRzbKsBx3pwCQuRdSrYxcr7g0PFN8geIOspiLQnUzwONyMA3Bw==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.2.tgz",
+      "integrity": "sha512-jAbA75qJ70T5AOdmw9X8675ppeRfj7j57sOypoZ4mQlfQ/LKF8eoeLzTYVo8+aqLKqeIIl0vQ4hKOB0FyG98Zg==",
       "optional": true
     },
     "@esbuild/linux-arm64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.1.tgz",
-      "integrity": "sha512-dHlvkKAVlYNt5LPg1GUha99QiaEGKEC21zpHVAxs7hhW6EkR8nN3iWmyndGXxVJm4K7e4lKAzl8ekPqSr5gAXQ==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.2.tgz",
+      "integrity": "sha512-DFKavAzbu/n9HXWuetxmYN10XnfzW7FgOgpcrGD8eXaiu77KdgB+OVWA83x9FtDYtsoFpfdlDuVFAQFfrhu77A==",
       "optional": true
     },
     "@esbuild/linux-ia32": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.1.tgz",
-      "integrity": "sha512-QHS4duBPuAsLZP82sNeoqTXAJ1mNU4QcfmYtBN/jNvQJXb6n0im8F4ljFSAQbivt1jl1OnKL8HhlLUeKY75nLg==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.2.tgz",
+      "integrity": "sha512-VEaK3Z+vJyDwwPsP0sovaEw1foDzrMs7XQNYEIFkOwMjSe2BipKRKUUyrznil0p8qqsK7U8W+T7oNqZpgdnD2Q==",
       "optional": true
     },
     "@esbuild/linux-loong64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.1.tgz",
-      "integrity": "sha512-g4YSiF/qBvXvJhSowxaR7Ei/79otL48Qfjviuo+FpXREykA9nSe407T5ZvezFXryFgdf44Fe8lWpjvtQ+n42cQ==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.2.tgz",
+      "integrity": "sha512-Af1uZdB0oeJo4PW67l9aw94oakSamFxhC6ltC2eDkndozd9QygVNMTF7s7uxTLjo+BJqyVqG9wjmLCYF1o4NmA==",
       "optional": true
     },
     "@esbuild/linux-mips64el": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.1.tgz",
-      "integrity": "sha512-/G1fzmaR5u2S9wgQhiQEhWRct0+GMpuNjhll59uv5Tjojlma9MUPinVnvpw9Re+Idb6gxe6kmzUxFP2YkC/svg==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.2.tgz",
+      "integrity": "sha512-WcTbt61+9dREuOFKXac4Qg+3OuRhLxPL9lmkI2P7fGuq/fWS2qq+AvGGVLMyk+OtXGDjyQolcEDeYlRoOmjRYQ==",
       "optional": true
     },
     "@esbuild/linux-ppc64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.1.tgz",
-      "integrity": "sha512-NkDjIvleUc3lSV1VI3QE9Oh5mz3nY11H5TCbi4DJ8X09FGwHN5pDVXdAsQYPGjlt/frXZzq6x7vMmTOb5VyBog==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.2.tgz",
+      "integrity": "sha512-Ov+VHayvCPb52axma6+xm8QDawRjwHscPXedHg4U92DxlhKQ0H+6onRiC3J9kKI50p8pKKypprpCWrRrXjZN7Q==",
       "optional": true
     },
     "@esbuild/linux-riscv64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.1.tgz",
-      "integrity": "sha512-IhN7Nz+HyDRnMQOLcCl6m5BgQMITMhS9O1hOqgAUIy6FI0m/0zTSkZHtvMmSIpOy1uleaGqfNDA9SM3nBeTATQ==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.2.tgz",
+      "integrity": "sha512-qW37zzKKN9C5l5LnVDriOK0eZRzQeixhtrfd5C78PAsTE15GeHU9G0oyT/u/IkNjEBjXWpTZOOHKNbjhrvuL9g==",
       "optional": true
     },
     "@esbuild/linux-s390x": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.1.tgz",
-      "integrity": "sha512-u9iRg0eUUIyBbg5hANvRBYRaAnhVemAA2+pi3IgrzQTMeR/uPHQtJI3XInNZkNR6ACA4Fdl8N941p81XygeqWQ==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.2.tgz",
+      "integrity": "sha512-izzEFMRO8LaQIlX22+fTgP5I7Os3T51mtAWsRNpZ5pMfQIa9PqtgFAoRcb10DV+/YkH/TMMxQIlevUvDS6E4vw==",
       "optional": true
     },
     "@esbuild/linux-x64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.1.tgz",
-      "integrity": "sha512-0QeWU0a0+RmxPCDt+plXS7/hVMJtfde/LaSzs6X3UTr4FYA0hYpnwDzGXxumcPLzt5c8ctugPuKat0tmRb7noQ==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.2.tgz",
+      "integrity": "sha512-y5yqQ1ww4FfI9bQ1ZP/0k1rcgA6Ql2/AgzvqpowN0Q5tXDZkCavPdJbFXKrqA43vd1UTXt+AutTHYJ7km6e2Eg==",
       "optional": true
     },
     "@esbuild/netbsd-x64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.1.tgz",
-      "integrity": "sha512-eFL7sxibN8wKuwrRf3HRkcjELALlfl/TavJ8P4J+BJfnkXOITF7zx4tTmGkzK8OwAR9snT2kEfp1Ictc80atGw==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.2.tgz",
+      "integrity": "sha512-usNjpKFf83X4o60gdMD47NCblaSZ6DARf31/FyCzxOgnF80mJ+RhDs9RTqgyfH8KyduO5mjgInw9+ct286ayYA==",
       "optional": true
     },
     "@esbuild/openbsd-x64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.1.tgz",
-      "integrity": "sha512-riCQUnngF2xYUzr0XDdrGEEz0nqnocch0No7SBIQM22wTRi5gt5WqTQexGd/2u2Z19d0rVYQbKBelaJ1dwe9bg==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.2.tgz",
+      "integrity": "sha512-6urzy1+VwcPuhG+5jwHA8lD9E87E5+ey3qKw2EhRS+qUmMxLvfwP8szWC2JHVGZDPEDge6fgn0pBj+y9rxDLwQ==",
       "optional": true
     },
     "@esbuild/sunos-x64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.1.tgz",
-      "integrity": "sha512-6lTop2k+GMkWlrwMy2+55xIBXKfXOi6uzWYypXZZP8HxXG3Mb5N4O71z2KzisVNJtYK2VlQRNbmGtUzIQIhHAw==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.2.tgz",
+      "integrity": "sha512-SMZPTACsvpKYAIl9o8nhnmMn6/lp62iMeV/2EBMtj+sW6dXwW9b0cLjihkBv4PG1CCRlwWKPZo43imqZxC95ZA==",
       "optional": true
     },
     "@esbuild/win32-arm64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.1.tgz",
-      "integrity": "sha512-d6wt4g9GluZp7xCmgpm7gY6wy0mjcBHbKeeK9MYrlWNFJd8KBcD2uCil8kFuaH3Dt6AUz62D0wIoDETFsZ01Tg==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.2.tgz",
+      "integrity": "sha512-H2zzjPdzSDNwUnZdZf9/xfm0CYqHFXuenCMAx+tRzIRqWUT6MmZ9/q7722KnAZ6uPpq0RLs7EjCIIfmt6CaRGg==",
       "optional": true
     },
     "@esbuild/win32-ia32": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.1.tgz",
-      "integrity": "sha512-z51DOtcwECu4WlqJUhu39AVnnpaVmTvXei0EQxc99QK7ZJyn4tj0EelYkMBZckpqzqB/GyGSLwEclKtRJ0l2uw==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.2.tgz",
+      "integrity": "sha512-lfyjTN+FrKgvNvrH7nOLtaz58J/8coZOo4LQwgBMP4D7ZOurhvluXS3GjePLzq9GbWnJDZdKCKbMKhZPPcdJJA==",
       "optional": true
     },
     "@esbuild/win32-x64": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.1.tgz",
-      "integrity": "sha512-6tdeuCLT+l9QuCFaYsNtULO6xH2fgJObvICMCsOZvkqIey6FUXVVju5aO+OZjxswy7WgKadhI1k/nq2wQSmB+Q==",
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.2.tgz",
+      "integrity": "sha512-Q4nIjqWXjxkELwd7kVepsJxbQ/6ERNsHpjz1j+IKjwSYw+g06U0RQOy5xh848AHvgr9itnGLa3cT2G5t0dBFsw==",
       "optional": true
     },
     "@jridgewell/gen-mapping": {
@@ -7885,32 +7885,32 @@
       "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="
     },
     "esbuild": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.1.tgz",
-      "integrity": "sha512-ZUvsIx2wPjpj86b805UwbGJu47Kxgr2UTio9rGhWpBr1oOVk88exzoieOgTweX0UcVCwSAk3z2WvNALpTcpQZw==",
-      "requires": {
-        "@esbuild/android-arm": "0.18.1",
-        "@esbuild/android-arm64": "0.18.1",
-        "@esbuild/android-x64": "0.18.1",
-        "@esbuild/darwin-arm64": "0.18.1",
-        "@esbuild/darwin-x64": "0.18.1",
-        "@esbuild/freebsd-arm64": "0.18.1",
-        "@esbuild/freebsd-x64": "0.18.1",
-        "@esbuild/linux-arm": "0.18.1",
-        "@esbuild/linux-arm64": "0.18.1",
-        "@esbuild/linux-ia32": "0.18.1",
-        "@esbuild/linux-loong64": "0.18.1",
-        "@esbuild/linux-mips64el": "0.18.1",
-        "@esbuild/linux-ppc64": "0.18.1",
-        "@esbuild/linux-riscv64": "0.18.1",
-        "@esbuild/linux-s390x": "0.18.1",
-        "@esbuild/linux-x64": "0.18.1",
-        "@esbuild/netbsd-x64": "0.18.1",
-        "@esbuild/openbsd-x64": "0.18.1",
-        "@esbuild/sunos-x64": "0.18.1",
-        "@esbuild/win32-arm64": "0.18.1",
-        "@esbuild/win32-ia32": "0.18.1",
-        "@esbuild/win32-x64": "0.18.1"
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.2.tgz",
+      "integrity": "sha512-1P4sK9gXVcjvrrUjE94Hbo9goU+T6U1sdzLf+JJ+3uI6GEb4e4n3Wrqto9hZHUWabblpT2ifmC61LhZnLyTNFw==",
+      "requires": {
+        "@esbuild/android-arm": "0.18.2",
+        "@esbuild/android-arm64": "0.18.2",
+        "@esbuild/android-x64": "0.18.2",
+        "@esbuild/darwin-arm64": "0.18.2",
+        "@esbuild/darwin-x64": "0.18.2",
+        "@esbuild/freebsd-arm64": "0.18.2",
+        "@esbuild/freebsd-x64": "0.18.2",
+        "@esbuild/linux-arm": "0.18.2",
+        "@esbuild/linux-arm64": "0.18.2",
+        "@esbuild/linux-ia32": "0.18.2",
+        "@esbuild/linux-loong64": "0.18.2",
+        "@esbuild/linux-mips64el": "0.18.2",
+        "@esbuild/linux-ppc64": "0.18.2",
+        "@esbuild/linux-riscv64": "0.18.2",
+        "@esbuild/linux-s390x": "0.18.2",
+        "@esbuild/linux-x64": "0.18.2",
+        "@esbuild/netbsd-x64": "0.18.2",
+        "@esbuild/openbsd-x64": "0.18.2",
+        "@esbuild/sunos-x64": "0.18.2",
+        "@esbuild/win32-arm64": "0.18.2",
+        "@esbuild/win32-ia32": "0.18.2",
+        "@esbuild/win32-x64": "0.18.2"
       }
     },
     "escalade": {
diff --git a/package.json b/package.json
index fc09087..fbf21d2 100644
--- a/package.json
+++ b/package.json
@@ -22,7 +22,7 @@
     "a17t": "^0.10.1",
     "browserslist": "^4.21.7",
     "cheerio": "^1.0.0-rc.12",
-    "esbuild": "^0.18.1",
+    "esbuild": "^0.18.2",
     "fs-cheerio": "^3.0.0",
     "inline-source": "^8.0.2",
     "jsdom": "^22.1.0",
diff --git a/ts/modules/accounts.ts b/ts/modules/accounts.ts
index abe6913..bab0dd8 100644
--- a/ts/modules/accounts.ts
+++ b/ts/modules/accounts.ts
@@ -737,7 +737,7 @@ export class accountsList {
 
     private _selectAll = document.getElementById("accounts-select-all") as HTMLInputElement;
     private _users: { [id: string]: user };
-    private _sortedByName: string[] = [];
+    private _ordering: string[] = [];
     private _checkCount: number = 0;
     private _inSearch = false;
     // Whether the enable/disable button should enable or not.
@@ -748,6 +748,11 @@ export class accountsList {
     private _addUserEmail = this._addUserForm.querySelector("input[type=email]") as HTMLInputElement;
     private _addUserPassword = this._addUserForm.querySelector("input[type=password]") as HTMLInputElement;
     
+    // Columns for sorting.
+    private _columns: { [className: string]: Column } = {};
+    private _activeSortColumn: string;
+
+
     // Whether the "Extend expiry" is extending or setting an expiry.
     private _settingExpiry = false;
 
@@ -782,7 +787,7 @@ export class accountsList {
                     if (querySplit[1] == "true" || querySplit[1] == "yes") {
                         state = true;
                     }
-                    for (let id in this._users) {
+                    for (let id of this._ordering) {
                         const user = this._users[id];
                         let attrib: boolean;
                         if (querySplit[0] == "admin") { attrib = user.admin; }
@@ -793,7 +798,7 @@ export class accountsList {
             }
         }
         if (query == "") { return result; }
-        for (let id in this._users) {
+        for (let id of this._ordering) {
             const user = this._users[id];
             if (user.name.toLowerCase().includes(query)) {
                 result.push(id);
@@ -821,36 +826,6 @@ export class accountsList {
     add = (u: User) => {
         let domAccount = new user(u);
         this._users[u.id] = domAccount;
-        this.unhide(u.id);
-    }
-
-    unhide = (id: string) => {
-        const keys = Object.keys(this._users);
-        if (keys.length == 0) {
-            this._table.appendChild(this._users[id].asElement());
-            return;
-        }
-        this._sortedByName = keys.sort((a, b) => this._users[a].name.localeCompare(this._users[b].name));
-        let index = this._sortedByName.indexOf(id)+1;
-        if (index == this._sortedByName.length-1) {
-            this._table.appendChild(this._users[id].asElement());
-            return;
-        }
-        while (index < this._sortedByName.length) {
-            if (this._table.contains(this._users[this._sortedByName[index]].asElement())) {
-                this._table.insertBefore(this._users[id].asElement(), this._users[this._sortedByName[index]].asElement());
-                return;
-            }
-            index++;
-        }
-        this._table.appendChild(this._users[id].asElement());
-    }
-
-    hide = (id: string) => {
-        const el = this._users[id].asElement();
-        if (this._table.contains(el)) {
-            this._table.removeChild(this._users[id].asElement());
-        }
     }
 
     private _checkCheckCount = () => {
@@ -1427,6 +1402,18 @@ export class accountsList {
         }
         window.modals.extendExpiry.show();
     }
+    
+
+    setVisibility = (users: string[], visible: boolean) => {
+        this._table.textContent = "";
+        for (let id of this._ordering) {
+            if (visible && users.indexOf(id) != -1) {
+                this._table.appendChild(this._users[id].asElement());
+            } else if (!visible && users.indexOf(id) == -1) {
+                this._table.appendChild(this._users[id].asElement());
+            }
+        }
+    }
 
     constructor() {
         this._populateNumbers();
@@ -1508,32 +1495,14 @@ export class accountsList {
             this._deleteNotify.checked = false;
         }*/
 
-        const setVisibility = (users: string[], visible: boolean) => {
-            for (let id in this._users) {
-                if (users.indexOf(id) != -1) {
-                    if (visible) {
-                        this.unhide(id);
-                    } else {
-                        this.hide(id);
-                    }
-                } else {
-                    if (visible) {
-                        this.hide(id);
-                    } else {
-                        this.unhide(id);
-                    }
-                }
-            }
-        }
-
         this._search.oninput = () => {
             const query = this._search.value;
             if (!query) {
-                setVisibility(Object.keys(this._users), true);
+                this.setVisibility(this._ordering, true);
                 this._inSearch = false;
             } else {
                 this._inSearch = true;
-                setVisibility(this.search(query), true);
+                this.setVisibility(this.search(query), true);
             }
             this._checkCheckCount();
         };
@@ -1559,6 +1528,30 @@ export class accountsList {
             insertText(this._announceTextarea, announceVarUsername.children[0].textContent);
             this.loadPreview();
         };
+
+        const headerNames: string[] = ["username", "access-jfa", "email", "telegram", "matrix", "discord", "expiry", "last-active"];
+        const headerGetters: string[] = ["name", "accounts_admin", "email", "telegram", "matrix", "discord", "expiry", "last_active"];
+        for (let i = 0; i < headerNames.length; i++) {
+            const header: HTMLTableHeaderCellElement = document.getElementsByClassName("accounts-header-" + headerNames[i])[0] as HTMLTableHeaderCellElement;
+            if (header !== null) {
+                this._columns[header.className] = new Column(header, Object.getOwnPropertyDescriptor(user.prototype, headerGetters[i]).get);
+            }
+        }
+
+        document.addEventListener("header-click", (event: CustomEvent) => {
+            this._ordering = this._columns[event.detail].sort(this._users);
+            this._activeSortColumn = event.detail;
+            // console.log("ordering by", event.detail, ": ", this._ordering);
+            if (!(this._inSearch)) {
+                this.setVisibility(this._ordering, true);
+            } else {
+                this.setVisibility(this.search(this._search.value), true);
+            }
+        });
+
+        // Start off sorting by Name
+        this._activeSortColumn = document.getElementsByClassName("accounts-header-" + headerNames[0])[0].className;
+        document.dispatchEvent(new CustomEvent("header-click", { detail: this._activeSortColumn }));
     }
 
     reload = () => {
@@ -1579,9 +1572,83 @@ export class accountsList {
                     this._users[id].remove();
                     delete this._users[id];
                 }
+                // console.log("reload, so sorting by", this._activeSortColumn);
+                this._ordering = this._columns[this._activeSortColumn].sort(this._users);
+                if (!(this._inSearch)) {
+                    this.setVisibility(this._ordering, true);
+                } else {
+                    this.setVisibility(this.search(this._search.value), true);
+                }
                 this._checkCheckCount();
             }
         });
         this.loadTemplates();
     }
 }
+
+type GetterReturnType = Boolean | boolean | String | Number | number;
+type Getter = () => GetterReturnType;
+
+// When a column is clicked, it broadcasts it's name and ordering to be picked up and stored by accountsList
+// When list is refreshed, accountList calls method of the specific Column and re-orders accordingly.
+// Listen for broadcast event from others, check its not us by comparing the header className in the message, then hide the arrow icon
+class Column {
+    private _header: HTMLTableHeaderCellElement;
+    private _headerContent: string;
+    private _getter: Getter;
+    private _ascending: boolean;
+    private _active: boolean;
+
+    constructor(header: HTMLTableHeaderCellElement, getter: Getter) {
+        this._header = header;
+        this._headerContent = this._header.textContent;
+        this._getter = getter;
+        this._ascending = true;
+        this._active = false;
+
+        this._header.addEventListener("click", () => {
+            // If we are the active sort column, a click means to switch between ascending/descending.
+            if (this._active) {
+                this._ascending = !this._ascending;
+                console.log("was already active, switching direction to", this._ascending ? "ascending" : "descending");
+            } else {
+                console.log("wasn't active keeping direction as", this._ascending ? "ascending" : "descending");
+            }
+            this._active = true;
+            this.updateHeader();
+            document.dispatchEvent(new CustomEvent("header-click", { detail: this._header.className }));
+        });
+        document.addEventListener("header-click", (event: CustomEvent) => {
+            if (event.detail != this._header.className) {
+                this._active = false;
+                this.hideIcon();
+            }
+        });
+    }
+
+    hideIcon = () => {
+        this._header.textContent = this._headerContent;
+    }
+
+    updateHeader = () => {
+        this._header.innerHTML = `
+        ${this._headerContent}
+        <i class="ri-arrow-${this._ascending? "up" : "down"}-s-line ml-2"></i>
+        `;
+    }
+
+
+    // Sorts the user list. previouslyActive is whether this column was previously sorted by, indicating that the direction should change.
+    sort = (users: { [id: string]: user }): string[] => {
+        let userIDs = Object.keys(users);
+        userIDs.sort((a: string, b: string): number => {
+            const av: GetterReturnType = this._getter.call(users[a]);
+            const bv: GetterReturnType = this._getter.call(users[b]);
+            if (av < bv) return this._ascending ? -1 : 1;
+            if (av > bv) return this._ascending ? 1 : -1;
+            return 0;
+        });
+
+        return userIDs;
+    }
+}