From d4f2fcdf7908ffa176350468a85e631f0497646c Mon Sep 17 00:00:00 2001
From: Dan Brown <ssddanbrown@googlemail.com>
Date: Tue, 2 Aug 2022 20:11:02 +0100
Subject: [PATCH 1/4] Started codemirror update, In broken state

---
 dev/build/esbuild.js                      |  16 +-
 package-lock.json                         | 633 +++++++++++++++-------
 package.json                              |  13 +-
 resources/js/{code.mjs => code/index.mjs} | 161 ++----
 resources/js/code/modes.js                | 134 +++++
 resources/js/code/setups.js               |  32 ++
 6 files changed, 661 insertions(+), 328 deletions(-)
 rename resources/js/{code.mjs => code/index.mjs} (55%)
 create mode 100644 resources/js/code/modes.js
 create mode 100644 resources/js/code/setups.js

diff --git a/dev/build/esbuild.js b/dev/build/esbuild.js
index 46357038a..57a224876 100644
--- a/dev/build/esbuild.js
+++ b/dev/build/esbuild.js
@@ -1,7 +1,6 @@
 #!/usr/bin/env node
 
 const esbuild = require('esbuild');
-const fs = require('fs');
 const path = require('path');
 
 // Check if we're building for production
@@ -9,20 +8,19 @@ const path = require('path');
 const isProd = process.argv[2] === 'production';
 
 // Gather our input files
-const jsInDir = path.join(__dirname, '../../resources/js');
-const jsInDirFiles = fs.readdirSync(jsInDir, 'utf8');
-const entryFiles = jsInDirFiles
-    .filter(f => f.endsWith('.js') || f.endsWith('.mjs'))
-    .map(f => path.join(jsInDir, f));
+const entryPoints = {
+    app: path.join(__dirname, '../../resources/js/app.js'),
+    code: path.join(__dirname, '../../resources/js/code/index.mjs'),
+};
 
 // Locate our output directory
-const outDir = path.join(__dirname, '../../public/dist');
+const outdir = path.join(__dirname, '../../public/dist');
 
 // Build via esbuild
 esbuild.build({
     bundle: true,
-    entryPoints: entryFiles,
-    outdir: outDir,
+    entryPoints,
+    outdir,
     sourcemap: true,
     target: 'es2020',
     mainFields: ['module', 'main'],
diff --git a/package-lock.json b/package-lock.json
index 1448d592f..c141e654a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,21 +5,131 @@
   "packages": {
     "": {
       "dependencies": {
+        "@codemirror/commands": "^6.0.1",
+        "@codemirror/language": "^6.2.1",
+        "@codemirror/legacy-modes": "^6.1.0",
+        "@codemirror/state": "^6.1.0",
+        "@codemirror/view": "^6.1.2",
         "clipboard": "^2.0.11",
-        "codemirror": "^5.65.5",
+        "codemirror": "^6.0.1",
         "dropzone": "^5.9.3",
         "markdown-it": "^13.0.1",
         "markdown-it-task-lists": "^2.1.1",
-        "snabbdom": "^3.5.0",
+        "snabbdom": "^3.5.1",
         "sortablejs": "^1.15.0"
       },
       "devDependencies": {
         "chokidar-cli": "^3.0",
-        "esbuild": "0.14.42",
+        "esbuild": "0.14.51",
         "livereload": "^0.9.3",
         "npm-run-all": "^4.1.5",
         "punycode": "^2.1.1",
-        "sass": "^1.52.1"
+        "sass": "^1.54.0"
+      }
+    },
+    "node_modules/@codemirror/autocomplete": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.1.0.tgz",
+      "integrity": "sha512-wtO4O5WDyXhhCd4q4utDIDZxnQfmJ++3dGBCG9LMtI79+92OcA1DVk/n7BEupKmjIr8AzvptDz7YQ9ud6OkU+A==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0"
+      },
+      "peerDependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/commands": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.0.1.tgz",
+      "integrity": "sha512-iNHDByicYqQjs0Wo1MKGfqNbMYMyhS9WV6EwMVwsHXImlFemgEUC+c5X22bXKBStN3qnwg4fArNZM+gkv22baQ==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/language": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz",
+      "integrity": "sha512-MC3svxuvIj0MRpFlGHxLS6vPyIdbTr2KKPEW46kCoCXw2ktb4NTkpkPBI/lSP/FoNXLCBJ0mrnUi1OoZxtpW1Q==",
+      "dependencies": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0",
+        "style-mod": "^4.0.0"
+      }
+    },
+    "node_modules/@codemirror/legacy-modes": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.1.0.tgz",
+      "integrity": "sha512-V/PgGpndkZeTn3Hdlg/gd8MLFdyvTCIX+iwJzjUw5iNziWiNsAY8X0jvf7m3gSfxnKkNzmid6l0g4rYSpiDaCw==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0"
+      }
+    },
+    "node_modules/@codemirror/lint": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.0.0.tgz",
+      "integrity": "sha512-nUUXcJW1Xp54kNs+a1ToPLK8MadO0rMTnJB8Zk4Z8gBdrN0kqV7uvUraU/T2yqg+grDNR38Vmy/MrhQN/RgwiA==",
+      "dependencies": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "crelt": "^1.0.5"
+      }
+    },
+    "node_modules/@codemirror/search": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.0.1.tgz",
+      "integrity": "sha512-uOinkOrM+daMduCgMPomDfKLr7drGHB4jHl3Vq6xY2WRlL7MkNsBE0b+XHYa/Mee2npsJOgwvkW4n1lMFeBW2Q==",
+      "dependencies": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "crelt": "^1.0.5"
+      }
+    },
+    "node_modules/@codemirror/state": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.1.0.tgz",
+      "integrity": "sha512-qbUr94DZTe6/V1VS7LDLz11rM/1t/nJxR1El4I6UaxDEdc0aZZvq6JCLJWiRmUf95NRAnDH6fhXn+PWp9wGCIg=="
+    },
+    "node_modules/@codemirror/view": {
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.1.2.tgz",
+      "integrity": "sha512-puUydfKwfmOo+ixtuB+uN/ZpcteEYSnpjHmMaow1sOQhNICsKtGBup3i9ybVqyzDagARRYzSHTWjbdeHqmn31w==",
+      "dependencies": {
+        "@codemirror/state": "^6.0.0",
+        "style-mod": "^4.0.0",
+        "w3c-keyname": "^2.2.4"
+      }
+    },
+    "node_modules/@lezer/common": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.0.tgz",
+      "integrity": "sha512-ohydQe+Hb+w4oMDvXzs8uuJd2NoA3D8YDcLiuDsLqH+yflDTPEpgCsWI3/6rH5C3BAedtH1/R51dxENldQceEA=="
+    },
+    "node_modules/@lezer/highlight": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.0.0.tgz",
+      "integrity": "sha512-nsCnNtim90UKsB5YxoX65v3GEIw3iCHw9RM2DtdgkiqAbKh9pCdvi8AWNwkYf10Lu6fxNhXPpkpHbW6mihhvJA==",
+      "dependencies": {
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/lr": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.2.0.tgz",
+      "integrity": "sha512-TgEpfm9br2SX8JwtwKT8HsQZKuFkLRg6g+IRxObk9nVKQLKnkP3oMh+QGcTBL9GQsfQ2ADtKPbj2iGSMf3ytiA==",
+      "dependencies": {
+        "@lezer/common": "^1.0.0"
       }
     },
     "node_modules/ansi-regex": {
@@ -195,9 +305,18 @@
       }
     },
     "node_modules/codemirror": {
-      "version": "5.65.5",
-      "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.5.tgz",
-      "integrity": "sha512-HNyhvGLnYz5c+kIsB9QKVitiZUevha3ovbIYaQiGzKo7ECSL/elWD9RXt3JgNr0NdnyqE9/Rc/7uLfkJQL638w=="
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
+      "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
+      "dependencies": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/commands": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/lint": "^6.0.0",
+        "@codemirror/search": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0"
+      }
     },
     "node_modules/color-convert": {
       "version": "1.9.3",
@@ -220,6 +339,11 @@
       "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
       "dev": true
     },
+    "node_modules/crelt": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.5.tgz",
+      "integrity": "sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA=="
+    },
     "node_modules/cross-spawn": {
       "version": "6.0.5",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -345,9 +469,9 @@
       }
     },
     "node_modules/esbuild": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.42.tgz",
-      "integrity": "sha512-V0uPZotCEHokJdNqyozH6qsaQXqmZEOiZWrXnds/zaH/0SyrIayRXWRB98CENO73MIZ9T3HBIOsmds5twWtmgw==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.51.tgz",
+      "integrity": "sha512-+CvnDitD7Q5sT7F+FM65sWkF8wJRf+j9fPcprxYV4j+ohmzVj2W7caUqH2s5kCaCJAfcAICjSlKhDCcvDpU7nw==",
       "dev": true,
       "hasInstallScript": true,
       "bin": {
@@ -357,32 +481,32 @@
         "node": ">=12"
       },
       "optionalDependencies": {
-        "esbuild-android-64": "0.14.42",
-        "esbuild-android-arm64": "0.14.42",
-        "esbuild-darwin-64": "0.14.42",
-        "esbuild-darwin-arm64": "0.14.42",
-        "esbuild-freebsd-64": "0.14.42",
-        "esbuild-freebsd-arm64": "0.14.42",
-        "esbuild-linux-32": "0.14.42",
-        "esbuild-linux-64": "0.14.42",
-        "esbuild-linux-arm": "0.14.42",
-        "esbuild-linux-arm64": "0.14.42",
-        "esbuild-linux-mips64le": "0.14.42",
-        "esbuild-linux-ppc64le": "0.14.42",
-        "esbuild-linux-riscv64": "0.14.42",
-        "esbuild-linux-s390x": "0.14.42",
-        "esbuild-netbsd-64": "0.14.42",
-        "esbuild-openbsd-64": "0.14.42",
-        "esbuild-sunos-64": "0.14.42",
-        "esbuild-windows-32": "0.14.42",
-        "esbuild-windows-64": "0.14.42",
-        "esbuild-windows-arm64": "0.14.42"
+        "esbuild-android-64": "0.14.51",
+        "esbuild-android-arm64": "0.14.51",
+        "esbuild-darwin-64": "0.14.51",
+        "esbuild-darwin-arm64": "0.14.51",
+        "esbuild-freebsd-64": "0.14.51",
+        "esbuild-freebsd-arm64": "0.14.51",
+        "esbuild-linux-32": "0.14.51",
+        "esbuild-linux-64": "0.14.51",
+        "esbuild-linux-arm": "0.14.51",
+        "esbuild-linux-arm64": "0.14.51",
+        "esbuild-linux-mips64le": "0.14.51",
+        "esbuild-linux-ppc64le": "0.14.51",
+        "esbuild-linux-riscv64": "0.14.51",
+        "esbuild-linux-s390x": "0.14.51",
+        "esbuild-netbsd-64": "0.14.51",
+        "esbuild-openbsd-64": "0.14.51",
+        "esbuild-sunos-64": "0.14.51",
+        "esbuild-windows-32": "0.14.51",
+        "esbuild-windows-64": "0.14.51",
+        "esbuild-windows-arm64": "0.14.51"
       }
     },
     "node_modules/esbuild-android-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.42.tgz",
-      "integrity": "sha512-P4Y36VUtRhK/zivqGVMqhptSrFILAGlYp0Z8r9UQqHJ3iWztRCNWnlBzD9HRx0DbueXikzOiwyOri+ojAFfW6A==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.51.tgz",
+      "integrity": "sha512-6FOuKTHnC86dtrKDmdSj2CkcKF8PnqkaIXqvgydqfJmqBazCPdw+relrMlhGjkvVdiiGV70rpdnyFmA65ekBCQ==",
       "cpu": [
         "x64"
       ],
@@ -396,9 +520,9 @@
       }
     },
     "node_modules/esbuild-android-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.42.tgz",
-      "integrity": "sha512-0cOqCubq+RWScPqvtQdjXG3Czb3AWI2CaKw3HeXry2eoA2rrPr85HF7IpdU26UWdBXgPYtlTN1LUiuXbboROhg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.51.tgz",
+      "integrity": "sha512-vBtp//5VVkZWmYYvHsqBRCMMi1MzKuMIn5XDScmnykMTu9+TD9v0NMEDqQxvtFToeYmojdo5UCV2vzMQWJcJ4A==",
       "cpu": [
         "arm64"
       ],
@@ -412,9 +536,9 @@
       }
     },
     "node_modules/esbuild-darwin-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.42.tgz",
-      "integrity": "sha512-ipiBdCA3ZjYgRfRLdQwP82rTiv/YVMtW36hTvAN5ZKAIfxBOyPXY7Cejp3bMXWgzKD8B6O+zoMzh01GZsCuEIA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.51.tgz",
+      "integrity": "sha512-YFmXPIOvuagDcwCejMRtCDjgPfnDu+bNeh5FU2Ryi68ADDVlWEpbtpAbrtf/lvFTWPexbgyKgzppNgsmLPr8PA==",
       "cpu": [
         "x64"
       ],
@@ -428,9 +552,9 @@
       }
     },
     "node_modules/esbuild-darwin-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.42.tgz",
-      "integrity": "sha512-bU2tHRqTPOaoH/4m0zYHbFWpiYDmaA0gt90/3BMEFaM0PqVK/a6MA2V/ypV5PO0v8QxN6gH5hBPY4YJ2lopXgA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.51.tgz",
+      "integrity": "sha512-juYD0QnSKwAMfzwKdIF6YbueXzS6N7y4GXPDeDkApz/1RzlT42mvX9jgNmyOlWKN7YzQAYbcUEJmZJYQGdf2ow==",
       "cpu": [
         "arm64"
       ],
@@ -444,9 +568,9 @@
       }
     },
     "node_modules/esbuild-freebsd-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.42.tgz",
-      "integrity": "sha512-75h1+22Ivy07+QvxHyhVqOdekupiTZVLN1PMwCDonAqyXd8TVNJfIRFrdL8QmSJrOJJ5h8H1I9ETyl2L8LQDaw==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.51.tgz",
+      "integrity": "sha512-cLEI/aXjb6vo5O2Y8rvVSQ7smgLldwYY5xMxqh/dQGfWO+R1NJOFsiax3IS4Ng300SVp7Gz3czxT6d6qf2cw0g==",
       "cpu": [
         "x64"
       ],
