diff --git a/smp-angular/package-lock.json b/smp-angular/package-lock.json
index e8963ca7c39b41638a20b1d936cb9b335bcd7683..dc520c05255fa5ce04de3d506740e620d0548081 100644
--- a/smp-angular/package-lock.json
+++ b/smp-angular/package-lock.json
@@ -24,9 +24,12 @@
         "@angular/platform-browser-dynamic": "^16.2.12",
         "@angular/platform-server": "^16.2.12",
         "@angular/router": "^16.2.12",
-        "@ctrl/ngx-codemirror": "^7.0.0",
+        "@codemirror/language": "^6.10.0",
+        "@codemirror/language-data": "^6.3.1",
+        "@codemirror/merge": "^6.5.0",
+        "@codemirror/theme-one-dark": "^6.1.2",
         "@swimlane/ngx-datatable": "^20.1.0",
-        "codemirror": "^5.65.16",
+        "codemirror": "^6.0.1",
         "file-saver": "^2.0.5",
         "rxjs": "^7.8.1",
         "ts-helpers": "^1.1.2",
@@ -286,12 +289,167 @@
         "semver": "bin/semver.js"
       }
     },
+    "node_modules/@angular-devkit/build-angular/node_modules/eslint-scope": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+      "dev": true,
+      "dependencies": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^4.1.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@angular-devkit/build-angular/node_modules/estraverse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/@angular-devkit/build-angular/node_modules/json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+      "dev": true
+    },
+    "node_modules/@angular-devkit/build-angular/node_modules/sass-loader": {
+      "version": "13.3.2",
+      "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.2.tgz",
+      "integrity": "sha512-CQbKl57kdEv+KDLquhC+gE3pXt74LEAzm+tzywcA0/aHZuub8wTErbjAoNI57rPUWRYRNC5WUnNl8eGJNbDdwg==",
+      "dev": true,
+      "dependencies": {
+        "neo-async": "^2.6.2"
+      },
+      "engines": {
+        "node": ">= 14.15.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "fibers": ">= 3.1.0",
+        "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0",
+        "sass": "^1.3.0",
+        "sass-embedded": "*",
+        "webpack": "^5.0.0"
+      },
+      "peerDependenciesMeta": {
+        "fibers": {
+          "optional": true
+        },
+        "node-sass": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "sass-embedded": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@angular-devkit/build-angular/node_modules/schema-utils": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+      "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+      "dev": true,
+      "dependencies": {
+        "@types/json-schema": "^7.0.8",
+        "ajv": "^6.12.5",
+        "ajv-keywords": "^3.5.2"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/@angular-devkit/build-angular/node_modules/schema-utils/node_modules/ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
+      }
+    },
+    "node_modules/@angular-devkit/build-angular/node_modules/schema-utils/node_modules/ajv-keywords": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+      "dev": true,
+      "peerDependencies": {
+        "ajv": "^6.9.1"
+      }
+    },
     "node_modules/@angular-devkit/build-angular/node_modules/tslib": {
       "version": "2.6.1",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz",
       "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==",
       "dev": true
     },
+    "node_modules/@angular-devkit/build-angular/node_modules/webpack": {
+      "version": "5.88.2",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz",
+      "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/eslint-scope": "^3.7.3",
+        "@types/estree": "^1.0.0",
+        "@webassemblyjs/ast": "^1.11.5",
+        "@webassemblyjs/wasm-edit": "^1.11.5",
+        "@webassemblyjs/wasm-parser": "^1.11.5",
+        "acorn": "^8.7.1",
+        "acorn-import-assertions": "^1.9.0",
+        "browserslist": "^4.14.5",
+        "chrome-trace-event": "^1.0.2",
+        "enhanced-resolve": "^5.15.0",
+        "es-module-lexer": "^1.2.1",
+        "eslint-scope": "5.1.1",
+        "events": "^3.2.0",
+        "glob-to-regexp": "^0.4.1",
+        "graceful-fs": "^4.2.9",
+        "json-parse-even-better-errors": "^2.3.1",
+        "loader-runner": "^4.2.0",
+        "mime-types": "^2.1.27",
+        "neo-async": "^2.6.2",
+        "schema-utils": "^3.2.0",
+        "tapable": "^2.1.1",
+        "terser-webpack-plugin": "^5.3.7",
+        "watchpack": "^2.4.0",
+        "webpack-sources": "^3.2.3"
+      },
+      "bin": {
+        "webpack": "bin/webpack.js"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependenciesMeta": {
+        "webpack-cli": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@angular-devkit/build-webpack": {
       "version": "0.1602.11",
       "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1602.11.tgz",
@@ -2614,6 +2772,339 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@codemirror/autocomplete": {
+      "version": "6.12.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.12.0.tgz",
+      "integrity": "sha512-r4IjdYFthwbCQyvqnSlx0WBHRHi8nBvU+WjJxFUij81qsBfhNudf/XKKmmC2j3m0LaOYUQTf3qiEK1J8lO1sdg==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.17.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.3.3",
+      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.3.3.tgz",
+      "integrity": "sha512-dO4hcF0fGT9tu1Pj1D2PvGvxjeGkbC6RGcZw6Qs74TH+Ed1gw98jmUgd2axWvIZEqTeTuFrg1lEB1KV6cK9h1A==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.4.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.1.0"
+      }
+    },
+    "node_modules/@codemirror/lang-angular": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-angular/-/lang-angular-0.1.3.tgz",
+      "integrity": "sha512-xgeWGJQQl1LyStvndWtruUvb4SnBZDAu/gvFH/ZU+c0W25tQR8e5hq7WTwiIY2dNxnf+49mRiGI/9yxIwB6f5w==",
+      "dependencies": {
+        "@codemirror/lang-html": "^6.0.0",
+        "@codemirror/lang-javascript": "^6.1.2",
+        "@codemirror/language": "^6.0.0",
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.3.3"
+      }
+    },
+    "node_modules/@codemirror/lang-cpp": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-cpp/-/lang-cpp-6.0.2.tgz",
+      "integrity": "sha512-6oYEYUKHvrnacXxWxYa6t4puTlbN3dgV662BDfSH8+MfjQjVmP697/KYTDOqpxgerkvoNm7q5wlFMBeX8ZMocg==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/cpp": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-css": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.2.1.tgz",
+      "integrity": "sha512-/UNWDNV5Viwi/1lpr/dIXJNWiwDxpw13I4pTUAsNxZdg6E0mI2kTQb0P2iHczg1Tu+H4EBgJR+hYhKiHKko7qg==",
+      "dependencies": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/common": "^1.0.2",
+        "@lezer/css": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-html": {
+      "version": "6.4.7",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.7.tgz",
+      "integrity": "sha512-y9hWSSO41XlcL4uYwWyk0lEgTHcelWWfRuqmvcAmxfCs0HNWZdriWo/EU43S63SxEZpc1Hd50Itw7ktfQvfkUg==",
+      "dependencies": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/lang-css": "^6.0.0",
+        "@codemirror/lang-javascript": "^6.0.0",
+        "@codemirror/language": "^6.4.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.17.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/css": "^1.1.0",
+        "@lezer/html": "^1.3.0"
+      }
+    },
+    "node_modules/@codemirror/lang-java": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-java/-/lang-java-6.0.1.tgz",
+      "integrity": "sha512-OOnmhH67h97jHzCuFaIEspbmsT98fNdhVhmA3zCxW0cn7l8rChDhZtwiwJ/JOKXgfm4J+ELxQihxaI7bj7mJRg==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/java": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-javascript": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.1.tgz",
+      "integrity": "sha512-jlFOXTejVyiQCW3EQwvKH0m99bUYIw40oPmFjSX2VS78yzfe0HELZ+NEo9Yfo1MkGRpGlj3Gnu4rdxV1EnAs5A==",
+      "dependencies": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/language": "^6.6.0",
+        "@codemirror/lint": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.17.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/javascript": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-json": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.1.tgz",
+      "integrity": "sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/json": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-less": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-less/-/lang-less-6.0.2.tgz",
+      "integrity": "sha512-EYdQTG22V+KUUk8Qq582g7FMnCZeEHsyuOJisHRft/mQ+ZSZ2w51NupvDUHiqtsOy7It5cHLPGfHQLpMh9bqpQ==",
+      "dependencies": {
+        "@codemirror/lang-css": "^6.2.0",
+        "@codemirror/language": "^6.0.0",
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-markdown": {
+      "version": "6.2.4",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.2.4.tgz",
+      "integrity": "sha512-UghkA1vSMs8bT7RSZM6vsIocigyah2bV00eRQuZy76401UmFZdsTsbQNBGdyxRQDOLeEvF5iFwap0BM8LKyd+g==",
+      "dependencies": {
+        "@codemirror/autocomplete": "^6.7.1",
+        "@codemirror/lang-html": "^6.0.0",
+        "@codemirror/language": "^6.3.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.2.1",
+        "@lezer/markdown": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-php": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-php/-/lang-php-6.0.1.tgz",
+      "integrity": "sha512-ublojMdw/PNWa7qdN5TMsjmqkNuTBD3k6ndZ4Z0S25SBAiweFGyY68AS3xNcIOlb6DDFDvKlinLQ40vSLqf8xA==",
+      "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/lang-python": {
+      "version": "6.1.3",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.1.3.tgz",
+      "integrity": "sha512-S9w2Jl74hFlD5nqtUMIaXAq9t5WlM0acCkyuQWUUSvZclk1sV+UfnpFiZzuZSG+hfEaOmxKR5UxY/Uxswn7EhQ==",
+      "dependencies": {
+        "@codemirror/autocomplete": "^6.3.2",
+        "@codemirror/language": "^6.8.0",
+        "@lezer/python": "^1.1.4"
+      }
+    },
+    "node_modules/@codemirror/lang-rust": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-rust/-/lang-rust-6.0.1.tgz",
+      "integrity": "sha512-344EMWFBzWArHWdZn/NcgkwMvZIWUR1GEBdwG8FEp++6o6vT6KL9V7vGs2ONsKxxFUPXKI0SPcWhyYyl2zPYxQ==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/rust": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-sass": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-sass/-/lang-sass-6.0.2.tgz",
+      "integrity": "sha512-l/bdzIABvnTo1nzdY6U+kPAC51czYQcOErfzQ9zSm9D8GmNPD0WTW8st/CJwBTPLO8jlrbyvlSEcN20dc4iL0Q==",
+      "dependencies": {
+        "@codemirror/lang-css": "^6.2.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/common": "^1.0.2",
+        "@lezer/sass": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-sql": {
+      "version": "6.5.5",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-sql/-/lang-sql-6.5.5.tgz",
+      "integrity": "sha512-DvOaP2RXLb2xlxJxxydTFfwyYw5YDqEFea6aAfgh9UH0kUD6J1KFZ0xPgPpw1eo/5s2w3L6uh5PVR7GM23GxkQ==",
+      "dependencies": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-vue": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-vue/-/lang-vue-0.1.3.tgz",
+      "integrity": "sha512-QSKdtYTDRhEHCfo5zOShzxCmqKJvgGrZwDQSdbvCRJ5pRLWBS7pD/8e/tH44aVQT6FKm0t6RVNoSUWHOI5vNug==",
+      "dependencies": {
+        "@codemirror/lang-html": "^6.0.0",
+        "@codemirror/lang-javascript": "^6.1.2",
+        "@codemirror/language": "^6.0.0",
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.3.1"
+      }
+    },
+    "node_modules/@codemirror/lang-wast": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-wast/-/lang-wast-6.0.2.tgz",
+      "integrity": "sha512-Imi2KTpVGm7TKuUkqyJ5NRmeFWF7aMpNiwHnLQe0x9kmrxElndyH0K6H/gXtWwY6UshMRAhpENsgfpSwsgmC6Q==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/lang-xml": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-xml/-/lang-xml-6.0.2.tgz",
+      "integrity": "sha512-JQYZjHL2LAfpiZI2/qZ/qzDuSqmGKMwyApYmEUUCTxLM4MWS7sATUEfIguZQr9Zjx/7gcdnewb039smF6nC2zw==",
+      "dependencies": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/language": "^6.4.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/xml": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/language": {
+      "version": "6.10.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.0.tgz",
+      "integrity": "sha512-2vaNn9aPGCRFKWcHPFksctzJ8yS5p7YoaT+jHpc0UGKzNuAIx4qy6R5wiqbP+heEEdyaABA582mNqSHzSoYdmg==",
+      "dependencies": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.23.0",
+        "@lezer/common": "^1.1.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0",
+        "style-mod": "^4.0.0"
+      }
+    },
+    "node_modules/@codemirror/language-data": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/language-data/-/language-data-6.3.1.tgz",
+      "integrity": "sha512-p6jhJmvhGe1TG1EGNhwH7nFWWFSTJ8NDKnB2fVx5g3t+PpO0+63R7GJNxjS0TmmH3cdMxZbzejsik+rlEh1EyQ==",
+      "dependencies": {
+        "@codemirror/lang-angular": "^0.1.0",
+        "@codemirror/lang-cpp": "^6.0.0",
+        "@codemirror/lang-css": "^6.0.0",
+        "@codemirror/lang-html": "^6.0.0",
+        "@codemirror/lang-java": "^6.0.0",
+        "@codemirror/lang-javascript": "^6.0.0",
+        "@codemirror/lang-json": "^6.0.0",
+        "@codemirror/lang-less": "^6.0.0",
+        "@codemirror/lang-markdown": "^6.0.0",
+        "@codemirror/lang-php": "^6.0.0",
+        "@codemirror/lang-python": "^6.0.0",
+        "@codemirror/lang-rust": "^6.0.0",
+        "@codemirror/lang-sass": "^6.0.0",
+        "@codemirror/lang-sql": "^6.0.0",
+        "@codemirror/lang-vue": "^0.1.1",
+        "@codemirror/lang-wast": "^6.0.0",
+        "@codemirror/lang-xml": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/legacy-modes": "^6.1.0"
+      }
+    },
+    "node_modules/@codemirror/legacy-modes": {
+      "version": "6.3.3",
+      "resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.3.3.tgz",
+      "integrity": "sha512-X0Z48odJ0KIoh/HY8Ltz75/4tDYc9msQf1E/2trlxFaFFhgjpVHjZ/BCXe1Lk7s4Gd67LL/CeEEHNI+xHOiESg==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0"
+      }
+    },
+    "node_modules/@codemirror/lint": {
+      "version": "6.4.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.4.2.tgz",
+      "integrity": "sha512-wzRkluWb1ptPKdzlsrbwwjYCPLgzU6N88YBAmlZi8WFyuiEduSd05MnJYNogzyc8rPK7pj6m95ptUApc8sHKVA==",
+      "dependencies": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "crelt": "^1.0.5"
+      }
+    },
+    "node_modules/@codemirror/merge": {
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/merge/-/merge-6.5.0.tgz",
+      "integrity": "sha512-Am88bwcZFrVM84M7x+Njq3X1TSNXqEdOjp7iFI+45KDG+zJUA1gTkJxzGtrTKBKK7gL1Q0/tihpGQBlZOZCO/w==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.17.0",
+        "@lezer/highlight": "^1.0.0",
+        "style-mod": "^4.1.0"
+      }
+    },
+    "node_modules/@codemirror/search": {
+      "version": "6.5.5",
+      "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.5.tgz",
+      "integrity": "sha512-PIEN3Ke1buPod2EHbJsoQwlbpkz30qGZKcnmH1eihq9+bPQx8gelauUwLYaY4vBOuBAuEhmpDLii4rj/uO0yMA==",
+      "dependencies": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "crelt": "^1.0.5"
+      }
+    },
+    "node_modules/@codemirror/state": {
+      "version": "6.4.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.0.tgz",
+      "integrity": "sha512-hm8XshYj5Fo30Bb922QX9hXB/bxOAVH+qaqHBzw5TKa72vOeslyGwd4X8M0c1dJ9JqxlaMceOQ8RsL9tC7gU0A=="
+    },
+    "node_modules/@codemirror/theme-one-dark": {
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz",
+      "integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==",
+      "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.23.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.23.0.tgz",
+      "integrity": "sha512-/51px9N4uW8NpuWkyUX+iam5+PM6io2fm+QmRnzwqBy5v/pwGg9T0kILFtYeum8hjuvENtgsGNKluOfqIICmeQ==",
+      "dependencies": {
+        "@codemirror/state": "^6.4.0",
+        "style-mod": "^4.1.0",
+        "w3c-keyname": "^2.2.4"
+      }
+    },
     "node_modules/@colors/colors": {
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
@@ -2623,20 +3114,6 @@
         "node": ">=0.1.90"
       }
     },
-    "node_modules/@ctrl/ngx-codemirror": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@ctrl/ngx-codemirror/-/ngx-codemirror-7.0.0.tgz",
-      "integrity": "sha512-qvIWtSTw/8fdXDnofBTX6LmTW9646HhawG2+Qyagf1vH40jCy0ZbHnkC20UYOVpUX+QCd1e/PQpkvWQ/1iGFzQ==",
-      "dependencies": {
-        "@types/codemirror": "^5.60.7",
-        "tslib": "^2.3.0"
-      },
-      "peerDependencies": {
-        "@angular/core": ">=16.0.0-0",
-        "@angular/forms": ">=16.0.0-0",
-        "codemirror": "^5.65.9"
-      }
-    },
     "node_modules/@discoveryjs/json-ext": {
       "version": "0.5.7",
       "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
@@ -3330,13 +3807,13 @@
       "dev": true
     },
     "node_modules/@jridgewell/trace-mapping": {
-      "version": "0.3.17",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
-      "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+      "version": "0.3.22",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz",
+      "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/resolve-uri": "3.1.0",
-        "@jridgewell/sourcemap-codec": "1.4.14"
+        "@jridgewell/resolve-uri": "^3.1.0",
+        "@jridgewell/sourcemap-codec": "^1.4.14"
       }
     },
     "node_modules/@leichtgewicht/ip-codec": {
@@ -3345,15 +3822,155 @@
       "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
       "dev": true
     },
-    "node_modules/@material/animation": {
-      "version": "15.0.0-canary.bc9ae6c9c.0",
-      "resolved": "https://registry.npmjs.org/@material/animation/-/animation-15.0.0-canary.bc9ae6c9c.0.tgz",
-      "integrity": "sha512-leRf+BcZTfC/iSigLXnYgcHAGvFVQveoJT5+2PIRdyPI/bIG7hhciRgacHRsCKC0sGya81dDblLgdkjSUemYLw==",
+    "node_modules/@lezer/common": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz",
+      "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ=="
+    },
+    "node_modules/@lezer/cpp": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@lezer/cpp/-/cpp-1.1.2.tgz",
+      "integrity": "sha512-macwKtyeUO0EW86r3xWQCzOV9/CF8imJLpJlPv3sDY57cPGeUZ8gXWOWNlJr52TVByMV3PayFQCA5SHEERDmVQ==",
       "dependencies": {
-        "tslib": "^2.1.0"
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
       }
     },
