aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.eslintrc.cjs23
-rw-r--r--.gitignore29
-rw-r--r--.prettierrc.json8
-rw-r--r--README.md46
-rw-r--r--env.d.ts1
-rw-r--r--index.html13
-rw-r--r--package-lock.json3390
-rw-r--r--package.json44
-rw-r--r--public/favicon.icobin0 -> 4286 bytes
-rw-r--r--src/App.vue12
-rw-r--r--src/assets/base.css205
-rw-r--r--src/assets/main.css2
-rw-r--r--src/assets/quests-logo.pngbin0 -> 54415 bytes
-rw-r--r--src/components/Control/Button.vue54
-rw-r--r--src/components/Control/Checkbox.vue42
-rw-r--r--src/components/Control/TrueFalseSwitch.vue54
-rw-r--r--src/components/Editor/Category/CategoryChildrenOptionsPanel.vue53
-rw-r--r--src/components/Editor/Category/CategoryOptionsPanel.vue54
-rw-r--r--src/components/Editor/EditorOptionsPanel.vue18
-rw-r--r--src/components/Editor/EditorPane.vue157
-rw-r--r--src/components/Editor/EditorSidebar.vue28
-rw-r--r--src/components/Editor/EditorSidebarCategory.vue94
-rw-r--r--src/components/Editor/EditorSidebarQuest.vue68
-rw-r--r--src/components/Editor/Quest/QuestOptionsPanel.vue154
-rw-r--r--src/components/Editor/Quest/QuestTasksOptionsPanel.vue75
-rw-r--r--src/components/Editor/Quest/Task/TaskConfiguration.vue191
-rw-r--r--src/components/Editor/Quest/Task/TaskConfigurationRow.vue156
-rw-r--r--src/components/Header/SiteHeader.vue43
-rw-r--r--src/data/materials.json1924
-rw-r--r--src/data/taskDefinitions.json53
-rw-r--r--src/data/testData.json384
-rw-r--r--src/lib/questsLoader.ts68
-rw-r--r--src/lib/util.ts3
-rw-r--r--src/main.ts35
-rw-r--r--src/router/index.ts23
-rw-r--r--src/stores/session.ts149
-rw-r--r--src/views/EditorView.vue37
-rw-r--r--tsconfig.app.json14
-rw-r--r--tsconfig.json11
-rw-r--r--tsconfig.node.json19
-rw-r--r--vite.config.ts16
41 files changed, 7750 insertions, 0 deletions
diff --git a/.eslintrc.cjs b/.eslintrc.cjs
new file mode 100644
index 0000000..95c7d05
--- /dev/null
+++ b/.eslintrc.cjs
@@ -0,0 +1,23 @@
+/* eslint-env node */
+require('@rushstack/eslint-patch/modern-module-resolution')
+
+module.exports = {
+ root: true,
+ 'extends': [
+ 'plugin:vue/vue3-essential',
+ 'eslint:recommended',
+ '@vue/eslint-config-typescript',
+ '@vue/eslint-config-prettier/skip-formatting'
+ ],
+ parserOptions: {
+ ecmaVersion: 'latest'
+ },
+ overrides: [
+ {
+ files: ['**/*.ts', '**/*.vue'],
+ rules: {
+ 'vue/multi-word-component-names': 'off'
+ }
+ }
+ ]
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..099f5ae
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,29 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+.DS_Store
+dist
+dist-ssr
+coverage
+*.local
+
+/cypress/videos/
+/cypress/screenshots/
+
+# Editor directories and files
+.vscode
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 0000000..66e2335
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,8 @@
+{
+ "$schema": "https://json.schemastore.org/prettierrc",
+ "semi": false,
+ "tabWidth": 2,
+ "singleQuote": true,
+ "printWidth": 100,
+ "trailingComma": "none"
+} \ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..756d173
--- /dev/null
+++ b/README.md
@@ -0,0 +1,46 @@
+# quests-web-editor
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+npm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+npm run dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+npm run build
+```
+
+### Lint with [ESLint](https://eslint.org/)
+
+```sh
+npm run lint
+```
diff --git a/env.d.ts b/env.d.ts
new file mode 100644
index 0000000..11f02fe
--- /dev/null
+++ b/env.d.ts
@@ -0,0 +1 @@
+/// <reference types="vite/client" />
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..a888544
--- /dev/null
+++ b/index.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <link rel="icon" href="/favicon.ico">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Vite App</title>
+ </head>
+ <body>
+ <div id="app"></div>
+ <script type="module" src="/src/main.ts"></script>
+ </body>
+</html>
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..3c1569b
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,3390 @@
+{
+ "name": "quests-web-editor",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "quests-web-editor",
+ "version": "0.0.0",
+ "dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^6.5.1",
+ "@fortawesome/free-brands-svg-icons": "^6.5.1",
+ "@fortawesome/free-regular-svg-icons": "^6.5.1",
+ "@fortawesome/free-solid-svg-icons": "^6.5.1",
+ "@fortawesome/vue-fontawesome": "^3.0.6",
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15",
+ "vue-multiselect": "^3.0.0-beta.3",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@rushstack/eslint-patch": "^1.3.3",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.10",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/eslint-config-prettier": "^8.0.0",
+ "@vue/eslint-config-typescript": "^12.0.0",
+ "@vue/tsconfig": "^0.5.1",
+ "eslint": "^8.49.0",
+ "eslint-plugin-vue": "^9.17.0",
+ "npm-run-all2": "^6.1.1",
+ "prettier": "^3.0.3",
+ "sass": "^1.70.0",
+ "sass-loader": "^14.1.0",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vue-tsc": "^1.8.27"
+ }
+ },
+ "node_modules/@aashutoshrathi/word-wrap": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
+ "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.23.9",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz",
+ "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==",
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
+ "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
+ "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
+ "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
+ "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
+ "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
+ "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
+ "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
+ "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
+ "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
+ "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
+ "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
+ "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
+ "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
+ "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
+ "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
+ "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
+ "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
+ "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
+ "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
+ "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
+ "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
+ "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
+ "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+ "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
+ "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+ "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "8.56.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
+ "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@fortawesome/fontawesome-common-types": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz",
+ "integrity": "sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A==",
+ "hasInstallScript": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@fortawesome/fontawesome-svg-core": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.1.tgz",
+ "integrity": "sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "6.5.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@fortawesome/free-brands-svg-icons": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.5.1.tgz",
+ "integrity": "sha512-093l7DAkx0aEtBq66Sf19MgoZewv1zeY9/4C7vSKPO4qMwEsW/2VYTUTpBtLwfb9T2R73tXaRDPmE4UqLCYHfg==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "6.5.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@fortawesome/free-regular-svg-icons": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.1.tgz",
+ "integrity": "sha512-m6ShXn+wvqEU69wSP84coxLbNl7sGVZb+Ca+XZq6k30SzuP3X4TfPqtycgUh9ASwlNh5OfQCd8pDIWxl+O+LlQ==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "6.5.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@fortawesome/free-solid-svg-icons": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.1.tgz",
+ "integrity": "sha512-S1PPfU3mIJa59biTtXJz1oI0+KAXW6bkAb31XKhxdxtuXDiUIFsih4JR1v5BbxY7hVHsD1RKq+jRkVRaf773NQ==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "6.5.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@fortawesome/vue-fontawesome": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-3.0.6.tgz",
+ "integrity": "sha512-akrL7lTroyNpPkoHtvK2UpsMzJr6jXdHaQ0YdcwqDsB8jdwlpNHZYijpOUd9KJsARr+VB3WXY4EyObepqJ4ytQ==",
+ "peerDependencies": {
+ "@fortawesome/fontawesome-svg-core": "~1 || ~6",
+ "vue": ">= 3.0.0 < 4"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.11.14",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
+ "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
+ "dev": true,
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^2.0.2",
+ "debug": "^4.3.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz",
+ "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@pkgr/core": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz",
+ "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/unts"
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.10.0.tgz",
+ "integrity": "sha512-/MeDQmcD96nVoRumKUljsYOLqfv1YFJps+0pTrb2Z9Nl/w5qNUysMaWQsrd1mvAlNT4yza1iVyIu4Q4AgF6V3A==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.10.0.tgz",
+ "integrity": "sha512-lvu0jK97mZDJdpZKDnZI93I0Om8lSDaiPx3OiCk0RXn3E8CMPJNS/wxjAvSJJzhhZpfjXsjLWL8LnS6qET4VNQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.10.0.tgz",
+ "integrity": "sha512-uFpayx8I8tyOvDkD7X6n0PriDRWxcqEjqgtlxnUA/G9oS93ur9aZ8c8BEpzFmsed1TH5WZNG5IONB8IiW90TQg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.10.0.tgz",
+ "integrity": "sha512-nIdCX03qFKoR/MwQegQBK+qZoSpO3LESurVAC6s6jazLA1Mpmgzo3Nj3H1vydXp/JM29bkCiuF7tDuToj4+U9Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.10.0.tgz",
+ "integrity": "sha512-Fz7a+y5sYhYZMQFRkOyCs4PLhICAnxRX/GnWYReaAoruUzuRtcf+Qnw+T0CoAWbHCuz2gBUwmWnUgQ67fb3FYw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.10.0.tgz",
+ "integrity": "sha512-yPtF9jIix88orwfTi0lJiqINnlWo6p93MtZEoaehZnmCzEmLL0eqjA3eGVeyQhMtxdV+Mlsgfwhh0+M/k1/V7Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.10.0.tgz",
+ "integrity": "sha512-9GW9yA30ib+vfFiwjX+N7PnjTnCMiUffhWj4vkG4ukYv1kJ4T9gHNg8zw+ChsOccM27G9yXrEtMScf1LaCuoWQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.10.0.tgz",
+ "integrity": "sha512-X1ES+V4bMq2ws5fF4zHornxebNxMXye0ZZjUrzOrf7UMx1d6wMQtfcchZ8SqUnQPPHdOyOLW6fTcUiFgHFadRA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.10.0.tgz",
+ "integrity": "sha512-w/5OpT2EnI/Xvypw4FIhV34jmNqU5PZjZue2l2Y3ty1Ootm3SqhI+AmfhlUYGBTd9JnpneZCDnt3uNOiOBkMyw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.10.0.tgz",
+ "integrity": "sha512-q/meftEe3QlwQiGYxD9rWwB21DoKQ9Q8wA40of/of6yGHhZuGfZO0c3WYkN9dNlopHlNT3mf5BPsUSxoPuVQaw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.10.0.tgz",
+ "integrity": "sha512-NrR6667wlUfP0BHaEIKgYM/2va+Oj+RjZSASbBMnszM9k+1AmliRjHc3lJIiOehtSSjqYiO7R6KLNrWOX+YNSQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.10.0.tgz",
+ "integrity": "sha512-FV0Tpt84LPYDduIDcXvEC7HKtyXxdvhdAOvOeWMWbQNulxViH2O07QXkT/FffX4FqEI02jEbCJbr+YcuKdyyMg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.10.0.tgz",
+ "integrity": "sha512-OZoJd+o5TaTSQeFFQ6WjFCiltiYVjIdsXxwu/XZ8qRpsvMQr4UsVrE5UyT9RIvsnuF47DqkJKhhVZ2Q9YW9IpQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rushstack/eslint-patch": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.7.2.tgz",
+ "integrity": "sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node20": {
+ "version": "20.1.2",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.2.tgz",
+ "integrity": "sha512-madaWq2k+LYMEhmcp0fs+OGaLFk0OenpHa4gmI4VEmCKX4PJntQ6fnnGADVFrVkBj0wIdAlQnK/MrlYTHsa1gQ==",
+ "dev": true
+ },
+ "node_modules/@types/estree": {
+ "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/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true
+ },
+ "node_modules/@types/node": {
+ "version": "20.11.17",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.17.tgz",
+ "integrity": "sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==",
+ "dev": true,
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
+ },
+ "node_modules/@types/semver": {
+ "version": "7.5.7",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz",
+ "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==",
+ "dev": true
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
+ "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.5.1",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/type-utils": "6.21.0",
+ "@typescript-eslint/utils": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.4",
+ "natural-compare": "^1.4.0",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
+ "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
+ "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz",
+ "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "@typescript-eslint/utils": "6.21.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
+ "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
+ "dev": true,
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
+ "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "minimatch": "9.0.3",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
+ "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@types/json-schema": "^7.0.12",
+ "@types/semver": "^7.5.0",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
+ "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "6.21.0",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
+ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
+ "dev": true
+ },
+ "node_modules/@vitejs/plugin-vue": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz",
+ "integrity": "sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==",
+ "dev": true,
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^5.0.0",
+ "vue": "^3.2.25"
+ }
+ },
+ "node_modules/@volar/language-core": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.11.1.tgz",
+ "integrity": "sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==",
+ "dev": true,
+ "dependencies": {
+ "@volar/source-map": "1.11.1"
+ }
+ },
+ "node_modules/@volar/source-map": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.11.1.tgz",
+ "integrity": "sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==",
+ "dev": true,
+ "dependencies": {
+ "muggle-string": "^0.3.1"
+ }
+ },
+ "node_modules/@volar/typescript": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.11.1.tgz",
+ "integrity": "sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==",
+ "dev": true,
+ "dependencies": {
+ "@volar/language-core": "1.11.1",
+ "path-browserify": "^1.0.1"
+ }
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.4.18",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.18.tgz",
+ "integrity": "sha512-F7YK8lMK0iv6b9/Gdk15A67wM0KKZvxDxed0RR60C1z9tIJTKta+urs4j0RTN5XqHISzI3etN3mX0uHhjmoqjQ==",
+ "dependencies": {
+ "@babel/parser": "^7.23.9",
+ "@vue/shared": "3.4.18",
+ "entities": "^4.5.0",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.0.2"
+ }
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.4.18",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.18.tgz",
+ "integrity": "sha512-24Eb8lcMfInefvQ6YlEVS18w5Q66f4+uXWVA+yb7praKbyjHRNuKVWGuinfSSjM0ZIiPi++QWukhkgznBaqpEA==",
+ "dependencies": {
+ "@vue/compiler-core": "3.4.18",
+ "@vue/shared": "3.4.18"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.4.18",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.18.tgz",
+ "integrity": "sha512-rG5tqtnzwrVpMqAQ7FHtvHaV70G6LLfJIWLYZB/jZ9m/hrnZmIQh+H3ewnC5onwe/ibljm9+ZupxeElzqCkTAw==",
+ "dependencies": {
+ "@babel/parser": "^7.23.9",
+ "@vue/compiler-core": "3.4.18",
+ "@vue/compiler-dom": "3.4.18",
+ "@vue/compiler-ssr": "3.4.18",
+ "@vue/shared": "3.4.18",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.6",
+ "postcss": "^8.4.33",
+ "source-map-js": "^1.0.2"
+ }
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.4.18",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.18.tgz",
+ "integrity": "sha512-hSlv20oUhPxo2UYUacHgGaxtqP0tvFo6ixxxD6JlXIkwzwoZ9eKK6PFQN4hNK/R13JlNyldwWt/fqGBKgWJ6nQ==",
+ "dependencies": {
+ "@vue/compiler-dom": "3.4.18",
+ "@vue/shared": "3.4.18"
+ }
+ },
+ "node_modules/@vue/devtools-api": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.1.tgz",
+ "integrity": "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA=="
+ },
+ "node_modules/@vue/eslint-config-prettier": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-8.0.0.tgz",
+ "integrity": "sha512-55dPqtC4PM/yBjhAr+yEw6+7KzzdkBuLmnhBrDfp4I48+wy+Giqqj9yUr5T2uD/BkBROjjmqnLZmXRdOx/VtQg==",
+ "dev": true,
+ "dependencies": {
+ "eslint-config-prettier": "^8.8.0",
+ "eslint-plugin-prettier": "^5.0.0"
+ },
+ "peerDependencies": {
+ "eslint": ">= 8.0.0",
+ "prettier": ">= 3.0.0"
+ }
+ },
+ "node_modules/@vue/eslint-config-typescript": {
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-12.0.0.tgz",
+ "integrity": "sha512-StxLFet2Qe97T8+7L8pGlhYBBr8Eg05LPuTDVopQV6il+SK6qqom59BA/rcFipUef2jD8P2X44Vd8tMFytfvlg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "^6.7.0",
+ "@typescript-eslint/parser": "^6.7.0",
+ "vue-eslint-parser": "^9.3.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0",
+ "eslint-plugin-vue": "^9.0.0",
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vue/language-core": {
+ "version": "1.8.27",
+ "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.27.tgz",
+ "integrity": "sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==",
+ "dev": true,
+ "dependencies": {
+ "@volar/language-core": "~1.11.1",
+ "@volar/source-map": "~1.11.1",
+ "@vue/compiler-dom": "^3.3.0",
+ "@vue/shared": "^3.3.0",
+ "computeds": "^0.0.1",
+ "minimatch": "^9.0.3",
+ "muggle-string": "^0.3.1",
+ "path-browserify": "^1.0.1",
+ "vue-template-compiler": "^2.7.14"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vue/reactivity": {
+ "version": "3.4.18",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.18.tgz",
+ "integrity": "sha512-7uda2/I0jpLiRygprDo5Jxs2HJkOVXcOMlyVlY54yRLxoycBpwGJRwJT9EdGB4adnoqJDXVT2BilUAYwI7qvmg==",
+ "dependencies": {
+ "@vue/shared": "3.4.18"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.4.18",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.18.tgz",
+ "integrity": "sha512-7mU9diCa+4e+8/wZ7Udw5pwTH10A11sZ1nldmHOUKJnzCwvZxfJqAtw31mIf4T5H2FsLCSBQT3xgioA9vIjyDQ==",
+ "dependencies": {
+ "@vue/reactivity": "3.4.18",
+ "@vue/shared": "3.4.18"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.4.18",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.18.tgz",
+ "integrity": "sha512-2y1Mkzcw1niSfG7z3Qx+2ir9Gb4hdTkZe5p/I8x1aTIKQE0vY0tPAEUPhZm5tx6183gG3D/KwHG728UR0sIufA==",
+ "dependencies": {
+ "@vue/runtime-core": "3.4.18",
+ "@vue/shared": "3.4.18",
+ "csstype": "^3.1.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.4.18",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.18.tgz",
+ "integrity": "sha512-YJd1wa7mzUN3NRqLEsrwEYWyO+PUBSROIGlCc3J/cvn7Zu6CxhNLgXa8Z4zZ5ja5/nviYO79J1InoPeXgwBTZA==",
+ "dependencies": {
+ "@vue/compiler-ssr": "3.4.18",
+ "@vue/shared": "3.4.18"
+ },
+ "peerDependencies": {
+ "vue": "3.4.18"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.4.18",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.18.tgz",
+ "integrity": "sha512-CxouGFxxaW5r1WbrSmWwck3No58rApXgRSBxrqgnY1K+jk20F6DrXJkHdH9n4HVT+/B6G2CAn213Uq3npWiy8Q=="
+ },
+ "node_modules/@vue/tsconfig": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/@vue/tsconfig/-/tsconfig-0.5.1.tgz",
+ "integrity": "sha512-VcZK7MvpjuTPx2w6blwnwZAu5/LgBUtejFOi3pPGQFXQN5Ela03FUtd2Qtg4yWGGissVL0dr6Ro1LfOFh+PCuQ==",
+ "dev": true
+ },
+ "node_modules/acorn": {
+ "version": "8.11.3",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
+ "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "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/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "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,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "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
+ },
+ "node_modules/computeds": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz",
+ "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==",
+ "dev": true
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+ },
+ "node_modules/de-indent": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
+ "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==",
+ "dev": true
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz",
+ "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.19.12",
+ "@esbuild/android-arm": "0.19.12",
+ "@esbuild/android-arm64": "0.19.12",
+ "@esbuild/android-x64": "0.19.12",
+ "@esbuild/darwin-arm64": "0.19.12",
+ "@esbuild/darwin-x64": "0.19.12",
+ "@esbuild/freebsd-arm64": "0.19.12",
+ "@esbuild/freebsd-x64": "0.19.12",
+ "@esbuild/linux-arm": "0.19.12",
+ "@esbuild/linux-arm64": "0.19.12",
+ "@esbuild/linux-ia32": "0.19.12",
+ "@esbuild/linux-loong64": "0.19.12",
+ "@esbuild/linux-mips64el": "0.19.12",
+ "@esbuild/linux-ppc64": "0.19.12",
+ "@esbuild/linux-riscv64": "0.19.12",
+ "@esbuild/linux-s390x": "0.19.12",
+ "@esbuild/linux-x64": "0.19.12",
+ "@esbuild/netbsd-x64": "0.19.12",
+ "@esbuild/openbsd-x64": "0.19.12",
+ "@esbuild/sunos-x64": "0.19.12",
+ "@esbuild/win32-arm64": "0.19.12",
+ "@esbuild/win32-ia32": "0.19.12",
+ "@esbuild/win32-x64": "0.19.12"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.56.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
+ "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.4",
+ "@eslint/js": "8.56.0",
+ "@humanwhocodes/config-array": "^0.11.13",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "@ungap/structured-clone": "^1.2.0",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "8.10.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz",
+ "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==",
+ "dev": true,
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-prettier": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz",
+ "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==",
+ "dev": true,
+ "dependencies": {
+ "prettier-linter-helpers": "^1.0.0",
+ "synckit": "^0.8.6"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-plugin-prettier"
+ },
+ "peerDependencies": {
+ "@types/eslint": ">=8.0.0",
+ "eslint": ">=8.0.0",
+ "eslint-config-prettier": "*",
+ "prettier": ">=3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/eslint": {
+ "optional": true
+ },
+ "eslint-config-prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-vue": {
+ "version": "9.21.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.21.1.tgz",
+ "integrity": "sha512-XVtI7z39yOVBFJyi8Ljbn7kY9yHzznKXL02qQYn+ta63Iy4A9JFBw6o4OSB9hyD2++tVT+su9kQqetUyCCwhjw==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "natural-compare": "^1.4.0",
+ "nth-check": "^2.1.1",
+ "postcss-selector-parser": "^6.0.13",
+ "semver": "^7.5.4",
+ "vue-eslint-parser": "^9.4.2",
+ "xml-name-validator": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/eslint/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+ "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "node_modules/fast-diff": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
+ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
+ "dev": true
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
+ "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true
+ },
+ "node_modules/fastq": {
+ "version": "1.17.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
+ "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
+ "dev": true,
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
+ "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
+ "dev": true,
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.3",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.2.9",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz",
+ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==",
+ "dev": true
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "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,
+ "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/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/glob/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/glob/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/globals": {
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true
+ },
+ "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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true,
+ "bin": {
+ "he": "bin/he"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
+ "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/immutable": {
+ "version": "4.3.5",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz",
+ "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==",
+ "dev": true
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz",
+ "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "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/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true
+ },
+ "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,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.7",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz",
+ "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.4.15"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/memorystream": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
+ "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "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/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/minimatch": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/muggle-string": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.3.1.tgz",
+ "integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==",
+ "dev": true
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
+ "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true
+ },
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true
+ },
+ "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/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-run-all2": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/npm-run-all2/-/npm-run-all2-6.1.2.tgz",
+ "integrity": "sha512-WwwnS8Ft+RpXve6T2EIEVpFLSqN+ORHRvgNk3H9N62SZXjmzKoRhMFg3I17TK3oMaAEr+XFbRirWS2Fn3BCPSg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "cross-spawn": "^7.0.3",
+ "memorystream": "^0.3.1",
+ "minimatch": "^9.0.0",
+ "pidtree": "^0.6.0",
+ "read-package-json-fast": "^3.0.2",
+ "shell-quote": "^1.7.3"
+ },
+ "bin": {
+ "npm-run-all": "bin/npm-run-all/index.js",
+ "npm-run-all2": "bin/npm-run-all/index.js",
+ "run-p": "bin/run-p/index.js",
+ "run-s": "bin/run-s/index.js"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0",
+ "npm": ">= 8"
+ }
+ },
+ "node_modules/npm-run-all2/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
+ "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
+ "dev": true,
+ "dependencies": {
+ "@aashutoshrathi/word-wrap": "^1.2.3",
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-browserify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
+ "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+ "dev": true
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pidtree": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz",
+ "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==",
+ "dev": true,
+ "bin": {
+ "pidtree": "bin/pidtree.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/pinia": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz",
+ "integrity": "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==",
+ "dependencies": {
+ "@vue/devtools-api": "^6.5.0",
+ "vue-demi": ">=0.14.5"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/posva"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.4.0",
+ "typescript": ">=4.4.4",
+ "vue": "^2.6.14 || ^3.3.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/pinia/node_modules/vue-demi": {
+ "version": "0.14.7",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz",
+ "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==",
+ "hasInstallScript": true,
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.4.35",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
+ "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.0.15",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz",
+ "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==",
+ "dev": true,
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.2.5",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
+ "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "dev": true,
+ "dependencies": {
+ "fast-diff": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/read-package-json-fast": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz",
+ "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==",
+ "dev": true,
+ "dependencies": {
+ "json-parse-even-better-errors": "^3.0.0",
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.10.0.tgz",
+ "integrity": "sha512-t2v9G2AKxcQ8yrG+WGxctBes1AomT0M4ND7jTFBCVPXQ/WFTvNSefIrNSmLKhIKBrvN8SG+CZslimJcT3W2u2g==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "1.0.5"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.10.0",
+ "@rollup/rollup-android-arm64": "4.10.0",
+ "@rollup/rollup-darwin-arm64": "4.10.0",
+ "@rollup/rollup-darwin-x64": "4.10.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.10.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.10.0",
+ "@rollup/rollup-linux-arm64-musl": "4.10.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.10.0",
+ "@rollup/rollup-linux-x64-gnu": "4.10.0",
+ "@rollup/rollup-linux-x64-musl": "4.10.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.10.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.10.0",
+ "@rollup/rollup-win32-x64-msvc": "4.10.0",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/sass": {
+ "version": "1.70.0",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.70.0.tgz",
+ "integrity": "sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==",
+ "dev": true,
+ "dependencies": {
+ "chokidar": ">=3.0.0 <4.0.0",
+ "immutable": "^4.0.0",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ },
+ "bin": {
+ "sass": "sass.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-loader": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-14.1.0.tgz",
+ "integrity": "sha512-LS2mLeFWA+orYxHNu+O18Xe4jR0kyamNOOUsE3NyBP4DvIL+8stHpNX0arYTItdPe80kluIiJ7Wfe/9iHSRO0Q==",
+ "dev": true,
+ "dependencies": {
+ "neo-async": "^2.6.2"
+ },
+ "engines": {
+ "node": ">= 18.12.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "@rspack/core": "0.x || 1.x",
+ "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": {
+ "@rspack/core": {
+ "optional": true
+ },
+ "node-sass": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "webpack": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+ "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shell-quote": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz",
+ "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "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",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/synckit": {
+ "version": "0.8.8",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz",
+ "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==",
+ "dev": true,
+ "dependencies": {
+ "@pkgr/core": "^0.1.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/unts"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+ "dev": true
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz",
+ "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
+ "dev": true
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
+ "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
+ "devOptional": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "5.26.5",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
+ "dev": true
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true
+ },
+ "node_modules/vite": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.1.tgz",
+ "integrity": "sha512-wclpAgY3F1tR7t9LL5CcHC41YPkQIpKUGeIuT8MdNwNZr6OqOTLs7JX5vIHAtzqLWXts0T+GDrh9pN2arneKqg==",
+ "dev": true,
+ "dependencies": {
+ "esbuild": "^0.19.3",
+ "postcss": "^8.4.35",
+ "rollup": "^4.2.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue": {
+ "version": "3.4.18",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.18.tgz",
+ "integrity": "sha512-0zLRYamFRe0wF4q2L3O24KQzLyLpL64ye1RUToOgOxuWZsb/FhaNRdGmeozdtVYLz6tl94OXLaK7/WQIrVCw1A==",
+ "dependencies": {
+ "@vue/compiler-dom": "3.4.18",
+ "@vue/compiler-sfc": "3.4.18",
+ "@vue/runtime-dom": "3.4.18",
+ "@vue/server-renderer": "3.4.18",
+ "@vue/shared": "3.4.18"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue-eslint-parser": {
+ "version": "9.4.2",
+ "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
+ "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.3.4",
+ "eslint-scope": "^7.1.1",
+ "eslint-visitor-keys": "^3.3.0",
+ "espree": "^9.3.1",
+ "esquery": "^1.4.0",
+ "lodash": "^4.17.21",
+ "semver": "^7.3.6"
+ },
+ "engines": {
+ "node": "^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=6.0.0"
+ }
+ },
+ "node_modules/vue-multiselect": {
+ "version": "3.0.0-beta.3",
+ "resolved": "https://registry.npmjs.org/vue-multiselect/-/vue-multiselect-3.0.0-beta.3.tgz",
+ "integrity": "sha512-P7Fx+ovVF7WMERSZ0lw6N3p4H4bnQ3NcaY3ORjzFPv0r/6lpIqvFWmK9Xnwze9mgAvmNV1foI1VWrBmjnfBTLQ==",
+ "engines": {
+ "node": ">= 4.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/vue-router": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.5.tgz",
+ "integrity": "sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==",
+ "dependencies": {
+ "@vue/devtools-api": "^6.5.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/posva"
+ },
+ "peerDependencies": {
+ "vue": "^3.2.0"
+ }
+ },
+ "node_modules/vue-template-compiler": {
+ "version": "2.7.16",
+ "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz",
+ "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==",
+ "dev": true,
+ "dependencies": {
+ "de-indent": "^1.0.2",
+ "he": "^1.2.0"
+ }
+ },
+ "node_modules/vue-tsc": {
+ "version": "1.8.27",
+ "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.27.tgz",
+ "integrity": "sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==",
+ "dev": true,
+ "dependencies": {
+ "@volar/typescript": "~1.11.1",
+ "@vue/language-core": "1.8.27",
+ "semver": "^7.5.4"
+ },
+ "bin": {
+ "vue-tsc": "bin/vue-tsc.js"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true
+ },
+ "node_modules/xml-name-validator": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
+ "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "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
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..85a789c
--- /dev/null
+++ b/package.json
@@ -0,0 +1,44 @@
+{
+ "name": "quests-web-editor",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force",
+ "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
+ "format": "prettier --write src/"
+ },
+ "dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^6.5.1",
+ "@fortawesome/free-brands-svg-icons": "^6.5.1",
+ "@fortawesome/free-regular-svg-icons": "^6.5.1",
+ "@fortawesome/free-solid-svg-icons": "^6.5.1",
+ "@fortawesome/vue-fontawesome": "^3.0.6",
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15",
+ "vue-multiselect": "^3.0.0-beta.3",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@rushstack/eslint-patch": "^1.3.3",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.10",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/eslint-config-prettier": "^8.0.0",
+ "@vue/eslint-config-typescript": "^12.0.0",
+ "@vue/tsconfig": "^0.5.1",
+ "eslint": "^8.49.0",
+ "eslint-plugin-vue": "^9.17.0",
+ "npm-run-all2": "^6.1.1",
+ "prettier": "^3.0.3",
+ "sass": "^1.70.0",
+ "sass-loader": "^14.1.0",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..df36fcf
--- /dev/null
+++ b/public/favicon.ico
Binary files differ
diff --git a/src/App.vue b/src/App.vue
new file mode 100644
index 0000000..0b4985d
--- /dev/null
+++ b/src/App.vue
@@ -0,0 +1,12 @@
+<script setup lang="ts">
+import SiteHeader from '@/components/Header/SiteHeader.vue';
+</script>
+
+<template>
+ <SiteHeader />
+
+ <RouterView />
+</template>
+
+<style scoped>
+</style>
diff --git a/src/assets/base.css b/src/assets/base.css
new file mode 100644
index 0000000..145d7cc
--- /dev/null
+++ b/src/assets/base.css
@@ -0,0 +1,205 @@
+/* color palette from <https://github.com/vuejs/theme> */
+:root {
+ --c-white: #ffffff;
+ --c-white-soft: #f8f8f8;
+ --c-white-mute: #f2f2f2;
+
+ --c-black: #181818;
+ --c-black-soft: #222222;
+ --c-black-mute: #282828;
+
+ --c-indigo: #2c3e50;
+
+ --c-divider-light-1: rgba(60, 60, 60, 0.2);
+ --c-divider-light-2: rgba(60, 60, 60, 0.4);
+ --c-divider-dark-1: rgba(84, 84, 84, 0.2);
+ --c-divider-dark-2: rgba(84, 84, 84, 0.4);
+
+ --c-text-light-1: #f8f8f8;
+ --c-text-light-2: #a7a7a7;
+ --c-text-dark-1: #181818;
+ --c-text-dark-2: #222222;
+
+ --c-brand: #8b72f0;
+ --c-brand-light: #a08df5;
+ --c-brand-dark: #7058d1;
+ --c-brand-mute: #866ee755;
+ --c-brand-highlight: #9885e463;
+
+ --c-true: #2ecc71;
+ --c-false: #e74c3c;
+}
+
+/* semantic color variables for this project */
+:root {
+ --color-background: var(--c-white);
+ --color-background-soft: var(--c-white-soft);
+ --color-background-mute: var(--c-white-mute);
+
+ --color-border: var(--c-divider-light-2);
+ --color-border-soft: var(--c-divider-light-1);
+
+ --color-heading: var(--c-text-dark-1);
+ --color-text: var(--c-text-dark-1);
+ --color-text-mute: var(--c-text-dark-2);
+ --color-text-primary: var(--c-brand-dark);
+
+ --color-primary: var(--c-brand);
+ --color-primary-light: var(--c-brand-light);
+ --color-primary-dark: var(--c-brand-dark);
+ --color-primary-mute: var(--c-brand-mute);
+
+ --color-hover: var(--c-brand-highlight);
+
+ --color-true: var(--c-true);
+ --color-false: var(--c-false);
+
+ --section-gap: 160px;
+}
+
+@media (prefers-color-scheme: dark) {
+ :root {
+ --color-background: var(--c-black);
+ --color-background-soft: var(--c-black-soft);
+ --color-background-mute: var(--c-black-mute);
+
+ --color-border: var(--c-divider-dark-2);
+ --color-border-soft: var(--c-divider-dark-1);
+
+ --color-heading: var(--c-text-light-1);
+ --color-text: var(--c-text-light-1);
+ --color-text-mute: var(--c-text-light-2);
+ --color-text-primary: var(--c-brand-light);
+ }
+}
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+ margin: 0;
+ font-weight: normal;
+}
+
+body {
+ min-height: 100vh;
+ color: var(--color-text);
+ background: var(--color-background);
+ transition:
+ color 0.5s,
+ background-color 0.5s;
+ line-height: 1.6;
+ font-family:
+ Inter,
+ -apple-system,
+ BlinkMacSystemFont,
+ 'Segoe UI',
+ Roboto,
+ Oxygen,
+ Ubuntu,
+ Cantarell,
+ 'Fira Sans',
+ 'Droid Sans',
+ 'Helvetica Neue',
+ sans-serif;
+ font-size: 15px;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+code {
+ font-family: 'Fira Code', monospace;
+}
+
+input {
+ font-family: inherit;
+ font-size: inherit;
+ color: inherit;
+ background: var(--color-background-soft);
+ border: 1px solid var(--color-border);
+ padding: 0.5em 1em;
+ border-radius: 4px;
+ transition: border-color 0.5s;
+}
+
+input:focus {
+ outline: none;
+ border-color: var(--color-primary);
+}
+
+input:disabled {
+ background: var(--color-background-mute);
+ border-color: var(--color-border);
+ color: var(--color-text-mute);
+ cursor: not-allowed;
+}
+
+fieldset {
+ border: 1px solid var(--color-border);
+}
+
+input[type="checkbox"] {
+ accent-color: var(--color-primary);
+}
+
+.multiselect__input {
+ background: var(--color-background-soft) !important ;
+ color: inherit !important;
+
+ &::placeholder {
+ color: rgba(255, 255, 255, .2) !important;
+ }
+}
+
+.multiselect__tags {
+ background: var(--color-background-soft) !important;
+ border: 1px solid var(--color-border) !important;
+ border-radius: 4px !important;
+ overflow-y: auto !important;
+}
+
+.multiselect__single {
+ font-family: monospace !important;
+ background: var(--color-background-soft) !important;
+ color: var(--color-text) !important;
+ font-size: 0.8rem !important;
+}
+
+.multiselect__content {
+ font-family: monospace;
+
+ &-wrapper {
+ background: var(--color-background);
+ border: 0;
+ border-top-left-radius: 2px;
+ border-top-right-radius: 2px;
+ box-shadow: 0 -1rem 2rem rgba(0, 0, 0, .1);
+ }
+}
+
+.multiselect__element {
+ &:not(:first-child) {
+ border-top: 1px solid rgba(0, 0, 0, .2);
+ }
+}
+
+.multiselect__option {
+ &--highlight {
+ background: rgba(255, 255, 255, .2);
+
+ &:after {
+ background: rgba(0, 0, 0, .2);
+ }
+ }
+
+ &--selected {
+ background: var(--color-primary);
+ color: white;
+
+ &:after {
+ color: rgba(0, 0, 0, .5);
+ }
+
+ }
+} \ No newline at end of file
diff --git a/src/assets/main.css b/src/assets/main.css
new file mode 100644
index 0000000..37a2a09
--- /dev/null
+++ b/src/assets/main.css
@@ -0,0 +1,2 @@
+@import 'vue-multiselect/dist/vue-multiselect.css';
+@import './base.css'; \ No newline at end of file
diff --git a/src/assets/quests-logo.png b/src/assets/quests-logo.png
new file mode 100644
index 0000000..0d0194f
--- /dev/null
+++ b/src/assets/quests-logo.png
Binary files differ
diff --git a/src/components/Control/Button.vue b/src/components/Control/Button.vue
new file mode 100644
index 0000000..044cca1
--- /dev/null
+++ b/src/components/Control/Button.vue
@@ -0,0 +1,54 @@
+<script setup lang="ts">
+defineProps({
+ type: {
+ type: String,
+ required: false,
+ default: 'text',
+ },
+ label: String,
+ icon: Array<String>,
+});
+</script>
+
+<template>
+ <a id="button" :class="{text: type === 'text', solid: type === 'solid'}" >
+ <font-awesome-icon :icon="icon" />
+ {{ label }}
+ </a>
+</template>
+
+<style scoped>
+#button {
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+ user-select: none;
+}
+
+.text {
+ background-color: transparent;
+ color: var(--color-text-primary);
+ transition: color 0.3s;
+ font-weight: 700;
+ cursor: pointer;
+}
+
+.solid {
+ background-color: var(--color-primary);
+ transition: background-color 0.3s;
+ color: var(--color-text);
+ padding: 0.25rem 0.5rem;
+ border-radius: 4px;
+ font-weight: 700;
+ cursor: pointer;
+}
+
+.text:hover {
+ color: var(--color-primary-dark);
+}
+
+.solid:hover {
+ background-color: var(--color-primary-dark);
+}
+
+</style> \ No newline at end of file
diff --git a/src/components/Control/Checkbox.vue b/src/components/Control/Checkbox.vue
new file mode 100644
index 0000000..e0325e7
--- /dev/null
+++ b/src/components/Control/Checkbox.vue
@@ -0,0 +1,42 @@
+<script setup lang="ts">
+const model = defineModel();
+
+defineProps({
+ id: String,
+ label: String,
+ description: String,
+});
+
+</script>
+
+<template>
+ <div class="checkbox">
+ <label id="wrapper" :for="id">
+ <input :id="id" type="checkbox" v-model="model" />
+ <span id="label">{{ label }}</span>
+ <span id="description">{{ description }}</span>
+ </label>
+ </div>
+</template>
+
+<style scoped>
+#label {
+ display: block;
+ font-weight: bold;
+}
+
+#description {
+ display: block;
+ font-size: 0.8em;
+}
+
+input {
+ float: left;
+ margin: 5px 0 0 -20px;
+}
+
+.checkbox {
+ padding: 0 0 0 20px;
+}
+
+</style> \ No newline at end of file
diff --git a/src/components/Control/TrueFalseSwitch.vue b/src/components/Control/TrueFalseSwitch.vue
new file mode 100644
index 0000000..a0a3392
--- /dev/null
+++ b/src/components/Control/TrueFalseSwitch.vue
@@ -0,0 +1,54 @@
+<script setup lang="ts">
+import { ref } from 'vue';
+
+const props = defineProps<{
+ value: boolean;
+}>();
+const emit = defineEmits(['update']);
+
+const value = ref(props.value);
+
+const invert = () => {
+ value.value = !value.value;
+ emit('update', value.value);
+};
+</script>
+
+<template>
+ <div class="switch" @click="invert">
+ <span v-if="value" class="true"><font-awesome-icon :icon="['fas', 'fa-check']" /> True</span>
+ <span v-else class="false"><font-awesome-icon :icon="['fas', 'fa-xmark']" /> False</span>
+ </div>
+</template>
+
+<style scoped>
+.switch {
+ display: flex;
+ width: 100%;
+ height: 100%;
+ cursor: pointer;
+ align-items: center;
+ padding: 0.5rem;
+ user-select: none;
+ transition: background-color 0.3s;
+ background-color: var(--color-background-soft);
+
+ span {
+ font-family: monospace;
+ font-size: 0.8rem;
+ }
+
+ .true {
+ color: var(--color-text-primary);
+ }
+
+ .false {
+ color: var(--color-false);
+ }
+
+ &:hover {
+ background-color: var(--color-hover);
+ }
+}
+
+</style> \ No newline at end of file
diff --git a/src/components/Editor/Category/CategoryChildrenOptionsPanel.vue b/src/components/Editor/Category/CategoryChildrenOptionsPanel.vue
new file mode 100644
index 0000000..6e96f64
--- /dev/null
+++ b/src/components/Editor/Category/CategoryChildrenOptionsPanel.vue
@@ -0,0 +1,53 @@
+<script setup lang="ts">
+import { useSessionStore, type EditorCategory } from '@/stores/session';
+import { computed } from 'vue';
+import EditorOptionsPanel from '../EditorOptionsPanel.vue';
+
+const props = defineProps<{
+ categoryId: string;
+}>();
+
+const sessionStore = useSessionStore();
+
+const category = computed(() => {
+ return sessionStore.getCategoryById(props.categoryId) as EditorCategory;
+});
+</script>
+
+<template>
+ <EditorOptionsPanel v-if="category">
+ <div id="options">
+ <h2>Quests in this category</h2>
+ <p>Drag to reorder.</p>
+ <div class="option-group">
+ </div>
+ </div>
+ </EditorOptionsPanel>
+</template>
+
+<style>
+#options {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.option-group {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.description {
+ font-size: 0.8em;
+}
+
+label {
+ font-weight: 700;
+}
+
+h2 {
+ border-bottom: 1px solid var(--color-border);
+}
+</style>
+
diff --git a/src/components/Editor/Category/CategoryOptionsPanel.vue b/src/components/Editor/Category/CategoryOptionsPanel.vue
new file mode 100644
index 0000000..f7d548c
--- /dev/null
+++ b/src/components/Editor/Category/CategoryOptionsPanel.vue
@@ -0,0 +1,54 @@
+<script setup lang="ts">
+import { useSessionStore, type EditorCategory } from '@/stores/session';
+import { computed } from 'vue';
+import EditorOptionsPanel from '../EditorOptionsPanel.vue';
+import Checkbox from '@/components/Control/Checkbox.vue';
+
+const props = defineProps<{
+ categoryId: string;
+}>();
+
+const sessionStore = useSessionStore();
+
+const category = computed(() => {
+ return sessionStore.getCategoryById(props.categoryId) as EditorCategory;
+});
+</script>
+
+<template>
+ <EditorOptionsPanel v-if="category">
+ <div id="options">
+ <div class="option-group">
+ <Checkbox id="category-permissionrequired" label="Require permission for category"
+ description="Players must have permission to open and start quests in this category." v-model="category.permissionRequired" />
+ </div>
+ </div>
+ </EditorOptionsPanel>
+</template>
+
+<style>
+#options {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.option-group {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.description {
+ font-size: 0.8em;
+}
+
+label {
+ font-weight: 700;
+}
+
+h2 {
+ border-bottom: 1px solid var(--color-border);
+}
+</style>
+
diff --git a/src/components/Editor/EditorOptionsPanel.vue b/src/components/Editor/EditorOptionsPanel.vue
new file mode 100644
index 0000000..1415d84
--- /dev/null
+++ b/src/components/Editor/EditorOptionsPanel.vue
@@ -0,0 +1,18 @@
+<script setup lang="ts">
+</script>
+
+<template>
+ <div id="options-panel">
+ <slot />
+ </div>
+</template>
+
+<style scoped>
+#options-panel {
+ width: 100%;
+ background-color: var(--color-background);
+ border: 1px solid var(--color-border);
+ padding: 1rem;
+ height: 100%;
+}
+</style> \ No newline at end of file
diff --git a/src/components/Editor/EditorPane.vue b/src/components/Editor/EditorPane.vue
new file mode 100644
index 0000000..6245e56
--- /dev/null
+++ b/src/components/Editor/EditorPane.vue
@@ -0,0 +1,157 @@
+<script setup lang="ts">
+import { useSessionStore } from '@/stores/session';
+import { computed } from 'vue';
+import { stripColourCodes } from '@/lib/util';
+import QuestOptionsPanel from '@/components/Editor/Quest/QuestOptionsPanel.vue';
+import QuestTasksOptionsPanel from '@/components/Editor/Quest/QuestTasksOptionsPanel.vue';
+import CategoryOptionsPanel from '@/components/Editor/Category/CategoryOptionsPanel.vue';
+import CategoryChildrenOptionsPanel from '@/components/Editor/Category/CategoryChildrenOptionsPanel.vue';
+import Button from '@/components/Control/Button.vue';
+
+const sessionStore = useSessionStore();
+
+const selectedType = computed(() => sessionStore.editor.selected.type);
+const selectedId = computed(() => sessionStore.editor.selected.id);
+const selectedName = computed(() => {
+ if (selectedType.value === 'Quest') {
+ return sessionStore.getQuestById(selectedId.value)?.display.name;
+ } else if (selectedType.value === 'Category') {
+ return sessionStore.getCategoryById(selectedId.value)?.display.name;
+ } else {
+ return '';
+ }
+});
+
+const categoryFromSelectedQuest = computed(() => {
+ const quest = sessionStore.getQuestById(selectedId.value);
+ if (quest) {
+ return sessionStore.getCategoryById(quest.options.category) || null;
+ } else {
+ return null;
+ }
+});
+</script>
+
+<template>
+ <div id="pane-container" v-if="!selectedId || !selectedType">
+ <h1 class="none-selected">Select a quest or category from the sidebar to continue</h1>
+ </div>
+ <div id="pane-container" v-if="selectedId && selectedType">
+ <div id="header">
+ <span id="path">
+ <template v-if="selectedType === 'Quest'">
+ <template v-if="categoryFromSelectedQuest">
+ <font-awesome-icon class="icon" :icon="['fas', 'fa-folder']"/>
+ {{ stripColourCodes(categoryFromSelectedQuest?.display.name) }}
+ <font-awesome-icon class="chevron" :icon="['fas', 'fa-chevron-right']"/>
+ </template>
+ <font-awesome-icon class="icon" :icon="['far', 'fa-compass']"/>
+ <span class="title">{{ stripColourCodes(selectedName!) }} </span>
+ <code>({{ selectedId }})</code>
+ </template>
+ <template v-if="selectedType === 'Category'">
+ <font-awesome-icon class="icon" :icon="['fas', 'fa-folder']"/>
+ <span class="title">{{ stripColourCodes(selectedName!) }} </span>
+ <code>({{ selectedId }})</code>
+ </template>
+ </span>
+ <span id="controls">
+ <Button
+ v-if="selectedType === 'Quest'"
+ :icon="['fas', 'fa-code']"
+ :label="'YAML'"
+ ></Button>
+ <Button
+ :icon="['fas', 'fa-pen']"
+ :label="'Rename'"
+ ></Button>
+ <Button
+ :icon="['fas', 'fa-trash']"
+ :label="'Delete'"
+ ></Button>
+ </span>
+ </div>
+
+ <div id="options-container">
+ <QuestOptionsPanel v-if="selectedType === 'Quest'" :questId="selectedId" />
+ <QuestTasksOptionsPanel v-if="selectedType === 'Quest'" :questId="selectedId" />
+
+ <CategoryOptionsPanel v-if="selectedType === 'Category'" :categoryId="selectedId" />
+ <CategoryChildrenOptionsPanel v-if="selectedType === 'Category'" :categoryId="selectedId" />
+ </div>
+ </div>
+</template>
+
+<style scoped>
+#header {
+ padding: 1rem 1rem 0.5rem 1rem;
+ background-color: var(--color-background);
+ border-bottom: 1px solid var(--color-border);
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+ width: 100%;
+ height: 55px;
+ display: flex;
+ align-items: left;
+ justify-content: space-between;
+ gap: 1rem;
+
+ #path {
+ font-size: 1.2rem;
+ display: flex;
+ gap: 0.5rem;
+ align-items: center;
+
+ .icon {
+ font-size: 0.8rem;
+ }
+
+ .chevron {
+ font-size: 0.8rem;
+ color: var(--color-text-mute);
+ }
+
+ .title {
+ font-weight: 700;
+ }
+
+ code {
+ font-size: 0.8rem;
+ color: var(--color-text-mute);
+ }
+ }
+
+ #controls {
+ display: flex;
+ gap: 1rem;
+ }
+}
+
+.none-selected {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 1rem;
+ font-size: 1.2rem;
+ color: var(--color-text-mute);
+}
+
+#pane-container {
+ width: 100%;
+ flex-grow: 1;
+ height: calc(100vh - 73px);
+ max-height: calc(100vh - 73px);
+}
+
+#options-container {
+ width: 100%;
+ display: flex;
+ gap: 1rem;
+ padding: 1rem;
+ overflow: scroll;
+ max-height: calc(100% - 55px);
+}
+
+header {
+ border-bottom: 1px solid var(--color-border);
+}
+</style> \ No newline at end of file
diff --git a/src/components/Editor/EditorSidebar.vue b/src/components/Editor/EditorSidebar.vue
new file mode 100644
index 0000000..c9539fa
--- /dev/null
+++ b/src/components/Editor/EditorSidebar.vue
@@ -0,0 +1,28 @@
+<script setup lang="ts">
+import { useSessionStore } from '@/stores/session';
+import { storeToRefs } from 'pinia';
+import EditorSidebarCategory from '@/components/Editor/EditorSidebarCategory.vue';
+import EditorSidebarQuest from '@/components/Editor/EditorSidebarQuest.vue';
+
+const sessionStore = useSessionStore();
+
+const { session } = storeToRefs(sessionStore);
+</script>
+
+<template>
+ <div id="sidebar-container">
+ <EditorSidebarCategory v-for="category in session.categories" :key="category.id" :category="category" />
+ <EditorSidebarQuest v-for="quest in session.quests.filter((q) => (!session.categories.some((c) => c.id === q.options.category)))" :key="quest.id" :quest="quest" />
+ </div>
+</template>
+
+<style scoped>
+#sidebar-container {
+ width: 20rem;
+ border-right: 1px solid var(--color-border);
+ height: calc(100vh - 73px);
+ max-height: calc(100vh - 73px);
+ background-color: var(--color-background);
+ user-select: none;
+}
+</style> \ No newline at end of file
diff --git a/src/components/Editor/EditorSidebarCategory.vue b/src/components/Editor/EditorSidebarCategory.vue
new file mode 100644
index 0000000..932b36b
--- /dev/null
+++ b/src/components/Editor/EditorSidebarCategory.vue
@@ -0,0 +1,94 @@
+<script setup lang="ts">
+import { useSessionStore, type EditorCategory } from '@/stores/session';
+import { computed, ref, toRefs } from 'vue';
+import { stripColourCodes } from '@/lib/util';
+import EditorSidebarQuest from '@/components/Editor/EditorSidebarQuest.vue';
+
+const props = defineProps<{
+ category: EditorCategory;
+}>();
+
+const { category } = toRefs(props);
+
+const expanded = ref(true);
+
+const sessionStore = useSessionStore();
+
+const questsInCategory = computed(() => {
+ return sessionStore.getQuestsInCategory(category.value.id);
+});
+
+const expandCategory = () => {
+ expanded.value = !expanded.value;
+};
+
+const setSelectedCategory = () => {
+ sessionStore.setEditorSelected('Category', category.value.id);
+};
+
+const selected = computed(() => {
+ return sessionStore.editor.selected.type === 'Category' && sessionStore.editor.selected.id === category.value.id;
+});
+</script>
+
+<template>
+ <div id="category-container" :class="{selected: selected}">
+ <span id="category-title" @click="setSelectedCategory">
+ <font-awesome-icon @click.stop="expandCategory" class="category-icon" :icon="expanded ? ['fas', 'fa-caret-down'] : ['fas', 'fa-caret-up']"/>
+ <span id="category-name">
+ <span id="category-display-name">{{ stripColourCodes(category.display.name) }}</span>
+ <code id="category-display-id">{{ category.id }}</code>
+ </span>
+ </span>
+ </div>
+ <div v-if="expanded" id="quests">
+ <EditorSidebarQuest class="quest" v-for="quest in questsInCategory" :key="quest.id" :quest="quest" />
+ </div>
+</template>
+
+<style scoped>
+#category-container {
+ cursor: pointer;
+ padding: 0.5rem 1rem;
+ transition: background-color 0.3s;
+ border-bottom: 1px solid var(--color-border-soft);
+
+ #category-title {
+ display: flex;
+ align-items: center;
+ margin: 0;
+ gap: 1rem;
+ font-size: 1.1rem;
+
+ #category-name {
+ display: flex;
+ flex-direction: column;
+ align-items: left;
+
+ #category-display-id {
+ font-size: 0.8rem;
+ color: var(--color-text-mute);
+ }
+ }
+ }
+}
+
+.selected {
+ background-color: var(--color-primary-mute);
+}
+
+#quests {
+ background-color: var(--color-background-mute);
+ border-bottom: 1px solid var(--color-border-soft);
+}
+
+.quest {
+ margin: 0 0 0 1.4rem;
+ background-color: var(--color-background);
+ border-left: 1px solid var(--color-border);
+}
+
+#category-container:hover {
+ background-color: var(--color-hover);
+}
+</style> \ No newline at end of file
diff --git a/src/components/Editor/EditorSidebarQuest.vue b/src/components/Editor/EditorSidebarQuest.vue
new file mode 100644
index 0000000..08f1625
--- /dev/null
+++ b/src/components/Editor/EditorSidebarQuest.vue
@@ -0,0 +1,68 @@
+<script setup lang="ts">
+import { useSessionStore, type EditorQuest } from '@/stores/session';
+import { computed, toRefs } from 'vue';
+import { stripColourCodes } from '@/lib/util';
+
+const props = defineProps<{
+ quest: EditorQuest;
+}>();
+
+const { quest } = toRefs(props);
+
+const sessionStore = useSessionStore();
+
+const setSelectedQuest = () => {
+ sessionStore.setEditorSelected('Quest', quest.value.id);
+};
+
+const selected = computed(() => {
+ return sessionStore.editor.selected.type === 'Quest' && sessionStore.editor.selected.id === quest.value.id;
+});
+</script>
+
+<template>
+ <div id="quest-container" @click.stop="setSelectedQuest" :class="{selected: selected}">
+ <span id="quest-title">
+ <font-awesome-icon class="quest-icon" :icon="['far', 'fa-compass']"/>
+ <span id="quest-name">
+ <span id="quest-display-name">{{ stripColourCodes(quest.display.name) }}</span>
+ <code id="quest-display-id">{{ quest.id }}</code>
+ </span>
+ </span>
+ </div>
+</template>
+
+<style scoped>
+#quest-container {
+ cursor: pointer;
+ padding: 0.3rem 1rem;
+ transition: background-color 0.3s;
+
+ #quest-title {
+ display: flex;
+ align-items: center;
+ margin: 0;
+ gap: 0.5rem;
+ font-size: 0.8rem;
+
+ #quest-name {
+ display: flex;
+ flex-direction: column;
+ align-items: left;
+
+ #quest-display-id {
+ font-size: 0.6rem;
+ color: var(--color-text-mute);
+ }
+ }
+ }
+}
+
+.selected {
+ background-color: var(--color-primary-mute) !important;
+}
+
+#quest-container:hover {
+ background-color: var(--color-hover);
+}
+</style> \ No newline at end of file
diff --git a/src/components/Editor/Quest/QuestOptionsPanel.vue b/src/components/Editor/Quest/QuestOptionsPanel.vue
new file mode 100644
index 0000000..3495d60
--- /dev/null
+++ b/src/components/Editor/Quest/QuestOptionsPanel.vue
@@ -0,0 +1,154 @@
+<script setup lang="ts">
+import { useSessionStore, type EditorQuest } from '@/stores/session';
+import { computed } from 'vue';
+import EditorOptionsPanel from '@/components/Editor/EditorOptionsPanel.vue';
+import Checkbox from '@/components/Control/Checkbox.vue';
+
+const props = defineProps<{
+ questId: string;
+}>();
+
+const sessionStore = useSessionStore();
+
+const quest = computed(() => {
+ return sessionStore.getQuestById(props.questId) as EditorQuest;
+});
+const knownCategories = computed(() => {
+ return sessionStore.session.categories.map((category) => category.id);
+});
+const knownQuests = computed(() => {
+ return sessionStore.session.quests.map((quest) => quest.id);
+});
+</script>
+
+<template>
+ <EditorOptionsPanel v-if="quest">
+ <div id="options">
+ <div class="option-group">
+ <label for="quest-category">Category</label>
+ <multiselect
+ id="quest-category"
+ v-model="quest.options.category"
+ :options="knownCategories"
+ :searchable="true"
+ placeholder="No category"></multiselect>
+ </div>
+
+ <div class="option-group">
+ <label for="quest-requirements">Requirements</label>
+ <multiselect
+ id="quest-requirements"
+ v-model="quest.options.requirements"
+ :options="knownQuests"
+ :searchable="true"
+ :taggable="true"
+ :multiple="true"
+ placeholder="Add requirement"></multiselect>
+ <p class="description">
+ This quest will only be available if the player has completed all of the quests listed above.
+ </p>
+ </div>
+
+ <h2>Quest options</h2>
+
+ <div class="option-group">
+ <Checkbox id="quest-permissionrequired" label="Require permission to start quest"
+ description="Players must have permission to start the quest." v-model="quest.options.permissionRequired" />
+ </div>
+
+ <div class="option-group">
+ <Checkbox id="quest-cancellable" label="Allow players to cancel quest"
+ description="Players can cancel the quest after they have started it." v-model="quest.options.cancellable" />
+ </div>
+
+ <div class="option-group">
+ <Checkbox id="quest-countstowardslimit" label="Count towards quest limit"
+ description="Quest will count towards the player's quest started limit."
+ v-model="quest.options.countsTowardsLimit" />
+ </div>
+
+ <div class="option-group">
+ <Checkbox id="quest-repeatable" label="Allow players to repeat quest"
+ description="Quest can be completed again after it has been completed once."
+ v-model="quest.options.repeatable" />
+ </div>
+
+ <div class="option-group">
+ <Checkbox id="quest-autostart" label="Automatically start quest"
+ description="Quest will start automatically when the player has unlocked it."
+ v-model="quest.options.autostart" />
+ </div>
+
+
+ <h2>Cooldown</h2>
+
+ <div class="option-group">
+ <Checkbox id="quest-cooldown" label="Enable cooldown"
+ description="Players will have to wait a certain amount of time before they can start the quest again."
+ v-model="quest.options.cooldown.enabled" />
+ </div>
+
+ <div class="option-group">
+ <label for="quest-cooldown-time">
+ Cooldown (in seconds)
+ </label>
+ <input id="quest-cooldown-time" type="number" v-model="quest.options.cooldown.time"
+ :disabled="!quest.options.cooldown.enabled" />
+ <p class="description">
+ Common values are: <code>3600</code> (1 hour), <code>86400</code> (24 hours), <code>604800</code> (7 days),
+ <code>2592000</code> (30 days)
+ </p>
+ </div>
+
+ <h2>Time limit</h2>
+
+ <div class="option-group">
+ <Checkbox id="quest-timelimit" label="Enable time limit"
+ description="Players will be required to complete the quest within a certain amount of time, otherwise it will be automatically cancelled."
+ v-model="quest.options.timeLimit.enabled" />
+ </div>
+
+ <div class="option-group">
+ <label for="quest-timelimit-time">
+ Time limit (in seconds)
+ </label>
+ <input id="quest-timelimit-time" type="number" v-model="quest.options.timeLimit.time"
+ :disabled="!quest.options.timeLimit.enabled" />
+ <p class="description">
+ Common values are: <code>3600</code> (1 hour), <code>86400</code> (24 hours), <code>604800</code> (7 days),
+ <code>2592000</code> (30 days)
+ </p>
+ </div>
+ </div>
+ </EditorOptionsPanel>
+</template>
+
+<style src="vue-multiselect/dist/vue-multiselect.css" />
+
+<style>
+#options {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.option-group {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.description {
+ font-size: 0.8em;
+}
+
+label {
+ font-weight: 700;
+}
+
+h2 {
+ border-bottom: 1px solid var(--color-border);
+}
+
+</style>
+
diff --git a/src/components/Editor/Quest/QuestTasksOptionsPanel.vue b/src/components/Editor/Quest/QuestTasksOptionsPanel.vue
new file mode 100644
index 0000000..12b1263
--- /dev/null
+++ b/src/components/Editor/Quest/QuestTasksOptionsPanel.vue
@@ -0,0 +1,75 @@
+<script setup lang="ts">
+import { useSessionStore, type EditorQuest } from '@/stores/session';
+import { computed } from 'vue';
+import EditorOptionsPanel from '@/components/Editor/EditorOptionsPanel.vue';
+import TaskConfiguration from '@/components/Editor/Quest/Task/TaskConfiguration.vue';
+import Button from '@/components/Control/Button.vue';
+
+const props = defineProps<{
+ questId: string;
+}>();
+
+const sessionStore = useSessionStore();
+
+const quest = computed(() => {
+ return sessionStore.getQuestById(props.questId) as EditorQuest;
+});
+</script>
+
+<template>
+ <EditorOptionsPanel v-if="quest">
+ <div id="options">
+ <h2>Tasks <code>({{ Object.keys(quest.tasks).length }})</code></h2>
+
+ <TaskConfiguration v-for="(task, taskId) in quest.tasks" :key="taskId" :taskId="String(taskId)" :quest="quest" />
+
+ <div id="controls">
+ <Button
+ id="add-task"
+ :icon="['fas', 'fa-plus']"
+ type="solid"
+ label="Add task"
+ />
+ </div>
+ </div>
+ </EditorOptionsPanel>
+</template>
+
+
+<style scoped>
+#options {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+
+ #controls {
+ display: flex;
+ justify-content: flex-end;
+ gap: 1rem;
+ }
+}
+
+.option-group {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.description {
+ font-size: 0.8em;
+}
+
+label {
+ font-weight: 700;
+}
+
+h2 {
+ border-bottom: 1px solid var(--color-border);
+
+ code {
+ font-size: 0.8em;
+ color: var(--color-text-mute);
+ }
+}
+</style>
+
diff --git a/src/components/Editor/Quest/Task/TaskConfiguration.vue b/src/components/Editor/Quest/Task/TaskConfiguration.vue
new file mode 100644
index 0000000..5c6613a
--- /dev/null
+++ b/src/components/Editor/Quest/Task/TaskConfiguration.vue
@@ -0,0 +1,191 @@
+<script setup lang="ts">
+import { useSessionStore, type EditorQuest } from '@/stores/session';
+import { computed } from 'vue';
+import Button from '@/components/Control/Button.vue';
+import TaskConfigurationRow from '@/components/Editor/Quest/Task/TaskConfigurationRow.vue';
+
+const props = defineProps<{
+ taskId: string;
+ quest: EditorQuest;
+}>();
+
+const sessionStore = useSessionStore();
+
+const taskType = computed(() => props.quest.tasks[props.taskId].config.type);
+const taskDefintion = computed(() => sessionStore.getTaskDefinitionByTaskType(taskType.value));
+
+const taskConfig = computed(() => {
+ return Object.keys(props.quest.tasks[props.taskId].config).filter((fieldName) => fieldName !== 'type').reduce((acc, fieldName) => {
+ acc[fieldName] = props.quest.tasks[props.taskId].config[fieldName];
+ return acc;
+ }, {} as { [key: string]: any });
+});
+
+const requiredFields = computed(() => {
+ return Object.keys(taskDefintion.value.configuration).filter((fieldName) => taskDefintion.value.configuration[fieldName].required);
+});
+
+const givenRequiredFields = computed(() => {
+ return requiredFields.value.filter((fieldName) => taskConfig.value[fieldName]);
+});
+
+const missingFields = computed(() => {
+ return requiredFields.value.filter((fieldName) => !props.quest.tasks[props.taskId].config[fieldName]);
+});
+
+const remainingGivenFields = computed(() => {
+ return Object.keys(taskConfig.value).filter((fieldName) => !requiredFields.value.includes(fieldName));
+});
+
+const configKeysOptions = computed(() => Object.keys(taskDefintion.value.configuration).filter((key) => !Object.keys(taskConfig.value).some((fieldName) => fieldName === key)));
+// const configKeysOptions = computed(() => {
+// const keys = Object.keys(taskDefintion.value.configuration).filter((key) => !Object.keys(taskConfig.value).some((fieldName) => fieldName === key));
+//
+// return keys.map((key) => {
+// return {
+// value: key,
+// description: taskDefintion.value.configuration[key].description,
+// note: taskDefintion.value.configuration[key].note,
+// };
+// });
+// });
+
+const onAddOption = (option: any) => {
+ sessionStore.getQuestById(props.quest.id)!.tasks[props.taskId].config[option] = taskDefintion.value.configuration[option].default || null;
+};
+
+const updateValue = (fieldName: string, value: any) => {
+ sessionStore.getQuestById(props.quest.id)!.tasks[props.taskId].config[fieldName] = value;
+};
+
+const deleteValue = (fieldName: string) => {
+ delete sessionStore.getQuestById(props.quest.id)!.tasks[props.taskId].config[fieldName];
+};
+
+</script>
+
+<template>
+ <div id="task-configuration-table">
+ <div id="task-header">
+ <p id="task-id">
+ <span id="task-name">
+ {{ props.taskId }}
+ </span>
+ <code>
+ ({{ taskType }})
+ </code>
+ </p>
+ <div id="task-controls">
+ <Button
+ :icon="['fas', 'fa-pen']"
+ :label="'Change'"
+ ></Button>
+ <Button
+ :icon="['fas', 'fa-trash']"
+ :label="'Delete'"
+ ></Button>
+ </div>
+ </div>
+ <div id="task-configuration">
+ <div v-if="!taskDefintion" class="error">
+ <font-awesome-icon id="error-icon" :icon="['fas', 'fa-triangle-exclamation']"/>
+ <p id="error-message">
+ Unable to edit task <code>{{ props.taskId }}</code>.
+ </p>
+ <p id="error-description">
+ The quests web editor does not know how to configure task
+ type <code>{{ taskType }}</code> as it has no task definition.
+ </p>
+ </div>
+
+ <div v-if="taskDefintion">
+ <TaskConfigurationRow
+ v-for="fieldName in [...givenRequiredFields, ...missingFields, ...remainingGivenFields]"
+ :key="fieldName"
+ :required="requiredFields.includes(fieldName)"
+ :configKey="fieldName"
+ :initialValue="taskConfig[fieldName]"
+ :taskType="taskType"
+ :type="(taskDefintion.configuration[fieldName].type as string)"
+ @update="newValue => updateValue(fieldName, newValue)"
+ @delete="() => deleteValue(fieldName)"
+ />
+ <div id="add-option">
+ <multiselect
+ class="multiselect"
+ :options="configKeysOptions"
+ :searchable="true"
+ @select="onAddOption"
+ placeholder="Add option...">
+ </multiselect>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<style scoped>
+.error {
+ padding: 0.5rem 0.5rem 0.5rem calc(0.5rem + 20px);
+
+ #error-icon {
+ float: left;
+ margin: 5px 0 0 -20px;
+ }
+
+ #error-message {
+ font-weight: 700;
+ }
+
+}
+
+#task-configuration-table {
+ display: flex;
+ flex-direction: column;
+ border: 1px solid var(--color-border);
+
+ #task-header {
+ display: flex;
+ justify-content: space-between;
+ border-bottom: 1px solid var(--color-border);
+ background-color: var(--color-background-soft);
+ padding: 0.5rem;
+
+ #task-id {
+ font-size: 1.2em;
+
+ #task-name {
+ font-weight: 700;
+ }
+
+ code {
+ font-size: 0.8em;
+ color: var(--color-text-mute);
+ }
+ }
+
+ #task-controls {
+ display: flex;
+ gap: 1rem;
+ }
+ }
+}
+
+#add-option {
+ width: 100%;
+ border-right: 1px solid var(--color-border);
+ border-top: 1px solid var(--color-border);
+}
+
+.multiselect::v-deep .multiselect__tags {
+ border: none !important;
+ border-radius: 0px !important;
+ background: transparent !important;
+}
+
+.multiselect::v-deep .multiselect__select {
+ background: transparent !important;
+}
+
+</style>
+
diff --git a/src/components/Editor/Quest/Task/TaskConfigurationRow.vue b/src/components/Editor/Quest/Task/TaskConfigurationRow.vue
new file mode 100644
index 0000000..fb872a8
--- /dev/null
+++ b/src/components/Editor/Quest/Task/TaskConfigurationRow.vue
@@ -0,0 +1,156 @@
+<script setup lang="ts">
+import { useSessionStore } from '@/stores/session';
+import { computed, ref, toRefs, watch } from 'vue';
+import TrueFalseSwitch from '@/components/Control/TrueFalseSwitch.vue';
+import materials from '@/data/materials.json';
+
+const props = defineProps({
+ taskType: {
+ type: String,
+ required: true,
+ },
+ configKey: {
+ type: String,
+ required: true,
+ },
+ initialValue: null,
+ type: String,
+ required: Boolean,
+});
+const emit = defineEmits(['update', 'delete']);
+
+const sessionStore = useSessionStore();
+
+const definition = computed(() => {
+ const def = sessionStore.getTaskDefinitionByTaskType(props.taskType).configuration[props.configKey];
+ return { description: def.description, note: def.note };
+});
+
+const { description, note } = toRefs(definition.value);
+const showDescription = ref(false);
+const currentValue = ref(props.initialValue);
+
+const error = computed(() => currentValue.value === undefined || currentValue.value === null || currentValue.value === '');
+const updateValue = (value: any) => {
+ currentValue.value = value;
+};
+
+watch(currentValue, () => {
+ emit('update', currentValue.value);
+});
+
+</script>
+
+<template>
+ <div id="task-configuration-row">
+ <div id="key">
+ <div id="delete" @click="emit('delete')" v-if="!props.required" class="delete">
+ <font-awesome-icon :icon="['fas', 'fa-xmark']" />
+ </div>
+ <p id="name" @click="showDescription = !showDescription">{{ props.configKey }}</p>
+ </div>
+ <div id="value">
+ <div id="value-container">
+ <input v-if="props.type === 'string'" v-model="currentValue" />
+ <input v-else-if="props.type === 'number'" type="number" v-model="currentValue" />
+ <TrueFalseSwitch v-else-if="props.type === 'boolean'" :value="!!currentValue" @update="updateValue" />
+ <multiselect v-else-if="props.type === 'material-list'" :value="currentValue" :options="materials"
+ :multiple="true" :taggable="true" :searchable="true" placeholder="Enter material name"></multiselect>
+ </div>
+ <div v-if="showDescription || error" id="task-configuration-row-info">
+ <p v-if="error" class="error">A value is required.</p>
+ <p>{{ description }} <i>{{ note }}</i></p>
+ </div>
+ </div>
+ </div>
+</template>
+
+<style scoped>
+#task-configuration-row {
+ display: flex;
+ flex-direction: row;
+ transition: background-color 0.3s;
+ border-bottom: 1px solid var(--color-border);
+
+ #key {
+ width: 25%;
+ background-color: var(--color-background);
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ user-select: none;
+
+ #delete {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 20px;
+ height: 100%;
+ cursor: pointer;
+ color: var(--color-text-mute);
+ border-right: 1px solid var(--color-border);
+ background-color: var(--color-background-soft);
+ transition: color 0.3s;
+
+ &:hover {
+ color: var(--color-false);
+ }
+ }
+ #name {
+ display: flex;
+ align-items: center;
+ font-size: 0.8rem;
+ padding: 0.5rem;
+ width: 100%;
+ height: 100%;
+ font-family: monospace;
+ cursor: pointer;
+ transition: background-color 0.3s;
+
+ &:hover {
+ background-color: var(--color-hover);
+ }
+ }
+ }
+
+ #value {
+ width: 75%;
+ background-color: var(--color-background);
+ border-left: 1px solid var(--color-border);
+ }
+}
+
+#task-configuration-row:hover {
+ background-color: var(--color-hover);
+}
+
+#task-configuration-row-info {
+ padding: 0.25rem 0.5rem;
+ font-size: 0.8em;
+ background-color: var(--color-background);
+ border-top: 1px solid var(--color-border);
+}
+
+input {
+ width: 100%;
+ padding: 0.5rem;
+ border-radius: 0;
+ border: none;
+ font-family: monospace;
+ font-size: 0.8rem;
+ height: 40px;
+}
+
+.error {
+ color: var(--color-false);
+}
+
+.multiselect::v-deep .multiselect__tags {
+ border: unset !important;
+ border-radius: 0px !important;
+}
+
+.multiselect::v-deep .multiselect__select {
+ background: unset !important;
+}
+</style> \ No newline at end of file
diff --git a/src/components/Header/SiteHeader.vue b/src/components/Header/SiteHeader.vue
new file mode 100644
index 0000000..f51e970
--- /dev/null
+++ b/src/components/Header/SiteHeader.vue
@@ -0,0 +1,43 @@
+<template>
+ <header>
+ <div id="nav">
+ <img src="@/assets/quests-logo.png" alt="Quests logo" />
+ <h1>Quests Web Editor</h1>
+ <code>Preview</code>
+ </div>
+ </header>
+</template>
+
+<style lang="scss" scoped>
+
+#nav {
+ padding: 1rem 1rem 0.5rem 1rem;
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ max-height: 72px;
+ gap: 1rem;
+
+ img {
+ max-width: 3rem;
+ height: auto;
+ }
+
+ h1 {
+ font-size: 1.5rem;
+ margin: -5px 0 0 0;
+ font-weight: 700;
+ }
+
+ code {
+ font-size: 0.8rem;
+ color: var(--color-text-mute);
+ }
+
+}
+
+header {
+ border-bottom: 1px solid var(--color-border);
+}
+
+</style> \ No newline at end of file
diff --git a/src/data/materials.json b/src/data/materials.json
new file mode 100644
index 0000000..1726002
--- /dev/null
+++ b/src/data/materials.json
@@ -0,0 +1,1924 @@
+[
+ "ACACIA_BOAT",
+ "ACACIA_BUTTON",
+ "ACACIA_CHEST_BOAT",
+ "ACACIA_DOOR",
+ "ACACIA_FENCE",
+ "ACACIA_FENCE_GATE",
+ "ACACIA_HANGING_SIGN",
+ "ACACIA_LEAVES",
+ "ACACIA_LOG",
+ "ACACIA_PLANKS",
+ "ACACIA_PRESSURE_PLATE",
+ "ACACIA_SAPLING",
+ "ACACIA_SIGN",
+ "ACACIA_SLAB",
+ "ACACIA_STAIRS",
+ "ACACIA_TRAPDOOR",
+ "ACACIA_WALL_HANGING_SIGN",
+ "ACACIA_WALL_SIGN",
+ "ACACIA_WOOD",
+ "ACTIVATOR_RAIL",
+ "AIR",
+ "ALLAY_SPAWN_EGG",
+ "ALLIUM",
+ "AMETHYST_BLOCK",
+ "AMETHYST_CLUSTER",
+ "AMETHYST_SHARD",
+ "ANCIENT_DEBRIS",
+ "ANDESITE",
+ "ANDESITE_SLAB",
+ "ANDESITE_STAIRS",
+ "ANDESITE_WALL",
+ "ANGLER_POTTERY_SHERD",
+ "ANVIL",
+ "APPLE",
+ "ARCHER_POTTERY_SHERD",
+ "ARMOR_STAND",
+ "ARMS_UP_POTTERY_SHERD",
+ "ARROW",
+ "ATTACHED_MELON_STEM",
+ "ATTACHED_PUMPKIN_STEM",
+ "AXOLOTL_BUCKET",
+ "AXOLOTL_SPAWN_EGG",
+ "AZALEA",
+ "AZALEA_LEAVES",
+ "AZURE_BLUET",
+ "BAKED_POTATO",
+ "BAMBOO",
+ "BAMBOO_BLOCK",
+ "BAMBOO_BUTTON",
+ "BAMBOO_CHEST_RAFT",
+ "BAMBOO_DOOR",
+ "BAMBOO_FENCE",
+ "BAMBOO_FENCE_GATE",
+ "BAMBOO_HANGING_SIGN",
+ "BAMBOO_MOSAIC",
+ "BAMBOO_MOSAIC_SLAB",
+ "BAMBOO_MOSAIC_STAIRS",
+ "BAMBOO_PLANKS",
+ "BAMBOO_PRESSURE_PLATE",
+ "BAMBOO_RAFT",
+ "BAMBOO_SAPLING",
+ "BAMBOO_SIGN",
+ "BAMBOO_SLAB",
+ "BAMBOO_STAIRS",
+ "BAMBOO_TRAPDOOR",
+ "BAMBOO_WALL_HANGING_SIGN",
+ "BAMBOO_WALL_SIGN",
+ "BARREL",
+ "BARRIER",
+ "BASALT",
+ "BAT_SPAWN_EGG",
+ "BEACON",
+ "BEDROCK",
+ "BEE_NEST",
+ "BEE_SPAWN_EGG",
+ "BEEF",
+ "BEEHIVE",
+ "BEETROOT",
+ "BEETROOT_SEEDS",
+ "BEETROOT_SOUP",
+ "BEETROOTS",
+ "BELL",
+ "BIG_DRIPLEAF",
+ "BIG_DRIPLEAF_STEM",
+ "BIRCH_BOAT",
+ "BIRCH_BUTTON",
+ "BIRCH_CHEST_BOAT",
+ "BIRCH_DOOR",
+ "BIRCH_FENCE",
+ "BIRCH_FENCE_GATE",
+ "BIRCH_HANGING_SIGN",
+ "BIRCH_LEAVES",
+ "BIRCH_LOG",
+ "BIRCH_PLANKS",
+ "BIRCH_PRESSURE_PLATE",
+ "BIRCH_SAPLING",
+ "BIRCH_SIGN",
+ "BIRCH_SLAB",
+ "BIRCH_STAIRS",
+ "BIRCH_TRAPDOOR",
+ "BIRCH_WALL_HANGING_SIGN",
+ "BIRCH_WALL_SIGN",
+ "BIRCH_WOOD",
+ "BLACK_BANNER",
+ "BLACK_BED",
+ "BLACK_CANDLE",
+ "BLACK_CANDLE_CAKE",
+ "BLACK_CARPET",
+ "BLACK_CONCRETE",
+ "BLACK_CONCRETE_POWDER",
+ "BLACK_DYE",
+ "BLACK_GLAZED_TERRACOTTA",
+ "BLACK_SHULKER_BOX",
+ "BLACK_STAINED_GLASS",
+ "BLACK_STAINED_GLASS_PANE",
+ "BLACK_TERRACOTTA",
+ "BLACK_WALL_BANNER",
+ "BLACK_WOOL",
+ "BLACKSTONE",
+ "BLACKSTONE_SLAB",
+ "BLACKSTONE_STAIRS",
+ "BLACKSTONE_WALL",
+ "BLADE_POTTERY_SHERD",
+ "BLAST_FURNACE",
+ "BLAZE_POWDER",
+ "BLAZE_ROD",
+ "BLAZE_SPAWN_EGG",
+ "BLUE_BANNER",
+ "BLUE_BED",
+ "BLUE_CANDLE",
+ "BLUE_CANDLE_CAKE",
+ "BLUE_CARPET",
+ "BLUE_CONCRETE",
+ "BLUE_CONCRETE_POWDER",
+ "BLUE_DYE",
+ "BLUE_GLAZED_TERRACOTTA",
+ "BLUE_ICE",
+ "BLUE_ORCHID",
+ "BLUE_SHULKER_BOX",
+ "BLUE_STAINED_GLASS",
+ "BLUE_STAINED_GLASS_PANE",
+ "BLUE_TERRACOTTA",
+ "BLUE_WALL_BANNER",
+ "BLUE_WOOL",
+ "BONE",
+ "BONE_BLOCK",
+ "BONE_MEAL",
+ "BOOK",
+ "BOOKSHELF",
+ "BOW",
+ "BOWL",
+ "BRAIN_CORAL",
+ "BRAIN_CORAL_BLOCK",
+ "BRAIN_CORAL_FAN",
+ "BRAIN_CORAL_WALL_FAN",
+ "BREAD",
+ "BREEZE_SPAWN_EGG",
+ "BREWER_POTTERY_SHERD",
+ "BREWING_STAND",
+ "BRICK",
+ "BRICK_SLAB",
+ "BRICK_STAIRS",
+ "BRICK_WALL",
+ "BRICKS",
+ "BROWN_BANNER",
+ "BROWN_BED",
+ "BROWN_CANDLE",
+ "BROWN_CANDLE_CAKE",
+ "BROWN_CARPET",
+ "BROWN_CONCRETE",
+ "BROWN_CONCRETE_POWDER",
+ "BROWN_DYE",
+ "BROWN_GLAZED_TERRACOTTA",
+ "BROWN_MUSHROOM",
+ "BROWN_MUSHROOM_BLOCK",
+ "BROWN_SHULKER_BOX",
+ "BROWN_STAINED_GLASS",
+ "BROWN_STAINED_GLASS_PANE",
+ "BROWN_TERRACOTTA",
+ "BROWN_WALL_BANNER",
+ "BROWN_WOOL",
+ "BRUSH",
+ "BUBBLE_COLUMN",
+ "BUBBLE_CORAL",
+ "BUBBLE_CORAL_BLOCK",
+ "BUBBLE_CORAL_FAN",
+ "BUBBLE_CORAL_WALL_FAN",
+ "BUCKET",
+ "BUDDING_AMETHYST",
+ "BUNDLE",
+ "BURN_POTTERY_SHERD",
+ "CACTUS",
+ "CAKE",
+ "CALCITE",
+ "CALIBRATED_SCULK_SENSOR",
+ "CAMEL_SPAWN_EGG",
+ "CAMPFIRE",
+ "CANDLE",
+ "CANDLE_CAKE",
+ "CARROT",
+ "CARROT_ON_A_STICK",
+ "CARROTS",
+ "CARTOGRAPHY_TABLE",
+ "CARVED_PUMPKIN",
+ "CAT_SPAWN_EGG",
+ "CAULDRON",
+ "CAVE_AIR",
+ "CAVE_SPIDER_SPAWN_EGG",
+ "CAVE_VINES",
+ "CAVE_VINES_PLANT",
+ "CHAIN",
+ "CHAIN_COMMAND_BLOCK",
+ "CHAINMAIL_BOOTS",
+ "CHAINMAIL_CHESTPLATE",
+ "CHAINMAIL_HELMET",
+ "CHAINMAIL_LEGGINGS",
+ "CHARCOAL",
+ "CHERRY_BOAT",
+ "CHERRY_BUTTON",
+ "CHERRY_CHEST_BOAT",
+ "CHERRY_DOOR",
+ "CHERRY_FENCE",
+ "CHERRY_FENCE_GATE",
+ "CHERRY_HANGING_SIGN",
+ "CHERRY_LEAVES",
+ "CHERRY_LOG",
+ "CHERRY_PLANKS",
+ "CHERRY_PRESSURE_PLATE",
+ "CHERRY_SAPLING",
+ "CHERRY_SIGN",
+ "CHERRY_SLAB",
+ "CHERRY_STAIRS",
+ "CHERRY_TRAPDOOR",
+ "CHERRY_WALL_HANGING_SIGN",
+ "CHERRY_WALL_SIGN",
+ "CHERRY_WOOD",
+ "CHEST",
+ "CHEST_MINECART",
+ "CHICKEN",
+ "CHICKEN_SPAWN_EGG",
+ "CHIPPED_ANVIL",
+ "CHISELED_BOOKSHELF",
+ "CHISELED_COPPER",
+ "CHISELED_DEEPSLATE",
+ "CHISELED_NETHER_BRICKS",
+ "CHISELED_POLISHED_BLACKSTONE",
+ "CHISELED_QUARTZ_BLOCK",
+ "CHISELED_RED_SANDSTONE",
+ "CHISELED_SANDSTONE",
+ "CHISELED_STONE_BRICKS",
+ "CHISELED_TUFF",
+ "CHISELED_TUFF_BRICKS",
+ "CHORUS_FLOWER",
+ "CHORUS_FRUIT",
+ "CHORUS_PLANT",
+ "CLAY",
+ "CLAY_BALL",
+ "CLOCK",
+ "COAL",
+ "COAL_BLOCK",
+ "COAL_ORE",
+ "COARSE_DIRT",
+ "COAST_ARMOR_TRIM_SMITHING_TEMPLATE",
+ "COBBLED_DEEPSLATE",
+ "COBBLED_DEEPSLATE_SLAB",
+ "COBBLED_DEEPSLATE_STAIRS",
+ "COBBLED_DEEPSLATE_WALL",
+ "COBBLESTONE",
+ "COBBLESTONE_SLAB",
+ "COBBLESTONE_STAIRS",
+ "COBBLESTONE_WALL",
+ "COBWEB",
+ "COCOA",
+ "COCOA_BEANS",
+ "COD",
+ "COD_BUCKET",
+ "COD_SPAWN_EGG",
+ "COMMAND_BLOCK",
+ "COMMAND_BLOCK_MINECART",
+ "COMPARATOR",
+ "COMPASS",
+ "COMPOSTER",
+ "CONDUIT",
+ "COOKED_BEEF",
+ "COOKED_CHICKEN",
+ "COOKED_COD",
+ "COOKED_MUTTON",
+ "COOKED_PORKCHOP",
+ "COOKED_RABBIT",
+ "COOKED_SALMON",
+ "COOKIE",
+ "COPPER_BLOCK",
+ "COPPER_BULB",
+ "COPPER_DOOR",
+ "COPPER_GRATE",
+ "COPPER_INGOT",
+ "COPPER_ORE",
+ "COPPER_TRAPDOOR",
+ "CORNFLOWER",
+ "COW_SPAWN_EGG",
+ "CRACKED_DEEPSLATE_BRICKS",
+ "CRACKED_DEEPSLATE_TILES",
+ "CRACKED_NETHER_BRICKS",
+ "CRACKED_POLISHED_BLACKSTONE_BRICKS",
+ "CRACKED_STONE_BRICKS",
+ "CRAFTER",
+ "CRAFTING_TABLE",
+ "CREEPER_BANNER_PATTERN",
+ "CREEPER_HEAD",
+ "CREEPER_SPAWN_EGG",
+ "CREEPER_WALL_HEAD",
+ "CRIMSON_BUTTON",
+ "CRIMSON_DOOR",
+ "CRIMSON_FENCE",
+ "CRIMSON_FENCE_GATE",
+ "CRIMSON_FUNGUS",
+ "CRIMSON_HANGING_SIGN",
+ "CRIMSON_HYPHAE",
+ "CRIMSON_NYLIUM",
+ "CRIMSON_PLANKS",
+ "CRIMSON_PRESSURE_PLATE",
+ "CRIMSON_ROOTS",
+ "CRIMSON_SIGN",
+ "CRIMSON_SLAB",
+ "CRIMSON_STAIRS",
+ "CRIMSON_STEM",
+ "CRIMSON_TRAPDOOR",
+ "CRIMSON_WALL_HANGING_SIGN",
+ "CRIMSON_WALL_SIGN",
+ "CROSSBOW",
+ "CRYING_OBSIDIAN",
+ "CUT_COPPER",
+ "CUT_COPPER_SLAB",
+ "CUT_COPPER_STAIRS",
+ "CUT_RED_SANDSTONE",
+ "CUT_RED_SANDSTONE_SLAB",
+ "CUT_SANDSTONE",
+ "CUT_SANDSTONE_SLAB",
+ "CYAN_BANNER",
+ "CYAN_BED",
+ "CYAN_CANDLE",
+ "CYAN_CANDLE_CAKE",
+ "CYAN_CARPET",
+ "CYAN_CONCRETE",
+ "CYAN_CONCRETE_POWDER",
+ "CYAN_DYE",
+ "CYAN_GLAZED_TERRACOTTA",
+ "CYAN_SHULKER_BOX",
+ "CYAN_STAINED_GLASS",
+ "CYAN_STAINED_GLASS_PANE",
+ "CYAN_TERRACOTTA",
+ "CYAN_WALL_BANNER",
+ "CYAN_WOOL",
+ "DAMAGED_ANVIL",
+ "DANDELION",
+ "DANGER_POTTERY_SHERD",
+ "DARK_OAK_BOAT",
+ "DARK_OAK_BUTTON",
+ "DARK_OAK_CHEST_BOAT",
+ "DARK_OAK_DOOR",
+ "DARK_OAK_FENCE",
+ "DARK_OAK_FENCE_GATE",
+ "DARK_OAK_HANGING_SIGN",
+ "DARK_OAK_LEAVES",
+ "DARK_OAK_LOG",
+ "DARK_OAK_PLANKS",
+ "DARK_OAK_PRESSURE_PLATE",
+ "DARK_OAK_SAPLING",
+ "DARK_OAK_SIGN",
+ "DARK_OAK_SLAB",
+ "DARK_OAK_STAIRS",
+ "DARK_OAK_TRAPDOOR",
+ "DARK_OAK_WALL_HANGING_SIGN",
+ "DARK_OAK_WALL_SIGN",
+ "DARK_OAK_WOOD",
+ "DARK_PRISMARINE",
+ "DARK_PRISMARINE_SLAB",
+ "DARK_PRISMARINE_STAIRS",
+ "DAYLIGHT_DETECTOR",
+ "DEAD_BRAIN_CORAL",
+ "DEAD_BRAIN_CORAL_BLOCK",
+ "DEAD_BRAIN_CORAL_FAN",
+ "DEAD_BRAIN_CORAL_WALL_FAN",
+ "DEAD_BUBBLE_CORAL",
+ "DEAD_BUBBLE_CORAL_BLOCK",
+ "DEAD_BUBBLE_CORAL_FAN",
+ "DEAD_BUBBLE_CORAL_WALL_FAN",
+ "DEAD_BUSH",
+ "DEAD_FIRE_CORAL",
+ "DEAD_FIRE_CORAL_BLOCK",
+ "DEAD_FIRE_CORAL_FAN",
+ "DEAD_FIRE_CORAL_WALL_FAN",
+ "DEAD_HORN_CORAL",
+ "DEAD_HORN_CORAL_BLOCK",
+ "DEAD_HORN_CORAL_FAN",
+ "DEAD_HORN_CORAL_WALL_FAN",
+ "DEAD_TUBE_CORAL",
+ "DEAD_TUBE_CORAL_BLOCK",
+ "DEAD_TUBE_CORAL_FAN",
+ "DEAD_TUBE_CORAL_WALL_FAN",
+ "DEBUG_STICK",
+ "DECORATED_POT",
+ "DEEPSLATE",
+ "DEEPSLATE_BRICK_SLAB",
+ "DEEPSLATE_BRICK_STAIRS",
+ "DEEPSLATE_BRICK_WALL",
+ "DEEPSLATE_BRICKS",
+ "DEEPSLATE_COAL_ORE",
+ "DEEPSLATE_COPPER_ORE",
+ "DEEPSLATE_DIAMOND_ORE",
+ "DEEPSLATE_EMERALD_ORE",
+ "DEEPSLATE_GOLD_ORE",
+ "DEEPSLATE_IRON_ORE",
+ "DEEPSLATE_LAPIS_ORE",
+ "DEEPSLATE_REDSTONE_ORE",
+ "DEEPSLATE_TILE_SLAB",
+ "DEEPSLATE_TILE_STAIRS",
+ "DEEPSLATE_TILE_WALL",
+ "DEEPSLATE_TILES",
+ "DETECTOR_RAIL",
+ "DIAMOND",
+ "DIAMOND_AXE",
+ "DIAMOND_BLOCK",
+ "DIAMOND_BOOTS",
+ "DIAMOND_CHESTPLATE",
+ "DIAMOND_HELMET",
+ "DIAMOND_HOE",
+ "DIAMOND_HORSE_ARMOR",
+ "DIAMOND_LEGGINGS",
+ "DIAMOND_ORE",
+ "DIAMOND_PICKAXE",
+ "DIAMOND_SHOVEL",
+ "DIAMOND_SWORD",
+ "DIORITE",
+ "DIORITE_SLAB",
+ "DIORITE_STAIRS",
+ "DIORITE_WALL",
+ "DIRT",
+ "DIRT_PATH",
+ "DISC_FRAGMENT_5",
+ "DISPENSER",
+ "DOLPHIN_SPAWN_EGG",
+ "DONKEY_SPAWN_EGG",
+ "DRAGON_BREATH",
+ "DRAGON_EGG",
+ "DRAGON_HEAD",
+ "DRAGON_WALL_HEAD",
+ "DRIED_KELP",
+ "DRIED_KELP_BLOCK",
+ "DRIPSTONE_BLOCK",
+ "DROPPER",
+ "DROWNED_SPAWN_EGG",
+ "DUNE_ARMOR_TRIM_SMITHING_TEMPLATE",
+ "ECHO_SHARD",
+ "EGG",
+ "ELDER_GUARDIAN_SPAWN_EGG",
+ "ELYTRA",
+ "EMERALD",
+ "EMERALD_BLOCK",
+ "EMERALD_ORE",
+ "ENCHANTED_BOOK",
+ "ENCHANTED_GOLDEN_APPLE",
+ "ENCHANTING_TABLE",
+ "END_CRYSTAL",
+ "END_GATEWAY",
+ "END_PORTAL",
+ "END_PORTAL_FRAME",
+ "END_ROD",
+ "END_STONE",
+ "END_STONE_BRICK_SLAB",
+ "END_STONE_BRICK_STAIRS",
+ "END_STONE_BRICK_WALL",
+ "END_STONE_BRICKS",
+ "ENDER_CHEST",
+ "ENDER_DRAGON_SPAWN_EGG",
+ "ENDER_EYE",
+ "ENDER_PEARL",
+ "ENDERMAN_SPAWN_EGG",
+ "ENDERMITE_SPAWN_EGG",
+ "EVOKER_SPAWN_EGG",
+ "EXPERIENCE_BOTTLE",
+ "EXPLORER_POTTERY_SHERD",
+ "EXPOSED_CHISELED_COPPER",
+ "EXPOSED_COPPER",
+ "EXPOSED_COPPER_BULB",
+ "EXPOSED_COPPER_DOOR",
+ "EXPOSED_COPPER_GRATE",
+ "EXPOSED_COPPER_TRAPDOOR",
+ "EXPOSED_CUT_COPPER",
+ "EXPOSED_CUT_COPPER_SLAB",
+ "EXPOSED_CUT_COPPER_STAIRS",
+ "EYE_ARMOR_TRIM_SMITHING_TEMPLATE",
+ "FARMLAND",
+ "FEATHER",
+ "FERMENTED_SPIDER_EYE",
+ "FERN",
+ "FILLED_MAP",
+ "FIRE",
+ "FIRE_CHARGE",
+ "FIRE_CORAL",
+ "FIRE_CORAL_BLOCK",
+ "FIRE_CORAL_FAN",
+ "FIRE_CORAL_WALL_FAN",
+ "FIREWORK_ROCKET",
+ "FIREWORK_STAR",
+ "FISHING_ROD",
+ "FLETCHING_TABLE",
+ "FLINT",
+ "FLINT_AND_STEEL",
+ "FLOWER_BANNER_PATTERN",
+ "FLOWER_POT",
+ "FLOWERING_AZALEA",
+ "FLOWERING_AZALEA_LEAVES",
+ "FOX_SPAWN_EGG",
+ "FRIEND_POTTERY_SHERD",
+ "FROG_SPAWN_EGG",
+ "FROGSPAWN",
+ "FROSTED_ICE",
+ "FURNACE",
+ "FURNACE_MINECART",
+ "GHAST_SPAWN_EGG",
+ "GHAST_TEAR",
+ "GILDED_BLACKSTONE",
+ "GLASS",
+ "GLASS_BOTTLE",
+ "GLASS_PANE",
+ "GLISTERING_MELON_SLICE",
+ "GLOBE_BANNER_PATTERN",
+ "GLOW_BERRIES",
+ "GLOW_INK_SAC",
+ "GLOW_ITEM_FRAME",
+ "GLOW_LICHEN",
+ "GLOW_SQUID_SPAWN_EGG",
+ "GLOWSTONE",
+ "GLOWSTONE_DUST",
+ "GOAT_HORN",
+ "GOAT_SPAWN_EGG",
+ "GOLD_BLOCK",
+ "GOLD_INGOT",
+ "GOLD_NUGGET",
+ "GOLD_ORE",
+ "GOLDEN_APPLE",
+ "GOLDEN_AXE",
+ "GOLDEN_BOOTS",
+ "GOLDEN_CARROT",
+ "GOLDEN_CHESTPLATE",
+ "GOLDEN_HELMET",
+ "GOLDEN_HOE",
+ "GOLDEN_HORSE_ARMOR",
+ "GOLDEN_LEGGINGS",
+ "GOLDEN_PICKAXE",
+ "GOLDEN_SHOVEL",
+ "GOLDEN_SWORD",
+ "GRANITE",
+ "GRANITE_SLAB",
+ "GRANITE_STAIRS",
+ "GRANITE_WALL",
+ "GRASS_BLOCK",
+ "GRAVEL",
+ "GRAY_BANNER",
+ "GRAY_BED",
+ "GRAY_CANDLE",
+ "GRAY_CANDLE_CAKE",
+ "GRAY_CARPET",
+ "GRAY_CONCRETE",
+ "GRAY_CONCRETE_POWDER",
+ "GRAY_DYE",
+ "GRAY_GLAZED_TERRACOTTA",
+ "GRAY_SHULKER_BOX",
+ "GRAY_STAINED_GLASS",
+ "GRAY_STAINED_GLASS_PANE",
+ "GRAY_TERRACOTTA",
+ "GRAY_WALL_BANNER",
+ "GRAY_WOOL",
+ "GREEN_BANNER",
+ "GREEN_BED",
+ "GREEN_CANDLE",
+ "GREEN_CANDLE_CAKE",
+ "GREEN_CARPET",
+ "GREEN_CONCRETE",
+ "GREEN_CONCRETE_POWDER",
+ "GREEN_DYE",
+ "GREEN_GLAZED_TERRACOTTA",
+ "GREEN_SHULKER_BOX",
+ "GREEN_STAINED_GLASS",
+ "GREEN_STAINED_GLASS_PANE",
+ "GREEN_TERRACOTTA",
+ "GREEN_WALL_BANNER",
+ "GREEN_WOOL",
+ "GRINDSTONE",
+ "GUARDIAN_SPAWN_EGG",
+ "GUNPOWDER",
+ "HANGING_ROOTS",
+ "HAY_BLOCK",
+ "HEART_OF_THE_SEA",
+ "HEART_POTTERY_SHERD",
+ "HEARTBREAK_POTTERY_SHERD",
+ "HEAVY_WEIGHTED_PRESSURE_PLATE",
+ "HOGLIN_SPAWN_EGG",
+ "HONEY_BLOCK",
+ "HONEY_BOTTLE",
+ "HONEYCOMB",
+ "HONEYCOMB_BLOCK",
+ "HOPPER",
+ "HOPPER_MINECART",
+ "HORN_CORAL",
+ "HORN_CORAL_BLOCK",
+ "HORN_CORAL_FAN",
+ "HORN_CORAL_WALL_FAN",
+ "HORSE_SPAWN_EGG",
+ "HOST_ARMOR_TRIM_SMITHING_TEMPLATE",
+ "HOWL_POTTERY_SHERD",
+ "HUSK_SPAWN_EGG",
+ "ICE",
+ "INFESTED_CHISELED_STONE_BRICKS",
+ "INFESTED_COBBLESTONE",
+ "INFESTED_CRACKED_STONE_BRICKS",
+ "INFESTED_DEEPSLATE",
+ "INFESTED_MOSSY_STONE_BRICKS",
+ "INFESTED_STONE",
+ "INFESTED_STONE_BRICKS",
+ "INK_SAC",
+ "IRON_AXE",
+ "IRON_BARS",
+ "IRON_BLOCK",
+ "IRON_BOOTS",
+ "IRON_CHESTPLATE",
+ "IRON_DOOR",
+ "IRON_GOLEM_SPAWN_EGG",
+ "IRON_HELMET",
+ "IRON_HOE",
+ "IRON_HORSE_ARMOR",
+ "IRON_INGOT",
+ "IRON_LEGGINGS",
+ "IRON_NUGGET",
+ "IRON_ORE",
+ "IRON_PICKAXE",
+ "IRON_SHOVEL",
+ "IRON_SWORD",
+ "IRON_TRAPDOOR",
+ "ITEM_FRAME",
+ "JACK_O_LANTERN",
+ "JIGSAW",
+ "JUKEBOX",
+ "JUNGLE_BOAT",
+ "JUNGLE_BUTTON",
+ "JUNGLE_CHEST_BOAT",
+ "JUNGLE_DOOR",
+ "JUNGLE_FENCE",
+ "JUNGLE_FENCE_GATE",
+ "JUNGLE_HANGING_SIGN",
+ "JUNGLE_LEAVES",
+ "JUNGLE_LOG",
+ "JUNGLE_PLANKS",
+ "JUNGLE_PRESSURE_PLATE",
+ "JUNGLE_SAPLING",
+ "JUNGLE_SIGN",
+ "JUNGLE_SLAB",
+ "JUNGLE_STAIRS",
+ "JUNGLE_TRAPDOOR",
+ "JUNGLE_WALL_HANGING_SIGN",
+ "JUNGLE_WALL_SIGN",
+ "JUNGLE_WOOD",
+ "KELP",
+ "KELP_PLANT",
+ "KNOWLEDGE_BOOK",
+ "LADDER",
+ "LANTERN",
+ "LAPIS_BLOCK",
+ "LAPIS_LAZULI",
+ "LAPIS_ORE",
+ "LARGE_AMETHYST_BUD",
+ "LARGE_FERN",
+ "LAVA",
+ "LAVA_BUCKET",
+ "LAVA_CAULDRON",
+ "LEAD",
+ "LEATHER",
+ "LEATHER_BOOTS",
+ "LEATHER_CHESTPLATE",
+ "LEATHER_HELMET",
+ "LEATHER_HORSE_ARMOR",
+ "LEATHER_LEGGINGS",
+ "LECTERN",
+ "LEGACY_ACACIA_DOOR",
+ "LEGACY_ACACIA_DOOR_ITEM",
+ "LEGACY_ACACIA_FENCE",
+ "LEGACY_ACACIA_FENCE_GATE",
+ "LEGACY_ACACIA_STAIRS",
+ "LEGACY_ACTIVATOR_RAIL",
+ "LEGACY_AIR",
+ "LEGACY_ANVIL",
+ "LEGACY_APPLE",
+ "LEGACY_ARMOR_STAND",
+ "LEGACY_ARROW",
+ "LEGACY_BAKED_POTATO",
+ "LEGACY_BANNER",
+ "LEGACY_BARRIER",
+ "LEGACY_BEACON",
+ "LEGACY_BED",
+ "LEGACY_BED_BLOCK",
+ "LEGACY_BEDROCK",
+ "LEGACY_BEETROOT",
+ "LEGACY_BEETROOT_BLOCK",
+ "LEGACY_BEETROOT_SEEDS",
+ "LEGACY_BEETROOT_SOUP",
+ "LEGACY_BIRCH_DOOR",
+ "LEGACY_BIRCH_DOOR_ITEM",
+ "LEGACY_BIRCH_FENCE",
+ "LEGACY_BIRCH_FENCE_GATE",
+ "LEGACY_BIRCH_WOOD_STAIRS",
+ "LEGACY_BLACK_GLAZED_TERRACOTTA",
+ "LEGACY_BLACK_SHULKER_BOX",
+ "LEGACY_BLAZE_POWDER",
+ "LEGACY_BLAZE_ROD",
+ "LEGACY_BLUE_GLAZED_TERRACOTTA",
+ "LEGACY_BLUE_SHULKER_BOX",
+ "LEGACY_BOAT",
+ "LEGACY_BOAT_ACACIA",
+ "LEGACY_BOAT_BIRCH",
+ "LEGACY_BOAT_DARK_OAK",
+ "LEGACY_BOAT_JUNGLE",
+ "LEGACY_BOAT_SPRUCE",
+ "LEGACY_BONE",
+ "LEGACY_BONE_BLOCK",
+ "LEGACY_BOOK",
+ "LEGACY_BOOK_AND_QUILL",
+ "LEGACY_BOOKSHELF",
+ "LEGACY_BOW",
+ "LEGACY_BOWL",
+ "LEGACY_BREAD",
+ "LEGACY_BREWING_STAND",
+ "LEGACY_BREWING_STAND_ITEM",
+ "LEGACY_BRICK",
+ "LEGACY_BRICK_STAIRS",
+ "LEGACY_BROWN_GLAZED_TERRACOTTA",
+ "LEGACY_BROWN_MUSHROOM",
+ "LEGACY_BROWN_SHULKER_BOX",
+ "LEGACY_BUCKET",
+ "LEGACY_BURNING_FURNACE",
+ "LEGACY_CACTUS",
+ "LEGACY_CAKE",
+ "LEGACY_CAKE_BLOCK",
+ "LEGACY_CARPET",
+ "LEGACY_CARROT",
+ "LEGACY_CARROT_ITEM",
+ "LEGACY_CARROT_STICK",
+ "LEGACY_CAULDRON",
+ "LEGACY_CAULDRON_ITEM",
+ "LEGACY_CHAINMAIL_BOOTS",
+ "LEGACY_CHAINMAIL_CHESTPLATE",
+ "LEGACY_CHAINMAIL_HELMET",
+ "LEGACY_CHAINMAIL_LEGGINGS",
+ "LEGACY_CHEST",
+ "LEGACY_CHORUS_FLOWER",
+ "LEGACY_CHORUS_FRUIT",
+ "LEGACY_CHORUS_FRUIT_POPPED",
+ "LEGACY_CHORUS_PLANT",
+ "LEGACY_CLAY",
+ "LEGACY_CLAY_BALL",
+ "LEGACY_CLAY_BRICK",
+ "LEGACY_COAL",
+ "LEGACY_COAL_BLOCK",
+ "LEGACY_COAL_ORE",
+ "LEGACY_COBBLE_WALL",
+ "LEGACY_COBBLESTONE",
+ "LEGACY_COBBLESTONE_STAIRS",
+ "LEGACY_COCOA",
+ "LEGACY_COMMAND",
+ "LEGACY_COMMAND_CHAIN",
+ "LEGACY_COMMAND_MINECART",
+ "LEGACY_COMMAND_REPEATING",
+ "LEGACY_COMPASS",
+ "LEGACY_CONCRETE",
+ "LEGACY_CONCRETE_POWDER",
+ "LEGACY_COOKED_BEEF",
+ "LEGACY_COOKED_CHICKEN",
+ "LEGACY_COOKED_FISH",
+ "LEGACY_COOKED_MUTTON",
+ "LEGACY_COOKED_RABBIT",
+ "LEGACY_COOKIE",
+ "LEGACY_CROPS",
+ "LEGACY_CYAN_GLAZED_TERRACOTTA",
+ "LEGACY_CYAN_SHULKER_BOX",
+ "LEGACY_DARK_OAK_DOOR",
+ "LEGACY_DARK_OAK_DOOR_ITEM",
+ "LEGACY_DARK_OAK_FENCE",
+ "LEGACY_DARK_OAK_FENCE_GATE",
+ "LEGACY_DARK_OAK_STAIRS",
+ "LEGACY_DAYLIGHT_DETECTOR",
+ "LEGACY_DAYLIGHT_DETECTOR_INVERTED",
+ "LEGACY_DEAD_BUSH",
+ "LEGACY_DETECTOR_RAIL",
+ "LEGACY_DIAMOND",
+ "LEGACY_DIAMOND_AXE",
+ "LEGACY_DIAMOND_BARDING",
+ "LEGACY_DIAMOND_BLOCK",
+ "LEGACY_DIAMOND_BOOTS",
+ "LEGACY_DIAMOND_CHESTPLATE",
+ "LEGACY_DIAMOND_HELMET",
+ "LEGACY_DIAMOND_HOE",
+ "LEGACY_DIAMOND_LEGGINGS",
+ "LEGACY_DIAMOND_ORE",
+ "LEGACY_DIAMOND_PICKAXE",
+ "LEGACY_DIAMOND_SPADE",
+ "LEGACY_DIAMOND_SWORD",
+ "LEGACY_DIODE",
+ "LEGACY_DIODE_BLOCK_OFF",
+ "LEGACY_DIODE_BLOCK_ON",
+ "LEGACY_DIRT",
+ "LEGACY_DISPENSER",
+ "LEGACY_DOUBLE_PLANT",
+ "LEGACY_DOUBLE_STEP",
+ "LEGACY_DOUBLE_STONE_SLAB2",
+ "LEGACY_DRAGON_EGG",
+ "LEGACY_DRAGONS_BREATH",
+ "LEGACY_DROPPER",
+ "LEGACY_EGG",
+ "LEGACY_ELYTRA",
+ "LEGACY_EMERALD",
+ "LEGACY_EMERALD_BLOCK",
+ "LEGACY_EMERALD_ORE",
+ "LEGACY_EMPTY_MAP",
+ "LEGACY_ENCHANTED_BOOK",
+ "LEGACY_ENCHANTMENT_TABLE",
+ "LEGACY_END_BRICKS",
+ "LEGACY_END_CRYSTAL",
+ "LEGACY_END_GATEWAY",
+ "LEGACY_END_ROD",
+ "LEGACY_ENDER_CHEST",
+ "LEGACY_ENDER_PEARL",
+ "LEGACY_ENDER_PORTAL",
+ "LEGACY_ENDER_PORTAL_FRAME",
+ "LEGACY_ENDER_STONE",
+ "LEGACY_EXP_BOTTLE",
+ "LEGACY_EXPLOSIVE_MINECART",
+ "LEGACY_EYE_OF_ENDER",
+ "LEGACY_FEATHER",
+ "LEGACY_FENCE",
+ "LEGACY_FENCE_GATE",
+ "LEGACY_FERMENTED_SPIDER_EYE",
+ "LEGACY_FIRE",
+ "LEGACY_FIREBALL",
+ "LEGACY_FIREWORK",
+ "LEGACY_FIREWORK_CHARGE",
+ "LEGACY_FISHING_ROD",
+ "LEGACY_FLINT",
+ "LEGACY_FLINT_AND_STEEL",
+ "LEGACY_FLOWER_POT",
+ "LEGACY_FLOWER_POT_ITEM",
+ "LEGACY_FROSTED_ICE",
+ "LEGACY_FURNACE",
+ "LEGACY_GHAST_TEAR",
+ "LEGACY_GLASS",
+ "LEGACY_GLASS_BOTTLE",
+ "LEGACY_GLOWING_REDSTONE_ORE",
+ "LEGACY_GLOWSTONE",
+ "LEGACY_GLOWSTONE_DUST",
+ "LEGACY_GOLD_AXE",
+ "LEGACY_GOLD_BARDING",
+ "LEGACY_GOLD_BLOCK",
+ "LEGACY_GOLD_BOOTS",
+ "LEGACY_GOLD_CHESTPLATE",
+ "LEGACY_GOLD_HELMET",
+ "LEGACY_GOLD_HOE",
+ "LEGACY_GOLD_INGOT",
+ "LEGACY_GOLD_LEGGINGS",
+ "LEGACY_GOLD_NUGGET",
+ "LEGACY_GOLD_ORE",
+ "LEGACY_GOLD_PICKAXE",
+ "LEGACY_GOLD_PLATE",
+ "LEGACY_GOLD_RECORD",
+ "LEGACY_GOLD_SPADE",
+ "LEGACY_GOLD_SWORD",
+ "LEGACY_GOLDEN_APPLE",
+ "LEGACY_GOLDEN_CARROT",
+ "LEGACY_GRASS",
+ "LEGACY_GRASS_PATH",
+ "LEGACY_GRAVEL",
+ "LEGACY_GRAY_GLAZED_TERRACOTTA",
+ "LEGACY_GRAY_SHULKER_BOX",
+ "LEGACY_GREEN_GLAZED_TERRACOTTA",
+ "LEGACY_GREEN_RECORD",
+ "LEGACY_GREEN_SHULKER_BOX",
+ "LEGACY_GRILLED_PORK",
+ "LEGACY_HARD_CLAY",
+ "LEGACY_HAY_BLOCK",
+ "LEGACY_HOPPER",
+ "LEGACY_HOPPER_MINECART",
+ "LEGACY_HUGE_MUSHROOM_1",
+ "LEGACY_HUGE_MUSHROOM_2",
+ "LEGACY_ICE",
+ "LEGACY_INK_SACK",
+ "LEGACY_IRON_AXE",
+ "LEGACY_IRON_BARDING",
+ "LEGACY_IRON_BLOCK",
+ "LEGACY_IRON_BOOTS",
+ "LEGACY_IRON_CHESTPLATE",
+ "LEGACY_IRON_DOOR",
+ "LEGACY_IRON_DOOR_BLOCK",
+ "LEGACY_IRON_FENCE",
+ "LEGACY_IRON_HELMET",
+ "LEGACY_IRON_HOE",
+ "LEGACY_IRON_INGOT",
+ "LEGACY_IRON_LEGGINGS",
+ "LEGACY_IRON_NUGGET",
+ "LEGACY_IRON_ORE",
+ "LEGACY_IRON_PICKAXE",
+ "LEGACY_IRON_PLATE",
+ "LEGACY_IRON_SPADE",
+ "LEGACY_IRON_SWORD",
+ "LEGACY_IRON_TRAPDOOR",
+ "LEGACY_ITEM_FRAME",
+ "LEGACY_JACK_O_LANTERN",
+ "LEGACY_JUKEBOX",
+ "LEGACY_JUNGLE_DOOR",
+ "LEGACY_JUNGLE_DOOR_ITEM",
+ "LEGACY_JUNGLE_FENCE",
+ "LEGACY_JUNGLE_FENCE_GATE",
+ "LEGACY_JUNGLE_WOOD_STAIRS",
+ "LEGACY_KNOWLEDGE_BOOK",
+ "LEGACY_LADDER",
+ "LEGACY_LAPIS_BLOCK",
+ "LEGACY_LAPIS_ORE",
+ "LEGACY_LAVA",
+ "LEGACY_LAVA_BUCKET",
+ "LEGACY_LEASH",
+ "LEGACY_LEATHER",
+ "LEGACY_LEATHER_BOOTS",
+ "LEGACY_LEATHER_CHESTPLATE",
+ "LEGACY_LEATHER_HELMET",
+ "LEGACY_LEATHER_LEGGINGS",
+ "LEGACY_LEAVES",
+ "LEGACY_LEAVES_2",
+ "LEGACY_LEVER",
+ "LEGACY_LIGHT_BLUE_GLAZED_TERRACOTTA",
+ "LEGACY_LIGHT_BLUE_SHULKER_BOX",
+ "LEGACY_LIME_GLAZED_TERRACOTTA",
+ "LEGACY_LIME_SHULKER_BOX",
+ "LEGACY_LINGERING_POTION",
+ "LEGACY_LOG",
+ "LEGACY_LOG_2",
+ "LEGACY_LONG_GRASS",
+ "LEGACY_MAGENTA_GLAZED_TERRACOTTA",
+ "LEGACY_MAGENTA_SHULKER_BOX",
+ "LEGACY_MAGMA",
+ "LEGACY_MAGMA_CREAM",
+ "LEGACY_MAP",
+ "LEGACY_MELON",
+ "LEGACY_MELON_BLOCK",
+ "LEGACY_MELON_SEEDS",
+ "LEGACY_MELON_STEM",
+ "LEGACY_MILK_BUCKET",
+ "LEGACY_MINECART",
+ "LEGACY_MOB_SPAWNER",
+ "LEGACY_MONSTER_EGG",
+ "LEGACY_MONSTER_EGGS",
+ "LEGACY_MOSSY_COBBLESTONE",
+ "LEGACY_MUSHROOM_SOUP",
+ "LEGACY_MUTTON",
+ "LEGACY_MYCEL",
+ "LEGACY_NAME_TAG",
+ "LEGACY_NETHER_BRICK",
+ "LEGACY_NETHER_BRICK_ITEM",
+ "LEGACY_NETHER_BRICK_STAIRS",
+ "LEGACY_NETHER_FENCE",
+ "LEGACY_NETHER_STALK",
+ "LEGACY_NETHER_STAR",
+ "LEGACY_NETHER_WART_BLOCK",
+ "LEGACY_NETHER_WARTS",
+ "LEGACY_NETHERRACK",
+ "LEGACY_NOTE_BLOCK",
+ "LEGACY_OBSERVER",
+ "LEGACY_OBSIDIAN",
+ "LEGACY_ORANGE_GLAZED_TERRACOTTA",
+ "LEGACY_ORANGE_SHULKER_BOX",
+ "LEGACY_PACKED_ICE",
+ "LEGACY_PAINTING",
+ "LEGACY_PAPER",
+ "LEGACY_PINK_GLAZED_TERRACOTTA",
+ "LEGACY_PINK_SHULKER_BOX",
+ "LEGACY_PISTON_BASE",
+ "LEGACY_PISTON_EXTENSION",
+ "LEGACY_PISTON_MOVING_PIECE",
+ "LEGACY_PISTON_STICKY_BASE",
+ "LEGACY_POISONOUS_POTATO",
+ "LEGACY_PORK",
+ "LEGACY_PORTAL",
+ "LEGACY_POTATO",
+ "LEGACY_POTATO_ITEM",
+ "LEGACY_POTION",
+ "LEGACY_POWERED_MINECART",
+ "LEGACY_POWERED_RAIL",
+ "LEGACY_PRISMARINE",
+ "LEGACY_PRISMARINE_CRYSTALS",
+ "LEGACY_PRISMARINE_SHARD",
+ "LEGACY_PUMPKIN",
+ "LEGACY_PUMPKIN_PIE",
+ "LEGACY_PUMPKIN_SEEDS",
+ "LEGACY_PUMPKIN_STEM",
+ "LEGACY_PURPLE_GLAZED_TERRACOTTA",
+ "LEGACY_PURPLE_SHULKER_BOX",
+ "LEGACY_PURPUR_BLOCK",
+ "LEGACY_PURPUR_DOUBLE_SLAB",
+ "LEGACY_PURPUR_PILLAR",
+ "LEGACY_PURPUR_SLAB",
+ "LEGACY_PURPUR_STAIRS",
+ "LEGACY_QUARTZ",
+ "LEGACY_QUARTZ_BLOCK",
+ "LEGACY_QUARTZ_ORE",
+ "LEGACY_QUARTZ_STAIRS",
+ "LEGACY_RABBIT",
+ "LEGACY_RABBIT_FOOT",
+ "LEGACY_RABBIT_HIDE",
+ "LEGACY_RABBIT_STEW",
+ "LEGACY_RAILS",
+ "LEGACY_RAW_BEEF",
+ "LEGACY_RAW_CHICKEN",
+ "LEGACY_RAW_FISH",
+ "LEGACY_RECORD_10",
+ "LEGACY_RECORD_11",
+ "LEGACY_RECORD_12",
+ "LEGACY_RECORD_3",
+ "LEGACY_RECORD_4",
+ "LEGACY_RECORD_5",
+ "LEGACY_RECORD_6",
+ "LEGACY_RECORD_7",
+ "LEGACY_RECORD_8",
+ "LEGACY_RECORD_9",
+ "LEGACY_RED_GLAZED_TERRACOTTA",
+ "LEGACY_RED_MUSHROOM",
+ "LEGACY_RED_NETHER_BRICK",
+ "LEGACY_RED_ROSE",
+ "LEGACY_RED_SANDSTONE",
+ "LEGACY_RED_SANDSTONE_STAIRS",
+ "LEGACY_RED_SHULKER_BOX",
+ "LEGACY_REDSTONE",
+ "LEGACY_REDSTONE_BLOCK",
+ "LEGACY_REDSTONE_COMPARATOR",
+ "LEGACY_REDSTONE_COMPARATOR_OFF",
+ "LEGACY_REDSTONE_COMPARATOR_ON",
+ "LEGACY_REDSTONE_LAMP_OFF",
+ "LEGACY_REDSTONE_LAMP_ON",
+ "LEGACY_REDSTONE_ORE",
+ "LEGACY_REDSTONE_TORCH_OFF",
+ "LEGACY_REDSTONE_TORCH_ON",
+ "LEGACY_REDSTONE_WIRE",
+ "LEGACY_ROTTEN_FLESH",
+ "LEGACY_SADDLE",
+ "LEGACY_SAND",
+ "LEGACY_SANDSTONE",
+ "LEGACY_SANDSTONE_STAIRS",
+ "LEGACY_SAPLING",
+ "LEGACY_SEA_LANTERN",
+ "LEGACY_SEEDS",
+ "LEGACY_SHEARS",
+ "LEGACY_SHIELD",
+ "LEGACY_SHULKER_SHELL",
+ "LEGACY_SIGN",
+ "LEGACY_SIGN_POST",
+ "LEGACY_SILVER_GLAZED_TERRACOTTA",
+ "LEGACY_SILVER_SHULKER_BOX",
+ "LEGACY_SKULL",
+ "LEGACY_SKULL_ITEM",
+ "LEGACY_SLIME_BALL",
+ "LEGACY_SLIME_BLOCK",
+ "LEGACY_SMOOTH_BRICK",
+ "LEGACY_SMOOTH_STAIRS",
+ "LEGACY_SNOW",
+ "LEGACY_SNOW_BALL",
+ "LEGACY_SNOW_BLOCK",
+ "LEGACY_SOIL",
+ "LEGACY_SOUL_SAND",
+ "LEGACY_SPECKLED_MELON",
+ "LEGACY_SPECTRAL_ARROW",
+ "LEGACY_SPIDER_EYE",
+ "LEGACY_SPLASH_POTION",
+ "LEGACY_SPONGE",
+ "LEGACY_SPRUCE_DOOR",
+ "LEGACY_SPRUCE_DOOR_ITEM",
+ "LEGACY_SPRUCE_FENCE",
+ "LEGACY_SPRUCE_FENCE_GATE",
+ "LEGACY_SPRUCE_WOOD_STAIRS",
+ "LEGACY_STAINED_CLAY",
+ "LEGACY_STAINED_GLASS",
+ "LEGACY_STAINED_GLASS_PANE",
+ "LEGACY_STANDING_BANNER",
+ "LEGACY_STATIONARY_LAVA",
+ "LEGACY_STATIONARY_WATER",
+ "LEGACY_STEP",
+ "LEGACY_STICK",
+ "LEGACY_STONE",
+ "LEGACY_STONE_AXE",
+ "LEGACY_STONE_BUTTON",
+ "LEGACY_STONE_HOE",
+ "LEGACY_STONE_PICKAXE",
+ "LEGACY_STONE_PLATE",
+ "LEGACY_STONE_SLAB2",
+ "LEGACY_STONE_SPADE",
+ "LEGACY_STONE_SWORD",
+ "LEGACY_STORAGE_MINECART",
+ "LEGACY_STRING",
+ "LEGACY_STRUCTURE_BLOCK",
+ "LEGACY_STRUCTURE_VOID",
+ "LEGACY_SUGAR",
+ "LEGACY_SUGAR_CANE",
+ "LEGACY_SUGAR_CANE_BLOCK",
+ "LEGACY_SULPHUR",
+ "LEGACY_THIN_GLASS",
+ "LEGACY_TIPPED_ARROW",
+ "LEGACY_TNT",
+ "LEGACY_TORCH",
+ "LEGACY_TOTEM",
+ "LEGACY_TRAP_DOOR",
+ "LEGACY_TRAPPED_CHEST",
+ "LEGACY_TRIPWIRE",
+ "LEGACY_TRIPWIRE_HOOK",
+ "LEGACY_VINE",
+ "LEGACY_WALL_BANNER",
+ "LEGACY_WALL_SIGN",
+ "LEGACY_WATCH",
+ "LEGACY_WATER",
+ "LEGACY_WATER_BUCKET",
+ "LEGACY_WATER_LILY",
+ "LEGACY_WEB",
+ "LEGACY_WHEAT",
+ "LEGACY_WHITE_GLAZED_TERRACOTTA",
+ "LEGACY_WHITE_SHULKER_BOX",
+ "LEGACY_WOOD",
+ "LEGACY_WOOD_AXE",
+ "LEGACY_WOOD_BUTTON",
+ "LEGACY_WOOD_DOOR",
+ "LEGACY_WOOD_DOUBLE_STEP",
+ "LEGACY_WOOD_HOE",
+ "LEGACY_WOOD_PICKAXE",
+ "LEGACY_WOOD_PLATE",
+ "LEGACY_WOOD_SPADE",
+ "LEGACY_WOOD_STAIRS",
+ "LEGACY_WOOD_STEP",
+ "LEGACY_WOOD_SWORD",
+ "LEGACY_WOODEN_DOOR",
+ "LEGACY_WOOL",
+ "LEGACY_WORKBENCH",
+ "LEGACY_WRITTEN_BOOK",
+ "LEGACY_YELLOW_FLOWER",
+ "LEGACY_YELLOW_GLAZED_TERRACOTTA",
+ "LEGACY_YELLOW_SHULKER_BOX",
+ "LEVER",
+ "LIGHT",
+ "LIGHT_BLUE_BANNER",
+ "LIGHT_BLUE_BED",
+ "LIGHT_BLUE_CANDLE",
+ "LIGHT_BLUE_CANDLE_CAKE",
+ "LIGHT_BLUE_CARPET",
+ "LIGHT_BLUE_CONCRETE",
+ "LIGHT_BLUE_CONCRETE_POWDER",
+ "LIGHT_BLUE_DYE",
+ "LIGHT_BLUE_GLAZED_TERRACOTTA",
+ "LIGHT_BLUE_SHULKER_BOX",
+ "LIGHT_BLUE_STAINED_GLASS",
+ "LIGHT_BLUE_STAINED_GLASS_PANE",
+ "LIGHT_BLUE_TERRACOTTA",
+ "LIGHT_BLUE_WALL_BANNER",
+ "LIGHT_BLUE_WOOL",
+ "LIGHT_GRAY_BANNER",
+ "LIGHT_GRAY_BED",
+ "LIGHT_GRAY_CANDLE",
+ "LIGHT_GRAY_CANDLE_CAKE",
+ "LIGHT_GRAY_CARPET",
+ "LIGHT_GRAY_CONCRETE",
+ "LIGHT_GRAY_CONCRETE_POWDER",
+ "LIGHT_GRAY_DYE",
+ "LIGHT_GRAY_GLAZED_TERRACOTTA",
+ "LIGHT_GRAY_SHULKER_BOX",
+ "LIGHT_GRAY_STAINED_GLASS",
+ "LIGHT_GRAY_STAINED_GLASS_PANE",
+ "LIGHT_GRAY_TERRACOTTA",
+ "LIGHT_GRAY_WALL_BANNER",
+ "LIGHT_GRAY_WOOL",
+ "LIGHT_WEIGHTED_PRESSURE_PLATE",
+ "LIGHTNING_ROD",
+ "LILAC",
+ "LILY_OF_THE_VALLEY",
+ "LILY_PAD",
+ "LIME_BANNER",
+ "LIME_BED",
+ "LIME_CANDLE",
+ "LIME_CANDLE_CAKE",
+ "LIME_CARPET",
+ "LIME_CONCRETE",
+ "LIME_CONCRETE_POWDER",
+ "LIME_DYE",
+ "LIME_GLAZED_TERRACOTTA",
+ "LIME_SHULKER_BOX",
+ "LIME_STAINED_GLASS",
+ "LIME_STAINED_GLASS_PANE",
+ "LIME_TERRACOTTA",
+ "LIME_WALL_BANNER",
+ "LIME_WOOL",
+ "LINGERING_POTION",
+ "LLAMA_SPAWN_EGG",
+ "LODESTONE",
+ "LOOM",
+ "MAGENTA_BANNER",
+ "MAGENTA_BED",
+ "MAGENTA_CANDLE",
+ "MAGENTA_CANDLE_CAKE",
+ "MAGENTA_CARPET",
+ "MAGENTA_CONCRETE",
+ "MAGENTA_CONCRETE_POWDER",
+ "MAGENTA_DYE",
+ "MAGENTA_GLAZED_TERRACOTTA",
+ "MAGENTA_SHULKER_BOX",
+ "MAGENTA_STAINED_GLASS",
+ "MAGENTA_STAINED_GLASS_PANE",
+ "MAGENTA_TERRACOTTA",
+ "MAGENTA_WALL_BANNER",
+ "MAGENTA_WOOL",
+ "MAGMA_BLOCK",
+ "MAGMA_CREAM",
+ "MAGMA_CUBE_SPAWN_EGG",
+ "MANGROVE_BOAT",
+ "MANGROVE_BUTTON",
+ "MANGROVE_CHEST_BOAT",
+ "MANGROVE_DOOR",
+ "MANGROVE_FENCE",
+ "MANGROVE_FENCE_GATE",
+ "MANGROVE_HANGING_SIGN",
+ "MANGROVE_LEAVES",
+ "MANGROVE_LOG",
+ "MANGROVE_PLANKS",
+ "MANGROVE_PRESSURE_PLATE",
+ "MANGROVE_PROPAGULE",
+ "MANGROVE_ROOTS",
+ "MANGROVE_SIGN",
+ "MANGROVE_SLAB",
+ "MANGROVE_STAIRS",
+ "MANGROVE_TRAPDOOR",
+ "MANGROVE_WALL_HANGING_SIGN",
+ "MANGROVE_WALL_SIGN",
+ "MANGROVE_WOOD",
+ "MAP",
+ "MEDIUM_AMETHYST_BUD",
+ "MELON",
+ "MELON_SEEDS",
+ "MELON_SLICE",
+ "MELON_STEM",
+ "MILK_BUCKET",
+ "MINECART",
+ "MINER_POTTERY_SHERD",
+ "MOJANG_BANNER_PATTERN",
+ "MOOSHROOM_SPAWN_EGG",
+ "MOSS_BLOCK",
+ "MOSS_CARPET",
+ "MOSSY_COBBLESTONE",
+ "MOSSY_COBBLESTONE_SLAB",
+ "MOSSY_COBBLESTONE_STAIRS",
+ "MOSSY_COBBLESTONE_WALL",
+ "MOSSY_STONE_BRICK_SLAB",
+ "MOSSY_STONE_BRICK_STAIRS",
+ "MOSSY_STONE_BRICK_WALL",
+ "MOSSY_STONE_BRICKS",
+ "MOURNER_POTTERY_SHERD",
+ "MOVING_PISTON",
+ "MUD",
+ "MUD_BRICK_SLAB",
+ "MUD_BRICK_STAIRS",
+ "MUD_BRICK_WALL",
+ "MUD_BRICKS",
+ "MUDDY_MANGROVE_ROOTS",
+ "MULE_SPAWN_EGG",
+ "MUSHROOM_STEM",
+ "MUSHROOM_STEW",
+ "MUSIC_DISC_11",
+ "MUSIC_DISC_13",
+ "MUSIC_DISC_5",
+ "MUSIC_DISC_BLOCKS",
+ "MUSIC_DISC_CAT",
+ "MUSIC_DISC_CHIRP",
+ "MUSIC_DISC_FAR",
+ "MUSIC_DISC_MALL",
+ "MUSIC_DISC_MELLOHI",
+ "MUSIC_DISC_OTHERSIDE",
+ "MUSIC_DISC_PIGSTEP",
+ "MUSIC_DISC_RELIC",
+ "MUSIC_DISC_STAL",
+ "MUSIC_DISC_STRAD",
+ "MUSIC_DISC_WAIT",
+ "MUSIC_DISC_WARD",
+ "MUTTON",
+ "MYCELIUM",
+ "NAME_TAG",
+ "NAUTILUS_SHELL",
+ "NETHER_BRICK",
+ "NETHER_BRICK_FENCE",
+ "NETHER_BRICK_SLAB",
+ "NETHER_BRICK_STAIRS",
+ "NETHER_BRICK_WALL",
+ "NETHER_BRICKS",
+ "NETHER_GOLD_ORE",
+ "NETHER_PORTAL",
+ "NETHER_QUARTZ_ORE",
+ "NETHER_SPROUTS",
+ "NETHER_STAR",
+ "NETHER_WART",
+ "NETHER_WART_BLOCK",
+ "NETHERITE_AXE",
+ "NETHERITE_BLOCK",
+ "NETHERITE_BOOTS",
+ "NETHERITE_CHESTPLATE",
+ "NETHERITE_HELMET",
+ "NETHERITE_HOE",
+ "NETHERITE_INGOT",
+ "NETHERITE_LEGGINGS",
+ "NETHERITE_PICKAXE",
+ "NETHERITE_SCRAP",
+ "NETHERITE_SHOVEL",
+ "NETHERITE_SWORD",
+ "NETHERITE_UPGRADE_SMITHING_TEMPLATE",
+ "NETHERRACK",
+ "NOTE_BLOCK",
+ "OAK_BOAT",
+ "OAK_BUTTON",
+ "OAK_CHEST_BOAT",
+ "OAK_DOOR",
+ "OAK_FENCE",
+ "OAK_FENCE_GATE",
+ "OAK_HANGING_SIGN",
+ "OAK_LEAVES",
+ "OAK_LOG",
+ "OAK_PLANKS",
+ "OAK_PRESSURE_PLATE",
+ "OAK_SAPLING",
+ "OAK_SIGN",
+ "OAK_SLAB",
+ "OAK_STAIRS",
+ "OAK_TRAPDOOR",
+ "OAK_WALL_HANGING_SIGN",
+ "OAK_WALL_SIGN",
+ "OAK_WOOD",
+ "OBSERVER",
+ "OBSIDIAN",
+ "OCELOT_SPAWN_EGG",
+ "OCHRE_FROGLIGHT",
+ "ORANGE_BANNER",
+ "ORANGE_BED",
+ "ORANGE_CANDLE",
+ "ORANGE_CANDLE_CAKE",
+ "ORANGE_CARPET",
+ "ORANGE_CONCRETE",
+ "ORANGE_CONCRETE_POWDER",
+ "ORANGE_DYE",
+ "ORANGE_GLAZED_TERRACOTTA",
+ "ORANGE_SHULKER_BOX",
+ "ORANGE_STAINED_GLASS",
+ "ORANGE_STAINED_GLASS_PANE",
+ "ORANGE_TERRACOTTA",
+ "ORANGE_TULIP",
+ "ORANGE_WALL_BANNER",
+ "ORANGE_WOOL",
+ "OXEYE_DAISY",
+ "OXIDIZED_CHISELED_COPPER",
+ "OXIDIZED_COPPER",
+ "OXIDIZED_COPPER_BULB",
+ "OXIDIZED_COPPER_DOOR",
+ "OXIDIZED_COPPER_GRATE",
+ "OXIDIZED_COPPER_TRAPDOOR",
+ "OXIDIZED_CUT_COPPER",
+ "OXIDIZED_CUT_COPPER_SLAB",
+ "OXIDIZED_CUT_COPPER_STAIRS",
+ "PACKED_ICE",
+ "PACKED_MUD",
+ "PAINTING",
+ "PANDA_SPAWN_EGG",
+ "PAPER",
+ "PARROT_SPAWN_EGG",
+ "PEARLESCENT_FROGLIGHT",
+ "PEONY",
+ "PETRIFIED_OAK_SLAB",
+ "PHANTOM_MEMBRANE",
+ "PHANTOM_SPAWN_EGG",
+ "PIG_SPAWN_EGG",
+ "PIGLIN_BANNER_PATTERN",
+ "PIGLIN_BRUTE_SPAWN_EGG",
+ "PIGLIN_HEAD",
+ "PIGLIN_SPAWN_EGG",
+ "PIGLIN_WALL_HEAD",
+ "PILLAGER_SPAWN_EGG",
+ "PINK_BANNER",
+ "PINK_BED",
+ "PINK_CANDLE",
+ "PINK_CANDLE_CAKE",
+ "PINK_CARPET",
+ "PINK_CONCRETE",
+ "PINK_CONCRETE_POWDER",
+ "PINK_DYE",
+ "PINK_GLAZED_TERRACOTTA",
+ "PINK_PETALS",
+ "PINK_SHULKER_BOX",
+ "PINK_STAINED_GLASS",
+ "PINK_STAINED_GLASS_PANE",
+ "PINK_TERRACOTTA",
+ "PINK_TULIP",
+ "PINK_WALL_BANNER",
+ "PINK_WOOL",
+ "PISTON",
+ "PISTON_HEAD",
+ "PITCHER_CROP",
+ "PITCHER_PLANT",
+ "PITCHER_POD",
+ "PLAYER_HEAD",
+ "PLAYER_WALL_HEAD",
+ "PLENTY_POTTERY_SHERD",
+ "PODZOL",
+ "POINTED_DRIPSTONE",
+ "POISONOUS_POTATO",
+ "POLAR_BEAR_SPAWN_EGG",
+ "POLISHED_ANDESITE",
+ "POLISHED_ANDESITE_SLAB",
+ "POLISHED_ANDESITE_STAIRS",
+ "POLISHED_BASALT",
+ "POLISHED_BLACKSTONE",
+ "POLISHED_BLACKSTONE_BRICK_SLAB",
+ "POLISHED_BLACKSTONE_BRICK_STAIRS",
+ "POLISHED_BLACKSTONE_BRICK_WALL",
+ "POLISHED_BLACKSTONE_BRICKS",
+ "POLISHED_BLACKSTONE_BUTTON",
+ "POLISHED_BLACKSTONE_PRESSURE_PLATE",
+ "POLISHED_BLACKSTONE_SLAB",
+ "POLISHED_BLACKSTONE_STAIRS",
+ "POLISHED_BLACKSTONE_WALL",
+ "POLISHED_DEEPSLATE",
+ "POLISHED_DEEPSLATE_SLAB",
+ "POLISHED_DEEPSLATE_STAIRS",
+ "POLISHED_DEEPSLATE_WALL",
+ "POLISHED_DIORITE",
+ "POLISHED_DIORITE_SLAB",
+ "POLISHED_DIORITE_STAIRS",
+ "POLISHED_GRANITE",
+ "POLISHED_GRANITE_SLAB",
+ "POLISHED_GRANITE_STAIRS",
+ "POLISHED_TUFF",
+ "POLISHED_TUFF_SLAB",
+ "POLISHED_TUFF_STAIRS",
+ "POLISHED_TUFF_WALL",
+ "POPPED_CHORUS_FRUIT",
+ "POPPY",
+ "PORKCHOP",
+ "POTATO",
+ "POTATOES",
+ "POTION",
+ "POTTED_ACACIA_SAPLING",
+ "POTTED_ALLIUM",
+ "POTTED_AZALEA_BUSH",
+ "POTTED_AZURE_BLUET",
+ "POTTED_BAMBOO",
+ "POTTED_BIRCH_SAPLING",
+ "POTTED_BLUE_ORCHID",
+ "POTTED_BROWN_MUSHROOM",
+ "POTTED_CACTUS",
+ "POTTED_CHERRY_SAPLING",
+ "POTTED_CORNFLOWER",
+ "POTTED_CRIMSON_FUNGUS",
+ "POTTED_CRIMSON_ROOTS",
+ "POTTED_DANDELION",
+ "POTTED_DARK_OAK_SAPLING",
+ "POTTED_DEAD_BUSH",
+ "POTTED_FERN",
+ "POTTED_FLOWERING_AZALEA_BUSH",
+ "POTTED_JUNGLE_SAPLING",
+ "POTTED_LILY_OF_THE_VALLEY",
+ "POTTED_MANGROVE_PROPAGULE",
+ "POTTED_OAK_SAPLING",
+ "POTTED_ORANGE_TULIP",
+ "POTTED_OXEYE_DAISY",
+ "POTTED_PINK_TULIP",
+ "POTTED_POPPY",
+ "POTTED_RED_MUSHROOM",
+ "POTTED_RED_TULIP",
+ "POTTED_SPRUCE_SAPLING",
+ "POTTED_TORCHFLOWER",
+ "POTTED_WARPED_FUNGUS",
+ "POTTED_WARPED_ROOTS",
+ "POTTED_WHITE_TULIP",
+ "POTTED_WITHER_ROSE",
+ "POWDER_SNOW",
+ "POWDER_SNOW_BUCKET",
+ "POWDER_SNOW_CAULDRON",
+ "POWERED_RAIL",
+ "PRISMARINE",
+ "PRISMARINE_BRICK_SLAB",
+ "PRISMARINE_BRICK_STAIRS",
+ "PRISMARINE_BRICKS",
+ "PRISMARINE_CRYSTALS",
+ "PRISMARINE_SHARD",
+ "PRISMARINE_SLAB",
+ "PRISMARINE_STAIRS",
+ "PRISMARINE_WALL",
+ "PRIZE_POTTERY_SHERD",
+ "PUFFERFISH",
+ "PUFFERFISH_BUCKET",
+ "PUFFERFISH_SPAWN_EGG",
+ "PUMPKIN",
+ "PUMPKIN_PIE",
+ "PUMPKIN_SEEDS",
+ "PUMPKIN_STEM",
+ "PURPLE_BANNER",
+ "PURPLE_BED",
+ "PURPLE_CANDLE",
+ "PURPLE_CANDLE_CAKE",
+ "PURPLE_CARPET",
+ "PURPLE_CONCRETE",
+ "PURPLE_CONCRETE_POWDER",
+ "PURPLE_DYE",
+ "PURPLE_GLAZED_TERRACOTTA",
+ "PURPLE_SHULKER_BOX",
+ "PURPLE_STAINED_GLASS",
+ "PURPLE_STAINED_GLASS_PANE",
+ "PURPLE_TERRACOTTA",
+ "PURPLE_WALL_BANNER",
+ "PURPLE_WOOL",
+ "PURPUR_BLOCK",
+ "PURPUR_PILLAR",
+ "PURPUR_SLAB",
+ "PURPUR_STAIRS",
+ "QUARTZ",
+ "QUARTZ_BLOCK",
+ "QUARTZ_BRICKS",
+ "QUARTZ_PILLAR",
+ "QUARTZ_SLAB",
+ "QUARTZ_STAIRS",
+ "RABBIT",
+ "RABBIT_FOOT",
+ "RABBIT_HIDE",
+ "RABBIT_SPAWN_EGG",
+ "RABBIT_STEW",
+ "RAIL",
+ "RAISER_ARMOR_TRIM_SMITHING_TEMPLATE",
+ "RAVAGER_SPAWN_EGG",
+ "RAW_COPPER",
+ "RAW_COPPER_BLOCK",
+ "RAW_GOLD",
+ "RAW_GOLD_BLOCK",
+ "RAW_IRON",
+ "RAW_IRON_BLOCK",
+ "RECOVERY_COMPASS",
+ "RED_BANNER",
+ "RED_BED",
+ "RED_CANDLE",
+ "RED_CANDLE_CAKE",
+ "RED_CARPET",
+ "RED_CONCRETE",
+ "RED_CONCRETE_POWDER",
+ "RED_DYE",
+ "RED_GLAZED_TERRACOTTA",
+ "RED_MUSHROOM",
+ "RED_MUSHROOM_BLOCK",
+ "RED_NETHER_BRICK_SLAB",
+ "RED_NETHER_BRICK_STAIRS",
+ "RED_NETHER_BRICK_WALL",
+ "RED_NETHER_BRICKS",
+ "RED_SAND",
+ "RED_SANDSTONE",
+ "RED_SANDSTONE_SLAB",
+ "RED_SANDSTONE_STAIRS",
+ "RED_SANDSTONE_WALL",
+ "RED_SHULKER_BOX",
+ "RED_STAINED_GLASS",
+ "RED_STAINED_GLASS_PANE",
+ "RED_TERRACOTTA",
+ "RED_TULIP",
+ "RED_WALL_BANNER",
+ "RED_WOOL",
+ "REDSTONE",
+ "REDSTONE_BLOCK",
+ "REDSTONE_LAMP",
+ "REDSTONE_ORE",
+ "REDSTONE_TORCH",
+ "REDSTONE_WALL_TORCH",
+ "REDSTONE_WIRE",
+ "REINFORCED_DEEPSLATE",
+ "REPEATER",
+ "REPEATING_COMMAND_BLOCK",
+ "RESPAWN_ANCHOR",
+ "RIB_ARMOR_TRIM_SMITHING_TEMPLATE",
+ "ROOTED_DIRT",
+ "ROSE_BUSH",
+ "ROTTEN_FLESH",
+ "SADDLE",
+ "SALMON",
+ "SALMON_BUCKET",
+ "SALMON_SPAWN_EGG",
+ "SAND",
+ "SANDSTONE",
+ "SANDSTONE_SLAB",
+ "SANDSTONE_STAIRS",
+ "SANDSTONE_WALL",
+ "SCAFFOLDING",
+ "SCULK",
+ "SCULK_CATALYST",
+ "SCULK_SENSOR",
+ "SCULK_SHRIEKER",
+ "SCULK_VEIN",
+ "SCUTE",
+ "SEA_LANTERN",
+ "SEA_PICKLE",
+ "SEAGRASS",
+ "SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE",
+ "SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE",
+ "SHEAF_POTTERY_SHERD",
+ "SHEARS",
+ "SHEEP_SPAWN_EGG",
+ "SHELTER_POTTERY_SHERD",
+ "SHIELD",
+ "SHORT_GRASS",
+ "SHROOMLIGHT",
+ "SHULKER_BOX",
+ "SHULKER_SHELL",
+ "SHULKER_SPAWN_EGG",
+ "SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE",
+ "SILVERFISH_SPAWN_EGG",
+ "SKELETON_HORSE_SPAWN_EGG",
+ "SKELETON_SKULL",
+ "SKELETON_SPAWN_EGG",
+ "SKELETON_WALL_SKULL",
+ "SKULL_BANNER_PATTERN",
+ "SKULL_POTTERY_SHERD",
+ "SLIME_BALL",
+ "SLIME_BLOCK",
+ "SLIME_SPAWN_EGG",
+ "SMALL_AMETHYST_BUD",
+ "SMALL_DRIPLEAF",
+ "SMITHING_TABLE",
+ "SMOKER",
+ "SMOOTH_BASALT",
+ "SMOOTH_QUARTZ",
+ "SMOOTH_QUARTZ_SLAB",
+ "SMOOTH_QUARTZ_STAIRS",
+ "SMOOTH_RED_SANDSTONE",
+ "SMOOTH_RED_SANDSTONE_SLAB",
+ "SMOOTH_RED_SANDSTONE_STAIRS",
+ "SMOOTH_SANDSTONE",
+ "SMOOTH_SANDSTONE_SLAB",
+ "SMOOTH_SANDSTONE_STAIRS",
+ "SMOOTH_STONE",
+ "SMOOTH_STONE_SLAB",
+ "SNIFFER_EGG",
+ "SNIFFER_SPAWN_EGG",
+ "SNORT_POTTERY_SHERD",
+ "SNOUT_ARMOR_TRIM_SMITHING_TEMPLATE",
+ "SNOW",
+ "SNOW_BLOCK",
+ "SNOW_GOLEM_SPAWN_EGG",
+ "SNOWBALL",
+ "SOUL_CAMPFIRE",
+ "SOUL_FIRE",
+ "SOUL_LANTERN",
+ "SOUL_SAND",
+ "SOUL_SOIL",
+ "SOUL_TORCH",
+ "SOUL_WALL_TORCH",
+ "SPAWNER",
+ "SPECTRAL_ARROW",
+ "SPIDER_EYE",
+ "SPIDER_SPAWN_EGG",
+ "SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE",
+ "SPLASH_POTION",
+ "SPONGE",
+ "SPORE_BLOSSOM",
+ "SPRUCE_BOAT",
+ "SPRUCE_BUTTON",
+ "SPRUCE_CHEST_BOAT",
+ "SPRUCE_DOOR",
+ "SPRUCE_FENCE",
+ "SPRUCE_FENCE_GATE",
+ "SPRUCE_HANGING_SIGN",
+ "SPRUCE_LEAVES",
+ "SPRUCE_LOG",
+ "SPRUCE_PLANKS",
+ "SPRUCE_PRESSURE_PLATE",
+ "SPRUCE_SAPLING",
+ "SPRUCE_SIGN",
+ "SPRUCE_SLAB",
+ "SPRUCE_STAIRS",
+ "SPRUCE_TRAPDOOR",
+ "SPRUCE_WALL_HANGING_SIGN",
+ "SPRUCE_WALL_SIGN",
+ "SPRUCE_WOOD",
+ "SPYGLASS",
+ "SQUID_SPAWN_EGG",
+ "STICK",
+ "STICKY_PISTON",
+ "STONE",
+ "STONE_AXE",
+ "STONE_BRICK_SLAB",
+ "STONE_BRICK_STAIRS",
+ "STONE_BRICK_WALL",
+ "STONE_BRICKS",
+ "STONE_BUTTON",
+ "STONE_HOE",
+ "STONE_PICKAXE",
+ "STONE_PRESSURE_PLATE",
+ "STONE_SHOVEL",
+ "STONE_SLAB",
+ "STONE_STAIRS",
+ "STONE_SWORD",
+ "STONECUTTER",
+ "STRAY_SPAWN_EGG",
+ "STRIDER_SPAWN_EGG",
+ "STRING",
+ "STRIPPED_ACACIA_LOG",
+ "STRIPPED_ACACIA_WOOD",
+ "STRIPPED_BAMBOO_BLOCK",
+ "STRIPPED_BIRCH_LOG",
+ "STRIPPED_BIRCH_WOOD",
+ "STRIPPED_CHERRY_LOG",
+ "STRIPPED_CHERRY_WOOD",
+ "STRIPPED_CRIMSON_HYPHAE",
+ "STRIPPED_CRIMSON_STEM",
+ "STRIPPED_DARK_OAK_LOG",
+ "STRIPPED_DARK_OAK_WOOD",
+ "STRIPPED_JUNGLE_LOG",
+ "STRIPPED_JUNGLE_WOOD",
+ "STRIPPED_MANGROVE_LOG",
+ "STRIPPED_MANGROVE_WOOD",
+ "STRIPPED_OAK_LOG",
+ "STRIPPED_OAK_WOOD",
+ "STRIPPED_SPRUCE_LOG",
+ "STRIPPED_SPRUCE_WOOD",
+ "STRIPPED_WARPED_HYPHAE",
+ "STRIPPED_WARPED_STEM",
+ "STRUCTURE_BLOCK",
+ "STRUCTURE_VOID",
+ "SUGAR",
+ "SUGAR_CANE",
+ "SUNFLOWER",
+ "SUSPICIOUS_GRAVEL",
+ "SUSPICIOUS_SAND",
+ "SUSPICIOUS_STEW",
+ "SWEET_BERRIES",
+ "SWEET_BERRY_BUSH",
+ "TADPOLE_BUCKET",
+ "TADPOLE_SPAWN_EGG",
+ "TALL_GRASS",
+ "TALL_SEAGRASS",
+ "TARGET",
+ "TERRACOTTA",
+ "TIDE_ARMOR_TRIM_SMITHING_TEMPLATE",
+ "TINTED_GLASS",
+ "TIPPED_ARROW",
+ "TNT",
+ "TNT_MINECART",
+ "TORCH",
+ "TORCHFLOWER",
+ "TORCHFLOWER_CROP",
+ "TORCHFLOWER_SEEDS",
+ "TOTEM_OF_UNDYING",
+ "TRADER_LLAMA_SPAWN_EGG",
+ "TRAPPED_CHEST",
+ "TRIAL_KEY",
+ "TRIAL_SPAWNER",
+ "TRIDENT",
+ "TRIPWIRE",
+ "TRIPWIRE_HOOK",
+ "TROPICAL_FISH",
+ "TROPICAL_FISH_BUCKET",
+ "TROPICAL_FISH_SPAWN_EGG",
+ "TUBE_CORAL",
+ "TUBE_CORAL_BLOCK",
+ "TUBE_CORAL_FAN",
+ "TUBE_CORAL_WALL_FAN",
+ "TUFF",
+ "TUFF_BRICK_SLAB",
+ "TUFF_BRICK_STAIRS",
+ "TUFF_BRICK_WALL",
+ "TUFF_BRICKS",
+ "TUFF_SLAB",
+ "TUFF_STAIRS",
+ "TUFF_WALL",
+ "TURTLE_EGG",
+ "TURTLE_HELMET",
+ "TURTLE_SPAWN_EGG",
+ "TWISTING_VINES",
+ "TWISTING_VINES_PLANT",
+ "VERDANT_FROGLIGHT",
+ "VEX_ARMOR_TRIM_SMITHING_TEMPLATE",
+ "VEX_SPAWN_EGG",
+ "VILLAGER_SPAWN_EGG",
+ "VINDICATOR_SPAWN_EGG",
+ "VINE",
+ "VOID_AIR",
+ "WALL_TORCH",
+ "WANDERING_TRADER_SPAWN_EGG",
+ "WARD_ARMOR_TRIM_SMITHING_TEMPLATE",
+ "WARDEN_SPAWN_EGG",
+ "WARPED_BUTTON",
+ "WARPED_DOOR",
+ "WARPED_FENCE",
+ "WARPED_FENCE_GATE",
+ "WARPED_FUNGUS",
+ "WARPED_FUNGUS_ON_A_STICK",
+ "WARPED_HANGING_SIGN",
+ "WARPED_HYPHAE",
+ "WARPED_NYLIUM",
+ "WARPED_PLANKS",
+ "WARPED_PRESSURE_PLATE",
+ "WARPED_ROOTS",
+ "WARPED_SIGN",
+ "WARPED_SLAB",
+ "WARPED_STAIRS",
+ "WARPED_STEM",
+ "WARPED_TRAPDOOR",
+ "WARPED_WALL_HANGING_SIGN",
+ "WARPED_WALL_SIGN",
+ "WARPED_WART_BLOCK",
+ "WATER",
+ "WATER_BUCKET",
+ "WATER_CAULDRON",
+ "WAXED_CHISELED_COPPER",
+ "WAXED_COPPER_BLOCK",
+ "WAXED_COPPER_BULB",
+ "WAXED_COPPER_DOOR",
+ "WAXED_COPPER_GRATE",
+ "WAXED_COPPER_TRAPDOOR",
+ "WAXED_CUT_COPPER",
+ "WAXED_CUT_COPPER_SLAB",
+ "WAXED_CUT_COPPER_STAIRS",
+ "WAXED_EXPOSED_CHISELED_COPPER",
+ "WAXED_EXPOSED_COPPER",
+ "WAXED_EXPOSED_COPPER_BULB",
+ "WAXED_EXPOSED_COPPER_DOOR",
+ "WAXED_EXPOSED_COPPER_GRATE",
+ "WAXED_EXPOSED_COPPER_TRAPDOOR",
+ "WAXED_EXPOSED_CUT_COPPER",
+ "WAXED_EXPOSED_CUT_COPPER_SLAB",
+ "WAXED_EXPOSED_CUT_COPPER_STAIRS",
+ "WAXED_OXIDIZED_CHISELED_COPPER",
+ "WAXED_OXIDIZED_COPPER",
+ "WAXED_OXIDIZED_COPPER_BULB",
+ "WAXED_OXIDIZED_COPPER_DOOR",
+ "WAXED_OXIDIZED_COPPER_GRATE",
+ "WAXED_OXIDIZED_COPPER_TRAPDOOR",
+ "WAXED_OXIDIZED_CUT_COPPER",
+ "WAXED_OXIDIZED_CUT_COPPER_SLAB",
+ "WAXED_OXIDIZED_CUT_COPPER_STAIRS",
+ "WAXED_WEATHERED_CHISELED_COPPER",
+ "WAXED_WEATHERED_COPPER",
+ "WAXED_WEATHERED_COPPER_BULB",
+ "WAXED_WEATHERED_COPPER_DOOR",
+ "WAXED_WEATHERED_COPPER_GRATE",
+ "WAXED_WEATHERED_COPPER_TRAPDOOR",
+ "WAXED_WEATHERED_CUT_COPPER",
+ "WAXED_WEATHERED_CUT_COPPER_SLAB",
+ "WAXED_WEATHERED_CUT_COPPER_STAIRS",
+ "WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE",
+ "WEATHERED_CHISELED_COPPER",
+ "WEATHERED_COPPER",
+ "WEATHERED_COPPER_BULB",
+ "WEATHERED_COPPER_DOOR",
+ "WEATHERED_COPPER_GRATE",
+ "WEATHERED_COPPER_TRAPDOOR",
+ "WEATHERED_CUT_COPPER",
+ "WEATHERED_CUT_COPPER_SLAB",
+ "WEATHERED_CUT_COPPER_STAIRS",
+ "WEEPING_VINES",
+ "WEEPING_VINES_PLANT",
+ "WET_SPONGE",
+ "WHEAT",
+ "WHEAT_SEEDS",
+ "WHITE_BANNER",
+ "WHITE_BED",
+ "WHITE_CANDLE",
+ "WHITE_CANDLE_CAKE",
+ "WHITE_CARPET",
+ "WHITE_CONCRETE",
+ "WHITE_CONCRETE_POWDER",
+ "WHITE_DYE",
+ "WHITE_GLAZED_TERRACOTTA",
+ "WHITE_SHULKER_BOX",
+ "WHITE_STAINED_GLASS",
+ "WHITE_STAINED_GLASS_PANE",
+ "WHITE_TERRACOTTA",
+ "WHITE_TULIP",
+ "WHITE_WALL_BANNER",
+ "WHITE_WOOL",
+ "WILD_ARMOR_TRIM_SMITHING_TEMPLATE",
+ "WITCH_SPAWN_EGG",
+ "WITHER_ROSE",
+ "WITHER_SKELETON_SKULL",
+ "WITHER_SKELETON_SPAWN_EGG",
+ "WITHER_SKELETON_WALL_SKULL",
+ "WITHER_SPAWN_EGG",
+ "WOLF_SPAWN_EGG",
+ "WOODEN_AXE",
+ "WOODEN_HOE",
+ "WOODEN_PICKAXE",
+ "WOODEN_SHOVEL",
+ "WOODEN_SWORD",
+ "WRITABLE_BOOK",
+ "WRITTEN_BOOK",
+ "YELLOW_BANNER",
+ "YELLOW_BED",
+ "YELLOW_CANDLE",
+ "YELLOW_CANDLE_CAKE",
+ "YELLOW_CARPET",
+ "YELLOW_CONCRETE",
+ "YELLOW_CONCRETE_POWDER",
+ "YELLOW_DYE",
+ "YELLOW_GLAZED_TERRACOTTA",
+ "YELLOW_SHULKER_BOX",
+ "YELLOW_STAINED_GLASS",
+ "YELLOW_STAINED_GLASS_PANE",
+ "YELLOW_TERRACOTTA",
+ "YELLOW_WALL_BANNER",
+ "YELLOW_WOOL",
+ "ZOGLIN_SPAWN_EGG",
+ "ZOMBIE_HEAD",
+ "ZOMBIE_HORSE_SPAWN_EGG",
+ "ZOMBIE_SPAWN_EGG",
+ "ZOMBIE_VILLAGER_SPAWN_EGG",
+ "ZOMBIE_WALL_HEAD",
+ "ZOMBIFIED_PIGLIN_SPAWN_EGG"
+] \ No newline at end of file
diff --git a/src/data/taskDefinitions.json b/src/data/taskDefinitions.json
new file mode 100644
index 0000000..5a5143e
--- /dev/null
+++ b/src/data/taskDefinitions.json
@@ -0,0 +1,53 @@
+{
+ "taskTypes": {
+ "blockbreak": {
+ "description": "Break a set amount of blocks.",
+ "configuration": {
+ "amount": {
+ "type": "number",
+ "description": "The amount of blocks to break.",
+ "default": 1,
+ "required": true
+ },
+ "block": {
+ "type": "material-list",
+ "description": "The specific block to break.",
+ "note": "Omitting this value will allow any block to be broken."
+ },
+ "data": {
+ "type": "number",
+ "description": "The data value of the block to break.",
+ "default": 0,
+ "note": "Not required for Minecraft versions 1.13 and above."
+ },
+ "reverse-if-placed": {
+ "type": "boolean",
+ "description": "Whether placing blocks should decrement from the quest progress.",
+ "default": false
+ },
+ "check-coreprotect": {
+ "type": "boolean",
+ "description": "Whether the plugin should query CoreProtect if a block has been recently placed.",
+ "default": false,
+ "note": "This requires the CoreProtect plugin to be installed."
+ },
+ "check-coreprotect-time": {
+ "type": "number",
+ "description": "How long ago (in seconds) the plugin should check with CoreProtect whether a block was placed.",
+ "default": false,
+ "note": "This requires the CoreProtect plugin to be installed."
+ },
+ "check-playerblocktracker": {
+ "type": "boolean",
+ "description": "Whether the plugin should query PlayerBlockTracker if a block has been recently placed.",
+ "default": false,
+ "note": "This requires the PlayerBlockTracker plugin to be installed."
+ },
+ "worlds": {
+ "type": "string-list",
+ "description": "The worlds in which the blocks should be broken."
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/data/testData.json b/src/data/testData.json
new file mode 100644
index 0000000..c01d6c3
--- /dev/null
+++ b/src/data/testData.json
@@ -0,0 +1,384 @@
+{
+ "quests": {
+ "example1": {
+ "tasks": {
+ "mining": {
+ "type": "blockbreak",
+ "amount": 30
+ }
+ },
+ "display": {
+ "name": "&cExample I (Single Task)",
+ "lore-normal": [
+ "&cThis category is designed to show you the different",
+ "&cattributes a quest can have.",
+ "",
+ "&7This quest requires you to:",
+ "&7 - Break &f30 blocks&7.",
+ "",
+ "&7Rewards:",
+ "&7 - &f10 &7diamonds."
+ ],
+ "lore-started": [
+ "",
+ "&7Your current progression:",
+ "&7 - &f{mining:progress}&7/30 blocks broken."
+ ],
+ "type": "WOODEN_PICKAXE"
+ },
+ "rewards": [
+ "give {player} diamond 10"
+ ],
+ "placeholders": {
+ "description": "&7Break &f30 blocks &7of any type.",
+ "progress": " &8- &f{mining:progress}&7/30 broken"
+ },
+ "options": {
+ "category": "examples",
+ "repeatable": false,
+ "cooldown": {
+ "enabled": true,
+ "time": 1440
+ },
+ "sort-order": 1
+ }
+ },
+ "example2": {
+ "tasks": {
+ "mining": {
+ "type": "blockbreak",
+ "amount": 100
+ },
+ "building": {
+ "type": "blockplace",
+ "amount": 100
+ }
+ },
+ "display": {
+ "name": "&cExample II (Multiple Tasks)",
+ "lore-normal": [
+ "&cThis category is designed to show you the different",
+ "&cattributes a quest can have. This quest requires",
+ "&cmultiple things to be done, unlike the previous one.",
+ "",
+ "&7This quest requires you to:",
+ "&7 - Break &f100 &7blocks.",
+ "&7 - Place &f100 &7blocks.",
+ "",
+ "&7Rewards:",
+ "&7 - &f15 diamonds&7.",
+ "&7 - &f$50&7 added to your in-game balance."
+ ],
+ "lore-started": [
+ "",
+ "&7Your current progression:",
+ "&7 - &f{mining:progress}&7/100 blocks broken.",
+ "&7 - &f{building:progress}&7/100 blocks placed."
+ ],
+ "type": "GRASS_BLOCK"
+ },
+ "rewards": [
+ "give {player} diamond 15",
+ "eco give {player} 50"
+ ],
+ "placeholders": {
+ "description": "&7Break and place &f100 blocks &7of any type.",
+ "progress": " &8- &f{mining:progress}&7/100 broken, &f{building:progress}&7/100 placed"
+ },
+ "options": {
+ "category": "examples",
+ "requires": [
+ "example1"
+ ],
+ "repeatable": false,
+ "cooldown": {
+ "enabled": true,
+ "time": 1440
+ },
+ "sort-order": 2
+ }
+ },
+ "example3": {
+ "tasks": {
+ "mining": {
+ "type": "blockbreak",
+ "amount": 81,
+ "block": "GOLD_ORE"
+ },
+ "building": {
+ "type": "blockplace",
+ "amount": 9,
+ "block": "GOLD_BLOCK"
+ }
+ },
+ "display": {
+ "name": "&cExample III (Repeatable, 10 minute cooldown)",
+ "lore-normal": [
+ "&cThis category is designed to show you the different",
+ "&cattributes a quest can have. This quest can be replayed",
+ "&cafter a cooldown, unlike the previous one.",
+ "",
+ "&7This quest requires you to:",
+ "&7 - Break &f81 gold ore&7.",
+ "&7 - Place &f9 gold blocks&7.",
+ "",
+ "&7Rewards:",
+ "&7 - &f30 diamonds&7.",
+ "&7 - &f$10&7 added to your in-game balance."
+ ],
+ "lore-started": [
+ "",
+ "&7Your current progression:",
+ "&7 - &f{mining:progress}&7/81 gold ore broken.",
+ "&7 - &f{building:progress}&7/9 gold blocks placed."
+ ],
+ "type": "GOLD_ORE"
+ },
+ "rewards": [
+ "give {player} diamond 30",
+ "eco give {player} 10"
+ ],
+ "placeholders": {
+ "description": "&7Break &f81 gold ore &7and place &f9 gold blocks.",
+ "progress": " &8- &f{mining:progress}&7/81 gold ore, &f{building:progress}&7/9 gold blocks"
+ },
+ "options": {
+ "category": "examples",
+ "requires": [
+ "example2"
+ ],
+ "repeatable": true,
+ "cooldown": {
+ "enabled": true,
+ "time": 10
+ },
+ "sort-order": 3
+ }
+ },
+ "example4": {
+ "tasks": {
+ "mobkilling": {
+ "type": "mobkilling",
+ "amount": 3
+ }
+ },
+ "display": {
+ "name": "&cExample IV (Reward String)",
+ "lore-normal": [
+ "&cThis category is designed to show you the different",
+ "&cattributes a quest can have. This quest has a 'reward string'",
+ "&c(a series of messages sent when a quest is complete),",
+ "&cunlike the previous one.",
+ "",
+ "&7This quest requires you to:",
+ "&7 - Kill &f3 &7mobs.",
+ "",
+ "&7Rewards:",
+ "&7 - &f$50 &7added to your in-game balance.",
+ "&7 - &f1 diamond&7."
+ ],
+ "lore-started": [
+ "",
+ "&7Your current progression:",
+ "&7 - &f{mobkilling:progress}&7/3 mobs killed."
+ ],
+ "type": "STRING"
+ },
+ "startstring": [
+ "&7Upon completion of this quest, you will be rewarded with",
+ " &8* &c$50",
+ " &8* &c1 diamonds"
+ ],
+ "rewards": [
+ "eco give {player} 50",
+ "give {player} diamond 1"
+ ],
+ "placeholders": {
+ "description": "&7Kill &f3 &7mobs.",
+ "progress": " &8- &f{mobkilling:progress}&7/3 mobs"
+ },
+ "rewardstring": [
+ " &8* &c$1000 &7was added to your in-game balance.",
+ " &8* &c1 diamond &7was added to your inventory."
+ ],
+ "options": {
+ "category": "examples",
+ "requires": [
+ "example3"
+ ],
+ "repeatable": true,
+ "cooldown": {
+ "enabled": true,
+ "time": 10
+ },
+ "sort-order": 4
+ }
+ },
+ "example5": {
+ "tasks": {
+ "building": {
+ "type": "blockplace",
+ "amount": 10
+ }
+ },
+ "display": {
+ "name": "&cExample V (Permission)",
+ "lore-normal": [
+ "&cThis category is designed to show you the different",
+ "&cattributes a quest can have. This quest requires",
+ "&ccertain permissions.",
+ "",
+ "&7This quest requires you to:",
+ "&7 - Place &f10 &7blocks.",
+ "",
+ "&7Rewards:",
+ "&7 - &f$10 &7added to your in-game balance."
+ ],
+ "lore-started": [
+ "",
+ "&7Your current progression:",
+ "&7 - &f{building:progress}&7/10 blocks placed."
+ ],
+ "type": "GRASS_BLOCK"
+ },
+ "rewards": [
+ "eco give {player} 10"
+ ],
+ "placeholders": {
+ "description": "&7Place &f10 &7blocks of any type.",
+ "progress": " &8- &f{building:progress}&7/10 blocks"
+ },
+ "options": {
+ "category": "examples",
+ "requires": [
+ "example4"
+ ],
+ "permission-required": true,
+ "repeatable": false,
+ "cooldown": {
+ "enabled": true,
+ "time": 1440
+ },
+ "sort-order": 5
+ }
+ },
+ "example6": {
+ "tasks": {
+ "building": {
+ "type": "blockplace",
+ "amount": 10
+ }
+ },
+ "display": {
+ "name": "&cExample VI (Different category, permissions)",
+ "lore-normal": [
+ "&cThis category is designed to show you the different",
+ "&cattributes a quest can have. This quest requires",
+ "&ccertain permissions.",
+ "",
+ "&7This quest requires you to:",
+ "&7 - Place &f10 &7blocks.",
+ "",
+ "&7Rewards:",
+ "&7 - &f$10 &7added to your in-game balance."
+ ],
+ "lore-started": [
+ "",
+ "&7Your current progression:",
+ "&7 - &f{building:progress}&7/10 blocks placed."
+ ],
+ "type": "GRASS_BLOCK"
+ },
+ "rewards": [
+ "eco give {player} 10"
+ ],
+ "placeholders": {
+ "description": "&7Place &f10 &7blocks of any type.",
+ "progress": " &8- &f{building:progress}&7/10 blocks"
+ },
+ "options": {
+ "category": "permissionexample",
+ "repeatable": false,
+ "cooldown": {
+ "enabled": true,
+ "time": 1440
+ },
+ "sort-order": 1
+ }
+ },
+ "example7": {
+ "tasks": {
+ "building": {
+ "type": "blockplace",
+ "amount": 10,
+ "worlds": [
+ "world"
+ ]
+ }
+ },
+ "display": {
+ "name": "&cExample VII (Different category, world restricted)",
+ "lore-normal": [
+ "&cThis category is designed to show you the different",
+ "&cattributes a quest can have. This quest requires",
+ "&chas a task which requires you to be in a world called 'world'.",
+ "",
+ "&7This quest requires you to:",
+ "&7 - Place &f10 &7blocks.",
+ "",
+ "&7Rewards:",
+ "&7 - &f$10 &7added to your in-game balance."
+ ],
+ "lore-started": [
+ "",
+ "&7Your current progression:",
+ "&7 - &f{building:progress}&7/10 blocks placed."
+ ],
+ "type": "GRASS_BLOCK"
+ },
+ "rewards": [
+ "eco give {player} 10"
+ ],
+ "placeholders": {
+ "description": "&7Place &f10 &7blocks of any type in world &fworld.",
+ "progress": " &8- &f{building:progress}&7/10 blocks"
+ },
+ "options": {
+ "category": "permissionexample",
+ "repeatable": false,
+ "cooldown": {
+ "enabled": true,
+ "time": 1440
+ },
+ "sort-order": 1
+ }
+ }
+ },
+ "categories": {
+ "examples": {
+ "display": {
+ "name": "&cExamples",
+ "lore": [
+ "&cThis category is designed to show you the different",
+ "&cattributes a quest can have."
+ ],
+ "type": "WOODEN_SWORD"
+ }
+ },
+ "permissionexample": {
+ "display": {
+ "name": "&cPermission Example",
+ "lore": [
+ "&7This category is an example of one which",
+ "&7requires a permission to open.",
+ "",
+ "&cIt is highly recommended you read this",
+ "&csection and all the comments so you can",
+ "&cmake the most of this plugin."
+ ],
+ "type": "WATER_BUCKET"
+ },
+ "permission-required": true
+ }
+ }
+} \ No newline at end of file
diff --git a/src/lib/questsLoader.ts b/src/lib/questsLoader.ts
new file mode 100644
index 0000000..0623f04
--- /dev/null
+++ b/src/lib/questsLoader.ts
@@ -0,0 +1,68 @@
+import type { EditorQuest, EditorTask, EditorCategory } from '../stores/session';
+
+export function loadQuestsFromJson(config: any): EditorQuest[] {
+ return Object.keys(config).map((questid: any) => {
+ const quest = config[questid];
+
+ return {
+ id: questid,
+ display: {
+ name: quest.display.name,
+ lore: {
+ normal: quest.display['lore-normal'],
+ started: quest.display['lore-started'],
+ },
+ type: quest.display.type,
+ },
+ tasks: Object.fromEntries(Object.keys(quest.tasks).map((taskId: string) => {
+ return [taskId, {
+ id: taskId,
+ config: quest.tasks[taskId],
+ } as EditorTask];
+ })),
+ rewards: quest.rewards,
+ ...(quest.startcommands && { startCommands: quest.startcommands }),
+ ...(quest.startstring && { startString: quest.startstring }),
+ ...(quest.rewardstring && { rewardString: quest.rewardstring }),
+ ...(quest.placeholders && { placeholders: quest.placeholders }),
+ options: {
+ category: quest.options.category,
+ requirements: quest.options.requires || [],
+ permissionRequired: quest.options['permission-required'] || false,
+ cancellable: quest.options.cancellable || false,
+ countsTowardsLimit: quest.options['counts-towards-limit'] || true,
+ repeatable: quest.options.repeatable || false,
+ cooldown: {
+ enabled: quest.options.cooldown?.enabled || false,
+ time: quest.options.cooldown?.time || 0,
+ },
+ timeLimit: {
+ enabled: quest.options['time-limit']?.enabled || false,
+ time: quest.options['time-limit']?.time || 0,
+ },
+ sortOrder: quest.options['sort-order'] || 0,
+ autostart: quest.options.autostart || false,
+ ...(quest.options['completed-display'] && { completedDisplay: quest.options['completed-display'] }),
+ ...(quest.options['cooldown-display'] && { cooldownDisplay: quest.options['cooldown-display'] }),
+ ...(quest.options['permission-display'] && { permissionDisplay: quest.options['permission-display'] }),
+ ...(quest.options['locked-display'] && { lockedDisplay: quest.options['locked-display'] }),
+ },
+ } as EditorQuest;
+ });
+}
+
+export function loadCategoriesFromJson(config: any): EditorCategory[] {
+ return Object.keys(config).map((categoryid: any) => {
+ const category = config[categoryid];
+
+ return {
+ id: categoryid,
+ display: {
+ name: category.display.name,
+ lore: category.display.lore,
+ type: category.display.type,
+ },
+ permissionRequired: category['permission-required'],
+ };
+ });
+}
diff --git a/src/lib/util.ts b/src/lib/util.ts
new file mode 100644
index 0000000..9903e2c
--- /dev/null
+++ b/src/lib/util.ts
@@ -0,0 +1,3 @@
+export function stripColourCodes(str: string): string {
+ return str.replace(/&[0-9a-fk-or]/i, '');
+} \ No newline at end of file
diff --git a/src/main.ts b/src/main.ts
new file mode 100644
index 0000000..6e14a1e
--- /dev/null
+++ b/src/main.ts
@@ -0,0 +1,35 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
+import { library } from "@fortawesome/fontawesome-svg-core";
+import { faFolder, faCaretDown, faCaretUp, faChevronRight, faTriangleExclamation, faPen, faTrash, faCode, faCheck, faXmark, faPlus } from "@fortawesome/free-solid-svg-icons";
+import { faCompass } from '@fortawesome/free-regular-svg-icons';
+
+import App from './App.vue'
+import Multiselect from 'vue-multiselect'
+import router from './router'
+
+const app = createApp(App)
+
+library.add(faFolder);
+library.add(faCaretDown);
+library.add(faCaretUp);
+library.add(faChevronRight);
+library.add(faCompass);
+library.add(faTriangleExclamation);
+library.add(faPen);
+library.add(faTrash);
+library.add(faCode);
+library.add(faCheck);
+library.add(faXmark);
+library.add(faPlus);
+
+app.component('font-awesome-icon', FontAwesomeIcon)
+app.component('multiselect', Multiselect)
+
+app.use(createPinia())
+app.use(router)
+
+app.mount('#app')
diff --git a/src/router/index.ts b/src/router/index.ts
new file mode 100644
index 0000000..9091d16
--- /dev/null
+++ b/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import EditorView from '../views/EditorView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: EditorView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/EditorView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/src/stores/session.ts b/src/stores/session.ts
new file mode 100644
index 0000000..22db332
--- /dev/null
+++ b/src/stores/session.ts
@@ -0,0 +1,149 @@
+import { defineStore } from 'pinia'
+
+export interface EditorQuest {
+ id: string;
+ display: {
+ name: string;
+ lore: {
+ normal: string[];
+ started: string[];
+ }
+ type: string;
+ }
+ tasks: { [key: string]: EditorTask };
+ rewards: string[];
+ startCommands?: string[];
+ startString?: string[];
+ rewardString?: string[];
+ placeholders?: { [key: string]: string };
+ options: {
+ category: string;
+ requirements: string[];
+ permissionRequired: boolean;
+ cancellable: boolean;
+ countsTowardsLimit: boolean;
+ repeatable: boolean;
+ cooldown: {
+ enabled: boolean;
+ time: number;
+ }
+ timeLimit: {
+ enabled: boolean;
+ time: number;
+ }
+ sortOrder: number;
+ autostart: boolean;
+ completedDisplay?: string;
+ cooldownDisplay?: string;
+ permissionDisplay?: string;
+ lockedDisplay?: string;
+ }
+}
+
+export interface EditorTask {
+ id: string;
+ config: {
+ type: string;
+ [key: string]: any;
+ }
+}
+
+export interface EditorCategory {
+ id: string;
+ display: {
+ name: string;
+ lore: string[];
+ type: string;
+ }
+ permissionRequired: string;
+}
+
+export interface TaskDefinition {
+ description: string;
+ configuration: {
+ [key: string]: {
+ type: string | string[];
+ description: string;
+ default?: any;
+ required?: boolean;
+ note?: string;
+ }
+ }
+}
+
+export const useSessionStore = defineStore('session', {
+ state: () => ({
+ sessionType: '',
+ session: {
+ quests: [] as EditorQuest[],
+ categories: [] as EditorCategory[],
+ taskDefinitions: {} as { [key: string]: TaskDefinition },
+ },
+ editor: {
+ selected: {
+ type: '' as 'Quest' | 'Category',
+ id: '',
+ }
+ }
+ }),
+ getters: {
+ getSessionType(): string {
+ return this.sessionType
+ },
+ getQuests(): EditorQuest[] {
+ return this.session.quests
+ },
+ getCategories(): EditorCategory[] {
+ return this.session.categories
+ },
+ getQuestById: (state) => (id: string) => {
+ return state.session.quests.find(quest => quest.id === id)
+ },
+ getCategoryById: (state) => (id: string) => {
+ return state.session.categories.find(quest => quest.id === id)
+ },
+ getQuestsInCategory: (state) => (id: string) => {
+ return state.session.quests.filter(quest => quest.options.category === id)
+ },
+ getTaskDefinitions: (state) => {
+ return state.session.taskDefinitions
+ },
+ getTaskDefinitionByTaskType: (state) => (type: string) => {
+ return state.session.taskDefinitions[type]
+ },
+ getKnownTaskTypes: (state) => () => {
+ return Object.keys(state.session.taskDefinitions)
+ }
+ // getEditorCategories: (state) => {
+ // return state.editor.categories
+ // }
+ },
+ actions: {
+ setSessionType(type: string) {
+ this.sessionType = type
+ },
+ setQuests(quests: EditorQuest[]) {
+ this.session.quests = quests
+ },
+ setCategories(categories: EditorCategory[]) {
+ this.session.categories = categories
+ },
+ // updateEditorCategories() {
+ // const categories: { [key: string]: { quests: string[] } } = {}
+ // this.session.categories.forEach(category => {
+ // categories[category.id] = { quests: [] }
+ // })
+ // this.session.quests.forEach(quest => {
+ // categories[quest.options.category].quests.push(quest.id)
+ // })
+ // this.editor.categories = categories;
+ // },
+ setEditorSelected(type: 'Quest' | 'Category', id: string) {
+ this.editor.selected.type = type
+ this.editor.selected.id = id
+ },
+ setTaskDefinitions(definitions: { [key: string]: TaskDefinition }) {
+ this.session.taskDefinitions = definitions
+ }
+ }
+});
diff --git a/src/views/EditorView.vue b/src/views/EditorView.vue
new file mode 100644
index 0000000..b94f998
--- /dev/null
+++ b/src/views/EditorView.vue
@@ -0,0 +1,37 @@
+<script setup lang="ts">
+import { useSessionStore } from '@/stores/session';
+import { loadQuestsFromJson, loadCategoriesFromJson } from '@/lib/questsLoader';
+import EditorSidebar from '@/components/Editor/EditorSidebar.vue';
+import testData from '@/data/testData.json';
+import taskDefinitions from '@/data/taskDefinitions.json';
+import EditorPane from '@/components/Editor/EditorPane.vue';
+
+const sessionStore = useSessionStore();
+
+const quests = loadQuestsFromJson(testData.quests);
+const categories = loadCategoriesFromJson(testData.categories);
+
+sessionStore.setQuests(quests);
+sessionStore.setCategories(categories);
+sessionStore.setTaskDefinitions(taskDefinitions.taskTypes);
+// sessionStore.updateEditorCategories();
+</script>
+
+<template>
+ <main>
+ <div id="editor-container">
+ <EditorSidebar />
+
+ <EditorPane />
+ </div>
+ </main>
+</template>
+
+<style lang="scss" scoped>
+#editor-container {
+ display: flex;
+ background-color: var(--color-background-soft);
+ max-height: calc(100vh - 73px);
+ flex-direction: row;
+}
+</style> \ No newline at end of file
diff --git a/tsconfig.app.json b/tsconfig.app.json
new file mode 100644
index 0000000..6bd811a
--- /dev/null
+++ b/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.ts", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..66b5e57
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/tsconfig.node.json b/tsconfig.node.json
new file mode 100644
index 0000000..f094063
--- /dev/null
+++ b/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/vite.config.ts b/vite.config.ts
new file mode 100644
index 0000000..5c45e1d
--- /dev/null
+++ b/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})