@@ -460,9 +584,9 @@
       }
     },
     "node_modules/esbuild-freebsd-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.42.tgz",
-      "integrity": "sha512-W6Jebeu5TTDQMJUJVarEzRU9LlKpNkPBbjqSu+GUPTHDCly5zZEQq9uHkmHHl7OKm+mQ2zFySN83nmfCeZCyNA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.51.tgz",
+      "integrity": "sha512-TcWVw/rCL2F+jUgRkgLa3qltd5gzKjIMGhkVybkjk6PJadYInPtgtUBp1/hG+mxyigaT7ib+od1Xb84b+L+1Mg==",
       "cpu": [
         "arm64"
       ],
@@ -476,9 +600,9 @@
       }
     },
     "node_modules/esbuild-linux-32": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.42.tgz",
-      "integrity": "sha512-Ooy/Bj+mJ1z4jlWcK5Dl6SlPlCgQB9zg1UrTCeY8XagvuWZ4qGPyYEWGkT94HUsRi2hKsXvcs6ThTOjBaJSMfg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.51.tgz",
+      "integrity": "sha512-RFqpyC5ChyWrjx8Xj2K0EC1aN0A37H6OJfmUXIASEqJoHcntuV3j2Efr9RNmUhMfNE6yEj2VpYuDteZLGDMr0w==",
       "cpu": [
         "ia32"
       ],
@@ -492,9 +616,9 @@
       }
     },
     "node_modules/esbuild-linux-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.42.tgz",
-      "integrity": "sha512-2L0HbzQfbTuemUWfVqNIjOfaTRt9zsvjnme6lnr7/MO9toz/MJ5tZhjqrG6uDWDxhsaHI2/nsDgrv8uEEN2eoA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.51.tgz",
+      "integrity": "sha512-dxjhrqo5i7Rq6DXwz5v+MEHVs9VNFItJmHBe1CxROWNf4miOGoQhqSG8StStbDkQ1Mtobg6ng+4fwByOhoQoeA==",
       "cpu": [
         "x64"
       ],
@@ -508,9 +632,9 @@
       }
     },
     "node_modules/esbuild-linux-arm": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.42.tgz",
-      "integrity": "sha512-STq69yzCMhdRaWnh29UYrLSr/qaWMm/KqwaRF1pMEK7kDiagaXhSL1zQGXbYv94GuGY/zAwzK98+6idCMUOOCg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.51.tgz",
+      "integrity": "sha512-LsJynDxYF6Neg7ZC7748yweCDD+N8ByCv22/7IAZglIEniEkqdF4HCaa49JNDLw1UQGlYuhOB8ZT/MmcSWzcWg==",
       "cpu": [
         "arm"
       ],
@@ -524,9 +648,9 @@
       }
     },
     "node_modules/esbuild-linux-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.42.tgz",
-      "integrity": "sha512-c3Ug3e9JpVr8jAcfbhirtpBauLxzYPpycjWulD71CF6ZSY26tvzmXMJYooQ2YKqDY4e/fPu5K8bm7MiXMnyxuA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.51.tgz",
+      "integrity": "sha512-D9rFxGutoqQX3xJPxqd6o+kvYKeIbM0ifW2y0bgKk5HPgQQOo2k9/2Vpto3ybGYaFPCE5qTGtqQta9PoP6ZEzw==",
       "cpu": [
         "arm64"
       ],
@@ -540,9 +664,9 @@
       }
     },
     "node_modules/esbuild-linux-mips64le": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.42.tgz",
-      "integrity": "sha512-QuvpHGbYlkyXWf2cGm51LBCHx6eUakjaSrRpUqhPwjh/uvNUYvLmz2LgPTTPwCqaKt0iwL+OGVL0tXA5aDbAbg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.51.tgz",
+      "integrity": "sha512-vS54wQjy4IinLSlb5EIlLoln8buh1yDgliP4CuEHumrPk4PvvP4kTRIG4SzMXm6t19N0rIfT4bNdAxzJLg2k6A==",
       "cpu": [
         "mips64el"
       ],
@@ -556,9 +680,9 @@
       }
     },
     "node_modules/esbuild-linux-ppc64le": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.42.tgz",
-      "integrity": "sha512-8ohIVIWDbDT+i7lCx44YCyIRrOW1MYlks9fxTo0ME2LS/fxxdoJBwHWzaDYhjvf8kNpA+MInZvyOEAGoVDrMHg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.51.tgz",
+      "integrity": "sha512-xcdd62Y3VfGoyphNP/aIV9LP+RzFw5M5Z7ja+zdpQHHvokJM7d0rlDRMN+iSSwvUymQkqZO+G/xjb4/75du8BQ==",
       "cpu": [
         "ppc64"
       ],
@@ -572,9 +696,9 @@
       }
     },
     "node_modules/esbuild-linux-riscv64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.42.tgz",
-      "integrity": "sha512-DzDqK3TuoXktPyG1Lwx7vhaF49Onv3eR61KwQyxYo4y5UKTpL3NmuarHSIaSVlTFDDpcIajCDwz5/uwKLLgKiQ==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.51.tgz",
+      "integrity": "sha512-syXHGak9wkAnFz0gMmRBoy44JV0rp4kVCEA36P5MCeZcxFq8+fllBC2t6sKI23w3qd8Vwo9pTADCgjTSf3L3rA==",
       "cpu": [
         "riscv64"
       ],
@@ -588,9 +712,9 @@
       }
     },
     "node_modules/esbuild-linux-s390x": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.42.tgz",
-      "integrity": "sha512-YFRhPCxl8nb//Wn6SiS5pmtplBi4z9yC2gLrYoYI/tvwuB1jldir9r7JwAGy1Ck4D7sE7wBN9GFtUUX/DLdcEQ==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.51.tgz",
+      "integrity": "sha512-kFAJY3dv+Wq8o28K/C7xkZk/X34rgTwhknSsElIqoEo8armCOjMJ6NsMxm48KaWY2h2RUYGtQmr+RGuUPKBhyw==",
       "cpu": [
         "s390x"
       ],
@@ -604,9 +728,9 @@
       }
     },
     "node_modules/esbuild-netbsd-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.42.tgz",
-      "integrity": "sha512-QYSD2k+oT9dqB/4eEM9c+7KyNYsIPgzYOSrmfNGDIyJrbT1d+CFVKvnKahDKNJLfOYj8N4MgyFaU9/Ytc6w5Vw==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.51.tgz",
+      "integrity": "sha512-ZZBI7qrR1FevdPBVHz/1GSk1x5GDL/iy42Zy8+neEm/HA7ma+hH/bwPEjeHXKWUDvM36CZpSL/fn1/y9/Hb+1A==",
       "cpu": [
         "x64"
       ],
@@ -620,9 +744,9 @@
       }
     },
     "node_modules/esbuild-openbsd-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.42.tgz",
-      "integrity": "sha512-M2meNVIKWsm2HMY7+TU9AxM7ZVwI9havdsw6m/6EzdXysyCFFSoaTQ/Jg03izjCsK17FsVRHqRe26Llj6x0MNA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.51.tgz",
+      "integrity": "sha512-7R1/p39M+LSVQVgDVlcY1KKm6kFKjERSX1lipMG51NPcspJD1tmiZSmmBXoY5jhHIu6JL1QkFDTx94gMYK6vfA==",
       "cpu": [
         "x64"
       ],
@@ -636,9 +760,9 @@
       }
     },
     "node_modules/esbuild-sunos-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.42.tgz",
-      "integrity": "sha512-uXV8TAZEw36DkgW8Ak3MpSJs1ofBb3Smkc/6pZ29sCAN1KzCAQzsje4sUwugf+FVicrHvlamCOlFZIXgct+iqQ==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.51.tgz",
+      "integrity": "sha512-HoHaCswHxLEYN8eBTtyO0bFEWvA3Kdb++hSQ/lLG7TyKF69TeSG0RNoBRAs45x/oCeWaTDntEZlYwAfQlhEtJA==",
       "cpu": [
         "x64"
       ],
@@ -652,9 +776,9 @@
       }
     },
     "node_modules/esbuild-windows-32": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.42.tgz",
-      "integrity": "sha512-4iw/8qWmRICWi9ZOnJJf9sYt6wmtp3hsN4TdI5NqgjfOkBVMxNdM9Vt3626G1Rda9ya2Q0hjQRD9W1o+m6Lz6g==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.51.tgz",
+      "integrity": "sha512-4rtwSAM35A07CBt1/X8RWieDj3ZUHQqUOaEo5ZBs69rt5WAFjP4aqCIobdqOy4FdhYw1yF8Z0xFBTyc9lgPtEg==",
       "cpu": [
         "ia32"
       ],
@@ -668,9 +792,9 @@
       }
     },
     "node_modules/esbuild-windows-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.42.tgz",
-      "integrity": "sha512-j3cdK+Y3+a5H0wHKmLGTJcq0+/2mMBHPWkItR3vytp/aUGD/ua/t2BLdfBIzbNN9nLCRL9sywCRpOpFMx3CxzA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.51.tgz",
+      "integrity": "sha512-HoN/5HGRXJpWODprGCgKbdMvrC3A2gqvzewu2eECRw2sYxOUoh2TV1tS+G7bHNapPGI79woQJGV6pFH7GH7qnA==",
       "cpu": [
         "x64"
       ],
@@ -684,9 +808,9 @@
       }
     },
     "node_modules/esbuild-windows-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.42.tgz",
-      "integrity": "sha512-+lRAARnF+hf8J0mN27ujO+VbhPbDqJ8rCcJKye4y7YZLV6C4n3pTRThAb388k/zqF5uM0lS5O201u0OqoWSicw==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.51.tgz",
+      "integrity": "sha512-JQDqPjuOH7o+BsKMSddMfmVJXrnYZxXDHsoLHc0xgmAZkOOCflRmC43q31pk79F9xuyWY45jDBPolb5ZgGOf9g==",
       "cpu": [
         "arm64"
       ],
@@ -1524,9 +1648,9 @@
       }
     },
     "node_modules/sass": {
-      "version": "1.52.1",
-      "resolved": "https://registry.npmjs.org/sass/-/sass-1.52.1.tgz",
-      "integrity": "sha512-fSzYTbr7z8oQnVJ3Acp9hV80dM1fkMN7mSD/25mpcct9F7FPBMOI8krEYALgU1aZoqGhQNhTPsuSmxjnIvAm4Q==",
+      "version": "1.54.0",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.0.tgz",
+      "integrity": "sha512-C4zp79GCXZfK0yoHZg+GxF818/aclhp9F48XBu/+bm9vXEVAYov9iU3FBVRMq3Hx3OA4jfKL+p2K9180mEh0xQ==",
       "dev": true,
       "dependencies": {
         "chokidar": ">=3.0.0 <4.0.0",
@@ -1602,9 +1726,9 @@
       }
     },
     "node_modules/snabbdom": {
-      "version": "3.5.0",
-      "resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-3.5.0.tgz",
-      "integrity": "sha512-Ff5BKG18KrrPuskHJlA9aujPHqEabItaDl96l7ZZndF4zt5AYSczz7ZjjgQAX5IBd5cd25lw9NfgX21yVUJ+9g==",
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-3.5.1.tgz",
+      "integrity": "sha512-wHMNIOjkm/YNE5EM3RCbr/+DVgPg6AqQAX1eOxO46zYNvCXjKP5Y865tqQj3EXnaMBjkxmQA5jFuDpDK/dbfiA==",
       "engines": {
         "node": ">=8.3.0"
       }
@@ -1733,6 +1857,11 @@
         "node": ">=4"
       }
     },
+    "node_modules/style-mod": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz",
+      "integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw=="
+    },
     "node_modules/supports-color": {
       "version": "5.5.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -1792,6 +1921,11 @@
         "spdx-expression-parse": "^3.0.0"
       }
     },
+    "node_modules/w3c-keyname": {
+      "version": "2.2.5",
+      "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.5.tgz",
+      "integrity": "sha512-WJrK7i6w+ULuZsGscCezbCH4Aev5U3xY87vnSimzzEgPQhb0Sa0a1rE3c2jtEwrFtSfi61Jefw3jI5/DD/3jbQ=="
+    },
     "node_modules/which": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
@@ -1897,6 +2031,105 @@
     }
   },
   "dependencies": {
+    "@codemirror/autocomplete": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.1.0.tgz",
+      "integrity": "sha512-wtO4O5WDyXhhCd4q4utDIDZxnQfmJ++3dGBCG9LMtI79+92OcA1DVk/n7BEupKmjIr8AzvptDz7YQ9ud6OkU+A==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "@codemirror/commands": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.0.1.tgz",
+      "integrity": "sha512-iNHDByicYqQjs0Wo1MKGfqNbMYMyhS9WV6EwMVwsHXImlFemgEUC+c5X22bXKBStN3qnwg4fArNZM+gkv22baQ==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "@codemirror/language": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz",
+      "integrity": "sha512-MC3svxuvIj0MRpFlGHxLS6vPyIdbTr2KKPEW46kCoCXw2ktb4NTkpkPBI/lSP/FoNXLCBJ0mrnUi1OoZxtpW1Q==",
+      "requires": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0",
+        "style-mod": "^4.0.0"
+      }
+    },
+    "@codemirror/legacy-modes": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.1.0.tgz",
+      "integrity": "sha512-V/PgGpndkZeTn3Hdlg/gd8MLFdyvTCIX+iwJzjUw5iNziWiNsAY8X0jvf7m3gSfxnKkNzmid6l0g4rYSpiDaCw==",
+      "requires": {
+        "@codemirror/language": "^6.0.0"
+      }
+    },
+    "@codemirror/lint": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.0.0.tgz",
+      "integrity": "sha512-nUUXcJW1Xp54kNs+a1ToPLK8MadO0rMTnJB8Zk4Z8gBdrN0kqV7uvUraU/T2yqg+grDNR38Vmy/MrhQN/RgwiA==",
+      "requires": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "crelt": "^1.0.5"
+      }
+    },
+    "@codemirror/search": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.0.1.tgz",
+      "integrity": "sha512-uOinkOrM+daMduCgMPomDfKLr7drGHB4jHl3Vq6xY2WRlL7MkNsBE0b+XHYa/Mee2npsJOgwvkW4n1lMFeBW2Q==",
+      "requires": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "crelt": "^1.0.5"
+      }
+    },
+    "@codemirror/state": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.1.0.tgz",
+      "integrity": "sha512-qbUr94DZTe6/V1VS7LDLz11rM/1t/nJxR1El4I6UaxDEdc0aZZvq6JCLJWiRmUf95NRAnDH6fhXn+PWp9wGCIg=="
+    },
+    "@codemirror/view": {
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.1.2.tgz",
+      "integrity": "sha512-puUydfKwfmOo+ixtuB+uN/ZpcteEYSnpjHmMaow1sOQhNICsKtGBup3i9ybVqyzDagARRYzSHTWjbdeHqmn31w==",
+      "requires": {
+        "@codemirror/state": "^6.0.0",
+        "style-mod": "^4.0.0",
+        "w3c-keyname": "^2.2.4"
+      }
+    },
+    "@lezer/common": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.0.tgz",
+      "integrity": "sha512-ohydQe+Hb+w4oMDvXzs8uuJd2NoA3D8YDcLiuDsLqH+yflDTPEpgCsWI3/6rH5C3BAedtH1/R51dxENldQceEA=="
+    },
+    "@lezer/highlight": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.0.0.tgz",
+      "integrity": "sha512-nsCnNtim90UKsB5YxoX65v3GEIw3iCHw9RM2DtdgkiqAbKh9pCdvi8AWNwkYf10Lu6fxNhXPpkpHbW6mihhvJA==",
+      "requires": {
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "@lezer/lr": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.2.0.tgz",
+      "integrity": "sha512-TgEpfm9br2SX8JwtwKT8HsQZKuFkLRg6g+IRxObk9nVKQLKnkP3oMh+QGcTBL9GQsfQ2ADtKPbj2iGSMf3ytiA==",
+      "requires": {
+        "@lezer/common": "^1.0.0"
+      }
+    },
     "ansi-regex": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