-    "node_modules/@material/auto-init": {
+    "node_modules/@lezer/css": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.7.tgz",
+      "integrity": "sha512-7BlFFAKNn/b39jJLrhdLSX5A2k56GIJvyLqdmm7UU+7XvequY084iuKDMAEhAmAzHnwDE8FK4OQtsIUssW91tg==",
+      "dependencies": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/highlight": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz",
+      "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==",
+      "dependencies": {
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/html": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.8.tgz",
+      "integrity": "sha512-EXseJ3pUzWxE6XQBQdqWHZqqlGQRSuNMBcLb6mZWS2J2v+QZhOObD+3ZIKIcm59ntTzyor4LqFTb72iJc3k23Q==",
+      "dependencies": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/java": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@lezer/java/-/java-1.1.1.tgz",
+      "integrity": "sha512-mt3dX13fRlpY7RlWELYRakanXgmwXsLRCrhstrn+c1sZd7jR2xle46/3heoxGd+oHxnuTnpoyXTyxcLJQs9+mQ==",
+      "dependencies": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/javascript": {
+      "version": "1.4.13",
+      "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.13.tgz",
+      "integrity": "sha512-5IBr8LIO3xJdJH1e9aj/ZNLE4LSbdsx25wFmGRAZsj2zSmwAYjx26JyU/BYOCpRQlu1jcv1z3vy4NB9+UkfRow==",
+      "dependencies": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.1.3",
+        "@lezer/lr": "^1.3.0"
+      }
+    },
+    "node_modules/@lezer/json": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.2.tgz",
+      "integrity": "sha512-xHT2P4S5eeCYECyKNPhr4cbEL9tc8w83SPwRC373o9uEdrvGKTZoJVAGxpOsZckMlEh9W23Pc72ew918RWQOBQ==",
+      "dependencies": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/lr": {
+      "version": "1.3.14",
+      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.3.14.tgz",
+      "integrity": "sha512-z5mY4LStlA3yL7aHT/rqgG614cfcvklS+8oFRFBYrs4YaWLJyKKM4+nN6KopToX0o9Hj6zmH6M5kinOYuy06ug==",
+      "dependencies": {
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/markdown": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.2.0.tgz",
+      "integrity": "sha512-d7MwsfAukZJo1GpPrcPGa3MxaFFOqNp0gbqF+3F7pTeNDOgeJN1muXzx1XXDPt+Ac+/voCzsH7qXqnn+xReG/g==",
+      "dependencies": {
+        "@lezer/common": "^1.0.0",
+        "@lezer/highlight": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/php": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@lezer/php/-/php-1.0.2.tgz",
+      "integrity": "sha512-GN7BnqtGRpFyeoKSEqxvGvhJQiI4zkgmYnDk/JIyc7H7Ifc1tkPnUn/R2R8meH3h/aBf5rzjvU8ZQoyiNDtDrA==",
+      "dependencies": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.1.0"
+      }
+    },
+    "node_modules/@lezer/python": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/@lezer/python/-/python-1.1.11.tgz",
+      "integrity": "sha512-C3QeLCcdAKJDUOsYjfFP6a1wdn8jhUNX200bgFm8TpKH1eM2PlgYQS5ugw6E38qGeEx7CP21I1Q52SoybXt0OQ==",
+      "dependencies": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/rust": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@lezer/rust/-/rust-1.0.2.tgz",
+      "integrity": "sha512-Lz5sIPBdF2FUXcWeCu1//ojFAZqzTQNRga0aYv6dYXqJqPfMdCAI0NzajWUd4Xijj1IKJLtjoXRPMvTKWBcqKg==",
+      "dependencies": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/sass": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/@lezer/sass/-/sass-1.0.4.tgz",
+      "integrity": "sha512-AqW4myvp73sbMk6y0+gJrMjN5xtqFZzqTftzO3YcO8gSL5d3pymIP3deQllAI8+s1ZoSzH6kD4hsoFLpkD9Kfg==",
+      "dependencies": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/xml": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/@lezer/xml/-/xml-1.0.4.tgz",
+      "integrity": "sha512-WmXKb5eX8+rRfZYSNRR5TPee/ZoDgBdVS/rj1VCJGDKa5gNldIctQYibCoFVyNhvZsyL/8nHbZJZPM4gnXN2Vw==",
+      "dependencies": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "node_modules/@material/animation": {
+      "version": "15.0.0-canary.bc9ae6c9c.0",
+      "resolved": "https://registry.npmjs.org/@material/animation/-/animation-15.0.0-canary.bc9ae6c9c.0.tgz",
+      "integrity": "sha512-leRf+BcZTfC/iSigLXnYgcHAGvFVQveoJT5+2PIRdyPI/bIG7hhciRgacHRsCKC0sGya81dDblLgdkjSUemYLw==",
+      "dependencies": {
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/@material/auto-init": {
       "version": "15.0.0-canary.bc9ae6c9c.0",
       "resolved": "https://registry.npmjs.org/@material/auto-init/-/auto-init-15.0.0-canary.bc9ae6c9c.0.tgz",
       "integrity": "sha512-uxzDq7q3c0Bu1pAsMugc1Ik9ftQYQqZY+5e2ybNplT8gTImJhNt4M2mMiMHbMANk2l3UgICmUyRSomgPBWCPIA==",
@@ -4684,14 +5301,6 @@
         "@types/node": "*"
       }
     },
-    "node_modules/@types/codemirror": {
-      "version": "5.60.7",
-      "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.7.tgz",
-      "integrity": "sha512-QXIC+RPzt/1BGSuD6iFn6UMC9TDp+9hkOANYNPVsjjrDdzKphfRkwQDKGp2YaC54Yhz0g6P5uYTCCibZZEiMAA==",
-      "dependencies": {
-        "@types/tern": "*"
-      }
-    },
     "node_modules/@types/connect": {
       "version": "3.4.38",
       "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
@@ -4747,9 +5356,10 @@
       }
     },
     "node_modules/@types/estree": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
-      "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ=="
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+      "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
+      "dev": true
     },
     "node_modules/@types/express": {
       "version": "4.17.21",
@@ -4814,6 +5424,14 @@
       "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
       "dev": true
     },
+    "node_modules/@types/minimist": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz",
+      "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
     "node_modules/@types/node": {
       "version": "18.15.6",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.6.tgz",
@@ -4829,6 +5447,14 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/normalize-package-data": {
+      "version": "2.4.4",
+      "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
+      "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
     "node_modules/@types/q": {
       "version": "0.0.32",
       "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz",
@@ -4908,14 +5534,6 @@
         "@types/node": "*"
       }
     },
-    "node_modules/@types/tern": {
-      "version": "0.23.4",
-      "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.4.tgz",
-      "integrity": "sha512-JAUw1iXGO1qaWwEOzxTKJZ/5JxVeON9kvGZ/osgZaJImBnyjyn0cjovPsf6FNLmyGY8Vw9DoXZCMlfMkMwHRWg==",
-      "dependencies": {
-        "@types/estree": "*"
-      }
-    },
     "node_modules/@types/ws": {
       "version": "8.5.10",
       "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz",
@@ -5568,6 +6186,17 @@
         "node": ">=0.8"
       }
     },
+    "node_modules/async-foreach": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
+      "integrity": "sha512-VUeSMD8nEGBWaZK4lizI1sf3yEC7pnAQ/mrI7pC2fBz2s/tq5jWWEngTwaf0Gruu/OoXRGLGg1XFqpYBiGTYJA==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -6094,6 +6723,25 @@
         "node": ">=6"
       }
     },
+    "node_modules/camelcase-keys": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz",
+      "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "camelcase": "^5.3.1",
+        "map-obj": "^4.0.0",
+        "quick-lru": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/caniuse-lite": {
       "version": "1.0.30001566",
       "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz",
@@ -6267,9 +6915,18 @@
       }
     },
     "node_modules/codemirror": {
-      "version": "5.65.16",
-      "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.16.tgz",
-      "integrity": "sha512-br21LjYmSlVL0vFCPWPfhzUCT34FM/pAdK7rRIZwa0rrtrIdotvP4Oh4GUHsu2E3IrQMCfRkL/fN3ytMNxVQvg=="
+      "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",
@@ -6617,6 +7274,11 @@
         "js-yaml": "bin/js-yaml.js"
       }
     },
+    "node_modules/crelt": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
+      "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g=="
+    },
     "node_modules/critters": {
       "version": "0.0.20",
       "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.20.tgz",
@@ -6883,6 +7545,35 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/decamelize-keys": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
+      "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "decamelize": "^1.1.0",
+        "map-obj": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/decamelize-keys/node_modules/map-obj": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+      "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/decimal.js": {
       "version": "10.4.3",
       "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
@@ -8483,6 +9174,20 @@
         "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
       }
     },
+    "node_modules/gaze": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
+      "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "globule": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
     "node_modules/gensync": {
       "version": "1.0.0-beta.2",
       "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -8524,6 +9229,17 @@
         "node": ">=8.0.0"
       }
     },
+    "node_modules/get-stdin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+      "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/get-stream": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
@@ -8639,6 +9355,58 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/globule": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz",
+      "integrity": "sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "glob": "~7.1.1",
+        "lodash": "^4.17.21",
+        "minimatch": "~3.0.2"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/globule/node_modules/glob": {
+      "version": "7.1.7",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+      "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/globule/node_modules/minimatch": {
+      "version": "3.0.8",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
+      "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/graceful-fs": {
       "version": "4.2.11",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -8731,6 +9499,17 @@
       "optional": true,
       "peer": true
     },
+    "node_modules/hard-rejection": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
+      "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/has": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -9835,6 +10614,14 @@
         "jiti": "bin/jiti.js"
       }
     },
+    "node_modules/js-base64": {
+      "version": "2.6.4",
+      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
+      "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
     "node_modules/js-sdsl": {
       "version": "4.4.0",
       "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz",
@@ -10919,6 +11706,20 @@
       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
       "dev": true
     },
+    "node_modules/map-obj": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
+      "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/media-typer": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -10940,51 +11741,157 @@
         "node": ">= 4.0.0"
       }
     },
-    "node_modules/merge-descriptors": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
-      "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==",
-      "dev": true
-    },
-    "node_modules/merge-stream": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
-      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
-      "dev": true
-    },
-    "node_modules/merge2": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
-      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/methods": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
-      "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+    "node_modules/meow": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz",
+      "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "@types/minimist": "^1.2.0",
+        "camelcase-keys": "^6.2.2",
+        "decamelize": "^1.2.0",
+        "decamelize-keys": "^1.1.0",
+        "hard-rejection": "^2.1.0",
+        "minimist-options": "4.1.0",
+        "normalize-package-data": "^3.0.0",
+        "read-pkg-up": "^7.0.1",
+        "redent": "^3.0.0",
+        "trim-newlines": "^3.0.0",
+        "type-fest": "^0.18.0",
+        "yargs-parser": "^20.2.3"
+      },
       "engines": {
-        "node": ">= 0.6"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/micromatch": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
-      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+    "node_modules/meow/node_modules/hosted-git-info": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+      "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
-        "braces": "^3.0.2",
-        "picomatch": "^2.3.1"
+        "lru-cache": "^6.0.0"
       },
       "engines": {
-        "node": ">=8.6"
+        "node": ">=10"
       }
     },
-    "node_modules/mime": {
-      "version": "2.6.0",
+    "node_modules/meow/node_modules/lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/meow/node_modules/normalize-package-data": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
+      "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "hosted-git-info": "^4.0.1",
+        "is-core-module": "^2.5.0",
+        "semver": "^7.3.4",
+        "validate-npm-package-license": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/meow/node_modules/type-fest": {
+      "version": "0.18.1",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
+      "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/meow/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
+    "node_modules/meow/node_modules/yargs-parser": {
+      "version": "20.2.9",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/merge-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+      "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==",
+      "dev": true
+    },
+    "node_modules/merge-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "dev": true
+    },
+    "node_modules/merge2": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/micromatch": {
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+      "dev": true,
+      "dependencies": {
+        "braces": "^3.0.2",
+        "picomatch": "^2.3.1"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/mime": {
+      "version": "2.6.0",
       "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
       "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
       "dev": true,
@@ -11025,6 +11932,17 @@
         "node": ">=6"
       }
     },
+    "node_modules/min-indent": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
+      "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/mini-css-extract-plugin": {
       "version": "2.7.6",
       "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz",
@@ -11071,6 +11989,33 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/minimist-options": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
+      "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "arrify": "^1.0.1",
+        "is-plain-obj": "^1.1.0",
+        "kind-of": "^6.0.3"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/minimist-options/node_modules/is-plain-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+      "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/minipass": {
       "version": "7.0.4",
       "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
@@ -11331,6 +12276,14 @@
       "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
       "dev": true
     },
+    "node_modules/nan": {
+      "version": "2.18.0",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz",
+      "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
     "node_modules/nanoid": {
       "version": "3.3.7",
       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
@@ -12003,117 +12956,532 @@
       "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
       "dev": true
     },
-    "node_modules/nopt": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz",
-      "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==",
+    "node_modules/node-sass": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-9.0.0.tgz",
+      "integrity": "sha512-yltEuuLrfH6M7Pq2gAj5B6Zm7m+gdZoG66wTqG6mIZV/zijq3M2OO2HswtT6oBspPyFhHDcaxWpsBm0fRNDHPg==",
       "dev": true,
+      "hasInstallScript": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
-        "abbrev": "^1.0.0"
+        "async-foreach": "^0.1.3",
+        "chalk": "^4.1.2",
+        "cross-spawn": "^7.0.3",
+        "gaze": "^1.0.0",
+        "get-stdin": "^4.0.1",
+        "glob": "^7.0.3",
+        "lodash": "^4.17.15",
+        "make-fetch-happen": "^10.0.4",
+        "meow": "^9.0.0",
+        "nan": "^2.17.0",
+        "node-gyp": "^8.4.1",
+        "sass-graph": "^4.0.1",
+        "stdout-stream": "^1.4.0",
+        "true-case-path": "^2.2.1"
       },
       "bin": {
-        "nopt": "bin/nopt.js"
+        "node-sass": "bin/node-sass"
       },
       "engines": {
-        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+        "node": ">=16"
       }
     },
-    "node_modules/normalize-package-data": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz",
-      "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==",
+    "node_modules/node-sass/node_modules/@npmcli/fs": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
+      "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
-        "hosted-git-info": "^6.0.0",
-        "is-core-module": "^2.8.1",
-        "semver": "^7.3.5",
-        "validate-npm-package-license": "^3.0.4"
-      },
-      "engines": {
-        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
-      }
-    },
-    "node_modules/normalize-path": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
-      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/normalize-range": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
-      "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
+        "@gar/promisify": "^1.0.1",
+        "semver": "^7.3.5"
       }
     },
-    "node_modules/npm-bundled": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.0.tgz",
-      "integrity": "sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==",
+    "node_modules/node-sass/node_modules/@npmcli/move-file": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
+      "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
+      "deprecated": "This functionality has been moved to @npmcli/fs",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
-        "npm-normalize-package-bin": "^3.0.0"
+        "mkdirp": "^1.0.4",
+        "rimraf": "^3.0.2"
       },
       "engines": {
-        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+        "node": ">=10"
       }
     },
-    "node_modules/npm-install-checks": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz",
-      "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==",
+    "node_modules/node-sass/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
-        "semver": "^7.1.1"
+        "color-convert": "^2.0.1"
       },
       "engines": {
-        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
-    "node_modules/npm-normalize-package-bin": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz",
-      "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==",
+    "node_modules/node-sass/node_modules/cacache": {
+      "version": "15.3.0",
+      "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
+      "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "@npmcli/fs": "^1.0.0",
+        "@npmcli/move-file": "^1.0.1",
+        "chownr": "^2.0.0",
+        "fs-minipass": "^2.0.0",
+        "glob": "^7.1.4",
+        "infer-owner": "^1.0.4",
+        "lru-cache": "^6.0.0",
+        "minipass": "^3.1.1",
+        "minipass-collect": "^1.0.2",
+        "minipass-flush": "^1.0.5",
+        "minipass-pipeline": "^1.2.2",
+        "mkdirp": "^1.0.3",
+        "p-map": "^4.0.0",
+        "promise-inflight": "^1.0.1",
+        "rimraf": "^3.0.2",
+        "ssri": "^8.0.1",
+        "tar": "^6.0.2",
+        "unique-filename": "^1.1.1"
+      },
       "engines": {
-        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+        "node": ">= 10"
       }
     },
-    "node_modules/npm-package-arg": {
-      "version": "10.1.0",
-      "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz",
-      "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==",
+    "node_modules/node-sass/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
-        "hosted-git-info": "^6.0.0",
-        "proc-log": "^3.0.0",
-        "semver": "^7.3.5",
-        "validate-npm-package-name": "^5.0.0"
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
       },
       "engines": {
-        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
-    "node_modules/npm-packlist": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz",
-      "integrity": "sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==",
+    "node_modules/node-sass/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
-        "ignore-walk": "^6.0.0"
+        "color-name": "~1.1.4"
       },
       "engines": {
-        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+        "node": ">=7.0.0"
       }
     },