@@ -2035,9 +2268,18 @@
       }
     },
     "codemirror": {
-      "version": "5.65.5",
-      "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.5.tgz",
-      "integrity": "sha512-HNyhvGLnYz5c+kIsB9QKVitiZUevha3ovbIYaQiGzKo7ECSL/elWD9RXt3JgNr0NdnyqE9/Rc/7uLfkJQL638w=="
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
+      "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
+      "requires": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/commands": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/lint": "^6.0.0",
+        "@codemirror/search": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0"
+      }
     },
     "color-convert": {
       "version": "1.9.3",
@@ -2060,6 +2302,11 @@
       "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
       "dev": true
     },
+    "crelt": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.5.tgz",
+      "integrity": "sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA=="
+    },
     "cross-spawn": {
       "version": "6.0.5",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -2158,170 +2405,170 @@
       }
     },
     "esbuild": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.42.tgz",
-      "integrity": "sha512-V0uPZotCEHokJdNqyozH6qsaQXqmZEOiZWrXnds/zaH/0SyrIayRXWRB98CENO73MIZ9T3HBIOsmds5twWtmgw==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.51.tgz",
+      "integrity": "sha512-+CvnDitD7Q5sT7F+FM65sWkF8wJRf+j9fPcprxYV4j+ohmzVj2W7caUqH2s5kCaCJAfcAICjSlKhDCcvDpU7nw==",
       "dev": true,
       "requires": {
-        "esbuild-android-64": "0.14.42",
-        "esbuild-android-arm64": "0.14.42",
-        "esbuild-darwin-64": "0.14.42",
-        "esbuild-darwin-arm64": "0.14.42",
-        "esbuild-freebsd-64": "0.14.42",
-        "esbuild-freebsd-arm64": "0.14.42",
-        "esbuild-linux-32": "0.14.42",
-        "esbuild-linux-64": "0.14.42",
-        "esbuild-linux-arm": "0.14.42",
-        "esbuild-linux-arm64": "0.14.42",
-        "esbuild-linux-mips64le": "0.14.42",
-        "esbuild-linux-ppc64le": "0.14.42",
-        "esbuild-linux-riscv64": "0.14.42",
-        "esbuild-linux-s390x": "0.14.42",
-        "esbuild-netbsd-64": "0.14.42",
-        "esbuild-openbsd-64": "0.14.42",
-        "esbuild-sunos-64": "0.14.42",
-        "esbuild-windows-32": "0.14.42",
-        "esbuild-windows-64": "0.14.42",
-        "esbuild-windows-arm64": "0.14.42"
+        "esbuild-android-64": "0.14.51",
+        "esbuild-android-arm64": "0.14.51",
+        "esbuild-darwin-64": "0.14.51",
+        "esbuild-darwin-arm64": "0.14.51",
+        "esbuild-freebsd-64": "0.14.51",
+        "esbuild-freebsd-arm64": "0.14.51",
+        "esbuild-linux-32": "0.14.51",
+        "esbuild-linux-64": "0.14.51",
+        "esbuild-linux-arm": "0.14.51",
+        "esbuild-linux-arm64": "0.14.51",
+        "esbuild-linux-mips64le": "0.14.51",
+        "esbuild-linux-ppc64le": "0.14.51",
+        "esbuild-linux-riscv64": "0.14.51",
+        "esbuild-linux-s390x": "0.14.51",
+        "esbuild-netbsd-64": "0.14.51",
+        "esbuild-openbsd-64": "0.14.51",
+        "esbuild-sunos-64": "0.14.51",
+        "esbuild-windows-32": "0.14.51",
+        "esbuild-windows-64": "0.14.51",
+        "esbuild-windows-arm64": "0.14.51"
       }
     },
     "esbuild-android-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.42.tgz",
-      "integrity": "sha512-P4Y36VUtRhK/zivqGVMqhptSrFILAGlYp0Z8r9UQqHJ3iWztRCNWnlBzD9HRx0DbueXikzOiwyOri+ojAFfW6A==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.51.tgz",
+      "integrity": "sha512-6FOuKTHnC86dtrKDmdSj2CkcKF8PnqkaIXqvgydqfJmqBazCPdw+relrMlhGjkvVdiiGV70rpdnyFmA65ekBCQ==",
       "dev": true,
       "optional": true
     },
     "esbuild-android-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.42.tgz",
-      "integrity": "sha512-0cOqCubq+RWScPqvtQdjXG3Czb3AWI2CaKw3HeXry2eoA2rrPr85HF7IpdU26UWdBXgPYtlTN1LUiuXbboROhg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.51.tgz",
+      "integrity": "sha512-vBtp//5VVkZWmYYvHsqBRCMMi1MzKuMIn5XDScmnykMTu9+TD9v0NMEDqQxvtFToeYmojdo5UCV2vzMQWJcJ4A==",
       "dev": true,
       "optional": true
     },
     "esbuild-darwin-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.42.tgz",
-      "integrity": "sha512-ipiBdCA3ZjYgRfRLdQwP82rTiv/YVMtW36hTvAN5ZKAIfxBOyPXY7Cejp3bMXWgzKD8B6O+zoMzh01GZsCuEIA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.51.tgz",
+      "integrity": "sha512-YFmXPIOvuagDcwCejMRtCDjgPfnDu+bNeh5FU2Ryi68ADDVlWEpbtpAbrtf/lvFTWPexbgyKgzppNgsmLPr8PA==",
       "dev": true,
       "optional": true
     },
     "esbuild-darwin-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.42.tgz",
-      "integrity": "sha512-bU2tHRqTPOaoH/4m0zYHbFWpiYDmaA0gt90/3BMEFaM0PqVK/a6MA2V/ypV5PO0v8QxN6gH5hBPY4YJ2lopXgA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.51.tgz",
+      "integrity": "sha512-juYD0QnSKwAMfzwKdIF6YbueXzS6N7y4GXPDeDkApz/1RzlT42mvX9jgNmyOlWKN7YzQAYbcUEJmZJYQGdf2ow==",
       "dev": true,
       "optional": true
     },
     "esbuild-freebsd-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.42.tgz",
-      "integrity": "sha512-75h1+22Ivy07+QvxHyhVqOdekupiTZVLN1PMwCDonAqyXd8TVNJfIRFrdL8QmSJrOJJ5h8H1I9ETyl2L8LQDaw==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.51.tgz",
+      "integrity": "sha512-cLEI/aXjb6vo5O2Y8rvVSQ7smgLldwYY5xMxqh/dQGfWO+R1NJOFsiax3IS4Ng300SVp7Gz3czxT6d6qf2cw0g==",
       "dev": true,
       "optional": true
     },
     "esbuild-freebsd-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.42.tgz",
-      "integrity": "sha512-W6Jebeu5TTDQMJUJVarEzRU9LlKpNkPBbjqSu+GUPTHDCly5zZEQq9uHkmHHl7OKm+mQ2zFySN83nmfCeZCyNA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.51.tgz",
+      "integrity": "sha512-TcWVw/rCL2F+jUgRkgLa3qltd5gzKjIMGhkVybkjk6PJadYInPtgtUBp1/hG+mxyigaT7ib+od1Xb84b+L+1Mg==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-32": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.42.tgz",
-      "integrity": "sha512-Ooy/Bj+mJ1z4jlWcK5Dl6SlPlCgQB9zg1UrTCeY8XagvuWZ4qGPyYEWGkT94HUsRi2hKsXvcs6ThTOjBaJSMfg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.51.tgz",
+      "integrity": "sha512-RFqpyC5ChyWrjx8Xj2K0EC1aN0A37H6OJfmUXIASEqJoHcntuV3j2Efr9RNmUhMfNE6yEj2VpYuDteZLGDMr0w==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.42.tgz",
-      "integrity": "sha512-2L0HbzQfbTuemUWfVqNIjOfaTRt9zsvjnme6lnr7/MO9toz/MJ5tZhjqrG6uDWDxhsaHI2/nsDgrv8uEEN2eoA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.51.tgz",
+      "integrity": "sha512-dxjhrqo5i7Rq6DXwz5v+MEHVs9VNFItJmHBe1CxROWNf4miOGoQhqSG8StStbDkQ1Mtobg6ng+4fwByOhoQoeA==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-arm": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.42.tgz",
-      "integrity": "sha512-STq69yzCMhdRaWnh29UYrLSr/qaWMm/KqwaRF1pMEK7kDiagaXhSL1zQGXbYv94GuGY/zAwzK98+6idCMUOOCg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.51.tgz",
+      "integrity": "sha512-LsJynDxYF6Neg7ZC7748yweCDD+N8ByCv22/7IAZglIEniEkqdF4HCaa49JNDLw1UQGlYuhOB8ZT/MmcSWzcWg==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.42.tgz",
-      "integrity": "sha512-c3Ug3e9JpVr8jAcfbhirtpBauLxzYPpycjWulD71CF6ZSY26tvzmXMJYooQ2YKqDY4e/fPu5K8bm7MiXMnyxuA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.51.tgz",
+      "integrity": "sha512-D9rFxGutoqQX3xJPxqd6o+kvYKeIbM0ifW2y0bgKk5HPgQQOo2k9/2Vpto3ybGYaFPCE5qTGtqQta9PoP6ZEzw==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-mips64le": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.42.tgz",
-      "integrity": "sha512-QuvpHGbYlkyXWf2cGm51LBCHx6eUakjaSrRpUqhPwjh/uvNUYvLmz2LgPTTPwCqaKt0iwL+OGVL0tXA5aDbAbg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.51.tgz",
+      "integrity": "sha512-vS54wQjy4IinLSlb5EIlLoln8buh1yDgliP4CuEHumrPk4PvvP4kTRIG4SzMXm6t19N0rIfT4bNdAxzJLg2k6A==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-ppc64le": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.42.tgz",
-      "integrity": "sha512-8ohIVIWDbDT+i7lCx44YCyIRrOW1MYlks9fxTo0ME2LS/fxxdoJBwHWzaDYhjvf8kNpA+MInZvyOEAGoVDrMHg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.51.tgz",
+      "integrity": "sha512-xcdd62Y3VfGoyphNP/aIV9LP+RzFw5M5Z7ja+zdpQHHvokJM7d0rlDRMN+iSSwvUymQkqZO+G/xjb4/75du8BQ==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-riscv64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.42.tgz",
-      "integrity": "sha512-DzDqK3TuoXktPyG1Lwx7vhaF49Onv3eR61KwQyxYo4y5UKTpL3NmuarHSIaSVlTFDDpcIajCDwz5/uwKLLgKiQ==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.51.tgz",
+      "integrity": "sha512-syXHGak9wkAnFz0gMmRBoy44JV0rp4kVCEA36P5MCeZcxFq8+fllBC2t6sKI23w3qd8Vwo9pTADCgjTSf3L3rA==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-s390x": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.42.tgz",
-      "integrity": "sha512-YFRhPCxl8nb//Wn6SiS5pmtplBi4z9yC2gLrYoYI/tvwuB1jldir9r7JwAGy1Ck4D7sE7wBN9GFtUUX/DLdcEQ==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.51.tgz",
+      "integrity": "sha512-kFAJY3dv+Wq8o28K/C7xkZk/X34rgTwhknSsElIqoEo8armCOjMJ6NsMxm48KaWY2h2RUYGtQmr+RGuUPKBhyw==",
       "dev": true,
       "optional": true
     },
     "esbuild-netbsd-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.42.tgz",
-      "integrity": "sha512-QYSD2k+oT9dqB/4eEM9c+7KyNYsIPgzYOSrmfNGDIyJrbT1d+CFVKvnKahDKNJLfOYj8N4MgyFaU9/Ytc6w5Vw==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.51.tgz",
+      "integrity": "sha512-ZZBI7qrR1FevdPBVHz/1GSk1x5GDL/iy42Zy8+neEm/HA7ma+hH/bwPEjeHXKWUDvM36CZpSL/fn1/y9/Hb+1A==",
       "dev": true,
       "optional": true
     },
     "esbuild-openbsd-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.42.tgz",
-      "integrity": "sha512-M2meNVIKWsm2HMY7+TU9AxM7ZVwI9havdsw6m/6EzdXysyCFFSoaTQ/Jg03izjCsK17FsVRHqRe26Llj6x0MNA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.51.tgz",
+      "integrity": "sha512-7R1/p39M+LSVQVgDVlcY1KKm6kFKjERSX1lipMG51NPcspJD1tmiZSmmBXoY5jhHIu6JL1QkFDTx94gMYK6vfA==",
       "dev": true,
       "optional": true
     },
     "esbuild-sunos-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.42.tgz",