-    "node_modules/npm-pick-manifest": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.1.tgz",
+    "node_modules/node-sass/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
+    "node_modules/node-sass/node_modules/fs-minipass": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+      "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "minipass": "^3.0.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/node-sass/node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/node-sass/node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/node-sass/node_modules/lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/node-sass/node_modules/minipass": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/node-sass/node_modules/minipass-collect": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
+      "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "minipass": "^3.0.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/node-sass/node_modules/minipass-fetch": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
+      "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "minipass": "^3.1.0",
+        "minipass-sized": "^1.0.3",
+        "minizlib": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "optionalDependencies": {
+        "encoding": "^0.1.12"
+      }
+    },
+    "node_modules/node-sass/node_modules/mkdirp": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "bin": {
+        "mkdirp": "bin/cmd.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/node-sass/node_modules/node-gyp": {
+      "version": "8.4.1",
+      "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz",
+      "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "env-paths": "^2.2.0",
+        "glob": "^7.1.4",
+        "graceful-fs": "^4.2.6",
+        "make-fetch-happen": "^9.1.0",
+        "nopt": "^5.0.0",
+        "npmlog": "^6.0.0",
+        "rimraf": "^3.0.2",
+        "semver": "^7.3.5",
+        "tar": "^6.1.2",
+        "which": "^2.0.2"
+      },
+      "bin": {
+        "node-gyp": "bin/node-gyp.js"
+      },
+      "engines": {
+        "node": ">= 10.12.0"
+      }
+    },
+    "node_modules/node-sass/node_modules/node-gyp/node_modules/make-fetch-happen": {
+      "version": "9.1.0",
+      "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
+      "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "agentkeepalive": "^4.1.3",
+        "cacache": "^15.2.0",
+        "http-cache-semantics": "^4.1.0",
+        "http-proxy-agent": "^4.0.1",
+        "https-proxy-agent": "^5.0.0",
+        "is-lambda": "^1.0.1",
+        "lru-cache": "^6.0.0",
+        "minipass": "^3.1.3",
+        "minipass-collect": "^1.0.2",
+        "minipass-fetch": "^1.3.2",
+        "minipass-flush": "^1.0.5",
+        "minipass-pipeline": "^1.2.4",
+        "negotiator": "^0.6.2",
+        "promise-retry": "^2.0.1",
+        "socks-proxy-agent": "^6.0.0",
+        "ssri": "^8.0.0"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/node-sass/node_modules/nopt": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
+      "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "abbrev": "1"
+      },
+      "bin": {
+        "nopt": "bin/nopt.js"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/node-sass/node_modules/socks-proxy-agent": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz",
+      "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "agent-base": "^6.0.2",
+        "debug": "^4.3.3",
+        "socks": "^2.6.2"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/node-sass/node_modules/ssri": {
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
+      "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "minipass": "^3.1.1"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/node-sass/node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/node-sass/node_modules/unique-filename": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+      "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "unique-slug": "^2.0.0"
+      }
+    },
+    "node_modules/node-sass/node_modules/unique-slug": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
+      "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "imurmurhash": "^0.1.4"
+      }
+    },
+    "node_modules/node-sass/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
+    "node_modules/nopt": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz",
+      "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==",
+      "dev": true,
+      "dependencies": {
+        "abbrev": "^1.0.0"
+      },
+      "bin": {
+        "nopt": "bin/nopt.js"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+      }
+    },
+    "node_modules/normalize-package-data": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz",
+      "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==",
+      "dev": true,
+      "dependencies": {
+        "hosted-git-info": "^6.0.0",
+        "is-core-module": "^2.8.1",
+        "semver": "^7.3.5",
+        "validate-npm-package-license": "^3.0.4"
+      },
+      "engines": {
+        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+      }
+    },
+    "node_modules/normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/normalize-range": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+      "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/npm-bundled": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.0.tgz",
+      "integrity": "sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==",
+      "dev": true,
+      "dependencies": {
+        "npm-normalize-package-bin": "^3.0.0"
+      },
+      "engines": {
+        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+      }
+    },
+    "node_modules/npm-install-checks": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz",
+      "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==",
+      "dev": true,
+      "dependencies": {
+        "semver": "^7.1.1"
+      },
+      "engines": {
+        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+      }
+    },
+    "node_modules/npm-normalize-package-bin": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz",
+      "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==",
+      "dev": true,
+      "engines": {
+        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+      }
+    },
+    "node_modules/npm-package-arg": {
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz",
+      "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==",
+      "dev": true,
+      "dependencies": {
+        "hosted-git-info": "^6.0.0",
+        "proc-log": "^3.0.0",
+        "semver": "^7.3.5",
+        "validate-npm-package-name": "^5.0.0"
+      },
+      "engines": {
+        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+      }
+    },
+    "node_modules/npm-packlist": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz",
+      "integrity": "sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==",
+      "dev": true,
+      "dependencies": {
+        "ignore-walk": "^6.0.0"
+      },
+      "engines": {
+        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+      }
+    },
+    "node_modules/npm-pick-manifest": {
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.1.tgz",
       "integrity": "sha512-mRtvlBjTsJvfCCdmPtiu2bdlx8d/KXtF7yNXNWe7G0Z36qWA9Ny5zXsI2PfBZEv7SXgoxTmNaTzGSbbzDZChoA==",
       "dev": true,
       "dependencies": {
@@ -13738,6 +15106,17 @@
         }
       ]
     },
+    "node_modules/quick-lru": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
+      "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/randombytes": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -13817,6 +15196,97 @@
         "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
       }
     },
+    "node_modules/read-pkg": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
+      "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "@types/normalize-package-data": "^2.4.0",
+        "normalize-package-data": "^2.5.0",
+        "parse-json": "^5.0.0",
+        "type-fest": "^0.6.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
+      "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "find-up": "^4.1.0",
+        "read-pkg": "^5.2.0",
+        "type-fest": "^0.8.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/type-fest": {
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg/node_modules/hosted-git-info": {
+      "version": "2.8.9",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+      "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
+    "node_modules/read-pkg/node_modules/normalize-package-data": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "hosted-git-info": "^2.1.4",
+        "resolve": "^1.10.0",
+        "semver": "2 || 3 || 4 || 5",
+        "validate-npm-package-license": "^3.0.1"
+      }
+    },
+    "node_modules/read-pkg/node_modules/semver": {
+      "version": "5.7.2",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/read-pkg/node_modules/type-fest": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
+      "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/readable-stream": {
       "version": "3.6.2",
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -13843,6 +15313,21 @@
         "node": ">=8.10.0"
       }
     },
+    "node_modules/redent": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
+      "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "indent-string": "^4.0.0",
+        "strip-indent": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/reflect-metadata": {
       "version": "0.1.13",
       "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
@@ -14245,41 +15730,46 @@
         "node": ">=14.0.0"
       }
     },
-    "node_modules/sass-loader": {
-      "version": "13.3.2",
-      "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.2.tgz",
-      "integrity": "sha512-CQbKl57kdEv+KDLquhC+gE3pXt74LEAzm+tzywcA0/aHZuub8wTErbjAoNI57rPUWRYRNC5WUnNl8eGJNbDdwg==",
+    "node_modules/sass-graph": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-4.0.1.tgz",
+      "integrity": "sha512-5YCfmGBmxoIRYHnKK2AKzrAkCoQ8ozO+iumT8K4tXJXRVCPf+7s1/9KxTSW3Rbvf+7Y7b4FR3mWyLnQr3PHocA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
-        "neo-async": "^2.6.2"
+        "glob": "^7.0.0",
+        "lodash": "^4.17.11",
+        "scss-tokenizer": "^0.4.3",
+        "yargs": "^17.2.1"
       },
-      "engines": {
-        "node": ">= 14.15.0"
+      "bin": {
+        "sassgraph": "bin/sassgraph"
       },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/sass-graph/node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
       },
-      "peerDependencies": {
-        "fibers": ">= 3.1.0",
-        "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0",
-        "sass": "^1.3.0",
-        "sass-embedded": "*",
-        "webpack": "^5.0.0"
+      "engines": {
+        "node": "*"
       },
-      "peerDependenciesMeta": {
-        "fibers": {
-          "optional": true
-        },
-        "node-sass": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "sass-embedded": {
-          "optional": true
-        }
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
     "node_modules/saucelabs": {
@@ -14374,6 +15864,18 @@
         "url": "https://opencollective.com/webpack"
       }
     },
+    "node_modules/scss-tokenizer": {
+      "version": "0.4.3",
+      "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.4.3.tgz",
+      "integrity": "sha512-raKLgf1LI5QMQnG+RxHz6oK0sL3x3I4FN2UDLqgLOGO8hodECNnNh5BXn7fAyBxrA8zVzdQizQ6XjNJQ+uBwMw==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "js-base64": "^2.4.9",
+        "source-map": "^0.7.3"
+      }
+    },
     "node_modules/select-hose": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@@ -15170,13 +16672,60 @@
         "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
       }
     },
-    "node_modules/statuses": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
-      "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+    "node_modules/statuses": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+      "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/stdout-stream": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
+      "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "readable-stream": "^2.0.1"
+      }
+    },
+    "node_modules/stdout-stream/node_modules/readable-stream": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+      "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      }
+    },
+    "node_modules/stdout-stream/node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
       "dev": true,
-      "engines": {
-        "node": ">= 0.6"
+      "optional": true,
+      "peer": true
+    },
+    "node_modules/stdout-stream/node_modules/string_decoder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
       }
     },
     "node_modules/streamroller": {
@@ -15265,6 +16814,20 @@
         "node": ">=6"
       }
     },
+    "node_modules/strip-indent": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
+      "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "min-indent": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/strip-json-comments": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -15277,6 +16840,11 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/style-mod": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.0.tgz",
+      "integrity": "sha512-Ca5ib8HrFn+f+0n4N4ScTIA9iTOQ7MaGS1ylHcoVqW9J7w2w8PzN6g9gKmTYgGEBH8e120+RCmhpje6jC5uGWA=="
+    },
     "node_modules/supports-color": {
       "version": "5.5.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -15412,16 +16980,16 @@
       }
     },
     "node_modules/terser-webpack-plugin": {
-      "version": "5.3.7",
-      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz",
-      "integrity": "sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==",
+      "version": "5.3.10",
+      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
+      "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/trace-mapping": "^0.3.17",
+        "@jridgewell/trace-mapping": "^0.3.20",
         "jest-worker": "^27.4.5",
         "schema-utils": "^3.1.1",
         "serialize-javascript": "^6.0.1",
-        "terser": "^5.16.5"
+        "terser": "^5.26.0"
       },
       "engines": {
         "node": ">= 10.13.0"
@@ -15477,9 +17045,9 @@
       "dev": true
     },
     "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
-      "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+      "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
       "dev": true,
       "dependencies": {
         "@types/json-schema": "^7.0.8",
@@ -15494,6 +17062,24 @@
         "url": "https://opencollective.com/webpack"
       }
     },
+    "node_modules/terser-webpack-plugin/node_modules/terser": {
+      "version": "5.27.0",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz",
+      "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/source-map": "^0.3.3",
+        "acorn": "^8.8.2",
+        "commander": "^2.20.0",
+        "source-map-support": "~0.5.20"
+      },
+      "bin": {
+        "terser": "bin/terser"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/test-exclude": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
@@ -15624,6 +17210,25 @@
         "tree-kill": "cli.js"
       }
     },
+    "node_modules/trim-newlines": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
+      "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/true-case-path": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz",
+      "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
     "node_modules/ts-helpers": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/ts-helpers/-/ts-helpers-1.1.2.tgz",
@@ -16164,6 +17769,11 @@
         "browser-process-hrtime": "^1.0.0"
       }
     },
+    "node_modules/w3c-keyname": {
+      "version": "2.2.8",
+      "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
+      "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
+    },
     "node_modules/w3c-xmlserializer": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
@@ -16379,19 +17989,20 @@
       }
     },
     "node_modules/webpack": {
-      "version": "5.88.2",
-      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz",
-      "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==",
+      "version": "5.90.0",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.0.tgz",
+      "integrity": "sha512-bdmyXRCXeeNIePv6R6tGPyy20aUobw4Zy8r0LUS2EWO+U+Ke/gYDgsCh7bl5rB6jPpr4r0SZa6dPxBxLooDT3w==",
       "dev": true,
+      "peer": true,
       "dependencies": {
         "@types/eslint-scope": "^3.7.3",
-        "@types/estree": "^1.0.0",
+        "@types/estree": "^1.0.5",
         "@webassemblyjs/ast": "^1.11.5",
         "@webassemblyjs/wasm-edit": "^1.11.5",
         "@webassemblyjs/wasm-parser": "^1.11.5",
         "acorn": "^8.7.1",
         "acorn-import-assertions": "^1.9.0",
-        "browserslist": "^4.14.5",
+        "browserslist": "^4.21.10",
         "chrome-trace-event": "^1.0.2",
         "enhanced-resolve": "^5.15.0",
         "es-module-lexer": "^1.2.1",
@@ -16405,7 +18016,7 @@
         "neo-async": "^2.6.2",
         "schema-utils": "^3.2.0",
         "tapable": "^2.1.1",
-        "terser-webpack-plugin": "^5.3.7",
+        "terser-webpack-plugin": "^5.3.10",
         "watchpack": "^2.4.0",
         "webpack-sources": "^3.2.3"
       },
@@ -16604,6 +18215,7 @@
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
       "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
       "dev": true,
+      "peer": true,
       "dependencies": {
         "fast-deep-equal": "^3.1.1",
         "fast-json-stable-stringify": "^2.0.0",
@@ -16620,6 +18232,7 @@
       "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
       "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
       "dev": true,
+      "peer": true,
       "peerDependencies": {
         "ajv": "^6.9.1"
       }
@@ -16629,6 +18242,7 @@
       "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
       "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
       "dev": true,
+      "peer": true,
       "dependencies": {
         "esrecurse": "^4.3.0",
         "estraverse": "^4.1.1"
@@ -16642,6 +18256,7 @@
       "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
       "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
       "dev": true,
+      "peer": true,
       "engines": {
         "node": ">=4.0"
       }
@@ -16650,13 +18265,15 @@
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
       "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-      "dev": true
+      "dev": true,
+      "peer": true
     },
     "node_modules/webpack/node_modules/schema-utils": {
       "version": "3.3.0",
       "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
       "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
       "dev": true,
+      "peer": true,
       "dependencies": {
         "@types/json-schema": "^7.0.8",
         "ajv": "^6.12.5",
@@ -17164,11 +18781,106 @@
             }
           }
         },
+        "eslint-scope": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+          "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+          "dev": true,
+          "requires": {
+            "esrecurse": "^4.3.0",
+            "estraverse": "^4.1.1"
+          }
+        },
+        "estraverse": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+          "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+          "dev": true
+        },
+        "json-schema-traverse": {
+          "version": "0.4.1",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+          "dev": true
+        },
+        "sass-loader": {
+          "version": "13.3.2",
+          "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.2.tgz",
+          "integrity": "sha512-CQbKl57kdEv+KDLquhC+gE3pXt74LEAzm+tzywcA0/aHZuub8wTErbjAoNI57rPUWRYRNC5WUnNl8eGJNbDdwg==",
+          "dev": true,
+          "requires": {
+            "neo-async": "^2.6.2"
+          }
+        },
+        "schema-utils": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+          "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+          "dev": true,
+          "requires": {
+            "@types/json-schema": "^7.0.8",
+            "ajv": "^6.12.5",
+            "ajv-keywords": "^3.5.2"
+          },
+          "dependencies": {
+            "ajv": {
+              "version": "6.12.6",
+              "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+              "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+              "dev": true,
+              "requires": {
+                "fast-deep-equal": "^3.1.1",
+                "fast-json-stable-stringify": "^2.0.0",
+                "json-schema-traverse": "^0.4.1",
+                "uri-js": "^4.2.2"
+              }
+            },
+            "ajv-keywords": {
+              "version": "3.5.2",
+              "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+              "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+              "dev": true,
+              "requires": {}
+            }
+          }
+        },
         "tslib": {
           "version": "2.6.1",
           "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz",
           "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==",
           "dev": true
+        },
+        "webpack": {
+          "version": "5.88.2",
+          "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz",
+          "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==",
+          "dev": true,
+          "requires": {
+            "@types/eslint-scope": "^3.7.3",
+            "@types/estree": "^1.0.0",
+            "@webassemblyjs/ast": "^1.11.5",
+            "@webassemblyjs/wasm-edit": "^1.11.5",
+            "@webassemblyjs/wasm-parser": "^1.11.5",
+            "acorn": "^8.7.1",
+            "acorn-import-assertions": "^1.9.0",
+            "browserslist": "^4.14.5",
+            "chrome-trace-event": "^1.0.2",
+            "enhanced-resolve": "^5.15.0",
+            "es-module-lexer": "^1.2.1",
+            "eslint-scope": "5.1.1",
+            "events": "^3.2.0",
+            "glob-to-regexp": "^0.4.1",
+            "graceful-fs": "^4.2.9",
+            "json-parse-even-better-errors": "^2.3.1",
+            "loader-runner": "^4.2.0",
+            "mime-types": "^2.1.27",
+            "neo-async": "^2.6.2",
+            "schema-utils": "^3.2.0",
+            "tapable": "^2.1.1",
+            "terser-webpack-plugin": "^5.3.7",
+            "watchpack": "^2.4.0",
+            "webpack-sources": "^3.2.3"
+          }
         }
       }
     },