-      "integrity": "sha512-uXV8TAZEw36DkgW8Ak3MpSJs1ofBb3Smkc/6pZ29sCAN1KzCAQzsje4sUwugf+FVicrHvlamCOlFZIXgct+iqQ==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.51.tgz",
+      "integrity": "sha512-HoHaCswHxLEYN8eBTtyO0bFEWvA3Kdb++hSQ/lLG7TyKF69TeSG0RNoBRAs45x/oCeWaTDntEZlYwAfQlhEtJA==",
       "dev": true,
       "optional": true
     },
     "esbuild-windows-32": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.42.tgz",
-      "integrity": "sha512-4iw/8qWmRICWi9ZOnJJf9sYt6wmtp3hsN4TdI5NqgjfOkBVMxNdM9Vt3626G1Rda9ya2Q0hjQRD9W1o+m6Lz6g==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.51.tgz",
+      "integrity": "sha512-4rtwSAM35A07CBt1/X8RWieDj3ZUHQqUOaEo5ZBs69rt5WAFjP4aqCIobdqOy4FdhYw1yF8Z0xFBTyc9lgPtEg==",
       "dev": true,
       "optional": true
     },
     "esbuild-windows-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.42.tgz",
-      "integrity": "sha512-j3cdK+Y3+a5H0wHKmLGTJcq0+/2mMBHPWkItR3vytp/aUGD/ua/t2BLdfBIzbNN9nLCRL9sywCRpOpFMx3CxzA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.51.tgz",
+      "integrity": "sha512-HoN/5HGRXJpWODprGCgKbdMvrC3A2gqvzewu2eECRw2sYxOUoh2TV1tS+G7bHNapPGI79woQJGV6pFH7GH7qnA==",
       "dev": true,
       "optional": true
     },
     "esbuild-windows-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.42.tgz",
-      "integrity": "sha512-+lRAARnF+hf8J0mN27ujO+VbhPbDqJ8rCcJKye4y7YZLV6C4n3pTRThAb388k/zqF5uM0lS5O201u0OqoWSicw==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.51.tgz",
+      "integrity": "sha512-JQDqPjuOH7o+BsKMSddMfmVJXrnYZxXDHsoLHc0xgmAZkOOCflRmC43q31pk79F9xuyWY45jDBPolb5ZgGOf9g==",
       "dev": true,
       "optional": true
     },
@@ -2922,9 +3169,9 @@
       }
     },
     "sass": {
-      "version": "1.52.1",
-      "resolved": "https://registry.npmjs.org/sass/-/sass-1.52.1.tgz",
-      "integrity": "sha512-fSzYTbr7z8oQnVJ3Acp9hV80dM1fkMN7mSD/25mpcct9F7FPBMOI8krEYALgU1aZoqGhQNhTPsuSmxjnIvAm4Q==",
+      "version": "1.54.0",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.0.tgz",
+      "integrity": "sha512-C4zp79GCXZfK0yoHZg+GxF818/aclhp9F48XBu/+bm9vXEVAYov9iU3FBVRMq3Hx3OA4jfKL+p2K9180mEh0xQ==",
       "dev": true,
       "requires": {
         "chokidar": ">=3.0.0 <4.0.0",
@@ -2982,9 +3229,9 @@
       }
     },
     "snabbdom": {
-      "version": "3.5.0",
-      "resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-3.5.0.tgz",
-      "integrity": "sha512-Ff5BKG18KrrPuskHJlA9aujPHqEabItaDl96l7ZZndF4zt5AYSczz7ZjjgQAX5IBd5cd25lw9NfgX21yVUJ+9g=="
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-3.5.1.tgz",
+      "integrity": "sha512-wHMNIOjkm/YNE5EM3RCbr/+DVgPg6AqQAX1eOxO46zYNvCXjKP5Y865tqQj3EXnaMBjkxmQA5jFuDpDK/dbfiA=="
     },
     "sortablejs": {
       "version": "1.15.0",
@@ -3086,6 +3333,11 @@
       "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
       "dev": true
     },
+    "style-mod": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz",
+      "integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw=="
+    },
     "supports-color": {
       "version": "5.5.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -3136,6 +3388,11 @@
         "spdx-expression-parse": "^3.0.0"
       }
     },
+    "w3c-keyname": {
+      "version": "2.2.5",
+      "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.5.tgz",
+      "integrity": "sha512-WJrK7i6w+ULuZsGscCezbCH4Aev5U3xY87vnSimzzEgPQhb0Sa0a1rE3c2jtEwrFtSfi61Jefw3jI5/DD/3jbQ=="
+    },
     "which": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
diff --git a/package.json b/package.json
index 9a2f66448..8407ffc77 100644
--- a/package.json
+++ b/package.json
@@ -16,19 +16,24 @@
   },
   "devDependencies": {
     "chokidar-cli": "^3.0",
-    "esbuild": "0.14.42",
+    "esbuild": "0.14.51",
     "livereload": "^0.9.3",
     "npm-run-all": "^4.1.5",
     "punycode": "^2.1.1",
-    "sass": "^1.52.1"
+    "sass": "^1.54.0"
   },
   "dependencies": {
+    "@codemirror/commands": "^6.0.1",
+    "@codemirror/language": "^6.2.1",
+    "@codemirror/legacy-modes": "^6.1.0",
+    "@codemirror/state": "^6.1.0",
+    "@codemirror/view": "^6.1.2",
     "clipboard": "^2.0.11",
-    "codemirror": "^5.65.5",
+    "codemirror": "^6.0.1",
     "dropzone": "^5.9.3",
     "markdown-it": "^13.0.1",
     "markdown-it-task-lists": "^2.1.1",
-    "snabbdom": "^3.5.0",
+    "snabbdom": "^3.5.1",
     "sortablejs": "^1.15.0"
   }
 }
diff --git a/resources/js/code.mjs b/resources/js/code/index.mjs
similarity index 55%
rename from resources/js/code.mjs
rename to resources/js/code/index.mjs
index eca941f1c..ff60cbff5 100644
--- a/resources/js/code.mjs
+++ b/resources/js/code/index.mjs
@@ -1,106 +1,10 @@
-import CodeMirror from "codemirror";
+import {EditorView} from "@codemirror/view"
+// import {EditorState} from "@codemirror/state"
 import Clipboard from "clipboard/dist/clipboard.min";
 
 // Modes
-import 'codemirror/mode/css/css';
-import 'codemirror/mode/clike/clike';
-import 'codemirror/mode/diff/diff';
-import 'codemirror/mode/fortran/fortran';
-import 'codemirror/mode/go/go';
-import 'codemirror/mode/haskell/haskell';
-import 'codemirror/mode/htmlmixed/htmlmixed';
-import 'codemirror/mode/javascript/javascript';
-import 'codemirror/mode/julia/julia';
-import 'codemirror/mode/lua/lua';
-import 'codemirror/mode/markdown/markdown';
-import 'codemirror/mode/mllike/mllike';
-import 'codemirror/mode/nginx/nginx';
-import 'codemirror/mode/perl/perl';
-import 'codemirror/mode/pascal/pascal';
-import 'codemirror/mode/php/php';
-import 'codemirror/mode/powershell/powershell';
-import 'codemirror/mode/properties/properties';
-import 'codemirror/mode/python/python';
-import 'codemirror/mode/ruby/ruby';
-import 'codemirror/mode/rust/rust';
-import 'codemirror/mode/shell/shell';
-import 'codemirror/mode/sql/sql';
-import 'codemirror/mode/stex/stex';
-import 'codemirror/mode/toml/toml';
-import 'codemirror/mode/vb/vb';
-import 'codemirror/mode/vbscript/vbscript';
-import 'codemirror/mode/xml/xml';
-import 'codemirror/mode/yaml/yaml';
-
-// Addons
-import 'codemirror/addon/scroll/scrollpastend';
-
-// Mapping of possible languages or formats from user input to their codemirror modes.
-// Value can be a mode string or a function that will receive the code content & return the mode string.
-// The function option is used in the event the exact mode could be dynamic depending on the code.
-const modeMap = {
-    bash: 'shell',
-    css: 'css',
-    c: 'text/x-csrc',
-    java: 'text/x-java',
-    scala: 'text/x-scala',
-    kotlin: 'text/x-kotlin',
-    'c++': 'text/x-c++src',
-    'c#': 'text/x-csharp',
-    csharp: 'text/x-csharp',
-    diff: 'diff',
-    for: 'fortran',
-    fortran: 'fortran',
-    'f#': 'text/x-fsharp',
-    fsharp: 'text/x-fsharp',
-    go: 'go',
-    haskell: 'haskell',
-    hs: 'haskell',
-    html: 'htmlmixed',
-    ini: 'properties',
-    javascript: 'text/javascript',
-    json: 'application/json',
-    js: 'text/javascript',
-    jl: 'text/x-julia',
-    julia: 'text/x-julia',
-    latex: 'text/x-stex',
-    lua: 'lua',
-    md: 'markdown',
-    mdown: 'markdown',
-    markdown: 'markdown',
-    ml: 'mllike',
-    nginx: 'nginx',
-    perl: 'perl',
-    pl: 'perl',
-    powershell: 'powershell',
-    properties: 'properties',
-    ocaml: 'text/x-ocaml',
-    pascal: 'text/x-pascal',
-    pas: 'text/x-pascal',
-    php: (content) => {
-        return content.includes('<?php') ? 'php' : 'text/x-php';
-    },
-    py: 'python',
-    python: 'python',
-    ruby: 'ruby',
-    rust: 'rust',
-    rb: 'ruby',
-    rs: 'rust',
-    shell: 'shell',
-    sh: 'shell',
-    stext: 'text/x-stex',
-    toml: 'toml',
-    ts: 'text/typescript',
-    typescript: 'text/typescript',
-    sql: 'text/x-sql',
-    vbs: 'vbscript',
-    vbscript: 'vbscript',
-    'vb.net': 'text/x-vb',
-    vbnet: 'text/x-vb',
-    xml: 'xml',
-    yaml: 'yaml',
-    yml: 'yaml',
-};
+import {modes, modeMap, modesAsStreamLanguages} from "./modes";
+import {viewer} from "./setups.js";
 
 /**
  * Highlight pre elements on a page
@@ -138,17 +42,19 @@ function highlightElem(elem) {
         mode = getMode(langName, content);
     }
 
-    const cm = CodeMirror(function(elt) {
-        elem.parentNode.replaceChild(elt, elem);
-    }, {
-        value: content,
-        mode:  mode,
-        lineNumbers: true,
-        lineWrapping: false,
-        theme: getTheme(),
-        readOnly: true
+    const wrapper = document.createElement('div');
+    elem.parentNode.insertBefore(wrapper, elem);
+
+    const cm = new EditorView({
+        parent: wrapper,
+        doc: content,
+        extensions: viewer(),
     });
 
+    elem.remove();
+
+    // TODO - theme: getTheme(),
+    // TODO - mode,
     addCopyIcon(cm);
 }
 
@@ -157,24 +63,25 @@ function highlightElem(elem) {
  * @param cmInstance
  */
 function addCopyIcon(cmInstance) {
-    const copyIcon = `<svg viewBox="0 0 24 24" width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>`;
-    const copyButton = document.createElement('div');
-    copyButton.classList.add('CodeMirror-copy');
-    copyButton.innerHTML = copyIcon;
-    cmInstance.display.wrapper.appendChild(copyButton);
-
-    const clipboard = new Clipboard(copyButton, {
-        text: function(trigger) {
-            return cmInstance.getValue()
-        }
-    });
-
-    clipboard.on('success', event => {
-        copyButton.classList.add('success');
-        setTimeout(() => {
-            copyButton.classList.remove('success');
-        }, 240);
-    });
+    // TODO
+    // const copyIcon = `<svg viewBox="0 0 24 24" width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>`;
+    // const copyButton = document.createElement('div');
+    // copyButton.classList.add('CodeMirror-copy');
+    // copyButton.innerHTML = copyIcon;
+    // cmInstance.display.wrapper.appendChild(copyButton);
+    //
+    // const clipboard = new Clipboard(copyButton, {
+    //     text: function(trigger) {
+    //         return cmInstance.getValue()
+    //     }
+    // });
+    //
+    // clipboard.on('success', event => {
+    //     copyButton.classList.add('success');
+    //     setTimeout(() => {
+    //         copyButton.classList.remove('success');
+    //     }, 240);
+    // });
 }
 
 /**
diff --git a/resources/js/code/modes.js b/resources/js/code/modes.js
new file mode 100644
index 000000000..5a89255a5
--- /dev/null
+++ b/resources/js/code/modes.js
@@ -0,0 +1,134 @@
+import {StreamLanguage} from "@codemirror/language"
+
+import {css as langCss} from '@codemirror/legacy-modes/mode/css';
+import {clike as langClike} from '@codemirror/legacy-modes/mode/clike';
+import {diff as langDiff} from '@codemirror/legacy-modes/mode/diff';
+import {fortran as langFortran} from '@codemirror/legacy-modes/mode/fortran';
+import {go as langGo} from '@codemirror/legacy-modes/mode/go';
+import {haskell as langHaskell} from '@codemirror/legacy-modes/mode/haskell';
+// import {htmlmixed as langHtmlmixed} from '@codemirror/legacy-modes/mode/htmlmixed';
+import {javascript as langJavascript} from '@codemirror/legacy-modes/mode/javascript';
+import {julia as langJulia} from '@codemirror/legacy-modes/mode/julia';
+import {lua as langLua} from '@codemirror/legacy-modes/mode/lua';
+// import {markdown as langMarkdown} from '@codemirror/legacy-modes/mode/markdown';
+import {oCaml as langMllike} from '@codemirror/legacy-modes/mode/mllike';
+import {nginx as langNginx} from '@codemirror/legacy-modes/mode/nginx';
+import {perl as langPerl} from '@codemirror/legacy-modes/mode/perl';
+import {pascal as langPascal} from '@codemirror/legacy-modes/mode/pascal';
+// import {php as langPhp} from '@codemirror/legacy-modes/mode/php';
+import {powerShell as langPowershell} from '@codemirror/legacy-modes/mode/powershell';
+import {properties as langProperties} from '@codemirror/legacy-modes/mode/properties';
+import {python as langPython} from '@codemirror/legacy-modes/mode/python';
+import {ruby as langRuby} from '@codemirror/legacy-modes/mode/ruby';
+import {rust as langRust} from '@codemirror/legacy-modes/mode/rust';
+import {shell as langShell} from '@codemirror/legacy-modes/mode/shell';
+import {sql as langSql} from '@codemirror/legacy-modes/mode/sql';
+import {stex as langStex} from '@codemirror/legacy-modes/mode/stex';
+import {toml as langToml} from '@codemirror/legacy-modes/mode/toml';
+import {vb as langVb} from '@codemirror/legacy-modes/mode/vb';
+import {vbScript as langVbscript} from '@codemirror/legacy-modes/mode/vbscript';
+import {xml as langXml} from '@codemirror/legacy-modes/mode/xml';
+import {yaml as langYaml} from '@codemirror/legacy-modes/mode/yaml';
+
+export const modes = [
+    langCss,
+    langClike,
+    langDiff,
+    langFortran,
+    langGo,
+    langHaskell,
+    // langHtmlmixed,
+    langJavascript,
+    langJulia,
+    langLua,
+    // langMarkdown,
+    langMllike,
+    langNginx,
+    langPerl,
+    langPascal,
+    // langPhp,
+    langPowershell,
+    langProperties,
+    langPython,
+    langRuby,
+    langRust,
+    langShell,
+    langSql,
+    langStex,
+    langToml,
+    langVb,
+    langVbscript,
+    langXml,
+    langYaml,
+];
+
+// Mapping of possible languages or formats from user input to their codemirror modes.
+// Value can be a mode string or a function that will receive the code content & return the mode string.
+// The function option is used in the event the exact mode could be dynamic depending on the code.
+export const modeMap = {
+    bash: 'shell',
+    css: 'css',
+    c: 'text/x-csrc',
+    java: 'text/x-java',
+    scala: 'text/x-scala',
+    kotlin: 'text/x-kotlin',
+    'c++': 'text/x-c++src',
+    'c#': 'text/x-csharp',
+    csharp: 'text/x-csharp',
+    diff: 'diff',
+    for: 'fortran',
+    fortran: 'fortran',
+    'f#': 'text/x-fsharp',
+    fsharp: 'text/x-fsharp',
+    go: 'go',
+    haskell: 'haskell',
+    hs: 'haskell',
+    html: 'htmlmixed',
+    ini: 'properties',
+    javascript: 'text/javascript',
+    json: 'application/json',
+    js: 'text/javascript',
+    jl: 'text/x-julia',
+    julia: 'text/x-julia',
+    latex: 'text/x-stex',
+    lua: 'lua',
+    md: 'markdown',
+    mdown: 'markdown',
+    markdown: 'markdown',
+    ml: 'mllike',
+    nginx: 'nginx',
+    perl: 'perl',
+    pl: 'perl',
+    powershell: 'powershell',
+    properties: 'properties',
+    ocaml: 'text/x-ocaml',
+    pascal: 'text/x-pascal',
+    pas: 'text/x-pascal',
+    php: (content) => {
+        return content.includes('<?php') ? 'php' : 'text/x-php';
+    },
+    py: 'python',
+    python: 'python',
+    ruby: 'ruby',
+    rust: 'rust',
+    rb: 'ruby',
+    rs: 'rust',
+    shell: 'shell',
+    sh: 'shell',
+    stext: 'text/x-stex',
+    toml: 'toml',
+    ts: 'text/typescript',
+    typescript: 'text/typescript',
+    sql: 'text/x-sql',
+    vbs: 'vbscript',
+    vbscript: 'vbscript',
+    'vb.net': 'text/x-vb',
+    vbnet: 'text/x-vb',
+    xml: 'xml',
+    yaml: 'yaml',
+    yml: 'yaml',
+};
+
+export function modesAsStreamLanguages() {
+    return modes.map(mode => StreamLanguage.define(mode));
+}
\ No newline at end of file
diff --git a/resources/js/code/setups.js b/resources/js/code/setups.js
new file mode 100644
index 000000000..768d3a35d
--- /dev/null
+++ b/resources/js/code/setups.js
@@ -0,0 +1,32 @@
+
+import {keymap, highlightSpecialChars, drawSelection, highlightActiveLine, dropCursor,
+    rectangularSelection, lineNumbers, highlightActiveLineGutter} from "@codemirror/view"
+import {defaultHighlightStyle, syntaxHighlighting, bracketMatching,
+     foldKeymap} from "@codemirror/language"
+import {defaultKeymap, history, historyKeymap} from "@codemirror/commands"
+import {EditorState} from "@codemirror/state"
+
+import {modesAsStreamLanguages} from "./modes";
+
+
+export function viewer() {
+    return [
+        lineNumbers(),
+        highlightActiveLineGutter(),
+        highlightSpecialChars(),
+        history(),
+        drawSelection(),
+        dropCursor(),
+        syntaxHighlighting(defaultHighlightStyle, {fallback: true}),
+        bracketMatching(),
+        rectangularSelection(),
+        highlightActiveLine(),
+        keymap.of([
+            ...defaultKeymap,
+            ...historyKeymap,
+            ...foldKeymap,
+        ]),
+        EditorState.readOnly.of(true),
+        ...modesAsStreamLanguages(),
+    ];
+}
\ No newline at end of file

From 97146a63590fa193a4958c09202b40340e840a1f Mon Sep 17 00:00:00 2001
From: Dan Brown <ssddanbrown@googlemail.com>
Date: Wed, 3 Aug 2022 19:40:16 +0100
Subject: [PATCH 2/4] Added handling of codemirror 6 code languages

---
 package-lock.json              | 261 +++++++++++++++++++++++++++++++++
 package.json                   |   5 +
 resources/js/code/index.mjs    |  49 ++-----
 resources/js/code/languages.js | 120 +++++++++++++++
 resources/js/code/modes.js     | 134 -----------------
 resources/js/code/setups.js    |   4 -
 resources/js/code/views.js     |  38 +++++
 7 files changed, 437 insertions(+), 174 deletions(-)
 create mode 100644 resources/js/code/languages.js
 delete mode 100644 resources/js/code/modes.js
 create mode 100644 resources/js/code/views.js

diff --git a/package-lock.json b/package-lock.json
index c141e654a..0eca777cb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6,6 +6,11 @@
     "": {
       "dependencies": {
         "@codemirror/commands": "^6.0.1",
+        "@codemirror/lang-html": "^6.1.0",
+        "@codemirror/lang-javascript": "^6.0.2",
+        "@codemirror/lang-json": "^6.0.0",
+        "@codemirror/lang-markdown": "^6.0.1",
+        "@codemirror/lang-php": "^6.0.0",
         "@codemirror/language": "^6.2.1",
         "@codemirror/legacy-modes": "^6.1.0",
         "@codemirror/state": "^6.1.0",
@@ -55,6 +60,79 @@
         "@lezer/common": "^1.0.0"
       }
     },
+    "node_modules/@codemirror/lang-css": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.0.0.tgz",
+      "integrity": "sha512-jBqc+BTuwhNOTlrimFghLlSrN6iFuE44HULKWoR4qKYObhOIl9Lci1iYj6zMIte1XTQmZguNvjXMyr43LUKwSw==",
+      "dependencies": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/css": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-html": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.1.0.tgz",
+      "integrity": "sha512-gA7NmJxqvnhwza05CvR7W/39Ap9r/4Vs9uiC0IeFYo1hSlJzc/8N6Evviz6vTW1x8SpHcRYyqKOf6rpl6LfWtg==",
+      "dependencies": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/lang-css": "^6.0.0",
+        "@codemirror/lang-javascript": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/html": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-javascript": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.0.2.tgz",
+      "integrity": "sha512-BZRJ9u/zl16hLkSpDAWm73mrfIR7HJrr0lvnhoSOCQVea5BglguWI/slxexhvUb0CB5cXgKWuo2bM+N9EhIaZw==",
+      "dependencies": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/lint": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/javascript": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-json": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.0.tgz",
+      "integrity": "sha512-DvTcYTKLmg2viADXlTdufrT334M9jowe1qO02W28nvm+nejcvhM5vot5mE8/kPrxYw/HJHhwu1z2PyBpnMLCNQ==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/json": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-markdown": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.0.1.tgz",
+      "integrity": "sha512-pHPQuRwf9cUrmkmsTHRjtS9ZnGu3fA9YzAdh2++d+L9wbfnC2XbKh0Xvm/0YiUjdCnoCx9wDFEoCuAnkqKWLIw==",
+      "dependencies": {
+        "@codemirror/lang-html": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/markdown": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-php": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-php/-/lang-php-6.0.0.tgz",
+      "integrity": "sha512-96CEjq0xEgbzc6bdFPwILPfZ6m8917JRbh2oPszZJABlYxG4Y+eYjtYkUTDb4yuyjQKyigHoeGC6zoIOYA1NWA==",
+      "dependencies": {
+        "@codemirror/lang-html": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/php": "^1.0.0"
+      }
+    },
     "node_modules/@codemirror/language": {
       "version": "6.2.1",
       "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz",
@@ -116,6 +194,15 @@
       "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.0.tgz",
       "integrity": "sha512-ohydQe+Hb+w4oMDvXzs8uuJd2NoA3D8YDcLiuDsLqH+yflDTPEpgCsWI3/6rH5C3BAedtH1/R51dxENldQceEA=="
     },
+    "node_modules/@lezer/css": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.0.0.tgz",
+      "integrity": "sha512-616VqgDKumHmYIuxs3tnX1irEQmoDHgF/TlP4O5ICWwyHwLMErq+8iKVuzTkOdBqvYAVmObqThcDEAaaMJjAdg==",
+      "dependencies": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
     "node_modules/@lezer/highlight": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.0.0.tgz",
@@ -124,6 +211,34 @@
         "@lezer/common": "^1.0.0"
       }
     },
+    "node_modules/@lezer/html": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.0.1.tgz",
+      "integrity": "sha512-sC00zEt3GBh3vVO6QaGX4YZCl41S9dHWN/WGBsDixy9G+sqOC7gsa4cxA/fmRVAiBvhqYkJk+5Ul4oul92CPVw==",
+      "dependencies": {
+        "@lezer/common": "^1.0.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/javascript": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.0.2.tgz",
+      "integrity": "sha512-IjOVeIRhM8IuafWNnk+UzRz7p4/JSOKBNINLYLsdSGuJS9Ju7vFdc82AlTt0jgtV5D8eBZf4g0vK4d3ttBNz7A==",
+      "dependencies": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/json": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.0.tgz",
+      "integrity": "sha512-zbAuUY09RBzCoCA3lJ1+ypKw5WSNvLqGMtasdW6HvVOqZoCpPr8eWrsGnOVWGKGn8Rh21FnrKRVlJXrGAVUqRw==",
+      "dependencies": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
     "node_modules/@lezer/lr": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.2.0.tgz",
@@ -132,6 +247,24 @@
         "@lezer/common": "^1.0.0"
       }
     },
+    "node_modules/@lezer/markdown": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.0.1.tgz",
+      "integrity": "sha512-LlpNWLqes3XQvd8TwpJTHf9ENl4fI6H32xQkMgltUITFMMdQpOASXQtDawWR03yS6hskh4bkhATQbgjdGMoUvA==",
+      "dependencies": {
+        "@lezer/common": "^1.0.0",
+        "@lezer/highlight": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/php": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/php/-/php-1.0.0.tgz",
+      "integrity": "sha512-kFQu/mk/vmjpA+fjQU87d9eimqKJ9PFCa8CZCPFWGEwNnm7Ahpw32N+HYEU/YAQ0XcfmOAnW/YJCEa8WpUOMMw==",
+      "dependencies": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
     "node_modules/ansi-regex": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
@@ -2053,6 +2186,79 @@
         "@lezer/common": "^1.0.0"
       }
     },
+    "@codemirror/lang-css": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.0.0.tgz",
+      "integrity": "sha512-jBqc+BTuwhNOTlrimFghLlSrN6iFuE44HULKWoR4qKYObhOIl9Lci1iYj6zMIte1XTQmZguNvjXMyr43LUKwSw==",
+      "requires": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/css": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-html": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.1.0.tgz",
+      "integrity": "sha512-gA7NmJxqvnhwza05CvR7W/39Ap9r/4Vs9uiC0IeFYo1hSlJzc/8N6Evviz6vTW1x8SpHcRYyqKOf6rpl6LfWtg==",
+      "requires": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/lang-css": "^6.0.0",
+        "@codemirror/lang-javascript": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/html": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-javascript": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.0.2.tgz",
+      "integrity": "sha512-BZRJ9u/zl16hLkSpDAWm73mrfIR7HJrr0lvnhoSOCQVea5BglguWI/slxexhvUb0CB5cXgKWuo2bM+N9EhIaZw==",
+      "requires": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/lint": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/javascript": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-json": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.0.tgz",
+      "integrity": "sha512-DvTcYTKLmg2viADXlTdufrT334M9jowe1qO02W28nvm+nejcvhM5vot5mE8/kPrxYw/HJHhwu1z2PyBpnMLCNQ==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/json": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-markdown": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.0.1.tgz",
+      "integrity": "sha512-pHPQuRwf9cUrmkmsTHRjtS9ZnGu3fA9YzAdh2++d+L9wbfnC2XbKh0Xvm/0YiUjdCnoCx9wDFEoCuAnkqKWLIw==",
+      "requires": {
+        "@codemirror/lang-html": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/markdown": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-php": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-php/-/lang-php-6.0.0.tgz",
+      "integrity": "sha512-96CEjq0xEgbzc6bdFPwILPfZ6m8917JRbh2oPszZJABlYxG4Y+eYjtYkUTDb4yuyjQKyigHoeGC6zoIOYA1NWA==",
+      "requires": {
+        "@codemirror/lang-html": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/php": "^1.0.0"
+      }
+    },
     "@codemirror/language": {
       "version": "6.2.1",
       "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz",
@@ -2114,6 +2320,15 @@
       "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.0.tgz",
       "integrity": "sha512-ohydQe+Hb+w4oMDvXzs8uuJd2NoA3D8YDcLiuDsLqH+yflDTPEpgCsWI3/6rH5C3BAedtH1/R51dxENldQceEA=="
     },
+    "@lezer/css": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.0.0.tgz",
+      "integrity": "sha512-616VqgDKumHmYIuxs3tnX1irEQmoDHgF/TlP4O5ICWwyHwLMErq+8iKVuzTkOdBqvYAVmObqThcDEAaaMJjAdg==",
+      "requires": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
     "@lezer/highlight": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.0.0.tgz",
@@ -2122,6 +2337,34 @@
         "@lezer/common": "^1.0.0"
       }
     },
+    "@lezer/html": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.0.1.tgz",
+      "integrity": "sha512-sC00zEt3GBh3vVO6QaGX4YZCl41S9dHWN/WGBsDixy9G+sqOC7gsa4cxA/fmRVAiBvhqYkJk+5Ul4oul92CPVw==",
+      "requires": {
+        "@lezer/common": "^1.0.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "@lezer/javascript": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.0.2.tgz",
+      "integrity": "sha512-IjOVeIRhM8IuafWNnk+UzRz7p4/JSOKBNINLYLsdSGuJS9Ju7vFdc82AlTt0jgtV5D8eBZf4g0vK4d3ttBNz7A==",
+      "requires": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "@lezer/json": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.0.tgz",
+      "integrity": "sha512-zbAuUY09RBzCoCA3lJ1+ypKw5WSNvLqGMtasdW6HvVOqZoCpPr8eWrsGnOVWGKGn8Rh21FnrKRVlJXrGAVUqRw==",
+      "requires": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
     "@lezer/lr": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.2.0.tgz",
@@ -2130,6 +2373,24 @@
         "@lezer/common": "^1.0.0"
       }
     },
+    "@lezer/markdown": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.0.1.tgz",
+      "integrity": "sha512-LlpNWLqes3XQvd8TwpJTHf9ENl4fI6H32xQkMgltUITFMMdQpOASXQtDawWR03yS6hskh4bkhATQbgjdGMoUvA==",
+      "requires": {
+        "@lezer/common": "^1.0.0",
+        "@lezer/highlight": "^1.0.0"
+      }
+    },
+    "@lezer/php": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/php/-/php-1.0.0.tgz",
+      "integrity": "sha512-kFQu/mk/vmjpA+fjQU87d9eimqKJ9PFCa8CZCPFWGEwNnm7Ahpw32N+HYEU/YAQ0XcfmOAnW/YJCEa8WpUOMMw==",
+      "requires": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
     "ansi-regex": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
diff --git a/package.json b/package.json
index 8407ffc77..4d2b70247 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,11 @@
   },
   "dependencies": {
     "@codemirror/commands": "^6.0.1",
+    "@codemirror/lang-html": "^6.1.0",
+    "@codemirror/lang-javascript": "^6.0.2",
+    "@codemirror/lang-json": "^6.0.0",
+    "@codemirror/lang-markdown": "^6.0.1",
+    "@codemirror/lang-php": "^6.0.0",
     "@codemirror/language": "^6.2.1",
     "@codemirror/legacy-modes": "^6.1.0",
     "@codemirror/state": "^6.1.0",
diff --git a/resources/js/code/index.mjs b/resources/js/code/index.mjs
index ff60cbff5..6ef659994 100644
--- a/resources/js/code/index.mjs
+++ b/resources/js/code/index.mjs
@@ -1,10 +1,9 @@
 import {EditorView} from "@codemirror/view"
-// import {EditorState} from "@codemirror/state"
 import Clipboard from "clipboard/dist/clipboard.min";
 
 // Modes
-import {modes, modeMap, modesAsStreamLanguages} from "./modes";
 import {viewer} from "./setups.js";
+import {createView, updateViewLanguage} from "./views.js";
 
 /**
  * Highlight pre elements on a page
@@ -36,26 +35,24 @@ function highlightElem(elem) {
     elem.innerHTML = elem.innerHTML.replace(/<br\s*[\/]?>/gi ,'\n');
     const content = elem.textContent.trimEnd();
 
-    let mode = '';
+    let langName = '';
     if (innerCodeElem !== null) {
-        const langName = innerCodeElem.className.replace('language-', '');
-        mode = getMode(langName, content);
+        langName = innerCodeElem.className.replace('language-', '');
     }
 
     const wrapper = document.createElement('div');
     elem.parentNode.insertBefore(wrapper, elem);
 
-    const cm = new EditorView({
+    const ev = createView({
         parent: wrapper,
         doc: content,
         extensions: viewer(),
     });
+    setMode(ev, langName, content);
 
     elem.remove();
 
-    // TODO - theme: getTheme(),
-    // TODO - mode,
-    addCopyIcon(cm);
+    addCopyIcon(ev);
 }
 
 /**
@@ -84,28 +81,6 @@ function addCopyIcon(cmInstance) {
     // });
 }
 
-/**
- * Search for a codemirror code based off a user suggestion
- * @param {String} suggestion
- * @param {String} content
- * @returns {string}
- */
-function getMode(suggestion, content) {
-    suggestion = suggestion.trim().replace(/^\./g, '').toLowerCase();
-
-    const modeMapType = typeof modeMap[suggestion];
-
-    if (modeMapType === 'undefined') {
-        return '';
-    }
-
-    if (modeMapType === 'function') {
-        return modeMap[suggestion](content);
-    }
-
-    return modeMap[suggestion];
-}
-
 /**
  * Ge the theme to use for CodeMirror instances.
  * @returns {*|string}
@@ -172,12 +147,14 @@ export function inlineEditor(textArea, mode) {
 }
 
 /**
- * Set the mode of a codemirror instance.
- * @param cmInstance
- * @param modeSuggestion
+ * Set the language mode of a codemirror EditorView.
+ *
+ * @param {EditorView} ev
+ * @param {string} modeSuggestion
+ * @param {string} content
  */