@@ -18724,41 +20436,368 @@
       "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==",
       "dev": true,
       "requires": {
-        "@babel/code-frame": "^7.23.5",
-        "@babel/generator": "^7.23.5",
-        "@babel/helper-environment-visitor": "^7.22.20",
-        "@babel/helper-function-name": "^7.23.0",
-        "@babel/helper-hoist-variables": "^7.22.5",
-        "@babel/helper-split-export-declaration": "^7.22.6",
-        "@babel/parser": "^7.23.5",
-        "@babel/types": "^7.23.5",
-        "debug": "^4.1.0",
-        "globals": "^11.1.0"
-      },
-      "dependencies": {
-        "@babel/generator": {
-          "version": "7.23.5",
-          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz",
-          "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.23.5",
-            "@jridgewell/gen-mapping": "^0.3.2",
-            "@jridgewell/trace-mapping": "^0.3.17",
-            "jsesc": "^2.5.1"
-          }
-        }
+        "@babel/code-frame": "^7.23.5",
+        "@babel/generator": "^7.23.5",
+        "@babel/helper-environment-visitor": "^7.22.20",
+        "@babel/helper-function-name": "^7.23.0",
+        "@babel/helper-hoist-variables": "^7.22.5",
+        "@babel/helper-split-export-declaration": "^7.22.6",
+        "@babel/parser": "^7.23.5",
+        "@babel/types": "^7.23.5",
+        "debug": "^4.1.0",
+        "globals": "^11.1.0"
+      },
+      "dependencies": {
+        "@babel/generator": {
+          "version": "7.23.5",
+          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz",
+          "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "^7.23.5",
+            "@jridgewell/gen-mapping": "^0.3.2",
+            "@jridgewell/trace-mapping": "^0.3.17",
+            "jsesc": "^2.5.1"
+          }
+        }
+      }
+    },
+    "@babel/types": {
+      "version": "7.23.5",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz",
+      "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-string-parser": "^7.23.4",
+        "@babel/helper-validator-identifier": "^7.22.20",
+        "to-fast-properties": "^2.0.0"
+      }
+    },
+    "@codemirror/autocomplete": {
+      "version": "6.12.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.12.0.tgz",
+      "integrity": "sha512-r4IjdYFthwbCQyvqnSlx0WBHRHi8nBvU+WjJxFUij81qsBfhNudf/XKKmmC2j3m0LaOYUQTf3qiEK1J8lO1sdg==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.17.0",
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "@codemirror/commands": {
+      "version": "6.3.3",
+      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.3.3.tgz",
+      "integrity": "sha512-dO4hcF0fGT9tu1Pj1D2PvGvxjeGkbC6RGcZw6Qs74TH+Ed1gw98jmUgd2axWvIZEqTeTuFrg1lEB1KV6cK9h1A==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.4.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.1.0"
+      }
+    },
+    "@codemirror/lang-angular": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-angular/-/lang-angular-0.1.3.tgz",
+      "integrity": "sha512-xgeWGJQQl1LyStvndWtruUvb4SnBZDAu/gvFH/ZU+c0W25tQR8e5hq7WTwiIY2dNxnf+49mRiGI/9yxIwB6f5w==",
+      "requires": {
+        "@codemirror/lang-html": "^6.0.0",
+        "@codemirror/lang-javascript": "^6.1.2",
+        "@codemirror/language": "^6.0.0",
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.3.3"
+      }
+    },
+    "@codemirror/lang-cpp": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-cpp/-/lang-cpp-6.0.2.tgz",
+      "integrity": "sha512-6oYEYUKHvrnacXxWxYa6t4puTlbN3dgV662BDfSH8+MfjQjVmP697/KYTDOqpxgerkvoNm7q5wlFMBeX8ZMocg==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/cpp": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-css": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.2.1.tgz",
+      "integrity": "sha512-/UNWDNV5Viwi/1lpr/dIXJNWiwDxpw13I4pTUAsNxZdg6E0mI2kTQb0P2iHczg1Tu+H4EBgJR+hYhKiHKko7qg==",
+      "requires": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/common": "^1.0.2",
+        "@lezer/css": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-html": {
+      "version": "6.4.7",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.7.tgz",
+      "integrity": "sha512-y9hWSSO41XlcL4uYwWyk0lEgTHcelWWfRuqmvcAmxfCs0HNWZdriWo/EU43S63SxEZpc1Hd50Itw7ktfQvfkUg==",
+      "requires": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/lang-css": "^6.0.0",
+        "@codemirror/lang-javascript": "^6.0.0",
+        "@codemirror/language": "^6.4.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.17.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/css": "^1.1.0",
+        "@lezer/html": "^1.3.0"
+      }
+    },
+    "@codemirror/lang-java": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-java/-/lang-java-6.0.1.tgz",
+      "integrity": "sha512-OOnmhH67h97jHzCuFaIEspbmsT98fNdhVhmA3zCxW0cn7l8rChDhZtwiwJ/JOKXgfm4J+ELxQihxaI7bj7mJRg==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/java": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-javascript": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.1.tgz",
+      "integrity": "sha512-jlFOXTejVyiQCW3EQwvKH0m99bUYIw40oPmFjSX2VS78yzfe0HELZ+NEo9Yfo1MkGRpGlj3Gnu4rdxV1EnAs5A==",
+      "requires": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/language": "^6.6.0",
+        "@codemirror/lint": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.17.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/javascript": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-json": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.1.tgz",
+      "integrity": "sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/json": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-less": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-less/-/lang-less-6.0.2.tgz",
+      "integrity": "sha512-EYdQTG22V+KUUk8Qq582g7FMnCZeEHsyuOJisHRft/mQ+ZSZ2w51NupvDUHiqtsOy7It5cHLPGfHQLpMh9bqpQ==",
+      "requires": {
+        "@codemirror/lang-css": "^6.2.0",
+        "@codemirror/language": "^6.0.0",
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-markdown": {
+      "version": "6.2.4",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.2.4.tgz",
+      "integrity": "sha512-UghkA1vSMs8bT7RSZM6vsIocigyah2bV00eRQuZy76401UmFZdsTsbQNBGdyxRQDOLeEvF5iFwap0BM8LKyd+g==",
+      "requires": {
+        "@codemirror/autocomplete": "^6.7.1",
+        "@codemirror/lang-html": "^6.0.0",
+        "@codemirror/language": "^6.3.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.2.1",
+        "@lezer/markdown": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-php": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-php/-/lang-php-6.0.1.tgz",
+      "integrity": "sha512-ublojMdw/PNWa7qdN5TMsjmqkNuTBD3k6ndZ4Z0S25SBAiweFGyY68AS3xNcIOlb6DDFDvKlinLQ40vSLqf8xA==",
+      "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/lang-python": {
+      "version": "6.1.3",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.1.3.tgz",
+      "integrity": "sha512-S9w2Jl74hFlD5nqtUMIaXAq9t5WlM0acCkyuQWUUSvZclk1sV+UfnpFiZzuZSG+hfEaOmxKR5UxY/Uxswn7EhQ==",
+      "requires": {
+        "@codemirror/autocomplete": "^6.3.2",
+        "@codemirror/language": "^6.8.0",
+        "@lezer/python": "^1.1.4"
+      }
+    },
+    "@codemirror/lang-rust": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-rust/-/lang-rust-6.0.1.tgz",
+      "integrity": "sha512-344EMWFBzWArHWdZn/NcgkwMvZIWUR1GEBdwG8FEp++6o6vT6KL9V7vGs2ONsKxxFUPXKI0SPcWhyYyl2zPYxQ==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/rust": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-sass": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-sass/-/lang-sass-6.0.2.tgz",
+      "integrity": "sha512-l/bdzIABvnTo1nzdY6U+kPAC51czYQcOErfzQ9zSm9D8GmNPD0WTW8st/CJwBTPLO8jlrbyvlSEcN20dc4iL0Q==",
+      "requires": {
+        "@codemirror/lang-css": "^6.2.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/common": "^1.0.2",
+        "@lezer/sass": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-sql": {
+      "version": "6.5.5",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-sql/-/lang-sql-6.5.5.tgz",
+      "integrity": "sha512-DvOaP2RXLb2xlxJxxydTFfwyYw5YDqEFea6aAfgh9UH0kUD6J1KFZ0xPgPpw1eo/5s2w3L6uh5PVR7GM23GxkQ==",
+      "requires": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-vue": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-vue/-/lang-vue-0.1.3.tgz",
+      "integrity": "sha512-QSKdtYTDRhEHCfo5zOShzxCmqKJvgGrZwDQSdbvCRJ5pRLWBS7pD/8e/tH44aVQT6FKm0t6RVNoSUWHOI5vNug==",
+      "requires": {
+        "@codemirror/lang-html": "^6.0.0",
+        "@codemirror/lang-javascript": "^6.1.2",
+        "@codemirror/language": "^6.0.0",
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.3.1"
+      }
+    },
+    "@codemirror/lang-wast": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-wast/-/lang-wast-6.0.2.tgz",
+      "integrity": "sha512-Imi2KTpVGm7TKuUkqyJ5NRmeFWF7aMpNiwHnLQe0x9kmrxElndyH0K6H/gXtWwY6UshMRAhpENsgfpSwsgmC6Q==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "@codemirror/lang-xml": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-xml/-/lang-xml-6.0.2.tgz",
+      "integrity": "sha512-JQYZjHL2LAfpiZI2/qZ/qzDuSqmGKMwyApYmEUUCTxLM4MWS7sATUEfIguZQr9Zjx/7gcdnewb039smF6nC2zw==",
+      "requires": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/language": "^6.4.0",
+        "@codemirror/state": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/xml": "^1.0.0"
+      }
+    },
+    "@codemirror/language": {
+      "version": "6.10.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.0.tgz",
+      "integrity": "sha512-2vaNn9aPGCRFKWcHPFksctzJ8yS5p7YoaT+jHpc0UGKzNuAIx4qy6R5wiqbP+heEEdyaABA582mNqSHzSoYdmg==",
+      "requires": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.23.0",
+        "@lezer/common": "^1.1.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0",
+        "style-mod": "^4.0.0"
+      }
+    },
+    "@codemirror/language-data": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/language-data/-/language-data-6.3.1.tgz",
+      "integrity": "sha512-p6jhJmvhGe1TG1EGNhwH7nFWWFSTJ8NDKnB2fVx5g3t+PpO0+63R7GJNxjS0TmmH3cdMxZbzejsik+rlEh1EyQ==",
+      "requires": {
+        "@codemirror/lang-angular": "^0.1.0",
+        "@codemirror/lang-cpp": "^6.0.0",
+        "@codemirror/lang-css": "^6.0.0",
+        "@codemirror/lang-html": "^6.0.0",
+        "@codemirror/lang-java": "^6.0.0",
+        "@codemirror/lang-javascript": "^6.0.0",
+        "@codemirror/lang-json": "^6.0.0",
+        "@codemirror/lang-less": "^6.0.0",
+        "@codemirror/lang-markdown": "^6.0.0",
+        "@codemirror/lang-php": "^6.0.0",
+        "@codemirror/lang-python": "^6.0.0",
+        "@codemirror/lang-rust": "^6.0.0",
+        "@codemirror/lang-sass": "^6.0.0",
+        "@codemirror/lang-sql": "^6.0.0",
+        "@codemirror/lang-vue": "^0.1.1",
+        "@codemirror/lang-wast": "^6.0.0",
+        "@codemirror/lang-xml": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/legacy-modes": "^6.1.0"
+      }
+    },
+    "@codemirror/legacy-modes": {
+      "version": "6.3.3",
+      "resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.3.3.tgz",
+      "integrity": "sha512-X0Z48odJ0KIoh/HY8Ltz75/4tDYc9msQf1E/2trlxFaFFhgjpVHjZ/BCXe1Lk7s4Gd67LL/CeEEHNI+xHOiESg==",
+      "requires": {
+        "@codemirror/language": "^6.0.0"
+      }
+    },
+    "@codemirror/lint": {
+      "version": "6.4.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.4.2.tgz",
+      "integrity": "sha512-wzRkluWb1ptPKdzlsrbwwjYCPLgzU6N88YBAmlZi8WFyuiEduSd05MnJYNogzyc8rPK7pj6m95ptUApc8sHKVA==",
+      "requires": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "crelt": "^1.0.5"
+      }
+    },
+    "@codemirror/merge": {
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/merge/-/merge-6.5.0.tgz",
+      "integrity": "sha512-Am88bwcZFrVM84M7x+Njq3X1TSNXqEdOjp7iFI+45KDG+zJUA1gTkJxzGtrTKBKK7gL1Q0/tihpGQBlZOZCO/w==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.17.0",
+        "@lezer/highlight": "^1.0.0",
+        "style-mod": "^4.1.0"
+      }
+    },
+    "@codemirror/search": {
+      "version": "6.5.5",
+      "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.5.tgz",
+      "integrity": "sha512-PIEN3Ke1buPod2EHbJsoQwlbpkz30qGZKcnmH1eihq9+bPQx8gelauUwLYaY4vBOuBAuEhmpDLii4rj/uO0yMA==",
+      "requires": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "crelt": "^1.0.5"
+      }
+    },
+    "@codemirror/state": {
+      "version": "6.4.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.0.tgz",
+      "integrity": "sha512-hm8XshYj5Fo30Bb922QX9hXB/bxOAVH+qaqHBzw5TKa72vOeslyGwd4X8M0c1dJ9JqxlaMceOQ8RsL9tC7gU0A=="
+    },
+    "@codemirror/theme-one-dark": {
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz",
+      "integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/highlight": "^1.0.0"
       }
     },
-    "@babel/types": {
-      "version": "7.23.5",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz",
-      "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==",
-      "dev": true,
+    "@codemirror/view": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.23.0.tgz",
+      "integrity": "sha512-/51px9N4uW8NpuWkyUX+iam5+PM6io2fm+QmRnzwqBy5v/pwGg9T0kILFtYeum8hjuvENtgsGNKluOfqIICmeQ==",
       "requires": {
-        "@babel/helper-string-parser": "^7.23.4",
-        "@babel/helper-validator-identifier": "^7.22.20",
-        "to-fast-properties": "^2.0.0"
+        "@codemirror/state": "^6.4.0",
+        "style-mod": "^4.1.0",
+        "w3c-keyname": "^2.2.4"
       }
     },
     "@colors/colors": {
@@ -18767,15 +20806,6 @@
       "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
       "dev": true
     },
-    "@ctrl/ngx-codemirror": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@ctrl/ngx-codemirror/-/ngx-codemirror-7.0.0.tgz",
-      "integrity": "sha512-qvIWtSTw/8fdXDnofBTX6LmTW9646HhawG2+Qyagf1vH40jCy0ZbHnkC20UYOVpUX+QCd1e/PQpkvWQ/1iGFzQ==",
-      "requires": {
-        "@types/codemirror": "^5.60.7",
-        "tslib": "^2.3.0"
-      }
-    },
     "@discoveryjs/json-ext": {
       "version": "0.5.7",
       "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
@@ -19177,13 +21207,13 @@
       "dev": true
     },
     "@jridgewell/trace-mapping": {
-      "version": "0.3.17",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
-      "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+      "version": "0.3.22",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz",
+      "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==",
       "dev": true,
       "requires": {
-        "@jridgewell/resolve-uri": "3.1.0",
-        "@jridgewell/sourcemap-codec": "1.4.14"
+        "@jridgewell/resolve-uri": "^3.1.0",
+        "@jridgewell/sourcemap-codec": "^1.4.14"
       }
     },
     "@leichtgewicht/ip-codec": {
@@ -19192,6 +21222,146 @@
       "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
       "dev": true
     },
+    "@lezer/common": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz",
+      "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ=="
+    },
+    "@lezer/cpp": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@lezer/cpp/-/cpp-1.1.2.tgz",
+      "integrity": "sha512-macwKtyeUO0EW86r3xWQCzOV9/CF8imJLpJlPv3sDY57cPGeUZ8gXWOWNlJr52TVByMV3PayFQCA5SHEERDmVQ==",
+      "requires": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "@lezer/css": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.7.tgz",
+      "integrity": "sha512-7BlFFAKNn/b39jJLrhdLSX5A2k56GIJvyLqdmm7UU+7XvequY084iuKDMAEhAmAzHnwDE8FK4OQtsIUssW91tg==",
+      "requires": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "@lezer/highlight": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz",
+      "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==",
+      "requires": {
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "@lezer/html": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.8.tgz",
+      "integrity": "sha512-EXseJ3pUzWxE6XQBQdqWHZqqlGQRSuNMBcLb6mZWS2J2v+QZhOObD+3ZIKIcm59ntTzyor4LqFTb72iJc3k23Q==",
+      "requires": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "@lezer/java": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@lezer/java/-/java-1.1.1.tgz",
+      "integrity": "sha512-mt3dX13fRlpY7RlWELYRakanXgmwXsLRCrhstrn+c1sZd7jR2xle46/3heoxGd+oHxnuTnpoyXTyxcLJQs9+mQ==",
+      "requires": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "@lezer/javascript": {
+      "version": "1.4.13",
+      "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.13.tgz",
+      "integrity": "sha512-5IBr8LIO3xJdJH1e9aj/ZNLE4LSbdsx25wFmGRAZsj2zSmwAYjx26JyU/BYOCpRQlu1jcv1z3vy4NB9+UkfRow==",
+      "requires": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.1.3",
+        "@lezer/lr": "^1.3.0"
+      }
+    },
+    "@lezer/json": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.2.tgz",
+      "integrity": "sha512-xHT2P4S5eeCYECyKNPhr4cbEL9tc8w83SPwRC373o9uEdrvGKTZoJVAGxpOsZckMlEh9W23Pc72ew918RWQOBQ==",
+      "requires": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "@lezer/lr": {
+      "version": "1.3.14",
+      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.3.14.tgz",
+      "integrity": "sha512-z5mY4LStlA3yL7aHT/rqgG614cfcvklS+8oFRFBYrs4YaWLJyKKM4+nN6KopToX0o9Hj6zmH6M5kinOYuy06ug==",
+      "requires": {
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "@lezer/markdown": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.2.0.tgz",
+      "integrity": "sha512-d7MwsfAukZJo1GpPrcPGa3MxaFFOqNp0gbqF+3F7pTeNDOgeJN1muXzx1XXDPt+Ac+/voCzsH7qXqnn+xReG/g==",
+      "requires": {
+        "@lezer/common": "^1.0.0",
+        "@lezer/highlight": "^1.0.0"
+      }
+    },
+    "@lezer/php": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@lezer/php/-/php-1.0.2.tgz",
+      "integrity": "sha512-GN7BnqtGRpFyeoKSEqxvGvhJQiI4zkgmYnDk/JIyc7H7Ifc1tkPnUn/R2R8meH3h/aBf5rzjvU8ZQoyiNDtDrA==",
+      "requires": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.1.0"
+      }
+    },
+    "@lezer/python": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/@lezer/python/-/python-1.1.11.tgz",
+      "integrity": "sha512-C3QeLCcdAKJDUOsYjfFP6a1wdn8jhUNX200bgFm8TpKH1eM2PlgYQS5ugw6E38qGeEx7CP21I1Q52SoybXt0OQ==",
+      "requires": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "@lezer/rust": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@lezer/rust/-/rust-1.0.2.tgz",
+      "integrity": "sha512-Lz5sIPBdF2FUXcWeCu1//ojFAZqzTQNRga0aYv6dYXqJqPfMdCAI0NzajWUd4Xijj1IKJLtjoXRPMvTKWBcqKg==",
+      "requires": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "@lezer/sass": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/@lezer/sass/-/sass-1.0.4.tgz",
+      "integrity": "sha512-AqW4myvp73sbMk6y0+gJrMjN5xtqFZzqTftzO3YcO8gSL5d3pymIP3deQllAI8+s1ZoSzH6kD4hsoFLpkD9Kfg==",
+      "requires": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
+    "@lezer/xml": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/@lezer/xml/-/xml-1.0.4.tgz",
+      "integrity": "sha512-WmXKb5eX8+rRfZYSNRR5TPee/ZoDgBdVS/rj1VCJGDKa5gNldIctQYibCoFVyNhvZsyL/8nHbZJZPM4gnXN2Vw==",
+      "requires": {
+        "@lezer/common": "^1.2.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
     "@material/animation": {
       "version": "15.0.0-canary.bc9ae6c9c.0",
       "resolved": "https://registry.npmjs.org/@material/animation/-/animation-15.0.0-canary.bc9ae6c9c.0.tgz",
@@ -20374,14 +22544,6 @@
         "@types/node": "*"
       }
     },
-    "@types/codemirror": {
-      "version": "5.60.7",
-      "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.7.tgz",
-      "integrity": "sha512-QXIC+RPzt/1BGSuD6iFn6UMC9TDp+9hkOANYNPVsjjrDdzKphfRkwQDKGp2YaC54Yhz0g6P5uYTCCibZZEiMAA==",
-      "requires": {
-        "@types/tern": "*"
-      }
-    },
     "@types/connect": {
       "version": "3.4.38",
       "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
@@ -20437,9 +22599,10 @@
       }
     },
     "@types/estree": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
-      "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ=="
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+      "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
+      "dev": true
     },
     "@types/express": {
       "version": "4.17.21",
@@ -20504,6 +22667,14 @@
       "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
       "dev": true
     },
+    "@types/minimist": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz",
+      "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
     "@types/node": {
       "version": "18.15.6",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.6.tgz",
@@ -20519,6 +22690,14 @@
         "@types/node": "*"
       }
     },
+    "@types/normalize-package-data": {
+      "version": "2.4.4",
+      "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
+      "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
     "@types/q": {
       "version": "0.0.32",
       "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz",
@@ -20598,14 +22777,6 @@
         "@types/node": "*"
       }
     },
-    "@types/tern": {
-      "version": "0.23.4",
-      "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.4.tgz",
-      "integrity": "sha512-JAUw1iXGO1qaWwEOzxTKJZ/5JxVeON9kvGZ/osgZaJImBnyjyn0cjovPsf6FNLmyGY8Vw9DoXZCMlfMkMwHRWg==",
-      "requires": {
-        "@types/estree": "*"
-      }
-    },
     "@types/ws": {
       "version": "8.5.10",
       "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz",
@@ -21135,6 +23306,14 @@
       "optional": true,
       "peer": true
     },
+    "async-foreach": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
+      "integrity": "sha512-VUeSMD8nEGBWaZK4lizI1sf3yEC7pnAQ/mrI7pC2fBz2s/tq5jWWEngTwaf0Gruu/OoXRGLGg1XFqpYBiGTYJA==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
     "asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -21525,6 +23704,19 @@
       "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
       "dev": true
     },