-export function setMode(cmInstance, modeSuggestion, content) {
-      cmInstance.setOption('mode', getMode(modeSuggestion, content));
+export function setMode(ev, modeSuggestion, content) {
+    updateViewLanguage(ev, modeSuggestion, content);
 }
 
 /**
diff --git a/resources/js/code/languages.js b/resources/js/code/languages.js
new file mode 100644
index 000000000..4b04bdb14
--- /dev/null
+++ b/resources/js/code/languages.js
@@ -0,0 +1,120 @@
+import {StreamLanguage} from "@codemirror/language"
+
+import {css} from '@codemirror/legacy-modes/mode/css';
+import {c, java, cpp, csharp, kotlin, scala} from '@codemirror/legacy-modes/mode/clike';
+import {diff} from '@codemirror/legacy-modes/mode/diff';
+import {fortran} from '@codemirror/legacy-modes/mode/fortran';
+import {go} from '@codemirror/legacy-modes/mode/go';
+import {haskell} from '@codemirror/legacy-modes/mode/haskell';
+import {html} from '@codemirror/lang-html';
+import {javascript} from '@codemirror/lang-javascript';
+import {json} from '@codemirror/lang-json';
+import {julia} from '@codemirror/legacy-modes/mode/julia';
+import {lua} from '@codemirror/legacy-modes/mode/lua';
+import {markdown} from '@codemirror/lang-markdown';
+import {oCaml, fSharp, sml} from '@codemirror/legacy-modes/mode/mllike';
+import {nginx} from '@codemirror/legacy-modes/mode/nginx';
+import {perl} from '@codemirror/legacy-modes/mode/perl';
+import {pascal} from '@codemirror/legacy-modes/mode/pascal';
+import {php} from '@codemirror/lang-php';
+import {powerShell} from '@codemirror/legacy-modes/mode/powershell';
+import {properties} from '@codemirror/legacy-modes/mode/properties';
+import {python} from '@codemirror/legacy-modes/mode/python';
+import {ruby} from '@codemirror/legacy-modes/mode/ruby';
+import {rust} from '@codemirror/legacy-modes/mode/rust';
+import {shell} from '@codemirror/legacy-modes/mode/shell';
+import {sql} from '@codemirror/legacy-modes/mode/sql';
+import {stex} from '@codemirror/legacy-modes/mode/stex';
+import {toml} from '@codemirror/legacy-modes/mode/toml';
+import {vb} from '@codemirror/legacy-modes/mode/vb';
+import {vbScript} from '@codemirror/legacy-modes/mode/vbscript';
+import {xml} from '@codemirror/legacy-modes/mode/xml';
+import {yaml} from '@codemirror/legacy-modes/mode/yaml';
+
+
+// Mapping of possible languages or formats from user input to their codemirror modes.
+// Value can be a mode string or a function that will receive the code content & return the mode string.
+// The function option is used in the event the exact mode could be dynamic depending on the code.
+const modeMap = {
+    bash: () => StreamLanguage.define(shell),
+    css: () => StreamLanguage.define(css),
+    c: () => StreamLanguage.define(c),
+    java: () => StreamLanguage.define(java),
+    scala: () => StreamLanguage.define(scala),
+    kotlin: () => StreamLanguage.define(kotlin),
+    'c++': () => StreamLanguage.define(cpp),
+    'c#': () => StreamLanguage.define(csharp),
+    csharp: () => StreamLanguage.define(csharp),
+    diff: () => StreamLanguage.define(diff),
+    for: () => StreamLanguage.define(fortran),
+    fortran: () => StreamLanguage.define(fortran),
+    'f#': () => StreamLanguage.define(fSharp),
+    fsharp: () => StreamLanguage.define(fSharp),
+    go: () => StreamLanguage.define(go),
+    haskell: () => StreamLanguage.define(haskell),
+    hs: () => StreamLanguage.define(haskell),
+    html: () => html(),
+    ini: () => StreamLanguage.define(properties),
+    javascript: () => javascript(),
+    json: () => json(),
+    js: () => javascript(),
+    jl: () => StreamLanguage.define(julia),
+    julia: () => StreamLanguage.define(julia),
+    latex: () => StreamLanguage.define(stex),
+    lua: () => StreamLanguage.define(lua),
+    md: () => StreamLanguage.define(markdown),
+    mdown: () => StreamLanguage.define(markdown),
+    markdown: () => StreamLanguage.define(markdown),
+    ml: () => StreamLanguage.define(sml),
+    nginx: () => StreamLanguage.define(nginx),
+    perl: () => StreamLanguage.define(perl),
+    pl: () => StreamLanguage.define(perl),
+    powershell: () => StreamLanguage.define(powerShell),
+    properties: () => StreamLanguage.define(properties),
+    ocaml: () => StreamLanguage.define(oCaml),
+    pascal: () => StreamLanguage.define(pascal),
+    pas: () => StreamLanguage.define(pascal),
+    php: (code) => {
+        const hasTags = code.includes('<?php');
+        return php({plain: !hasTags});
+    },
+    py: () => StreamLanguage.define(python),
+    python: () => StreamLanguage.define(python),
+    ruby: () => StreamLanguage.define(ruby),
+    rust: () => StreamLanguage.define(rust),
+    rb: () => StreamLanguage.define(ruby),
+    rs: () => StreamLanguage.define(rust),
+    shell: () => StreamLanguage.define(shell),
+    sh: () => StreamLanguage.define(shell),
+    stext: () => StreamLanguage.define(stex),
+    toml: () => StreamLanguage.define(toml),
+    ts: () => javascript({typescript: true}),
+    typescript: () => javascript({typescript: true}),
+    sql: () => StreamLanguage.define(sql),
+    vbs: () => StreamLanguage.define(vbScript),
+    vbscript: () => StreamLanguage.define(vbScript),
+    'vb.net': () => StreamLanguage.define(vb),
+    vbnet: () => StreamLanguage.define(vb),
+    xml: () => StreamLanguage.define(xml),
+    yaml: () => StreamLanguage.define(yaml),
+    yml: () => StreamLanguage.define(yaml),
+};
+
+/**
+ * Get the relevant codemirror language extension based upon the given language
+ * suggestion and content.
+ * @param {String} langSuggestion
+ * @param {String} content
+ * @returns {StreamLanguage}
+ */
+export function getLanguageExtension(langSuggestion, content) {
+    const suggestion = langSuggestion.trim().replace(/^\./g, '').toLowerCase();
+
+    const language = modeMap[suggestion];
+
+    if (typeof language === 'undefined') {
+        return undefined;
+    }
+
+    return language(content);
+}
\ No newline at end of file
diff --git a/resources/js/code/modes.js b/resources/js/code/modes.js
deleted file mode 100644
index 5a89255a5..000000000
--- a/resources/js/code/modes.js
+++ /dev/null
@@ -1,134 +0,0 @@
-import {StreamLanguage} from "@codemirror/language"
-
-import {css as langCss} from '@codemirror/legacy-modes/mode/css';
-import {clike as langClike} from '@codemirror/legacy-modes/mode/clike';
-import {diff as langDiff} from '@codemirror/legacy-modes/mode/diff';
-import {fortran as langFortran} from '@codemirror/legacy-modes/mode/fortran';
-import {go as langGo} from '@codemirror/legacy-modes/mode/go';
-import {haskell as langHaskell} from '@codemirror/legacy-modes/mode/haskell';
-// import {htmlmixed as langHtmlmixed} from '@codemirror/legacy-modes/mode/htmlmixed';
-import {javascript as langJavascript} from '@codemirror/legacy-modes/mode/javascript';
-import {julia as langJulia} from '@codemirror/legacy-modes/mode/julia';
-import {lua as langLua} from '@codemirror/legacy-modes/mode/lua';
-// import {markdown as langMarkdown} from '@codemirror/legacy-modes/mode/markdown';
-import {oCaml as langMllike} from '@codemirror/legacy-modes/mode/mllike';
-import {nginx as langNginx} from '@codemirror/legacy-modes/mode/nginx';
-import {perl as langPerl} from '@codemirror/legacy-modes/mode/perl';
-import {pascal as langPascal} from '@codemirror/legacy-modes/mode/pascal';
-// import {php as langPhp} from '@codemirror/legacy-modes/mode/php';
-import {powerShell as langPowershell} from '@codemirror/legacy-modes/mode/powershell';
-import {properties as langProperties} from '@codemirror/legacy-modes/mode/properties';
-import {python as langPython} from '@codemirror/legacy-modes/mode/python';
-import {ruby as langRuby} from '@codemirror/legacy-modes/mode/ruby';
-import {rust as langRust} from '@codemirror/legacy-modes/mode/rust';
-import {shell as langShell} from '@codemirror/legacy-modes/mode/shell';
-import {sql as langSql} from '@codemirror/legacy-modes/mode/sql';
-import {stex as langStex} from '@codemirror/legacy-modes/mode/stex';
-import {toml as langToml} from '@codemirror/legacy-modes/mode/toml';
-import {vb as langVb} from '@codemirror/legacy-modes/mode/vb';
-import {vbScript as langVbscript} from '@codemirror/legacy-modes/mode/vbscript';
-import {xml as langXml} from '@codemirror/legacy-modes/mode/xml';
-import {yaml as langYaml} from '@codemirror/legacy-modes/mode/yaml';
-
-export const modes = [
-    langCss,
-    langClike,
-    langDiff,
-    langFortran,
-    langGo,
-    langHaskell,
-    // langHtmlmixed,
-    langJavascript,
-    langJulia,
-    langLua,
-    // langMarkdown,
-    langMllike,
-    langNginx,
-    langPerl,
-    langPascal,
-    // langPhp,
-    langPowershell,
-    langProperties,
-    langPython,
-    langRuby,
-    langRust,
-    langShell,
-    langSql,
-    langStex,
-    langToml,
-    langVb,
-    langVbscript,
-    langXml,
-    langYaml,
-];
-
-// Mapping of possible languages or formats from user input to their codemirror modes.
-// Value can be a mode string or a function that will receive the code content & return the mode string.
-// The function option is used in the event the exact mode could be dynamic depending on the code.
-export const modeMap = {
-    bash: 'shell',
-    css: 'css',
-    c: 'text/x-csrc',
-    java: 'text/x-java',
-    scala: 'text/x-scala',
-    kotlin: 'text/x-kotlin',
-    'c++': 'text/x-c++src',
-    'c#': 'text/x-csharp',
-    csharp: 'text/x-csharp',
-    diff: 'diff',
-    for: 'fortran',
-    fortran: 'fortran',
-    'f#': 'text/x-fsharp',
-    fsharp: 'text/x-fsharp',
-    go: 'go',
-    haskell: 'haskell',
-    hs: 'haskell',
-    html: 'htmlmixed',
-    ini: 'properties',
-    javascript: 'text/javascript',
-    json: 'application/json',
-    js: 'text/javascript',
-    jl: 'text/x-julia',
-    julia: 'text/x-julia',
-    latex: 'text/x-stex',
-    lua: 'lua',
-    md: 'markdown',
-    mdown: 'markdown',
-    markdown: 'markdown',
-    ml: 'mllike',
-    nginx: 'nginx',
-    perl: 'perl',
-    pl: 'perl',
-    powershell: 'powershell',
-    properties: 'properties',
-    ocaml: 'text/x-ocaml',
-    pascal: 'text/x-pascal',
-    pas: 'text/x-pascal',
-    php: (content) => {
-        return content.includes('<?php') ? 'php' : 'text/x-php';
-    },
-    py: 'python',
-    python: 'python',
-    ruby: 'ruby',
-    rust: 'rust',
-    rb: 'ruby',
-    rs: 'rust',
-    shell: 'shell',
-    sh: 'shell',
-    stext: 'text/x-stex',
-    toml: 'toml',
-    ts: 'text/typescript',
-    typescript: 'text/typescript',
-    sql: 'text/x-sql',
-    vbs: 'vbscript',
-    vbscript: 'vbscript',
-    'vb.net': 'text/x-vb',
-    vbnet: 'text/x-vb',
-    xml: 'xml',
-    yaml: 'yaml',
-    yml: 'yaml',
-};
-
-export function modesAsStreamLanguages() {
-    return modes.map(mode => StreamLanguage.define(mode));
-}
\ No newline at end of file
diff --git a/resources/js/code/setups.js b/resources/js/code/setups.js
index 768d3a35d..45cc9c317 100644
--- a/resources/js/code/setups.js
+++ b/resources/js/code/setups.js
@@ -6,9 +6,6 @@ import {defaultHighlightStyle, syntaxHighlighting, bracketMatching,
 import {defaultKeymap, history, historyKeymap} from "@codemirror/commands"
 import {EditorState} from "@codemirror/state"
 
-import {modesAsStreamLanguages} from "./modes";
-
-
 export function viewer() {
     return [
         lineNumbers(),
@@ -27,6 +24,5 @@ export function viewer() {
             ...foldKeymap,
         ]),
         EditorState.readOnly.of(true),
-        ...modesAsStreamLanguages(),
     ];
 }
\ No newline at end of file
diff --git a/resources/js/code/views.js b/resources/js/code/views.js
new file mode 100644
index 000000000..e87718939
--- /dev/null
+++ b/resources/js/code/views.js
@@ -0,0 +1,38 @@
+import {getLanguageExtension} from "./languages";
+import {Compartment} from "@codemirror/state"
+import {EditorView} from "@codemirror/view"
+
+const viewLangCompartments = new WeakMap();
+
+/**
+ * Create a new editor view.
+ *
+ * @param {Object} config
+ * @returns {EditorView}
+ */
+export function createView(config) {
+    const langCompartment = new Compartment();
+    config.extensions.push(langCompartment.of([]));
+
+    const ev = new EditorView(config);
+
+    viewLangCompartments.set(ev, langCompartment);
+
+    return ev;
+}
+
+/**
+ * Set the language mode of an EditorView.
+ *
+ * @param {EditorView} ev
+ * @param {string} modeSuggestion
+ * @param {string} content
+ */
+export function updateViewLanguage(ev, modeSuggestion, content) {
+    const compartment = viewLangCompartments.get(ev);
+    const language = getLanguageExtension(modeSuggestion, content);
+
+    ev.dispatch({
+        effects: compartment.reconfigure(language ? language : [])
+    })
+}
\ No newline at end of file

From 4757ed9453c0cfd8dd229e34ee3a64f74dfe0f3a Mon Sep 17 00:00:00 2001
From: Dan Brown <ssddanbrown@googlemail.com>
Date: Thu, 4 Aug 2022 13:33:51 +0100
Subject: [PATCH 3/4] Converted codemirror languges to new packages where
 available

Does increase bundle size massively though, Will need to think about
solutions for this.
---
 package-lock.json              | 217 +++++++++++++++++++++++++++++++++
 package.json                   |   7 ++
 resources/js/code/languages.js |  56 +++++----
 3 files changed, 253 insertions(+), 27 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 0eca777cb..a29be3324 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6,11 +6,18 @@
     "": {
       "dependencies": {
         "@codemirror/commands": "^6.0.1",
+        "@codemirror/lang-cpp": "^6.0.1",
+        "@codemirror/lang-css": "^6.0.0",
         "@codemirror/lang-html": "^6.1.0",
+        "@codemirror/lang-java": "^6.0.0",
         "@codemirror/lang-javascript": "^6.0.2",
         "@codemirror/lang-json": "^6.0.0",
         "@codemirror/lang-markdown": "^6.0.1",
         "@codemirror/lang-php": "^6.0.0",
+        "@codemirror/lang-python": "^6.0.1",
+        "@codemirror/lang-rust": "^6.0.0",
+        "@codemirror/lang-sql": "^6.0.0",
+        "@codemirror/lang-xml": "^6.0.0",
         "@codemirror/language": "^6.2.1",
         "@codemirror/legacy-modes": "^6.1.0",
         "@codemirror/state": "^6.1.0",
@@ -60,6 +67,15 @@
         "@lezer/common": "^1.0.0"
       }
     },
+    "node_modules/@codemirror/lang-cpp": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-cpp/-/lang-cpp-6.0.1.tgz",
+      "integrity": "sha512-46p3ohfhjzkLWJ3VwvzX0aqlXh8UkEqX1xo2Eds9l6Ql3uDoxI2IZEjR9cgJaGOZTXCkDzQuQH7sfYAxMvzLjA==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/cpp": "^1.0.0"
+      }
+    },
     "node_modules/@codemirror/lang-css": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.0.0.tgz",
@@ -85,6 +101,15 @@
         "@lezer/html": "^1.0.0"
       }
     },
+    "node_modules/@codemirror/lang-java": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-java/-/lang-java-6.0.0.tgz",
+      "integrity": "sha512-aeWq+ikUS6Eubk6RBbiMgxuBIT4Ih8Asb1qc2pSiMcstrwr4ODbazPXsBHbLBYg3aObvFyOm2bNQncbQJjZ3sQ==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/java": "^1.0.0"
+      }
+    },
     "node_modules/@codemirror/lang-javascript": {
       "version": "6.0.2",
       "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.0.2.tgz",
@@ -133,6 +158,48 @@
         "@lezer/php": "^1.0.0"
       }
     },
+    "node_modules/@codemirror/lang-python": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.0.1.tgz",
+      "integrity": "sha512-w2jTSY+LgXnK7iIBLgMxk6xtJhZHkcxcGGveuq9zYmncURmOTFXKnDvBaBClNIHKgjkHXZqGK8ZduCMK23hZPA==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/python": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-rust": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-rust/-/lang-rust-6.0.0.tgz",
+      "integrity": "sha512-VQql3Qk1BwoXb3SUkeWll/EEwhsgQWc1bpia7CFqqp2PhQBb5A6r4Vj2JCkU/nE6A7TDPSGHTOoqJSG5s/VXtQ==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/rust": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-sql": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-sql/-/lang-sql-6.0.0.tgz",
+      "integrity": "sha512-mq4NwTDbbo7QZktfgPsS+ms0FmAceH4WM2jLbgf+N28FoKUy0JzGe3XJymgnTewXnNUwujKBxArQzibxSDdVyQ==",
+      "dependencies": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-xml": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-xml/-/lang-xml-6.0.0.tgz",
+      "integrity": "sha512-M/HLWxIiP956xGjtrxkeHkCmDGVQGKu782x8pOH5CLJIMkWtiB1DWfDoDHqpFjdEE9dkfcqPWvYfVi6GbhuXEg==",
+      "dependencies": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/xml": "^1.0.0"
+      }
+    },
     "node_modules/@codemirror/language": {
       "version": "6.2.1",
       "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz",
@@ -194,6 +261,15 @@
       "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.0.tgz",
       "integrity": "sha512-ohydQe+Hb+w4oMDvXzs8uuJd2NoA3D8YDcLiuDsLqH+yflDTPEpgCsWI3/6rH5C3BAedtH1/R51dxENldQceEA=="
     },
+    "node_modules/@lezer/cpp": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/cpp/-/cpp-1.0.0.tgz",
+      "integrity": "sha512-Klk3/AIEKoptmm6cNm7xTulNXjdTKkD+hVOEcz/NeRg8tIestP5hsGHJeFDR/XtyDTxsjoPjKZRIGohht7zbKw==",
+      "dependencies": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
     "node_modules/@lezer/css": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.0.0.tgz",
@@ -221,6 +297,15 @@
         "@lezer/lr": "^1.0.0"
       }
     },
+    "node_modules/@lezer/java": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/java/-/java-1.0.0.tgz",
+      "integrity": "sha512-z2EA0JHq2WoiKfQy5uOOd4t17PJtq8guh58gPkSzOnNcQ7DNbkrU+Axak+jL8+Noinwyz2tRNOseQFj+Tg+P0A==",
+      "dependencies": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
     "node_modules/@lezer/javascript": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.0.2.tgz",
@@ -265,6 +350,33 @@
         "@lezer/lr": "^1.0.0"
       }
     },
+    "node_modules/@lezer/python": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@lezer/python/-/python-1.1.0.tgz",
+      "integrity": "sha512-FVPp2usfj3zZuc+2RidXAY94WAcsHQ3dbKDbXuZgoAwUungAcXwd3EWXiWQvwNqbae+ek51bWi8dwbiQqweWCg==",
+      "dependencies": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/rust": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/rust/-/rust-1.0.0.tgz",
+      "integrity": "sha512-IpGAxIjNxYmX9ra6GfQTSPegdCAWNeq23WNmrsMMQI7YNSvKtYxO4TX5rgZUmbhEucWn0KTBMeDEPXg99YKtTA==",
+      "dependencies": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/xml": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/xml/-/xml-1.0.0.tgz",
+      "integrity": "sha512-73iI9UK8iqSvWtLlOEl/g+50ivwQn8Ge6foHVN66AXUS1RccFnAoc7BYU8b3c8/rP6dfCOGqAGaWLxBzhj60MA==",
+      "dependencies": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
     "node_modules/ansi-regex": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
@@ -2186,6 +2298,15 @@
         "@lezer/common": "^1.0.0"
       }
     },
+    "@codemirror/lang-cpp": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-cpp/-/lang-cpp-6.0.1.tgz",
+      "integrity": "sha512-46p3ohfhjzkLWJ3VwvzX0aqlXh8UkEqX1xo2Eds9l6Ql3uDoxI2IZEjR9cgJaGOZTXCkDzQuQH7sfYAxMvzLjA==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/cpp": "^1.0.0"
+      }
+    },
     "@codemirror/lang-css": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.0.0.tgz",
@@ -2211,6 +2332,15 @@
         "@lezer/html": "^1.0.0"
       }
     },
+    "@codemirror/lang-java": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-java/-/lang-java-6.0.0.tgz",
+      "integrity": "sha512-aeWq+ikUS6Eubk6RBbiMgxuBIT4Ih8Asb1qc2pSiMcstrwr4ODbazPXsBHbLBYg3aObvFyOm2bNQncbQJjZ3sQ==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/java": "^1.0.0"
+      }
+    },
     "@codemirror/lang-javascript": {
       "version": "6.0.2",
       "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.0.2.tgz",
@@ -2259,6 +2389,48 @@
         "@lezer/php": "^1.0.0"
       }
     },
+    "@codemirror/lang-python": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.0.1.tgz",
+      "integrity": "sha512-w2jTSY+LgXnK7iIBLgMxk6xtJhZHkcxcGGveuq9zYmncURmOTFXKnDvBaBClNIHKgjkHXZqGK8ZduCMK23hZPA==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/python": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-rust": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-rust/-/lang-rust-6.0.0.tgz",
+      "integrity": "sha512-VQql3Qk1BwoXb3SUkeWll/EEwhsgQWc1bpia7CFqqp2PhQBb5A6r4Vj2JCkU/nE6A7TDPSGHTOoqJSG5s/VXtQ==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/rust": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-sql": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-sql/-/lang-sql-6.0.0.tgz",
+      "integrity": "sha512-mq4NwTDbbo7QZktfgPsS+ms0FmAceH4WM2jLbgf+N28FoKUy0JzGe3XJymgnTewXnNUwujKBxArQzibxSDdVyQ==",
+      "requires": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-xml": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-xml/-/lang-xml-6.0.0.tgz",
+      "integrity": "sha512-M/HLWxIiP956xGjtrxkeHkCmDGVQGKu782x8pOH5CLJIMkWtiB1DWfDoDHqpFjdEE9dkfcqPWvYfVi6GbhuXEg==",
+      "requires": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/xml": "^1.0.0"
+      }
+    },
     "@codemirror/language": {
       "version": "6.2.1",
       "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz",
@@ -2320,6 +2492,15 @@
       "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.0.tgz",
       "integrity": "sha512-ohydQe+Hb+w4oMDvXzs8uuJd2NoA3D8YDcLiuDsLqH+yflDTPEpgCsWI3/6rH5C3BAedtH1/R51dxENldQceEA=="
     },