+    "camelcase-keys": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz",
+      "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "requires": {
+        "camelcase": "^5.3.1",
+        "map-obj": "^4.0.0",
+        "quick-lru": "^4.0.1"
+      }
+    },
     "caniuse-lite": {
       "version": "1.0.30001566",
       "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz",
@@ -21640,9 +23832,18 @@
       }
     },
     "codemirror": {
-      "version": "5.65.16",
-      "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.16.tgz",
-      "integrity": "sha512-br21LjYmSlVL0vFCPWPfhzUCT34FM/pAdK7rRIZwa0rrtrIdotvP4Oh4GUHsu2E3IrQMCfRkL/fN3ytMNxVQvg=="
+      "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",
@@ -21925,6 +24126,11 @@
         }
       }
     },
+    "crelt": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
+      "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g=="
+    },
     "critters": {
       "version": "0.0.20",
       "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.20.tgz",
@@ -22123,6 +24329,28 @@
       "optional": true,
       "peer": true
     },
+    "decamelize-keys": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
+      "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "requires": {
+        "decamelize": "^1.1.0",
+        "map-obj": "^1.0.0"
+      },
+      "dependencies": {
+        "map-obj": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+          "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
+          "dev": true,
+          "optional": true,
+          "peer": true
+        }
+      }
+    },
     "decimal.js": {
       "version": "10.4.3",
       "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
@@ -23354,6 +25582,17 @@
         "wide-align": "^1.1.5"
       }
     },
+    "gaze": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
+      "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "requires": {
+        "globule": "^1.0.0"
+      }
+    },
     "gensync": {
       "version": "1.0.0-beta.2",
       "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -23383,6 +25622,14 @@
       "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
       "dev": true
     },
+    "get-stdin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+      "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
     "get-stream": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
@@ -23467,6 +25714,48 @@
         "slash": "^4.0.0"
       }
     },
+    "globule": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz",
+      "integrity": "sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "requires": {
+        "glob": "~7.1.1",
+        "lodash": "^4.17.21",
+        "minimatch": "~3.0.2"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.1.7",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+          "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "minimatch": {
+          "version": "3.0.8",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
+          "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "brace-expansion": "^1.1.7"
+          }
+        }
+      }
+    },
     "graceful-fs": {
       "version": "4.2.11",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -23544,6 +25833,14 @@
         }
       }
     },
+    "hard-rejection": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
+      "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
     "has": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -24383,6 +26680,14 @@
       "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==",
       "dev": true
     },
+    "js-base64": {
+      "version": "2.6.4",
+      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
+      "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
     "js-sdsl": {
       "version": "4.4.0",
       "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz",
@@ -25227,25 +27532,117 @@
           "version": "4.0.0",
           "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
           "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
-          "dev": true
+          "dev": true
+        }
+      }
+    },
+    "map-obj": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
+      "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
+    "media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+      "dev": true
+    },
+    "memfs": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz",
+      "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==",
+      "dev": true,
+      "requires": {
+        "fs-monkey": "^1.0.4"
+      }
+    },
+    "meow": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz",
+      "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "requires": {
+        "@types/minimist": "^1.2.0",
+        "camelcase-keys": "^6.2.2",
+        "decamelize": "^1.2.0",
+        "decamelize-keys": "^1.1.0",
+        "hard-rejection": "^2.1.0",
+        "minimist-options": "4.1.0",
+        "normalize-package-data": "^3.0.0",
+        "read-pkg-up": "^7.0.1",
+        "redent": "^3.0.0",
+        "trim-newlines": "^3.0.0",
+        "type-fest": "^0.18.0",
+        "yargs-parser": "^20.2.3"
+      },
+      "dependencies": {
+        "hosted-git-info": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+          "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
+        },
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
+        "normalize-package-data": {
+          "version": "3.0.3",
+          "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
+          "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "hosted-git-info": "^4.0.1",
+            "is-core-module": "^2.5.0",
+            "semver": "^7.3.4",
+            "validate-npm-package-license": "^3.0.1"
+          }
+        },
+        "type-fest": {
+          "version": "0.18.1",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
+          "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
+          "dev": true,
+          "optional": true,
+          "peer": true
+        },
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+          "dev": true,
+          "optional": true,
+          "peer": true
+        },
+        "yargs-parser": {
+          "version": "20.2.9",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+          "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+          "dev": true,
+          "optional": true,
+          "peer": true
         }
       }
     },
-    "media-typer": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
-      "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
-      "dev": true
-    },
-    "memfs": {
-      "version": "3.5.3",
-      "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz",
-      "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==",
-      "dev": true,
-      "requires": {
-        "fs-monkey": "^1.0.4"
-      }
-    },
     "merge-descriptors": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
@@ -25307,6 +27704,14 @@
       "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
       "dev": true
     },
+    "min-indent": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
+      "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
     "mini-css-extract-plugin": {
       "version": "2.7.6",
       "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz",
@@ -25337,6 +27742,29 @@
       "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
       "dev": true
     },
+    "minimist-options": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
+      "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "requires": {
+        "arrify": "^1.0.1",
+        "is-plain-obj": "^1.1.0",
+        "kind-of": "^6.0.3"
+      },
+      "dependencies": {
+        "is-plain-obj": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+          "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
+          "dev": true,
+          "optional": true,
+          "peer": true
+        }
+      }
+    },
     "minipass": {
       "version": "7.0.4",
       "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
@@ -25556,6 +27984,14 @@
       "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
       "dev": true
     },
+    "nan": {
+      "version": "2.18.0",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz",
+      "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
     "nanoid": {
       "version": "3.3.7",
       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
@@ -25921,29 +28357,363 @@
           "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
           "dev": true,
           "requires": {
-            "fs.realpath": "^1.0.0",
-            "inflight": "^1.0.4",
-            "inherits": "2",
-            "minimatch": "^3.1.1",
-            "once": "^1.3.0",
-            "path-is-absolute": "^1.0.0"
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.1.1",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        }
+      }
+    },
+    "node-gyp-build": {
+      "version": "4.7.1",
+      "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.7.1.tgz",
+      "integrity": "sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg==",
+      "dev": true,
+      "optional": true
+    },
+    "node-releases": {
+      "version": "2.0.14",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+      "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
+      "dev": true
+    },
+    "node-sass": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-9.0.0.tgz",
+      "integrity": "sha512-yltEuuLrfH6M7Pq2gAj5B6Zm7m+gdZoG66wTqG6mIZV/zijq3M2OO2HswtT6oBspPyFhHDcaxWpsBm0fRNDHPg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "requires": {
+        "async-foreach": "^0.1.3",
+        "chalk": "^4.1.2",
+        "cross-spawn": "^7.0.3",
+        "gaze": "^1.0.0",
+        "get-stdin": "^4.0.1",
+        "glob": "^7.0.3",
+        "lodash": "^4.17.15",
+        "make-fetch-happen": "^10.0.4",
+        "meow": "^9.0.0",
+        "nan": "^2.17.0",
+        "node-gyp": "^8.4.1",
+        "sass-graph": "^4.0.1",
+        "stdout-stream": "^1.4.0",
+        "true-case-path": "^2.2.1"
+      },
+      "dependencies": {
+        "@npmcli/fs": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
+          "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "@gar/promisify": "^1.0.1",
+            "semver": "^7.3.5"
+          }
+        },
+        "@npmcli/move-file": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
+          "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "mkdirp": "^1.0.4",
+            "rimraf": "^3.0.2"
+          }
+        },
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "cacache": {
+          "version": "15.3.0",
+          "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
+          "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "@npmcli/fs": "^1.0.0",
+            "@npmcli/move-file": "^1.0.1",
+            "chownr": "^2.0.0",
+            "fs-minipass": "^2.0.0",
+            "glob": "^7.1.4",
+            "infer-owner": "^1.0.4",
+            "lru-cache": "^6.0.0",
+            "minipass": "^3.1.1",
+            "minipass-collect": "^1.0.2",
+            "minipass-flush": "^1.0.5",
+            "minipass-pipeline": "^1.2.2",
+            "mkdirp": "^1.0.3",
+            "p-map": "^4.0.0",
+            "promise-inflight": "^1.0.1",
+            "rimraf": "^3.0.2",
+            "ssri": "^8.0.1",
+            "tar": "^6.0.2",
+            "unique-filename": "^1.1.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true,
+          "optional": true,
+          "peer": true
+        },
+        "fs-minipass": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+          "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "minipass": "^3.0.0"
+          }
+        },
+        "glob": {
+          "version": "7.2.3",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+          "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.1.1",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true,
+          "optional": true,
+          "peer": true
+        },
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
+        "minipass": {
+          "version": "3.3.6",
+          "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+          "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
+        "minipass-collect": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
+          "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "minipass": "^3.0.0"
+          }
+        },
+        "minipass-fetch": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
+          "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "encoding": "^0.1.12",
+            "minipass": "^3.1.0",
+            "minipass-sized": "^1.0.3",
+            "minizlib": "^2.0.0"
+          }
+        },
+        "mkdirp": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+          "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+          "dev": true,
+          "optional": true,
+          "peer": true
+        },
+        "node-gyp": {
+          "version": "8.4.1",
+          "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz",
+          "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "env-paths": "^2.2.0",
+            "glob": "^7.1.4",
+            "graceful-fs": "^4.2.6",
+            "make-fetch-happen": "^9.1.0",
+            "nopt": "^5.0.0",
+            "npmlog": "^6.0.0",
+            "rimraf": "^3.0.2",
+            "semver": "^7.3.5",
+            "tar": "^6.1.2",
+            "which": "^2.0.2"
+          },
+          "dependencies": {
+            "make-fetch-happen": {
+              "version": "9.1.0",
+              "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
+              "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
+              "dev": true,
+              "optional": true,
+              "peer": true,
+              "requires": {
+                "agentkeepalive": "^4.1.3",
+                "cacache": "^15.2.0",
+                "http-cache-semantics": "^4.1.0",
+                "http-proxy-agent": "^4.0.1",
+                "https-proxy-agent": "^5.0.0",
+                "is-lambda": "^1.0.1",
+                "lru-cache": "^6.0.0",
+                "minipass": "^3.1.3",
+                "minipass-collect": "^1.0.2",
+                "minipass-fetch": "^1.3.2",
+                "minipass-flush": "^1.0.5",
+                "minipass-pipeline": "^1.2.4",
+                "negotiator": "^0.6.2",
+                "promise-retry": "^2.0.1",
+                "socks-proxy-agent": "^6.0.0",
+                "ssri": "^8.0.0"
+              }
+            }
+          }
+        },
+        "nopt": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
+          "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "abbrev": "1"
+          }
+        },
+        "socks-proxy-agent": {
+          "version": "6.2.1",
+          "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz",
+          "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "agent-base": "^6.0.2",
+            "debug": "^4.3.3",
+            "socks": "^2.6.2"
+          }
+        },
+        "ssri": {
+          "version": "8.0.1",
+          "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
+          "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "minipass": "^3.1.1"
+          }
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "unique-filename": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+          "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "unique-slug": "^2.0.0"
+          }
+        },
+        "unique-slug": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
+          "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "imurmurhash": "^0.1.4"
           }
+        },
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+          "dev": true,
+          "optional": true,
+          "peer": true
         }
       }
     },
-    "node-gyp-build": {
-      "version": "4.7.1",
-      "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.7.1.tgz",
-      "integrity": "sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg==",
-      "dev": true,
-      "optional": true
-    },
-    "node-releases": {
-      "version": "2.0.14",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
-      "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
-      "dev": true
-    },
     "nopt": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz",
@@ -27237,6 +30007,14 @@
       "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
       "dev": true
     },
+    "quick-lru": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
+      "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
     "randombytes": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -27302,6 +30080,83 @@
         }
       }
     },
+    "read-pkg": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
+      "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "requires": {
+        "@types/normalize-package-data": "^2.4.0",
+        "normalize-package-data": "^2.5.0",
+        "parse-json": "^5.0.0",
+        "type-fest": "^0.6.0"
+      },
+      "dependencies": {
+        "hosted-git-info": {
+          "version": "2.8.9",
+          "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+          "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+          "dev": true,
+          "optional": true,
+          "peer": true
+        },
+        "normalize-package-data": {
+          "version": "2.5.0",
+          "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+          "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "hosted-git-info": "^2.1.4",
+            "resolve": "^1.10.0",
+            "semver": "2 || 3 || 4 || 5",
+            "validate-npm-package-license": "^3.0.1"
+          }
+        },
+        "semver": {
+          "version": "5.7.2",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+          "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+          "dev": true,
+          "optional": true,
+          "peer": true
+        },
+        "type-fest": {
+          "version": "0.6.0",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
+          "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
+          "dev": true,
+          "optional": true,
+          "peer": true
+        }
+      }
+    },
+    "read-pkg-up": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
+      "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "requires": {
+        "find-up": "^4.1.0",
+        "read-pkg": "^5.2.0",
+        "type-fest": "^0.8.1"
+      },
+      "dependencies": {
+        "type-fest": {
+          "version": "0.8.1",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+          "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+          "dev": true,
+          "optional": true,
+          "peer": true
+        }
+      }
+    },
     "readable-stream": {
       "version": "3.6.2",
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -27322,6 +30177,18 @@
         "picomatch": "^2.2.1"
       }
     },
+    "redent": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
+      "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "requires": {
+        "indent-string": "^4.0.0",
+        "strip-indent": "^3.0.0"
+      }
+    },
     "reflect-metadata": {
       "version": "0.1.13",
       "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
@@ -27623,13 +30490,36 @@
         "source-map-js": ">=0.6.2 <2.0.0"
       }
     },
-    "sass-loader": {
-      "version": "13.3.2",
-      "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.2.tgz",
-      "integrity": "sha512-CQbKl57kdEv+KDLquhC+gE3pXt74LEAzm+tzywcA0/aHZuub8wTErbjAoNI57rPUWRYRNC5WUnNl8eGJNbDdwg==",
+    "sass-graph": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-4.0.1.tgz",
+      "integrity": "sha512-5YCfmGBmxoIRYHnKK2AKzrAkCoQ8ozO+iumT8K4tXJXRVCPf+7s1/9KxTSW3Rbvf+7Y7b4FR3mWyLnQr3PHocA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
-        "neo-async": "^2.6.2"
+        "glob": "^7.0.0",
+        "lodash": "^4.17.11",
+        "scss-tokenizer": "^0.4.3",
+        "yargs": "^17.2.1"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.2.3",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+          "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.1.1",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        }
       }
     },
     "saucelabs": {
@@ -27707,6 +30597,18 @@
         "ajv-keywords": "^5.0.0"
       }
     },
+    "scss-tokenizer": {
+      "version": "0.4.3",
+      "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.4.3.tgz",
+      "integrity": "sha512-raKLgf1LI5QMQnG+RxHz6oK0sL3x3I4FN2UDLqgLOGO8hodECNnNh5BXn7fAyBxrA8zVzdQizQ6XjNJQ+uBwMw==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "requires": {
+        "js-base64": "^2.4.9",
+        "source-map": "^0.7.3"
+      }
+    },
     "select-hose": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@@ -28368,6 +31270,55 @@
       "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
       "dev": true
     },
+    "stdout-stream": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
+      "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "requires": {
+        "readable-stream": "^2.0.1"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "2.3.8",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+          "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true,
+          "optional": true,
+          "peer": true
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "optional": true,
+          "peer": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
     "streamroller": {
       "version": "3.1.5",
       "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz",
@@ -28434,12 +31385,28 @@
       "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
       "dev": true
     },
+    "strip-indent": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
+      "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "requires": {
+        "min-indent": "^1.0.0"
+      }
+    },
     "strip-json-comments": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
       "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
       "dev": true
     },
+    "style-mod": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.0.tgz",
+      "integrity": "sha512-Ca5ib8HrFn+f+0n4N4ScTIA9iTOQ7MaGS1ylHcoVqW9J7w2w8PzN6g9gKmTYgGEBH8e120+RCmhpje6jC5uGWA=="
+    },
     "supports-color": {
       "version": "5.5.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -28540,16 +31507,16 @@
       }
     },
     "terser-webpack-plugin": {
-      "version": "5.3.7",
-      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz",
-      "integrity": "sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==",
+      "version": "5.3.10",
+      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
+      "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
       "dev": true,
       "requires": {
-        "@jridgewell/trace-mapping": "^0.3.17",
+        "@jridgewell/trace-mapping": "^0.3.20",
         "jest-worker": "^27.4.5",
         "schema-utils": "^3.1.1",
         "serialize-javascript": "^6.0.1",
-        "terser": "^5.16.5"
+        "terser": "^5.26.0"
       },
       "dependencies": {
         "ajv": {
@@ -28578,15 +31545,27 @@
           "dev": true
         },
         "schema-utils": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
-          "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+          "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
           "dev": true,
           "requires": {
             "@types/json-schema": "^7.0.8",
             "ajv": "^6.12.5",
             "ajv-keywords": "^3.5.2"
           }
+        },
+        "terser": {
+          "version": "5.27.0",
+          "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz",
+          "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==",
+          "dev": true,
+          "requires": {
+            "@jridgewell/source-map": "^0.3.3",
+            "acorn": "^8.8.2",
+            "commander": "^2.20.0",
+            "source-map-support": "~0.5.20"
+          }
         }
       }
     },
@@ -28692,6 +31671,22 @@
       "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
       "dev": true
     },
+    "trim-newlines": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
+      "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
+    "true-case-path": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz",
+      "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
     "ts-helpers": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/ts-helpers/-/ts-helpers-1.1.2.tgz",
@@ -29062,6 +32057,11 @@
         "browser-process-hrtime": "^1.0.0"
       }
     },
+    "w3c-keyname": {
+      "version": "2.2.8",
+      "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
+      "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
+    },
     "w3c-xmlserializer": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