+    "@lezer/cpp": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/cpp/-/cpp-1.0.0.tgz",
+      "integrity": "sha512-Klk3/AIEKoptmm6cNm7xTulNXjdTKkD+hVOEcz/NeRg8tIestP5hsGHJeFDR/XtyDTxsjoPjKZRIGohht7zbKw==",
+      "requires": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
     "@lezer/css": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.0.0.tgz",
@@ -2347,6 +2528,15 @@
         "@lezer/lr": "^1.0.0"
       }
     },
+    "@lezer/java": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/java/-/java-1.0.0.tgz",
+      "integrity": "sha512-z2EA0JHq2WoiKfQy5uOOd4t17PJtq8guh58gPkSzOnNcQ7DNbkrU+Axak+jL8+Noinwyz2tRNOseQFj+Tg+P0A==",
+      "requires": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
     "@lezer/javascript": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.0.2.tgz",
@@ -2391,6 +2581,33 @@
         "@lezer/lr": "^1.0.0"
       }
     },
+    "@lezer/python": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@lezer/python/-/python-1.1.0.tgz",
+      "integrity": "sha512-FVPp2usfj3zZuc+2RidXAY94WAcsHQ3dbKDbXuZgoAwUungAcXwd3EWXiWQvwNqbae+ek51bWi8dwbiQqweWCg==",
+      "requires": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "@lezer/rust": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/rust/-/rust-1.0.0.tgz",
+      "integrity": "sha512-IpGAxIjNxYmX9ra6GfQTSPegdCAWNeq23WNmrsMMQI7YNSvKtYxO4TX5rgZUmbhEucWn0KTBMeDEPXg99YKtTA==",
+      "requires": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "@lezer/xml": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/xml/-/xml-1.0.0.tgz",
+      "integrity": "sha512-73iI9UK8iqSvWtLlOEl/g+50ivwQn8Ge6foHVN66AXUS1RccFnAoc7BYU8b3c8/rP6dfCOGqAGaWLxBzhj60MA==",
+      "requires": {
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
     "ansi-regex": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
diff --git a/package.json b/package.json
index 4d2b70247..11e69962e 100644
--- a/package.json
+++ b/package.json
@@ -24,11 +24,18 @@
   },
   "dependencies": {
     "@codemirror/commands": "^6.0.1",
+    "@codemirror/lang-cpp": "^6.0.1",
+    "@codemirror/lang-css": "^6.0.0",
     "@codemirror/lang-html": "^6.1.0",
+    "@codemirror/lang-java": "^6.0.0",
     "@codemirror/lang-javascript": "^6.0.2",
     "@codemirror/lang-json": "^6.0.0",
     "@codemirror/lang-markdown": "^6.0.1",
     "@codemirror/lang-php": "^6.0.0",
+    "@codemirror/lang-python": "^6.0.1",
+    "@codemirror/lang-rust": "^6.0.0",
+    "@codemirror/lang-sql": "^6.0.0",
+    "@codemirror/lang-xml": "^6.0.0",
     "@codemirror/language": "^6.2.1",
     "@codemirror/legacy-modes": "^6.1.0",
     "@codemirror/state": "^6.1.0",
diff --git a/resources/js/code/languages.js b/resources/js/code/languages.js
index 4b04bdb14..b43b1c397 100644
--- a/resources/js/code/languages.js
+++ b/resources/js/code/languages.js
@@ -1,12 +1,14 @@
 import {StreamLanguage} from "@codemirror/language"
 
-import {css} from '@codemirror/legacy-modes/mode/css';
-import {c, java, cpp, csharp, kotlin, scala} from '@codemirror/legacy-modes/mode/clike';
+import {css} from '@codemirror/lang-css';
+import {c, csharp, kotlin, scala} from '@codemirror/legacy-modes/mode/clike';
+import {cpp} from '@codemirror/lang-cpp';
 import {diff} from '@codemirror/legacy-modes/mode/diff';
 import {fortran} from '@codemirror/legacy-modes/mode/fortran';
 import {go} from '@codemirror/legacy-modes/mode/go';
 import {haskell} from '@codemirror/legacy-modes/mode/haskell';
 import {html} from '@codemirror/lang-html';
+import {java} from '@codemirror/lang-java';
 import {javascript} from '@codemirror/lang-javascript';
 import {json} from '@codemirror/lang-json';
 import {julia} from '@codemirror/legacy-modes/mode/julia';
@@ -19,16 +21,16 @@ import {pascal} from '@codemirror/legacy-modes/mode/pascal';
 import {php} from '@codemirror/lang-php';
 import {powerShell} from '@codemirror/legacy-modes/mode/powershell';
 import {properties} from '@codemirror/legacy-modes/mode/properties';
-import {python} from '@codemirror/legacy-modes/mode/python';
+import {python} from '@codemirror/lang-python';
 import {ruby} from '@codemirror/legacy-modes/mode/ruby';
-import {rust} from '@codemirror/legacy-modes/mode/rust';
+import {rust} from '@codemirror/lang-rust';
 import {shell} from '@codemirror/legacy-modes/mode/shell';
-import {sql} from '@codemirror/legacy-modes/mode/sql';
+import {sql} from '@codemirror/lang-sql';
 import {stex} from '@codemirror/legacy-modes/mode/stex';
 import {toml} from '@codemirror/legacy-modes/mode/toml';
 import {vb} from '@codemirror/legacy-modes/mode/vb';
 import {vbScript} from '@codemirror/legacy-modes/mode/vbscript';
-import {xml} from '@codemirror/legacy-modes/mode/xml';
+import {xml} from '@codemirror/lang-xml';
 import {yaml} from '@codemirror/legacy-modes/mode/yaml';
 
 
@@ -37,12 +39,9 @@ import {yaml} from '@codemirror/legacy-modes/mode/yaml';
 // The function option is used in the event the exact mode could be dynamic depending on the code.
 const modeMap = {
     bash: () => StreamLanguage.define(shell),
-    css: () => StreamLanguage.define(css),
     c: () => StreamLanguage.define(c),
-    java: () => StreamLanguage.define(java),
-    scala: () => StreamLanguage.define(scala),
-    kotlin: () => StreamLanguage.define(kotlin),
-    'c++': () => StreamLanguage.define(cpp),
+    css: () => css(),
+    'c++': () => cpp(),
     'c#': () => StreamLanguage.define(csharp),
     csharp: () => StreamLanguage.define(csharp),
     diff: () => StreamLanguage.define(diff),
@@ -55,47 +54,50 @@ const modeMap = {
     hs: () => StreamLanguage.define(haskell),
     html: () => html(),
     ini: () => StreamLanguage.define(properties),
+    java: () => java(),
     javascript: () => javascript(),
     json: () => json(),
     js: () => javascript(),
     jl: () => StreamLanguage.define(julia),
     julia: () => StreamLanguage.define(julia),
+    kotlin: () => StreamLanguage.define(kotlin),
     latex: () => StreamLanguage.define(stex),
     lua: () => StreamLanguage.define(lua),
-    md: () => StreamLanguage.define(markdown),
-    mdown: () => StreamLanguage.define(markdown),
-    markdown: () => StreamLanguage.define(markdown),
+    markdown: () => markdown(),
+    md: () => markdown(),
+    mdown: () => markdown(),
     ml: () => StreamLanguage.define(sml),
     nginx: () => StreamLanguage.define(nginx),
-    perl: () => StreamLanguage.define(perl),
-    pl: () => StreamLanguage.define(perl),
-    powershell: () => StreamLanguage.define(powerShell),
-    properties: () => StreamLanguage.define(properties),
-    ocaml: () => StreamLanguage.define(oCaml),
-    pascal: () => StreamLanguage.define(pascal),
     pas: () => StreamLanguage.define(pascal),
+    pascal: () => StreamLanguage.define(pascal),
+    perl: () => StreamLanguage.define(perl),
     php: (code) => {
         const hasTags = code.includes('<?php');
         return php({plain: !hasTags});
     },
-    py: () => StreamLanguage.define(python),
-    python: () => StreamLanguage.define(python),
-    ruby: () => StreamLanguage.define(ruby),
-    rust: () => StreamLanguage.define(rust),
+    pl: () => StreamLanguage.define(perl),
+    powershell: () => StreamLanguage.define(powerShell),
+    properties: () => StreamLanguage.define(properties),
+    ocaml: () => StreamLanguage.define(oCaml),
+    py: () => python(),
+    python: () => python(),
     rb: () => StreamLanguage.define(ruby),
-    rs: () => StreamLanguage.define(rust),
+    rs: () => rust(),
+    ruby: () => StreamLanguage.define(ruby),
+    rust: () => rust(),
+    scala: () => StreamLanguage.define(scala),
     shell: () => StreamLanguage.define(shell),
     sh: () => StreamLanguage.define(shell),
     stext: () => StreamLanguage.define(stex),
     toml: () => StreamLanguage.define(toml),
     ts: () => javascript({typescript: true}),
     typescript: () => javascript({typescript: true}),
-    sql: () => StreamLanguage.define(sql),
+    sql: () => sql(),
     vbs: () => StreamLanguage.define(vbScript),
     vbscript: () => StreamLanguage.define(vbScript),
     'vb.net': () => StreamLanguage.define(vb),
     vbnet: () => StreamLanguage.define(vb),
-    xml: () => StreamLanguage.define(xml),
+    xml: () => xml(),
     yaml: () => StreamLanguage.define(yaml),
     yml: () => StreamLanguage.define(yaml),
 };

From 9fd7a6abedaf69efc449c7ea00724eb890fc71f7 Mon Sep 17 00:00:00 2001
From: Dan Brown <ssddanbrown@googlemail.com>
Date: Thu, 4 Aug 2022 14:19:04 +0100
Subject: [PATCH 4/4] Added dark theme handling

---
 package-lock.json          | 23 +++++++++++++++++++++++
 package.json               |  1 +
 resources/js/code/views.js | 23 +++++++++++++++++++++--
 3 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index a29be3324..8327421b3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,6 +21,7 @@
         "@codemirror/language": "^6.2.1",
         "@codemirror/legacy-modes": "^6.1.0",
         "@codemirror/state": "^6.1.0",
+        "@codemirror/theme-one-dark": "^6.0.0",
         "@codemirror/view": "^6.1.2",
         "clipboard": "^2.0.11",
         "codemirror": "^6.0.1",
@@ -246,6 +247,17 @@
       "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.1.0.tgz",
       "integrity": "sha512-qbUr94DZTe6/V1VS7LDLz11rM/1t/nJxR1El4I6UaxDEdc0aZZvq6JCLJWiRmUf95NRAnDH6fhXn+PWp9wGCIg=="
     },
+    "node_modules/@codemirror/theme-one-dark": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.0.0.tgz",
+      "integrity": "sha512-jTCfi1I8QT++3m21Ui6sU8qwu3F/hLv161KLxfvkV1cYWSBwyUanmQFs89ChobQjBHi2x7s2k71wF9WYvE8fdw==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/highlight": "^1.0.0"
+      }
+    },
     "node_modules/@codemirror/view": {
       "version": "6.1.2",
       "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.1.2.tgz",
@@ -2477,6 +2489,17 @@
       "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.1.0.tgz",
       "integrity": "sha512-qbUr94DZTe6/V1VS7LDLz11rM/1t/nJxR1El4I6UaxDEdc0aZZvq6JCLJWiRmUf95NRAnDH6fhXn+PWp9wGCIg=="
     },
+    "@codemirror/theme-one-dark": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.0.0.tgz",
+      "integrity": "sha512-jTCfi1I8QT++3m21Ui6sU8qwu3F/hLv161KLxfvkV1cYWSBwyUanmQFs89ChobQjBHi2x7s2k71wF9WYvE8fdw==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/highlight": "^1.0.0"
+      }
+    },
     "@codemirror/view": {
       "version": "6.1.2",
       "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.1.2.tgz",
diff --git a/package.json b/package.json
index 11e69962e..3a655c87a 100644
--- a/package.json
+++ b/package.json
@@ -39,6 +39,7 @@
     "@codemirror/language": "^6.2.1",
     "@codemirror/legacy-modes": "^6.1.0",
     "@codemirror/state": "^6.1.0",
+    "@codemirror/theme-one-dark": "^6.0.0",
     "@codemirror/view": "^6.1.2",
     "clipboard": "^2.0.11",
     "codemirror": "^6.0.1",
diff --git a/resources/js/code/views.js b/resources/js/code/views.js
index e87718939..cada9a1d6 100644
--- a/resources/js/code/views.js
+++ b/resources/js/code/views.js
@@ -1,18 +1,20 @@
-import {getLanguageExtension} from "./languages";
+import {getLanguageExtension} from "./languages"
 import {Compartment} from "@codemirror/state"
 import {EditorView} from "@codemirror/view"
+import {oneDark} from "@codemirror/theme-one-dark"
 
 const viewLangCompartments = new WeakMap();
 
 /**
  * Create a new editor view.
  *
- * @param {Object} config
+ * @param {{parent: Element, doc: String, extensions: Array}} config
  * @returns {EditorView}
  */
 export function createView(config) {
     const langCompartment = new Compartment();
     config.extensions.push(langCompartment.of([]));
+    config.extensions.push(getTheme(config.parent));
 
     const ev = new EditorView(config);
 
@@ -21,6 +23,23 @@ export function createView(config) {
     return ev;
 }
 
+/**
+ * Ge the theme extension to use for editor view instance.
+ * @returns {Extension}
+ */
+function getTheme(viewParentEl) {
+    const darkMode = document.documentElement.classList.contains('dark-mode');
+
+    const eventData = {
+        darkMode: darkMode,
+        theme: null,
+    };
+
+    window.$events.emitPublic(viewParentEl, 'library-cm6::configure-theme', eventData);
+
+    return eventData.theme || (darkMode ? oneDark : []);
+}
+
 /**
  * Set the language mode of an EditorView.
  *