@@ -29234,19 +32234,20 @@
       "dev": true
     },
     "webpack": {
-      "version": "5.88.2",
-      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz",
-      "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==",
+      "version": "5.90.0",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.0.tgz",
+      "integrity": "sha512-bdmyXRCXeeNIePv6R6tGPyy20aUobw4Zy8r0LUS2EWO+U+Ke/gYDgsCh7bl5rB6jPpr4r0SZa6dPxBxLooDT3w==",
       "dev": true,
+      "peer": true,
       "requires": {
         "@types/eslint-scope": "^3.7.3",
-        "@types/estree": "^1.0.0",
+        "@types/estree": "^1.0.5",
         "@webassemblyjs/ast": "^1.11.5",
         "@webassemblyjs/wasm-edit": "^1.11.5",
         "@webassemblyjs/wasm-parser": "^1.11.5",
         "acorn": "^8.7.1",
         "acorn-import-assertions": "^1.9.0",
-        "browserslist": "^4.14.5",
+        "browserslist": "^4.21.10",
         "chrome-trace-event": "^1.0.2",
         "enhanced-resolve": "^5.15.0",
         "es-module-lexer": "^1.2.1",
@@ -29260,7 +32261,7 @@
         "neo-async": "^2.6.2",
         "schema-utils": "^3.2.0",
         "tapable": "^2.1.1",
-        "terser-webpack-plugin": "^5.3.7",
+        "terser-webpack-plugin": "^5.3.10",
         "watchpack": "^2.4.0",
         "webpack-sources": "^3.2.3"
       },
@@ -29270,6 +32271,7 @@
           "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
           "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
           "dev": true,
+          "peer": true,
           "requires": {
             "fast-deep-equal": "^3.1.1",
             "fast-json-stable-stringify": "^2.0.0",
@@ -29282,6 +32284,7 @@
           "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
           "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
           "dev": true,
+          "peer": true,
           "requires": {}
         },
         "eslint-scope": {
@@ -29289,6 +32292,7 @@
           "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
           "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
           "dev": true,
+          "peer": true,
           "requires": {
             "esrecurse": "^4.3.0",
             "estraverse": "^4.1.1"
@@ -29298,19 +32302,22 @@
           "version": "4.3.0",
           "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
           "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
-          "dev": true
+          "dev": true,
+          "peer": true
         },
         "json-schema-traverse": {
           "version": "0.4.1",
           "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
           "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-          "dev": true
+          "dev": true,
+          "peer": true
         },
         "schema-utils": {
           "version": "3.3.0",
           "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
           "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
           "dev": true,
+          "peer": true,
           "requires": {
             "@types/json-schema": "^7.0.8",
             "ajv": "^6.12.5",
diff --git a/smp-angular/package.json b/smp-angular/package.json
index d8e128a3789785c8bd8b9080f9778c5006421e61..169ef34444e3a3974bb00dc320d519f2084c4be8 100644
--- a/smp-angular/package.json
+++ b/smp-angular/package.json
@@ -31,8 +31,11 @@
     "@swimlane/ngx-datatable": "^20.1.0",
     "@angular-material-components/datetime-picker": "^16.0.1",
     "@angular-material-components/moment-adapter": "^16.0.1",
-    "@ctrl/ngx-codemirror": "^7.0.0",
-    "codemirror": "^5.65.16",
+    "codemirror": "^6.0.1",
+    "@codemirror/language": "^6.10.0",
+    "@codemirror/language-data": "^6.3.1",
+    "@codemirror/theme-one-dark": "^6.1.2",
+    "@codemirror/merge": "^6.5.0",
     "file-saver": "^2.0.5",
     "rxjs": "^7.8.1",
     "ts-helpers": "^1.1.2",
@@ -60,4 +63,4 @@
   "peerDependencies": {
     "postcss": "^8.4.21"
   }
-}
\ No newline at end of file
+}
diff --git a/smp-angular/src/app/app.component.ts b/smp-angular/src/app/app.component.ts
index 721675e504cde616ec6985c891a198ad896dd0a3..21402f2d79faf6f50d8db513be1dd5fdd901562d 100644
--- a/smp-angular/src/app/app.component.ts
+++ b/smp-angular/src/app/app.component.ts
@@ -9,10 +9,6 @@ import {HttpClient} from "@angular/common/http";
 import {SidenavComponent} from "./window/sidenav/sidenav.component";
 import {ToolbarComponent} from "./window/toolbar/toolbar.component";
 import {ThemeService} from "./common/theme-service/theme.service";
-import 'codemirror/mode/javascript/javascript';
-import 'codemirror/mode/markdown/markdown';
-import 'codemirror/mode/xml/xml';
-import 'codemirror/mode/properties/properties';
 import {UserController} from "./common/services/user-controller";
 
 
diff --git a/smp-angular/src/app/app.module.ts b/smp-angular/src/app/app.module.ts
index 4958d4eb9cf4f53e15922fc6c1ef226eb4081489..28e510d58ebbd3c8edab03acb799743c289526a6 100644
--- a/smp-angular/src/app/app.module.ts
+++ b/smp-angular/src/app/app.module.ts
@@ -119,7 +119,6 @@ import {EditResourceComponent} from "./edit/edit-resources/edit-resource.compone
 import {EditResourceService} from "./edit/edit-resources/edit-resource.service";
 import {ResourceDetailsPanelComponent} from "./edit/edit-resources/resource-details-panel/resource-details-panel.component";
 import {ResourceDocumentPanelComponent} from "./edit/edit-resources/resource-document-panel/resource-document-panel.component";
-import { CodemirrorModule } from '@ctrl/ngx-codemirror';
 import {DocumentWizardDialogComponent} from "./edit/edit-resources/document-wizard-dialog/document-wizard-dialog.component";
 import {SubresourcePanelComponent} from "./edit/edit-resources/subresource-panel/subresource-panel.component";
 import {SubresourceDialogComponent} from "./edit/edit-resources/subresource-panel/resource-dialog/subresource-dialog.component";
@@ -141,6 +140,8 @@ import {
   PropertyDetailsDialogComponent
 } from "./system-settings/admin-properties/property-details-dialog/property-details-dialog.component";
 import {UserAlertsComponent} from "./user-settings/user-alerts/user-alerts.component";
+import {SmpEditorComponent} from "./common/components/smp-editor/smp-editor.component";
+
 
 @NgModule({
   declarations: [
@@ -161,6 +162,7 @@ import {UserAlertsComponent} from "./user-settings/user-alerts/user-alerts.compo
     CertificateDialogComponent,
     CertificatePanelComponent,
     ClearInvalidDirective,
+    SmpEditorComponent,
     ColumnPickerComponent,
     ConfirmationDialogComponent,
     CredentialDialogComponent,
@@ -261,7 +263,6 @@ import {UserAlertsComponent} from "./user-settings/user-alerts/user-alerts.compo
     ReactiveFormsModule,
     routing,
     MatAutocompleteModule,
-    CodemirrorModule,
     ClipboardModule,
   ],
   providers: [
diff --git a/smp-angular/src/app/common/components/smp-editor/smp-editor.component.css b/smp-angular/src/app/common/components/smp-editor/smp-editor.component.css
new file mode 100644
index 0000000000000000000000000000000000000000..40f877779fd4d6868d776a3d5096024c43410169
--- /dev/null
+++ b/smp-angular/src/app/common/components/smp-editor/smp-editor.component.css
@@ -0,0 +1,3 @@
+.cm-gutters {
+  padding-top: 1.4em;
+}
diff --git a/smp-angular/src/app/common/components/smp-editor/smp-editor.component.html b/smp-angular/src/app/common/components/smp-editor/smp-editor.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..b11a0efcc28880bce42a12170fbb6f64dd0de7bc
--- /dev/null
+++ b/smp-angular/src/app/common/components/smp-editor/smp-editor.component.html
@@ -0,0 +1,2 @@
+<div #editorRoot id="editorRoot">
+</div>
diff --git a/smp-angular/src/app/common/components/smp-editor/smp-editor.component.ts b/smp-angular/src/app/common/components/smp-editor/smp-editor.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6fcd18ca67511801ba647e28540f08106bad089e
--- /dev/null
+++ b/smp-angular/src/app/common/components/smp-editor/smp-editor.component.ts
@@ -0,0 +1,201 @@
+import {
+  AfterViewInit,
+  Component,
+  ElementRef,
+  forwardRef,
+  Input,
+  OnDestroy,
+  ViewChild,
+} from '@angular/core';
+import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
+import {EditorView} from "@codemirror/view";
+import {basicSetup} from "codemirror";
+import {Compartment, EditorState, Extension} from "@codemirror/state"
+import {LanguageSupport} from "@codemirror/language"
+import {javascript} from "@codemirror/lang-javascript"
+import {xml} from "@codemirror/lang-xml"
+import {html} from "@codemirror/lang-html"
+import {json} from "@codemirror/lang-json"
+import {ThemeService} from "../../theme-service/theme.service";
+import {oneDark} from "@codemirror/theme-one-dark";
+
+function normalizeLineEndings(str: string): string {
+  if (!str) {
+    return str;
+  }
+  return str.replace(/\r\n|\r/g, '\n');
+}
+
+@Component({
+  selector: 'smp-editor',
+  templateUrl: './smp-editor.component.html',
+  styleUrls: ['./smp-editor.component.css'],
+  providers: [
+    {
+      provide: NG_VALUE_ACCESSOR,
+      useExisting: forwardRef(() => SmpEditorComponent),
+      multi: true
+    }
+  ]
+})
+export class SmpEditorComponent
+  implements AfterViewInit, OnDestroy, ControlValueAccessor {
+  /* class applied to the created textarea */
+  @Input() className = '';
+  /* name applied to the created textarea */
+  @Input() name = 'smpEditor';
+  @ViewChild('editorRoot') ref!: ElementRef<HTMLDivElement>;
+  value = '';
+  _readOnly:boolean = false;
+  _mimeType: string = "text/xml";
+
+  codeMirror: EditorView;
+  readOnlyDocument = new Compartment;
+  documentLanguage = new Compartment;
+  themeConfig = new Compartment;
+
+  constructor( private  themeService: ThemeService) {
+  }
+
+  ngAfterViewInit() {
+
+    let updateListenerExtension = EditorView.updateListener.of((update) => {
+      if (update.docChanged) {
+        this.onChange(update.view.state.doc.toString());
+      }
+    });
+    // configure the default extensions
+    let initExtensions: Extension[] =  [
+        basicSetup,
+        EditorView.lineWrapping,
+        updateListenerExtension,
+        this.documentLanguage.of(xml()),
+        this.readOnlyDocument.of(EditorState.readOnly.of(false))
+      ];
+    // add the dark theme extension
+    if (this.themeService.currentTheme === "pink_blue-grey_theme"
+      || this.themeService.currentTheme === "purple_green_theme" ) {
+      initExtensions.push(this.themeConfig.of(oneDark));
+    }
+    this.codeMirror = new EditorView({
+      extensions: initExtensions,
+      parent: this.ref.nativeElement
+    })
+  }
+
+  @Input() set mimeType(mime: string) {
+    this._mimeType = mime;
+    this.codeMirror?.dispatch({
+      effects: this.documentLanguage.reconfigure(this.getLanguagePack)
+    })
+  }
+
+  get mimeType(): string {
+    return this._mimeType;
+  }
+
+  @Input() set readOnly(readOnly: boolean) {
+    this._readOnly = readOnly;
+    this.codeMirror?.dispatch({
+      effects: this.readOnlyDocument.reconfigure(EditorState.readOnly.of(readOnly))
+    })
+  }
+
+  get readOnly(): boolean {
+    return this._readOnly;
+  }
+
+  get hasFocus(): boolean {
+    return this.codeMirror.hasFocus;
+  }
+
+  /**
+   *  puts focus on editor instance
+   */
+  focus(): void {
+    this.codeMirror.focus();
+  }
+
+  /**
+   *  puts focus on editor instance
+   */
+  focusAndCursorToEnd(): void {
+    this.focus();
+    let length = this.codeMirror.state.doc.length
+    this.codeMirror.dispatch({selection: {anchor: length, head: length}})
+  }
+
+
+  ngOnDestroy() {
+    // is there a lighter-weight way to remove the cm instance?
+    if (this.codeMirror) {
+      //this.codeMirror.toTextArea();
+    }
+  }
+
+  get getLanguagePack(): LanguageSupport {
+    console.log("getLanguagePack")
+    //mime to codemirror language
+    let langSupport = javascript();
+    if (this.mimeType == "text/xml"
+      || this.mimeType == "application/xml") {
+      langSupport = xml();
+    } else if (this.mimeType == "text/javascript") {
+      langSupport = javascript();
+    } else if (this.mimeType == "text/html"
+      || this.mimeType == "application/xhtml+xml") {
+      langSupport = html();
+    } else if (this.mimeType == "application/json") {
+      langSupport = json();
+    } else if (this.mimeType == "text/x-properties") {
+      langSupport = javascript();
+    }
+    return langSupport;
+  }
+
+
+  /** Implemented as part of ControlValueAccessor. */
+  writeValue(value: string) {
+    if (value === null || value === undefined) {
+      return;
+    }
+    if (!this.codeMirror) {
+      this.value = value;
+      return;
+    }
+    const cur = this.codeMirror.state.doc.toString();
+
+    if (value !== cur && normalizeLineEndings(cur) !== normalizeLineEndings(value)) {
+      this.value = value;
+      let transaction = this.codeMirror.state.update({
+        changes: {
+          from: 0,
+          to: this.codeMirror.state.doc.length, insert: value
+        }
+      })
+      this.codeMirror.dispatch(transaction)
+    }
+  }
+
+  /** Implemented as part of ControlValueAccessor. */
+  registerOnChange(fn: (value: string) => void) {
+    this.onChange = fn;
+  }
+
+  /** Implemented as part of ControlValueAccessor. */
+  registerOnTouched(fn: () => void) {
+    this.onTouched = fn;
+  }
+
+  /** Implemented as part of ControlValueAccessor. */
+  setDisabledState(isDisabled: boolean) {
+    this.readOnly = isDisabled;
+  }
+
+  /** Implemented as part of ControlValueAccessor. */
+  private onChange = (_: any) => {
+  };
+  /** Implemented as part of ControlValueAccessor. */
+  private onTouched = () => {
+  };
+}
diff --git a/smp-angular/src/app/common/panels/membership-panel/membership-panel.component.html b/smp-angular/src/app/common/panels/membership-panel/membership-panel.component.html
index 287e139c5c4b0a2dd653f5989c39492c67b8670f..7465e4ff2dcbcabaed88e05dda456b975e6cfdb6 100644
--- a/smp-angular/src/app/common/panels/membership-panel/membership-panel.component.html
+++ b/smp-angular/src/app/common/panels/membership-panel/membership-panel.component.html
@@ -86,7 +86,6 @@
                    (page)="onPageChanged($event)"
                    [hidePageSize]="true"
                    [pageSize]="pageSize"
-                   [showFirstLastButtons]="true"
                    [disabled]="entityNotSelected"
                    aria-label="Select pages"></mat-paginator>
   </div>
diff --git a/smp-angular/src/app/common/theme-service/theme.service.ts b/smp-angular/src/app/common/theme-service/theme.service.ts
index d5cb426215f0c8c39ac1dc4798c5b7a891adbf53..cbd5084e77554b90f6c33f23dcd75895044ed539 100644
--- a/smp-angular/src/app/common/theme-service/theme.service.ts
+++ b/smp-angular/src/app/common/theme-service/theme.service.ts
@@ -1,4 +1,4 @@
-import {Injectable} from '@angular/core';
+import {EventEmitter, Injectable} from '@angular/core';
 import {SecurityEventService} from "../../security/security-event.service";
 
 
@@ -43,6 +43,8 @@ export interface ThemeItem {
  */
 @Injectable()
 export class ThemeService {
+
+  selectedTheme: EventEmitter<string> = new EventEmitter<string>();
   private static THEME_STORAGE_NAME = "smp-theme";
   private static DEFAULT_THEME_NAME = "default_theme";
 
@@ -61,6 +63,10 @@ export class ThemeService {
 
   }
 
+  getThemeChangedEventEmitter(): EventEmitter<string> {
+    return this.selectedTheme;
+  }
+
   get themes(): ThemeItem[] {
     return SMP_THEME_ITEMS;
   }
@@ -70,12 +76,12 @@ export class ThemeService {
    * @param theme
    */
   setTheme(theme: string) {
-    console.log("set theme" + theme)
     this.resetTheme();
     if (!!theme) {
       let body = document.getElementsByTagName('body')[0]
       body.classList.add(theme)
     }
+    this.selectedTheme.emit(theme);
   };
 
   /**
diff --git a/smp-angular/src/app/edit/edit-domain/domain-group-panel/domain-group.component.html b/smp-angular/src/app/edit/edit-domain/domain-group-panel/domain-group.component.html
index fb4675ca0f77bd7c2096cad706c354bb853f4a90..f0fccb5208462bfd4f825f5975211436bb426c24 100644
--- a/smp-angular/src/app/edit/edit-domain/domain-group-panel/domain-group.component.html
+++ b/smp-angular/src/app/edit/edit-domain/domain-group-panel/domain-group.component.html
@@ -84,7 +84,6 @@
 
     <mat-paginator class="mat-elevation-z2" [length]="resultsLength"
                    [hidePageSize]="true"
-                   [showFirstLastButtons]="true"
                    [pageSize]="5"
                    [disabled]="domainNotSelected"
                    aria-label="Select pages"></mat-paginator>
diff --git a/smp-angular/src/app/edit/edit-domain/edit-domain.component.html b/smp-angular/src/app/edit/edit-domain/edit-domain.component.html
index e3fbd8612958253f5bc8ab7a688a46a034febd53..ac36184ffacf178a748c3414ce6731ede9b2b53f 100644
--- a/smp-angular/src/app/edit/edit-domain/edit-domain.component.html
+++ b/smp-angular/src/app/edit/edit-domain/edit-domain.component.html
@@ -65,7 +65,6 @@
 
   <mat-paginator class="mat-elevation-z2" id="edit-domain-paginator" #editDomainPaginator
                  [hidePageSize]="true"
-                 [showFirstLastButtons]="true"
                  [pageSize]="5"
                  aria-label="Select page"></mat-paginator>
 </ng-template>
diff --git a/smp-angular/src/app/edit/edit-group/group-resource-panel/group-resource-panel.component.html b/smp-angular/src/app/edit/edit-group/group-resource-panel/group-resource-panel.component.html
index 1d1cf29fe5a9aa807c3ae5fe84fc6291ef477dc1..5b454b161cd48e5587abe2b15b4f3c1bb105bdb0 100644
--- a/smp-angular/src/app/edit/edit-group/group-resource-panel/group-resource-panel.component.html
+++ b/smp-angular/src/app/edit/edit-group/group-resource-panel/group-resource-panel.component.html
@@ -82,7 +82,6 @@
     <mat-paginator class="mat-elevation-z2" [length]="resultsLength"
                    (page)="onPageChanged($event)"
                    [hidePageSize]="true"
-                   [showFirstLastButtons]="true"
                    [pageSize]="5"
                    [disabled]="disabledForm"
                    aria-label="Select pages"></mat-paginator>
diff --git a/smp-angular/src/app/edit/edit-resources/edit-resource.component.html b/smp-angular/src/app/edit/edit-resources/edit-resource.component.html
index fbda8325e872e29450d93f46ca12921f9782f226..13024006bebfa998f689382f6b38e5b7c2b0860e 100644
--- a/smp-angular/src/app/edit/edit-resources/edit-resource.component.html
+++ b/smp-angular/src/app/edit/edit-resources/edit-resource.component.html
@@ -5,7 +5,7 @@
               [labelColumnContent]="searchGroupPanel">
 
     <mat-tab-group #domainTabs
-                   *ngIf="!!resourceList && resourceList.length>0;else noUserAdminGroupsDataFound"
+                   *ngIf="hasResources;else noUserAdminGroupsDataFound"
                    style="height: 100%">
       <mat-tab>
         <ng-template mat-tab-label>
@@ -55,7 +55,7 @@
 
 <ng-template #searchGroupPanel>
   <div
-    *ngIf="!!resourceList &&  resourceList.length>0 || filterResourceResults "
+    *ngIf="hasResources || filterResourceResults "
   >
     <mat-form-field style="width:100%">
       <mat-label>Selected domain</mat-label>
@@ -101,7 +101,7 @@
                  #inputDomainMemberFilter>
         </mat-form-field>
 
-        <table class="mat-elevation-z2" mat-table [dataSource]="resourceList">
+        <table class="mat-elevation-z2" mat-table [dataSource]="dataSource">
 
           <ng-container matColumnDef="identifierScheme">
             <th mat-header-cell *matHeaderCellDef>Scheme</th>
@@ -135,7 +135,6 @@
       <mat-paginator class="mat-elevation-z2" [length]="resultsLength"
                      (page)="onPageChanged($event)"
                      [hidePageSize]="true"
-                     [showFirstLastButtons]="true"
                      [pageSize]="5"
                      aria-label="Select pages"></mat-paginator>
     </div>
diff --git a/smp-angular/src/app/edit/edit-resources/edit-resource.component.ts b/smp-angular/src/app/edit/edit-resources/edit-resource.component.ts
index e207ebd0e9c4949de1daebf36575ec8e84e6a16f..e34c09a08695c2e7cf46a1f59b5596c58743eb36 100644
--- a/smp-angular/src/app/edit/edit-resources/edit-resource.component.ts
+++ b/smp-angular/src/app/edit/edit-resources/edit-resource.component.ts
@@ -7,6 +7,7 @@ import {MemberTypeEnum} from "../../common/enums/member-type.enum";
 import {ResourceDefinitionRo} from "../../system-settings/admin-extension/resource-definition-ro.model";
 import {ResourceRo} from "../../common/model/resource-ro.model";
 import {EditResourceController} from "./edit-resource.controller";
+import {MatTableDataSource} from "@angular/material/table";
 
 
 @Component({
@@ -15,19 +16,17 @@ import {EditResourceController} from "./edit-resource.controller";
 })
 export class EditResourceComponent implements OnInit, BeforeLeaveGuard {
   groupMembershipType: MemberTypeEnum = MemberTypeEnum.RESOURCE;
-
-
   displayedColumns: string[] = ['identifierValue', 'identifierScheme'];
-
   selected: ResourceRo;
   filter: any = {};
   resultsLength = 0;
   isLoadingResults = false;
 
+  dataSource: MatTableDataSource<ResourceRo>;
   @ViewChild(MatPaginator) paginator: MatPaginator;
 
   constructor(private editResourceController: EditResourceController) {
-
+    this.dataSource  = editResourceController;
   }
 
   ngOnInit() {
@@ -37,16 +36,21 @@ export class EditResourceComponent implements OnInit, BeforeLeaveGuard {
     }
   }
 
+  ngAfterViewInit():void {
+    // bind data to resource controller
+    this.dataSource.paginator = this.paginator;
+  }
+
+
   applyResourceFilter(event: Event) {
     const filterValue = (event.target as HTMLInputElement).value;
     this.editResourceController.filter["filter"] = filterValue.trim().toLowerCase();
     this.editResourceController.refreshResources();
   }
 
-  get resourceList(): ResourceRo[] {
-    return this.editResourceController.resourceList;
-  };
-
+  get hasResources(): boolean {
+    return this.editResourceController.data?.length > 0;
+  }
   get domainList(): DomainRo[] {
     return this.editResourceController.domainList;
   };
diff --git a/smp-angular/src/app/edit/edit-resources/edit-resource.controller.ts b/smp-angular/src/app/edit/edit-resources/edit-resource.controller.ts
index b4f54273f87c2092c61b0e15c309f8b9c8a902c1..be213942fc01800941d40ce9928aa0d753af7dd2 100644
--- a/smp-angular/src/app/edit/edit-resources/edit-resource.controller.ts
+++ b/smp-angular/src/app/edit/edit-resources/edit-resource.controller.ts
@@ -8,6 +8,7 @@ import {EditResourceService} from "./edit-resource.service";
 import {EditDomainService} from "../edit-domain/edit-domain.service";
 import {EditGroupService} from "../edit-group/edit-group.service";
 import {AlertMessageService} from "../../common/alert-message/alert-message.service";
+import {MatTableDataSource} from "@angular/material/table";
 
 /**
  * The purpose of the EditResourceController is to  control the data of edit resource components when navigating
@@ -17,11 +18,10 @@ import {AlertMessageService} from "../../common/alert-message/alert-message.serv
  * @since 5.1
  */
 @Injectable()
-export class EditResourceController {
+export class EditResourceController extends MatTableDataSource<ResourceRo>{
 
   domainList: DomainRo[] = [];
   groupList: GroupRo[] = [];
-  resourceList: ResourceRo[] = [];
 
   _selectedDomain: DomainRo;
   _selectedGroup: GroupRo;
@@ -30,7 +30,7 @@ export class EditResourceController {
 
   pageIndex: number = 0;
   pageSize: number = 10;
-  filter: any = {};
+  filterResources: any = {};
   isLoadingResults = false;
 
 
@@ -40,6 +40,7 @@ export class EditResourceController {
     private resourceService: EditResourceService,
     private alertService: AlertMessageService,
   ) {
+    super();
   }
 
   get selectedDomain(): DomainRo {
@@ -68,7 +69,7 @@ export class EditResourceController {
       this.refreshResources();
     } else {
       this.isLoadingResults = false;
-      this.resourceList = [];
+      this.data = [];
     }
   };
 
@@ -119,9 +120,8 @@ export class EditResourceController {
     }
     this.isLoadingResults = true;
     this.resourceService.getGroupResourcesForResourceAdminObservable(this.selectedGroup, this.selectedDomain,
-      this.filter, this.pageIndex, this.pageSize)
+      this.filterResources, this.pageIndex, this.pageSize)
       .subscribe((result: TableResult<ResourceRo>) => {
-        console.log("got resources: " + JSON.stringify(result))
         this.updateResourceList(result.serviceEntities)
         this.isLoadingResults = false;
       }, (error: any) => {
@@ -133,7 +133,6 @@ export class EditResourceController {
   refreshDomainsResourceDefinitions() {
     this.domainService.getDomainResourceDefinitionsObservable(this.selectedDomain)
       .subscribe((result: ResourceDefinitionRo[]) => {
-        console.log("got resource definitions: " + JSON.stringify(result))
         this._selectedDomainResourceDefs = result
       }, (error: any) => {
         this.alertService.error(error.error?.errorDescription)
@@ -159,20 +158,21 @@ export class EditResourceController {
   }
 
   updateResourceList(list: ResourceRo[]) {
-    this.resourceList = list
-    if (!!this.resourceList && this.resourceList.length > 0) {
-      this.selectedResource = this.resourceList[0];
+    this.data = list;
+    // select first resource by default
+    if (!!list && list.length > 0) {
+      this.selectedResource = list[0];
     }
   }
 
   applyResourceFilter(event: Event) {
     const filterValue = (event.target as HTMLInputElement).value;
-    this.filter["filter"] = filterValue.trim().toLowerCase();
+    this.filterResources["filter"] = filterValue.trim().toLowerCase();
     this.refreshResources();
   }
 
   get filterResourceResults(): boolean {
-    return !!this.filter["filter"]
+    return !!this.filterResources["filter"]
   }
 
   get disabledResourceFilter(): boolean {
diff --git a/smp-angular/src/app/edit/edit-resources/resource-document-panel/resource-document-panel.component.html b/smp-angular/src/app/edit/edit-resources/resource-document-panel/resource-document-panel.component.html
index 87d426a06526a45148e77950a749882a547a0c43..2f33d49d375644b61eea10e70d34bb10a1c581c9 100644
--- a/smp-angular/src/app/edit/edit-resources/resource-document-panel/resource-document-panel.component.html
+++ b/smp-angular/src/app/edit/edit-resources/resource-document-panel/resource-document-panel.component.html
@@ -81,14 +81,13 @@
 
   <div [formGroup]="documentForm" style="width: 100%; display: flex; flex-direction: column; flex:1; gap:0.5em ">
     <div
-      style="display:block; overflow: auto;flex: 2;align-self: stretch; flex-direction: column;background-color: #FCFCFCBB; border: ridge 3px #b0bec5"
+      style="display:block; overflow: auto;flex: 2;align-self: stretch; flex-direction: column;border: ridge 3px #b0bec5"
       (click)="onEditPanelClick()"
     >
-      <ngx-codemirror #codemirror
+      <smp-editor #smpDocumentEditor
                       formControlName="payload"
-                      [options]="codemirrorOptions"
-                      ngDefaultControl
-      ></ngx-codemirror>
+                  ngDefaultControl
+      ></smp-editor>
     </div>
     <mat-toolbar class="mat-elevation-z2" style="flex-grow: 0">
       <mat-toolbar-row class="smp-toolbar-row">
diff --git a/smp-angular/src/app/edit/edit-resources/resource-document-panel/resource-document-panel.component.ts b/smp-angular/src/app/edit/edit-resources/resource-document-panel/resource-document-panel.component.ts
index 3b3566ba9344808b4d373b9fbf94dba9cae362b1..b9f4d146aac0039a847822b92fdceac36ee0be3e 100644
--- a/smp-angular/src/app/edit/edit-resources/resource-document-panel/resource-document-panel.component.ts
+++ b/smp-angular/src/app/edit/edit-resources/resource-document-panel/resource-document-panel.component.ts
@@ -8,11 +8,11 @@ import {DomainRo} from "../../../common/model/domain-ro.model";
 import {ResourceDefinitionRo} from "../../../system-settings/admin-extension/resource-definition-ro.model";
 import {EditResourceService} from "../edit-resource.service";
 import {FormBuilder, FormControl, FormGroup} from "@angular/forms";
-import {CodemirrorComponent} from "@ctrl/ngx-codemirror";
 import {DocumentRo} from "../../../common/model/document-ro.model";
 import {NavigationService} from "../../../window/sidenav/navigation-model.service";
 import {DocumentWizardDialogComponent} from "../document-wizard-dialog/document-wizard-dialog.component";
 import {ConfirmationDialogComponent} from "../../../common/dialogs/confirmation-dialog/confirmation-dialog.component";
+import {SmpEditorComponent} from "../../../common/components/smp-editor/smp-editor.component";
 
 @Component({
   templateUrl: './resource-document-panel.component.html',
@@ -28,14 +28,8 @@ export class ResourceDocumentPanelComponent implements AfterViewInit, BeforeLeav
   @Input() domain: DomainRo;
   @Input() domainResourceDefs: ResourceDefinitionRo[];
 
-  @ViewChild("codemirror") codemirror: CodemirrorComponent;
-// code mirror configuration
-  codemirrorOptions = {
-    lineNumbers: true,
-    lineWrapping: true,
-    viewportMargin: Infinity,
-    mode: 'xml'
-  };
+  @ViewChild("smpDocumentEditor") documentEditor: SmpEditorComponent;
+
 
   resourceForm: FormGroup;
   documentForm: FormGroup;
@@ -104,7 +98,7 @@ export class ResourceDocumentPanelComponent implements AfterViewInit, BeforeLeav
     this._document = value;
     this.documentForm.disable();
     if (!!value) {
-      this.codemirror.setOptionIfChanged("mode", value.mimeType);
+      this.documentEditor.mimeType = value.mimeType;
       this.documentForm.controls['mimeType'].setValue(value.mimeType);
       this.documentForm.controls['name'].setValue(value.name);
       this.documentForm.controls['currentResourceVersion'].setValue(value.currentResourceVersion);
@@ -238,16 +232,11 @@ export class ResourceDocumentPanelComponent implements AfterViewInit, BeforeLeav
   }
 
   public onEditPanelClick() {
-    if (this.codemirror.codeMirror.hasFocus()) {
+
+    if (this.documentEditor.hasFocus) {
       return;
     }
-    let endPosition: number = this._document?.payload?.length;
-    if (endPosition) {
-      // forward focus to "codeMirror"
-      this.codemirror.codeMirror.setCursor(endPosition)
-    }
-    this.codemirror.codeMirror.focus()
-
+    this.documentEditor.focusAndCursorToEnd();
   }
 
   get getDocumentVersions(): number[] {
diff --git a/smp-angular/src/app/edit/edit-resources/subresource-document-panel/subresource-document-panel.component.html b/smp-angular/src/app/edit/edit-resources/subresource-document-panel/subresource-document-panel.component.html
index e449be2b4344915eca18ea22e62d9c576f07d8a0..3dcbe7efcc2a1e413c4001488ef23537c4f8885f 100644
--- a/smp-angular/src/app/edit/edit-resources/subresource-document-panel/subresource-document-panel.component.html
+++ b/smp-angular/src/app/edit/edit-resources/subresource-document-panel/subresource-document-panel.component.html
@@ -86,11 +86,10 @@
       style="display:block; overflow: auto;flex: 2;align-self: stretch; flex-direction: column;background-color: #FCFCFCBB; border: ridge 3px #b0bec5"
       (click)="onEditPanelClick()"
     >
-      <ngx-codemirror #codemirror
-                      formControlName="payload"
-                      [options]="codemirrorOptions"
-                      ngDefaultControl
-      ></ngx-codemirror>
+      <smp-editor #smpDocumentEditor
+                  formControlName="payload"
+                  ngDefaultControl
+      ></smp-editor>
     </div>
     <mat-toolbar class="mat-elevation-z2" style="flex-grow: 0">
       <mat-toolbar-row class="smp-toolbar-row">
diff --git a/smp-angular/src/app/edit/edit-resources/subresource-document-panel/subresource-document-panel.component.ts b/smp-angular/src/app/edit/edit-resources/subresource-document-panel/subresource-document-panel.component.ts
index 80a5ae896322a519deed7ff596b26e099b3168f0..37990409b684fa6c1fe9a8c112f6d720ad2cf2fd 100644
--- a/smp-angular/src/app/edit/edit-resources/subresource-document-panel/subresource-document-panel.component.ts
+++ b/smp-angular/src/app/edit/edit-resources/subresource-document-panel/subresource-document-panel.component.ts
@@ -8,7 +8,6 @@ import {DomainRo} from "../../../common/model/domain-ro.model";
 import {ResourceDefinitionRo} from "../../../system-settings/admin-extension/resource-definition-ro.model";
 import {EditResourceService} from "../edit-resource.service";
 import {FormBuilder, FormControl, FormGroup} from "@angular/forms";
-import {CodemirrorComponent} from "@ctrl/ngx-codemirror";
 import {DocumentRo} from "../../../common/model/document-ro.model";
 import {NavigationService} from "../../../window/sidenav/navigation-model.service";
 import {SubresourceRo} from "../../../common/model/subresource-ro.model";
@@ -19,6 +18,7 @@ import {
   SubresourceWizardRo
 } from "../subresource-document-wizard-dialog/subresource-wizard-edit-ro.model";
 import {ConfirmationDialogComponent} from "../../../common/dialogs/confirmation-dialog/confirmation-dialog.component";
+import {SmpEditorComponent} from "../../../common/components/smp-editor/smp-editor.component";
 
 @Component({
   templateUrl: './subresource-document-panel.component.html',
@@ -36,14 +36,7 @@ export class SubresourceDocumentPanelComponent implements AfterViewInit, BeforeL
   @Input() domain: DomainRo;
   @Input() domainResourceDefs: ResourceDefinitionRo[];
 
-  @ViewChild("codemirror") codemirror: CodemirrorComponent;
-// code mirror configuration
-  codemirrorOptions = {
-    lineNumbers: true,
-    lineWrapping: true,
-    viewportMargin: Infinity,
-    mode: 'xml'
-  };
+  @ViewChild("smpDocumentEditor") documentEditor: SmpEditorComponent;
 
   resourceForm: FormGroup;
   subresourceForm: FormGroup;
@@ -54,19 +47,19 @@ export class SubresourceDocumentPanelComponent implements AfterViewInit, BeforeL
               private dialog: MatDialog,
               private navigationService: NavigationService,
               private formBuilder: FormBuilder) {
-    this.resourceForm = formBuilder.group({
+    this.resourceForm = this.formBuilder.group({
       'identifierValue': new FormControl({value: null}),
       'identifierScheme': new FormControl({value: null}),
       'visibility': new FormControl({value: null}),
       'resourceTypeIdentifier': new FormControl({value: null}),
     });
-    this.subresourceForm = formBuilder.group({
+    this.subresourceForm = this.formBuilder.group({
       'identifierValue': new FormControl({value: null}),
       'identifierScheme': new FormControl({value: null}),
       'subresourceTypeIdentifier': new FormControl({value: null}),
     });
 
-    this.documentForm = formBuilder.group({
+    this.documentForm = this.formBuilder.group({
       'mimeType': new FormControl({value: null}),
       'name': new FormControl({value: null}),
       'currentResourceVersion': new FormControl({value: null}),
@@ -264,16 +257,10 @@ export class SubresourceDocumentPanelComponent implements AfterViewInit, BeforeL
   }
 
   public onEditPanelClick() {
-    if (this.codemirror.codeMirror.hasFocus()) {
+    if (this.documentEditor.hasFocus) {
       return;
     }
-    let endPosition: number = this._document?.payload?.length;
-    if (endPosition) {
-      // forward focus to "codeMirror"
-      this.codemirror.codeMirror.setCursor(endPosition)
-    }
-    this.codemirror.codeMirror.focus()
-
+    this.documentEditor.focusAndCursorToEnd();
   }
 
   get getDocumentVersions(): number[] {
diff --git a/smp-angular/src/app/edit/edit-resources/subresource-panel/subresource-panel.component.html b/smp-angular/src/app/edit/edit-resources/subresource-panel/subresource-panel.component.html
index 8a34e543330ef5d805f77cd378de9f8d937488a7..905c648ea0a7f382d025ed8b11fa64885874db1d 100644
--- a/smp-angular/src/app/edit/edit-resources/subresource-panel/subresource-panel.component.html
+++ b/smp-angular/src/app/edit/edit-resources/subresource-panel/subresource-panel.component.html
@@ -73,7 +73,6 @@
 
     <mat-paginator class="mat-elevation-z2"
                    [hidePageSize]="true"
-                   [showFirstLastButtons]="true"
                    [pageSize]="5"
                    [disabled]="disabledForm"
                    aria-label="Select pages"></mat-paginator>
diff --git a/smp-angular/src/app/system-settings/admin-domain/admin-domain.component.html b/smp-angular/src/app/system-settings/admin-domain/admin-domain.component.html
index 9d9a25deb02c8f2eec7f14abad43f29ba67e98d8..2088b5d14f7329ed0530874edcd550ccfe9ef8a5 100644
--- a/smp-angular/src/app/system-settings/admin-domain/admin-domain.component.html
+++ b/smp-angular/src/app/system-settings/admin-domain/admin-domain.component.html
@@ -101,7 +101,6 @@
 
   <mat-paginator class="mat-elevation-z2" id="domain-paginator"
                  [hidePageSize]="true"
-                 [showFirstLastButtons]="true"
                  [pageSize]="5"
                  aria-label="Select page"></mat-paginator>
 
diff --git a/smp-angular/src/app/system-settings/admin-extension/extension-panel/extension-panel.component.html b/smp-angular/src/app/system-settings/admin-extension/extension-panel/extension-panel.component.html
index ecddf629c834528e9d1c38a73cc0669176ed35b7..83e33e1b9176dee8fc21220ab7e717a765760eb6 100644
--- a/smp-angular/src/app/system-settings/admin-extension/extension-panel/extension-panel.component.html
+++ b/smp-angular/src/app/system-settings/admin-extension/extension-panel/extension-panel.component.html
@@ -70,7 +70,6 @@
 
   <mat-paginator class="mat-elevation-z2" #resourcePaginator
                  [hidePageSize]="true"
-                 [showFirstLastButtons]="true"
                  [pageSize]="5" aria-label="Select page"></mat-paginator>
 
 </div>
diff --git a/smp-angular/src/app/system-settings/admin-extension/extension.component.html b/smp-angular/src/app/system-settings/admin-extension/extension.component.html
index a7b9c0cd078a277c5833f9aa9570e6cd6b2d4e66..02e9a662c52582b92fb839f733ef034d81516ac8 100644
--- a/smp-angular/src/app/system-settings/admin-extension/extension.component.html
+++ b/smp-angular/src/app/system-settings/admin-extension/extension.component.html
@@ -50,7 +50,6 @@
 
   <mat-paginator class="mat-elevation-z2" id="extension-paginator"
                  [hidePageSize]="true"
-                 [showFirstLastButtons]="true"
                  [pageSize]="5" aria-label="Select page"></mat-paginator>
 
 </ng-template>
diff --git a/smp-angular/src/app/system-settings/admin-extension/resource-details-dialog/resource-details-dialog.component.html b/smp-angular/src/app/system-settings/admin-extension/resource-details-dialog/resource-details-dialog.component.html
index 1f11d2c57e32cffebd0e765a386ca117aeef004d..53ce0483c85b57fce6db342e655ab7808a071216 100644
--- a/smp-angular/src/app/system-settings/admin-extension/resource-details-dialog/resource-details-dialog.component.html
+++ b/smp-angular/src/app/system-settings/admin-extension/resource-details-dialog/resource-details-dialog.component.html
@@ -72,7 +72,6 @@
 
       <mat-paginator #resourcePaginator
                      [hidePageSize]="true"
-                     [showFirstLastButtons]="true"
                      [pageSize]="5" aria-label="Select page"></mat-paginator>
     </div>
 
diff --git a/smp-angular/src/app/system-settings/admin-keystore/admin-keystore.component.html b/smp-angular/src/app/system-settings/admin-keystore/admin-keystore.component.html
index 06792a74f4aa593484eb362ff2e5931457dfd8d0..f5fb37fd0a03936b435e8f50c05e088dd651a0b2 100644
--- a/smp-angular/src/app/system-settings/admin-keystore/admin-keystore.component.html
+++ b/smp-angular/src/app/system-settings/admin-keystore/admin-keystore.component.html
@@ -61,7 +61,6 @@
 
   <mat-paginator class="mat-elevation-z2" id="extension-paginator"
                  [hidePageSize]="true"
-                 [showFirstLastButtons]="true"
                  [pageSize]="5" aria-label="Select page"></mat-paginator>
 
 </ng-template>
diff --git a/smp-angular/src/app/system-settings/admin-truststore/admin-truststore.component.html b/smp-angular/src/app/system-settings/admin-truststore/admin-truststore.component.html
index 8cc1eefa679ae4fa8d6699657bf21a7767d34005..18bdf5ff6d381abb780708e0150884247f7a1f5f 100644
--- a/smp-angular/src/app/system-settings/admin-truststore/admin-truststore.component.html
+++ b/smp-angular/src/app/system-settings/admin-truststore/admin-truststore.component.html
@@ -73,7 +73,6 @@
 
   <mat-paginator class="mat-elevation-z2" id="extension-paginator"
                  [hidePageSize]="true"
-                 [showFirstLastButtons]="true"
                  [pageSize]="5" aria-label="Select page"></mat-paginator>
 
 </ng-template>
diff --git a/smp-angular/src/app/system-settings/admin-users/admin-user.component.html b/smp-angular/src/app/system-settings/admin-users/admin-user.component.html
index 1fd0f3980b4cf4ed3b1cac8f2a391ac43652efd7..9331404b299dc717c471879f4343ae8ab666fd7a 100644
--- a/smp-angular/src/app/system-settings/admin-users/admin-user.component.html
+++ b/smp-angular/src/app/system-settings/admin-users/admin-user.component.html
@@ -72,6 +72,5 @@
                  (page)="onPageChanged($event)"
                  [hidePageSize]="true"
                  [pageSize]="5"
-                 [showFirstLastButtons]="true"
                  aria-label="Select page"></mat-paginator>
 </ng-template>
diff --git a/smp-angular/src/app/user-settings/user-access-tokens/user-access-tokens.component.html b/smp-angular/src/app/user-settings/user-access-tokens/user-access-tokens.component.html
index 81a843da20df3e3bf4ff43de5b508360eb797dd0..12df24986467281e83a66a8a3392b065dabde2db 100644
--- a/smp-angular/src/app/user-settings/user-access-tokens/user-access-tokens.component.html
+++ b/smp-angular/src/app/user-settings/user-access-tokens/user-access-tokens.component.html
@@ -21,7 +21,6 @@
 
     <mat-paginator class="mat-elevation-z2" id="tokens-paginator"
                    [hidePageSize]="true"
-                   [showFirstLastButtons]="true"
                    [pageSize]="5" aria-label="Select page"></mat-paginator>
   </data-panel>
 
diff --git a/smp-angular/src/app/user-settings/user-certificates/user-certificates.component.html b/smp-angular/src/app/user-settings/user-certificates/user-certificates.component.html
index b7f5c924a83f33ff66fc130993f2071ce6c6c763..8ced199e4fa46c91282100b55194fc69ff15388e 100644
--- a/smp-angular/src/app/user-settings/user-certificates/user-certificates.component.html
+++ b/smp-angular/src/app/user-settings/user-certificates/user-certificates.component.html
@@ -22,7 +22,6 @@
 
     <mat-paginator class="mat-elevation-z2" id="tokens-paginator"
                    [hidePageSize]="true"
-                   [showFirstLastButtons]="true"
                    [pageSize]="5" aria-label="Select page"></mat-paginator>
   </data-panel>
 
diff --git a/smp-angular/src/app/window/breadcrumb/breadcrumb-item/_breadcrumb-item.component-theme.scss b/smp-angular/src/app/window/breadcrumb/breadcrumb-item/_breadcrumb-item.component-theme.scss
index 99e6fa2c65c9a31717e2f8a0c490994c5213aa16..05b6434b0ef3c64fda8a3dd652c3b599231cd1a2 100644
--- a/smp-angular/src/app/window/breadcrumb/breadcrumb-item/_breadcrumb-item.component-theme.scss
+++ b/smp-angular/src/app/window/breadcrumb/breadcrumb-item/_breadcrumb-item.component-theme.scss
@@ -4,7 +4,6 @@
 
   .smp-breadcrumb-item-selected {
     background-color: smp.get-theme-color($theme, primary, 600) !important;
-
   }
 
   .smp-breadcrumb-item:hover {
@@ -31,8 +30,5 @@
   .smp-breadcrumb-arrow.top {
     border-top: 1px solid smp.get-theme-color($theme, primary, 0.5);
   }
-
-
-
 }
 
diff --git a/smp-angular/src/assets/stylesheets/codeMirror.css b/smp-angular/src/assets/stylesheets/codeMirror.css
deleted file mode 100644
index 22bc92bb4f7f6fa5e2913d3ce8b481adde3f3c37..0000000000000000000000000000000000000000
--- a/smp-angular/src/assets/stylesheets/codeMirror.css
+++ /dev/null
@@ -1,344 +0,0 @@
-/* BASICS */
-
-.CodeMirror {
-  /* Set height, width, borders, and global font properties here */
-  font-family: monospace;
-  height: 300px;
-  color: black;
-  direction: ltr;
-}
-
-/* PADDING */
-
-.CodeMirror-lines {
-  padding: 4px 0; /* Vertical padding around content */
-}
-.CodeMirror pre.CodeMirror-line,
-.CodeMirror pre.CodeMirror-line-like {
-  padding: 0 4px; /* Horizontal padding of content */
-}
-
-.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
-  background-color: white; /* The little square between H and V scrollbars */
-}
-
-/* GUTTER */
-
-.CodeMirror-gutters {
-  border-right: 1px solid #ddd;
-  background-color: #f7f7f7;
-  white-space: nowrap;
-}
-.CodeMirror-linenumbers {}
-.CodeMirror-linenumber {
-  padding: 0 3px 0 5px;
-  min-width: 20px;
-  text-align: right;
-  color: #999;
-  white-space: nowrap;
-}
-
-.CodeMirror-guttermarker { color: black; }
-.CodeMirror-guttermarker-subtle { color: #999; }
-
-/* CURSOR */
-
-.CodeMirror-cursor {
-  border-left: 1px solid black;
-  border-right: none;
-  width: 0;
-}
-/* Shown when moving in bi-directional text */
-.CodeMirror div.CodeMirror-secondarycursor {
-  border-left: 1px solid silver;
-}
-.cm-fat-cursor .CodeMirror-cursor {
-  width: auto;
-  border: 0 !important;
-  background: #7e7;
-}
-.cm-fat-cursor div.CodeMirror-cursors {
-  z-index: 1;
-}
-.cm-fat-cursor .CodeMirror-line::selection,
-.cm-fat-cursor .CodeMirror-line > span::selection,
-.cm-fat-cursor .CodeMirror-line > span > span::selection { background: transparent; }
-.cm-fat-cursor .CodeMirror-line::-moz-selection,
-.cm-fat-cursor .CodeMirror-line > span::-moz-selection,
-.cm-fat-cursor .CodeMirror-line > span > span::-moz-selection { background: transparent; }
-.cm-fat-cursor { caret-color: transparent; }
-@-moz-keyframes blink {
-  0% {}
-  50% { background-color: transparent; }
-  100% {}
-}
-@-webkit-keyframes blink {
-  0% {}
-  50% { background-color: transparent; }
-  100% {}
-}
-@keyframes blink {
-  0% {}
-  50% { background-color: transparent; }
-  100% {}
-}
-
-/* Can style cursor different in overwrite (non-insert) mode */
-.CodeMirror-overwrite .CodeMirror-cursor {}
-
-.cm-tab { display: inline-block; text-decoration: inherit; }
-
-.CodeMirror-rulers {
-  position: absolute;
-  left: 0; right: 0; top: -50px; bottom: 0;
-  overflow: hidden;
-}
-.CodeMirror-ruler {
-  border-left: 1px solid #ccc;
-  top: 0; bottom: 0;
-  position: absolute;
-}
-
-/* DEFAULT THEME */
-
-.cm-s-default .cm-header {color: blue;}
-.cm-s-default .cm-quote {color: #090;}
-.cm-negative {color: #d44;}
-.cm-positive {color: #292;}
-.cm-header, .cm-strong {font-weight: bold;}
-.cm-em {font-style: italic;}
-.cm-link {text-decoration: underline;}
-.cm-strikethrough {text-decoration: line-through;}
-
-.cm-s-default .cm-keyword {color: #708;}
-.cm-s-default .cm-atom {color: #219;}
-.cm-s-default .cm-number {color: #164;}
-.cm-s-default .cm-def {color: #00f;}
-.cm-s-default .cm-variable,
-.cm-s-default .cm-punctuation,
-.cm-s-default .cm-property,
-.cm-s-default .cm-operator {}
-.cm-s-default .cm-variable-2 {color: #05a;}
-.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;}
-.cm-s-default .cm-comment {color: #a50;}
-.cm-s-default .cm-string {color: #a11;}
-.cm-s-default .cm-string-2 {color: #f50;}
-.cm-s-default .cm-meta {color: #555;}
-.cm-s-default .cm-qualifier {color: #555;}
-.cm-s-default .cm-builtin {color: #30a;}
-.cm-s-default .cm-bracket {color: #997;}
-.cm-s-default .cm-tag {color: #170;}
-.cm-s-default .cm-attribute {color: #00c;}
-.cm-s-default .cm-hr {color: #999;}
-.cm-s-default .cm-link {color: #00c;}
-
-.cm-s-default .cm-error {color: #f00;}
-.cm-invalidchar {color: #f00;}
-
-.CodeMirror-composing { border-bottom: 2px solid; }
-
-/* Default styles for common addons */
-
-div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;}
-div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
-.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
-.CodeMirror-activeline-background {background: #e8f2ff;}
-
-/* STOP */
-
-/* The rest of this file contains styles related to the mechanics of
-   the editor. You probably shouldn't touch them. */
-
-.CodeMirror {
-  position: relative;
-  overflow: hidden;
-  background: transparent;
-}
-
-.CodeMirror-scroll {
-  overflow: scroll !important; /* Things will break if this is overridden */
-  /* 50px is the magic margin used to hide the element's real scrollbars */
-  /* See overflow: hidden in .CodeMirror */
-  margin-bottom: -50px; margin-right: -50px;
-  padding-bottom: 50px;
-  height: 100%;
-  outline: none; /* Prevent dragging from highlighting the element */
-  position: relative;
-  z-index: 0;
-}
-.CodeMirror-sizer {
-  position: relative;
-  border-right: 50px solid transparent;
-}
-
-/* The fake, visible scrollbars. Used to force redraw during scrolling
-   before actual scrolling happens, thus preventing shaking and
-   flickering artifacts. */
-.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
-  position: absolute;
-  z-index: 6;
-  display: none;
-  outline: none;
-}
-.CodeMirror-vscrollbar {
-  right: 0; top: 0;
-  overflow-x: hidden;
-  overflow-y: scroll;
-}
-.CodeMirror-hscrollbar {
-  bottom: 0; left: 0;
-  overflow-y: hidden;
-  overflow-x: scroll;
-}
-.CodeMirror-scrollbar-filler {
-  right: 0; bottom: 0;
-}
-.CodeMirror-gutter-filler {
-  left: 0; bottom: 0;
-}
-
-.CodeMirror-gutters {
-  position: absolute; left: 0; top: 0;
-  min-height: 100%;
-  z-index: 3;
-}
-.CodeMirror-gutter {
-  white-space: normal;
-  height: 100%;
-  display: inline-block;
-  vertical-align: top;
-  margin-bottom: -50px;
-}
-.CodeMirror-gutter-wrapper {
-  position: absolute;
-  z-index: 4;
-  background: none !important;
-  border: none !important;
-}
-.CodeMirror-gutter-background {
-  position: absolute;
-  top: 0; bottom: 0;
-  z-index: 4;
-}
-.CodeMirror-gutter-elt {
-  position: absolute;
-  cursor: default;
-  z-index: 4;
-}
-.CodeMirror-gutter-wrapper ::selection { background-color: transparent }
-.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
-
-.CodeMirror-lines {
-  cursor: text;
-  min-height: 1px; /* prevents collapsing before first draw */
-}
-.CodeMirror pre.CodeMirror-line,
-.CodeMirror pre.CodeMirror-line-like {
-  /* Reset some styles that the rest of the page might have set */
-  -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
-  border-width: 0;
-  background: transparent;
-  font-family: inherit;
-  font-size: inherit;
-  margin: 0;
-  white-space: pre;
-  word-wrap: normal;
-  line-height: inherit;
-  color: inherit;
-  z-index: 2;
-  position: relative;
-  overflow: visible;
-  -webkit-tap-highlight-color: transparent;
-  -webkit-font-variant-ligatures: contextual;
-  font-variant-ligatures: contextual;
-}
-.CodeMirror-wrap pre.CodeMirror-line,
-.CodeMirror-wrap pre.CodeMirror-line-like {
-  word-wrap: break-word;
-  white-space: pre-wrap;
-  word-break: normal;
-}
-
-.CodeMirror-linebackground {
-  position: absolute;
-  left: 0; right: 0; top: 0; bottom: 0;
-  z-index: 0;
-}
-
-.CodeMirror-linewidget {
-  position: relative;
-  z-index: 2;
-  padding: 0.1px; /* Force widget margins to stay inside of the container */
-}
-
-.CodeMirror-widget {}
-
-.CodeMirror-rtl pre { direction: rtl; }
-
-.CodeMirror-code {
-  outline: none;
-}
-
-/* Force content-box sizing for the elements where we expect it */
-.CodeMirror-scroll,
-.CodeMirror-sizer,
-.CodeMirror-gutter,
-.CodeMirror-gutters,
-.CodeMirror-linenumber {
-  -moz-box-sizing: content-box;
-  box-sizing: content-box;
-}
-
-.CodeMirror-measure {
-  position: absolute;
-  width: 100%;
-  height: 0;
-  overflow: hidden;
-  visibility: hidden;
-}
-
-.CodeMirror-cursor {
-  position: absolute;
-  pointer-events: none;
-}
-.CodeMirror-measure pre { position: static; }
-
-div.CodeMirror-cursors {
-  visibility: hidden;
-  position: relative;
-  z-index: 3;
-}
-div.CodeMirror-dragcursors {
-  visibility: visible;
-}
-
-.CodeMirror-focused div.CodeMirror-cursors {
-  visibility: visible;
-}
-
-.CodeMirror-selected { background: #d9d9d9; }
-.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
-.CodeMirror-crosshair { cursor: crosshair; }
-.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
-.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
-
-.cm-searching {
-  background-color: #ffa;
-  background-color: rgba(255, 255, 0, .4);
-}
-
-/* Used to force a border model for a node */
-.cm-force-border { padding-right: .1px; }
-
-@media print {
-  /* Hide the cursor when printing */
-  .CodeMirror div.CodeMirror-cursors {
-    visibility: hidden;
-  }
-}
-
-/* See issue #2901 */
-.cm-tab-wrap-hack:after { content: ''; }
-
-/* Help users use markselection to safely style text background */
-span.CodeMirror-selectedtext { background: none; }
diff --git a/smp-angular/src/tsconfig.app.json b/smp-angular/src/tsconfig.app.json
index 5e2507db58c96c20ac2015842994a5af0e39734b..06176629bbdc38e1bd13b2e0b1c397c146eb073d 100644
--- a/smp-angular/src/tsconfig.app.json
+++ b/smp-angular/src/tsconfig.app.json
@@ -2,7 +2,7 @@
   "extends": "../tsconfig.json",
   "compilerOptions": {
     "outDir": "../out-tsc/app",
-    "module": "es2015",
+    "module": "es2022",
     "baseUrl": "",
     "types": []
   },
diff --git a/smp-examples/resource-spi-example/pom.xml b/smp-examples/resource-spi-example/pom.xml
index c600081f87c6f7c22ea0d80926d0f39269bcdf00..61b867b57d4cc78444e3761a6736b2bd443a2949 100644
--- a/smp-examples/resource-spi-example/pom.xml
+++ b/smp-examples/resource-spi-example/pom.xml
@@ -29,7 +29,6 @@
     <name>resource-spi-example</name>
     <packaging>jar</packaging>
     <description>Various resource examples.</description>
-
     <dependencies>
         <dependency>
             <groupId>eu.europa.ec.edelivery</groupId>